ATLAS Offline Software
ElectronChargeEfficiencyCorrectionTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
13 // Include this class's header
16 // xAOD includes
18 #include "xAODEgamma/Electron.h"
21 
22 // ROOT includes
23 #include "TFile.h"
24 
25 // STL includes
26 #include <cstdlib> /* atoi */
27 
28 // =============================================================================
29 // Standard constructor
30 // =============================================================================
31 CP::ElectronChargeEfficiencyCorrectionTool::
32  ElectronChargeEfficiencyCorrectionTool(const std::string& name)
33  : AsgTool(name)
34  , m_dataTypeOverwrite(-1)
35  , m_eventInfoCollectionName("EventInfo")
36  , m_SF_SS()
37  , m_SF_OS()
38  , m_RunNumbers()
39  , m_useRandomRunNumber(true)
40  , m_defaultRandomRunNumber(999999)
41  , m_filename("")
42  , m_workingPoint("")
43  , m_eta_lowlimit(0.0)
44  , m_eta_uplimit(0.0)
45  , m_pt_lowlimit(0.0)
46  , m_pt_uplimit(0.0)
47  , m_gevmev(0.0)
48  , m_filtered_sys_sets()
49  , m_mySysConf()
50  , m_affectingSys()
51  , m_appliedSystematics(nullptr)
52  , m_sf_decoration_name("chargeIDEffiSF")
53  , m_sfDec(nullptr)
54 {
55  // Declare the needed properties
56  declareProperty("CorrectionFileName",
57  m_filename,
58  "Name of the file with charge flipping rates");
60  "WorkingPoint", m_workingPoint, "Name of working point folder in the file");
61  declareProperty("ScaleFactorDecorationName", m_sf_decoration_name);
62  declareProperty("ForceDataType",
63  m_dataTypeOverwrite,
64  "Force the DataType of the electron to specified value (to "
65  "circumvent problem of incorrect DataType for forward "
66  "electrons in some old releases)");
67  declareProperty("EventInfoCollectionName",
68  m_eventInfoCollectionName,
69  "The EventInfo Collection Name");
70  declareProperty("UseRandomRunNumber", m_useRandomRunNumber);
71  declareProperty("DefaultRandomRunNumber", m_defaultRandomRunNumber);
72 }
73 
74 // =============================================================================
75 // Standard destructor
76 // =============================================================================
79 {
80  if (m_sfDec)
81  delete m_sfDec;
82 }
83 
84 // =============================================================================
85 // Athena initialize method
86 // =============================================================================
89 {
90  ATH_MSG_DEBUG("initializing");
91 
92  // initialize the random number generator (used in case of charge flip
93  // approach)
94  // m_Rndm = new TRandom3(1);
95 
96  if (m_sfDec)
97  delete m_sfDec;
98  m_sfDec = new SG::AuxElement::Decorator<float>(m_sf_decoration_name); // xxxx
99 
100  // Resolve the path to the input file for the charge flip rates
101  const std::string rootfilename = PathResolverFindCalibFile(m_filename);
102  if (m_filename.empty()) {
103  ATH_MSG_ERROR(" PathResolver was not able to find the file ... aborting");
104  return StatusCode::FAILURE;
105  }
106 
107  // Getting the root file and histograms
108  TFile* rootFile = TFile::Open(rootfilename.c_str());
109 
110  // protection against bad file
111  if (rootFile == nullptr) {
112  ATH_MSG_ERROR(" Was not able to open file: " << rootfilename
113  << " ...... aborting");
114  return StatusCode::FAILURE;
115  }
116 
118  //
119  // explanation: attempt to loop generally over a file
120  // -- if certain SINGALWORD is present -- then this is taken as a signal,
121  // that this is another dimension... can be dynamically added.
122  // e.g.
123  // SFSyst<number>_RunNumber<minRN>-<maxRN>_Nvtx<minNvtx>-<maxNvtx>
124  // SFStat_RunNumber<minRN>-<maxRN>_Nvtx<minNvtx>-<maxNvtx>
125  // SFCentral_RunNumber<minRN>-<maxRN>_Nvtx<minNvtx>-<maxNvtx>
126 
127  // Then can create a key that will dynamically give us access to a map:
128  // std::map<std::string key, std::vector<TH2 *>> m_SF_SS; // keys (e.g.
129  // RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of SF
130  // histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
131  // std::map<std::string key, std::vector<TH2 *>> m_SF_OS; // keys
132  // (e.g. RunNumber223333_319200_Nvtx0_10_Phi1.5_1.6) mapping to vector of
133  // SF histograms --> vector m_SF: 0=nominal, 1=stat, 2,3,4...n=syst
134  // TFile* data/ChMisIDSF_TightLL_FixedCutTight.root
135  // KEY: TH2F SFCentral_RunNumber296939_311481_SS;1
136  // SFCentral_RunNumber296939_311481_SS KEY: TH2F
137  // SFCentral_RunNumber296939_311481_OS;1 SFCentral_RunNumber296939_311481_OS
138  // KEY: TH2F STAT_RunNumber296939_311481_SS;1
139  // STAT_RunNumber296939_311481_SS KEY: TH2F STAT_RunNumber296939_311481_OS;1
140  // STAT_RunNumber296939_311481_OS KEY: TH2F
141  // SYST_RunNumber296939_311481_total_SS;1 SYST_RunNumber296939_311481_SS:
142  // total KEY: TH2F SYST_RunNumber296939_311481_total_OS;1
143  // SYST_RunNumber296939_311481_OS: total
144 
145  m_SF_SS.clear();
146  m_SF_OS.clear();
147  TList* keyListfolder = rootFile->GetListOfKeys();
148  std::vector<std::string> names;
149  std::set<std::string> set_systematics;
150 
151  names.reserve(keyListfolder->GetEntries());
152  for (int j = 0; j < keyListfolder->GetEntries(); j++) {
153  names.emplace_back((keyListfolder->At(j)->GetName()));
154  }
155  std::sort(names.begin(), names.end());
156 
157  for (unsigned int j = 0; j < names.size(); j++) {
158 
159  std::string name = names.at(j);
160  ATH_MSG_DEBUG("Got ROOT object with name: " << name);
161  if (name.find(Form("SFCentral_")) != std::string::npos) {
162  ATH_MSG_VERBOSE("Found name 'SFCentral_' in ROOT object name");
163  // Check for opposite-sign (=opposite-charge)
164  bool isOS = false;
165  if (name.find(Form("_OS")) != std::string::npos) {
166  isOS = true;
167  ATH_MSG_VERBOSE("Found name '_OS' in ROOT object name");
168  }
169  if (isOS) {
170  std::string histid = (names.at(j));
171  histid.erase(0, 10);
172  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
173  ATH_MSG_VERBOSE("Using histid: " << histid);
174 
175  if (histid.find("RunNumber") != std::string::npos) {
176  ATH_MSG_VERBOSE("Found name 'RunNumber' in histid");
177  std::string runlow = histid;
178  runlow.erase(histid.find(Form("RunNumber")), 9);
179  runlow.erase(runlow.find('_'), runlow.size());
180  m_RunNumbers.push_back(
181  static_cast<unsigned int>(atoi(runlow.c_str())));
182  std::string runhigh = histid;
183  runhigh.erase(histid.find(Form("RunNumber")), 9);
184  runhigh.erase(0, runhigh.find('_') + 1);
185  m_RunNumbers.push_back(
186  static_cast<unsigned int>(atoi(runhigh.c_str())));
187  }
188  ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
189  m_SF_OS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
190  } else {
191  std::string histid = (names.at(j));
192  histid.erase(0, 10);
193  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
194  ATH_MSG_VERBOSE("Using histid (do we this in ? SS): " << histid);
195  m_SF_SS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
196  }
197  }
198 
200  if (name.find(Form("STAT_")) != std::string::npos) {
201  ATH_MSG_VERBOSE("Found name 'STAT_' in ROOT object name");
202  bool isOS = false;
203  if (name.find(Form("_OS")) != std::string::npos) {
204  isOS = true;
205  ATH_MSG_VERBOSE("Found name '_OS' in ROOT object name");
206  }
207  if (isOS) {
208  std::string histid = (names.at(j));
209  histid.erase(0, 5);
210  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
211  ATH_MSG_VERBOSE("Using histid: " << histid);
212 
213  if (histid.find("RunNumber") != std::string::npos) {
214  ATH_MSG_VERBOSE("Found name 'RunNumber' in histid");
215  std::string runlow = histid;
216  runlow.erase(histid.find(Form("RunNumber")), 9);
217  runlow.erase(runlow.find('_'), runlow.size());
218  // m_RunNumbers.push_back( static_cast<unsigned
219  // int>(atoi(runlow.c_str())) );
220  std::string runhigh = histid;
221  runhigh.erase(histid.find(Form("RunNumber")), 9);
222  runhigh.erase(0, runhigh.find('_') + 1);
223  // m_RunNumbers.push_back( static_cast<unsigned
224  // int>(atoi(runhigh.c_str())) );
225  }
226  ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
227  m_SF_OS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
228  } else {
229  std::string histid = (names.at(j));
230  ATH_MSG_VERBOSE("Found histid: " << histid);
231  histid.erase(0, 5);
232  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
233  ATH_MSG_VERBOSE("Using histid (do we this in ? SS): " << histid);
234  m_SF_SS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
235  }
236 
237  }
238 
240  if (name.find(Form("SYST")) != std::string::npos) {
241  ATH_MSG_VERBOSE("Found name 'SYST' in ROOT object name");
242  bool isOS = false;
243  if (name.find(Form("_OS")) != std::string::npos) {
244  isOS = true;
245  ATH_MSG_VERBOSE("Found name '_OS' in ROOT object name");
246  }
247  if (isOS) {
248  std::string histid = (names.at(j));
249  histid.erase(0, 4);
250  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
251 
252  std::string sysname = histid;
253  sysname.erase(sysname.find('_'), sysname.size());
254  set_systematics.insert(sysname);
255 
256  histid.erase(0, histid.find('_') + 1); // remove _SS, _OS
257  ATH_MSG_VERBOSE("Using syst histid: " << histid);
258 
259  if (histid.find("RunNumber") != std::string::npos) {
260  std::string runlow = histid;
261  runlow.erase(histid.find(Form("RunNumber")), 9);
262  runlow.erase(runlow.find('_'), runlow.size());
263  // m_RunNumbers.push_back( static_cast<unsigned
264  // int>(atoi(runlow.c_str())) );
265  std::string runhigh = histid;
266  runhigh.erase(histid.find(Form("RunNumber")), 9);
267  runhigh.erase(0, runhigh.find('_') + 1);
268  // m_RunNumbers.push_back( static_cast<unsigned
269  // int>(atoi(runhigh.c_str())) );
270  }
271  ATH_MSG_VERBOSE("Using histid (OS hid): " << histid);
272  m_SF_OS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
273  } else {
274  std::string histid = (names.at(j));
275  histid.erase(0, 4);
276  histid.erase(histid.size() - 3, 3); // remove _SS, _OS
277  histid.erase(0, histid.find('_') + 1); // remove _SS, _OS
278  ATH_MSG_VERBOSE("Using histid (sys ? SS): " << histid);
279  m_SF_SS[histid].push_back((TH2*)rootFile->Get(names.at(j).c_str()));
280  }
281 
282  }
283  }
284 
286 
287  if (m_SF_OS.empty() || m_SF_SS.empty() || m_SF_SS.size() != m_SF_OS.size()) {
289  "OS/SS SF vectors not filled or of different size. -- Problem with "
290  "files. -- Report to <hn-atlas-EGammaWG@cern.ch>");
291  return StatusCode::FAILURE;
292  }
293 
294  m_systematics.insert(m_systematics.end(), set_systematics.begin(), set_systematics.end());
295 
296  std::sort(m_RunNumbers.begin(), m_RunNumbers.end());
298  // Determine the limits of validity
299 
301  ATH_MSG_DEBUG("Having m_SF_OS.size() = " << m_SF_OS.size());
302  std::map<std::string, std::vector<TH2*>>::iterator it = m_SF_OS.begin();
303 
304  // Get the kinematic limits
305  m_eta_lowlimit = (*it).second.at(0)->GetYaxis()->GetXmin();
306  m_eta_uplimit = (*it).second.at(0)->GetYaxis()->GetXmax();
307  ATH_MSG_VERBOSE("|eta| limits " << m_eta_lowlimit << ", " << m_eta_uplimit);
308 
309  m_pt_lowlimit = (*it).second.at(0)->GetXaxis()->GetXmin();
310  m_pt_uplimit = (*it).second.at(0)->GetXaxis()->GetXmax();
311  ATH_MSG_VERBOSE("pt limits " << m_pt_lowlimit << ", " << m_pt_uplimit);
312 
313  // Check if the input file is in GeV or MeV
314  if (m_pt_uplimit > 1500) {
315  ATH_MSG_VERBOSE("Rates in input file are in MeV");
316  m_gevmev = 1.;
317  } else {
318  ATH_MSG_VERBOSE("Rates in input file are in GeV");
319  m_gevmev = 0.001;
320  }
321 
322  // Systematics // dynamic too?
323  m_affectingSys = affectingSystematics();
324 
325  // Add the recommended systematics to the registry
326  if (registerSystematics() != StatusCode::SUCCESS) {
327  ATH_MSG_ERROR("(registerSystematics() != CP::SystematicCode::Ok)");
328  return StatusCode::FAILURE;
329  }
330 
331  return StatusCode::SUCCESS;
332 }
333 
334 
335 //---------------------------------------------------------------------------------------
336 // Get the scale factor for the electron
337 //---------------------------------------------------------------------------------------
338 
339 //
340 
343  const xAOD::Electron& ele,
344  double& sf) const
345 {
346 
347  // initialize the SF at 1
348  sf = 1.0;
349 
350  // checking on the truth electron: up to now if this is not a good ele it's
351  // returning
352  bool goodEle = false;
353  CP::CorrectionCode goodEle_result =
354  ElectronEfficiencyHelpers::isGoodEle( ele, goodEle);
355  if (goodEle_result != CP::CorrectionCode::Ok) {
356  sf = -999.0;
357  ATH_MSG_DEBUG("This is the check of goodeleCC in getscalefactor. Scale "
358  "factor set to -999");
359  return goodEle_result;
360  }
361 
362  if (!goodEle) {
363  // electron is background electron and should not be corrected
364  return CP::CorrectionCode::Ok;
365  ATH_MSG_DEBUG("Here goodele is false but CC ok");
366  }
367 
368  // taking reconstructed variables
369  int reco_ele_charge = ele.charge();
370  const double ele_pt = ele.pt() * m_gevmev;
371  const double ele_eta = std::abs(ele.caloCluster()->etaBE(2));
372 
373  // getting the truth charge
374  int truth_ele_charge = 9999;
375  CP::CorrectionCode charge_result =
376  ElectronEfficiencyHelpers::getEleTruthCharge( ele, truth_ele_charge);
377  if (charge_result != CP::CorrectionCode::Ok) {
378  sf = -9999.0;
379  ATH_MSG_VERBOSE("This is check of geteletruthchargeCC in getscalefactor. "
380  "Scale factor set to -9999");
381  return charge_result;
382  }
383 
384  if (truth_ele_charge == 0) {
385  ATH_MSG_DEBUG("Here truth charge is =0!!");
386  return CP::CorrectionCode::Ok;
387  }
388 
389  ATH_MSG_DEBUG("Reco charge = " << reco_ele_charge
390  << "; Truth charge = " << truth_ele_charge);
391 
392  // getting the rates from file....
393  float retVal(0.0);
394 
396  // here determine, WHICH of the [histid] to choose (after cuuts on runnumber
397  // etc....)
398  std::string cutRunNumber = "all";
399 
400  if (!m_RunNumbers.empty()) {
401  unsigned int runnumber = m_defaultRandomRunNumber;
402  ATH_MSG_DEBUG("RandomRunNumber: " << runnumber << " "
403  << m_useRandomRunNumber);
404  if (m_useRandomRunNumber) {
405  const xAOD::EventInfo* eventInfo =
406  evtStore()->retrieve<const xAOD::EventInfo>(m_eventInfoCollectionName);
407  if (!eventInfo) {
408  ATH_MSG_ERROR("Could not retrieve EventInfo object!");
409  sf = 1.0;
411  }
412  static const SG::AuxElement::Accessor<unsigned int> randomrunnumber(
413  "RandomRunNumber");
414  if (!randomrunnumber.isAvailable(*eventInfo)) {
415  sf = 1.0;
417  "Pileup tool not run before using ElectronEfficiencyTool! SFs do not "
418  "reflect PU distribution in data");
420  }
421  runnumber = randomrunnumber(*(eventInfo));
422  }
423  ATH_MSG_DEBUG("Number of RunNumbers in file: " << m_RunNumbers.size());
424  for (std::size_t r = 0; r < m_RunNumbers.size(); r++) {
425  ATH_MSG_DEBUG( " - " << m_RunNumbers.at(r));
426  }
427  ATH_MSG_VERBOSE("DONE");
428 
429  bool isInRunNumberRange = false;
430  for ( std::size_t r=0; r<m_RunNumbers.size()-1; r+=2 ){
431  // increment by two, run numbers always come in pairs (upper and lower bound specified in the histogram name)
432 
433  if ( runnumber >= (unsigned int)m_RunNumbers.at(r) &&
434  runnumber <= (unsigned int)m_RunNumbers.at(r+1) ) {
435  cutRunNumber.clear();
436  cutRunNumber =
437  Form("RunNumber%d_%d", m_RunNumbers.at(r), m_RunNumbers.at(r + 1));
438  ATH_MSG_DEBUG("Random run number lies in range " << m_RunNumbers.at(r) << " " << m_RunNumbers.at(r+1));
439  isInRunNumberRange = true;
440  }
441  }
442 
443  if (runnumber < m_RunNumbers.at(0) ||
444  (runnumber > m_RunNumbers.at(m_RunNumbers.size() - 1))) {
445  ATH_MSG_DEBUG("RunNumber " << runnumber << " is not in valid RunNumber Range ");
446  sf = 1.0;
448  }
449 
450  if ( !isInRunNumberRange ) {
452  }
453  }
454 
455  // check if electron is within recommendations in eta/Et
456  if ( ele_eta < m_eta_lowlimit || ele_eta > m_eta_uplimit ) {
457 
458  ATH_MSG_DEBUG("Got an electron outside of the range of eta validity " << ele_eta);
460  }
461 
462  if ( ele_pt < m_pt_lowlimit ) {
463 
464  ATH_MSG_DEBUG("Got an electron outside of the range of pt validity: pt lower than lower limit");
466  }
467 
468  // Determine WHICH histograms to use here
469  const std::vector<TH2*>& SShistograms = m_SF_SS.at(cutRunNumber.c_str());
470  const std::vector<TH2*>& OShistograms = m_SF_OS.at(cutRunNumber.c_str());
471 
472  // here check OS or SS
473  bool isOS = false;
474 
475  if (truth_ele_charge * reco_ele_charge > 0)
476  isOS = true;
477 
478  if (isOS) {
479  retVal = this->getChargeFlipRate(ele_eta, ele_pt, OShistograms.at(0), sf);
480  if (retVal != 0) {
481  sf = -9999.0;
483  }
484  } else {
485  ATH_MSG_DEBUG("Get SS his");
486  retVal = this->getChargeFlipRate(ele_eta, ele_pt, SShistograms.at(0), sf);
487  if (retVal != 0) {
488  sf = -9999.0;
490  }
491  }
492 
493  ATH_MSG_DEBUG("eta: " << ele_eta << " pt: " << ele_pt);
494  ATH_MSG_DEBUG("SF Rates---- . SF: " << sf);
495 
496  // Systematics
497  // ------------------------------------------------------------------------------------------------------
498  double val_stat;
499 
501  if (isOS) {
502  retVal =
503  this->getChargeFlipRate(ele_eta, ele_pt, OShistograms.at(1), val_stat);
504  if (retVal != 0) {
505  sf = -9999.0;
507  }
508  } else {
509  ATH_MSG_DEBUG("Get SS his");
510  retVal =
511  this->getChargeFlipRate(ele_eta, ele_pt, SShistograms.at(1), val_stat);
512  if (retVal != 0) {
513  sf = -9999.0;
515  }
516  }
517 
518  std::vector<float> systs;
519  double val_sys{ 0.0 };
521  for (unsigned int s = 2; s < OShistograms.size(); s++) {
522  if (isOS) {
523  retVal =
524  this->getChargeFlipRate(ele_eta, ele_pt, OShistograms.at(s), val_sys);
525  if (retVal != 0) {
526  val_sys = -9999.0;
528  }
529  } else {
530  ATH_MSG_DEBUG("Get SS his");
531  retVal =
532  this->getChargeFlipRate(ele_eta, ele_pt, SShistograms.at(s), val_sys);
533  if (retVal != 0) {
534  val_sys = -9999.0;
536  }
537  }
538  systs.push_back(static_cast<float>(val_sys));
539  }
540 
541  ATH_MSG_DEBUG(" ... nominal SF: " << sf);
542 
543  if (m_mySysConf.empty()) {
544  ATH_MSG_DEBUG(" ... nominal SF: " << sf);
545  } else if (*(m_mySysConf.begin()) ==
546  SystematicVariation("EL_CHARGEID_STAT", 1)) {
547  sf = (sf + (val_stat));
548  ATH_MSG_DEBUG("SF after STATup = " << sf);
549  } else if (*(m_mySysConf.begin()) ==
550  SystematicVariation("EL_CHARGEID_STAT", -1)) {
551  sf = (sf - (val_stat));
552  ATH_MSG_DEBUG("SF after STATdown = " << sf);
553  } else {
554 
555  for (unsigned int i = 0; i < m_systematics.size(); i++) {
556  if (*(m_mySysConf.begin()) ==
558  Form("EL_CHARGEID_SYS%s", m_systematics.at(i).c_str()), 1)) {
559  sf = (sf + (val_sys));
560  ATH_MSG_DEBUG("SF after SYSup = " << sf);
561  }
562 
563  if (*(m_mySysConf.begin()) ==
565  Form("EL_CHARGEID_SYS%s", m_systematics.at(i).c_str()), -1)) {
566  sf = (sf - (val_sys));
567  ATH_MSG_DEBUG("SF after SYSdown = " << sf);
568  }
569  }
570 
571  }
572 
573  return CP::CorrectionCode::Ok;
574 }
575 
576 //---------------------------------------------------------------------------------------
577 // Decorate the electron with the scale factor
578 //---------------------------------------------------------------------------------------
579 
582  const xAOD::Electron& part) const
583 {
585  "In "
586  "CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor("
587  "const xAOD::IParticle& part) const");
588  double sf = 0.0;
589  CP::CorrectionCode result = this->getEfficiencyScaleFactor(part, sf);
590  // Decorate the electron
591  (*m_sfDec)(part) = static_cast<float>(sf);
592  return result;
593 }
594 
595 // Get the correction rate given pt (E), eta, histogram
596 float
598  double eta,
599  double pt,
600  TH2* hrates,
601  double& flipRate) const
602 {
603  ATH_MSG_VERBOSE(" -> in: getChargeFlipRate(" << pt << ", " << eta
604  << " TH2, double&)");
605 
606  if (pt > m_pt_uplimit)
607  pt = m_pt_uplimit * 0.999;
608 
609  int bin2D = hrates->FindBin(pt, eta);
610  flipRate = hrates->GetBinContent(bin2D);
611 
612  ATH_MSG_VERBOSE(" -> flipRate is " << flipRate << ", for histogram "
613  << hrates->GetName());
614 
615  return 0;
616 }
617 
619 // returns whether this tool is affected by the given systematics
620 bool
622  const SystematicVariation& systematic) const
623 {
624 
625  CP::SystematicSet sys = affectingSystematics();
626  return sys.find(systematic) != sys.end();
627 }
628 
630 // returns the list of all systematics this tool can be affected by
631 
634 {
636  result.insert(SystematicVariation("EL_CHARGEID_STAT", 1));
637  result.insert(SystematicVariation("EL_CHARGEID_STAT", -1));
638 
639  for (unsigned int i = 0; i < m_systematics.size(); i++) {
641  Form("EL_CHARGEID_SYS%s", m_systematics.at(i).c_str()), 1));
643  Form("EL_CHARGEID_SYS%s", m_systematics.at(i).c_str()), -1));
644  }
645  return result;
646 }
647 
649 // returns the list of all systematics this tool recommends to use
652 {
653 
654  return affectingSystematics();
655 }
656 
658 // Gets a SystematicSet and filters it
661  const SystematicSet& systConfig)
662 {
663 
665  systConfig, m_affectingSys, m_mySysConf)) {
667  "Unsupported combination of systematics passed to the tool! ");
668  return StatusCode::FAILURE;
669  }
670 
671  return StatusCode::SUCCESS;
672 }
674 // Register the systematics with the registry and add them to the recommended list
677 
678  if (registry.registerSystematics(*this) != StatusCode::SUCCESS) {
679  ATH_MSG_ERROR("Failed to add systematic to list of recommended systematics.");
680  return StatusCode::FAILURE;
681  }
682 
683  return StatusCode::SUCCESS;
684 }
685 
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.Dso.registry
registry
Definition: Control/AthenaServices/python/Dso.py:159
beamspotman.r
def r
Definition: beamspotman.py:676
xAOD::Electron_v1::charge
float charge() const
Obtain the charge of the object.
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
CP::ElectronChargeEfficiencyCorrectionTool::affectingSystematics
virtual SystematicSet affectingSystematics() const override final
Returns the list of all systematics this tool can be affected by.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:633
CP::ElectronChargeEfficiencyCorrectionTool::initialize
virtual StatusCode initialize() override final
Gaudi Service Interface method implementations.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:88
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
skel.it
it
Definition: skel.GENtoEVGEN.py:423
test_pyathena.pt
pt
Definition: test_pyathena.py:11
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
ElectronChargeEfficiencyCorrectionTool.h
CP::ElectronChargeEfficiencyCorrectionTool::registerSystematics
StatusCode registerSystematics()
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:675
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CP::ElectronChargeEfficiencyCorrectionTool::getEfficiencyScaleFactor
virtual CP::CorrectionCode getEfficiencyScaleFactor(const xAOD::Electron &inputObject, double &sf) const override final
Retrieve the Scale factor.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:342
CP::SystematicVariation
Definition: SystematicVariation.h:47
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
xAOD::CaloCluster_v1::etaBE
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:644
CP::CorrectionCode::OutOfValidityRange
@ OutOfValidityRange
Input object is out of validity range.
Definition: CorrectionCode.h:37
CP::ElectronChargeEfficiencyCorrectionTool::recommendedSystematics
virtual CP::SystematicSet recommendedSystematics() const override final
Returns the list of all systematics this tool recommends to use.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:651
CP::CorrectionCode::Error
@ Error
Some error happened during the object correction.
Definition: CorrectionCode.h:36
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
lumiFormat.i
int i
Definition: lumiFormat.py:92
SystematicRegistry.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.subdetectors.mmg.names
names
Definition: mmg.py:8
CP::ElectronChargeEfficiencyCorrectionTool::applySystematicVariation
virtual StatusCode applySystematicVariation(const SystematicSet &systConfig) override final
effects: configure this tool for the given list of systematic variations.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:660
xAOD::Egamma_v1::caloCluster
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
Definition: Egamma_v1.cxx:388
makeComparison.rootFile
rootFile
Definition: makeComparison.py:27
CP::ElectronChargeEfficiencyCorrectionTool::m_sfDec
SG::AuxElement::Decorator< float > * m_sfDec
Definition: ElectronChargeEfficiencyCorrectionTool.h:173
TH2
Definition: rootspy.cxx:373
DeMoScan.runnumber
runnumber
Definition: DeMoScan.py:266
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
ElectronEfficiencyHelpers::isGoodEle
CP::CorrectionCode isGoodEle(const xAOD::Electron &ele, bool &goodEle)
Return true if it's good ele for charge flip measurements.
Definition: ElectronEfficiencyHelpers.cxx:36
CP::ElectronChargeEfficiencyCorrectionTool::isAffectedBySystematic
virtual bool isAffectedBySystematic(const SystematicVariation &systematic) const override final
Returns whether this tool is affected by the given systematics.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:621
CP::ElectronChargeEfficiencyCorrectionTool::applyEfficiencyScaleFactor
virtual CP::CorrectionCode applyEfficiencyScaleFactor(const xAOD::Electron &inputObject) const override final
Decorate the electron.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:581
xAOD::Electron_v1
Definition: Electron_v1.h:34
ElectronEfficiencyHelpers::getEleTruthCharge
CP::CorrectionCode getEleTruthCharge(const xAOD::Electron &ele, int &truthcharge)
Get the charge of the original electron.
Definition: ElectronEfficiencyHelpers.cxx:14
EventInfo.h
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
CP::CorrectionCode::Ok
@ Ok
The correction was done successfully.
Definition: CorrectionCode.h:38
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CP::ElectronChargeEfficiencyCorrectionTool::~ElectronChargeEfficiencyCorrectionTool
virtual ASG_TOOL_CLASS(ElectronChargeEfficiencyCorrectionTool, IAsgElectronEfficiencyCorrectionTool) public ~ElectronChargeEfficiencyCorrectionTool()
Standard destructor.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:78
CP::SystematicRegistry
This module implements the central registry for handling systematic uncertainties with CP tools.
Definition: SystematicRegistry.h:25
CP::CorrectionCode
Return value from object correction CP tools.
Definition: CorrectionCode.h:31
xAOD::Egamma_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: Egamma_v1.cxx:65
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Electron.h
xAOD::JetConstituentVector::iterator
Definition: JetConstituentVector.h:121
CP::ElectronChargeEfficiencyCorrectionTool::getChargeFlipRate
float getChargeFlipRate(double eta, double pt, TH2 *hrates, double &flipRate) const
Get the charge flip rate rate given pt, eta, histogram.
Definition: ElectronChargeEfficiencyCorrectionTool.cxx:597
ElectronEfficiencyHelpers.h
CP::SystematicSet::filterForAffectingSystematics
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
Definition: SystematicSet.cxx:213
CP::SystematicRegistry::getInstance
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
Definition: SystematicRegistry.cxx:25