ATLAS Offline Software
AsgElectronSelectorTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
15 // Include this class's header
20 #include "ElectronDNNCalculator.h"
21 // STL includes
22 #include <string>
23 #include <cstdint>
24 #include <cmath>
25 #include <unordered_map>
26 
27 //EDM includes
28 #include "xAODEgamma/Electron.h"
30 #include "TEnv.h"
31 
34 
36 {
37  enum e {
38  eta,
39  et,
40  f3,
45  f1,
48  d0,
49  qd0,
60  };
61 
62  const std::unordered_map<std::string, int> variableMap = {
63  {"eta", eta},
64  {"et", et},
65  {"f3", f3},
66  {"Rhad", Rhad},
67  {"Rhad1", Rhad1},
68  {"Reta", Reta},
69  {"weta2", weta2},
70  {"f1", f1},
71  {"Eratio", Eratio},
72  {"deltaEta1", deltaEta1},
73  {"d0", d0},
74  {"qd0", qd0},
75  {"d0significance", d0significance},
76  {"Rphi", Rphi},
77  {"dPOverP", dPOverP},
78  {"deltaPhiRescaled2", deltaPhiRescaled2},
79  {"trans_TRTPID", trans_TRTPID},
80  {"wtots1", wtots1},
81  {"EoverP", EoverP},
82  {"nPixHitsPlusDeadSensors", nPixHitsPlusDeadSensors},
83  {"nSCTHitsPlusDeadSensors", nSCTHitsPlusDeadSensors},
84  {"SCTWeightedCharge", SCTWeightedCharge},
85  };
86 };
87 
88 //=============================================================================
89 // Standard constructor
90 //=============================================================================
92  AsgTool(myname),
93  m_configFile{""},
94  m_mvaTool(nullptr)
95 {
96 
97  // Declare the needed properties
98  declareProperty("WorkingPoint", m_workingPoint="", "The Working Point");
99  declareProperty("ConfigFile", m_configFile="", "The config file to use");
100 
101  // model file name. Managed in the ElectronDNNCalculator.
102  declareProperty("inputModelFileName", m_modelFileName="", "The input file name that holds the model" );
103  // QuantileTransformer file name ( required for preprocessing ). Managed in the ElectronDNNCalculator.
104  declareProperty("quantileFileName", m_quantileFileName="", "The input file name that holds the QuantileTransformer");
105  // especially for trigger electron
106  declareProperty("skipDeltaPoverP",m_skipDeltaPoverP = false,"If true, it will skip the check of deltaPoverP");
107 
108  declareProperty("skipAmbiguityCut",m_skipAmbiguityCut = false,"If true, it will skip the ambiguity cut");
109 }
110 
111 
112 //=============================================================================
113 // Standard destructor
114 //=============================================================================
116 = default;
117 
118 
119 //=============================================================================
120 // Asgena initialize method
121 //=============================================================================
123 {
124  if (!m_workingPoint.empty()){
126  ATH_MSG_INFO("operating point : " << this->getOperatingPointName());
127  }
128 
129  if (m_configFile.empty()){
130  ATH_MSG_ERROR("Could not find configuration file " << m_configFile);
131  return StatusCode::FAILURE;
132  }
133 
135  if (configFile.empty()){
136  ATH_MSG_ERROR("Could not locate " << m_configFile);
137  return StatusCode::FAILURE;
138  }
139 
140 
141  ATH_MSG_DEBUG("Configfile to use: " << m_configFile);
142  TEnv env;
143  env.ReadFile(configFile.c_str(), kEnvLocal);
144 
145  std::string modelFilename("");
146  std::string quantileFilename("");
147 
148  // Get the input model in the tool.
149  ATH_MSG_DEBUG("Get the input model in the tool.");
150 
151  if (!m_modelFileName.empty()){ // If the property was set by the user, take that.
152  ATH_MSG_INFO("Setting user specified Model file: " << m_modelFileName);
153  modelFilename = m_modelFileName;
154  }
155  else {
156  modelFilename = env.GetValue("inputModelFileName", "ElectronPhotonSelectorTools/offline/mc16_20210204/ElectronDNNNetwork.json");
157  ATH_MSG_DEBUG("Getting the input Model from: " << modelFilename );
158  }
159  std::string filename = PathResolverFindCalibFile(modelFilename);
160  if (filename.empty()){
161  ATH_MSG_ERROR("Could not find model file " << modelFilename);
162  return StatusCode::FAILURE;
163  }
164 
165  // Get the input transformer in the tool.
166  ATH_MSG_DEBUG("Get the input transformer in the tool.");
167 
168  if (!m_quantileFileName.empty()){ // If the property was set by the user, take that.
169  ATH_MSG_INFO("Setting user specified QuantileTransformer file: " << m_quantileFileName);
170  quantileFilename = m_quantileFileName;
171  }
172  else {
173  quantileFilename = env.GetValue("inputQuantileFileName", "ElectronPhotonSelectorTools/offline/mc16_20210204/ElectronDNNQuantileTransformer.root");
174  ATH_MSG_DEBUG("Getting the input QuantileTransformer from: " << quantileFilename);
175  }
176  std::string qfilename = PathResolverFindCalibFile(quantileFilename);
177  if (qfilename.empty()){
178  ATH_MSG_ERROR("Could not find QuantileTransformer file " << quantileFilename);
179  return StatusCode::FAILURE;
180  }
181 
182  // Variables used in the MVA tool as comma separated string;
183  std::stringstream vars(env.GetValue("Variables", ""));
184  // parse variables string into vector
185  while(vars.good()){
186  std::string substr;
187  std::getline(vars, substr, ',');
188  m_variables.push_back( substr );
190  ATH_MSG_ERROR("Unsupported variable " << substr << " found in the config.");
191  return StatusCode::FAILURE;
192  }
193  m_enum_variables.push_back(AllowedVariables::variableMap.at(substr));
194  }
195 
196  // Model is multiclass or not, default is binary model
197  m_multiClass = env.GetValue("multiClass", false);
198  // Include cf node in numerator or denominator when combining different outputs
199  m_cfSignal = env.GetValue("cfSignal", true);
200  // Fractions to multiply different outputs with before combining
202 
203  // cut on MVA discriminant
206 
207  // cut on ambiguity bit
208  m_cutAmbiguity = AsgConfigHelper::HelperInt("CutAmbiguity", env);
209  // cut on b-layer
211  // cut on pixel hits
213  // cut on precision hits
215  // do smooth interpolation between bins
216  m_doSmoothBinInterpolation = env.GetValue("doSmoothBinInterpolation", false);
217 
218 
219 
220  unsigned int numberOfExpectedBinCombinedMVA ;
221  numberOfExpectedBinCombinedMVA = s_fnDiscEtBins * s_fnDiscEtaBins;
222  unsigned int numberOfExpectedEtaBins = s_fnDiscEtBins;
223 
224  if (m_cutSelector.size() != numberOfExpectedBinCombinedMVA){
225  ATH_MSG_ERROR("Configuration issue : cutSelector expected size " << numberOfExpectedBinCombinedMVA <<
226  " input size " << m_cutSelector.size());
227  return StatusCode::FAILURE;
228  }
229 
230  if (!m_cutSelectorCF.empty()){
231  m_CFReject = true;
232  if (m_cutSelectorCF.size() != numberOfExpectedBinCombinedMVA){
233  ATH_MSG_ERROR("Configuration issue : cutSelectorCF expected size " << numberOfExpectedBinCombinedMVA <<
234  " input size " << m_cutSelectorCF.size());
235  return StatusCode::FAILURE;
236  }
237  if(!m_multiClass){
238  ATH_MSG_ERROR("Configuration issue : CF rejection is only defined "
239  "for multiClass: TRUE");
240  return StatusCode::FAILURE;
241  }
242  }
243  else {
244  m_CFReject = false;
245  }
246  // Create an instance of the class calculating the DNN score
247  m_mvaTool = std::make_unique<ElectronDNNCalculator>(this, filename.c_str(), qfilename.c_str(), m_variables, m_multiClass);
248 
249  if (m_multiClass){
250  // Fractions are only needed if multiclass model is used
251  // There are five fractions for the combination, the signal fraction is either one (cfSignal == false) or 1 - cf fraction (cfSignal == true)
252  if (m_fractions.size() != numberOfExpectedEtaBins * 5){
253  ATH_MSG_ERROR("Configuration issue : multiclass but not the right amount of fractions." << m_fractions.size());
254  return StatusCode::FAILURE;
255  }
256  }
257 
258  if (!m_cutSCT.empty()){
259  if (m_cutSCT.size() != numberOfExpectedEtaBins){
260  ATH_MSG_ERROR("Configuration issue : cutSCT expected size " << numberOfExpectedEtaBins <<
261  " input size " << m_cutSCT.size());
262  return StatusCode::FAILURE;
263  }
264  }
265 
266  if (!m_cutPi.empty()){
267  if (m_cutPi.size() != numberOfExpectedEtaBins){
268  ATH_MSG_ERROR("Configuration issue : cutPi expected size " << numberOfExpectedEtaBins <<
269  " input size " << m_cutPi.size());
270  return StatusCode::FAILURE;
271  }
272  }
273 
274  if (!m_cutBL.empty()){
275  if (m_cutBL.size() != numberOfExpectedEtaBins){
276  ATH_MSG_ERROR("Configuration issue : cutBL expected size " << numberOfExpectedEtaBins <<
277  " input size " << m_cutBL.size());
278  return StatusCode::FAILURE;
279  }
280  }
281 
282  if (!m_cutAmbiguity.empty()){
283  if (m_cutAmbiguity.size() != numberOfExpectedEtaBins){
284  ATH_MSG_ERROR("Configuration issue : cutAmbiguity expected size " << numberOfExpectedEtaBins <<
285  " input size " << m_cutAmbiguity.size());
286  return StatusCode::FAILURE;
287  }
288  }
289 
290  // --------------------------------------------------------------------------
291  // Register the cuts and check that the registration worked:
292  // NOTE: THE ORDER IS IMPORTANT!!! Cut0 corresponds to bit 0, Cut1 to bit 1,...
293  // use an int as a StatusCode
294  int sc(1);
295 
296  // Cut position for the kineatic pre-selection
297  m_cutPosition_kinematic = m_acceptMVA.addCut("kinematic", "pass kinematic");
298  if (m_cutPosition_kinematic < 0) sc = 0;
299 
300  // NSilicon
301  m_cutPosition_NSilicon = m_acceptMVA.addCut("NSCT", "pass NSCT");
302  if (m_cutPosition_NSilicon < 0) sc = 0;
303 
304  // NPixel
305  m_cutPosition_NPixel = m_acceptMVA.addCut("NPixel", "pass NPixel");
306  if (m_cutPosition_NPixel < 0) sc = 0;
307 
308  // NBlayer
309  m_cutPosition_NBlayer = m_acceptMVA.addCut("NBlayer", "pass NBlayer");
310  if (m_cutPosition_NBlayer < 0) sc = 0;
311 
312  // Ambiguity
313  m_cutPosition_ambiguity = m_acceptMVA.addCut("ambiguity", "pass ambiguity");
314  if (m_cutPosition_ambiguity < 0) sc = 0;
315 
316 
317  // Cut position for the likelihood selection - DO NOT CHANGE ORDER!
318  m_cutPosition_MVA = m_acceptMVA.addCut("passMVA", "pass MVA");
319  if (m_cutPosition_MVA < 0) sc = 0;
320 
321  // Check that we got everything OK
322  if (sc == 0){
323  ATH_MSG_ERROR("ERROR: Something went wrong with the setup of the decision objects...");
324  return StatusCode::FAILURE;
325  }
326 
328 
329  // define a default vector to return in the calculateMultipleOutputs methods
330  // depending on the number of expected outputs
331  if (m_multiClass){
332  m_defaultVector = {-999., -999., -999., -999., -999., -999.};
333  }
334  else{
335  m_defaultVector = {-999.};
336  }
337 
338  return StatusCode::SUCCESS;
339 }
340 
341 
342 //=============================================================================
343 // return the accept info object
344 //=============================================================================
345 
347 {
348  return m_acceptMVA;
349 }
350 
351 //=============================================================================
352 // The main accept method: the actual cuts are applied here
353 //=============================================================================
354 asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const xAOD::Electron* eg, double mu ) const
355 {
356  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
357 
358  // Setup return accept with AcceptInfo
359  asg::AcceptData acceptData(&m_acceptMVA);
360 
361  if (!eg){
362  throw std::runtime_error("AsgElectronSelectorTool: Failed, no electron object was passed");
363  }
364 
365  const xAOD::CaloCluster* cluster = eg->caloCluster();
366  if (!cluster){
367  ATH_MSG_DEBUG("exiting because cluster is NULL " << cluster);
368  return acceptData;
369  }
370 
372  ATH_MSG_DEBUG("Failed, cluster is missing samplings EMB2 and EME2");
373  return acceptData;
374  }
375 
376  const double energy = cluster->e();
377  const float eta = cluster->etaBE(2);
378 
379  if(isForwardElectron(eg, eta)){
380  ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
381  return acceptData;
382  }
383 
384  const xAOD::TrackParticle* track = eg->trackParticle();
385  if (!track){
386  ATH_MSG_DEBUG("exiting because track is NULL " << track);
387  return acceptData;
388  }
389 
390  // transverse energy of the electron (using the track eta)
391  double et = (std::cosh(track->eta()) != 0.) ? energy / std::cosh(track->eta()) : 0.;
392 
393  // number of track hits
394  uint8_t nSiHitsPlusDeadSensors(0);
396  bool passBLayerRequirement(false);
397  uint8_t ambiguityBit(0);
398 
399  bool allFound = true;
400  std::string notFoundList = "";
401 
402  // get the ambiguity type from the decoration
403  if (!m_skipAmbiguityCut){
404  static const SG::AuxElement::Accessor<uint8_t> ambiguityTypeAcc("ambiguityType");
405  if (ambiguityTypeAcc.isAvailable(*eg)) {
406  ambiguityBit = ambiguityTypeAcc(*eg);
407  }
408  else {
409  allFound = false;
410  notFoundList += "ambiguityType ";
411  }
412  }
413 
417 
418  // calculate the output of the selector tool
419 
420  std::vector<float> mvaOutputs = calculateMultipleOutputs(ctx, eg, mu);
421  double mvaScore = getDiscriminant(mvaOutputs, eg);
422  ATH_MSG_VERBOSE(Form("PassVars: MVA=%8.5f, eta=%8.5f, et=%8.5f, nSiHitsPlusDeadSensors=%i, nHitsPlusPixDeadSensors=%i, passBLayerRequirement=%i, ambiguityBit=%i, mu=%8.5f",
423  mvaScore, eta, et,
424  nSiHitsPlusDeadSensors, nPixHitsPlusDeadSensors,
426  ambiguityBit, mu));
427  double mvaScoreCF = 0;
428  if (m_CFReject){
429  mvaScoreCF = combineOutputsCF(mvaOutputs);
430  ATH_MSG_VERBOSE(Form("PassVars: MVA=%8.5f, eta=%8.5f, et=%8.5f, nSiHitsPlusDeadSensors=%i, nHitsPlusPixDeadSensors=%i, passBLayerRequirement=%i, ambiguityBit=%i, mu=%8.5f",
431  mvaScoreCF, eta, et,
432  nSiHitsPlusDeadSensors, nPixHitsPlusDeadSensors,
434  ambiguityBit, mu));
435  }
436 
437  if (!allFound){
438  throw std::runtime_error("AsgElectronSelectorTool: Not all variables needed for the decision are found. The following variables are missing: " + notFoundList );
439  }
440 
441  // Set up the individual cuts
442  bool passKine(true);
443  bool passNSilicon(true);
444  bool passNPixel(true);
445  bool passNBlayer(true);
446  bool passAmbiguity(true);
447  bool passMVA(true);
448 
449  if (std::abs(eta) > 2.47){
450  ATH_MSG_DEBUG("This electron is fabs(eta)>2.47 Returning False.");
451  passKine = false;
452  }
453 
454  unsigned int etBin = getDiscEtBin(et);
455  unsigned int etaBin = getDiscEtaBin(eta);
456 
457  // sanity
458  if (etBin >= s_fnDiscEtBins){
459  ATH_MSG_DEBUG("Cannot evaluate model for Et " << et << ". Returning false..");
460  passKine = false;
461  }
462 
463  // Return if the kinematic requirements are not fulfilled
464  acceptData.setCutResult(m_cutPosition_kinematic, passKine);
465  if (!passKine){return acceptData;}
466 
467  // ambiguity bit
468  if (!m_cutAmbiguity.empty()){
470  ATH_MSG_DEBUG("MVA macro: ambiguity Bit Failed.");
471  passAmbiguity = false;
472  }
473  }
474 
475  // blayer cut
476  if (!m_cutBL.empty()) {
477  if(m_cutBL[etaBin] == 1 && !passBLayerRequirement){
478  ATH_MSG_DEBUG("MVA macro: Blayer cut failed.");
479  passNBlayer = false;
480  }
481  }
482  // pixel cut
483  if (!m_cutPi.empty()){
485  ATH_MSG_DEBUG("MVA macro: Pixels Failed.");
486  passNPixel = false;
487  }
488  }
489  // SCT cut
490  if (!m_cutSCT.empty()){
491  if (nSiHitsPlusDeadSensors < m_cutSCT[etaBin]){
492  ATH_MSG_DEBUG( "MVA macro: Silicon Failed.");
493  passNSilicon = false;
494  }
495  }
496 
497  unsigned int ibin_combinedMVA = etBin*s_fnDiscEtaBins+etaBin; // Must change if number of eta bins changes!.
498 
499  // First cut on the CF discriminant
500  // If empty, continue only with prompt ID
501  if (!m_cutSelectorCF.empty()){
502  double cutDiscriminantCF;
503  // To protect against a binning mismatch, which should never happen
504  if (ibin_combinedMVA >= m_cutSelectorCF.size()){
505  throw std::runtime_error("AsgElectronSelectorTool: The desired eta/pt bin is outside of the range specified by the input. This should never happen! This indicates a mismatch between the binning in the configuration file and the tool implementation." );
506  }
508  cutDiscriminantCF = interpolateCuts(m_cutSelectorCF, et, eta);
509  }
510  else{
511  cutDiscriminantCF = m_cutSelectorCF.at(ibin_combinedMVA);
512  }
513  // Determine if the calculated mva score value passes the combined cut
514  ATH_MSG_DEBUG("MVA macro: CF Discriminant: ");
515  if (mvaScoreCF < cutDiscriminantCF){
516  ATH_MSG_DEBUG("MVA macro: CF cut failed.");
517  passMVA = false;
518  }
519  }
520 
521 // (Second) cut on prompt discriminant
522  if (!m_cutSelector.empty()){
523  double cutDiscriminant;
524  // To protect against a binning mismatch, which should never happen
525  if (ibin_combinedMVA >= m_cutSelector.size()){
526  throw std::runtime_error("AsgElectronSelectorTool: The desired eta/pt bin is outside of the range specified by the input. This should never happen! This indicates a mismatch between the binning in the configuration file and the tool implementation." );
527  }
529  cutDiscriminant = interpolateCuts(m_cutSelector, et, eta);
530  }
531  else{
532  cutDiscriminant = m_cutSelector.at(ibin_combinedMVA);
533  }
534  // Determine if the calculated mva score value passes the combined cut
535  ATH_MSG_DEBUG("MVA macro: Prompt Discriminant: ");
536  if (mvaScore < cutDiscriminant){
537  ATH_MSG_DEBUG("MVA macro: Prompt cut failed.");
538  passMVA = false;
539  }
540  }
541 
542  // Set the individual cut bits in the return object
543  acceptData.setCutResult(m_cutPosition_NSilicon, passNSilicon);
544  acceptData.setCutResult(m_cutPosition_NPixel, passNPixel);
545  acceptData.setCutResult(m_cutPosition_NBlayer, passNBlayer);
547  acceptData.setCutResult(m_cutPosition_MVA, passMVA);
548 
549  return acceptData;
550 
551 }
552 
553 //=============================================================================
554 // The main result method: the actual mvaScore is calculated here
555 //=============================================================================
556 double AsgElectronSelectorTool::calculate( const EventContext& ctx, const xAOD::Electron* eg, double mu ) const
557 {
558  // Get all outputs of the mva tool
559  std::vector<float> mvaOutputs = calculateMultipleOutputs(ctx, eg, mu);
560 
561  return getDiscriminant(mvaOutputs, eg);
562 }
563 
564 double AsgElectronSelectorTool::getDiscriminant(std::vector<float>& mvaOutputs, const xAOD::Electron* eg ) const
565 {
566  double discriminant = 0;
567  // If a binary model is used, vector will have one entry, if multiclass is used vector will have six entries
568  if (!m_multiClass){
569  discriminant = transformMLOutput(mvaOutputs.at(0));
570  }
571  else{
572  const xAOD::CaloCluster* cluster = eg->caloCluster();
573  const float eta = cluster->etaBE(2);
574  // combine the six output nodes into one discriminant to cut on, any necessary transformation is applied within combineOutputs()
575  discriminant = combineOutputs(mvaOutputs, eta);
576  }
577 
578  return discriminant;
579 }
580 
581 
582 std::vector<float> AsgElectronSelectorTool::calculateMultipleOutputs(const EventContext &ctx, const xAOD::Electron *eg, double mu) const
583 {
584  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculateMultipleOutputs( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
585  if (!eg){
586  throw std::runtime_error("AsgElectronSelectorTool: Failed, no electron object was passed" );
587  }
588 
589  const xAOD::CaloCluster* cluster = eg->caloCluster();
590  if (!cluster){
591  ATH_MSG_DEBUG("Failed, no cluster.");
592  // Return a default value
593  return m_defaultVector;
594  }
595 
597  ATH_MSG_DEBUG("Failed, cluster is missing samplings EMB2 and EME2.");
598  // Return a default value
599  return m_defaultVector;
600  }
601 
602  const double energy = cluster->e();
603  const float eta = cluster->etaBE(2);
604 
605  if (isForwardElectron(eg, eta)){
606  ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
607  // Return a default value
608  return m_defaultVector;
609  }
610 
611  const xAOD::TrackParticle* track = eg->trackParticle();
612  if (!track){
613  ATH_MSG_DEBUG("Failed, no track.");
614  // Return a default value
615  return m_defaultVector;
616  }
617 
618  // transverse energy of the electron (using the track eta)
619  const double et = energy / std::cosh(track->eta());
620 
621  // Variables used in the ML model
622  // track quantities
623  double SCTWeightedCharge(0.0);
626  float d0(0.0), d0sigma(0.0), d0significance(0.0), qd0(0.0);
627  float trackqoverp(0.0);
628  double dPOverP(0.0);
629  float TRT_PID(0.0);
630  double trans_TRTPID(0.0);
631 
632  // Track Cluster matching
633  float deltaEta1(0), deltaPhiRescaled2(0), EoverP(0);
634 
635  // Calorimeter
636  float Reta(0), Rphi(0), Rhad1(0), Rhad(0), w2(0), f1(0), Eratio(0), f3(0), wtots1(0);
637 
638  bool allFound = true;
639  std::string notFoundList = "";
640 
641  // retrieve track variables
642  trackqoverp = track->qOverP();
643  d0 = track->d0();
644  qd0 = (eg->charge())*track->d0();
645  float vard0 = track->definingParametersCovMatrix()(0, 0);
646  if (vard0 > 0){
647  d0sigma = std::sqrt(vard0);
648  }
649  d0significance = std::abs(d0 / d0sigma);
650 
651  const static SG::AuxElement::Accessor<float> trans_TRT_PID_acc("transformed_e_probability_ht");
652  if (!trans_TRT_PID_acc.isAvailable(*eg)) {
653  // most probable case, need to compute the variable
654 
655  if (!track->summaryValue(TRT_PID, xAOD::eProbabilityHT)) {
656  allFound = false;
657  notFoundList += "eProbabilityHT ";
658  }
659 
660  // Transform the TRT PID output for use in the LH tool.
661  const double tau = 15.0;
662  const double fEpsilon = 1.0e-30; // to avoid zero division
663  double pid_tmp = TRT_PID;
664  if (pid_tmp >= 1.0)
665  pid_tmp = 1.0 - 1.0e-15; // this number comes from TMVA
666  else if (pid_tmp <= fEpsilon)
667  pid_tmp = fEpsilon;
668  trans_TRTPID = -std::log(1.0 / pid_tmp - 1.0) * (1. / tau);
669  }
670  else
671  {
672  // it means the variable have been already computed by another tool
673  // usually this is the EGammaVariableCorrection, which means that
674  // it is also fudged (only MC)
675  trans_TRTPID = trans_TRT_PID_acc(*eg);
676  }
677 
678  //Change default value of TRT PID to 0.15 instead of 0 when there is no information from the TRT
679  if ((std::abs(trans_TRTPID) < 1.0e-6) && (std::abs(eta) > 2.01)){
680  trans_TRTPID = 0.15;
681  }
682 
683  unsigned int index;
684  if (track->indexOfParameterAtPosition(index, xAOD::LastMeasurement)){
685  double refittedTrack_LMqoverp = track->charge() / std::sqrt(std::pow(track->parameterPX(index), 2) +
686  std::pow(track->parameterPY(index), 2) +
687  std::pow(track->parameterPZ(index), 2));
688 
689  dPOverP = 1 - trackqoverp / (refittedTrack_LMqoverp);
690  }
691  else if (!m_skipDeltaPoverP) {
692  allFound = false;
693  notFoundList += "deltaPoverP ";
694  }
695 
696  EoverP = energy * std::abs(trackqoverp);
697 
700 
701  float charge = 0;
702  uint8_t SCT = 0;
703  for (unsigned TPit = 0; TPit < eg->nTrackParticles(); TPit++) {
704  uint8_t temp_NSCTHits = 0;
705  if (eg->trackParticle(TPit)) {
706  eg->trackParticle(TPit)->summaryValue(temp_NSCTHits, xAOD::numberOfSCTHits);
707  SCT += temp_NSCTHits;
708  charge += temp_NSCTHits*(eg->trackParticle(TPit)->charge());
709  }
710  }
711  if (SCT)
712  SCTWeightedCharge = (eg->charge()*charge/SCT);
713  else {
714  ATH_MSG_WARNING("No SCT hit for any track associated to electron ! nTP = " << eg->nTrackParticles());
715  }
716 
717  // retrieve Calorimeter variables
718  // reta = e237/e277
719  if (!eg->showerShapeValue(Reta, xAOD::EgammaParameters::Reta)){
720  allFound = false;
721  notFoundList += "Reta ";
722  }
723  // rphi e233/e237
724  if (!eg->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi)){
725  allFound = false;
726  notFoundList += "Rphi ";
727  }
728  // rhad1 = ethad1/et
729  if (!eg->showerShapeValue(Rhad1, xAOD::EgammaParameters::Rhad1)){
730  allFound = false;
731  notFoundList += "Rhad1 ";
732  }
733  // rhad = ethad/et
734  if (!eg->showerShapeValue(Rhad, xAOD::EgammaParameters::Rhad)){
735  allFound = false;
736  notFoundList += "Rhad ";
737  }
738  // shower width in 2nd sampling
739  if (!eg->showerShapeValue(w2, xAOD::EgammaParameters::weta2)){
740  allFound = false;
741  notFoundList += "weta2 ";
742  }
743  // fraction of energy reconstructed in the 1st sampling
744  if (!eg->showerShapeValue(f1, xAOD::EgammaParameters::f1)){
745  allFound = false;
746  notFoundList += "f1 ";
747  }
748  // E of 2nd max between max and min in strips
749  if (!eg->showerShapeValue(Eratio, xAOD::EgammaParameters::Eratio)){
750  allFound = false;
751  notFoundList += "Eratio ";
752  }
753  // fraction of energy reconstructed in the 3rd sampling
754  if (!eg->showerShapeValue(f3, xAOD::EgammaParameters::f3)){
755  allFound = false;
756  notFoundList += "f3 ";
757  }
758 
759  // Set f3 to default value in eta region where it is poorly modelled
760  if (std::abs(eta) > 2.01) {
761  f3 = 0.05;
762  }
763 
764  // Shower width in first sampling of the calorimeter
765  if (!eg->showerShapeValue(wtots1, xAOD::EgammaParameters::wtots1)){
766  allFound = false;
767  notFoundList += "wtots1 ";
768  }
769 
770  // retrieve Track Cluster matching variables
771  // difference between cluster eta (sampling 1) and the eta of the track
772  if (!eg->trackCaloMatchValue(deltaEta1, xAOD::EgammaParameters::deltaEta1)){
773  allFound = false;
774  notFoundList += "deltaEta1 ";
775  }
776  // difference between the cluster phi (sampling 2) and the phi of the track extrapolated from the last measurement point.
778  allFound = false;
779  notFoundList += "deltaPhiRescaled2 ";
780  }
781 
782 
783  ATH_MSG_VERBOSE(Form("Vars: eta=%8.5f, et=%8.5f, f3=%8.5f, rHad==%8.5f, rHad1=%8.5f, Reta=%8.5f, w2=%8.5f, f1=%8.5f, Emaxs1=%8.5f, deltaEta1=%8.5f, d0=%8.5f, qd0=%8.5f, d0significance=%8.5f, Rphi=%8.5f, dPOverP=%8.5f, deltaPhiRescaled2=%8.5f, TRT_PID=%8.5f, trans_TRTPID=%8.5f, mu=%8.5f, wtots1=%8.5f, EoverP=%8.5f, nPixHitsPlusDeadSensors=%2df, nSCTHitsPlusDeadSensors=%2df, SCTWeightedCharge=%8.5f",
784  eta, et, f3, Rhad, Rhad1, Reta,
785  w2, f1, Eratio,
786  deltaEta1, d0, qd0,
789  TRT_PID, trans_TRTPID,
790  mu,
792 
793  if (!allFound){
794  throw std::runtime_error("AsgElectronSelectorTool: Not all variables needed for MVA calculation are found. The following variables are missing: " + notFoundList );
795  }
796 
797  std::vector<double> variableValues;
798  for(const auto varID : m_enum_variables)
799  {
800  switch(varID)
801  {
803  variableValues.push_back(std::abs(eta)); break; // TODO - rename to abseta?
805  variableValues.push_back(et); break;
807  variableValues.push_back(f3); break;
809  variableValues.push_back(Rhad); break;
811  variableValues.push_back(Rhad1); break;
813  variableValues.push_back(Reta); break;
815  variableValues.push_back(w2); break;
817  variableValues.push_back(f1); break;
819  variableValues.push_back(Eratio); break;
821  variableValues.push_back(deltaEta1); break;
823  variableValues.push_back(d0); break;
825  variableValues.push_back(qd0); break;
827  variableValues.push_back(d0significance); break;
829  variableValues.push_back(Rphi); break;
831  variableValues.push_back(dPOverP); break;
833  variableValues.push_back(deltaPhiRescaled2); break;
835  variableValues.push_back(trans_TRTPID); break;
837  variableValues.push_back(wtots1); break;
839  variableValues.push_back(EoverP); break;
841  variableValues.push_back(nPixHitsPlusDeadSensors); break;
843  variableValues.push_back(nSCTHitsPlusDeadSensors); break;
845  variableValues.push_back(SCTWeightedCharge); break;
846  default:
847  // Handle unknown varID or error case
848  throw std::runtime_error("AsgElectronSelectorTool: unknown variable "
849  "index, something went wrong in initialization!" );
850  break;
851  }
852  }
853 
854  Eigen::Matrix<float, -1, 1> mvaScores = m_mvaTool->calculate(variableValues);
855 
856  // Return a vector of all outputs of the MVA
857  std::vector<float> mvaOutputs;
858  mvaOutputs.reserve(mvaScores.rows());
859  for (int i = 0; i < mvaScores.rows(); i++) {
860  mvaOutputs.push_back(mvaScores(i, 0));
861  }
862 
863  return mvaOutputs;
864 }
865 
866 //=============================================================================
868 //=============================================================================
870 {
871  return m_workingPoint;
872 }
873 
874 //=============================================================================
876 {
877  return accept(Gaudi::Hive::currentContext(), part);
878 }
879 asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const xAOD::IParticle* part ) const
880 {
881  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *part= "<<(&ctx)<<", "<<part<<" )");
882  const xAOD::Electron* eg = dynamic_cast<const xAOD::Electron*>(part);
883  if (eg){
884  return accept(ctx, eg);
885  }
886  else {
887  ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
888  // Setup return accept with AcceptInfo
889  asg::AcceptData acceptData(&m_acceptMVA);
890  return acceptData;
891  }
892 }
893 
895 {
896  return calculate(Gaudi::Hive::currentContext(), part);
897 }
898 
899 double AsgElectronSelectorTool::calculate( const EventContext& ctx, const xAOD::IParticle* part ) const
900 {
901  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculate( &ctx, *part"<<(&ctx)<<", "<<part<<" )");
902  const xAOD::Electron* eg = dynamic_cast<const xAOD::Electron*>(part);
903  if (eg){
904  return calculate(ctx, eg);
905  }
906  else {
907  ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
908  // Return a default value
909  return -999.;
910  }
911 }
912 
913 asg::AcceptData AsgElectronSelectorTool::accept( const EventContext& ctx, const xAOD::Egamma* eg, double mu ) const
914 {
915  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
916  const xAOD::Electron* ele = dynamic_cast<const xAOD::Electron*>(eg);
917  if (ele){
918  return accept(ctx, ele, mu);
919  }
920  else {
921  ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
922  // Setup return accept with AcceptInfo
923  asg::AcceptData acceptData(&m_acceptMVA);
924  return acceptData;
925  }
926 }
927 
928 double AsgElectronSelectorTool::calculate( const EventContext& ctx, const xAOD::Egamma* eg, double mu ) const
929 {
930  ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculate( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
931  const xAOD::Electron* ele = dynamic_cast<const xAOD::Electron*>(eg);
932  if (ele){
933  return calculate(ctx, ele, mu);
934  }
935  else {
936  ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
937  return -999.;
938  }
939 }
940 
942 {
943  static const SG::AuxElement::ConstAccessor< uint16_t > accAuthor( "author" );
944 
945  if (accAuthor.isAvailable(*eg)){
946  // cannot just do eg->author() because it isn't always filled
947  // at trigger level
948  if (accAuthor(*eg) == xAOD::EgammaParameters::AuthorFwdElectron){
949  ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
950  return true;
951  }
952  }
953  else{
954  //Check for fwd via eta range the old logic
955  if (std::abs(eta) > 2.5){
956  ATH_MSG_DEBUG("Failed, cluster->etaBE(2) range due to " << eta << " seems like a fwd electron" );
957  return true;
958  }
959  }
960 
961  return false;
962 }
963 
964 
966 {
967  // returns transformed or non-transformed output
968  constexpr double oneOverTau = 1. / 10;
969  constexpr double fEpsilon = 1.0e-30; // to avoid zero division
970  if (score >= 1.0) score = 1.0 - 1.0e-15; // this number comes from TMVA
971  else if (score <= fEpsilon) score = fEpsilon;
972  score = -std::log(1.0 / score - 1.0) * oneOverTau;
973  ATH_MSG_DEBUG("score is " << score);
974  return score;
975 }
976 
977 
978 double AsgElectronSelectorTool::combineOutputs( const std::vector<float>& mvaScores, double eta ) const
979 {
980  unsigned int etaBin = getDiscEtaBin(eta);
981  double disc = 0;
982 
983  if (m_cfSignal){
984  // Put cf node into numerator
985 
986  disc = (mvaScores.at(0) * (1 - m_fractions.at(5 * etaBin + 0)) +
987  (mvaScores.at(1) * m_fractions.at(5 * etaBin + 0))) /
988  ((mvaScores.at(2) * m_fractions.at(5 * etaBin + 1)) +
989  (mvaScores.at(3) * m_fractions.at(5 * etaBin + 2)) +
990  (mvaScores.at(4) * m_fractions.at(5 * etaBin + 3)) +
991  (mvaScores.at(5) * m_fractions.at(5 * etaBin + 4)));
992  }
993  else{
994  // Put cf node in denominator
995  disc = mvaScores.at(0) /
996  ((mvaScores.at(1) * m_fractions.at(5 * etaBin + 0)) +
997  (mvaScores.at(2) * m_fractions.at(5 * etaBin + 1)) +
998  (mvaScores.at(3) * m_fractions.at(5 * etaBin + 2)) +
999  (mvaScores.at(4) * m_fractions.at(5 * etaBin + 3)) +
1000  (mvaScores.at(5) * m_fractions.at(5 * etaBin + 4)));
1001  }
1002 
1003  // Log transform to have values in reasonable range
1004  return std::log(disc);
1005 }
1006 
1007 double AsgElectronSelectorTool::combineOutputsCF( const std::vector<float>& mvaScores )
1008 {
1009  double disc = 0;
1010  disc = mvaScores.at(0) / mvaScores.at(1);
1011 
1012  return std::log(disc);
1013 }
1014 
1015 
1016 // Gets the Discriminant Eta bin [0,s_fnDiscEtaBins-1] given the eta
1018 {
1019  const unsigned int nEtaBins = s_fnDiscEtaBins;
1020  const double etaBins[nEtaBins] = {0.1, 0.6, 0.8, 1.15, 1.37, 1.52, 1.81, 2.01, 2.37, 2.47};
1021  for (unsigned int etaBin = 0; etaBin < nEtaBins; ++etaBin){
1022  if (std::abs(eta) < etaBins[etaBin]) return etaBin;
1023  }
1024  return (nEtaBins-1);
1025 }
1026 
1027 // Gets the Discriminant Et bin (MeV) [0,s_fnDiscEtBins-1]
1029 {
1030  static const double GeV = 1000;
1031  const unsigned int nEtBins = s_fnDiscEtBins;
1032  const double etBins[nEtBins] = {7*GeV,10*GeV,15*GeV,20*GeV,25*GeV,30*GeV,35*GeV,40*GeV,45*GeV,6000*GeV};
1033  for (unsigned int etBin = 0; etBin < nEtBins; ++etBin){
1034  if (et < etBins[etBin]) return etBin;
1035  }
1036  return (nEtBins-1);
1037 }
1038 
1039 
1040 // Note that this will only perform the cut interpolation up to ~45 GeV, so
1041 // no smoothing is done above this for the high ET LH binning yet
1042 double AsgElectronSelectorTool::interpolateCuts( const std::vector<double>& cuts,double et,double eta )
1043 {
1044  const int etbin = getDiscEtBin(et);
1045  const int etabin = getDiscEtaBin(eta);
1046  unsigned int ibin_combinedML = etbin*s_fnDiscEtaBins+etabin;
1047  double cut = cuts.at(ibin_combinedML);
1048  const double GeV = 1000;
1049  const double eTBins[10] = {5.5*GeV,8.5*GeV,12.5*GeV,17.5*GeV,22.5*GeV,27.5*GeV,32.5*GeV,37.5*GeV,42.5*GeV,47.5*GeV};
1050 
1051  if (et >= eTBins[9]) return cut; // no interpolation for electrons above 47.5 GeV
1052  if (et <= eTBins[0]) return cut; // no interpolation for electrons below 5.5 GeV
1053 
1054  // find the bin where the value is smaller than the next bin
1055  // Start with bin = 1, since it always has to be at least in
1056  // bin 1 because of previous cut
1057  int bin = 1;
1058  while ( et > eTBins[bin] ) bin++;
1059 
1060  double etLow = eTBins[bin-1];
1061  double etUp = eTBins[bin];
1062  double discLow = cuts.at((bin-1) * s_fnDiscEtaBins+etabin);
1063  double discUp = cuts.at((bin) * s_fnDiscEtaBins+etabin);
1064 
1065  double gradient = ( discUp - discLow ) / ( etUp - etLow );
1066 
1067  return discLow + (et - etLow) * gradient;
1068 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
AllowedVariables::Rhad1
@ Rhad1
Definition: AsgElectronSelectorTool.cxx:42
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
AsgElectronSelectorTool::getDiscriminant
double getDiscriminant(std::vector< float > &mvaOutputs, const xAOD::Electron *egu) const
Computes discrimiant value from mva output based on whether multiclass is true or false.
Definition: AsgElectronSelectorTool.cxx:564
ElectronSelectorHelpers::numberOfSCTHitsAndDeadSensors
std::size_t numberOfSCTHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of SCT hits plus dead sensors in the track particle
Definition: ElectronSelectorHelpers.cxx:32
ElectronSelectorHelpers::passAmbiguity
bool passAmbiguity(xAOD::AmbiguityTool::AmbiguityType type, const uint16_t criterion)
return true if the ambiguity type is one of several that are stored in a bitmask
Definition: ElectronSelectorHelpers.cxx:104
AsgElectronSelectorTool::m_cutPosition_kinematic
int m_cutPosition_kinematic
The position of the kinematic cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:180
et
Extra patterns decribing particle interation process.
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
AsgElectronSelectorTool::m_cutPi
std::vector< int > m_cutPi
cut min on pixel hits
Definition: AsgElectronSelectorTool.h:169
taskman.configFile
configFile
Definition: taskman.py:311
AllowedVariables::deltaPhiRescaled2
@ deltaPhiRescaled2
Definition: AsgElectronSelectorTool.cxx:53
AllowedVariables::weta2
@ weta2
Definition: AsgElectronSelectorTool.cxx:44
ElectronSelectorHelpers::numberOfSiliconHitsAndDeadSensors
std::size_t numberOfSiliconHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Silicon hits plus dead sensors in the track particle
Definition: ElectronSelectorHelpers.cxx:51
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TCS::KFMET::nEtaBins
constexpr unsigned nEtaBins
Definition: KalmanMETCorrectionConstants.h:18
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
AsgElectronSelectorTool::m_configFile
std::string m_configFile
The input config file.
Definition: AsgElectronSelectorTool.h:133
ParticleTest.eg
eg
Definition: ParticleTest.py:29
xAOD::EgammaParameters::Reta
@ Reta
e237/e277
Definition: EgammaEnums.h:154
AsgElectronSelectorTool::m_variables
std::vector< std::string > m_variables
Variables used in the MVA Tool.
Definition: AsgElectronSelectorTool.h:145
AsgElectronSelectorTool::m_mvaTool
std::unique_ptr< const ElectronDNNCalculator > m_mvaTool
Pointer to the class that calculates the MVA score.
Definition: AsgElectronSelectorTool.h:136
AllowedVariables::et
@ et
Definition: AsgElectronSelectorTool.cxx:39
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
AsgElectronSelectorTool::combineOutputsCF
static double combineOutputsCF(const std::vector< float > &mvaScores)
Definition: AsgElectronSelectorTool.cxx:1007
CurrentContext.h
AsgElectronSelectorTool::m_enum_variables
std::vector< int > m_enum_variables
Enum version of used variables.
Definition: AsgElectronSelectorTool.h:148
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
index
Definition: index.py:1
AsgElectronSelectorTool::getOperatingPointName
virtual std::string getOperatingPointName() const override
Get the name of the current operating point.
Definition: AsgElectronSelectorTool.cxx:869
AsgElectronSelectorTool::AsgElectronSelectorTool
AsgElectronSelectorTool(const std::string &myname)
Standard constructor.
Definition: AsgElectronSelectorTool.cxx:91
AllowedVariables::d0
@ d0
Definition: AsgElectronSelectorTool.cxx:48
ConvertOldUJHistosToNewHistos.etaBins
list etaBins
Definition: ConvertOldUJHistosToNewHistos.py:145
AllowedVariables::nSCTHitsPlusDeadSensors
@ nSCTHitsPlusDeadSensors
Definition: AsgElectronSelectorTool.cxx:58
bin
Definition: BinsDiffFromStripMedian.h:43
AsgElectronSelectorTool::getDiscEtBin
static unsigned int getDiscEtBin(double et)
Gets the Descriminant Et bin the et (MeV) [0,s_fnDiscEtBins-1].
Definition: AsgElectronSelectorTool.cxx:1028
AllowedVariables::trans_TRTPID
@ trans_TRTPID
Definition: AsgElectronSelectorTool.cxx:54
AsgElectronSelectorTool::m_defaultVector
std::vector< float > m_defaultVector
Default vector to return if calculation fails.
Definition: AsgElectronSelectorTool.h:193
AllowedVariables::qd0
@ qd0
Definition: AsgElectronSelectorTool.cxx:49
AsgEGammaConfigHelper.h
AsgElectronSelectorTool::m_modelFileName
std::string m_modelFileName
The input file name that holds the model.
Definition: AsgElectronSelectorTool.h:139
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
xAOD::EgammaParameters::Rphi
@ Rphi
e233/e237
Definition: EgammaEnums.h:156
xAOD::EgammaParameters::AuthorFwdElectron
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition: EgammaDefs.h:30
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
AsgElectronSelectorTool::m_CFReject
bool m_CFReject
Run CF rejection or not.
Definition: AsgElectronSelectorTool.h:158
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
ElectronSelectorHelpers::passBLayerRequirement
bool passBLayerRequirement(const xAOD::TrackParticle &tp)
return true if effective number of BL hits + outliers is at least one
Definition: ElectronSelectorHelpers.cxx:59
xAOD::EgammaParameters::wtots1
@ wtots1
shower width is determined in a window detaxdphi = 0,0625 ×~0,2, corresponding typically to 20 strips...
Definition: EgammaEnums.h:140
AsgElectronSelectorTool::m_cutAmbiguity
std::vector< int > m_cutAmbiguity
do cut on ambiguity bit
Definition: AsgElectronSelectorTool.h:165
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AsgElectronSelectorTool::m_cutSelector
std::vector< double > m_cutSelector
cut on mva output
Definition: AsgElectronSelectorTool.h:175
AsgElectronSelectorTool::accept
asg::AcceptData accept(const xAOD::IParticle *part) const override
The main accept method: using the generic interface.
Definition: AsgElectronSelectorTool.cxx:875
AsgElectronSelectorTool.h
xAOD::EgammaParameters::f3
@ f3
fraction of energy reconstructed in 3rd sampling
Definition: EgammaEnums.h:54
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
ElectronSelectorHelpers.h
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
xAOD::etaBin
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap etaBin
Definition: L2StandAloneMuon_v1.cxx:148
AsgElectronSelectorTool::m_cfSignal
bool m_cfSignal
Use the CF output node in the numerator or the denominator.
Definition: AsgElectronSelectorTool.h:160
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
AsgElectronSelectorTool::m_multiClass
bool m_multiClass
Multiclass model or not.
Definition: AsgElectronSelectorTool.h:156
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
asg::AcceptInfo
Definition: AcceptInfo.h:28
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
xAOD::EgammaParameters::f1
@ f1
E1/E = fraction of energy reconstructed in the first sampling, where E1 is energy in all strips belon...
Definition: EgammaEnums.h:52
AsgElectronSelectorTool::m_cutPosition_NBlayer
int m_cutPosition_NBlayer
The position of the NBlayer cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:186
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloCluster.h
AsgElectronSelectorTool::m_quantileFileName
std::string m_quantileFileName
The input file name that holds the QuantileTransformer.
Definition: AsgElectronSelectorTool.h:142
AsgElectronSelectorTool::initialize
virtual StatusCode initialize() override
Gaudi Service Interface method implementations.
Definition: AsgElectronSelectorTool.cxx:122
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
RTTAlgmain.Matrix
list Matrix
Definition: RTTAlgmain.py:19
AsgElectronSelectorTool::getDiscEtaBin
static unsigned int getDiscEtaBin(double eta)
Gets the Discriminant Eta bin [0,s_fnDiscEtaBins-1] given the eta.
Definition: AsgElectronSelectorTool.cxx:1017
AsgElectronSelectorTool::calculate
double calculate(const xAOD::IParticle *part) const
The main result method: the actual mva score is calculated here.
Definition: AsgElectronSelectorTool.cxx:894
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
AllowedVariables::deltaEta1
@ deltaEta1
Definition: AsgElectronSelectorTool.cxx:47
AsgElectronSelectorTool::calculateMultipleOutputs
std::vector< float > calculateMultipleOutputs(const EventContext &ctx, const xAOD::Electron *eg, double mu=-99) const override
The result method for multiple outputs: can return multiple outputs of the MVA.
Definition: AsgElectronSelectorTool.cxx:582
AllowedVariables::d0significance
@ d0significance
Definition: AsgElectronSelectorTool.cxx:50
BindingsTest.cut
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
Definition: BindingsTest.py:13
plotBeamSpotVert.cuts
string cuts
Definition: plotBeamSpotVert.py:93
ElectronDNNCalculator.h
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
xAOD::AmbiguityTool::AmbiguityType
AmbiguityType
Definition: IEGammaAmbiguityTool.h:33
xAOD::EgammaParameters::Rhad1
@ Rhad1
ethad1/et
Definition: EgammaEnums.h:162
AsgConfigHelper::HelperInt
std::vector< int > HelperInt(const std::string &input, TEnv &env)
Definition: AsgEGammaConfigHelper.cxx:115
SCT
Definition: SCT_ChipUtils.h:14
AsgElectronSelectorTool::interpolateCuts
static double interpolateCuts(const std::vector< double > &cuts, double et, double eta)
Interpolates cut values along pt.
Definition: AsgElectronSelectorTool.cxx:1042
PathResolver.h
AsgElectronSelectorTool::m_fractions
std::vector< double > m_fractions
Fractions to combine the output nodes of a multiclass model into one discriminant.
Definition: AsgElectronSelectorTool.h:162
TauJetParameters::discriminant
@ discriminant
Definition: TauJetParameters.h:166
AllowedVariables::Rhad
@ Rhad
Definition: AsgElectronSelectorTool.cxx:41
AllowedVariables::f1
@ f1
Definition: AsgElectronSelectorTool.cxx:45
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
AllowedVariables::f3
@ f3
Definition: AsgElectronSelectorTool.cxx:40
charge
double charge(const T &p)
Definition: AtlasPID.h:897
AsgElectronSelectorTool::m_skipAmbiguityCut
bool m_skipAmbiguityCut
Definition: AsgElectronSelectorTool.h:153
AsgElectronSelectorTool::m_doSmoothBinInterpolation
bool m_doSmoothBinInterpolation
do smooth interpolation between bins
Definition: AsgElectronSelectorTool.h:173
xAOD::Electron_v1
Definition: Electron_v1.h:34
AsgElectronSelectorTool::m_cutPosition_NPixel
int m_cutPosition_NPixel
The position of the NPixel cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:184
AsgElectronSelectorTool::m_cutPosition_MVA
int m_cutPosition_MVA
The position of the MVA cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:190
AsgElectronSelectorTool::m_cutPosition_ambiguity
int m_cutPosition_ambiguity
The position of the ambiguity cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:188
AllowedVariables::Eratio
@ Eratio
Definition: AsgElectronSelectorTool.cxx:46
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
xAOD::score
@ score
Definition: TrackingPrimitives.h:513
AllowedVariables::Reta
@ Reta
Definition: AsgElectronSelectorTool.cxx:43
AsgElectronSelectorTool::m_workingPoint
std::string m_workingPoint
Working Point.
Definition: AsgElectronSelectorTool.h:130
AllowedVariables::eta
@ eta
Definition: AsgElectronSelectorTool.cxx:38
AllowedVariables
Definition: AsgElectronSelectorTool.cxx:36
DeMoScan.index
string index
Definition: DeMoScan.py:364
AsgElectronSelectorTool::m_cutBL
std::vector< int > m_cutBL
cut min on b-layer hits
Definition: AsgElectronSelectorTool.h:167
EGSelectorConfigurationMapping.h
AsgElectronSelectorTool::s_fnDiscEtaBins
static const unsigned int s_fnDiscEtaBins
number of discriminants vs |eta|
Definition: AsgElectronSelectorTool.h:198
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
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AllowedVariables::nPixHitsPlusDeadSensors
@ nPixHitsPlusDeadSensors
Definition: AsgElectronSelectorTool.cxx:57
AllowedVariables::dPOverP
@ dPOverP
Definition: AsgElectronSelectorTool.cxx:52
AsgElectronSelectorTool::isForwardElectron
bool isForwardElectron(const xAOD::Egamma *eg, const float eta) const
check for FwdElectron
Definition: AsgElectronSelectorTool.cxx:941
AsgElectronSelectorTool::transformMLOutput
double transformMLOutput(float score) const
Applies a logit transformation to the score returned by the underlying MVA tool.
Definition: AsgElectronSelectorTool.cxx:965
AllowedVariables::wtots1
@ wtots1
Definition: AsgElectronSelectorTool.cxx:55
AsgElectronSelectorTool::m_cutPosition_NSilicon
int m_cutPosition_NSilicon
The position of the NSilicon cut bit in the AcceptInfo return object.
Definition: AsgElectronSelectorTool.h:182
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
AsgElectronSelectorTool::~AsgElectronSelectorTool
virtual ~AsgElectronSelectorTool()
Standard destructor.
AsgElectronSelectorTool::m_acceptMVA
asg::AcceptInfo m_acceptMVA
Accept info.
Definition: AsgElectronSelectorTool.h:101
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
xAOD::eProbabilityHT
@ eProbabilityHT
Electron probability from High Threshold (HT) information [float].
Definition: TrackingPrimitives.h:301
AllowedVariables::variableMap
const std::unordered_map< std::string, int > variableMap
Definition: AsgElectronSelectorTool.cxx:62
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
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
AllowedVariables::EoverP
@ EoverP
Definition: AsgElectronSelectorTool.cxx:56
EgammaSelectors::ElectronDNNPointToConfFile
const std::map< std::string, std::string > ElectronDNNPointToConfFile
Definition: EGSelectorConfigurationMapping.h:127
xAOD::EgammaParameters::Eratio
@ Eratio
(emaxs1-e2tsts1)/(emaxs1+e2tsts1)
Definition: EgammaEnums.h:158
AllowedVariables::SCTWeightedCharge
@ SCTWeightedCharge
Definition: AsgElectronSelectorTool.cxx:59
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
AllowedVariables::Rphi
@ Rphi
Definition: AsgElectronSelectorTool.cxx:51
AsgElectronSelectorTool::combineOutputs
double combineOutputs(const std::vector< float > &mvaScores, double eta) const
Combines the six output nodes of a multiclass model into one discriminant.
Definition: AsgElectronSelectorTool.cxx:978
xAOD::EgammaParameters::deltaEta1
@ deltaEta1
difference between the cluster eta (first sampling) and the eta of the track extrapolated to the firs...
Definition: EgammaEnums.h:184
AsgElectronSelectorTool::getAcceptInfo
virtual const asg::AcceptInfo & getAcceptInfo() const override
Method to get the plain AcceptInfo.
Definition: AsgElectronSelectorTool.cxx:346
xAOD::CaloCluster_v1::hasSampling
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
Definition: CaloCluster_v1.h:890
AsgElectronSelectorTool::m_cutSCT
std::vector< int > m_cutSCT
cut min on precision hits
Definition: AsgElectronSelectorTool.h:171
xAOD::EgammaParameters::Rhad
@ Rhad
ethad/et
Definition: EgammaEnums.h:160
python.DataFormatRates.env
env
Definition: DataFormatRates.py:32
asg::AcceptData
Definition: AcceptData.h:30
AsgElectronSelectorTool::m_cutSelectorCF
std::vector< double > m_cutSelectorCF
Definition: AsgElectronSelectorTool.h:176
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
AsgConfigHelper::HelperDouble
std::vector< double > HelperDouble(const std::string &input, TEnv &env)
Definition: AsgEGammaConfigHelper.cxx:105
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
AsgElectronSelectorTool::s_fnDiscEtBins
static const unsigned int s_fnDiscEtBins
number of discrimintants vs Et
Definition: AsgElectronSelectorTool.h:196
AsgElectronSelectorTool::m_skipDeltaPoverP
bool m_skipDeltaPoverP
Flag for skip the use of deltaPoverP in dnn calculation (like at HLT)
Definition: AsgElectronSelectorTool.h:151
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
xAOD::EgammaParameters::weta2
@ weta2
the lateral width is calculated with a window of 3x5 cells using the energy weighted sum over all cel...
Definition: EgammaEnums.h:103
AsgConfigHelper::findConfigFile
std::string findConfigFile(const std::string &input, const std::map< std::string, std::string > &configmap)
Definition: AsgEGammaConfigHelper.cxx:14
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65
ElectronSelectorHelpers::numberOfPixelHitsAndDeadSensors
std::size_t numberOfPixelHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Pixel hits plus dead sensors in the track particle
Definition: ElectronSelectorHelpers.cxx:12