ATLAS Offline Software
HistogramFillerTree.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef AthenaMonitoringKernel_HistogramFiller_HistogramFillerTree_h
6 #define AthenaMonitoringKernel_HistogramFiller_HistogramFillerTree_h
7 
8 #include "TTree.h"
9 
11 #include <boost/algorithm/string.hpp>
12 
13 namespace Monitored {
14  template <typename T> void scalarFillerFunc(TBranch* branch, const IMonitoredVariable& var);
15  template <> void scalarFillerFunc<std::string>(TBranch* branch, const IMonitoredVariable& var);
16  template <typename T> void vectorFillerFunc(TBranch* branch, const IMonitoredVariable& var);
17  template <> void vectorFillerFunc<std::string>(TBranch* branch, const IMonitoredVariable& var);
18 
23  public:
24  HistogramFillerTree(const HistogramDef& definition, std::shared_ptr<IHistogramProvider> provider)
25  : HistogramFiller(definition, std::move(provider)) {
27  }
28 
29  virtual unsigned fill( const HistogramFiller::VariablesPack& vars ) const override {
30  // handling of the cutmask
31  auto cutMaskValuePair = getCutMaskFunc(vars.cut);
32  if (cutMaskValuePair.first == 0) { return 0; }
33  if (ATH_UNLIKELY(cutMaskValuePair.first > 1)) {
34  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
35  log << MSG::WARNING << "HistogramFillerTree (" << m_histDef->alias
36  << ") does not support more than a single entry being filled at a time\n"
37  << "so a cut mask with > 1 entry doesn't make sense. Using first entry only." << endmsg;
38  if (! cutMaskValuePair.second(0)) { return 0; }
39  }
40 
41  if (ATH_UNLIKELY(vars.size() != m_branchDefs.size())) {
42  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
43  log << MSG::ERROR << "Mismatch of passed variables and expected variables for " << m_histDef->alias
44  << "(" << vars.size() << ", " << m_branchDefs.size() << ")" << endmsg;
45  return 0;
46  }
47 
48  auto tree = this->histogram<TTree>();
49  if (tree->GetListOfBranches()->GetEntries() == 0) {
51  }
52  auto branchList = tree->GetListOfBranches();
53  // following logic allows us to skip branches that were badly-defined
54  size_t idx = 0, idxgood = 0;
55  for (const auto& brdef : m_branchDefs) {
56  if (ATH_UNLIKELY(brdef.second == "IGNORE")) {
57  ++idx; continue;
58  }
59  TBranch* branch = static_cast<TBranch*>(branchList->At(idxgood));
61  ++idx; ++idxgood;
62  }
63  for (Int_t i = 0; i < branchList->GetEntries(); ++i) {
64 
65 
66  }
67  tree->SetEntries(tree->GetEntries() + 1);
68  return 1;
69  }
70 
71  private:
72  std::vector<std::pair<std::string, std::string>> m_branchDefs;
73  std::vector<std::function<void(TBranch*, const IMonitoredVariable&)>> m_fillerFunctions;
74 
75  void parseDefinition() {
76  std::vector<std::string> tokenized;
77  boost::split(tokenized, m_histDef->treeDef, [](char c){ return c ==':'; });
78  for (const auto& token : tokenized) {
79  auto ipart = token.find('/');
80  if (ipart == std::string::npos) {
81  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
82  log << MSG::ERROR << "Tree " << m_histDef->alias << ": Badly formed variable definition " << token
83  << "; skipping" << endmsg;
84  continue;
85  }
86  auto branch = token.substr(0, ipart);
87  auto type = token.substr(ipart+1);
88  std::function<void(TBranch*, const IMonitoredVariable&)> fillerFunc;
89  // scalar
90  if (type == "B") fillerFunc = scalarFillerFunc<Char_t>;
91  else if (type == "b") fillerFunc = scalarFillerFunc<UChar_t>;
92  else if (type == "S") fillerFunc = scalarFillerFunc<Short_t>;
93  else if (type == "s") fillerFunc = scalarFillerFunc<UShort_t>;
94  else if (type == "I") fillerFunc = scalarFillerFunc<Int_t>;
95  else if (type == "i") fillerFunc = scalarFillerFunc<UInt_t>;
96  else if (type == "F") fillerFunc = scalarFillerFunc<Float_t>;
97  else if (type == "f") fillerFunc = scalarFillerFunc<Float16_t>;
98  else if (type == "D") fillerFunc = scalarFillerFunc<Double_t>;
99  else if (type == "d") fillerFunc = scalarFillerFunc<Double32_t>;
100  else if (type == "L") fillerFunc = scalarFillerFunc<Long64_t>;
101  else if (type == "l") fillerFunc = scalarFillerFunc<ULong64_t>;
102  else if (type == "O") fillerFunc = scalarFillerFunc<Bool_t>;
103  else if (type == "string") fillerFunc = scalarFillerFunc<std::string>;
104  else if (type == "vector<char>") fillerFunc = vectorFillerFunc<char>;
105  else if (type == "vector<unsigned char>") fillerFunc = vectorFillerFunc<unsigned char>;
106  else if (type == "vector<int>") fillerFunc = vectorFillerFunc<int>;
107  else if (type == "vector<unsigned int>") fillerFunc = vectorFillerFunc<unsigned int>;
108  else if (type == "vector<float>") fillerFunc = vectorFillerFunc<float>;
109  else if (type == "vector<double>") fillerFunc = vectorFillerFunc<double>;
110  else if (type == "vector<long>") fillerFunc = vectorFillerFunc<long>;
111  else if (type == "vector<unsigned long>") fillerFunc = vectorFillerFunc<unsigned long>;
112  else if (type == "vector<string>") fillerFunc = vectorFillerFunc<std::string>;
113  else if (type == "C") {
114  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
115  log << MSG::ERROR << "Tree " << m_histDef->alias << ": Branch type \"C\" not supported for branch" << branch
116  << "; please use \"string\"" << endmsg;
117  type = "IGNORE";
118  } else {
119  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
120  log << MSG::ERROR << "Tree " << m_histDef->alias << ": Unrecognized branch type " << type << " for branch " << branch
121  << "; ignoring branch " << endmsg;
122  type = "IGNORE";
123  }
124  m_branchDefs.emplace_back(branch, type);
125  m_fillerFunctions.push_back(fillerFunc);
126  }
127  }
128 
129  template <typename T>
130  void branchHelper(TTree* tree, const std::pair<std::string, std::string>& brdef) const {
131  std::vector<T> dummy;
132  std::vector<T>* dummyptr = &dummy;
133  // we only need dummy object to exist through the end of this method
134  tree->Branch(brdef.first.c_str(), &dummyptr);
135  }
136 
137  void createBranches(TTree* tree) const {
138  for (const auto& brdef : m_branchDefs) {
139  if (brdef.second == "vector<char>") branchHelper<char>(tree, brdef);
140  else if (brdef.second == "vector<unsigned char>") branchHelper<unsigned char>(tree, brdef);
141  else if (brdef.second == "vector<int>") branchHelper<int>(tree, brdef);
142  else if (brdef.second == "vector<unsigned int>") branchHelper<unsigned int>(tree, brdef);
143  else if (brdef.second == "vector<float>") branchHelper<float>(tree, brdef);
144  else if (brdef.second == "vector<double>") branchHelper<double>(tree, brdef);
145  else if (brdef.second == "vector<long>") branchHelper<long>(tree, brdef);
146  else if (brdef.second == "vector<unsigned long>") branchHelper<unsigned long>(tree, brdef);
147  else if (brdef.second == "vector<string>") branchHelper<std::string>(tree, brdef);
148  else if (brdef.second == "string") {
149  std::string dummy; tree->Branch(brdef.first.c_str(), &dummy);
150  } else if (brdef.second != "IGNORE") {
151  tree->Branch(brdef.first.c_str(), (void*) nullptr, (brdef.first+"/"+brdef.second).c_str());
152  }
153  }
154  }
155  };
156 
157  // helper functions for filling branches
158  template <typename T>
160  if (ATH_UNLIKELY(var.size() == 0)) {
161  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
162  log << MSG::WARNING << "Tree " << branch->GetTree()->GetName() << ": Empty value passed to scalar branch fill for"
163  << branch->GetName() << endmsg;
164  return;
165  }
166  T tofill = var.get(0);
167  T* ptr = &tofill;
168  branch->SetAddress(ptr);
169  branch->Fill();
170  }
171 
172  // specialization for string
173  template <>
174  void scalarFillerFunc<std::string>(TBranch* branch, const IMonitoredVariable& var) {
175  if (ATH_UNLIKELY(var.size() == 0)) {
176  MsgStream log(Athena::getMessageSvc(), "HistogramFillerTree");
177  log << MSG::WARNING << "Tree " << branch->GetTree()->GetName() << ": Empty value passed to scalar branch fill for"
178  << branch->GetName() << endmsg;
179  return;
180  }
181  std::string tofill{var.getString(0)};
182  branch->SetObject(&tofill);
183  //*static_cast<std::string*>(branch->GetObject()) = tofill;
184  branch->Fill();
185  }
186 
187  template <typename T>
189  std::vector<T> tofill;
190  tofill.reserve(var.size());
191  for (size_t i = 0; i < var.size(); i++) {
192  tofill.push_back(var.get(i));
193  }
194  std::vector<T>* tofillptr = &tofill;
195  branch->SetAddress(&tofillptr);
196  branch->Fill();
197  }
198 
199  // specialization for string
200  template <>
201  void vectorFillerFunc<std::string>(TBranch* branch, const IMonitoredVariable& var) {
202  std::vector<std::string> tofill;
203  tofill.reserve(var.size());
204  for (size_t i = 0; i < var.size(); i++) {
205  tofill.push_back(var.getString(i));
206  }
207  auto* tofillptr = &tofill;
208  branch->SetAddress(&tofillptr);
209  branch->Fill();
210  }
211 }
212 
213 #endif // AthenaMonitoringKernel_HistogramFiller_HistogramFillerTree_h
beamspotnt.var
var
Definition: bin/beamspotnt.py:1393
Monitored::HistogramFiller::m_histDef
std::shared_ptr< HistogramDef > m_histDef
Definition: HistogramFiller.h:197
tree
TChain * tree
Definition: tile_monitor.h:30
Monitored::HistogramFiller::VariablesPack::cut
const Monitored::IMonitoredVariable * cut
pointer to cut mask variable, typically absent
Definition: HistogramFiller.h:116
Monitored::HistogramFillerTree
Filler for TTrees.
Definition: HistogramFillerTree.h:22
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
Monitored::HistogramDef
the internal class used to keep parsed Filler properties
Definition: HistogramDef.h:15
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
Monitored::vectorFillerFunc
void vectorFillerFunc(TBranch *branch, const IMonitoredVariable &var)
Definition: HistogramFillerTree.h:188
Monitored::HistogramFiller::VariablesPack
helper class to pass variables to fillers
Definition: HistogramFiller.h:72
Monitored::IMonitoredVariable
Definition: IMonitoredVariable.h:14
Monitored::HistogramFillerTree::fill
virtual unsigned fill(const HistogramFiller::VariablesPack &vars) const override
Method that actually fills the ROOT object.
Definition: HistogramFillerTree.h:29
lumiFormat.i
int i
Definition: lumiFormat.py:85
Monitored
Generic monitoring tool for athena components.
Definition: GenericMonitoringTool.h:30
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
Monitored::HistogramFiller::VariablesPack::size
size_t size() const
number of variables in the pack ( not counting the weight and mask )
Definition: HistogramFiller.h:80
Monitored::HistogramFillerTree::m_fillerFunctions
std::vector< std::function< void(TBranch *, const IMonitoredVariable &)> > m_fillerFunctions
Definition: HistogramFillerTree.h:73
CalibDbCompareRT.dummy
dummy
Definition: CalibDbCompareRT.py:59
Monitored::HistogramFillerTree::HistogramFillerTree
HistogramFillerTree(const HistogramDef &definition, std::shared_ptr< IHistogramProvider > provider)
Definition: HistogramFillerTree.h:24
Monitored::HistogramFillerTree::m_branchDefs
std::vector< std::pair< std::string, std::string > > m_branchDefs
Definition: HistogramFillerTree.h:72
Monitored::scalarFillerFunc
void scalarFillerFunc(TBranch *branch, const IMonitoredVariable &var)
Definition: HistogramFillerTree.h:159
Monitored::HistogramFillerTree::branchHelper
void branchHelper(TTree *tree, const std::pair< std::string, std::string > &brdef) const
Definition: HistogramFillerTree.h:130
HistogramFiller.h
Monitored::HistogramFiller
Base class for all histogram fillers.
Definition: HistogramFiller.h:44
Monitored::HistogramFillerTree::parseDefinition
void parseDefinition()
Definition: HistogramFillerTree.h:75
Monitored::HistogramFiller::VariablesPack::var
std::vector< const Monitored::IMonitoredVariable * > var
storage for variables, default size of 4, serves all histograming uses
Definition: HistogramFiller.h:114
RTTAlgmain.branch
branch
Definition: RTTAlgmain.py:61
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
Monitored::HistogramFiller::getCutMaskFunc
std::pair< size_t, std::function< bool(size_t)> > getCutMaskFunc(const Monitored::IMonitoredVariable *mask) const
Definition: HistogramFiller.h:156
Monitored::HistogramFillerTree::createBranches
void createBranches(TTree *tree) const
Definition: HistogramFillerTree.h:137
python.compressB64.c
def c
Definition: compressB64.py:93
Trk::split
@ split
Definition: LayerMaterialProperties.h:38