ATLAS Offline Software
TElectronEfficiencyCorrectionTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3  */
4 
15 // This class header
17 // STL includes
18 #include <cmath>
19 #include <iostream>
20 #include <memory>
21 #include <cstring>
22 // ROOT includes
23 #include "TClass.h"
24 #include "TFile.h"
25 #include "TKey.h"
26 #include "TMD5.h"
27 #include "TObjString.h"
28 #include "TROOT.h"
29 #include "TString.h"
30 #include "TSystem.h"
31 
32 namespace mapkey {
33 // The "keys" below are indices for the vectors
34 //(of size mapkey::end)
35 // we use to look up the numbers we need
36 enum key
37 {
38  sf = 0,
39  stat = 1,
40  eig = 2,
41  uncorr = 3,
42  sys = 4,
43  end = 5
44 };
45 const char*
46 keytostring(int input)
47 {
48  switch (input) {
49  case (sf):
50  return "sf";
51  case (stat):
52  return "stat";
53  case (eig):
54  return "eig";
55  case (uncorr):
56  return "uncorr";
57  case (sys):
58  return "sys";
59  }
60  return "";
61 }
62 }
63 
64 namespace {
65 char const * const LowPt_string = "LowPt" ;
66 const std::vector<int> s_keys = { mapkey::sf,
70 }
71 
73  const char* name)
74  : asg::AsgMessaging(std::string(name))
75  , m_doToyMC(false)
76  , m_doCombToyMC(false)
77  , m_nToyMC(0)
78  , m_seed(0)
79  , m_nSysMax(0)
80  , m_histList{ mapkey::end }
81  , m_fastHistList{ mapkey::end }
82  , m_Rndm()
83 {
84 }
85 
86 int
88 {
89  // use an int as a StatusCode
90  int sc(1);
91  // Check if files are present
92  if (m_corrFileNameList.empty()) {
93  ATH_MSG_ERROR(" No file added!");
94  return 0;
95  }
96  ATH_MSG_DEBUG("Initializing tool with " << m_corrFileNameList.size()
97  << " configuration file(s)");
98 
99  if (m_doToyMC && m_doCombToyMC) {
100  ATH_MSG_ERROR(" Both regular and combined toy MCs booked!"
101  << " Only use one!");
102  return 0;
103  }
104  /*
105  * initialize the random number generator if toyMC propagation booked
106  * Use the 1st 4 bytes of the CheckSum of the reccomendation file as seed
107  */
108  if (m_doToyMC || m_doCombToyMC) {
109  if (m_seed == 0) {
110  // Use the name of the correction for auto-setting of the seed based on
111  // the md5-sum of the file
112  const std::unique_ptr<char[]> fname(
113  gSystem->ExpandPathName(m_corrFileNameList[0].c_str()));
114  std::unique_ptr<TMD5> tmd = std::make_unique<TMD5>();
115  const char* tmd_as_string = tmd->FileChecksum(fname.get())->AsString();
116  m_seed = *(reinterpret_cast<const unsigned long int*>(tmd_as_string));
117  ATH_MSG_DEBUG("Seed (automatically) set to " << m_seed);
118  } else {
119  ATH_MSG_DEBUG("Seed set to " << m_seed);
120  }
121  m_Rndm = TRandom3(m_seed);
122  }
123  /*
124  * Load the needed histograms
125  */
126  if (0 == getHistograms()) {
127  ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
128  << "! Problem when calling getHistograms()");
129  return 0;
130  }
131  const unsigned int nRunNumbersFull = m_begRunNumberList.size();
132  const unsigned int nRunNumbersFast = m_begRunNumberListFastSim.size();
133 
134  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
135  << "Found " << nRunNumbersFast
136  << " run number ranges for fast sim with a total of "
137  << m_fastHistList[mapkey::sf].size()
138  << " scale factor histograms.");
139 
140  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
141  << "Found " << nRunNumbersFull
142  << " run number ranges for full sim with a total of "
143  << m_histList[mapkey::sf].size()
144  << " scale factor histograms.");
145 
146  ATH_MSG_DEBUG("Tool succesfully initialized!");
147 
148  return sc;
149 }
150 
151 int
154  const unsigned int runnumber,
155  const double cluster_eta,
156  const double et, /* in MeV */
157  Result& result,
158  const bool onlyTotal) const
159 {
160  // Set up the non-0 defaults
161  result.SF = -999;
162  result.Total = 1;
163  /*
164  * Determine Simulation flavour and find the run period
165  */
167  int runnumberIndex = -1;
168  if (isFastSim) {
169  for (unsigned int i = 0; i < m_begRunNumberListFastSim.size(); ++i) {
170  if (m_begRunNumberListFastSim[i] <= runnumber &&
171  runnumber <= m_endRunNumberListFastSim[i]) {
172  runnumberIndex = i;
173  break;
174  }
175  }
176  } else {
177  for (unsigned int i = 0; i < m_begRunNumberList.size(); ++i) {
178  if (m_begRunNumberList[i] <= runnumber &&
179  runnumber <= m_endRunNumberList[i]) {
180  runnumberIndex = i;
181  break;
182  }
183  }
184  }
185  if (runnumberIndex < 0) {
186  return 0;
187  }
188  /* What we have is a vector<vector<HistArray>> acting as a map:
189  * Key/Index is SF,Stat,Eigen,UnCorr
190  * The Entry in this index is a vector<HistArray>
191  * Each vector<HistArray> has as many entries as supported Run periods.
192  * Each HistArray has 2D histos (could be standard, low-et, or forward
193  * electrons) The 2D Histo then has the number we want. What follows is the
194  * logic to get to this number.
195  */
196  const auto& currentmap = (isFastSim) ? m_fastHistList : m_histList;
197  const std::vector<HistArray>& sfVector = currentmap.at(mapkey::sf);
198  /*
199  * See if we can find a vector for key SF in the map
200  * and then if we can get the corresponding HisArray
201  * for the run period.
202  */
203  if (sfVector.empty() || runnumberIndex >= static_cast<int>(sfVector.size())) {
204  return 0;
205  }
206  /*
207  * At this stage we have found the relevant period
208  * So we need to locate the right histogram.
209  */
210  const HistArray& sfObjectArray = sfVector[runnumberIndex];
211  const auto& edges = (isFastSim) ? m_fastHistEdges[runnumberIndex]
212  : m_histEdges[runnumberIndex];
213  const int entries = edges.size();
214  /*
215  * Now the logic of finding the histogram
216  * Some parts of the code can be perhaps improved ...
217  */
218  double xValue(et);
219  double yValue(cluster_eta);
220  int smallEt(0);
221  int etaCov(0);
222  int nSF(0);
223  bool invalid = false;
224  bool changedEt = false;
225  int index = -1;
226 
227  for (int i = 0; i < entries; ++i) {
228  invalid = false;
229  const HistEdge& histEdge = edges[i];
230  // invalid if we are below minimum et
231  if (et < histEdge.etMin) {
232  smallEt++;
233  invalid = true;
234  }
235  // invalid if we are above max eta
236  if (std::abs(yValue) >= histEdge.etaMax) {
237  etaCov++;
238  invalid = true;
239  }
240  // invalid if we are less than minimum eta (forward electrons)
241  if (std::abs(yValue) < histEdge.etaMin) {
242  etaCov++;
243  invalid = true;
244  }
245  /*
246  * Invalid if above max et and is a low Et histogram.
247  * If not low Et histogram then change the xValue to the maximum
248  * availabe Et of ths histogram. As we assume that the SF stays the same
249  * for very high Et
250  */
251  if (et > histEdge.etMax) {
252  if (histEdge.isLowPt) {
253  invalid = true;
254  } else {
255  xValue = histEdge.etMax - 1000 ; //1000 is 1 GeV
256  changedEt = true;
257  }
258  }
259  /*
260  * Get the histogram index in the TObjArray
261  * Also mark how many times we found something
262  * as SF should be unique
263  */
264  if (!invalid) {
265  index = i;
266  if (!changedEt) {
267  nSF++;
268  }
269  }
270  }
271  if (smallEt == entries) {
272  return 0;
273  }
274  if (etaCov == entries) {
275  return 0;
276  }
277  if (nSF > 1) {
278  ATH_MSG_WARNING("More than 1 SF found for eta="
279  << yValue << " , et = " << et << " , run number = "
280  << runnumber << ". Please check your input files!");
281  }
282  if (index < 0) {
283  return 0;
284  }
285 
286  /*
287  * Now we have the index of the histogram
288  */
289  const HistEdge& currentEdge = edges[index];
290  /*
291  * If SF is only given in Abs(eta) convert eta input to std::abs()
292  */
293  constexpr double epsilon = 1e-6;
294  if (currentEdge.etaMin >= (0 - epsilon)) {
295  yValue = std::abs(yValue);
296  }
297 
298  const TH2* currentHist = static_cast<TH2*>(sfObjectArray[index].get()) ;
299  const int globalBinNumber = currentHist->FindFixBin(xValue, yValue);
300  const double scaleFactor = currentHist->GetBinContent(globalBinNumber);
301  const double scaleFactorErr = currentHist->GetBinError(globalBinNumber);
302  /*
303  * Write the retrieved values to the output
304  */
305  result.SF= scaleFactor;
306  result.Total = scaleFactorErr;
307  result.histIndex = index;
308  result.histBinNum = globalBinNumber;
309  /*
310  * if we only wanted the Total we can exit here
311  */
312  if (onlyTotal) {
313  return 1;
314  }
315  /*
316  * Do the stat error using the available info from the above (SF)
317  */
318  double statErr = -999;
319  const std::vector<HistArray>& statVector = currentmap.at(mapkey::stat);
320  if (!statVector.empty()) {
321  if (!statVector[runnumberIndex].empty()) {
322  statErr = static_cast<TH1*>(statVector[runnumberIndex][index].get())
323  ->GetBinContent(globalBinNumber);
324  result.Stat = statErr;
325  }
326  }
327  /*
328  * Do the Uncorr uncertainty
329  */
330  double val = statErr;
331  const std::vector<HistArray>& uncorrVector = currentmap.at(mapkey::uncorr);
332  if (!uncorrVector.empty()) {
333  if (!uncorrVector.at(runnumberIndex).empty()) {
334  const double valAdd =
335  static_cast<TH1*>(uncorrVector[runnumberIndex][index].get())
336  ->GetBinContent(globalBinNumber);
337  val = sqrt(val * val + valAdd * valAdd);
338  }
339  }
340  result.UnCorr = val;
341  /*
342  * Do the correlated part
343  * For the N~16 systematic variations
344  * we keep them in a vector of vector of HistArray
345  * The first vector index being the runnumber
346  * The second the systematic
347  * And them the HistArray for high low etc.
348  */
349  result.Corr.resize(m_nSysMax);
350  const std::vector<std::vector<HistArray>>& sysList =
351  (isFastSim) ? m_fastSysList : m_sysList;
352  if (sysList.size() > static_cast<unsigned int>(index)) {
353  if (sysList.at(index).size() > static_cast<unsigned int>(runnumberIndex)) {
354  const int sys_entries = sysList.at(index).at(runnumberIndex).size();
355  for (int sys = 0; sys < sys_entries; ++sys) {
356  double sysVal =
357  static_cast<TH2*>(sysList[index][runnumberIndex][sys].get())
358  ->GetBinContent(globalBinNumber);
359  result.Corr[sys] = sysVal;
360  }
361  }
362  }
363  /*
364  * Do the toys if requested
365  */
366  if (m_doToyMC || m_doCombToyMC) {
367  result.toys.resize(static_cast<size_t>(m_nToyMC));
368  const std::vector<std::vector<HistArray>>& toyMCList =
369  ((isFastSim) ? m_uncorrToyMCSystFast : m_uncorrToyMCSystFull);
370  if (toyMCList.size() > (unsigned int)runnumberIndex) {
371  for (int toy = 0; toy < m_nToyMC; ++toy) {
372  if (toyMCList[runnumberIndex][toy].size() >
373  static_cast<unsigned int>(index)) {
374  result.toys[toy] =
375  static_cast<TH2*>(toyMCList[runnumberIndex][toy][index].get())
376  ->GetBinContent(globalBinNumber);
377  }
378  }
379  }
380  }
381  return 1;
382 }
383 /*
384  * Build the toyMC tables from inputs
385  * Ownership should be tranfered to the map of the tables
386  * and the proper delete happens in the dtor
387  */
388 std::vector<TH2*>
390  const TH2* sf,
391  const TH2* stat,
392  const TH2* uncorr,
393  const std::vector<TH1*>& corr,
394  int& randomCounter)
395 {
396  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")! "
397  << "Entering function buildSingleToyMC");
398  std::vector<TH2*> tmpHists;
399  int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
400  tmpHists.reserve(m_nToyMC);
401  for (int toy = 0; toy < m_nToyMC; toy++) {
402  tmpHists.push_back((TH2*)corr.at(0)->Clone());
403  }
404  // Loop over all bins
405  for (int bin = 0; bin < nBins; bin++) {
406  double val = stat->GetBinContent(bin);
407 
408  // Add uncorrelated systematics
409  if (uncorr != nullptr) {
410  double valAdd = uncorr->GetBinContent(bin);
411  val = sqrt(val * val + valAdd * valAdd);
412  }
413  for (int toy = 0; toy < m_nToyMC; toy++) {
414  tmpHists.at(toy)->SetBinContent(
415  bin, (val * m_Rndm.Gaus(0, 1)) + sf->GetBinContent(bin));
416  randomCounter++;
417  tmpHists.at(toy)->SetDirectory(nullptr);
418  }
419  }
420  return tmpHists;
421 }
422 /*
423  * Build the combined toyMC tables from inputs
424  * Ownership should be tranfered to the unique_ptr
425  * in the lookup tables and the proper delete
426  * happens in the dtor
427  */
428 TH2*
430  const TH2* sf,
431  const TH2* stat,
432  const TH2* uncorr,
433  const std::vector<TH1*>& corr,
434  const int nSys,
435  int& randomCounter)
436 {
437 
438  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
439  << "Entering function buildSingleCombToyMC");
440 
441  TH2* tmpHist;
442  const int nBins = (stat->GetNbinsX() + 2) * (stat->GetNbinsY() + 2);
443  tmpHist = (TH2*)corr.at(0)->Clone();
444  // Create random numbers for the corr. uncertainties
445  std::vector<double> rnd(nSys, 0);
446  for (int s = 0; s < nSys; ++s) {
447  rnd[s] = m_Rndm.Gaus(0, 1);
448  randomCounter++;
449  }
450  // Loop over all bins
451  for (int bin = 0; bin < nBins; ++bin) {
452  double val = stat->GetBinContent(bin);
453 
454  // Add uncorrelated systematics
455  if (uncorr != nullptr) {
456  double valAdd = uncorr->GetBinContent(bin);
457  val = sqrt(val * val + valAdd * valAdd);
458  }
459  val = val * m_Rndm.Gaus(0, 1);
460  randomCounter++;
461  // Add larger correlated systematics
462  for (int s = 0; s < nSys; ++s) {
463  if (corr.at(s) != nullptr) {
464  val += static_cast<TH2*>(corr.at(s))->GetBinContent(bin) * rnd[s];
465  }
466  }
467  tmpHist->SetBinContent(bin, val + sf->GetBinContent(bin));
468  }
469  tmpHist->SetDirectory(nullptr);
470  return tmpHist;
471 }
472 /*
473  * Build the toyMC tables from inputs
474  */
475 std::vector<Root::TElectronEfficiencyCorrectionTool::HistArray>
477  const std::vector<TH1*>& sf,
478  const std::vector<TH1*>& eig,
479  const std::vector<TH1*>& stat,
480  const std::vector<TH1*>& uncorr,
481  const std::vector<std::vector<TH1*>>& corr)
482 {
483 
484  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
485  << "Entering function buildToyMCTable");
486 
487  int nSys{};
488  int randomCounter(0);
489  std::vector<HistArray> tmpVec;
490  const int stat_entries = stat.size();
491  if (m_doCombToyMC) {
492  for (int toyMC = 0; toyMC < m_nToyMC; toyMC++) {
493  HistArray tmpArray;
494  for (int i = 0; i < stat_entries; ++i) {
495  if (!eig.empty() && !uncorr.empty()) {
496  nSys = ((TH1*)eig.at(i))->GetNbinsX() - 1;
497  tmpArray.emplace_back(buildSingleCombToyMC((TH2*)sf.at(i),
498  (TH2*)stat.at(i),
499  (TH2*)uncorr.at(i),
500  corr.at(i),
501  nSys,
502  randomCounter));
503  } else {
504  tmpArray.emplace_back(buildSingleCombToyMC((TH2*)sf.at(i),
505  (TH2*)stat.at(i),
506  nullptr,
507  corr.at(i),
508  nSys,
509  randomCounter));
510  }
511  }
512  tmpVec.emplace_back(std::move(tmpArray));
513  }
514  } else {
515  std::vector<std::vector<TH2*>> tmpVec2;
516  for (int i = 0; i < stat_entries; ++i) {
517  nSys = ((TH1*)eig.at(i))->GetNbinsX() - 1;
518  tmpVec2.push_back(buildSingleToyMC((TH2*)sf.at(i),
519  (TH2*)stat.at(i),
520  (TH2*)uncorr.at(i),
521  corr.at(i),
522  randomCounter));
523  }
524  for (int toy = 0; toy < m_nToyMC; toy++) {
525  HistArray tmpArray;
526  for (auto& i : tmpVec2) {
527  tmpArray.emplace_back(i.at(toy));
528  }
529  tmpVec.emplace_back(std::move(tmpArray));
530  }
531  }
532  return tmpVec;
533 }
534 /*
535  * Helper function to retrieve number of uncorrelated bins
536  */
537 int
539  std::map<float, std::vector<float>>& pt_eta1) const
540 {
541  // Get sf histograms
542  const std::vector<HistArray>& tmpVec = (!m_histList[mapkey::sf].empty())
543  ? m_histList[mapkey::sf]
544  : m_fastHistList[mapkey::sf];
545 
546  int nbinsTotal = 0;
547  pt_eta1.clear();
548  std::vector<float> eta1;
549  eta1.clear();
550 
551  // Loop over the different Run range (one TObjeArray for each)
552  for (const auto& ikey : tmpVec) {
553  // Loop over the histograms for a given run numbers
554  for (const auto& entries : ikey) {
555  eta1.clear();
556  // Get number of bins
557  TH2* h_tmp = ((TH2*)entries.get());
558  int nbinsX = h_tmp->GetNbinsX();
559  int nbinsY = h_tmp->GetNbinsY();
560  // fill in the eta pushing back
561  for (int biny = 1; biny <= nbinsY; ++biny) {
562  eta1.push_back(h_tmp->GetYaxis()->GetBinLowEdge(biny));
563  }
564  // associate each pt (bin) with the corresponding/available eta ones
565  for (int binx = 1; binx <= nbinsX; ++binx) {
566  pt_eta1[h_tmp->GetXaxis()->GetBinLowEdge(binx)] = eta1;
567  }
568  }
569  }
570  for (auto& i : pt_eta1) {
571  nbinsTotal += i.second.size();
572  }
573  return nbinsTotal;
574 }
575 /*
576  * Get the histograms from the input files
577  */
578 int
580 {
581 
582  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
583  << "Entering function getHistograms");
584  // Cache the current directory in the root file
585  TDirectory* origDir = gDirectory;
586  /*
587  * Get the name of the first input ROOT file and
588  * interpret from that what we have:
589  * efficiency vs. efficiencySF; offline vs. trigger; medium, loose,...
590  */
591  if (!m_corrFileNameList.empty()) {
592  TString firstFileNameAndPath = m_corrFileNameList[0].c_str();
593  std::unique_ptr<TObjArray> myStringList(firstFileNameAndPath.Tokenize("/"));
594  int lastIdx = myStringList->GetLast();
595  TString fileName = ((TObjString*)myStringList->At(lastIdx))->GetString();
596  std::unique_ptr<TObjArray> myFileNameTokensList(fileName.Tokenize("."));
597 
598  if (myFileNameTokensList->GetLast() < 3) {
599  ATH_MSG_ERROR("input file name has wrong format!");
600  return 0;
601  }
602  }
603  /*
604  * Get all ROOT files and histograms
605  */
606  for (auto& ifile : m_corrFileNameList) {
607  // Load the ROOT file
608  const std::unique_ptr<char[]> fname(gSystem->ExpandPathName(ifile.c_str()));
609  std::unique_ptr<TFile> rootFile(TFile::Open(fname.get(), "READ"));
610  if (!rootFile) {
611  ATH_MSG_ERROR("No ROOT file found here: " << ifile);
612  return 0;
613  }
614  // Loop over all directories inside the root file (correspond to the run
615  // number ranges
616  TIter nextdir(rootFile->GetListOfKeys());
617  TKey* dir = nullptr;
618  TObject* obj = nullptr;
619  while ((dir = (TKey*)nextdir())) {
620  obj = dir->ReadObj();
621  if (obj->IsA()->InheritsFrom("TDirectory")) {
622  // splits string by delimiter --> e.g RunNumber1_RunNumber2
623  std::unique_ptr<TObjArray> dirNameArray(
624  TString(obj->GetName()).Tokenize("_"));
625  // returns index of last string --> if one, the directory name does not
626  // contain any run numbers
627  int lastIdx = dirNameArray->GetLast();
628  if (lastIdx != 1) {
630  "The folder name seems to have the wrong format! Directory name:"
631  << obj->GetName());
632  return 0;
633  }
634  rootFile->cd(obj->GetName());
635  if (0 == this->setupHistogramsInFolder(*dirNameArray, lastIdx)) {
636  ATH_MSG_ERROR("Unable to setup the histograms in directory "
637  << dir->GetName() << "in file " << ifile);
638  return 0;
639  }
640  } else {
641  ATH_MSG_ERROR("Wrong file content! Expected only Directories "
642  << gDirectory->cd());
643  return 0;
644  }
645  // Return to the original ROOT directory
647  } // End: directory loop
648  } // End: file loop
649  return 1;
650 }
651 /*
652  * Get the input histograms from a given folder/run number range
653  */
654 int
656  const TObjArray& dirNameArray,
657  int lastIdx)
658 {
659 
660  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
661  << "Entering funtion setupHistogramsInFolder");
662 
663  int runNumBegin(-1);
664  TString myBegRunNumString =
665  ((TObjString*)dirNameArray.At(lastIdx - 1))->GetString();
666  if (myBegRunNumString.IsDigit()) {
667  runNumBegin = myBegRunNumString.Atoi();
668  }
669  int runNumEnd(-1);
670  TString myEndRunNumString =
671  ((TObjString*)dirNameArray.At(lastIdx))->GetString();
672  if (myEndRunNumString.IsDigit()) {
673  runNumEnd = myEndRunNumString.Atoi();
674  }
675  if (runNumBegin < 0 || runNumEnd < 0 || runNumEnd < runNumBegin) {
676  ATH_MSG_ERROR(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
677  << "Could NOT interpret the run number range: "
678  << runNumBegin << " - " << runNumEnd);
679  return 0;
680  }
682  //--> e.g. "sf" index 0 ,
683  std::vector<std::vector<TH1*>> objsFull(mapkey::end);
684  std::vector<std::vector<TH1*>> objsFast(mapkey::end);
685  // Vector to hold the N~16 systematic variations
686  std::vector<std::vector<TH1*>> sysObjsFull;
687  std::vector<std::vector<TH1*>> sysObjsFast;
688  TIter nextkey(gDirectory->GetListOfKeys());
689  TKey* key = nullptr;
690  TObject* obj = nullptr;
691  int seenSystematics = 0;
692  // Loop of the keys
693  while ((key = (TKey*)nextkey())) {
694  obj = key->ReadObj();
695  if (obj->IsA()->InheritsFrom("TH1")) {
696  // The histogram containing the scale factors need to end with _sf and
697  // need to contain either the string "FullSim" or "AtlFast"!
698  if (std::strstr(obj->GetName(), "FullSim") != nullptr) {
699  setupTempMapsHelper(
700  static_cast<TH1*>(obj), objsFull, sysObjsFull, seenSystematics);
701  } else if (std::strstr(obj->GetName(), "AtlFast") != nullptr) {
702  setupTempMapsHelper(
703  static_cast<TH1*>(obj), objsFast, sysObjsFast, seenSystematics);
704  } else {
705  ATH_MSG_ERROR("Could NOT interpret if the histogram: "
706  << obj->GetName() << " is full or fast simulation!");
707  return 0;
708  }
709  }
710  }
711  ATH_MSG_DEBUG(" (file: " << __FILE__ << ", line: " << __LINE__ << ")\n"
712  << "Setting up histograms for Run range "
713  << runNumEnd);
714  // Copy from the temporaries to the actual member variables
715  // via the setup function
716  for (int key : s_keys) {
717  if (!objsFull.at(key).empty()) {
718  if (0 == setup(objsFull.at(key),
719  m_histList[key],
720  m_begRunNumberList,
721  m_endRunNumberList,
722  runNumBegin,
723  runNumEnd)) {
724  ATH_MSG_ERROR("! Could NOT setup histogram " << key
725  << " for full sim!");
726  return 0;
727  }
728  }
729  if (!objsFast.at(key).empty()) {
730  if (0 == setup(objsFast.at(key),
731  m_fastHistList[key],
732  m_begRunNumberListFastSim,
733  m_endRunNumberListFastSim,
734  runNumBegin,
735  runNumEnd)) {
736  ATH_MSG_ERROR("! Could NOT setup histogram " << key << " for fast sim");
737  return 0;
738  }
739  }
740  }
741  m_fastSysList.resize(sysObjsFast.size());
742  for (unsigned int sys = 0; sys < sysObjsFast.size(); sys++) {
743  if (0 == setup(sysObjsFast.at(sys),
744  m_fastSysList[sys],
745  m_begRunNumberListFastSim,
746  m_endRunNumberListFastSim,
747  runNumBegin,
748  runNumEnd)) {
749  ATH_MSG_ERROR("! Could NOT setup systematic histograms for fast sim");
750  return 0;
751  }
752  }
753  m_sysList.resize(sysObjsFull.size());
754  for (unsigned int sys = 0; sys < sysObjsFull.size(); sys++) {
755  if (0 == setup(sysObjsFull.at(sys),
756  m_sysList[sys],
757  m_begRunNumberList,
758  m_endRunNumberList,
759  runNumBegin,
760  runNumEnd)) {
761  ATH_MSG_ERROR("! Could NOT setup systematic histograms for fast sim");
762  return 0;
763  }
764  }
765  //Histogram edges
766  fillHistEdges(m_histList.at(mapkey::sf), m_histEdges);
767  fillHistEdges(m_fastHistList.at(mapkey::sf), m_fastHistEdges);
768 
769  // Toys
770  if (m_doToyMC || m_doCombToyMC) {
771  bool fullToysBooked =
772  setupUncorrToySyst(objsFull, sysObjsFull, m_uncorrToyMCSystFull);
773  bool fastToysBooked =
774  setupUncorrToySyst(objsFast, sysObjsFast, m_uncorrToyMCSystFast);
775  if (fullToysBooked || fastToysBooked) {
776  if (m_doToyMC) {
777  ATH_MSG_DEBUG("Created tables for " << m_nToyMC
778  << " ToyMC systematics ");
779  }
780  if (m_doCombToyMC) {
781  ATH_MSG_DEBUG("Created tables for " << m_nToyMC
782  << " combined ToyMC systematics ");
783  }
784  }
785  }
786  return 1;
787 }
788 /*
789  * Helper for Setting up the temporary/intermediate maps
790  * from the histos
791  */
792 void
794  TH1* obj,
795  std::vector<std::vector<TH1*>>& objs,
796  std::vector<std::vector<TH1*>>& sysObjs,
797  int& seenSystematics)
798 {
799  // Add all except the correlated
800  for (int key : s_keys) {
801  if (TString(obj->GetName())
802  .EndsWith("_" + TString(mapkey::keytostring(key)))) {
803  objs.at(key).emplace_back(obj);
804  }
805  }
806 
807  const TString tmpName(obj->GetName());
808  // Special treatment , this is only for photons
809  if (tmpName.EndsWith("_sys")) {
810  objs.at(mapkey::sys).emplace_back(obj);
811  std::vector<TH1*> tmpArray;
812  // clone
813  tmpArray.emplace_back(static_cast<TH1*>(obj->Clone()));
814  sysObjs.emplace_back(tmpArray);
815  seenSystematics++;
816  }
817  // See if we are dealing with correlated
818  if (tmpName.Contains("_corr")) {
819  /*
820  * corr0 in the name triggers a few things
821  * We assume that 0 is the 1st
822  * histogram in a series of corr(i) that
823  * we see for each of the vector entries that
824  * can be one for LowPt,Standard,Forward etc
825  */
826  if (tmpName.EndsWith("corr0")) {
827  // 1st create a TObjectArray
828  std::vector<TH1*> tmpArray;
829  // Register it to the vector
830  sysObjs.emplace_back(tmpArray);
831  // Reset the counter here
832  seenSystematics = 0;
833  }
834  /*
835  * Now we can add to the TObjeArray
836  * This can be Low Pt or high Pt
837  */
838  sysObjs.back().emplace_back(obj);
839  //Increase the counter
840  seenSystematics++;
841  }
842 
843  if (seenSystematics > m_nSysMax) {
844  m_nSysMax = seenSystematics;
845  }
846 }
847 /*
848  * Helper for Setting up the uncorrelated syst for the toys
849  */
850 bool
852  std::vector<std::vector<TH1*>>& objs,
853  std::vector<std::vector<TH1*>>& sysObjs,
854  std::vector<std::vector<HistArray>>& uncorrToyMCSyst)
855 {
856  bool toysBooked = false;
857  if (!m_histList[mapkey::sf].empty()) {
858  if (objs.at(mapkey::eig).empty() || objs.at(mapkey::stat).empty() ||
859  objs.at(mapkey::uncorr).empty()) {
860 
861  if (objs.at(mapkey::stat).size() > 1 || objs.at(mapkey::sys).size() > 1) {
862 
863  uncorrToyMCSyst.push_back(buildToyMCTable(
864  objs.at(mapkey::sf), {}, objs.at(mapkey::stat), {}, sysObjs));
865  toysBooked = true;
866  }
867  } else {
868  uncorrToyMCSyst.push_back(buildToyMCTable(objs.at(mapkey::sf),
869  objs.at(mapkey::eig),
870  objs.at(mapkey::stat),
871  objs.at(mapkey::uncorr),
872  sysObjs));
873  toysBooked = true;
874  }
875  }
876  return toysBooked;
877 }
878 /*
879  * Fill and interpret the setup, depending
880  * on which histograms are found in the input file(s)
881  */
882 int
884  const std::vector<TH1*>& hists,
885  std::vector<HistArray>& histList,
886  std::vector<unsigned int>& beginRunNumberList,
887  std::vector<unsigned int>& endRunNumberList,
888  const int runNumBegin,
889  const int runNumEnd) const
890 {
891  if (hists.empty()) {
892  ATH_MSG_ERROR("! Could NOT find histogram with name *_sf in folder");
893  return 0;
894  }
895  TH1* tmpHist(nullptr);
896  HistArray tmpArray;
897  for (const auto& hist : hists) {
898  tmpHist = static_cast<TH1*>(hist);
899  tmpHist->SetDirectory(nullptr);
900  tmpArray.emplace_back(tmpHist);
901  }
902  histList.emplace_back(std::move(tmpArray));
903  // Now, we have all the needed info. Fill the vectors accordingly
904  if (!beginRunNumberList.empty()) {
905  if (runNumBegin != (int)beginRunNumberList.back()) {
906  beginRunNumberList.push_back(runNumBegin);
907  }
908  } else {
909  beginRunNumberList.push_back(runNumBegin);
910  }
911  if (!endRunNumberList.empty()) {
912  if (runNumEnd != (int)endRunNumberList.back()) {
913  endRunNumberList.push_back(runNumEnd);
914  }
915  } else {
916  endRunNumberList.push_back(runNumEnd);
917  }
918  return 1;
919 }
920 
921 
923  const std::vector<HistArray>& sfPerPeriodHist,
924  std::vector<std::vector<HistEdge>>& sfPerPeriodEdges) {
925 
926  for (const auto& vec : sfPerPeriodHist) {
927  const size_t vecSize = vec.size();
928  std::vector<HistEdge> periodVec;
929  periodVec.reserve(vecSize);
930  for (size_t i = 0; i < vecSize; ++i) {
931  const auto* tmpHist = static_cast<TH2*>(vec[i].get());
932  const auto* const xAxis = tmpHist->GetXaxis();
933  const auto* yAxis = tmpHist->GetYaxis();
934  HistEdge histEdge;
935  histEdge.etaMax = yAxis->GetXmax();
936  histEdge.etaMin = yAxis->GetXmin();
937  histEdge.etMax = xAxis->GetXmax();
938  histEdge.etMin = xAxis->GetXmin();
939  histEdge.isLowPt =
940  (std::strstr(tmpHist->GetName(), LowPt_string) != nullptr);
941 
942  periodVec.emplace_back(histEdge);
943  }
944  sfPerPeriodEdges.emplace_back(std::move(periodVec));
945  }
946 }
947 
TestSUSYToolsAlg.ifile
ifile
Definition: TestSUSYToolsAlg.py:92
Root::TElectronEfficiencyCorrectionTool::HistEdge::etaMin
double etaMin
Definition: TElectronEfficiencyCorrectionTool.h:159
et
Extra patterns decribing particle interation process.
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
mapkey::keytostring
const char * keytostring(int input)
Definition: TElectronEfficiencyCorrectionTool.cxx:46
Root::TElectronEfficiencyCorrectionTool::setupUncorrToySyst
bool setupUncorrToySyst(std::vector< std::vector< TH1 * >> &objs, std::vector< std::vector< TH1 * >> &sysObjs, std::vector< std::vector< HistArray >> &uncorrToyMCSyst)
Definition: TElectronEfficiencyCorrectionTool.cxx:851
mapkey::uncorr
@ uncorr
Definition: TElectronEfficiencyCorrectionTool.cxx:41
index
Definition: index.py:1
plotmaker.hist
hist
Definition: plotmaker.py:148
PATCore::ParticleDataType::Fast
@ Fast
Definition: PATCoreEnums.h:22
asg
Definition: DataHandleTestTool.h:28
bin
Definition: BinsDiffFromStripMedian.h:43
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
PATCore::ParticleDataType::DataType
DataType
Definition: PATCoreEnums.h:22
Root::TElectronEfficiencyCorrectionTool::HistEdge::isLowPt
bool isLowPt
Definition: TElectronEfficiencyCorrectionTool.h:162
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Root::TElectronEfficiencyCorrectionTool::Result
Definition: TElectronEfficiencyCorrectionTool.h:42
fitman.tmpHist
def tmpHist(what, wmin=-1e10, wmax=+1e10)
Definition: fitman.py:146
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
lumiFormat.i
int i
Definition: lumiFormat.py:92
Root::TElectronEfficiencyCorrectionTool::HistEdge::etaMax
double etaMax
Definition: TElectronEfficiencyCorrectionTool.h:158
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
mapkey
Definition: TElectronEfficiencyCorrectionTool.cxx:32
mergePhysValFiles.origDir
origDir
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:24
checkFileSG.objs
list objs
Definition: checkFileSG.py:93
Root::TElectronEfficiencyCorrectionTool::buildSingleToyMC
std::vector< TH2 * > buildSingleToyMC(const TH2 *sf, const TH2 *stat, const TH2 *uncorr, const std::vector< TH1 * > &corr, int &randomCounter)
Definition: TElectronEfficiencyCorrectionTool.cxx:389
Root::TElectronEfficiencyCorrectionTool::getHistograms
int getHistograms()
Load all histograms from the input file(s)
Definition: TElectronEfficiencyCorrectionTool.cxx:579
mapkey::end
@ end
Definition: TElectronEfficiencyCorrectionTool.cxx:43
makeComparison.rootFile
rootFile
Definition: makeComparison.py:27
jobOptions.isFastSim
string isFastSim
Definition: jobOptions.py:54
mapkey::eig
@ eig
Definition: TElectronEfficiencyCorrectionTool.cxx:40
TH2
Definition: rootspy.cxx:373
DeMoScan.runnumber
runnumber
Definition: DeMoScan.py:266
beamspotman.dir
string dir
Definition: beamspotman.py:623
Root::TElectronEfficiencyCorrectionTool::initialize
int initialize()
Initialize this class.
Definition: TElectronEfficiencyCorrectionTool.cxx:87
dumpTgcDigiJitter.nBins
list nBins
Definition: dumpTgcDigiJitter.py:29
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
Root::TElectronEfficiencyCorrectionTool::setup
int setup(const std::vector< TH1 * > &hists, std::vector< HistArray > &histList, std::vector< unsigned int > &beginRunNumberList, std::vector< unsigned int > &endRunNumberList, const int runNumBegin, const int runNumEnd) const
Fill and interpret the setup, depending on which histograms are found in the input file(s)
Definition: TElectronEfficiencyCorrectionTool.cxx:883
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
Root::TElectronEfficiencyCorrectionTool::buildToyMCTable
std::vector< HistArray > buildToyMCTable(const std::vector< TH1 * > &sf, const std::vector< TH1 * > &eig, const std::vector< TH1 * > &stat, const std::vector< TH1 * > &uncorr, const std::vector< std::vector< TH1 * >> &corr)
Definition: TElectronEfficiencyCorrectionTool.cxx:476
Root::TElectronEfficiencyCorrectionTool::HistArray
std::vector< std::unique_ptr< TH1 > > HistArray
Definition: TElectronEfficiencyCorrectionTool.h:39
Root::TElectronEfficiencyCorrectionTool::fillHistEdges
static void fillHistEdges(const std::vector< HistArray > &sfPerPeriodHist, std::vector< std::vector< HistEdge >> &sfPerPeriodEdges)
Definition: TElectronEfficiencyCorrectionTool.cxx:922
mapkey::stat
@ stat
Definition: TElectronEfficiencyCorrectionTool.cxx:39
python.AthDsoLogger.fname
string fname
Definition: AthDsoLogger.py:67
Root::TElectronEfficiencyCorrectionTool::HistEdge::etMin
double etMin
Definition: TElectronEfficiencyCorrectionTool.h:161
DeMoScan.index
string index
Definition: DeMoScan.py:362
readCCLHist.int
int
Definition: readCCLHist.py:84
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
Root::TElectronEfficiencyCorrectionTool::setupTempMapsHelper
void setupTempMapsHelper(TH1 *obj, std::vector< std::vector< TH1 * >> &objs, std::vector< std::vector< TH1 * >> &sysObjs, int &seenSystematics)
Definition: TElectronEfficiencyCorrectionTool.cxx:793
Root::TElectronEfficiencyCorrectionTool::TElectronEfficiencyCorrectionTool
TElectronEfficiencyCorrectionTool(const char *name="TElectronEfficiencyCorrectionTool")
Standard constructor.
Definition: TElectronEfficiencyCorrectionTool.cxx:72
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Root::TElectronEfficiencyCorrectionTool::HistEdge
Definition: TElectronEfficiencyCorrectionTool.h:157
Root::TElectronEfficiencyCorrectionTool::getNbins
int getNbins(std::map< float, std::vector< float >> &ptEta) const
Helpers to get the binning of the uncertainties in a std::map (pt, eta)
Definition: TElectronEfficiencyCorrectionTool.cxx:538
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
TH1
Definition: rootspy.cxx:268
entries
double entries
Definition: listroot.cxx:49
setup
bool setup(asg::AnaToolHandle< Interface > &tool, const std::string &type)
mostly useful for athena, which will otherwise re-use the previous tool
Definition: fbtTestBasics.cxx:193
Root::TElectronEfficiencyCorrectionTool::HistEdge::etMax
double etMax
Definition: TElectronEfficiencyCorrectionTool.h:160
beamspotVtxAnalysis.hists
def hists
Definition: beamspotVtxAnalysis.py:452
TElectronEfficiencyCorrectionTool.h
Root::TElectronEfficiencyCorrectionTool::setupHistogramsInFolder
int setupHistogramsInFolder(const TObjArray &dirNameArray, int lastIdx)
Definition: TElectronEfficiencyCorrectionTool.cxx:655
python.PyAthena.obj
obj
Definition: PyAthena.py:135
Root::TElectronEfficiencyCorrectionTool::calculate
int calculate(const PATCore::ParticleDataType::DataType dataType, const unsigned int runnumber, const double cluster_eta, const double et, Result &result, const bool onlyTotal=false) const
The main calculate method: dataType PATCore::ParticleDataType::DataType (e.g DATA,...
Definition: TElectronEfficiencyCorrectionTool.cxx:152
Root::TElectronEfficiencyCorrectionTool::buildSingleCombToyMC
TH2 * buildSingleCombToyMC(const TH2 *sf, const TH2 *stat, const TH2 *uncorr, const std::vector< TH1 * > &corr, const int nSys, int &randomCounter)
Definition: TElectronEfficiencyCorrectionTool.cxx:429
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37