ATLAS Offline Software
Loading...
Searching...
No Matches
AsgForwardElectronSelectorTool Class Reference

Tool to apply DNN-based ID to forward electrons for Run 4 using ITk and HGTD variables. More...

#include <AsgForwardElectronSelectorTool.h>

Inheritance diagram for AsgForwardElectronSelectorTool:
Collaboration diagram for AsgForwardElectronSelectorTool:

Public Member Functions

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< StoreGateSvcStoreGateSvc_t

Private Member Functions

virtual ASG_TOOL_CLASS2(AsgForwardElectronSelectorTool, IAsgElectronLikelihoodTool, IAsgSelectionTool) public ~AsgForwardElectronSelectorTool ()
 Standard constructor.
virtual StatusCode initialize () override final
 Gaudi Service Interface method implementations.
virtual const asg::AcceptInfogetAcceptInfo () const override
 Method to get the plain AcceptInfo.
virtual asg::AcceptData accept (const xAOD::IParticle *part) const override
 IAsgSelectionTool interface.
virtual asg::AcceptData accept (const EventContext &ctx, const xAOD::IParticle *part) const override
virtual asg::AcceptData accept (const EventContext &ctx, const xAOD::Electron *eg) const override
 The main accept method: the actual cuts are applied here.
virtual asg::AcceptData accept (const EventContext &ctx, const xAOD::Electron *eg, double mu) const override
 accept method with pointer to electron when mu not in EventInfo for online
virtual asg::AcceptData accept (const EventContext &ctx, const xAOD::Egamma *eg) const override
 accept method with pointer to egamma
virtual asg::AcceptData accept (const EventContext &ctx, const xAOD::Egamma *eg, double mu) const override
 accept method with pointer to egammma when mu not in EventInfo for online
virtual double calculate (const EventContext &ctx, const xAOD::IParticle *part) const override
 The main result method: the actual DNN is calculated here.
virtual double calculate (const EventContext &ctx, const xAOD::Electron *eg) const override
 calculate method: for pointer to electron
virtual double calculate (const EventContext &ctx, const xAOD::Electron *eg, double mu) const override
 calculate method: for pointer to electron when mu not in EventInfo for online
virtual double calculate (const EventContext &ctx, const xAOD::Egamma *eg) const override
 calculate method: for pointer to egamma
virtual double calculate (const EventContext &ctx, const xAOD::Egamma *eg, double mu) const override
 calculate method: for pointer to egamma when mu not in EventInfo for online
virtual std::vector< float > calculateMultipleOutputs (const EventContext &ctx, const xAOD::Electron *eg, double mu=-99) const override
 The result method for multiple outputs: only one output is used so return vector of that output.
virtual std::string getOperatingPointName () const override
 Method to get the operating point.
int getEtaBin (double absEta) const
 Select the eta bin index for |eta|, three eta bins: Bin 0: 2.5 < |eta| <= 2.7 Bin 1: 2.7 < |eta| <= 3.2 Bin 2: 3.2 < |eta| <= 4.0 Returns -1 if out of range.
int getPtBin (double calibPt) const
 Select the pT bin index, Bin 0: 5 GeV <= pT < 15 GeV Bin 1: 15 GeV <= pT < 20 GeV Bin 2: 20 GeV <= pT < 25 GeV Bin 3: 25 GeV <= pT < 30 GeV Bin 4: 30 GeV <= pT < 35 GeV Bin 5: 35 GeV <= pT < 40 GeV Bin 6: 40 GeV <= pT < 45 GeV Bin 7: 45 GeV <= pT < 50 GeV Bin 8: 50 GeV <= pT < 60 GeV Bin 9: 60 GeV <= pT < 80 GeV Bin 10: 80 GeV <= pT < 150 GeV Bin 11: 150 GeV <= pT < 500 GeV Returns -1 if outside valid range.
bool getInputs (const xAOD::Electron *eg, double calibPt, int etaBin, std::vector< double > &inputs) const
 Get 25 input variables Applies LR decorrelation Returns false on failure.
bool calculateWithCalibPt (const EventContext &ctx, const xAOD::Electron *eg, double &score, double &calibPt) const
 Runs calibration + LR + DNN in a single pass.
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

std::vector< std::unique_ptr< lwt::LightweightGraph > > m_graphs
std::vector< std::string > m_variables
 Input variable names.
ToolHandle< AsgForwardElectronCalibrationToolm_calibTool
 Handle to the calibration tool.
int m_wpIndex {-1}
 Working point index: 0 = Loose 1 = Medium 2 = Tight.
Gaudi::Property< std::vector< std::string > > m_modelFiles {this,"ModelFiles",{"","",""} ,"lwtnn JSON files, one per eta bin (in eta order)"}
 One lwtnn JSON file / DNN per eta bin.
Gaudi::Property< std::string > m_workingPoint {this,"WorkingPoint","Loose","Working Point: Loose(90%), Medium (80%), or Tight (70%)"}
 Working point: Loose = 90% | Medium = 80% | Tight = 70%.
asg::AcceptInfo m_acceptInfo
 AcceptInfo: defines the cut structure.
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

Detailed Description

Tool to apply DNN-based ID to forward electrons for Run 4 using ITk and HGTD variables.

Internal Note: https://cds.cern.ch/record/2922175

Workflow:

  1. Call AsgForwardElectronCalibrationTool to get the calibrated pT in this forward region
  2. Apply Linear Regression to decorrelate the 7 shower shape moments from pT
  3. Run DNN via lwtnn (MinMax scaler already into JSON as a batch norm layer)
  4. Apply pT- and eta-dependent working point cut on the DNN score
Author
Mathis Dubau (LAPP)
Date
Feb 2026

Based on ElectronDNNCalculator and AsgForwardElectronLikelihoodTool

Definition at line 44 of file AsgForwardElectronSelectorTool.h.

Member Typedef Documentation

◆ StoreGateSvc_t

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

Definition at line 388 of file AthCommonDataStore.h.

Member Function Documentation

◆ accept() [1/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Egamma * part ) const
overrideprivatevirtual

accept method with pointer to egamma

Implements IAsgElectronLikelihoodTool.

Definition at line 309 of file AsgForwardElectronSelectorTool.cxx.

311{
312 return accept(ctx, eg, -99);
313}
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override
IAsgSelectionTool interface.

◆ accept() [2/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Egamma * part,
double mu ) const
overrideprivatevirtual

accept method with pointer to egammma when mu not in EventInfo for online

Implements IAsgElectronLikelihoodTool.

Definition at line 316 of file AsgForwardElectronSelectorTool.cxx.

319{
320 const xAOD::Electron* el = dynamic_cast<const xAOD::Electron*>(eg);
321 if (!el) {
322 ATH_MSG_ERROR("Input is not an electron.");
323 return asg::AcceptData(&m_acceptInfo);
324 }
325 return accept(ctx, el, mu);
326}
#define ATH_MSG_ERROR(x)
asg::AcceptInfo m_acceptInfo
AcceptInfo: defines the cut structure.
Electron_v1 Electron
Definition of the current "egamma version".

◆ accept() [3/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Electron * eg ) const
overrideprivatevirtual

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

Implements IAsgElectronLikelihoodTool.

Definition at line 279 of file AsgForwardElectronSelectorTool.cxx.

281{
282 return accept(ctx, eg, -99);
283}

◆ accept() [4/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::Electron * part,
double mu ) const
overrideprivatevirtual

accept method with pointer to electron when mu not in EventInfo for online

Implements IAsgElectronLikelihoodTool.

Definition at line 286 of file AsgForwardElectronSelectorTool.cxx.

289{
290 asg::AcceptData acceptData(&m_acceptInfo);
291
292 double score{-999.}, calibPt{-999.};
293 if (!calculateWithCalibPt(ctx, eg, score, calibPt)) return acceptData;
294
295 const xAOD::CaloCluster* cluster = eg->caloCluster();
296 const int etaBin = getEtaBin(std::abs(cluster->eta()));
297 const int ptBin = getPtBin(calibPt);
298 if (etaBin < 0 || ptBin < 0) return acceptData;
299
300 acceptData.setCutResult("PassDNNScore",
301 score >= s_cuts[etaBin][ptBin][m_wpIndex]);
302 return acceptData;
303}
static const double s_cuts[3][12][3]
int getPtBin(double calibPt) const
Select the pT bin index, Bin 0: 5 GeV <= pT < 15 GeV Bin 1: 15 GeV <= pT < 20 GeV Bin 2: 20 GeV <= pT...
bool calculateWithCalibPt(const EventContext &ctx, const xAOD::Electron *eg, double &score, double &calibPt) const
Runs calibration + LR + DNN in a single pass.
int m_wpIndex
Working point index: 0 = Loose 1 = Medium 2 = Tight.
int getEtaBin(double absEta) const
Select the eta bin index for |eta|, three eta bins: Bin 0: 2.5 < |eta| <= 2.7 Bin 1: 2....
virtual double eta() const
The pseudorapidity ( ) of the particle.
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap etaBin
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.

◆ accept() [5/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const EventContext & ctx,
const xAOD::IParticle * part ) const
overrideprivatevirtual

Implements IAsgElectronLikelihoodTool.

Definition at line 263 of file AsgForwardElectronSelectorTool.cxx.

265{
266 if (part->type() == xAOD::Type::Electron) {
267 const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
268 return accept(ctx, el);
269 }
270 ATH_MSG_ERROR("Input is not an electron.");
271 return asg::AcceptData(&m_acceptInfo);
272}
@ Electron
The object is an electron.
Definition ObjectType.h:46

◆ accept() [6/6]

asg::AcceptData AsgForwardElectronSelectorTool::accept ( const xAOD::IParticle * part) const
overrideprivatevirtual

IAsgSelectionTool interface.

The main accept method: using the generic interface

Implements IAsgElectronLikelihoodTool.

Definition at line 256 of file AsgForwardElectronSelectorTool.cxx.

257{
258 // Backwards compatibility
259 return accept(Gaudi::Hive::currentContext(), part);
260}

◆ calculate() [1/5]

double AsgForwardElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Egamma * eg ) const
overrideprivatevirtual

calculate method: for pointer to egamma

Implements IAsgElectronLikelihoodTool.

Definition at line 368 of file AsgForwardElectronSelectorTool.cxx.

370{
371 return calculate(ctx, eg, -99);
372}
virtual double calculate(const EventContext &ctx, const xAOD::IParticle *part) const override
The main result method: the actual DNN is calculated here.

◆ calculate() [2/5]

double AsgForwardElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Egamma * eg,
double mu ) const
overrideprivatevirtual

calculate method: for pointer to egamma when mu not in EventInfo for online

Implements IAsgElectronLikelihoodTool.

Definition at line 375 of file AsgForwardElectronSelectorTool.cxx.

378{
379 const xAOD::Electron* el = dynamic_cast<const xAOD::Electron*>(eg);
380 if (!el) { ATH_MSG_ERROR("Input is not an electron."); return -999.; }
381 return calculate(ctx, el, mu);
382}

◆ calculate() [3/5]

double AsgForwardElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Electron * eg ) const
overrideprivatevirtual

calculate method: for pointer to electron

Implements IAsgElectronLikelihoodTool.

Definition at line 347 of file AsgForwardElectronSelectorTool.cxx.

349{
350 return calculate(ctx, eg, -99);
351}

◆ calculate() [4/5]

double AsgForwardElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::Electron * eg,
double mu ) const
overrideprivatevirtual

calculate method: for pointer to electron when mu not in EventInfo for online

Implements IAsgElectronLikelihoodTool.

Definition at line 354 of file AsgForwardElectronSelectorTool.cxx.

357{
358 double score{-999.}, calibPt{-999.};
359 calculateWithCalibPt(ctx, eg, score, calibPt);
360
361 return score;
362}

◆ calculate() [5/5]

double AsgForwardElectronSelectorTool::calculate ( const EventContext & ctx,
const xAOD::IParticle * part ) const
overrideprivatevirtual

The main result method: the actual DNN is calculated here.

Implements IAsgElectronLikelihoodTool.

Definition at line 332 of file AsgForwardElectronSelectorTool.cxx.

334{
335 if (part->type() == xAOD::Type::Electron) {
336 const xAOD::Electron* el = static_cast<const xAOD::Electron*>(part);
337 return calculate(ctx, el);
338 }
339 ATH_MSG_ERROR("Input is not an electron.");
340 return -999.;
341}

◆ calculateMultipleOutputs()

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

The result method for multiple outputs: only one output is used so return vector of that output.

Implements IAsgElectronLikelihoodTool.

Definition at line 443 of file AsgForwardElectronSelectorTool.cxx.

447{
448 return { static_cast<float>(calculate(ctx, eg, mu)) };
449}

◆ calculateWithCalibPt()

bool AsgForwardElectronSelectorTool::calculateWithCalibPt ( const EventContext & ctx,
const xAOD::Electron * eg,
double & score,
double & calibPt ) const
private

Runs calibration + LR + DNN in a single pass.

Returns false on error; on success fills score and calibPt.

Definition at line 388 of file AsgForwardElectronSelectorTool.cxx.

392{
393 score = -999.; calibPt = -999.;
394
395 if (!eg) {
396 ATH_MSG_ERROR("Failed, no Electron object.");
397 return false;
398 }
399
400 const xAOD::CaloCluster* cluster = eg->caloCluster();
401 if (!cluster) {
402 ATH_MSG_WARNING("Failed, no cluster.");
403 return false;
404 }
405
406 // ITk electron must have a track
408 if (!track) {
409 ATH_MSG_WARNING("Failed, no track.");
410 return false;
411 }
412
413 const double absEta = std::abs(cluster->eta());
414 const int etaBin = getEtaBin(absEta);
415 if (etaBin < 0) {
416 ATH_MSG_WARNING("Electron |eta|=" << absEta
417 << " is outside allowed range.");
418 return false;
419 }
420
421 // Step 1 - Usage of allready calibrated pT
422 calibPt=eg->pt();
423
424 // Step 2 - extract inputs with LR decorrelation
425 std::vector<double> inputs;
426 if (!getInputs(eg, calibPt, etaBin, inputs)) return false;
427
428 // Step 3 - run DNN
429 std::map<std::string, std::map<std::string, double>> inputMap;
430 for (size_t i = 0; i < m_variables.size(); ++i)
431 inputMap["node_0"][m_variables[i]] = inputs[i];
432
433 score = m_graphs[etaBin]->compute(inputMap).begin()->second;
434 // Round 6 digits due to lwtnn mismatch
435 score = std::round(score * 1e6) / 1e6;
436 return true;
437}
#define ATH_MSG_WARNING(x)
std::vector< std::unique_ptr< lwt::LightweightGraph > > m_graphs
std::vector< std::string > m_variables
Input variable names.
bool getInputs(const xAOD::Electron *eg, double calibPt, int etaBin, std::vector< double > &inputs) const
Get 25 input variables Applies LR decorrelation Returns false on failure.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition Egamma_v1.cxx:66
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.
bool absEta(const xAOD::TauJet &tau, float &out)
TrackParticle_v1 TrackParticle
Reference the current persistent version:

◆ 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 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ 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 & AsgForwardElectronSelectorTool::getAcceptInfo ( ) const
overrideprivatevirtual

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 247 of file AsgForwardElectronSelectorTool.cxx.

248{
249 return m_acceptInfo;
250}

◆ getEtaBin()

int AsgForwardElectronSelectorTool::getEtaBin ( double absEta) const
private

Select the eta bin index for |eta|, three eta bins: Bin 0: 2.5 < |eta| <= 2.7 Bin 1: 2.7 < |eta| <= 3.2 Bin 2: 3.2 < |eta| <= 4.0 Returns -1 if out of range.

Definition at line 463 of file AsgForwardElectronSelectorTool.cxx.

464{
465 // Convention: x1 < |eta| <= x2
466 if (absEta > 2.5 && absEta <= 2.7) return 0;
467 if (absEta > 2.7 && absEta <= 3.2) return 1;
468 if (absEta > 3.2 && absEta <= 4.0) return 2;
469 return -1;
470}

◆ getInputs()

bool AsgForwardElectronSelectorTool::getInputs ( const xAOD::Electron * eg,
double calibPt,
int etaBin,
std::vector< double > & inputs ) const
private

Get 25 input variables Applies LR decorrelation Returns false on failure.

Definition at line 488 of file AsgForwardElectronSelectorTool.cxx.

492{
493 inputs.clear();
494 inputs.reserve(25);
495
496 const xAOD::CaloCluster* cluster = eg->caloCluster();
498
499 if (!cluster) { ATH_MSG_ERROR("No CaloCluster."); return false; }
500 if (!track) { ATH_MSG_ERROR("No TrackParticle."); return false; }
501
502 // x1, x2 = calo eta and phi
503 inputs.push_back(static_cast<float>(cluster->eta()));
504 inputs.push_back(static_cast<float>(cluster->phi()));
505
506 // x3, x4 = track eta and phi
507 inputs.push_back(static_cast<float>(track->eta()));
508 inputs.push_back(static_cast<float>(track->phi()));
509
510 // x5 = HGTD time
511 static const SG::AuxElement::Accessor<uint8_t> accValid("hasValidTime");
512 if (accValid.isAvailable(*track))
513 {
514 if (accValid(*track))
515 {
516 inputs.push_back(static_cast<float>(track->time()));
517 }
518 else
519 {
520 ATH_MSG_DEBUG("No valid time for the track while doing track->time()" );
521 inputs.push_back(-99);
522 }
523 }
524 else
525 {
526 ATH_MSG_ERROR("No available time for the track" );
527 }
528
529 // x6, x7 = ITk hit counts
530 inputs.push_back(static_cast<float>(eg->trackParticleSummaryIntValue(xAOD::numberOfPixelHits)));
531 inputs.push_back(static_cast<float>(eg->trackParticleSummaryIntValue(xAOD::numberOfSCTHits)));
532
533 // x8 to x14 = 7 calorimeter shower-shape moments
534 auto getMoment = [&](xAOD::CaloCluster::MomentType type,
535 const char* name) -> float {
536 double val{0.};
537 if (!cluster->retrieveMoment(type, val))
538 ATH_MSG_WARNING("Could not retrieve calo moment: " << name);
539 return val;
540 };
541
542 // Retrieve raw moments
543 const double rawMoments[7] = {
544 getMoment(xAOD::CaloCluster::ENG_FRAC_MAX, "ENG_FRAC_MAX"),
545 getMoment(xAOD::CaloCluster::LONGITUDINAL, "LONGITUDINAL"),
546 getMoment(xAOD::CaloCluster::SECOND_LAMBDA, "SECOND_LAMBDA"),
547 getMoment(xAOD::CaloCluster::LATERAL, "LATERAL"),
548 getMoment(xAOD::CaloCluster::SECOND_R, "SECOND_R"),
549 getMoment(xAOD::CaloCluster::CENTER_LAMBDA, "CENTER_LAMBDA"),
550 getMoment(xAOD::CaloCluster::SECOND_ENG_DENS, "SECOND_ENG_DENS")
551 };
552
553 // Apply LR decorrelation: moment_decorr = moment_raw - (coeff * calibPt + intercept)
554 for (int i = 0; i < 7; ++i)
555 inputs.push_back(rawMoments[i]
556 - (s_lrCoeff[etaBin][i] * calibPt + s_lrIntercept[etaBin][i]));
557
558
559 // x15 to x18 = track-calo matching
561 const char* name) -> float {
562 float val{0.f};
563 if (!eg->trackCaloMatchValue(val, type))
564 ATH_MSG_WARNING("Could not retrieve track-calo match: " << name);
565 return val;
566 };
567
568 inputs.push_back(getMatch(xAOD::EgammaParameters::deltaEta2,
569 "delta_eta2"));
570 inputs.push_back(getMatch(xAOD::EgammaParameters::deltaPhi2,
571 "delta_phi2"));
573 "delta_phi_rescaled2"));
575 "delta_phi_last"));
576
577 // x19 to x25 = Derived calorimeter energy fractions
578 // Prevent division by zero
579 const double caloE = cluster->e();
580 const double inv_E = (caloE != 0.) ? 1. / caloE : 0.;
581
582 using CS = CaloSampling::CaloSample;
583
584 // EM fractions:
585 // f_i^EM = energyBE(i) / caloE for i in {1,2,3}
586 inputs.push_back(static_cast<float>(cluster->energyBE(1) * inv_E));
587 inputs.push_back(static_cast<float>(cluster->energyBE(2) * inv_E));
588 inputs.push_back(static_cast<float>(cluster->energyBE(3) * inv_E));
589
590 // HAD fractions:
591 // f_0^HAD = HEC0 / caloE
592 // f_i^HAD = (HEC_i + FCAL_(i-1)) / caloE for i in {1,2,3}
593 inputs.push_back(static_cast<float>(
594 cluster->eSample(static_cast<CS>(CaloSampling::HEC0)) * inv_E));
595 inputs.push_back(static_cast<float>(
596 (cluster->eSample(static_cast<CS>(CaloSampling::HEC1)) +
597 cluster->eSample(static_cast<CS>(CaloSampling::FCAL0))) * inv_E));
598 inputs.push_back(static_cast<float>(
599 (cluster->eSample(static_cast<CS>(CaloSampling::HEC2)) +
600 cluster->eSample(static_cast<CS>(CaloSampling::FCAL1))) * inv_E));
601 inputs.push_back(static_cast<float>(
602 (cluster->eSample(static_cast<CS>(CaloSampling::HEC3)) +
603 cluster->eSample(static_cast<CS>(CaloSampling::FCAL2))) * inv_E));
604
605 return true;
606}
static const double s_lrIntercept[3][7]
static const double s_lrCoeff[3][7]
#define ATH_MSG_DEBUG(x)
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double e() const
The total energy of the particle.
float eSample(const CaloSample sampling) const
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
virtual double phi() const
The azimuthal angle ( ) of the particle.
MomentType
Enums to identify different moments.
@ SECOND_ENG_DENS
Second Moment in E/V.
@ SECOND_LAMBDA
Second Moment in .
@ LATERAL
Normalized lateral moment.
@ LONGITUDINAL
Normalized longitudinal moment.
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
@ SECOND_R
Second Moment in .
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
bool trackCaloMatchValue(float &value, const EgammaParameters::TrackCaloMatchType information) const
Accessor for Track to Calo Match Values.
uint8_t trackParticleSummaryIntValue(const SummaryType information, int index=0) const
Accessor to the matching track(s) int information (index = 0 is the best match) Will lead to an excep...
@ deltaPhiFromLastMeasurement
difference between the cluster phi (sampling 2) and the eta of the track extrapolated from the last m...
@ deltaEta2
difference between the cluster eta (second sampling) and the eta of the track extrapolated to the sec...
@ deltaPhiRescaled2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
@ deltaPhi2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].

◆ 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 AsgForwardElectronSelectorTool::getOperatingPointName ( ) const
overrideprivatevirtual

Method to get the operating point.

Implements IAsgElectronLikelihoodTool.

Definition at line 455 of file AsgForwardElectronSelectorTool.cxx.

456{
457 return m_workingPoint;
458}
Gaudi::Property< std::string > m_workingPoint
Working point: Loose = 90% | Medium = 80% | Tight = 70%.

◆ getProperty()

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

Get one of the tool's properties.

◆ getPtBin()

int AsgForwardElectronSelectorTool::getPtBin ( double calibPt) const
private

Select the pT bin index, Bin 0: 5 GeV <= pT < 15 GeV Bin 1: 15 GeV <= pT < 20 GeV Bin 2: 20 GeV <= pT < 25 GeV Bin 3: 25 GeV <= pT < 30 GeV Bin 4: 30 GeV <= pT < 35 GeV Bin 5: 35 GeV <= pT < 40 GeV Bin 6: 40 GeV <= pT < 45 GeV Bin 7: 45 GeV <= pT < 50 GeV Bin 8: 50 GeV <= pT < 60 GeV Bin 9: 60 GeV <= pT < 80 GeV Bin 10: 80 GeV <= pT < 150 GeV Bin 11: 150 GeV <= pT < 500 GeV Returns -1 if outside valid range.

Definition at line 475 of file AsgForwardElectronSelectorTool.cxx.

476{
477 constexpr int nBins = 12;
478 for (int i = 0; i < nBins; ++i) {
479 if (calibPt >= s_ptEdges[i] && calibPt < s_ptEdges[i + 1])
480 return i;
481 }
482 return -1;
483}
static const double s_ptEdges[13]

◆ initialize()

StatusCode AsgForwardElectronSelectorTool::initialize ( void )
finaloverrideprivatevirtual

Gaudi Service Interface method implementations.

Reimplemented from asg::AsgTool.

Definition at line 158 of file AsgForwardElectronSelectorTool.cxx.

159{
160 // Resolve working point index
161 if (m_workingPoint == "Loose") m_wpIndex = 0;
162 else if (m_workingPoint == "Medium") m_wpIndex = 1;
163 else if (m_workingPoint == "Tight") m_wpIndex = 2;
164 else {
165 ATH_MSG_ERROR("Unknown Working Point '" << m_workingPoint
166 << "'. Choose Loose, Medium, or Tight.");
167 return StatusCode::FAILURE;
168 }
169
170 // Retrieve the calibration tool
171 ATH_CHECK(m_calibTool.retrieve());
172
173 // Sanity checks
174 if (m_modelFiles.size() != 3) {
175 ATH_MSG_ERROR("Exactly 3 model files expected (one per eta bin): "
176 "[2.5,2.7], [2.7,3.2], [3.2,4.0]). Only got "
177 << m_modelFiles.size());
178 return StatusCode::FAILURE;
179 }
180
181 // Fixed variable names - must match the lwtnn JSON input
182 m_variables = {
183 // Calo eta and Phi
184 "x1_calo_eta",
185 "x2_calo_phi",
186 // ITk eta and Phi
187 "x3_track_eta",
188 "x4_track_phi",
189 // HGTD time
190 "x5_time",
191 // ITk hit counts
192 "x6_pixels",
193 "x7_strips",
194 // Shower shape moments
195 "x8_ENG_FRAC_MAX",
196 "x9_LONGITUDINAL",
197 "x10_SECOND_LAMBDA",
198 "x11_LATERAL",
199 "x12_SECOND_R",
200 "x13_CENTER_LAMBDA",
201 "x14_SECOND_ENG_DENS",
202 // Track-cluster matching variables
203 "x15_delta_eta2",
204 "x16_delta_phi2",
205 "x17_delta_phi_rescaled2",
206 "x18_delta_phi_last",
207 // Calo energy fractions in each layer
208 "x19_calo_frac_EM_1",
209 "x20_calo_frac_EM_2",
210 "x21_calo_frac_EM_3",
211 "x22_calo_frac_HAD_0",
212 "x23_calo_frac_HAD_1",
213 "x24_calo_frac_HAD_2",
214 "x25_calo_frac_HAD_3"
215 };
216 // More informations on Table 3 in Internal Note: https://cds.cern.ch/record/2922175
217
218 // Load one JSON per eta bin
219 m_graphs.reserve(3);
220 for (const auto& model : m_modelFiles) {
221 const std::string path = PathResolverFindCalibFile(model);
222 if (path.empty()) {
223 ATH_MSG_ERROR("Could not locate: " << model);
224 return StatusCode::FAILURE;
225 }
226 std::ifstream dnn_json(path);
227 auto parsed = lwt::parse_json_graph(dnn_json);
228 m_graphs.emplace_back(
229 std::make_unique<lwt::LightweightGraph>(parsed));
230 ATH_MSG_INFO("Loaded ID model for bin "
231 << m_graphs.size() - 1 << ": " << path);
232 }
233
234 // Register the single cut in AcceptInfo
235 m_acceptInfo.addCut("PassDNNScore",
236 "Electron passes the DNN score cut for the configured WP");
237
238 ATH_MSG_INFO("AsgForwardElectronSelectorTool initialised. "
239 << "WorkingPoint=" << m_workingPoint);
240 return StatusCode::SUCCESS;
241}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Gaudi::Property< std::vector< std::string > > m_modelFiles
One lwtnn JSON file / DNN per eta bin.
ToolHandle< AsgForwardElectronCalibrationTool > m_calibTool
Handle to the calibration tool.
path
python interpreter configuration --------------------------------------—
Definition athena.py:130

◆ 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.

◆ 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()

void asg::AsgTool::print ( ) const
virtualinherited

◆ 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 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
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 364 of file AthCommonDataStore.h.

364 {
366 }

◆ 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 >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ 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.

◆ updateVHKA()

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

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

◆ ~AsgForwardElectronSelectorTool()

AsgForwardElectronSelectorTool::~AsgForwardElectronSelectorTool ( )
privatevirtualdefault

Standard constructor.

Standard destructor

Member Data Documentation

◆ m_acceptInfo

asg::AcceptInfo AsgForwardElectronSelectorTool::m_acceptInfo
private

AcceptInfo: defines the cut structure.

Definition at line 186 of file AsgForwardElectronSelectorTool.h.

◆ m_calibTool

ToolHandle<AsgForwardElectronCalibrationTool> AsgForwardElectronSelectorTool::m_calibTool
private
Initial value:
{
this, "CalibrationTool", "",
"Handle to the AsgForwardElectronCalibrationTool"}

Handle to the calibration tool.

Definition at line 171 of file AsgForwardElectronSelectorTool.h.

171 {
172 this, "CalibrationTool", "",
173 "Handle to the AsgForwardElectronCalibrationTool"};

◆ m_detStore

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

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

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

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_graphs

std::vector<std::unique_ptr<lwt::LightweightGraph> > AsgForwardElectronSelectorTool::m_graphs
private

Definition at line 164 of file AsgForwardElectronSelectorTool.h.

◆ m_modelFiles

Gaudi::Property<std::vector<std::string> > AsgForwardElectronSelectorTool::m_modelFiles {this,"ModelFiles",{"","",""} ,"lwtnn JSON files, one per eta bin (in eta order)"}
private

One lwtnn JSON file / DNN per eta bin.

Definition at line 182 of file AsgForwardElectronSelectorTool.h.

182{this,"ModelFiles",{"","",""} ,"lwtnn JSON files, one per eta bin (in eta order)"};

◆ m_varHandleArraysDeclared

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

Definition at line 399 of file AthCommonDataStore.h.

◆ m_variables

std::vector<std::string> AsgForwardElectronSelectorTool::m_variables
private

Input variable names.

Definition at line 167 of file AsgForwardElectronSelectorTool.h.

◆ m_vhka

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

Definition at line 398 of file AthCommonDataStore.h.

◆ m_workingPoint

Gaudi::Property<std::string> AsgForwardElectronSelectorTool::m_workingPoint {this,"WorkingPoint","Loose","Working Point: Loose(90%), Medium (80%), or Tight (70%)"}
private

Working point: Loose = 90% | Medium = 80% | Tight = 70%.

Definition at line 183 of file AsgForwardElectronSelectorTool.h.

183{this,"WorkingPoint","Loose","Working Point: Loose(90%), Medium (80%), or Tight (70%)"};

◆ m_wpIndex

int AsgForwardElectronSelectorTool::m_wpIndex {-1}
private

Working point index: 0 = Loose 1 = Medium 2 = Tight.

Definition at line 179 of file AsgForwardElectronSelectorTool.h.

179{-1};

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