ATLAS Offline Software
Loading...
Searching...
No Matches
AsgForwardElectronSelectorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
22
23
25
27#include "xAODEgamma/Electron.h"
28#include "xAODEgamma/Egamma.h"
32#include "CaloGeoHelpers/CaloSampling.h"
34
35#include "lwtnn/parse_json.hh"
36
37#include <fstream>
38#include <cmath>
39
40
41
42
43
44// ============================================================================
45// Model constants
46// ============================================================================
47
48// --- Linear regression ---
49// One coefficient and one intercept per shower shape variable (7) per eta bin
50// Order: ENG_FRAC_MAX, LONGITUDINAL, SECOND_LAMBDA, LATERAL,
51// SECOND_R, CENTER_LAMBDA, SECOND_ENG_DENS
52
53static const double s_lrCoeff[3][7] = {
54 // Bin 0: 2.5 < |eta| <= 2.7
55 { 5.7626170e-07, 4.7577697e-07, -1.3823183e-03, -9.1804844e-07,
56 -5.5160094e-03, 4.0462506e-05, 2.8797556e-06 },
57 // Bin 1: 2.7 < |eta| <= 3.2
58 { 4.9091057e-07, 4.2073955e-07, 2.5762843e-03, -7.4278881e-07,
59 -3.6089115e-03, -6.4899518e-06, 7.7993927e-06 },
60 // Bin 2: 3.2 < |eta| <= 4.0
61 { 2.9304172e-07, -1.0814731e-06, -1.6405748e-02, -3.3167328e-07,
62 -7.3823769e-04, -1.7326717e-04, 9.6527780e-05 }
63};
64
65static const double s_lrIntercept[3][7] = {
66 // Bin 0: 2.5 < |eta| <= 2.7
67 { 5.3479767e-01, 1.1612210e-01, 2.2856726e+03, 4.5776847e-01,
68 1.8551936e+03, 2.1710736e+02, -8.0515645e-02 },
69 // Bin 1: 2.7 < |eta| <= 3.2
70 { 5.3335690e-01, 7.2528444e-02, 9.1885895e+02, 3.8494921e-01,
71 1.2577064e+03, 1.9783354e+02, -1.9677971e-01 },
72 // Bin 2: 3.2 < |eta| <= 4.0
73 { 5.7937855e-01, 3.4406906e-01, 5.7875332e+03, 2.8120410e-01,
74 6.1775574e+02, 2.4003990e+02, -2.6005685e+00 }
75};
76
77// --- pT bin edges [MeV] - 12 bins ---
78static const double s_ptEdges[13] = {
79 5000., 15000., 20000., 25000., 30000., 35000.,
80 40000., 45000., 50000., 60000., 80000., 150000., 500000.
81};
82
83// --- DNN score cuts [eta_bin][pt_bin][wp_index] ---
84// wp_index:
85// 0 = Loose = 90%
86// 1 = Medium = 80%
87// 2 = Tight = 70%
88// pt_bin order matches s_ptEdges:
89// [5,15],[15,20],[20,25],[25,30],[30,35],[35,40],
90// [40,45],[45,50],[50,60],[60,80],[80,150],[150,500] GeV
91
92static const double s_cuts[3][12][3] = {
93 // Bin 0: 2.5 < |eta| <= 2.7
94 {
95 { 0.003434060638577299, 0.010929810583837518, 0.028987138649460953 }, // [5,15]
96 { 0.009150723693892365, 0.10347994714975359, 0.28577716946601867 }, // [15,20]
97 { 0.1186611831188202, 0.43142691254615784, 0.7045282602310181 }, // [20,25]
98 { 0.3128826916217804, 0.6842968463897705, 0.8462172150611877 }, // [25,30]
99 { 0.6381388902664185, 0.883872103691101, 0.9505972623825073 }, // [30,35]
100 { 0.815248429775238, 0.9427814483642578, 0.9722608327865601 }, // [35,40]
101 { 0.8642481029033661, 0.9566433548927307, 0.9769171953201294 }, // [40,45]
102 { 0.859777855873108, 0.9566103696823121, 0.9771971702575684 }, // [45,50]
103 { 0.8481978237628938, 0.9565577507019043, 0.9773394107818604 }, // [50,60]
104 { 0.8359241724014282, 0.9572678208351135, 0.9781455874443055 }, // [60,80]
105 { 0.8056963920593262, 0.9453475475311279, 0.9758875846862793 }, // [80,150]
106 { 0.8081184050246257, 0.9615500409750506, 0.9705579706236049 } // [150,500]
107 },
108 // Bin 1: 2.7 < |eta| <= 3.2
109 {
110 { 0.0024538897448333936, 0.006224703698926278, 0.01602673525486277 }, // [5,15]
111 { 0.029491694644093513, 0.1092548817396164, 0.2902836352586746 }, // [15,20]
112 { 0.20487691462039948, 0.5585798382759094, 0.789155101776123 }, // [20,25]
113 { 0.5053084492683411, 0.8155142784118653, 0.9119235754013061 }, // [25,30]
114 { 0.7210912346839905, 0.9057818174362183, 0.9574183464050293 }, // [30,35]
115 { 0.8253453254699707, 0.940361762046814, 0.9731698989868164 }, // [35,40]
116 { 0.8629356622695923, 0.9526293277740479, 0.9774575233459473 }, // [40,45]
117 { 0.8681894183158875, 0.954381775856018, 0.9784879982471466 }, // [45,50]
118 { 0.8598942279815674, 0.9535421252250672, 0.9780020833015441 }, // [50,60]
119 { 0.8658008813858032, 0.9549649477005004, 0.9777071833610534 }, // [60,80]
120 { 0.8357489705085754, 0.9435908794403076, 0.971304714679718 }, // [80,150]
121 { 0.8023493699313187, 0.9416966809437475, 0.9669603430019074 } // [150,500]
122 },
123 // Bin 2: 3.2 < |eta| <= 4.0
124 {
125 { 0.0007497479446309254, 0.010757287517960587, 0.004936974379270967 }, // [5,15]
126 { 0.014802457392215732, 0.042617067694664, 0.0812974080443382 }, // [15,20]
127 { 0.07443902641534805, 0.23044122755527496, 0.45949786901474 }, // [20,25]
128 { 0.34181419014930725, 0.6247072815895081, 0.7751210331916809 }, // [25,30]
129 { 0.5459890365600586, 0.7635000348091125, 0.8726731538772583 }, // [30,35]
130 { 0.6520047783851624, 0.8353232741355896, 0.9097822308540344 }, // [35,40]
131 { 0.7230071187019348, 0.8757749557495117, 0.9323666334152222 }, // [40,45]
132 { 0.7161759436130524, 0.8738378882408142, 0.9322998225688934 }, // [45,50]
133 { 0.6740142107009888, 0.8602323532104492, 0.9265623986721039 }, // [50,60]
134 { 0.7804294466972351, 0.9046212434768677, 0.9510670781135558 }, // [60,80]
135 { 0.8492123007774353, 0.9328805446624756, 0.9633602142333985 }, // [80,150]
136 { 0.7497747273127531, 0.8820413108674948, 0.9336298814733452 } // [150,500]
137 }
138};
139
140
141//=============================================================================
142// Standard constructor
143//=============================================================================
144AsgForwardElectronSelectorTool::AsgForwardElectronSelectorTool(
145 const std::string& myname)
146 : AsgTool(myname)
147{
148}
149
150//=============================================================================
151// Standard destructor
152//=============================================================================
154
155// ============================================================================
156// Initialise
157// ============================================================================
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}
242
243// ============================================================================
244// getAcceptInfo
245// ============================================================================
246const asg::AcceptInfo&
251
252// ============================================================================
253// accept - IParticle
254// ============================================================================
257{
258 // Backwards compatibility
259 return accept(Gaudi::Hive::currentContext(), part);
260}
261
264 const xAOD::IParticle* part) const
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.");
272}
273
274
275// ============================================================================
276// accept - Electron overloads
277// ============================================================================
280 const xAOD::Electron* eg) const
281{
282 return accept(ctx, eg, -99);
283}
284
287 const xAOD::Electron* eg,
288 double /*mu*/) const
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}
304
305// ============================================================================
306// accept - Egamma overloads
307// ============================================================================
310 const xAOD::Egamma* eg) const
311{
312 return accept(ctx, eg, -99);
313}
314
317 const xAOD::Egamma* eg,
318 double mu) const
319{
320 const xAOD::Electron* el = dynamic_cast<const xAOD::Electron*>(eg);
321 if (!el) {
322 ATH_MSG_ERROR("Input is not an electron.");
324 }
325 return accept(ctx, el, mu);
326}
327
328// ============================================================================
329// calculate - IParticle overload
330// ============================================================================
331double
333 const xAOD::IParticle* part) const
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}
342
343// ============================================================================
344// calculate - Electron overloads
345// ============================================================================
346double
348 const xAOD::Electron* eg) const
349{
350 return calculate(ctx, eg, -99);
351}
352
353double
355 const xAOD::Electron* eg,
356 double /*mu*/) const
357{
358 double score{-999.}, calibPt{-999.};
359 calculateWithCalibPt(ctx, eg, score, calibPt);
360
361 return score;
362}
363
364// ============================================================================
365// calculate - Egamma overloads
366// ============================================================================
367double
369 const xAOD::Egamma* eg) const
370{
371 return calculate(ctx, eg, -99);
372}
373
374double
376 const xAOD::Egamma* eg,
377 double mu) const
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}
383
384// ============================================================================
385// calculateWithCalibPt
386// ============================================================================
387bool
389 const xAOD::Electron* eg,
390 double& score,
391 double& calibPt) const
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
407 const xAOD::TrackParticle* track = eg->trackParticle();
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}
438
439// ============================================================================
440// calculateMultipleOutputs
441// ============================================================================
442std::vector<float>
444 const EventContext& ctx,
445 const xAOD::Electron* eg,
446 double mu) const
447{
448 return { static_cast<float>(calculate(ctx, eg, mu)) };
449}
450
451// ============================================================================
452// getOperatingPointName
453// ============================================================================
454std::string
459
460// ============================================================================
461// getEtaBin
462// ============================================================================
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}
471
472// ============================================================================
473// getPtBin
474// ============================================================================
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}
484
485// ============================================================================
486// getInputs
487// ============================================================================
489 double calibPt,
490 int etaBin,
491 std::vector<double>& inputs) const
492{
493 inputs.clear();
494 inputs.reserve(25);
495
496 const xAOD::CaloCluster* cluster = eg->caloCluster();
497 const xAOD::TrackParticle* track = eg->trackParticle();
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"));
572 inputs.push_back(getMatch(xAOD::EgammaParameters::deltaPhiRescaled2,
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_cuts[3][12][3]
static const double s_ptEdges[13]
static const double s_lrIntercept[3][7]
static const double s_lrCoeff[3][7]
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(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.
std::vector< std::unique_ptr< lwt::LightweightGraph > > m_graphs
virtual double calculate(const EventContext &ctx, const xAOD::IParticle *part) const override
The main result method: the actual DNN is calculated here.
std::vector< std::string > m_variables
Input variable names.
virtual StatusCode initialize() override final
Gaudi Service Interface method implementations.
virtual const asg::AcceptInfo & getAcceptInfo() const override
Method to get the plain AcceptInfo.
Gaudi::Property< std::string > m_workingPoint
Working point: Loose = 90% | Medium = 80% | Tight = 70%.
virtual std::string getOperatingPointName() const override
Method to get the operating point.
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.
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...
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override
IAsgSelectionTool interface.
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.
ToolHandle< AsgForwardElectronCalibrationTool > m_calibTool
Handle to the calibration tool.
bool calculateWithCalibPt(const EventContext &ctx, const xAOD::Electron *eg, double &score, double &calibPt) const
Runs calibration + LR + DNN in a single pass.
virtual ASG_TOOL_CLASS2(AsgForwardElectronSelectorTool, IAsgElectronLikelihoodTool, IAsgSelectionTool) public ~AsgForwardElectronSelectorTool()
Standard constructor.
int m_wpIndex
Working point index: 0 = Loose 1 = Medium 2 = Tight.
asg::AcceptInfo m_acceptInfo
AcceptInfo: defines the cut structure.
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....
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer).
Definition AcceptData.h:135
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double eta() const
The pseudorapidity ( ) of the particle.
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.
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.
bool trackCaloMatchValue(float &value, const EgammaParameters::TrackCaloMatchType information) const
Accessor for Track to Calo Match Values.
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
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...
Class providing the definition of the 4-vector interface.
@ Electron
The object is an electron.
Definition ObjectType.h:46
@ 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...
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".