ATLAS Offline Software
Loading...
Searching...
No Matches
AsgElectronSelectorTool Class Referencefinal

Electron selector tool to select signal electrons using the ElectronDNNCalculator retrieve a score based on a DNN. More...

#include <AsgElectronSelectorTool.h>

Inheritance diagram for AsgElectronSelectorTool:
Collaboration diagram for AsgElectronSelectorTool:

Classes

struct  SelectorOutputs
struct  SelectionLayer

Public Member Functions

 AsgElectronSelectorTool (const std::string &myname)
 Standard constructor.
virtual ~AsgElectronSelectorTool ()
 Standard destructor.
virtual StatusCode initialize () override
 Gaudi Service Interface method implementations.
virtual const asg::AcceptInfo & getAcceptInfo () const override
 Method to get the plain AcceptInfo.
asg::AcceptData accept (const xAOD::IParticle *part) const override
 The main accept method: using the generic interface.
asg::AcceptData accept (const EventContext &ctx, const xAOD::IParticle *part) const override
asg::AcceptData accept (const EventContext &ctx, const xAOD::Electron *eg) const override
 The main accept method: the actual cuts are applied here.
asg::AcceptData accept (const EventContext &ctx, const xAOD::Egamma *eg) const override
 The main accept method: the actual cuts are applied here.
asg::AcceptData accept (const EventContext &ctx, const xAOD::Electron *eg, double mu) const override
 The main accept method: in case mu not in EventInfo online.
asg::AcceptData accept (const EventContext &ctx, const xAOD::Egamma *eg, double mu) const override
 The main accept method: in case mu not in EventInfo online.
double calculate (const xAOD::IParticle *part) const
 The main result method: the actual mva score is calculated here.
double calculate (const EventContext &ctx, const xAOD::IParticle *part) const override
 calculate method: for pointer to IParticle
double calculate (const EventContext &ctx, const xAOD::Electron *eg) const override
 The main result method: the actual mva score is calculated here.
double calculate (const EventContext &ctx, const xAOD::Egamma *eg) const override
 The main result method: the actual mva score is calculated here.
double calculate (const EventContext &ctx, const xAOD::Electron *eg, double mu) const override
 The main result method: the actual mva score is calculated here.
double calculate (const EventContext &ctx, const xAOD::Egamma *eg, double mu) const override
 The main result method: the actual mva score is calculated here.
SelectorOutputs runSelections (const EventContext &ctx, const xAOD::Electron *eg, double mu) const
 The result method for multiple outputs: can return multiple outputs of the MVA.
virtual std::vector< float > calculateMultipleOutputs (const EventContext &ctx, const xAOD::Electron *eg, double mu=-99) const override
 calculate all outputs of the underlying method (MVA) if it produces multiple outputs
std::vector< double > getDiscriminant (const SelectorOutputs &mvaOutputs, const xAOD::Electron *egu) const
 Computes discrimiant value from mva output based on whether multiclass is true or false.
virtual std::string getOperatingPointName () const override
 Get the name of the current operating point.
virtual void print () const
 Print the state of the tool.
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const
Additional helper functions, not directly mimicking Athena
template<class T>
const T * getProperty (const std::string &name) const
 Get one of the tool's properties.
const std::string & msg_level_name () const __attribute__((deprecated))
 A deprecated function for getting the message level's name.
const std::string & getName (const void *ptr) const
 Get the name of an object that is / should be in the event store.
SG::sgkey_t getKey (const void *ptr) const
 Get the (hashed) key of an object that is in the event store.

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvc > StoreGateSvc_t

Private Member Functions

bool isForwardElectron (const xAOD::Egamma *eg, const float eta) const
 check for FwdElectron
double transformMLOutput (float score) const
 Applies a logit transformation to the score returned by the underlying MVA tool.
double combineOutputs (const std::vector< float > &mvaScores, double eta, const std::vector< double > &fractions, bool cfSignal=false) const
 Combines the six output nodes of a multiclass model into one discriminant.
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Static Private Member Functions

static double combineOutputsCF (const std::vector< float > &mvaScores)
static unsigned int getDiscEtaBin (double eta)
 Gets the Discriminant Eta bin [0,s_fnDiscEtaBins-1] given the eta.
static unsigned int getDiscEtBin (double et)
 Gets the Descriminant Et bin the et (MeV) [0,s_fnDiscEtBins-1].
static double interpolateCuts (const std::vector< double > &cuts, double et, double eta)
 Interpolates cut values along pt.

Private Attributes

asg::AcceptInfo m_acceptMVA
 Accept info.
std::string m_workingPoint
 Working Point.
std::string m_configFile
 The input config file.
std::string m_modelFileName
 The input file name that holds the model.
std::string m_quantileFileName
 The input file name that holds the QuantileTransformer.
bool m_skipDeltaPoverP
 Flag for skip the use of deltaPoverP in dnn calculation (like at HLT).
bool m_skipAmbiguityCut
bool m_doSmoothBinInterpolation {}
std::vector< SelectionLayer > m_layers
int m_cutPosition_kinematic {}
 The position of the kinematic cut bit in the AcceptInfo return object.
int m_cutPosition_NSilicon {}
 The position of the NSilicon cut bit in the AcceptInfo return object.
int m_cutPosition_NPixel {}
 The position of the NPixel cut bit in the AcceptInfo return object.
int m_cutPosition_NBlayer {}
 The position of the NBlayer cut bit in the AcceptInfo return object.
int m_cutPosition_ambiguity {}
 The position of the ambiguity cut bit in the AcceptInfo return object.
int m_cutPosition_MVA {}
 The position of the MVA cut bit in the AcceptInfo return object.
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Static Private Attributes

static const unsigned int s_fnDiscEtBins = 10
static const unsigned int s_fnDiscEtaBins = 10

Detailed Description

Electron selector tool to select signal electrons using the ElectronDNNCalculator retrieve a score based on a DNN.

This includes preprocessing/transformations of the input variables and the actual calculation of the score using lwtnn.

Author
Lukas Ehrke, Daniel Nielsen, Troels Petersen
Note
heavily adapted from AsgElectronLikelihoodTool

Definition at line 25 of file AsgElectronSelectorTool.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 376 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ AsgElectronSelectorTool()

AsgElectronSelectorTool::AsgElectronSelectorTool ( const std::string & myname)

Standard constructor.

Definition at line 213 of file AsgElectronSelectorTool.cxx.

213 :
214 AsgTool(myname),
215 m_configFile{""}
216{
217
218 // Declare the needed properties
219 declareProperty("WorkingPoint", m_workingPoint="", "The Working Point");
220 declareProperty("ConfigFile", m_configFile="", "The config file to use");
221
222 // model file name. Managed in the ElectronDNNCalculator.
223 declareProperty("inputModelFileName", m_modelFileName="", "The input file name that holds the model" );
224 // QuantileTransformer file name ( required for preprocessing ). Managed in the ElectronDNNCalculator.
225 declareProperty("quantileFileName", m_quantileFileName="", "The input file name that holds the QuantileTransformer");
226 // especially for trigger electron
227 declareProperty("skipDeltaPoverP",m_skipDeltaPoverP = false,"If true, it will skip the check of deltaPoverP");
228
229 declareProperty("skipAmbiguityCut",m_skipAmbiguityCut = false,"If true, it will skip the ambiguity cut");
230}
std::string m_workingPoint
Working Point.
std::string m_modelFileName
The input file name that holds the model.
bool m_skipDeltaPoverP
Flag for skip the use of deltaPoverP in dnn calculation (like at HLT).
std::string m_quantileFileName
The input file name that holds the QuantileTransformer.
std::string m_configFile
The input config file.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58

◆ ~AsgElectronSelectorTool()

AsgElectronSelectorTool::~AsgElectronSelectorTool ( )
virtualdefault

Standard destructor.

Member Function Documentation

◆ accept() [1/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Egamma * eg ) const
inlineoverridevirtual

The main accept method: the actual cuts are applied here.

Implements IAsgElectronLikelihoodTool.

Definition at line 64 of file AsgElectronSelectorTool.h.

64 {
65 return accept (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
66 }
asg::AcceptData accept(const xAOD::IParticle *part) const override
The main accept method: using the generic interface.

◆ accept() [2/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Egamma * eg,
double mu ) const
overridevirtual

The main accept method: in case mu not in EventInfo online.

Implements IAsgElectronLikelihoodTool.

Definition at line 931 of file AsgElectronSelectorTool.cxx.

932{
933 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
934 const xAOD::Electron* ele = dynamic_cast<const xAOD::Electron*>(eg);
935 if (ele){
936 return accept(ctx, ele, mu);
937 }
938 else {
939 ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
940 // Setup return accept with AcceptInfo
941 asg::AcceptData acceptData(&m_acceptMVA);
942 return acceptData;
943 }
944}
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_VERBOSE(x,...)
asg::AcceptInfo m_acceptMVA
Accept info.
Electron_v1 Electron
Definition of the current "egamma version".
Definition Electron.h:17

◆ accept() [3/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Electron * eg ) const
inlineoverridevirtual

The main accept method: the actual cuts are applied here.

Implements IAsgElectronLikelihoodTool.

Definition at line 59 of file AsgElectronSelectorTool.h.

59 {
60 return accept (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
61 }

◆ accept() [4/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Electron * eg,
double mu ) const
overridevirtual

The main accept method: in case mu not in EventInfo online.

Implements IAsgElectronLikelihoodTool.

Definition at line 360 of file AsgElectronSelectorTool.cxx.

361{
362 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
363
364 // Setup return accept with AcceptInfo
365 asg::AcceptData acceptData(&m_acceptMVA);
366
367 if (!eg){
368 throw std::runtime_error("AsgElectronSelectorTool: Failed, no electron object was passed");
369 }
370
371 const xAOD::CaloCluster* cluster = eg->caloCluster();
372 if (!cluster){
373 ATH_MSG_DEBUG("exiting because cluster is NULL " << cluster);
374 return acceptData;
375 }
376
377 if(!cluster->hasSampling(CaloSampling::CaloSample::EMB2) && !cluster->hasSampling(CaloSampling::CaloSample::EME2)){
378 ATH_MSG_DEBUG("Failed, cluster is missing samplings EMB2 and EME2");
379 return acceptData;
380 }
381
382 const double energy = cluster->e();
383 const float eta = cluster->etaBE(2);
384
385 if(isForwardElectron(eg, eta)){
386 ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
387 return acceptData;
388 }
389
391 if (!track){
392 ATH_MSG_DEBUG("exiting because track is NULL " << track);
393 return acceptData;
394 }
395
396 // transverse energy of the electron (using the track eta)
397 double et = (std::cosh(track->eta()) != 0.) ? energy / std::cosh(track->eta()) : 0.;
398
399 // number of track hits
400 uint8_t nSiHitsPlusDeadSensors(0);
402 bool passBLayerRequirement(false);
403 uint8_t ambiguityBit(0);
404
405 bool allFound = true;
406 std::string notFoundList = "";
407
408 // get the ambiguity type from the decoration
409 if (!m_skipAmbiguityCut){
410 static const SG::Accessor<uint8_t> ambiguityTypeAcc("ambiguityType");
411 if (ambiguityTypeAcc.isAvailable(*eg)) {
412 ambiguityBit = ambiguityTypeAcc(*eg);
413 }
414 else {
415 allFound = false;
416 notFoundList += "ambiguityType ";
417 }
418 }
419
420 nSiHitsPlusDeadSensors = ElectronSelectorHelpers::numberOfSiliconHitsAndDeadSensors(*track);
423
424 // calculate the output of the selector tool
425 SelectorOutputs mvaOutputs = runSelections(ctx, eg, mu);
426
427 if (!allFound){
428 throw std::runtime_error("AsgElectronSelectorTool: Not all variables needed for the decision are found. The following variables are missing: " + notFoundList );
429 }
430
431 // Set up the individual cuts
432 bool passKine(true);
433 bool passNSilicon(true);
434 bool passNPixel(true);
435 bool passNBlayer(true);
436 bool passAmbiguity(true);
437 bool passMVA(true);
438
439
440 if (std::abs(eta) > 2.47){
441 ATH_MSG_DEBUG("This electron is fabs(eta)>2.47 Returning False.");
442 passKine = false;
443 }
444
445 unsigned int etBin = getDiscEtBin(et);
446 unsigned int etaBin = getDiscEtaBin(eta);
447
448 // sanity
449 if (etBin >= s_fnDiscEtBins){
450 ATH_MSG_DEBUG("Cannot evaluate model for Et " << et << ". Returning false..");
451 passKine = false;
452 }
453
454 // Return if the kinematic requirements are not fulfilled
455 acceptData.setCutResult(m_cutPosition_kinematic, passKine);
456 if (!passKine){return acceptData;}
457
458for (size_t idx = 0; idx < m_layers.size(); ++idx) {
459 const auto& layer = m_layers[idx];
460 const auto& scores = mvaOutputs.layerOutputs[idx];
461
462 // ambiguity bit
463 if (!layer.m_cutAmbiguity.empty()){
464 if (!ElectronSelectorHelpers::passAmbiguity((xAOD::AmbiguityTool::AmbiguityType)ambiguityBit, layer.m_cutAmbiguity[etaBin])){
465 ATH_MSG_DEBUG("MVA macro: ambiguity Bit cut failed.");
466 passAmbiguity = false;
467 }
468 }
469
470 // blayer cut
471 if (!layer.m_cutBL.empty()) {
472 if(layer.m_cutBL[etaBin] == 1 && !passBLayerRequirement){
473 ATH_MSG_DEBUG("MVA macro: Blayer cut failed.");
474 passNBlayer = false;
475 }
476 }
477 // pixel cut
478 if (!layer.m_cutPi.empty()){
479 if (nPixHitsPlusDeadSensors < layer.m_cutPi[etaBin]){
480 ATH_MSG_DEBUG("MVA macro: Pixels Failed.");
481 passNPixel = false;
482 }
483 }
484 // SCT cut
485 if (!layer.m_cutSCT.empty()){
486 if (nSiHitsPlusDeadSensors < layer.m_cutSCT[etaBin]){
487 ATH_MSG_DEBUG( "MVA macro: Silicon Failed.");
488 passNSilicon = false;
489 }
490 }
491 unsigned int ibin_combinedMVA = etBin*s_fnDiscEtaBins+etaBin; // Must change if number of eta bins changes!.
492
493 // First cut on the CF discriminant
494 // If empty, continue only with prompt ID
495 if (!layer.m_cutSelectorCF.empty()){
496 double cutDiscriminantCF;
497 // To protect against a binning mismatch, which should never happen
498 if (ibin_combinedMVA >= layer.m_cutSelectorCF.size()){
499 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." );
500 }
502 cutDiscriminantCF = interpolateCuts(layer.m_cutSelectorCF, et, eta);
503 }
504 else{
505 cutDiscriminantCF = layer.m_cutSelectorCF.at(ibin_combinedMVA);
506 }
507 // Determine if the calculated mva score value passes the combined cut
508 ATH_MSG_DEBUG("MVA macro: CF Discriminant: ");
509 double mvaScoreCF = combineOutputsCF(scores);
510 if (mvaScoreCF < cutDiscriminantCF){
511 ATH_MSG_DEBUG("MVA macro: CF cut failed.");
512 passMVA = false;
513 }
514 }
515 // (Second) cut on prompt discriminant
516 // Cut on Score MVA First Selection
517 if (!layer.m_cutSelector.empty()) {
518 double cutDiscriminant;
519 // To protect against a binning mismatch, which should never happen
520 if (ibin_combinedMVA >= layer.m_cutSelector.size()){
521 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." );
522 }
524 cutDiscriminant = interpolateCuts(layer.m_cutSelector, et, eta);
525 }
526 else{
527 cutDiscriminant = layer.m_cutSelector.at(ibin_combinedMVA);
528 }
529
530 // Determine if the calculated mva score value passes the combined cut
531 ATH_MSG_DEBUG("MVA macro: Prompt Discriminant: ");
532 double disc = layer.m_multiClass
533 ? combineOutputs(scores, eta, layer.m_fractions, layer.m_cfSignal)
535
536 if (disc < cutDiscriminant) {
537 ATH_MSG_DEBUG("MVA macro: Prompt cut failed in layer " << layer.name);
538 passMVA = false;
539 }
540 }
541 if (!passMVA || !passNSilicon || !passNPixel || !passNBlayer || !passAmbiguity) {
542 break;
543 }
544}
545 // Set the individual cut bits in the return object
546 acceptData.setCutResult(m_cutPosition_NSilicon, passNSilicon);
547 acceptData.setCutResult(m_cutPosition_NPixel, passNPixel);
548 acceptData.setCutResult(m_cutPosition_NBlayer, passNBlayer);
549 acceptData.setCutResult(m_cutPosition_ambiguity, passAmbiguity);
550 acceptData.setCutResult(m_cutPosition_MVA, passMVA);
551
552 return acceptData;
553
554}
Scalar eta() const
pseudorapidity method
std::vector< std::vector< float > > scores
float et(const xAOD::jFexSRJetRoI *j)
static const unsigned int s_fnDiscEtBins
static unsigned int getDiscEtaBin(double eta)
Gets the Discriminant Eta bin [0,s_fnDiscEtaBins-1] given the eta.
int m_cutPosition_kinematic
The position of the kinematic cut bit in the AcceptInfo return object.
static unsigned int getDiscEtBin(double et)
Gets the Descriminant Et bin the et (MeV) [0,s_fnDiscEtBins-1].
SelectorOutputs runSelections(const EventContext &ctx, const xAOD::Electron *eg, double mu) const
The result method for multiple outputs: can return multiple outputs of the MVA.
static double interpolateCuts(const std::vector< double > &cuts, double et, double eta)
Interpolates cut values along pt.
static const unsigned int s_fnDiscEtaBins
int m_cutPosition_NPixel
The position of the NPixel cut bit in the AcceptInfo return object.
int m_cutPosition_NSilicon
The position of the NSilicon cut bit in the AcceptInfo return object.
bool isForwardElectron(const xAOD::Egamma *eg, const float eta) const
check for FwdElectron
int m_cutPosition_NBlayer
The position of the NBlayer cut bit in the AcceptInfo return object.
int m_cutPosition_MVA
The position of the MVA cut bit in the AcceptInfo return object.
double transformMLOutput(float score) const
Applies a logit transformation to the score returned by the underlying MVA tool.
double combineOutputs(const std::vector< float > &mvaScores, double eta, const std::vector< double > &fractions, bool cfSignal=false) const
Combines the six output nodes of a multiclass model into one discriminant.
static double combineOutputsCF(const std::vector< float > &mvaScores)
int m_cutPosition_ambiguity
The position of the ambiguity cut bit in the AcceptInfo return object.
std::vector< SelectionLayer > m_layers
virtual double e() const
The total energy of the particle.
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
mapped_type at(key_type key) const
Look up an element in the map.
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
std::size_t numberOfPixelHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Pixel hits plus dead sensors in the track particle
bool passBLayerRequirement(const xAOD::TrackParticle &tp)
return true if effective number of BL hits + outliers is at least one
std::size_t numberOfSiliconHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Silicon hits plus dead sensors in the track particle
@ layer
Definition HitInfo.h:79
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap etaBin
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:

◆ accept() [5/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::IParticle * part ) const
overridevirtual

Implements IAsgElectronLikelihoodTool.

Definition at line 902 of file AsgElectronSelectorTool.cxx.

903{
904 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::accept( &ctx, *part= "<<(&ctx)<<", "<<part<<" )");
905 const xAOD::Electron* eg = dynamic_cast<const xAOD::Electron*>(part);
906 if (eg){
907 return accept(ctx, eg);
908 }
909 else {
910 ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
911 // Setup return accept with AcceptInfo
912 asg::AcceptData acceptData(&m_acceptMVA);
913 return acceptData;
914 }
915}

◆ accept() [6/6]

asg::AcceptData AsgElectronSelectorTool::accept ( const xAOD::IParticle * part) const
overridevirtual

The main accept method: using the generic interface.

Implements IAsgElectronLikelihoodTool.

Definition at line 898 of file AsgElectronSelectorTool.cxx.

899{
900 return accept(Gaudi::Hive::currentContext(), part);
901}

◆ calculate() [1/6]

double AsgElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Egamma * eg ) const
inlineoverridevirtual

The main result method: the actual mva score is calculated here.

Implements IAsgElectronLikelihoodTool.

Definition at line 86 of file AsgElectronSelectorTool.h.

86 {
87 return calculate (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
88 }
double calculate(const xAOD::IParticle *part) const
The main result method: the actual mva score is calculated here.

◆ calculate() [2/6]

double AsgElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Egamma * eg,
double mu ) const
overridevirtual

The main result method: the actual mva score is calculated here.

Implements IAsgElectronLikelihoodTool.

Definition at line 946 of file AsgElectronSelectorTool.cxx.

947{
948 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculate( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
949 const xAOD::Electron* ele = dynamic_cast<const xAOD::Electron*>(eg);
950 if (ele){
951 return calculate(ctx, ele, mu);
952 }
953 else {
954 ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
955 return -999.;
956 }
957}

◆ calculate() [3/6]

double AsgElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Electron * eg ) const
inlineoverridevirtual

The main result method: the actual mva score is calculated here.

Implements IAsgElectronLikelihoodTool.

Definition at line 81 of file AsgElectronSelectorTool.h.

81 {
82 return calculate (ctx, eg, -99); // mu = -99 as input will force accept to grab the pileup variable from the xAOD object
83 }

◆ calculate() [4/6]

double AsgElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Electron * eg,
double mu ) const
overridevirtual

The main result method: the actual mva score is calculated here.

Implements IAsgElectronLikelihoodTool.

Definition at line 559 of file AsgElectronSelectorTool.cxx.

560{
561 // Get all outputs of the mva tool
562 SelectorOutputs mvaOutputs = runSelections(ctx, eg, mu);
563 if (mvaOutputs.layerOutputs.empty()) return -999.0;
564
565 auto discScores = getDiscriminant(mvaOutputs, eg);
566 return discScores.empty() ? -999.0 : discScores.back(); //Returns final layer score
567}
std::vector< double > getDiscriminant(const SelectorOutputs &mvaOutputs, const xAOD::Electron *egu) const
Computes discrimiant value from mva output based on whether multiclass is true or false.

◆ calculate() [5/6]

double AsgElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::IParticle * part ) const
overridevirtual

calculate method: for pointer to IParticle

Implements IAsgElectronLikelihoodTool.

Definition at line 917 of file AsgElectronSelectorTool.cxx.

918{
919 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculate( &ctx, *part"<<(&ctx)<<", "<<part<<" )");
920 const xAOD::Electron* eg = dynamic_cast<const xAOD::Electron*>(part);
921 if (eg){
922 return calculate(ctx, eg);
923 }
924 else {
925 ATH_MSG_DEBUG("AsgElectronSelectorTool::could not cast to const Electron");
926 // Return a default value
927 return -999.;
928 }
929}

◆ calculate() [6/6]

double AsgElectronSelectorTool::calculate ( const xAOD::IParticle * part) const

The main result method: the actual mva score is calculated here.

◆ calculateMultipleOutputs()

std::vector< float > AsgElectronSelectorTool::calculateMultipleOutputs ( const EventContext & ctx,
const xAOD::Electron * eg,
double mu = -99 ) const
overridevirtual

calculate all outputs of the underlying method (MVA) if it produces multiple outputs

Implements IAsgElectronLikelihoodTool.

Definition at line 591 of file AsgElectronSelectorTool.cxx.

592{
593 SelectorOutputs mvaOutputs = runSelections(ctx, eg, mu);
594
595 if (!mvaOutputs.layerOutputs.empty()) {
596 return mvaOutputs.layerOutputs.back();
597 }
598 return {};
599}

◆ combineOutputs()

double AsgElectronSelectorTool::combineOutputs ( const std::vector< float > & mvaScores,
double eta,
const std::vector< double > & fractions,
bool cfSignal = false ) const
private

Combines the six output nodes of a multiclass model into one discriminant.

Definition at line 997 of file AsgElectronSelectorTool.cxx.

998{
999 unsigned int etaBin = getDiscEtaBin(eta);
1000 double disc = 0;
1001 size_t nClasses = mvaScores.size();
1002 size_t nFractionsPerBin = nClasses - 1;
1003
1004 if (cfSignal && nClasses >= 3) {
1005
1006 double numerator = mvaScores.at(0) * (1.0 - fractions.at(nFractionsPerBin * etaBin + 0)) +
1007 mvaScores.at(1) * fractions.at(nFractionsPerBin * etaBin + 0);
1008
1009 double denominator = 0.0;
1010 for (size_t i = 2; i < nClasses; ++i) {
1011 denominator += mvaScores.at(i) * fractions.at(nFractionsPerBin * etaBin + i - 1);
1012 }
1013 if (denominator != 0.0) {
1014 disc = numerator / denominator;
1015 }
1016 }
1017 else {
1018
1019 double numerator = mvaScores.at(0);
1020 double denominator = 0.0;
1021
1022 for (size_t i = 1; i < nClasses; ++i) {
1023 denominator += mvaScores.at(i) * fractions.at(nFractionsPerBin * etaBin + i - 1);
1024 }
1025 if (denominator != 0.0) {
1026 disc = numerator / denominator;
1027 }
1028 }
1029 // Log transform to have values in reasonable range
1030 return std::log(disc);
1031}

◆ combineOutputsCF()

double AsgElectronSelectorTool::combineOutputsCF ( const std::vector< float > & mvaScores)
staticprivate

Definition at line 1033 of file AsgElectronSelectorTool.cxx.

1034{
1035 double disc = 0;
1036 disc = mvaScores.at(0) / mvaScores.at(1);
1037
1038 return std::log(disc);
1039}

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ getAcceptInfo()

const asg::AcceptInfo & AsgElectronSelectorTool::getAcceptInfo ( ) const
overridevirtual

Method to get the plain AcceptInfo.

This is needed so that one can already get the AcceptInfo and query what cuts are defined before the first object is passed to the tool.

Implements IAsgSelectionTool.

Definition at line 352 of file AsgElectronSelectorTool.cxx.

353{
354 return m_acceptMVA;
355}

◆ getDiscEtaBin()

unsigned int AsgElectronSelectorTool::getDiscEtaBin ( double eta)
staticprivate

Gets the Discriminant Eta bin [0,s_fnDiscEtaBins-1] given the eta.

Definition at line 1043 of file AsgElectronSelectorTool.cxx.

1044{
1045 const unsigned int nEtaBins = s_fnDiscEtaBins;
1046 const double etaBins[nEtaBins] = {0.1, 0.6, 0.8, 1.15, 1.37, 1.52, 1.81, 2.01, 2.37, 2.47};
1047 for (unsigned int etaBin = 0; etaBin < nEtaBins; ++etaBin){
1048 if (std::abs(eta) < etaBins[etaBin]) return etaBin;
1049 }
1050 return (nEtaBins-1);
1051}
constexpr unsigned nEtaBins

◆ getDiscEtBin()

unsigned int AsgElectronSelectorTool::getDiscEtBin ( double et)
staticprivate

Gets the Descriminant Et bin the et (MeV) [0,s_fnDiscEtBins-1].

Definition at line 1054 of file AsgElectronSelectorTool.cxx.

1055{
1056 static const double GeV = 1000;
1057 const unsigned int nEtBins = s_fnDiscEtBins;
1058 const double etBins[nEtBins] = {7*GeV,10*GeV,15*GeV,20*GeV,25*GeV,30*GeV,35*GeV,40*GeV,45*GeV,6000*GeV};
1059 for (unsigned int etBin = 0; etBin < nEtBins; ++etBin){
1060 if (et < etBins[etBin]) return etBin;
1061 }
1062 return (nEtBins-1);
1063}

◆ getDiscriminant()

std::vector< double > AsgElectronSelectorTool::getDiscriminant ( const SelectorOutputs & mvaOutputs,
const xAOD::Electron * egu ) const

Computes discrimiant value from mva output based on whether multiclass is true or false.

Definition at line 569 of file AsgElectronSelectorTool.cxx.

570{
571 std::vector<double> discriminants;
572 const xAOD::CaloCluster* cluster = eg->caloCluster();
573 const float eta = cluster->etaBE(2);
574 // If a binary model is used, vector will have one entry
575
576 for (size_t i = 0; i < mvaOutputs.layerOutputs.size(); ++i) {
577 const auto& scores = mvaOutputs.layerOutputs[i];
578 if (scores.empty()) continue;
579
580 const auto& layer = m_layers[i];
581 double disc = layer.m_multiClass
582 ? combineOutputs(scores, eta, layer.m_fractions, layer.m_cfSignal)
584
585 discriminants.push_back(disc);
586 }
587
588 return discriminants;
589}

◆ getKey()

SG::sgkey_t asg::AsgTool::getKey ( const void * ptr) const
inherited

Get the (hashed) key of an object that is in the event store.

This is a bit of a special one. StoreGateSvc and xAOD::Event both provide ways for getting the SG::sgkey_t key for an object that is in the store, based on a bare pointer. But they provide different interfaces for doing so.

In order to allow tools to efficiently perform this operation, they can use this helper function.

See also
asg::AsgTool::getName
Parameters
ptrThe bare pointer to the object that the event store should know about
Returns
The hashed key of the object in the store. If not found, an invalid (zero) key.

Definition at line 119 of file AsgTool.cxx.

119 {
120
121#ifdef XAOD_STANDALONE
122 // In case we use @c xAOD::Event, we have a direct function call
123 // for this.
124 return evtStore()->event()->getKey( ptr );
125#else
126 const SG::DataProxy* proxy = evtStore()->proxy( ptr );
127 return ( proxy == nullptr ? 0 : proxy->sgkey() );
128#endif // XAOD_STANDALONE
129 }
ServiceHandle< StoreGateSvc > & evtStore()

◆ getName()

const std::string & asg::AsgTool::getName ( const void * ptr) const
inherited

Get the name of an object that is / should be in the event store.

This is a bit of a special one. StoreGateSvc and xAOD::Event both provide ways for getting the std::string name for an object that is in the store, based on a bare pointer. But they provide different interfaces for doing so.

In order to allow tools to efficiently perform this operation, they can use this helper function.

See also
asg::AsgTool::getKey
Parameters
ptrThe bare pointer to the object that the event store should know about
Returns
The string name of the object in the store. If not found, an empty string.

Definition at line 106 of file AsgTool.cxx.

106 {
107
108#ifdef XAOD_STANDALONE
109 // In case we use @c xAOD::Event, we have a direct function call
110 // for this.
111 return evtStore()->event()->getName( ptr );
112#else
113 const SG::DataProxy* proxy = evtStore()->proxy( ptr );
114 static const std::string dummy = "";
115 return ( proxy == nullptr ? dummy : proxy->name() );
116#endif // XAOD_STANDALONE
117 }

◆ getOperatingPointName()

std::string AsgElectronSelectorTool::getOperatingPointName ( ) const
overridevirtual

Get the name of the current operating point.

Implements IAsgElectronLikelihoodTool.

Definition at line 892 of file AsgElectronSelectorTool.cxx.

893{
894 return m_workingPoint;
895}

◆ getProperty()

template<class T>
const T * asg::AsgTool::getProperty ( const std::string & name) const
inherited

Get one of the tool's properties.

◆ initialize()

StatusCode AsgElectronSelectorTool::initialize ( void )
overridevirtual

Gaudi Service Interface method implementations.

Reimplemented from asg::AsgTool.

Definition at line 243 of file AsgElectronSelectorTool.cxx.

244{
245
246if (m_configFile.empty()) {
247 if (!m_workingPoint.empty()){
249 ATH_MSG_INFO("operating point : " << this->getOperatingPointName());
250 }
251}
252else {
253 ATH_MSG_INFO("Using USER provided config file: " << m_configFile);
254}
255 if (m_configFile.empty()){
256 ATH_MSG_ERROR("Could not find configuration file " << m_configFile);
257 return StatusCode::FAILURE;
258 }
259
261 ATH_MSG_INFO("CONFIG FILE (logical): " << m_configFile);
262 ATH_MSG_INFO("CONFIG FILE (resolved full path): " << configFile);
263
264 if (configFile.empty()){
265 ATH_MSG_ERROR("Could not locate " << m_configFile);
266 return StatusCode::FAILURE;
267 }
268
269 ATH_MSG_DEBUG("Configfile to use: " << m_configFile);
270 TEnv env;
271 env.ReadFile(configFile.c_str(), kEnvLocal);
272
273 int nLayers = env.GetValue("nSelectionLayers", 1);
274
275 const std::vector<std::string> defaultPrefixes = {
276 "", // Layer 0: No prefix
277 "SecondSelection.", // Layer 1
278 "ThirdSelection.", // Layer 2
279 "FourthSelection." // Layer 3
280 };
281
282 m_layers.clear();
283 for (int i = 0; i < nLayers; ++i) {
284 std::string prefix = (i < static_cast<int>(defaultPrefixes.size()))
285 ? defaultPrefixes[i]
286 : ("Layer" + std::to_string(i + 1) + ".");
287
288 std::string layerName = (i == 0) ? "FirstSelection"
289 : (i == 1) ? "SecondSelection"
290 : ("Layer" + std::to_string(i + 1));
291
293 std::string userModel = (i == 0) ? m_modelFileName : "";
294 std::string userQuantile = (i == 0) ? m_quantileFileName : "";
295
296 if (!layer.initialize(env, prefix, layerName, userModel, userQuantile, this)) {
297 ATH_MSG_ERROR("Error initializing layer " << i << " with prefix: " << prefix);
298 return StatusCode::FAILURE;
299 }
300 m_layers.push_back(std::move(layer));
301 }
302
303 // do smooth interpolation between bins
304 m_doSmoothBinInterpolation = env.GetValue("doSmoothBinInterpolation", false);
305
306 // --------------------------------------------------------------------------
307 // Register the cuts and check that the registration worked:
308 // NOTE: THE ORDER IS IMPORTANT!!! Cut0 corresponds to bit 0, Cut1 to bit 1,...
309 // use an int as a StatusCode
310 int sc(1);
311
312 // Cut position for the kineatic pre-selection
313 m_cutPosition_kinematic = m_acceptMVA.addCut("kinematic", "pass kinematic");
314 if (m_cutPosition_kinematic < 0) sc = 0;
315
316 // NSilicon
317 m_cutPosition_NSilicon = m_acceptMVA.addCut("NSCT", "pass NSCT");
318 if (m_cutPosition_NSilicon < 0) sc = 0;
319
320 // NPixel
321 m_cutPosition_NPixel = m_acceptMVA.addCut("NPixel", "pass NPixel");
322 if (m_cutPosition_NPixel < 0) sc = 0;
323
324 // NBlayer
325 m_cutPosition_NBlayer = m_acceptMVA.addCut("NBlayer", "pass NBlayer");
326 if (m_cutPosition_NBlayer < 0) sc = 0;
327
328 // Ambiguity
329 m_cutPosition_ambiguity = m_acceptMVA.addCut("ambiguity", "pass ambiguity");
330 if (m_cutPosition_ambiguity < 0) sc = 0;
331
332
333 // Cut position for the likelihood selection - DO NOT CHANGE ORDER!
334 m_cutPosition_MVA = m_acceptMVA.addCut("passMVA", "pass MVA");
335 if (m_cutPosition_MVA < 0) sc = 0;
336
337 // Check that we got everything OK
338 if (sc == 0){
339 ATH_MSG_ERROR("ERROR: Something went wrong with the setup of the decision objects...");
340 return StatusCode::FAILURE;
341 }
342
343 ATH_MSG_INFO("Initialization SUCCESS");
344 return StatusCode::SUCCESS;
345}
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
static std::string to_string(const std::vector< T > &v)
static Double_t sc
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
virtual std::string getOperatingPointName() const override
Get the name of the current operating point.
std::string findConfigFile(const std::string &input, const std::map< std::string, std::string > &configmap)
const std::map< std::string, std::string > ElectronDNNPointToConfFile
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interpolateCuts()

double AsgElectronSelectorTool::interpolateCuts ( const std::vector< double > & cuts,
double et,
double eta )
staticprivate

Interpolates cut values along pt.

Definition at line 1068 of file AsgElectronSelectorTool.cxx.

1069{
1070 const int etbin = getDiscEtBin(et);
1071 const int etabin = getDiscEtaBin(eta);
1072 unsigned int ibin_combinedML = etbin*s_fnDiscEtaBins+etabin;
1073 double cut = cuts.at(ibin_combinedML);
1074 const double GeV = 1000;
1075 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};
1076
1077 if (et >= eTBins[9]) return cut; // no interpolation for electrons above 47.5 GeV
1078 if (et <= eTBins[0]) return cut; // no interpolation for electrons below 5.5 GeV
1079
1080 // find the bin where the value is smaller than the next bin
1081 // Start with bin = 1, since it always has to be at least in
1082 // bin 1 because of previous cut
1083 int bin = 1;
1084 while ( et > eTBins[bin] ) bin++;
1085
1086 double etLow = eTBins[bin-1];
1087 double etUp = eTBins[bin];
1088 double discLow = cuts.at((bin-1) * s_fnDiscEtaBins+etabin);
1089 double discUp = cuts.at((bin) * s_fnDiscEtaBins+etabin);
1090
1091 double gradient = ( discUp - discLow ) / ( etUp - etLow );
1092
1093 return discLow + (et - etLow) * gradient;
1094}

◆ isForwardElectron()

bool AsgElectronSelectorTool::isForwardElectron ( const xAOD::Egamma * eg,
const float eta ) const
private

check for FwdElectron

Definition at line 959 of file AsgElectronSelectorTool.cxx.

960{
961 static const SG::ConstAccessor< uint16_t > accAuthor( "author" );
962
963 if (accAuthor.isAvailable(*eg)){
964 // cannot just do eg->author() because it isn't always filled
965 // at trigger level
966 if (accAuthor(*eg) == xAOD::EgammaParameters::AuthorFwdElectron){
967 ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
968 return true;
969 }
970 }
971 else{
972 //Check for fwd via eta range the old logic
973 if (std::abs(eta) > 2.5){
974 ATH_MSG_DEBUG("Failed, cluster->etaBE(2) range due to " << eta << " seems like a fwd electron" );
975 return true;
976 }
977 }
978
979 return false;
980}
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition EgammaDefs.h:30

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msg_level_name()

const std::string & asg::AsgTool::msg_level_name ( ) const
inherited

A deprecated function for getting the message level's name.

Instead of using this, weirdly named function, user code should get the string name of the current minimum message level (in case they really need it...), with:

MSG::name( msg().level() )

This function's name doesn't follow the ATLAS coding rules, and as such will be removed in the not too distant future.

Returns
The string name of the current minimum message level that's printed

Definition at line 101 of file AsgTool.cxx.

101 {
102
103 return MSG::name( msg().level() );
104 }
MsgStream & msg() const
const std::string & name(Level lvl)
Convenience function for translating message levels to strings.
Definition MsgLevel.cxx:19

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ print()

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 368 of file AthCommonDataStore.h.

369 {
370 h.renounce();
372 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 352 of file AthCommonDataStore.h.

352 {
354 }

◆ runSelections()

AsgElectronSelectorTool::SelectorOutputs AsgElectronSelectorTool::runSelections ( const EventContext & ctx,
const xAOD::Electron * eg,
double mu ) const

The result method for multiple outputs: can return multiple outputs of the MVA.

Definition at line 600 of file AsgElectronSelectorTool.cxx.

601{
602
603 SelectorOutputs mvaOutputs;
604 ATH_MSG_VERBOSE("\t AsgElectronSelectorTool::calculateMultipleOutputs( &ctx, *eg, mu= "<<(&ctx)<<", "<<eg<<", "<<mu<<" )");
605 if (!eg){
606 throw std::runtime_error("AsgElectronSelectorTool: Failed, no electron object was passed" );
607 }
608
609 const xAOD::CaloCluster* cluster = eg->caloCluster();
610 if (!cluster){
611 ATH_MSG_DEBUG("Failed, no cluster.");
612 // Return a default value
613 for (const auto& l : m_layers) mvaOutputs.layerOutputs.push_back(l.m_defaultOutputs);
614 return mvaOutputs;
615 }
616
617 if (!cluster->hasSampling(CaloSampling::CaloSample::EMB2) && !cluster->hasSampling(CaloSampling::CaloSample::EME2)){
618 ATH_MSG_DEBUG("Failed, cluster is missing samplings EMB2 and EME2.");
619 // Return a default value
620 for (const auto& l : m_layers) mvaOutputs.layerOutputs.push_back(l.m_defaultOutputs);
621 return mvaOutputs;
622 }
623
624 const double energy = cluster->e();
625 const float eta = cluster->etaBE(2);
626
627 if (isForwardElectron(eg, eta)){
628 ATH_MSG_DEBUG("Failed, this is a forward electron! The AsgElectronSelectorTool is only suitable for central electrons!");
629 // Return a default value
630 for (const auto& l : m_layers) mvaOutputs.layerOutputs.push_back(l.m_defaultOutputs);
631 return mvaOutputs;
632 }
633
635 if (!track){
636 ATH_MSG_DEBUG("Failed, no track.");
637 // Return a default value
638 for (const auto& l : m_layers) mvaOutputs.layerOutputs.push_back(l.m_defaultOutputs);
639 return mvaOutputs;
640 }
641
642 // transverse energy of the electron (using the track eta)
643 const double et = energy / std::cosh(track->eta());
644
645 // Variables used in the ML model
646 // track quantities
647 double SCTWeightedCharge(0.0);
650 float d0(0.0), d0sigma(0.0), d0significance(0.0), qd0(0.0);
651 float trackqoverp(0.0);
652 double dPOverP(0.0);
653 float TRT_PID(0.0);
654 double trans_TRTPID(0.0);
655
656 // Track Cluster matching
657 float deltaEta1(0), deltaPhiRescaled2(0), EoverP(0);
658
659 // Calorimeter
660 float Reta(0), Rphi(0), Rhad1(0), Rhad(0), w2(0), f1(0), Eratio(0), f3(0), wtots1(0);
661
662 bool allFound = true;
663 std::string notFoundList = "";
664
665 // retrieve track variables
666 trackqoverp = track->qOverP();
667 d0 = track->d0();
668 qd0 = (eg->charge())*track->d0();
669 float vard0 = track->definingParametersCovMatrix()(0, 0);
670 if (vard0 > 0){
671 d0sigma = std::sqrt(vard0);
672 }
673 d0significance = (d0sigma == 0.) ? -99999. : std::abs(d0 / d0sigma);
674
675 const static SG::Accessor<float> trans_TRT_PID_acc("transformed_e_probability_ht");
676 if (!trans_TRT_PID_acc.isAvailable(*eg)) {
677 // most probable case, need to compute the variable
678
679 if (!track->summaryValue(TRT_PID, xAOD::eProbabilityHT)) {
680 allFound = false;
681 notFoundList += "eProbabilityHT ";
682 }
683
684 // Transform the TRT PID output for use in the LH tool.
685 const double tau = 15.0;
686 const double fEpsilon = 1.0e-30; // to avoid zero division
687 double pid_tmp = TRT_PID;
688 if (pid_tmp >= 1.0)
689 pid_tmp = 1.0 - 1.0e-15; // this number comes from TMVA
690 else if (pid_tmp <= fEpsilon)
691 pid_tmp = fEpsilon;
692 trans_TRTPID = -std::log(1.0 / pid_tmp - 1.0) * (1. / tau);
693 }
694 else
695 {
696 // it means the variable have been already computed by another tool
697 // usually this is the EGammaVariableCorrection, which means that
698 // it is also fudged (only MC)
699 trans_TRTPID = trans_TRT_PID_acc(*eg);
700 }
701
702 //Change default value of TRT PID to 0.15 instead of 0 when there is no information from the TRT
703 if ((std::abs(trans_TRTPID) < 1.0e-6) && (std::abs(eta) > 2.01)){
704 trans_TRTPID = 0.15;
705 }
706
707 unsigned int index;
708 if (track->indexOfParameterAtPosition(index, xAOD::LastMeasurement)){
709 double refittedTrack_LMqoverp = track->charge() / std::sqrt(std::pow(track->parameterPX(index), 2) +
710 std::pow(track->parameterPY(index), 2) +
711 std::pow(track->parameterPZ(index), 2));
712
713 dPOverP = 1 - trackqoverp / (refittedTrack_LMqoverp);
714 }
715 else if (!m_skipDeltaPoverP) {
716 allFound = false;
717 notFoundList += "deltaPoverP ";
718 }
719
720 EoverP = energy * std::abs(trackqoverp);
721
724
725 float charge = 0;
726 uint8_t SCT = 0;
727 for (unsigned TPit = 0; TPit < eg->nTrackParticles(); TPit++) {
728 uint8_t temp_NSCTHits = 0;
729 if (eg->trackParticle(TPit)) {
730 eg->trackParticle(TPit)->summaryValue(temp_NSCTHits, xAOD::numberOfSCTHits);
731 SCT += temp_NSCTHits;
732 charge += temp_NSCTHits*(eg->trackParticle(TPit)->charge());
733 }
734 }
735 if (SCT)
736 SCTWeightedCharge = (eg->charge()*charge/SCT);
737 else {
738 ATH_MSG_WARNING("No SCT hit for any track associated to electron ! nTP = " << eg->nTrackParticles());
739 }
740
741 // retrieve Calorimeter variables
742 // reta = e237/e277
744 allFound = false;
745 notFoundList += "Reta ";
746 }
747 // rphi e233/e237
749 allFound = false;
750 notFoundList += "Rphi ";
751 }
752 // rhad1 = ethad1/et
754 allFound = false;
755 notFoundList += "Rhad1 ";
756 }
757 // rhad = ethad/et
759 allFound = false;
760 notFoundList += "Rhad ";
761 }
762 // shower width in 2nd sampling
764 allFound = false;
765 notFoundList += "weta2 ";
766 }
767 // fraction of energy reconstructed in the 1st sampling
769 allFound = false;
770 notFoundList += "f1 ";
771 }
772 // E of 2nd max between max and min in strips
774 allFound = false;
775 notFoundList += "Eratio ";
776 }
777 // fraction of energy reconstructed in the 3rd sampling
779 allFound = false;
780 notFoundList += "f3 ";
781 }
782
783 // Set f3 to default value in eta region where it is poorly modelled
784 if (std::abs(eta) > 2.01) {
785 f3 = 0.05;
786 }
787
788 // Shower width in first sampling of the calorimeter
790 allFound = false;
791 notFoundList += "wtots1 ";
792 }
793
794 // retrieve Track Cluster matching variables
795 // difference between cluster eta (sampling 1) and the eta of the track
797 allFound = false;
798 notFoundList += "deltaEta1 ";
799 }
800 // difference between the cluster phi (sampling 2) and the phi of the track extrapolated from the last measurement point.
802 allFound = false;
803 notFoundList += "deltaPhiRescaled2 ";
804 }
805
806
807 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",
808 eta, et, f3, Rhad, Rhad1, Reta,
809 w2, f1, Eratio,
810 deltaEta1, d0, qd0,
811 d0significance,
812 Rphi, dPOverP, deltaPhiRescaled2,
813 TRT_PID, trans_TRTPID,
814 mu,
815 wtots1, EoverP, int(nPixHitsPlusDeadSensors), int(nSCTHitsPlusDeadSensors), SCTWeightedCharge));
816
817 if (!allFound){
818 throw std::runtime_error("AsgElectronSelectorTool: Not all variables needed for MVA calculation are found. The following variables are missing: " + notFoundList );
819 }
820
821
822 mvaOutputs.layerOutputs.reserve(m_layers.size());
823 for (const auto& layer : m_layers) {
824 std::vector<double> variableValues;
825 variableValues.reserve(layer.m_enum_variables.size());
826 for (const auto varID : layer.m_enum_variables) {
827
828 switch(varID)
829 {
831 variableValues.push_back(std::abs(eta)); break; // TODO - rename to abseta?
833 variableValues.push_back(et); break;
835 variableValues.push_back(f3); break;
837 variableValues.push_back(Rhad); break;
839 variableValues.push_back(Rhad1); break;
841 variableValues.push_back(Reta); break;
843 variableValues.push_back(w2); break;
845 variableValues.push_back(f1); break;
847 variableValues.push_back(Eratio); break;
849 variableValues.push_back(deltaEta1); break;
851 variableValues.push_back(d0); break;
853 variableValues.push_back(qd0); break;
855 variableValues.push_back(d0significance); break;
857 variableValues.push_back(Rphi); break;
859 variableValues.push_back(dPOverP); break;
861 variableValues.push_back(deltaPhiRescaled2); break;
863 variableValues.push_back(trans_TRTPID); break;
865 variableValues.push_back(wtots1); break;
867 variableValues.push_back(EoverP); break;
869 variableValues.push_back(nPixHitsPlusDeadSensors); break;
871 variableValues.push_back(nSCTHitsPlusDeadSensors); break;
873 variableValues.push_back(SCTWeightedCharge); break;
874 default:
875 // Handle unknown varID or error case
876 throw std::runtime_error("AsgElectronSelectorTool: unknown variable "
877 "index, something went wrong in initialization!" );
878 break;
879
880 }
881 }
882
883 mvaOutputs.layerOutputs.push_back(layer.evaluate(variableValues));
884 }
885
886return mvaOutputs;
887}
#define ATH_MSG_WARNING(x,...)
double charge(const T &p)
Definition AtlasPID.h:1003
@ SCT
Definition RegSelEnums.h:25
bool showerShapeValue(float &value, const EgammaParameters::ShowerShapeType information) const
Accessor for ShowerShape values.
bool trackCaloMatchValue(float &value, const EgammaParameters::TrackCaloMatchType information) const
Accessor for Track to Calo Match Values.
float charge() const
Obtain the charge of the object.
size_t nTrackParticles() const
Return the number xAOD::TrackParticles that match the electron candidate.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
str index
Definition DeMoScan.py:362
std::size_t numberOfSCTHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of SCT hits plus dead sensors in the track particle
l
Printing final latex table to .tex output file.
@ deltaPhiRescaled2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
@ deltaEta1
difference between the cluster eta (first sampling) and the eta of the track extrapolated to the firs...
@ wtots1
shower width is determined in a window detaxdphi = 0,0625 ×~0,2, corresponding typically to 20 strips...
@ f3
fraction of energy reconstructed in 3rd sampling
Definition EgammaEnums.h:55
@ f1
E1/E = fraction of energy reconstructed in the first sampling, where E1 is energy in all strips belon...
Definition EgammaEnums.h:53
@ Eratio
(emaxs1-e2tsts1)/(emaxs1+e2tsts1)
@ weta2
the lateral width is calculated with a window of 3x5 cells using the energy weighted sum over all cel...
@ eProbabilityHT
Electron probability from High Threshold (HT) information [float].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ LastMeasurement
Parameter defined at the position of the last measurement.

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, and AthCheckedComponent<::AthAlgTool >.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ transformMLOutput()

double AsgElectronSelectorTool::transformMLOutput ( float score) const
private

Applies a logit transformation to the score returned by the underlying MVA tool.

Definition at line 983 of file AsgElectronSelectorTool.cxx.

984{
985 // returns transformed or non-transformed output
986 constexpr double oneOverTau = 1 ;
987 constexpr double fEpsilon = 1.0e-30; // to avoid zero division
988 if (score >= 1.0) score = 1.0 - 1.0e-15; // this number comes from TMVA
989 else if (score <= fEpsilon) score = fEpsilon;
990 //cppcheck-suppress invalidFunctionArg
991 score = -std::log(1.0 / score - 1.0) * oneOverTau;
992 ATH_MSG_DEBUG("score is " << score);
993 return score;
994}

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 298 of file AthCommonDataStore.h.

298 {
299 for (auto &a : m_vhka) {
301 for (auto k : keys) {
302 k->setOwner(this);
303 }
304 }
305 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_acceptMVA

asg::AcceptInfo AsgElectronSelectorTool::m_acceptMVA
private

Accept info.

Definition at line 109 of file AsgElectronSelectorTool.h.

◆ m_configFile

std::string AsgElectronSelectorTool::m_configFile
private

The input config file.

Definition at line 186 of file AsgElectronSelectorTool.h.

◆ m_cutPosition_ambiguity

int AsgElectronSelectorTool::m_cutPosition_ambiguity {}
private

The position of the ambiguity cut bit in the AcceptInfo return object.

Definition at line 209 of file AsgElectronSelectorTool.h.

209{};

◆ m_cutPosition_kinematic

int AsgElectronSelectorTool::m_cutPosition_kinematic {}
private

The position of the kinematic cut bit in the AcceptInfo return object.

Definition at line 201 of file AsgElectronSelectorTool.h.

201{};

◆ m_cutPosition_MVA

int AsgElectronSelectorTool::m_cutPosition_MVA {}
private

The position of the MVA cut bit in the AcceptInfo return object.

Definition at line 211 of file AsgElectronSelectorTool.h.

211{};

◆ m_cutPosition_NBlayer

int AsgElectronSelectorTool::m_cutPosition_NBlayer {}
private

The position of the NBlayer cut bit in the AcceptInfo return object.

Definition at line 207 of file AsgElectronSelectorTool.h.

207{};

◆ m_cutPosition_NPixel

int AsgElectronSelectorTool::m_cutPosition_NPixel {}
private

The position of the NPixel cut bit in the AcceptInfo return object.

Definition at line 205 of file AsgElectronSelectorTool.h.

205{};

◆ m_cutPosition_NSilicon

int AsgElectronSelectorTool::m_cutPosition_NSilicon {}
private

The position of the NSilicon cut bit in the AcceptInfo return object.

Definition at line 203 of file AsgElectronSelectorTool.h.

203{};

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 381 of file AthCommonDataStore.h.

◆ m_doSmoothBinInterpolation

bool AsgElectronSelectorTool::m_doSmoothBinInterpolation {}
private

Definition at line 195 of file AsgElectronSelectorTool.h.

195{};

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 378 of file AthCommonDataStore.h.

◆ m_layers

std::vector<SelectionLayer> AsgElectronSelectorTool::m_layers
private

Definition at line 199 of file AsgElectronSelectorTool.h.

◆ m_modelFileName

std::string AsgElectronSelectorTool::m_modelFileName
private

The input file name that holds the model.

Definition at line 188 of file AsgElectronSelectorTool.h.

◆ m_quantileFileName

std::string AsgElectronSelectorTool::m_quantileFileName
private

The input file name that holds the QuantileTransformer.

Definition at line 191 of file AsgElectronSelectorTool.h.

◆ m_skipAmbiguityCut

bool AsgElectronSelectorTool::m_skipAmbiguityCut
private

Definition at line 194 of file AsgElectronSelectorTool.h.

◆ m_skipDeltaPoverP

bool AsgElectronSelectorTool::m_skipDeltaPoverP
private

Flag for skip the use of deltaPoverP in dnn calculation (like at HLT).

Definition at line 193 of file AsgElectronSelectorTool.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 387 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 386 of file AthCommonDataStore.h.

◆ m_workingPoint

std::string AsgElectronSelectorTool::m_workingPoint
private

Working Point.

Definition at line 183 of file AsgElectronSelectorTool.h.

◆ s_fnDiscEtaBins

const unsigned int AsgElectronSelectorTool::s_fnDiscEtaBins = 10
staticprivate

Definition at line 197 of file AsgElectronSelectorTool.h.

◆ s_fnDiscEtBins

const unsigned int AsgElectronSelectorTool::s_fnDiscEtBins = 10
staticprivate

Definition at line 196 of file AsgElectronSelectorTool.h.


The documentation for this class was generated from the following files: