ATLAS Offline Software
Loading...
Searching...
No Matches
BaseLinearFakeBkgTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
9#include "TTree.h"
10#include "TDirectory.h"
11#include "TFile.h"
12#include "TH1.h"
13#include "TH2.h"
14#include "TH3.h"
15
16using namespace FakeBkgTools;
17using namespace CP;
18
19namespace
20{
21 const char savedYieldsKey[] = "BaseLinearFakeBkgTool__yields";
22 const char savedHistogramsKey[] = "BaseLinearFakeBkgTool__histograms";
23}
24
25BaseLinearFakeBkgTool::BaseLinearFakeBkgTool(const std::string& toolname) : BaseFakeBkgTool(toolname), m_yields(1)
26{
28}
29
33
38
39StatusCode BaseLinearFakeBkgTool::getEventWeight(float& weight, const std::string& selection, const std::string& process)
40{
43 weight = w.value(this);
44 return sc;
45}
46
47StatusCode BaseLinearFakeBkgTool::getEventWeightCommon(FakeBkgTools::Weight& weight, const std::string& selection, const std::string& process)
48{
49 if(!m_initialized)
50 {
51 ATH_MSG_WARNING("the tool hasn't been initialized");
52 return StatusCode::FAILURE;
53 }
54 weight.uncertainties.clear();
55 bool success = true;
56 auto fs = getCachedFinalState(m_particles.size(), selection, process, success);
57 if(!success) return StatusCode::FAILURE;
58 auto itr = m_cachedWeights.find(fs);
59 if(itr != m_cachedWeights.end())
60 {
61 weight = itr->second;
62 return StatusCode::SUCCESS;
63 }
64 auto sc = getEventWeightCustom(weight, fs);
65 if(sc != StatusCode::SUCCESS) return sc;
66 m_cachedWeights.emplace(fs, weight);
67 return StatusCode::SUCCESS;
68}
69
70StatusCode BaseLinearFakeBkgTool::getTotalYield(float& yield, float& yieldStatErrorUp, float& yieldStatErrorDown)
71{
72 if(!m_initialized)
73 {
74 ATH_MSG_WARNING("the tool hasn't been initialized");
75 return StatusCode::FAILURE;
76 }
77 if(m_progressFileName.length() && m_progressFileName != "none")
78 {
80 }
81 auto& total = m_yields.at(0);
82 yield = total.value(this);
83 yieldStatErrorUp = sqrt(total.stat2.up);
84 yieldStatErrorDown = sqrt(total.stat2.down);
85 for(auto& kv : m_histogramYieldsRange)
86 {
87 for(int i=0;i<kv.first->GetNcells();++i)
88 {
89 auto& thisYield = m_yields.at(kv.second.first + i);
90 kv.first->SetBinContent(i, thisYield.value(this));
91 kv.first->SetBinError(i, thisYield.stat());
92 }
93 }
94 return StatusCode::SUCCESS;
95}
96
98{
99 FakeBkgTools::Weight eventWeight;
102 m_yields.at(0).add(eventWeight, m_externalWeight);
103 for(auto& kv : m_values_1dhisto_map)
104 {
105 unsigned index = m_histogramYieldsRange.at(kv.first).first + kv.first->FindBin(*kv.second);
106 m_yields.at(index).add(eventWeight, m_externalWeight);
107 }
108 for(auto& kv : m_values_2dhisto_map)
109 {
110 unsigned index = m_histogramYieldsRange.at(kv.first).first + kv.first->FindBin(*kv.second.first, *kv.second.second);
111 m_yields.at(index).add(eventWeight, m_externalWeight);
112 }
113 for(auto& kv : m_values_3dhisto_map)
114 {
115 unsigned index = m_histogramYieldsRange.at(kv.first).first + kv.first->FindBin(*std::get<0>(kv.second), *std::get<1>(kv.second), *std::get<2>(kv.second));
116 m_yields.at(index).add(eventWeight, m_externalWeight);
117 }
118 return StatusCode::SUCCESS;
119}
120
121StatusCode BaseLinearFakeBkgTool::register1DHistogram(TH1* h1, const float *val)
122{
124 if(sc != StatusCode::SUCCESS) return sc;
125 return assignYieldRange(h1);
126}
127
128StatusCode BaseLinearFakeBkgTool::register2DHistogram(TH2* h2, const float *xval, const float *yval)
129{
130 auto sc = BaseFakeBkgTool::register2DHistogram(h2, xval, yval);
131 if(sc != StatusCode::SUCCESS) return sc;
132 return assignYieldRange(h2);
133}
134
135StatusCode BaseLinearFakeBkgTool::register3DHistogram(TH3* h3, const float *xval, const float *yval, const float *zval)
136{
137 auto sc = BaseFakeBkgTool::register3DHistogram(h3, xval, yval, zval);
138 if(sc != StatusCode::SUCCESS) return sc;
139 return assignYieldRange(h3);
140}
141
143{
144 const std::string histname = h->GetName();
145 std::pair<uint32_t, uint32_t> range;
146 for(auto itr=m_histogramYieldsRange.begin();itr!=m_histogramYieldsRange.end();++itr)
147 {
148 if(histname != itr->first->GetName()) continue;
149 range = itr->second;
150 m_histogramYieldsRange.erase(itr);
151 m_histogramYieldsRange.emplace(h, range);
152 return StatusCode::SUCCESS;
153 }
154 range.first = m_yields.size();
155 m_yields.insert(m_yields.end(), std::max(1, h->GetNcells()), FakeBkgTools::Yield{});
156 range.second = m_yields.size() - 1;
157 m_histogramYieldsRange.emplace(h, range);
158 return StatusCode::SUCCESS;
159}
160
161StatusCode BaseLinearFakeBkgTool::saveProgress(TDirectory* dir)
162{
163 TTree tree(::savedYieldsKey, "binned yields saved by BaseLinearFakeBkgTool");
164 TObjArray histograms;
165
166 ULong64_t histname = 0;
167 UInt_t bin=0, n=0;
168 float nominal, stat2Up, stat2Down;
169 const std::size_t maxSize = m_database->numberOfStats() + m_database->numberOfSysts();
170 std::unique_ptr<UShort_t[]> systUID(new UShort_t[maxSize]);
171 std::unique_ptr<float[]> systUp(new float[maxSize]), systDown(new float[maxSize]);
172 tree.Branch("Name", &histname, "Name/l");
173 tree.Branch("Bin", &bin, "Bin/i");
174 tree.Branch("nominal", &nominal, "nominal/F");
175 tree.Branch("stat2Up", &stat2Up, "stat2Up/F");
176 tree.Branch("stat2Down", &stat2Down, "stat2Down/F");
177 tree.Branch("N", &n, "N/i");
178 tree.Branch("systUID", systUID.get(), "systUID[N]/s");
179 tree.Branch("systUp", systUp.get(), "systUp[N]/F");
180 tree.Branch("systDown", systDown.get(), "systDown[N]/F");
181
182 auto fillTree = [&](const auto& yield)
183 {
184 nominal = yield.nominal;
185 stat2Up = yield.stat2.up;
186 stat2Down = yield.stat2.down;
187 n = yield.uncertainties.size();
188 auto itr = yield.uncertainties.begin();
189 for(uint32_t j=0;j<n;++j)
190 {
191 systUID[j] = itr->first;
192 systUp[j] = itr->second.up;
193 systDown[j] = itr->second.down;
194 ++itr;
195 }
196 tree.Fill();
197 };
198
199 fillTree(m_yields.at(0));
200
201 std::hash<std::string> hasher;
202 for(auto& kv : m_histogramYieldsRange)
203 {
204 histograms.AddLast(kv.first);
205 histname = hasher(kv.first->GetName());
206 for(uint32_t i=kv.second.first;i<=kv.second.second;++i)
207 {
208 bin = i - kv.second.first;
209 fillTree(m_yields.at(i));
210 }
211 }
212
213 dir->cd();
214 tree.Write();
215 dir->mkdir(::savedHistogramsKey);
216 dir->cd(::savedHistogramsKey);
217 histograms.Write();
218 dir->cd("..");
219 return StatusCode::SUCCESS;
220}
221
223{
224 std::string filename = PathResolverFindDataFile(m_progressFileName);
225
226 auto file = std::unique_ptr<TFile>(TFile::Open(filename.c_str(), "READ"));
227 if(!file)
228 {
229 ATH_MSG_ERROR("Unable to open the file specified for the \"ProgressFileName\" property: " << m_progressFileName);
230 return StatusCode::FAILURE;
231 }
232 std::string path = ::savedYieldsKey;
233 if(m_progressFileDirectory.length())
234 {
235 path = m_progressFileDirectory + "/" + path;
236 }
237 auto tree = static_cast<TTree*>(file->Get(path.c_str()));
238 if(!tree)
239 {
240 ATH_MSG_ERROR("Unable to find the tree \"" << path << "\" in the input file " << m_progressFileName);
241 return StatusCode::FAILURE;
242 }
243
246
247 std::hash<std::string> hasher;
248 std::map<std::size_t, decltype(m_histogramYieldsRange.cbegin())> dictionary;
249 for(auto itr=m_histogramYieldsRange.cbegin();itr!=m_histogramYieldsRange.cend();++itr)
250 {
251 dictionary[hasher(itr->first->GetName())] = itr;
252 }
253
254 ULong64_t histname = 0;
255 UInt_t bin=0, n=0;
256 float nominal, stat2Up, stat2Down;
257 const std::size_t maxSize = m_database->numberOfStats() + m_database->numberOfSysts();
258 std::unique_ptr<UShort_t[]> systUID(new UShort_t[maxSize]);
259 std::unique_ptr<float[]> systUp(new float[maxSize]), systDown(new float[maxSize]);
260 tree->SetBranchStatus("*", kTRUE);
261 tree->SetBranchAddress("Name", &histname);
262 tree->SetBranchAddress("Bin", &bin);
263 tree->SetBranchAddress("nominal", &nominal);
264 tree->SetBranchAddress("stat2Up", &stat2Up);
265 tree->SetBranchAddress("stat2Down", &stat2Down);
266 tree->SetBranchAddress("N", &n);
267 TBranch* branch = tree->FindBranch("N");
268 tree->SetBranchAddress("systUID", systUID.get());
269 tree->SetBranchAddress("systUp", systUp.get());
270 tree->SetBranchAddress("systDown", systDown.get());
271
272 std::set<std::size_t> filledHistograms;
273 const long entries = tree->GetEntries();
274 for(long entry=0;entry<entries;++entry)
275 {
276 branch->GetEntry(entry);
277 if(n > maxSize)
278 {
279 ATH_MSG_ERROR("the tool configuration seems to have changed (number of systematics)!");
280 return StatusCode::FAILURE;
281 }
282 tree->GetEntry(entry);
283
284 long index;
285 if(histname != 0)
286 {
287 auto itr = dictionary.find(histname);
288 if(itr == dictionary.end()) continue;
289 filledHistograms.emplace(histname);
290 const TH1* h = itr->second->first;
291 const auto& range = itr->second->second;
292 if(bin > (range.second - range.first))
293 {
294 ATH_MSG_ERROR("inconsistent binnings found for histogram " << h->GetName());
295 return StatusCode::FAILURE;
296 }
297 index = range.first + bin;
298 }
299 else
300 {
301 index = 0;
302 }
303
305 yield.nominal = nominal;
306 yield.stat2.up = stat2Up;
307 yield.stat2.down = stat2Down;
308 for(unsigned j=0;j<n;++j)
309 {
311 u.up = systUp[j];
312 u.down= systDown[j];
313 auto emplaced = yield.uncertainties.emplace(systUID[j], u);
314 if(!emplaced.second) emplaced.first->second += u;
315 }
316 m_yields.at(index).add(yield);
317 }
318
319 if(filledHistograms.size() != m_histogramYieldsRange.size())
320 {
321 ATH_MSG_ERROR("some of the registered histogram were not found in the input file " << m_progressFileName);
322 return StatusCode::FAILURE;
323 }
324
325 m_progressFileName.clear();
326 return StatusCode::SUCCESS;
327}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
void fillTree(AccumulateMap &map, TTree *tree, int nLayers, int nCoords)
Writes the contents of an AccumulateMap into the supplied tree (one entry per sector).
static Double_t fs
static Double_t sc
std::string PathResolverFindDataFile(const std::string &logical_file_name)
std::vector< FakeBkgTools::ParticleData > m_particles
bool m_unlimitedSystematicVariations
used to prevent multiple calls to applySystematicVariation() when unsupported set to true in a partic...
std::map< TH2 *, std::pair< const float *, const float * > > m_values_2dhisto_map
std::string m_progressFileName
property ProgressFileName
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual StatusCode register1DHistogram(TH1 *h1, const float *val) override
associates a 1D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
std::string m_progressFileDirectory
property ProgressFileDirectory
std::map< TH3 *, std::tuple< const float *, const float *, const float * > > m_values_3dhisto_map
std::string m_selection
'selection' settings used to compute the total yield / fill histograms
std::unique_ptr< FakeBkgTools::Database > m_database
virtual StatusCode register3DHistogram(TH3 *h3, const float *xval, const float *yval, const float *zval) override
associates a 3D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
BaseFakeBkgTool(const std::string &toolname)
std::string m_process
'process' settings used to compute the total yield / fill histograms
virtual StatusCode register2DHistogram(TH2 *h2, const float *xval, const float *yval) override
associates a 2D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
FakeBkgTools::FinalState getCachedFinalState(uint8_t nparticles, const std::string &strPID, const std::string &strProc, bool &success)
std::map< TH1 *, const float * > m_values_1dhisto_map
virtual StatusCode getEventWeight(float &weight, const std::string &selection, const std::string &process) override final
returns an event weight addEvent() must have been called before hand.
std::vector< FakeBkgTools::Yield > m_yields
accumulated yield for all events (and histogram bins with uncertainties)
BaseLinearFakeBkgTool(const std::string &toolname)
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual StatusCode register1DHistogram(TH1 *h1, const float *val) override
associates a 1D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
StatusCode incrementTotalYield()
be sure to only call this once per event! (typically at the end of addEvent())
virtual StatusCode register3DHistogram(TH3 *h3, const float *xval, const float *yval, const float *zval) override
associates a 3D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
virtual StatusCode getTotalYield(float &yield, float &statErrorUp, float &statErrorDown) override final
returns the accumulated fake lepton background yield (or compute it, in the case of the likelihood ma...
virtual StatusCode register2DHistogram(TH2 *h2, const float *xval, const float *yval) override
associates a 2D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
StatusCode getEventWeightCommon(FakeBkgTools::Weight &weight, const std::string &selection, const std::string &process)
std::map< TH1 *, std::pair< uint32_t, uint32_t > > m_histogramYieldsRange
virtual StatusCode saveProgress(TDirectory *dir) override
virtual StatusCode getEventWeightCustom(FakeBkgTools::Weight &weight, const FakeBkgTools::FinalState &fs)=0
std::map< FakeBkgTools::FinalState, FakeBkgTools::Weight > m_cachedWeights
cached weight+uncertainties for a single event Each tool derived from this base class MUST clear the ...
const std::string selection
const std::string process
double entries
Definition listroot.cxx:49
Select isolated Photons, Electrons and Muons.
Definition index.py:1
setEventNumber uint32_t
std::map< uint16_t, FakeBkgTools::Uncertainty > uncertainties
a structure to hold a weight together with a variable number of systematic uncertainties
a structure to hold an event yield together with a statistical uncertainty and a variable number of s...
TChain * tree
TFile * file