22 const std::map<std::string, std::string, std::less<>> typeMap = {
23 {
"char",
"B" }, {
"unsigned char",
"b" }, {
"short",
"S" }, {
"unsigned short",
"s" },
24 {
"int",
"I" }, {
"unsigned int",
"i" }, {
"float",
"F" }, {
"double",
"D" },
25 {
"long long",
"L" }, {
"unsigned long long",
"l" }, {
"long",
"G" }, {
"unsigned long",
"g" },
29 std::optional<std::string> getLeafListForType(
const std::string_view& typeName ) {
30 auto it = typeMap.find( typeName );
31 return ( it != typeMap.end() ) ? std::optional<std::string>{ it->second } : std::nullopt;
38 const std::string& branchName,
const std::string& location,
const std::string& algName,
39 unsigned int bufferSize,
unsigned int splitLevel )
41 auto leafListTag = getLeafListForType(
m_className );
45 ( std::format(
"{}/{}",
m_className, leafListTag.value() ) ).c_str(), bufferSize );
46 setBranchAddress = []( gsl::not_null<TBranch*> br,
const void** wrappedDataPtr ) {
47 br->SetAddress(
const_cast<void*
>( *wrappedDataPtr ) );
50 }
else if ( TClass::GetClass(
m_className.c_str() ) ) {
53 setBranchAddress = []( gsl::not_null<TBranch*> br,
const void** wrappedDataPtr ) {
54 br->SetAddress( wrappedDataPtr );
58 throw GaudiException( std::format(
"Cannot create branch {} for unknown class: {}. Provide a dictionary please.",
80 m_dataBuffer = baseWrapper ? baseWrapper->payload() : pObj.get();
85 unsigned int approxEventsPerBasket,
unsigned int splitLevel ) {
87 auto dummy_file = std::make_unique<TMemFile>(
"dummy.root",
"CREATE" );
88 auto dummy_tree = std::make_unique<TTree>(
"DummyTree",
"DummyTree", splitLevel, dummy_file->GetDirectory(
"/" ) );
89 auto leafListTag = getLeafListForType(
m_className );
90 TBranch* dummy_branch{
nullptr };
95 ( fmt::format(
"{}/{}",
m_className, leafListTag.value() ) ).c_str(), minBufferSize );
96 }
else if ( TClass::GetClass(
m_className.c_str() ) ) {
98 dummy_branch = dummy_tree->Branch(
"DummyBranch",
m_className.c_str(), &
m_dataBuffer, minBufferSize, splitLevel );
100 int nWritten = dummy_branch->Fill();
101 if ( nWritten >= 0 ) {
102 unsigned int newBasketSize = nWritten * approxEventsPerBasket;
104 if ( std::numeric_limits<Int_t>::max() / approxEventsPerBasket < (
unsigned int)nWritten ) {
105 newBasketSize = std::numeric_limits<Int_t>::max();
107 return std::min( maxBufferSize, std::max( minBufferSize, newBasketSize ) );
109 return minBufferSize;
114 auto nEvents =
m_branch->GetTree()->GetEntries();
115 auto nEntries =
m_branch->GetEntries();
116 if ( nEntries < nEvents ) {
118 for (
auto i = nEntries; i < nEvents; i++ ) {
m_branch->Fill(); }
Define general base for Gaudi exception.
constexpr static const auto FAILURE
unsigned int computeOptimalBufferSize(unsigned int minBufferSize, unsigned int maxBufferSize, unsigned int approxEventsPerBasket, unsigned int splitLevel)
compute optimal buffer size to fit given number of element per basket, respecting given min and max
void padEntries()
pad the number of item in the branch to the one of the Tree in which it leaves by adding empty entrie...
void(* setBranchAddress)(gsl::not_null< TBranch * >, const void **)
void setDataPtr(void const *dataPtr)
BranchWrapper(const gsl::not_null< TTree * > tree, const std::string &className, const std::string &branchName, const std::string &location, const std::string &algName, unsigned int bufferSize=32000, unsigned int splitLevel=99)
void setBranchData(const gsl::not_null< DataObject * > pObj)
void const * m_dataBuffer