@@ -52,13 +52,15 @@ the following replacements should be used:
5252#include " RooMsgService.h"
5353#include " RooVectorDataStore.h"
5454#include " RooFitLegacy/RooAbsCategoryLegacyIterator.h"
55+ #include " TreeReadBuffer.h"
5556
5657#include " Compression.h"
5758#include " TString.h"
5859#include " TTree.h"
5960#include " TLeaf.h"
6061#include " TBranch.h"
6162
63+ #include < functional>
6264#include < memory>
6365
6466using namespace std ;
@@ -72,6 +74,10 @@ const decltype(RooAbsCategory::_stateNames)::value_type& RooAbsCategory::invalid
7274 return invalid;
7375}
7476
77+
78+ RooAbsCategory::RooAbsCategory () {}
79+
80+
7581// //////////////////////////////////////////////////////////////////////////////
7682// / Constructor
7783
@@ -90,8 +96,7 @@ RooAbsCategory::RooAbsCategory(const char *name, const char *title) :
9096RooAbsCategory::RooAbsCategory (const RooAbsCategory& other,const char * name) :
9197 RooAbsArg(other,name), _currentIndex(other._currentIndex),
9298 _stateNames(other._stateNames),
93- _insertionOrder(other._insertionOrder),
94- _treeVar(other._treeVar)
99+ _insertionOrder(other._insertionOrder)
95100{
96101 setValueDirty () ;
97102 setShapeDirty () ;
@@ -439,41 +444,65 @@ void RooAbsCategory::attachToVStore(RooVectorDataStore& vstore)
439444// / Attach the category index and label as branches to the given
440445// / TTree. The index field will be attached as integer with name
441446// / `<name>_idx`. If a branch `<name>` exists, it attaches to this branch.
442- void RooAbsCategory::attachToTree (TTree& t , Int_t bufSize)
447+ void RooAbsCategory::attachToTree (TTree& tree , Int_t bufSize)
443448{
444449 // First check if there is an integer branch matching the category name
445450 TString cleanName (cleanBranchName ()) ;
446- TBranch* branch = t .GetBranch (cleanName) ;
451+ TBranch* branch = tree .GetBranch (cleanName) ;
447452 if (!branch) {
448453 cleanName += " _idx" ;
449- branch = t .GetBranch (cleanName);
454+ branch = tree .GetBranch (cleanName);
450455 }
451456
452457 if (branch) {
453- TString typeName (((TLeaf*)branch->GetListOfLeaves ()->At (0 ))->GetTypeName ()) ;
454- if (!typeName.CompareTo (" Int_t" )) {
455- // Imported TTree: attach only index field as branch
456-
457- coutI (DataHandling) << " RooAbsCategory::attachToTree(" << GetName () << " ) TTree branch " << GetName ()
458- << " will be interpreted as category index" << endl ;
459-
460- t.SetBranchAddress (cleanName, &_currentIndex) ;
461- setAttribute (" INTIDXONLY_TREE_BRANCH" ,kTRUE ) ;
462- _treeVar = true ;
463- return ;
464- } else if (!typeName.CompareTo (" UChar_t" )) {
465- coutI (DataHandling) << " RooAbsReal::attachToTree(" << GetName () << " ) TTree UChar_t branch " << GetName ()
466- << " will be interpreted as category index" << endl ;
467- t.SetBranchAddress (cleanName,&_byteValue) ;
468- setAttribute (" UCHARIDXONLY_TREE_BRANCH" ,kTRUE ) ;
469- _treeVar = true ;
458+ TLeaf* leaf = (TLeaf*)branch->GetListOfLeaves ()->At (0 ) ;
459+
460+ // Check that leaf is _not_ an array
461+ Int_t dummy ;
462+ TLeaf* counterLeaf = leaf->GetLeafCounter (dummy) ;
463+ if (counterLeaf) {
464+ coutE (Eval) << " RooAbsCategory::attachToTree(" << GetName () << " ) ERROR: TTree branch " << GetName ()
465+ << " is an array and cannot be attached to a RooAbsCategory" << endl ;
470466 return ;
471467 }
468+
469+ TString typeName (leaf->GetTypeName ()) ;
470+
471+
472+ // For different type names, store a function to attach
473+ std::map<std::string, std::function<std::unique_ptr<TreeReadBuffer>()>> typeMap {
474+ {" Float_t" , [&](){ return createTreeReadBuffer<Float_t >(cleanName, tree); }},
475+ {" Double_t" , [&](){ return createTreeReadBuffer<Double_t >(cleanName, tree); }},
476+ {" UChar_t" , [&](){ return createTreeReadBuffer<UChar_t >(cleanName, tree); }},
477+ {" Bool_t" , [&](){ return createTreeReadBuffer<Bool_t >(cleanName, tree); }},
478+ {" Char_t" , [&](){ return createTreeReadBuffer<Char_t >(cleanName, tree); }},
479+ {" UInt_t" , [&](){ return createTreeReadBuffer<UInt_t >(cleanName, tree); }},
480+ {" Long64_t" , [&](){ return createTreeReadBuffer<Long64_t >(cleanName, tree); }},
481+ {" ULong64_t" , [&](){ return createTreeReadBuffer<ULong64_t>(cleanName, tree); }},
482+ {" Short_t" , [&](){ return createTreeReadBuffer<Short_t >(cleanName, tree); }},
483+ {" UShort_t" , [&](){ return createTreeReadBuffer<UShort_t >(cleanName, tree); }},
484+ };
485+
486+ auto typeDetails = typeMap.find (typeName.Data ());
487+ if (typeDetails != typeMap.end ()) {
488+ coutI (DataHandling) << " RooAbsCategory::attachToTree(" << GetName () << " ) TTree " << typeName << " branch \" " << cleanName
489+ << " \" will be converted to int." << endl ;
490+ _treeReadBuffer = typeDetails->second ();
491+ } else {
492+ _treeReadBuffer = nullptr ;
493+
494+ if (!typeName.CompareTo (" Int_t" )) {
495+ tree.SetBranchAddress (cleanName, &_currentIndex);
496+ }
497+ else {
498+ coutE (InputArguments) << " RooAbsCategory::attachToTree(" << GetName () << " ) data type " << typeName << " is not supported." << endl ;
499+ }
500+ }
472501 } else {
473502 TString format (cleanName);
474503 format.Append (" /I" );
475504 void * ptr = &_currentIndex;
476- t .Branch (cleanName, ptr, (const Text_t*)format, bufSize);
505+ tree .Branch (cleanName, ptr, (const Text_t*)format, bufSize);
477506 }
478507}
479508
@@ -533,33 +562,17 @@ void RooAbsCategory::copyCache(const RooAbsArg *source, Bool_t /*valueOnly*/, Bo
533562 auto other = static_cast <const RooAbsCategory*>(source);
534563 assert (dynamic_cast <const RooAbsCategory*>(source));
535564
536- _currentIndex = other->_currentIndex ;
537-
538- if (setValDirty) {
539- setValueDirty ();
540- }
541-
542- if (!_treeVar)
543- return ;
544-
545- if (source->getAttribute (" INTIDXONLY_TREE_BRANCH" )) {
546- // Lookup cat state from other-index because label is missing
547- if (hasIndex (other->_currentIndex )) {
548- _currentIndex = other->_currentIndex ;
549- } else {
550- coutE (DataHandling) << " RooAbsCategory::copyCache(" << GetName () << " ) ERROR: index of source arg "
551- << source->GetName () << " is invalid (" << other->_currentIndex
552- << " ), value not updated" << endl;
553- }
554- } else if (source->getAttribute (" UCHARIDXONLY_TREE_BRANCH" )) {
555- // Lookup cat state from other-index because label is missing
556- Int_t tmp = static_cast <int >(other->_byteValue );
557- if (hasIndex (tmp)) {
558- _currentIndex = tmp;
559- } else {
560- coutE (DataHandling) << " RooAbsCategory::copyCache(" << GetName () << " ) ERROR: index of source arg "
561- << source->GetName () << " is invalid (" << tmp << " ), value not updated" << endl;
565+ value_type tmp = other->_treeReadBuffer ? *other->_treeReadBuffer : other->_currentIndex ;
566+ // Lookup cat state from other-index because label is missing
567+ if (hasIndex (tmp)) {
568+ _currentIndex = tmp;
569+ if (setValDirty) {
570+ setValueDirty ();
562571 }
572+ } else {
573+ coutE (DataHandling) << " RooAbsCategory::copyCache(" << GetName () << " ) ERROR: index of source arg "
574+ << source->GetName () << " is invalid (" << other->_currentIndex
575+ << " ), value not updated" << endl;
563576 }
564577}
565578
0 commit comments