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