ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaFastCaloHypoTool.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 <format>
10#include "GaudiKernel/SystemOfUnits.h"
12
13
14using namespace TrigCompositeUtils;
15
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
28
30
31
32 ATH_MSG_DEBUG( "UseRinger = " << m_useRinger);
33 ATH_MSG_DEBUG( "AcceptAll = " << std::format("{}", m_acceptAll.value()) );
34 ATH_MSG_DEBUG( "EtaBins = " << m_etabin );
35 ATH_MSG_DEBUG( "ETthr = " << m_eTthr << "( lo )/" << m_eT2thr << "( hi )" );
36 ATH_MSG_DEBUG( "HADETthr = " << m_hadeTthr << "( lo )/" << m_hadeT2thr << "( hi )" );
37 ATH_MSG_DEBUG( "CARCOREthr = " << m_carcorethr );
38 ATH_MSG_DEBUG( "CAERATIOthr = " << m_caeratiothr );
39 ATH_MSG_DEBUG( "dPHICLUSTERthr = " << m_dphicluster );
40 ATH_MSG_DEBUG( "dETACLUSTERthr = " << m_detacluster );
41 ATH_MSG_DEBUG( "WETA2thr = " << m_WETA2thr );
42 ATH_MSG_DEBUG( "WSTOTthr = " << m_WSTOTthr );
43 ATH_MSG_DEBUG( "F3thr = " << m_F3thr );
44
45 if ( m_etabin.empty() ) {
46 ATH_MSG_ERROR( "There are no cuts set (EtaBins property is an empty list)" );
47 return StatusCode::FAILURE;
48 }
49
50 ATH_CHECK( m_eTthr.size() == m_etabin.size()-1 );
51 ATH_CHECK( m_eT2thr.size() == m_etabin.size()-1 );
52 ATH_CHECK( m_hadeTthr.size() == m_etabin.size()-1 );
53 ATH_CHECK( m_hadeT2thr.size() == m_etabin.size()-1 );
54 ATH_CHECK( m_carcorethr.size() == m_etabin.size()-1 );
55 ATH_CHECK( m_caeratiothr.size() == m_etabin.size()-1 );
56 ATH_CHECK( m_WETA2thr.size() == m_etabin.size()-1 );
57 ATH_CHECK( m_WSTOTthr.size() == m_etabin.size()-1 );
58 ATH_CHECK( m_F3thr.size() == m_etabin.size()-1 );
59
60 ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
61
62 if ( not m_monTool.name().empty() ) {
63 CHECK( m_monTool.retrieve() );
64 }
65
66 return StatusCode::SUCCESS;
67}
68
69
70StatusCode TrigEgammaFastCaloHypoTool::decide( std::vector<FastClusterInfo>& input ) const
71{
72 for ( auto& i: input ) {
73 if ( passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
74 if ( decide( i ) ) {
75 addDecisionID( m_decisionId, i.decision );
76 }
77 }
78 }
79 return StatusCode::SUCCESS;
80}
81
82
87
88
89
91{
92
93 bool pass = false;
94
95 auto mon_dEta = Monitored::Scalar( "dEta", -1.0 );
96 auto mon_dPhi = Monitored::Scalar( "dPhi", -1.0 );
97 auto mon_eT_T2Calo = Monitored::Scalar( "Et_em", -1.0 );
98 auto mon_hadET_T2Calo = Monitored::Scalar( "Et_had", -1.0 );
99 auto mon_rCore = Monitored::Scalar( "RCore", -1.0 );
100 auto mon_energyRatio = Monitored::Scalar( "Eratio", -1.0 );
101 auto mon_etaBin = Monitored::Scalar( "EtaBin", -1.0 );
102 auto mon_Eta = Monitored::Scalar( "Eta", -99. );
103 auto mon_Phi = Monitored::Scalar( "Phi", -99. );
104 auto mon_F1 = Monitored::Scalar( "F1", -1.0 );
105 auto mon_Weta2 = Monitored::Scalar( "Weta2", -1.0 );
106 auto mon_Wstot = Monitored::Scalar( "Wstot", -1.0 );
107 auto mon_F3 = Monitored::Scalar( "F3", -1.0 );
108 auto PassedCuts = Monitored::Scalar<int>( "CutCounter", -1 );
109 auto monitorIt = Monitored::Group( m_monTool,
110 mon_dEta, mon_dPhi, mon_eT_T2Calo, mon_hadET_T2Calo,
111 mon_rCore, mon_energyRatio, mon_etaBin, mon_Eta,
112 mon_Phi, mon_F1, mon_Weta2, mon_Wstot, mon_F3, PassedCuts );
113 // when leaving scope it will ship data to monTool
114 PassedCuts = PassedCuts + 1; //got called (data in place)
115
116 float dEta(0), dPhi(0), eT_T2Calo(0), rCore(0), hadET_T2Calo(0), energyRatio(0), eta(0), phi(0), F1(0), Weta2(0), Wstot(0), F3(0);
117
118 if ( m_acceptAll ) {
119 pass = true;
120 ATH_MSG_DEBUG( "AcceptAll property is set: taking all events" );
121 } else {
122 pass = false;
123 ATH_MSG_DEBUG( "AcceptAll property not set: applying selection" );
124 }
125
126 auto roiDescriptor = input.roi;
127
128 if ( fabs( roiDescriptor->eta() ) > 2.6 ) {
129 ATH_MSG_DEBUG( "REJECT The cluster had eta coordinates beyond the EM fiducial volume : " << roiDescriptor->eta() << "; stop the chain now" );
130 pass=false; // special case
131 return pass;
132 }
133
134 ATH_MSG_DEBUG( "; RoI ID = " << roiDescriptor->roiId()
135 << ": Eta = " << roiDescriptor->eta()
136 << ", Phi = " << roiDescriptor->phi() );
137
138 // fill local variables for RoI reference position
139 double etaRef = roiDescriptor->eta();
140 double phiRef = roiDescriptor->phi();
141 // correct phi the to right range ( probably not needed anymore )
142 if ( fabs( phiRef ) > M_PI ) phiRef -= 2*M_PI; // correct phi if outside range
143
144 auto pClus = input.cluster;
145 float absEta = fabs( pClus->eta() );
146
147 eta = pClus->eta();
148 phi = pClus->phi();
149 const int cutIndex = findCutIndex( absEta );
150
151 // find if electron is in calorimeter crack
152 bool inCrack = ( absEta > 2.37 || ( absEta > 1.37 && absEta < 1.52 ) );
153 dEta = pClus->eta() - etaRef;
154
155 // Deal with angle diferences greater than Pi
156 dPhi = fabs( pClus->phi() - phiRef );
157 dPhi = ( dPhi < M_PI ? dPhi : 2*M_PI - dPhi ); // TB why only <
158
159 // calculate cluster quantities // definition taken from TrigElectron constructor
160 if ( pClus->emaxs1() + pClus->e2tsts1() > 0 )
161 energyRatio = ( pClus->emaxs1() - pClus->e2tsts1() ) / ( pClus->emaxs1() + pClus->e2tsts1() );
162
163 // ( VD ) here the definition is a bit different to account for the cut of e277 @ EF
164 if ( pClus->e277()!= 0. ) rCore = pClus->e237() / pClus->e277();
165
166 //fraction of energy deposited in 1st sampling
167 if ( fabs( pClus->energy() ) > 0.00001 ) F1 = ( pClus->energy( CaloSampling::EMB1 )+pClus->energy( CaloSampling::EME1 ) )/pClus->energy();
168 eT_T2Calo = pClus->et();
169 if ( eT_T2Calo!=0 && pClus->eta()!=0 ) hadET_T2Calo = pClus->ehad1()/cosh( fabs( pClus->eta() ) )/eT_T2Calo;
170
171 //extract Weta2 varable
172 Weta2 = pClus->weta2();
173
174 //extract Wstot varable
175 Wstot = pClus->wstot();
176
177 //extract F3 ( backenergy i EM calorimeter
178 float e0 = pClus->energy( CaloSampling::PreSamplerB ) + pClus->energy( CaloSampling::PreSamplerE );
179 float e1 = pClus->energy( CaloSampling::EMB1 ) + pClus->energy( CaloSampling::EME1 );
180 float e2 = pClus->energy( CaloSampling::EMB2 ) + pClus->energy( CaloSampling::EME2 );
181 float e3 = pClus->energy( CaloSampling::EMB3 ) + pClus->energy( CaloSampling::EME3 );
182 float eallsamples = e0+e1+e2+e3;
183 F3 = fabs( eallsamples )>0. ? e3/eallsamples : 0.;
184
185 // apply cuts: DeltaEta( clus-ROI )
186 ATH_MSG_DEBUG( "TrigEMCluster: eta=" << pClus->eta()
187 << " roi eta=" << etaRef << " DeltaEta=" << dEta
188 << " cut: <" << m_detacluster );
189
190 if ( fabs( pClus->eta() - etaRef ) > m_detacluster ) {
191 ATH_MSG_DEBUG("REJECT Cluster dEta cut failed");
192 return pass;
193 }
194 mon_dEta = dEta;
195 mon_Eta = eta;
196 PassedCuts = PassedCuts + 1; //Deta
197
198 // DeltaPhi( clus-ROI )
199 ATH_MSG_DEBUG( ": phi=" << pClus->phi()
200 << " roi phi="<< phiRef << " DeltaPhi="<< dPhi
201 << " cut: <" << m_dphicluster );
202
203 if( dPhi > m_dphicluster ) {
204 ATH_MSG_DEBUG("REJECT Clsuter dPhi cut failed");
205 return pass;
206 }
207 mon_dPhi = dPhi;
208 mon_Phi = phi;
209 PassedCuts = PassedCuts + 1; //DPhi
210
211 // eta range
212 if ( cutIndex == -1 ) { // VD
213 ATH_MSG_DEBUG( "Cluster eta: " << absEta << " outside eta range " << m_etabin[m_etabin.size()-1] );
214 return pass;
215 }
216 else {
217 ATH_MSG_DEBUG( "eta bin used for cuts " << cutIndex );
218 }
219 mon_etaBin = m_etabin[cutIndex];
220 PassedCuts = PassedCuts + 1; // passed eta cut
221
222 // Rcore
223 ATH_MSG_DEBUG ( "TrigEMCluster: Rcore=" << rCore
224 << " cut: >" << m_carcorethr[cutIndex] );
225 if ( rCore < m_carcorethr[cutIndex] ) {
226 ATH_MSG_DEBUG("REJECT rCore cut failed");
227 return pass;
228 }
229 mon_rCore = rCore;
230 PassedCuts = PassedCuts + 1; //Rcore
231
232 // Eratio
233 ATH_MSG_DEBUG( " cut: >" << m_caeratiothr[cutIndex] );
234 if ( inCrack || F1 < m_F1thr[0] ) {
235 ATH_MSG_DEBUG ( "TrigEMCluster: InCrack= " << inCrack << " F1=" << F1 );
236 }
237 else {
238 if ( energyRatio < m_caeratiothr[cutIndex] ) {
239 ATH_MSG_DEBUG("REJECT e ratio cut failed");
240 return pass;
241 }
242 }
243 PassedCuts = PassedCuts + 1; //Eratio
244 if( inCrack ) energyRatio = -1; //Set default value in crack for monitoring.
245 mon_energyRatio = energyRatio;
246
247 // ET_em
248 ATH_MSG_DEBUG( "TrigEMCluster: ET_em=" << eT_T2Calo << " cut: >" << m_eTthr[cutIndex] );
249 if ( eT_T2Calo < m_eTthr[cutIndex] ) {
250 ATH_MSG_DEBUG("REJECT et cut failed");
251 return pass;
252 }
253 mon_eT_T2Calo = eT_T2Calo;
254 PassedCuts = PassedCuts + 1; // ET_em
255
256 float hadET_cut = 0.0;
257 // find which ET_had to apply : this depends on the ET_em and the eta bin
258 if ( eT_T2Calo > m_eT2thr[cutIndex] ) {
259 hadET_cut = m_hadeT2thr[cutIndex] ;
260 ATH_MSG_DEBUG ( "ET_em>" << m_eT2thr[cutIndex] << ": use high ET_had cut: <" << hadET_cut );
261 }
262 else {
263 hadET_cut = m_hadeTthr[cutIndex];
264 ATH_MSG_DEBUG ( "ET_em<" << m_eT2thr[cutIndex] << ": use low ET_had cut: <" << hadET_cut );
265 }
266
267 // ET_had
268 ATH_MSG_DEBUG ( "TrigEMCluster: ET_had=" << hadET_T2Calo << " cut: <" << hadET_cut );
269 if ( hadET_T2Calo > hadET_cut ) {
270 ATH_MSG_DEBUG("REJECT et had cut failed");
271 return pass;
272 }
273 mon_hadET_T2Calo = hadET_T2Calo;
274 PassedCuts = PassedCuts + 1; //ET_had
275
276 // F1
277 ATH_MSG_DEBUG ( "TrigEMCluster: F1=" << F1 << " cut: >" << m_F1thr[0] );
278 mon_F1 = F1;
279 PassedCuts = PassedCuts + 1; //F1
280
281 //Weta2
282 ATH_MSG_DEBUG ( "TrigEMCluster: Weta2=" << Weta2 << " cut: <" << m_WETA2thr[cutIndex] );
283 if ( Weta2 > m_WETA2thr[cutIndex] ) {
284 ATH_MSG_DEBUG("REJECT weta 2 cut failed");
285 return pass;
286 }
287 mon_Weta2 = Weta2;
288 PassedCuts = PassedCuts + 1; //Weta2
289
290 //Wstot
291 ATH_MSG_DEBUG ( "TrigEMCluster: Wstot=" <<Wstot << " cut: <" << m_WSTOTthr[cutIndex] );
292 if ( Wstot >= m_WSTOTthr[cutIndex] ) {
293 ATH_MSG_DEBUG("REJECT wstot cut failed");
294 return pass;
295 }
296 mon_Wstot = Wstot;
297 PassedCuts = PassedCuts + 1; //Wstot
298
299 //F3
300 ATH_MSG_DEBUG( "TrigEMCluster: F3=" << F3 << " cut: <" << m_F3thr[cutIndex] );
301 if ( F3 > m_F3thr[cutIndex] ) {
302 ATH_MSG_DEBUG("REJECT F3 cut failed");
303 return pass;
304 }
305 mon_F3 = F3;
306 PassedCuts = PassedCuts + 1; //F3
307
308 // got this far => passed!
309 pass = true;
310
311 // Reach this point successfully
312 ATH_MSG_DEBUG( "pass = " << pass );
313
314
315
316 return pass;
317
318}
319
320
321
323{
324
325 auto mon_et = Monitored::Scalar("Et",-100);
326 auto mon_eta = Monitored::Scalar("Eta",-100);
327 auto mon_phi = Monitored::Scalar("Phi",-100);
328 auto mon_NNOutput = Monitored::Scalar("NNOutput",-100);
329
330 auto mon = Monitored::Group(m_monTool,mon_et,mon_eta,mon_phi,mon_NNOutput);
331
332 float et(0), eta(0), phi(0), NNOutput(0);
333
334 if ( m_acceptAll ) {
335 ATH_MSG_DEBUG( "AcceptAll property is set: taking all events" );
336 return true;
337 } else {
338 ATH_MSG_DEBUG( "AcceptAll property not set: applying selection" );
339 }
340
341 auto ringerShape = input.ringerShape;
342 const xAOD::TrigEMCluster *emCluster = nullptr;
343
344 if(ringerShape){
345 emCluster = ringerShape->emCluster();
346 if(!emCluster){
347 ATH_MSG_DEBUG("There is no link to xAOD::TrigEMCluster into the Ringer object.");
348 return false;
349 }
350 }
351 else{
352 ATH_MSG_WARNING( "There is no xAOD::TrigRingerRings link into the rnnOutput object.");
353 return false;
354 }
355
356
357 et = emCluster->et();
358 eta = emCluster->eta();
359 phi = emCluster->phi();
360
361 if(et < m_emEtCut){
362 ATH_MSG_DEBUG( "Event reproved by Et threshold. Et = " << et << ", EtCut = " << m_emEtCut/Gaudi::Units::GeV);
363 return false;
364 }
365 mon_et = et;
366 mon_eta = eta;
367 mon_phi = phi;
368
369 bool pass = false;
370 if( input.pidDecorator.count(m_pidName)){
371 NNOutput = input.valueDecorator.at(m_pidName+"NNOutput");
372 pass = input.pidDecorator.at(m_pidName);
373 ATH_MSG_DEBUG( "ET Cut " << m_emEtCut <<" Get the decision for " << m_pidName << ": " << (pass?"Yes":"No") );
374 }else{
375 ATH_MSG_DEBUG( "Pid name " << m_pidName << " not found into the decorator. Probably this decision was not computed by the hypo alg." );
376 }
377 mon_NNOutput = NNOutput;
378
379 return pass;
380}
381
382
384{
385 const float absEta = std::abs(eta);
386 auto binIterator = std::adjacent_find( m_etabin.begin(), m_etabin.end(), [=](float left, float right){ return left < absEta and absEta < right; } );
387 if ( binIterator == m_etabin.end() ) {
388 return -1;
389 }
390 return binIterator - m_etabin.begin();
391}
392
393
#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.
float et(const xAOD::jFexSRJetRoI *j)
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_hadeT2thr
Gaudi::Property< std::vector< float > > m_F3thr
bool decide_cutbased(const ITrigEgammaFastCaloHypoTool::FastClusterInfo &i) const
bool decide_ringer(const ITrigEgammaFastCaloHypoTool::FastClusterInfo &i) const
virtual StatusCode decide(std::vector< ITrigEgammaFastCaloHypoTool::FastClusterInfo > &input) const override
Gaudi::Property< std::vector< float > > m_WETA2thr
virtual StatusCode initialize() override
Gaudi::Property< std::vector< float > > m_F1thr
ToolHandle< GenericMonitoringTool > m_monTool
Gaudi::Property< std::vector< float > > m_WSTOTthr
Gaudi::Property< std::vector< float > > m_caeratiothr
Gaudi::Property< std::vector< float > > m_eT2thr
TrigEgammaFastCaloHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< std::vector< float > > m_carcorethr
Gaudi::Property< std::vector< float > > m_etabin
selection variable for L2 calo selection:eta bins
Gaudi::Property< float > m_detacluster
Gaudi::Property< std::vector< float > > m_eTthr
Gaudi::Property< std::vector< float > > m_hadeTthr
Gaudi::Property< std::string > m_pidName
Gaudi::Property< float > m_dphicluster
float et() const
get Et (calibrated)
float eta() const
get Eta (calibrated)
float phi() const
get Phi (calibrated)
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.
TrigEMCluster_v1 TrigEMCluster
Define the latest version of the trigger EM cluster class.
Extra patterns decribing particle interation process.