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