ATLAS Offline Software
AsgElectronChargeIDSelectorTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
16 // Include this class's header
18 
19 // STL includes
20 #include <cmath>
21 #include <cstdint>
22 #include <string>
23 #include <sstream>
24 
25 // EDM includes
26 #include "TClass.h"
27 #include "TEnv.h"
28 #include "TFile.h"
29 #include "TKey.h"
30 #include "TObjArray.h"
31 #include "TObjString.h"
32 #include "TROOT.h"
34 #include "xAODEgamma/Electron.h"
36 #include "xAODTracking/Vertex.h"
38 
42 
43 //=============================================================================
44 // Standard constructor
45 //=============================================================================
46 AsgElectronChargeIDSelectorTool::AsgElectronChargeIDSelectorTool(
47  const std::string& myname)
48  : AsgTool(myname) //,m_cutOnBDT(0)//,m_configFile("")//,m_rootTool(0)
49 {
50  // Declare the needed properties
51  declareProperty("WorkingPoint", m_WorkingPoint = "", "The Working Point");
52  // declareProperty("ConfigFile",m_configFile="","The config file to use");
54  "usePVContainer", m_usePVCont = true, "Whether to use the PV container");
56  "nPVdefault", m_nPVdefault = 0, "The default number of PVs if not counted");
57  // declareProperty("primaryVertexContainer",
58  // m_primVtxContKey="PrimaryVertices", "The primary vertex container name" );
59 
60  declareProperty("TrainingFile",
61  m_trainingFile = "",
62  "The input ROOT file name holding training");
63  declareProperty("CutOnBDT", m_cutOnBDT = 0, "Cut on BDT discriminant");
64  m_pid_name = myname.data();
65 }
66 
67 //=============================================================================
68 // Standard destructor
69 //=============================================================================
71 {
72  for (auto* bdt : m_v_bdts)
73  if (bdt)
74  delete bdt;
75 }
76 
77 //=============================================================================
78 // Asgena initialize method
79 //=============================================================================
82 {
83  m_pid_name.ToLower(); // KM: List of 97% OPs with different PIDs below
84  std::string op_name = "loose";
85  bool op_isUserSpecified = false;
86  if (m_cutOnBDT == 0) { // when cutOnBDT is unmodified, adjust it to the 97% OP
87  // in each PID menu
88  if (m_pid_name.Contains("tight"))
89  op_name = "tight", m_cutOnBDT = -0.109249; // Tight (with data):
90  // -0.109249
91  else if (m_pid_name.Contains("medium"))
92  op_name = "medium",
93  m_cutOnBDT = -0.257081; // Medium (with data): -0.257081
94  else
95  m_cutOnBDT = -0.337671; // Loose (with data): -0.337671
96  } else
97  op_isUserSpecified = true;
98  m_pid_name = "loose"; // Now only one training is provided, using loose PID
99  // but OP varies for differnt PID
100 
101  std::string display =
102  op_isUserSpecified ? "user specified" : "97% signal-eff";
103  ATH_MSG_INFO("OP to use: " << op_name << ", with cut on BDT: " << m_cutOnBDT
104  << ", which corresponds to " << display
105  << " working point.");
106 
107  std::string TrainingFile;
108  if (!m_trainingFile
109  .empty()) { // If the property was set by the user, take that.
110 
112  if (TrainingFile.empty()) { // Error if it cant find the conf
113  ATH_MSG_ERROR("Could not locate " << m_trainingFile);
114  return StatusCode::FAILURE;
115  } else
116  ATH_MSG_INFO("trainingfile loaded from: " << TrainingFile);
117 
118  } else {
119  ATH_MSG_ERROR("Could not find configuration file: \"" << m_trainingFile
120  << "\"");
121  return StatusCode::FAILURE;
122  }
123 
124  unsigned nfold = 1;
125  std::unique_ptr<TFile> bdtfile(TFile::Open(TrainingFile.data(),"READ"));
126  if (!bdtfile) {
127  ATH_MSG_ERROR("Input file found to be empty!! " << TrainingFile);
128  return StatusCode::FAILURE;
129  } else {
130  TIter next(bdtfile->GetListOfKeys());
131  TKey* key;
132  while ((key = (TKey*)next())) {
133  TClass* clas = gROOT->GetClass(key->GetClassName());
134  if (!clas->InheritsFrom("TDirectoryFile"))
135  continue;
136  TDirectory* td = (TDirectoryFile*)key->ReadObj();
137  std::string dirName = td->GetName();
138  if (dirName.find(m_pid_name) != std::string::npos) {
139  std::string foldconf = dirName.substr(dirName.rfind('_') + 1);
140  std::string s_nfold = foldconf.substr(foldconf.find('o') + 1);
141  nfold = atoi(s_nfold.data());
142  break;
143  }
144  }
145  }
146  ATH_MSG_INFO("ECIDS nfold configuration: " << nfold);
147 
148  m_inputVars.clear();
149  const TString toaPath = Form("ECIDS_%s_0o%d/variables",m_pid_name.Data(),nfold);
150  const TObjArray* toa = bdtfile->Get<TObjArray>(toaPath);
151  if (toa) {
152  const TObjString* tos = dynamic_cast<const TObjString*>(toa->At(0));
153  if (tos) {
154  std::istringstream commaSepVars(tos->GetString().Data());
155  ATH_MSG_INFO("Variables for ECIDS " << commaSepVars.str());
156  std::string inVar;
157  while (std::getline(commaSepVars,inVar,',')) {
158  m_inputVars.push_back(inVar);
159  ATH_MSG_VERBOSE("Variables for ECIDS (check) " << inVar);
160  }
161  }
162  }
163  if (m_inputVars.empty()) {
164  ATH_MSG_FATAL("Cannot access the list of input variables @"
165  << bdtfile->GetName() << " " << toaPath);
166  }
167 
168  for (unsigned i_fold = 0; i_fold < nfold; i_fold++) {
169  TString treename = Form("ECIDS_%s_%do%d/BDT",m_pid_name.Data(),i_fold,nfold);
170  TTree* tree = (TTree*)bdtfile->Get(treename);
171  ATH_MSG_VERBOSE("Trying to access a ttree with name: " << treename << " " << tree);
172  m_v_bdts.push_back(new MVAUtils::BDT(tree));
173  }
174 
176 
177  // Setup primary vertex key handle
179 
180  m_cutPosition_bdt = m_acceptInfo.addCut("bdt", "pass bdt");
181 
182  return StatusCode::SUCCESS;
183 }
184 
185 //=============================================================================
186 // The main accept method: the actual cuts are applied here
187 //=============================================================================
190  const xAOD::Electron* eg,
191  double mu) const
192 {
193 
194  double bdt = calculate(ctx, eg, mu);
195 
196  ATH_MSG_VERBOSE("\t accept( ctx, el, mu ), bdt=" << bdt);
197 
198  asg::AcceptData acceptBDT(&m_acceptInfo);
199  acceptBDT.clear();
200 
201  acceptBDT.setCutResult(m_cutPosition_bdt, bdt > m_cutOnBDT);
202 
203  return acceptBDT;
204 }
205 
206 //=============================================================================
207 // Accept method for EFCaloLH in the trigger; do full LH if !CaloCutsOnly
208 //=============================================================================
211  const xAOD::Egamma* eg,
212  double mu) const
213 {
214  double bdt = calculate(ctx, eg, mu);
215 
216  ATH_MSG_VERBOSE("\t accept( ctx, eg, mu ), bdt=" << bdt);
217 
218  asg::AcceptData acceptBDT(&m_acceptInfo);
219  acceptBDT.clear();
220 
221  acceptBDT.setCutResult(m_cutPosition_bdt, bdt > m_cutOnBDT);
222 
223  return acceptBDT;
224 }
225 
226 //=============================================================================
227 // The main result method: the actual likelihood is calculated here
228 //=============================================================================
229 double
231  const xAOD::Electron* eg,
232  double mu) const
233 {
234 
236  "\t AsgElectronChargeIDSelectorTool::calculate( &ctx, *eg, mu= "
237  << (&ctx) << ", " << eg << ", " << mu << " )");
238 
239  if (!eg) {
240  ATH_MSG_ERROR("Failed, no egamma object.");
241  return -1;
242  }
243 
244  const xAOD::CaloCluster* cluster = eg->caloCluster();
245  if (!cluster) {
246  ATH_MSG_ERROR("Failed, no cluster.");
247  return -1;
248  }
249 
250  const double energy = cluster->e();
251  const float eta = cluster->etaBE(2);
252  if (fabs(eta) > 300.0) {
253  ATH_MSG_ERROR("Failed, eta range.");
254  return -1;
255  }
256 
257  double et = 0.; // transverse energy of the electron (using the track eta)
258  if (eg->trackParticle())
259  et = (cosh(eg->trackParticle()->eta()) != 0.)
260  ? energy / cosh(eg->trackParticle()->eta())
261  : 0.;
262  else
263  et = (cosh(eta) != 0.) ? energy / cosh(eta) : 0.;
264 
265  // number of track hits and other track quantities
266  uint8_t nSCT(0);
267  float trackqoverp(0.0);
268  float trackqoverpsig(0.0);
269  int charge(0.0);
270  int lifeSign(0.0);
271  float trackchi2(0.0);
272  float avgCharge_SCTw(0.0);
273  float d0(0.0);
274  float z0(0.0);
275  float phi0(0.0);
276  float theta(0.0);
277  float EoverP(0.0);
278  float d0sigma(0.0);
279  double dpOverp(0.0);
280  float TRT_PID(0.0);
281  // double trans_TRT_PID(0.0);
282  float deltaPhi1 = 0, deltaPhi2 = 0;
283  float deltaPhiFromLM = 0;
284  float deltaPhiRescaled2 = 0; // deltaEta=0,
285  // double rTRT(0.0);
286 
287  TVector2 el_cluster;
288  el_cluster.SetMagPhi(cluster->energyBE(2) / cosh(eta), cluster->phiBE(2));
289 
290  bool allFound = true;
291  // retrieve associated TrackParticle
292  const xAOD::TrackParticle* t = eg->trackParticle();
293  if (t) {
294  trackqoverp = t->qOverP();
295  charge = t->charge();
296  d0 = t->d0();
297 
298  if (std::find(m_inputVars.begin(), m_inputVars.end(), "z0sinTheta") !=
299  m_inputVars.end()) {
300  z0 = t->z0();
301  theta = t->theta();
302  }
303 
304  if (std::find(m_inputVars.begin(), m_inputVars.end(), "chi2oftrackfit") !=
305  m_inputVars.end())
306  trackchi2 = t->chiSquared();
307 
308  phi0 = t->phi() + (d0 >= 0 ? M_PI / 2 : -M_PI / 2);
309  TVector2 d0_direction;
310  d0_direction.SetMagPhi(fabs(d0), phi0);
311  float inner_product =
312  el_cluster.X() * d0_direction.X() + el_cluster.Y() * d0_direction.Y();
313  lifeSign = inner_product >= 0 ? 1 : -1;
314 
315  EoverP = energy * fabs(t->qOverP());
316  if (std::find(m_inputVars.begin(), m_inputVars.end(), "d0Err") !=
317  m_inputVars.end() or
318  std::find(m_inputVars.begin(), m_inputVars.end(), "d0Sig") !=
319  m_inputVars.end()) {
320  float vard0 = t->definingParametersCovMatrix()(0, 0);
321  if (vard0 > 0) {
322  d0sigma = sqrtf(vard0);
323  }
324  }
325 
326  // KM: calculation of SCT-weighted charge
327  float charge = 0, SCT = 0;
328  for (unsigned TPit = 0; TPit < eg->nTrackParticles(); TPit++) {
329  uint8_t temp_NSCTHits;
330  if (eg->trackParticle(TPit)) {
331  eg->trackParticle(TPit)->summaryValue(temp_NSCTHits,
333 
334  SCT += temp_NSCTHits;
335  charge += temp_NSCTHits * eg->trackParticle(TPit)->charge();
336  } else
337  ATH_MSG_WARNING("This electron has no track particle associated!!! "
338  "Assigning #SCT-hits= 0!!! ");
339  }
340  avgCharge_SCTw = SCT != 0 ? eg->charge() * charge / SCT : 0;
341 
342  const std::vector<float>& cov = t->definingParametersCovMatrixVec();
343  trackqoverpsig = cov[14];
344 
345  if (std::find(m_inputVars.begin(), m_inputVars.end(), "nSctHits") !=
346  m_inputVars.end())
347  allFound = allFound && t->summaryValue(nSCT, xAOD::numberOfSCTHits);
348 
349  // Transform the TRT PID output for use in the LH tool.
350  double fEpsilon = 1.0e-30; // to avoid zero division
351  double pid_tmp = TRT_PID;
352  if (pid_tmp >= 1.0)
353  pid_tmp = 1.0 - 1.0e-15; // this number comes from TMVA
354  else if (pid_tmp <= fEpsilon)
355  pid_tmp = fEpsilon;
356 
357  if (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaPoverP") !=
358  m_inputVars.end()) {
359  unsigned int index;
360  if (t->indexOfParameterAtPosition(index, xAOD::LastMeasurement)) {
361 
362  double refittedTrack_LMqoverp =
363  t->charge() / sqrt(std::pow(t->parameterPX(index), 2) +
364  std::pow(t->parameterPY(index), 2) +
365  std::pow(t->parameterPZ(index), 2));
366 
367  dpOverp = 1 - trackqoverp / (refittedTrack_LMqoverp);
368  }
369  }
370 
371  } else {
372  allFound = false;
373  ATH_MSG_WARNING("Failed, no track particle: et= " << et << "eta= " << eta);
374  }
375 
376  float Rphi(0); // float Reta(0), Rphi(0), Rhad1(0), Rhad(0), ws3(0), w2(0),
377  // f1(0), Eratio(0), f3(0);
378  allFound =
379  allFound &&
380  eg->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi); // rphi e233/e237
381  // allFound = allFound && eg->trackCaloMatchValue(deltaEta,
382  // xAOD::EgammaParameters::deltaEta1);
383 
384  // difference between the cluster phi (sampling 2) and the eta of the track
385  // extrapolated from the last measurement point.
386  allFound = allFound &&
387  eg->trackCaloMatchValue(deltaPhiRescaled2,
389 
390  // if(m_map_inputs.find("deltaphi1" )!= m_map_inputs.end())
391  if (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaphi1") !=
392  m_inputVars.end())
393  allFound = allFound && eg->trackCaloMatchValue(
395  // if(m_map_inputs.find("deltaphi2" )!= m_map_inputs.end() or
396  // m_map_inputs.find("deltaDeltaPhiFirstAndLM")!= m_map_inputs.end())
397  if (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaphi2") !=
398  m_inputVars.end() or
399  std::find(m_inputVars.begin(),
400  m_inputVars.end(),
401  "deltaDeltaPhiFirstAndLM") != m_inputVars.end())
402  allFound = allFound && eg->trackCaloMatchValue(
404  // if(m_map_inputs.find("deltaDeltaPhiFirstAndLM")!= m_map_inputs.end())
405  if (std::find(m_inputVars.begin(),
406  m_inputVars.end(),
407  "deltaDeltaPhiFirstAndLM") != m_inputVars.end())
408  allFound =
409  allFound &&
410  eg->trackCaloMatchValue(
412 
413  // Get the number of primary vertices in this event
414  // double ip = static_cast<double>(m_nPVdefault);
415  // if(mu < 0) // use npv if mu is negative (not given)
416  // ip = static_cast<double>(m_usePVCont ? this->getNPrimVertices() :
417  // m_nPVdefault);
418  // else ip = mu;
419 
420  if (!allFound)
421  ATH_MSG_FATAL("Missing input variable for ECIDS BDT calculation");
422 
423  const xAOD::EventInfo* eventInfo = nullptr;
424  if (evtStore()->retrieve(eventInfo, "EventInfo").isFailure())
425  ATH_MSG_WARNING(" Cannot access to event info ");
426  // lumiBlock = eventInfo->lumiBlock(), runNumber = eventInfo->runNumber(),
427  // eventNumber=eventInfo->eventNumber();
428  // ATH_MSG_DEBUG("event_num%bdt_size="<<eventInfo->eventNumber()<<"%"<<unsigned(m_v_bdts.size())<<"=
429  // "<<eventInfo->eventNumber()%unsigned(m_v_bdts.size()));
430  unsigned bdt_index = eventInfo->eventNumber() % unsigned(m_v_bdts.size());
431 
432  std::vector<float> v_inputs;
433  for (const auto& var : m_inputVars) {
434  if (var == "pt")
435  v_inputs.push_back(et);
436  if (var == "eta")
437  v_inputs.push_back(eta);
438  if (var == "abs_eta")
439  v_inputs.push_back(fabs(eta));
440  if (var == "avgCharge_SCTw")
441  v_inputs.push_back(avgCharge_SCTw);
442  if (var == "d0")
443  v_inputs.push_back(d0);
444  if (var == "ld0")
445  v_inputs.push_back(lifeSign * d0);
446  if (var == "cd0")
447  v_inputs.push_back(charge * d0);
448  if (var == "EoverP")
449  v_inputs.push_back(EoverP);
450  if (var == "deltaphi1")
451  v_inputs.push_back(deltaPhi1);
452  if (var == "deltaphiRes")
453  v_inputs.push_back(deltaPhiRescaled2);
454  if (var == "Rphi")
455  v_inputs.push_back(Rphi);
456  if (var == "qoverpSig")
457  v_inputs.push_back(trackqoverpsig);
458  if (var == "nSctHits")
459  v_inputs.push_back(nSCT);
460  if (var == "z0sinTheta")
461  v_inputs.push_back(z0 * sin(theta));
462  if (var == "d0Err")
463  v_inputs.push_back(d0sigma);
464  if (var == "d0Sig")
465  v_inputs.push_back(d0 / d0sigma);
466  if (var == "deltaphi2")
467  v_inputs.push_back(deltaPhi2);
468  if (var == "chi2oftrackfit")
469  v_inputs.push_back(trackchi2);
470  if (var == "deltaPoverP")
471  v_inputs.push_back(dpOverp);
472  if (var == "deltaDeltaPhiFirstAndLM")
473  v_inputs.push_back(deltaPhi2 - deltaPhiFromLM);
474  }
475 
477  "\t\t event# "
478  << eventInfo->eventNumber() << std::endl
479  << "xAOD variables: pt = " << et
480  << ",\t isRequested= "
481  << (std::find(m_inputVars.begin(), m_inputVars.end(), "pt") !=
482  m_inputVars.end())
483  << std::endl
484  << "\t\t xAOD variables: eta = " << eta
485  << ",\t isRequested= "
486  << (std::find(m_inputVars.begin(), m_inputVars.end(), "eta") !=
487  m_inputVars.end())
488  << std::endl
489  << "\t\t xAOD variables: abs_eta = " << fabs(eta)
490  << ",\t isRequested= "
491  << (std::find(m_inputVars.begin(), m_inputVars.end(), "abs_eta") !=
492  m_inputVars.end())
493  << std::endl
494  << "\t\t xAOD variables: avgCharge_SCTw = " << avgCharge_SCTw
495  << ",\t isRequested= "
496  << (std::find(m_inputVars.begin(), m_inputVars.end(), "avgCharge_SCTw") !=
497  m_inputVars.end())
498  << std::endl
499  << "\t\t xAOD variables: d0 = " << d0
500  << ",\t isRequested= "
501  << (std::find(m_inputVars.begin(), m_inputVars.end(), "d0") !=
502  m_inputVars.end())
503  << std::endl
504  << "\t\t xAOD variables: ld0 = " << lifeSign * d0
505  << ",\t isRequested= "
506  << (std::find(m_inputVars.begin(), m_inputVars.end(), "ld0") !=
507  m_inputVars.end())
508  << std::endl
509  << "\t\t xAOD variables: cd0 = " << charge * d0
510  << ",\t isRequested= "
511  << (std::find(m_inputVars.begin(), m_inputVars.end(), "cd0") !=
512  m_inputVars.end())
513  << std::endl
514  << "\t\t xAOD variables: EoverP = " << EoverP
515  << ",\t isRequested= "
516  << (std::find(m_inputVars.begin(), m_inputVars.end(), "EoverP") !=
517  m_inputVars.end())
518  << std::endl
519  << "\t\t xAOD variables: deltaphi1 = " << deltaPhi1
520  << ",\t isRequested= "
521  << (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaphi1") !=
522  m_inputVars.end())
523  << std::endl
524  << "\t\t xAOD variables: deltaphiRes = " << deltaPhiRescaled2
525  << ",\t isRequested= "
526  << (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaphiRes") !=
527  m_inputVars.end())
528  << std::endl
529  << "\t\t xAOD variables: Rphi = " << Rphi
530  << ",\t isRequested= "
531  << (std::find(m_inputVars.begin(), m_inputVars.end(), "Rphi") !=
532  m_inputVars.end())
533  << std::endl
534  << "\t\t xAOD variables: qoverpSig = " << trackqoverpsig
535  << ",\t isRequested= "
536  << (std::find(m_inputVars.begin(), m_inputVars.end(), "qoverpSig") !=
537  m_inputVars.end())
538  << std::endl
539  << "\t\t xAOD variables: nSctHits = " << unsigned(nSCT)
540  << ",\t isRequested= "
541  << (std::find(m_inputVars.begin(), m_inputVars.end(), "nSctHits") !=
542  m_inputVars.end())
543  << std::endl
544  << "\t\t xAOD variables: z0sinTheta = " << z0 * sin(theta)
545  << ",\t isRequested= "
546  << (std::find(m_inputVars.begin(), m_inputVars.end(), "z0sinTheta") !=
547  m_inputVars.end())
548  << std::endl
549  << "\t\t xAOD variables: d0Err = " << d0sigma
550  << ",\t isRequested= "
551  << (std::find(m_inputVars.begin(), m_inputVars.end(), "d0Err") !=
552  m_inputVars.end())
553  << std::endl
554  << "\t\t xAOD variables: d0Sig = " << d0 / d0sigma
555  << ",\t isRequested= "
556  << (std::find(m_inputVars.begin(), m_inputVars.end(), "d0Sig") !=
557  m_inputVars.end())
558  << std::endl
559  << "\t\t xAOD variables: deltaphi2 = " << deltaPhi2
560  << ",\t isRequested= "
561  << (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaphi2") !=
562  m_inputVars.end())
563  << std::endl
564  << "\t\t xAOD variables: chi2oftrackfit = " << trackchi2
565  << ",\t isRequested= "
566  << (std::find(m_inputVars.begin(), m_inputVars.end(), "chi2oftrackfit") !=
567  m_inputVars.end())
568  << std::endl
569  << "\t\t xAOD variables: deltaPoverP = " << dpOverp
570  << ",\t isRequested= "
571  << (std::find(m_inputVars.begin(), m_inputVars.end(), "deltaPoverP") !=
572  m_inputVars.end())
573  << std::endl
574  << "\t\t xAOD variables: deltaDeltaPhiFirstandLM = "
575  << deltaPhi2 - deltaPhiFromLM << ",\t isRequested= "
576  << (std::find(m_inputVars.begin(),
577  m_inputVars.end(),
578  "deltaDeltaPhiFirstAndLM") != m_inputVars.end())
579  << std::endl
580  << "\t\t xAOD variables: AllFound = " << allFound);
581 
583  // std::cout<<"\t\t event# "<<eventInfo->eventNumber()<<std::endl;
584  // unsigned i=0;
585  // for (auto inputVar: m_inputVars) {
586  // std::cout<<"\t kmdebug: "<<inputVar<<"\t = "<<v_inputs[i]<<std::endl;
587  // i++;
588  // }
589 
590  // double bdt_output =
591  // m_v_bdts.at(bdt_index)->GetGradBoostMVA(m_v_bdts.at(bdt_index)->GetPointers());
592  double bdt_output = m_v_bdts.at(bdt_index)->GetGradBoostMVA(v_inputs);
593  ATH_MSG_DEBUG("ECIDS-BDT= " << bdt_output);
594  // std::cout<<"\t kmdebug: \t ECIDS-BDT= "<<bdt_output<<std::endl;
595 
596  return bdt_output;
597 }
598 
599 double
601  const xAOD::Egamma* eg,
602  double mu) const
603 {
604  if (eg->type() == xAOD::Type::Electron) {
605  const xAOD::Electron* el = static_cast<const xAOD::Electron*>(eg);
606  return calculate(ctx, el, mu);
607  }
608  ATH_MSG_ERROR("Input is not an electron!!");
609  return -19;
610 }
611 
612 //=============================================================================
615 {
616  // Backward compatibility
617  return accept(Gaudi::Hive::currentContext(), part);
618 }
621  const xAOD::IParticle* part) const
622 {
623  if (part->type() == xAOD::Type::Electron) {
624  const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
625  return accept(ctx, el);
626  }
627  ATH_MSG_ERROR("Input is not an electron");
628  return asg::AcceptData(&m_acceptInfo);
629 }
630 
631 double
633  const xAOD::IParticle* part) const
634 {
635  if (part->type() == xAOD::Type::Electron) {
636  const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
637  return calculate(ctx, el);
638  }
639  ATH_MSG_ERROR("Input is not an electron!!");
640  return -19;
641 }
642 
643 //=============================================================================
644 // Helper method to get the number of primary vertices
645 // We don't want to iterate over all vertices in the event for each electron!!!
646 //=============================================================================
647 unsigned int
649 {
650  unsigned int nVtx(0);
652  if (!vtxCont.isValid()) {
653  ATH_MSG_WARNING("Cannot find " << m_primVtxContKey.key()
654  << " container, returning default nVtx");
655  return m_nPVdefault;
656  }
657  for (const auto *vxcand : *vtxCont) {
658  if (vxcand->nTrackParticles() >= 2)
659  nVtx++;
660  }
661  return nVtx;
662 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
AsgElectronChargeIDSelectorTool::m_cutPosition_bdt
int m_cutPosition_bdt
Definition: AsgElectronChargeIDSelectorTool.h:143
et
Extra patterns decribing particle interation process.
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
AsgElectronChargeIDSelectorTool::m_nPVdefault
unsigned int m_nPVdefault
defualt nPV (when not using PVCont)
Definition: AsgElectronChargeIDSelectorTool.h:155
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
ParticleTest.eg
eg
Definition: ParticleTest.py:29
CurrentContext.h
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
tree
TChain * tree
Definition: tile_monitor.h:30
AsgElectronChargeIDSelectorTool::getNPrimVertices
unsigned int getNPrimVertices(const EventContext &ctx) const
Get the number of primary vertices.
Definition: AsgElectronChargeIDSelectorTool.cxx:648
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
M_PI
#define M_PI
Definition: ActiveFraction.h:11
MVAUtils::BDT
Simplified Boosted Regression Tree, support TMVA, lgbm, and xgboost.
Definition: BDT.h:34
xAOD::CaloCluster_v1::phiBE
float phiBE(const unsigned layer) const
Get the phi in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:680
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
xAOD::EgammaParameters::Rphi
@ Rphi
e233/e237
Definition: EgammaEnums.h:156
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
xAOD::LastMeasurement
@ LastMeasurement
Parameter defined at the position of the last measurement.
Definition: TrackingPrimitives.h:215
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
xAOD::unsigned
unsigned
Definition: RingSetConf_v1.cxx:662
AsgElectronChargeIDSelectorTool::m_acceptInfo
asg::AcceptInfo m_acceptInfo
Definition: AsgElectronChargeIDSelectorTool.h:144
xAOD::EgammaParameters::deltaPhi1
@ deltaPhi1
difference between the cluster eta (1st sampling) and the eta of the track extrapolated to the 1st sa...
Definition: EgammaEnums.h:196
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
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
xAOD::EgammaParameters::deltaPhiFromLastMeasurement
@ deltaPhiFromLastMeasurement
difference between the cluster phi (sampling 2) and the eta of the track extrapolated from the last m...
Definition: EgammaEnums.h:210
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
AsgElectronChargeIDSelectorTool::m_trainingFile
std::string m_trainingFile
The input ROOT file name that holds the PDFs.
Definition: AsgElectronChargeIDSelectorTool.h:166
AsgElectronChargeIDSelectorTool::~AsgElectronChargeIDSelectorTool
virtual ASG_TOOL_CLASS2(AsgElectronChargeIDSelectorTool, IAsgElectronLikelihoodTool, IAsgSelectionTool) public ~AsgElectronChargeIDSelectorTool()
Standard constructor.
Definition: AsgElectronChargeIDSelectorTool.cxx:70
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
AsgElectronChargeIDSelectorTool::initialize
virtual StatusCode initialize() override
Gaudi Service Interface method implementations.
Definition: AsgElectronChargeIDSelectorTool.cxx:81
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
CaloCluster.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
PyAlgorithmExample.EoverP
int EoverP
Definition: PyAlgorithmExample.py:122
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::EgammaParameters::deltaPhiRescaled2
@ deltaPhiRescaled2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
Definition: EgammaEnums.h:225
AsgElectronChargeIDSelectorTool::m_primVtxContKey
SG::ReadHandleKey< xAOD::VertexContainer > m_primVtxContKey
The primary vertex container name.
Definition: AsgElectronChargeIDSelectorTool.h:158
AsgElectronChargeIDSelectorTool::accept
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override final
Method to get the plain AcceptInfo.
Definition: AsgElectronChargeIDSelectorTool.cxx:614
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
Vertex.h
pyroot.display
display
Definition: pyroot.py:44
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
SCT
Definition: SCT_ChipUtils.h:14
PathResolver.h
ReadHandle.h
Handle class for reading from StoreGate.
charge
double charge(const T &p)
Definition: AtlasPID.h:494
xAOD::EgammaParameters::deltaPhi2
@ deltaPhi2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
Definition: EgammaEnums.h:204
AsgElectronChargeIDSelectorTool::m_inputVars
std::vector< std::string > m_inputVars
Definition: AsgElectronChargeIDSelectorTool.h:169
xAOD::Electron_v1
Definition: Electron_v1.h:34
AsgElectronChargeIDSelectorTool::calculate
virtual double calculate(const EventContext &ctx, const xAOD::IParticle *part) const override final
The main result method: the actual likelihood is calculated here.
Definition: AsgElectronChargeIDSelectorTool.cxx:632
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
DeMoScan.index
string index
Definition: DeMoScan.py:362
VertexContainer.h
asg::AcceptData::setCutResult
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer)
Definition: AcceptData.h:134
asg::AcceptData::clear
void clear()
Clear all bits.
Definition: AcceptData.h:54
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::CaloCluster_v1::energyBE
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:630
AsgElectronChargeIDSelectorTool.h
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
AsgElectronChargeIDSelectorTool::m_usePVCont
bool m_usePVCont
Whether to use the PV (not available for trigger)
Definition: AsgElectronChargeIDSelectorTool.h:152
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
Electron.h
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AsgElectronChargeIDSelectorTool::m_pid_name
TString m_pid_name
Definition: AsgElectronChargeIDSelectorTool.h:140
AsgElectronChargeIDSelectorTool::m_v_bdts
std::vector< MVAUtils::BDT * > m_v_bdts
Definition: AsgElectronChargeIDSelectorTool.h:138
asg::AcceptData
Definition: AcceptData.h:30
AsgElectronChargeIDSelectorTool::m_cutOnBDT
float m_cutOnBDT
Definition: AsgElectronChargeIDSelectorTool.h:141
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
asg::AcceptInfo::addCut
int addCut(const std::string &cutName, const std::string &cutDescription)
Add a cut; returning the cut position.
Definition: AcceptInfo.h:53
SCT
@ SCT
Definition: RegSelEnums.h:25
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37