ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaPrecisionElectronHypoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <algorithm>
6#include <cmath>
12#include "xAODEgamma/Electron.h"
14
15namespace TCU = TrigCompositeUtils;
16
18 const std::string& name,
19 const IInterface* parent )
20 : base_class( type, name, parent ),
21 m_decisionId( HLT::Identifier::fromToolName( name ) ) {
22}
23
24
26{
27 ATH_MSG_DEBUG( "Initialization completed successfully" );
28 ATH_MSG_DEBUG( "EtaBins = " << m_etabin );
29 ATH_MSG_DEBUG( "ETthr = " << m_eTthr );
30 ATH_MSG_DEBUG( "dPHICLUSTERthr = " << m_dphicluster );
31 ATH_MSG_DEBUG( "dETACLUSTERthr = " << m_detacluster );
32 ATH_MSG_DEBUG( "d0Cut = " << m_d0 );
33 ATH_MSG_DEBUG( "DoNoPid = " << m_doNoPid );
34
35 if ( m_etabin.empty() ) {
36 ATH_MSG_ERROR( " There are no cuts set (EtaBins property is an empty list)" );
37 return StatusCode::FAILURE;
38 }
39
40 unsigned int nEtaBin = m_etabin.size();
41 ATH_CHECK( m_eTthr.size() == nEtaBin-1 );
42
43 ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
44
45 if ( not m_monTool.name().empty() )
46 CHECK( m_monTool.retrieve() );
47
48 return StatusCode::SUCCESS;
49}
50
51
53
54 bool pass = true;
55
56 auto mon_ET = Monitored::Scalar( "Et_em" , -1.0 );
57 auto mon_dEta = Monitored::Scalar( "dEta", -1. );
58 auto mon_dPhi = Monitored::Scalar( "dPhi", -1. );
59 auto mon_etaBin = Monitored::Scalar( "EtaBin", -1. );
60 auto mon_Eta = Monitored::Scalar( "Eta", -99. );
61 auto mon_Phi = Monitored::Scalar( "Phi", -99. );
62 auto cutCounter = Monitored::Scalar<int>( "CutCounter", -1 );
63 auto mon_lhval = Monitored::Scalar("LikelihoodRatio", -99.);
64 auto mon_mu = Monitored::Scalar("mu", -1.);
65 auto mon_ptvarcone20 = Monitored::Scalar("ptvarcone20", -99.);
66 auto mon_relptvarcone20 = Monitored::Scalar("relptvarcone20", -99.);
67 auto mon_ptvarcone30 = Monitored::Scalar("ptvarcone30", -99.);
68 auto mon_relptvarcone30 = Monitored::Scalar("relptvarcone30", -99.);
69 auto mon_ptcone20 = Monitored::Scalar("ptcone20", -99.);
70 auto mon_relptcone20 = Monitored::Scalar("relptcone20", -99.);
71 auto mon_ptcone30 = Monitored::Scalar("ptcone30", -99.);
72 auto mon_relptcone30 = Monitored::Scalar("relptcone30", -99.);
73 auto mon_trk_d0 = Monitored::Scalar("trk_d0", -1.);
74 auto monitorIt = Monitored::Group( m_monTool, mon_ET, mon_dEta, mon_dPhi,
75 mon_etaBin, mon_Eta,
76 mon_Phi,cutCounter,mon_lhval,mon_mu,
77 mon_ptvarcone20, mon_relptvarcone20,
78 mon_ptcone20, mon_relptcone20, mon_ptcone30, mon_relptcone30, mon_ptvarcone30, mon_relptvarcone30, mon_trk_d0);
79
80 float ET(0), dEta(0), dPhi(0), eta(0), phi(0), lhval(0), mu(0), trk_d0(0);
81
82 // when leaving scope it will ship data to monTool
83
84 auto roiDescriptor = input.roi;
85
86
87 if ( std::abs( roiDescriptor->eta() ) > 2.6 ) {
88 ATH_MSG_DEBUG( "REJECT The electron had eta coordinates beyond the EM fiducial volume : " << roiDescriptor->eta() << "; stop the chain now" );
89 return false;
90 }
91 cutCounter++;
92 ATH_MSG_DEBUG( "; RoI ID = " << roiDescriptor->roiId()
93 << ": Eta = " << roiDescriptor->eta()
94 << ", Phi = " << roiDescriptor->phi() );
95
96 // fill local variables for RoI reference position
97 double etaRef = roiDescriptor->eta();
98 double phiRef = roiDescriptor->phi();
99 ATH_MSG_DEBUG("etaRef: "<<etaRef);
100 // correct phi the to right range ( probably not needed anymore )
101 if ( std::abs( phiRef ) > M_PI ) phiRef -= 2*M_PI; // correct phi if outside range
102
103 ATH_MSG_DEBUG("AcceptAll: "<<m_acceptAll);
104
105 if(!m_acceptAll){
106
107 pass = false;
108 auto pClus = input.electron->caloCluster();
109
110 float absEta = std::abs( pClus->eta() );
111
112 ATH_MSG_DEBUG("absEta: "<<absEta);
113
114 const int cutIndex = findCutIndex( absEta );
115 ATH_MSG_DEBUG("cutIndex: "<<cutIndex);
116
117
118 dEta = pClus->eta() - etaRef;
119 // Deal with angle diferences greater than Pi
120 dPhi = std::abs( pClus->phi() - phiRef );
121 dPhi = ( dPhi < M_PI ? dPhi : 2*M_PI - dPhi ); // TB why only <
122 ET = pClus->et();
123 eta = pClus->eta();
124 phi = pClus->phi();
125
126 trk_d0 = std::abs(input.electron->trackParticle()->d0());
127
128 // apply cuts: DeltaEta( clus-ROI )
129 ATH_MSG_DEBUG( "Electron : eta=" << pClus->eta()
130 << " roi eta=" << etaRef << " DeltaEta=" << dEta
131 << " cut: <" << m_detacluster );
132
133
134 if ( std::abs( pClus->eta() - etaRef ) > m_detacluster ) {
135 ATH_MSG_DEBUG("REJECT Electron dEta cut failed");
136 return pass;
137 }
138 mon_Eta = eta;
139 mon_dEta = dEta;
140 cutCounter++; //Deta
141
142 // DeltaPhi( clus-ROI )
143 ATH_MSG_DEBUG( ": phi=" << pClus->phi()
144 << " roi phi="<< phiRef << " DeltaPhi="<< dPhi
145 << " cut: <" << m_dphicluster );
146
147 if( dPhi > m_dphicluster ) {
148 ATH_MSG_DEBUG("REJECT Clsuter dPhi cut failed");
149 return pass;
150 }
151 mon_Phi = phi;
152 mon_dPhi = dPhi;
153 cutCounter++; //DPhi
154
155 // eta range
156 if ( cutIndex == -1 ) { // VD
157 ATH_MSG_DEBUG( "Electron : " << absEta << " outside eta range " << m_etabin[m_etabin.size()-1] );
158 return pass;
159 } else {
160 ATH_MSG_DEBUG( "eta bin used for cuts " << cutIndex );
161 }
162 mon_etaBin = m_etabin[cutIndex];
163 cutCounter++; // passed eta cut
164
165 // ET_em
166 ATH_MSG_DEBUG( "Electron: ET_em=" << ET << " cut: >" << m_eTthr[cutIndex] );
167 if ( ET < m_eTthr[cutIndex] ) {
168 ATH_MSG_DEBUG("REJECT et cut failed");
169 return pass;
170 }
171 mon_ET = ET;
172 cutCounter++; // ET_em
173
174 if(m_doNoPid){
175 pass = true;
176 return pass;
177 }
178 // d0 for LRT
179 if (m_d0 and m_d0>0.)
180 {
181 ATH_MSG_DEBUG( "Electron: trk_d0=" << trk_d0 << " cut: >" << m_d0 );
182 if ( trk_d0 < m_d0 ) {
183 ATH_MSG_DEBUG("REJECT d0 cut failed");
184 return pass;
185 }
186 }
187 mon_trk_d0 = trk_d0;
188
189 // This is the last step. So pass is going to be the result of LH
190 // get average luminosity information to calculate LH
191 if(input.valueDecorator.count("avgmu")){
192 mu = input.valueDecorator.at("avgmu");
193 }
194 mon_mu = mu;
195
196 float Rhad1(0), Rhad(0), Reta(0), Rphi(0), e277(0), weta2c(0), //emax2(0),
197 Eratio(0), DeltaE(0), f1(0), weta1c(0), wtot(0), fracm(0);
198
199 float ptvarcone20(999), ptvarcone30(999), ptcone20(999), ptcone30(999), ptcone40(999), etcone20(999), etcone30(999),
200 etcone40(999), topoetcone20(999), topoetcone30(999), topoetcone40(999), relptcone20(999), relptvarcone20(999),relptcone30(999), relptvarcone30(999);
201
202 bool ispt20 = input.electron->isolationValue(ptvarcone20, xAOD::Iso::ptvarcone20);
203 if (!ispt20) {
204 ATH_MSG_WARNING("ptvarcone20 not available. Will not cut on isolation");
205 }
206
207 bool ispt30 = input.electron->isolationValue(ptvarcone30, xAOD::Iso::ptvarcone30);
208 if (!ispt30) {
209 ATH_MSG_WARNING("ptvarcone30 not available. Will not cut on isolation");
210 }
211
212 // variables based on HCAL
213 // transverse energy in 1st scintillator of hadronic calorimeter/ET
214 input.electron->showerShapeValue(Rhad1, xAOD::EgammaParameters::Rhad1);
215 // transverse energy in hadronic calorimeter/ET
216 input.electron->showerShapeValue(Rhad, xAOD::EgammaParameters::Rhad);
217
218 // variables based on S2 of EM CAL
219 // E(7*7) in 2nd sampling
220 input.electron->showerShapeValue(e277, xAOD::EgammaParameters::e277);
221 // E(3*7)/E(7*7) in 2nd sampling
222 input.electron->showerShapeValue(Reta, xAOD::EgammaParameters::Reta);
223 // E(3*3)/E(3*7) in 2nd sampling
224 input.electron->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi);
225 // shower width in 2nd sampling
226 input.electron->showerShapeValue(weta2c, xAOD::EgammaParameters::weta2);
227
228 // variables based on S1 of EM CAL
229 // fraction of energy reconstructed in the 1st sampling
230 input.electron->showerShapeValue(f1, xAOD::EgammaParameters::f1);
231 // shower width in 3 strips in 1st sampling
232 input.electron->showerShapeValue(weta1c, xAOD::EgammaParameters::weta1);
233 // E of 2nd max between max and min in strips [NOT USED]
234 // eg->showerShapeValue(emax2, xAOD::EgammaParameters::e2tsts1);
235 // (E of 1st max in strips-E of 2nd max)/(E of 1st max+E of 2nd max)
236 input.electron->showerShapeValue(Eratio, xAOD::EgammaParameters::Eratio);
237 // E(2nd max)-E(min) in strips
238 input.electron->showerShapeValue(DeltaE, xAOD::EgammaParameters::DeltaE);
239 // total shower width in 1st sampling
240 input.electron->showerShapeValue(wtot, xAOD::EgammaParameters::wtots1);
241 // E(+/-3)-E(+/-1)/E(+/-1)
242 input.electron->showerShapeValue(fracm, xAOD::EgammaParameters::fracs1);
243
244 input.electron->isolationValue(ptcone20, xAOD::Iso::ptcone20);
245
246 input.electron->isolationValue(ptcone30, xAOD::Iso::ptcone30);
247
248 input.electron->isolationValue(ptcone40, xAOD::Iso::ptcone40);
249
250 input.electron->isolationValue(etcone20, xAOD::Iso::etcone20);
251
252 input.electron->isolationValue(etcone30, xAOD::Iso::etcone30);
253
254 input.electron->isolationValue(etcone40, xAOD::Iso::etcone40);
255
256 input.electron->isolationValue(topoetcone20, xAOD::Iso::topoetcone20);
257
258 input.electron->isolationValue(topoetcone30, xAOD::Iso::topoetcone30);
259
260 input.electron->isolationValue(topoetcone40, xAOD::Iso::topoetcone40);
261
262 ATH_MSG_DEBUG(" electron Cluster Et "<<ET);
263 ATH_MSG_DEBUG( " Rhad1 " << Rhad1 ) ;
264 ATH_MSG_DEBUG( " Rhad " << Rhad ) ;
265 ATH_MSG_DEBUG( " e277 " << e277 ) ;
266 ATH_MSG_DEBUG( " Reta " << Reta ) ;
267 ATH_MSG_DEBUG( " Rphi " << Rphi ) ;
268 ATH_MSG_DEBUG( " weta2c " << weta2c ) ;
269 ATH_MSG_DEBUG( " f1 " << f1 ) ;
270 ATH_MSG_DEBUG( " weta1c " << weta1c ) ;
271 ATH_MSG_DEBUG( " Eratio " << Eratio ) ;
272 ATH_MSG_DEBUG( " DeltaE " << DeltaE ) ;
273 ATH_MSG_DEBUG( " wtot " << wtot ) ;
274 ATH_MSG_DEBUG( " fracm " << fracm ) ;
275 ATH_MSG_DEBUG( " trackPT "<<input.electron->trackParticle()->pt());
276 ATH_MSG_DEBUG( " d0 "<<input.electron->trackParticle()->d0());
277 ATH_MSG_DEBUG( " z0 "<<input.electron->trackParticle()->z0());
278 ATH_MSG_DEBUG( " ptvarcone20 " << ptvarcone20 ) ;
279 ATH_MSG_DEBUG( " ptvarcone30 " << ptvarcone30 ) ;
280 ATH_MSG_DEBUG( " ptcone20 " << ptcone20 ) ;
281 ATH_MSG_DEBUG( " ptcone30 " << ptcone30 ) ;
282 ATH_MSG_DEBUG( " ptcone40 " << ptcone40 ) ;
283 ATH_MSG_DEBUG( " etcone20 " << etcone20 ) ;
284 ATH_MSG_DEBUG( " etcone30 " << etcone30 ) ;
285 ATH_MSG_DEBUG( " etcone40 " << etcone40 ) ;
286 ATH_MSG_DEBUG( " topoetcone20 " << topoetcone20 ) ;
287 ATH_MSG_DEBUG( " topoetcone30 " << topoetcone30 ) ;
288 ATH_MSG_DEBUG( " topoetcone40 " << topoetcone40 ) ;
289 // Monitor showershapes
290
291 if (input.electron->pt() >0){
292 relptcone20 = ptcone20/input.electron->pt();
293 relptvarcone20 = ptvarcone20/input.electron->pt();
294 relptcone30 = ptcone30/input.electron->pt();
295 relptvarcone30 = ptvarcone30/input.electron->pt();
296 }
297 mon_ptvarcone20 = ptvarcone20;
298 mon_relptvarcone20 = relptvarcone20;
299 mon_ptcone20 = ptcone20;
300 mon_relptcone20 = relptcone20;
301
302 mon_ptvarcone30 = ptvarcone30;
303 mon_relptvarcone30 = relptvarcone30;
304 mon_ptcone30 = ptcone30;
305 mon_relptcone30 = relptcone30;
306
307 ATH_MSG_DEBUG("relptvarcone20 = " << relptvarcone20 );
308 ATH_MSG_DEBUG("relptcone20 = " << relptcone20 );
309 ATH_MSG_DEBUG("m_RelPtConeCut = " << m_RelPtConeCut );
310 ATH_MSG_DEBUG("m_TopoEtConeCut = " << m_TopoEtConeCut);
311
312 // Only for LH
313 if( input.valueDecorator.count(m_pidName+"LHValue")){
314 lhval = input.valueDecorator.at(m_pidName+"LHValue");
315 }
316 mon_lhval = lhval;
317 // Should works for DNN and LH
318 if( input.pidDecorator.count(m_pidName) )
319 {
320 pass = input.pidDecorator.at(m_pidName);
321 }
322 // Evaluating lh *after* retrieving variables for monitoing and debuging purposes
323 ATH_MSG_DEBUG("AthenaLHSelectorTool: TAccept = " << pass);
324 if ( !pass ){
325 ATH_MSG_DEBUG("REJECT Likelihood failed");
326 return pass;
327 } else {
328 ATH_MSG_DEBUG("ACCEPT Likelihood passed");
329 cutCounter++;
330 }
331
332 // Check if need to apply isolation
333 // First check logic. if cut is very negative, then no isolation cut is defined
334 // if m_RelPtConeCut <-100 then hypo is configured not to apply isolation
335 if (m_RelPtConeCut < -100){
336 ATH_MSG_DEBUG(" not applying isolation. Returning NOW");
337 ATH_MSG_DEBUG("TAccept = " << pass);
338 return pass;
339 }
340
342 pass = (relptvarcone30 < m_RelPtConeCut);
343 ATH_MSG_DEBUG("reptvarcon30_rel cut is: " << m_RelPtConeCut);
344 if (!pass){
345 ATH_MSG_DEBUG(" ACCEPT Isolation ptvarcon30_rel cut failed");
346 return pass;
347 }else{
348 ATH_MSG_DEBUG(" ACCEPT Isolation ptvarcon30_rel cut passed");
349 cutCounter++;
350 }
351 }
353 pass = (relptvarcone30 < m_RelPtConeCut && topoetcone20/input.electron->pt() < m_TopoEtConeCut);
354 if (!pass){
355 return pass;
356 }else{
357 cutCounter++;
358 }
359 }
361 // Then, It will pass if relptcone20 is less than cut:
362 pass = (relptvarcone20 < m_RelPtConeCut);
363 ATH_MSG_DEBUG("reptvarcon20_rel cut is: " << m_RelPtConeCut);
364 if (!pass){
365 ATH_MSG_DEBUG(" ACCEPT Isolation ptvarcon20_rel cut failed");
366 return pass;
367 }else{
368 ATH_MSG_DEBUG(" ACCEPT Isolation ptvarcon20_rel cut passed");
369 cutCounter++;
370 }
371 }
372
373 } // end of if(!m_acceptAll)
374 ATH_MSG_DEBUG( "pass = " << pass );
375 return pass;
376}
377
378
379
381 const float absEta = std::abs(eta);
382 auto binIterator = std::adjacent_find( m_etabin.begin(), m_etabin.end(), [=](float left, float right){ return left < absEta and absEta < right; } );
383 if ( binIterator == m_etabin.end() ) {
384 return -1;
385 }
386 return binIterator - m_etabin.begin();
387}
388
389
390StatusCode TrigEgammaPrecisionElectronHypoTool::decide( std::vector<ElectronInfo>& input) const {
391 for ( auto& i: input ) {
392 if ( TCU::passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
393 if ( decide( i ) ) {
394 TCU::addDecisionID( m_decisionId, i.decision );
395 }
396 }
397 }
398 return StatusCode::SUCCESS;
399}
400
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Header file to be included by clients of the Monitored infrastructure.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
Gaudi::Property< std::vector< float > > m_eTthr
TrigEgammaPrecisionElectronHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< std::vector< float > > m_etabin
selection variable for PRECISION electron selection:eta bins
virtual StatusCode decide(std::vector< ITrigEgammaPrecisionElectronHypoTool::ElectronInfo > &input) const override
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
void addDecisionID(DecisionID id, Decision *d)
Appends the decision (given as ID) to the decision object.
@ wtots1
shower width is determined in a window detaxdphi = 0,0625 ×~0,2, corresponding typically to 20 strips...
@ e277
uncalibrated energy (sum of cells) of the middle sampling in a rectangle of size 7x7
Definition EgammaEnums.h:81
@ 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)
@ DeltaE
e2tsts1-emins1
@ fracs1
shower shape in the shower core : [E(+/-3)-E(+/-1)]/E(+/-1), where E(+/-n) is the energy in ± n strip...
@ weta2
the lateral width is calculated with a window of 3x5 cells using the energy weighted sum over all cel...
@ weta1
shower width using +/-3 strips around the one with the maximal energy deposit: w3 strips = sqrt{sum(E...
Definition EgammaEnums.h:98
@ topoetcone20
Topo-cluster ET-sum.
@ etcone20
Calorimeter isolation.
@ ptcone20
Track isolation.
@ ptvarcone20
Mini-Isolation http://arxiv.org/abs/1007.2221.