ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaPrecisionPhotonHypoTool.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>
10#include "xAODEgamma/Photon.h"
12
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( "DoNoPid = " << m_doNoPid );
33
34 if ( m_etabin.empty() ) {
35 ATH_MSG_ERROR( " There are no cuts set (EtaBins property is an empty list)" );
36 return StatusCode::FAILURE;
37 }
38
39 // Now we try to retrieve the ElectronPhotonSelectorTools that we will use to apply the photon Identification. This is a *must*
40
41
42 // Retrieving Luminosity info
43 ATH_MSG_DEBUG( "Retrieving luminosityCondData..." );
44 ATH_CHECK( m_avgMuKey.initialize() );
45
46 unsigned int nEtaBin = m_etabin.size();
47
48#define CHECK_SIZE( __n) if ( m_##__n.size() != (nEtaBin - 1) ) \
49 { ATH_MSG_DEBUG(" __n size is " << m_##__n.size() << " but needs to be " << (nEtaBin - 1) ); return StatusCode::FAILURE; }
50
51 CHECK_SIZE( eTthr );
52#undef CHECK_SIZE
53
54 ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
55
56 if ( not m_monTool.name().empty() )
57 CHECK( m_monTool.retrieve() );
58
59 return StatusCode::SUCCESS;
60}
61
62
64{
65
66 bool pass = false;
67
68 auto mon_ET = Monitored::Scalar( "Et_em", -1.0 );
69 auto mon_dEta = Monitored::Scalar( "dEta", -1.0 );
70 auto mon_dPhi = Monitored::Scalar( "dPhi", -1.0 );
71 auto mon_etaBin = Monitored::Scalar( "EtaBin", -1.0 );
72 auto mon_Eta = Monitored::Scalar( "Eta", -99. );
73 auto mon_Phi = Monitored::Scalar( "Phi", -99. );
74 auto mon_mu = Monitored::Scalar("mu", -1.);
75
76 auto PassedCuts = Monitored::Scalar<int>( "CutCounter", -1 );
77 auto monitorIt = Monitored::Group( m_monTool, mon_ET, mon_dEta, mon_dPhi,
78 mon_etaBin, mon_Eta, mon_Phi, mon_mu,
79 PassedCuts );
80
81 // when leaving scope it will ship data to monTool
82 PassedCuts = PassedCuts + 1; //got called (data in place)
83
84 float ET(0), dEta(0), dPhi(0), eta(0), phi(0);
85
86 auto roiDescriptor = input.roi;
87
88 if ( fabs( roiDescriptor->eta() ) > 2.6 ) {
89 ATH_MSG_DEBUG( "REJECT The photon had eta coordinates beyond the EM fiducial volume : "
90 << roiDescriptor->eta() << "; stop the chain now" );
91 pass=false; // special case
92 return pass;
93 }
94
95 ATH_MSG_DEBUG( "; RoI ID = " << roiDescriptor->roiId()
96 << ": Eta = " << roiDescriptor->eta()
97 << ", Phi = " << roiDescriptor->phi() );
98
99 // fill local variables for RoI reference position
100 double etaRef = roiDescriptor->eta();
101 double phiRef = roiDescriptor->phi();
102 // correct phi the to right range ( probably not needed anymore )
103 if ( fabs( phiRef ) > M_PI ) phiRef -= 2*M_PI; // correct phi if outside range
104
105 auto pClus = input.photon->caloCluster();
106
107 float absEta = fabs( pClus->eta() );
108 const int cutIndex = findCutIndex( absEta );
109
110 dEta = pClus->eta() - etaRef;
111 // Deal with angle diferences greater than Pi
112 dPhi = fabs( pClus->phi() - phiRef );
113 dPhi = ( dPhi < M_PI ? dPhi : 2*M_PI - dPhi ); // TB why only <
114 ET = pClus->et();
115 eta = pClus->eta();
116 phi = pClus->phi();
117 // apply cuts: DeltaEta( clus-ROI )
118 ATH_MSG_DEBUG( "Photon : eta=" << pClus->eta()
119 << " roi eta=" << etaRef << " DeltaEta=" << dEta
120 << " cut: <" << m_detacluster );
121
122 if ( fabs( pClus->eta() - etaRef ) > m_detacluster ) {
123 ATH_MSG_DEBUG("REJECT Photon a cut failed");
124 return pass;
125 }
126 mon_Eta = eta;
127 mon_dEta = dEta;
128 PassedCuts = PassedCuts + 1; //Deta
129
130 // DeltaPhi( clus-ROI )
131 ATH_MSG_DEBUG( ": phi=" << pClus->phi()
132 << " roi phi="<< phiRef << " DeltaPhi="<< dPhi
133 << " cut: <" << m_dphicluster );
134
135 if( dPhi > m_dphicluster ) {
136 ATH_MSG_DEBUG("REJECT Clsuter dPhi cut failed");
137 return pass;
138 }
139 mon_Phi = phi;
140 mon_dPhi = dPhi;
141 PassedCuts = PassedCuts + 1; //DPhi
142
143 // eta range
144 if ( cutIndex == -1 ) { // VD
145 ATH_MSG_DEBUG( "Photon : " << absEta << " outside eta range " << m_etabin[m_etabin.size()-1] );
146 return pass;
147 } else {
148 ATH_MSG_DEBUG( "eta bin used for cuts " << cutIndex );
149 }
150 mon_etaBin = m_etabin[cutIndex];
151 PassedCuts = PassedCuts + 1; // passed eta cut
152
153 // ET_em
154 ATH_MSG_DEBUG( "Photon: ET_em=" << ET << " cut: >" << m_eTthr[cutIndex] );
155 if ( ET < m_eTthr[cutIndex] ) {
156 ATH_MSG_DEBUG("REJECT et cut failed");
157 return pass;
158 }
159 mon_ET = ET;
160 PassedCuts = PassedCuts + 1; // ET_em
161 if(m_doNoPid){
162 pass = true;
163 return pass;
164 }
165
166 if(input.pidDecorator.count(m_pidName)){
167 pass = input.pidDecorator.at(m_pidName);
168 }
169
170 // get average luminosity information to calculate LH
171 float avg_mu = 0;
173 if(eventInfoDecor.isPresent()) {
174 avg_mu = eventInfoDecor(0);
175 ATH_MSG_DEBUG("Average mu " << avg_mu);
176 }
177 mon_mu = avg_mu;
178
179 float Rhad1(0), Rhad(0), Reta(0), Rphi(0), e277(0), weta2c(0), //emax2(0),
180 Eratio(0), DeltaE(0), f1(0), weta1c(0), wtot(0), fracm(0);
181
182
183 // variables based on HCAL
184 // transverse energy in 1st scintillator of hadronic calorimeter/ET
185 input.photon->showerShapeValue(Rhad1, xAOD::EgammaParameters::Rhad1);
186 // transverse energy in hadronic calorimeter/ET
187 input.photon->showerShapeValue(Rhad, xAOD::EgammaParameters::Rhad);
188
189 // variables based on S2 of EM CAL
190 // E(7*7) in 2nd sampling
191 input.photon->showerShapeValue(e277, xAOD::EgammaParameters::e277);
192 // E(3*7)/E(7*7) in 2nd sampling
193 input.photon->showerShapeValue(Reta, xAOD::EgammaParameters::Reta);
194 // E(3*3)/E(3*7) in 2nd sampling
195 input.photon->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi);
196 // shower width in 2nd sampling
197 input.photon->showerShapeValue(weta2c, xAOD::EgammaParameters::weta2);
198
199 // variables based on S1 of EM CAL
200 // fraction of energy reconstructed in the 1st sampling
201 input.photon->showerShapeValue(f1, xAOD::EgammaParameters::f1);
202 // shower width in 3 strips in 1st sampling
203 input.photon->showerShapeValue(weta1c, xAOD::EgammaParameters::weta1);
204 // E of 2nd max between max and min in strips [NOT USED]
205 // eg->showerShapeValue(emax2, xAOD::EgammaParameters::e2tsts1);
206 // (E of 1st max in strips-E of 2nd max)/(E of 1st max+E of 2nd max)
207 input.photon->showerShapeValue(Eratio, xAOD::EgammaParameters::Eratio);
208 // E(2nd max)-E(min) in strips
209 input.photon->showerShapeValue(DeltaE, xAOD::EgammaParameters::DeltaE);
210 // total shower width in 1st sampling
211 input.photon->showerShapeValue(wtot, xAOD::EgammaParameters::wtots1);
212 // E(+/-3)-E(+/-1)/E(+/-1)
213 input.photon->showerShapeValue(fracm, xAOD::EgammaParameters::fracs1);
214
215 ATH_MSG_DEBUG( " Rhad = " << Rhad ) ;
216 ATH_MSG_DEBUG( " Rhad1 = " << Rhad1 ) ;
217 ATH_MSG_DEBUG( " e277 = " << e277 ) ;
218 ATH_MSG_DEBUG( " Reta = " << Reta ) ;
219 ATH_MSG_DEBUG( " Rphi = " << Rphi ) ;
220 ATH_MSG_DEBUG( " weta2c = " << weta2c ) ;
221 ATH_MSG_DEBUG( " f1 = " << f1 ) ;
222 ATH_MSG_DEBUG( " weta1c = " << weta1c ) ;
223 ATH_MSG_DEBUG( " Eratio = " << Eratio ) ;
224 ATH_MSG_DEBUG( " DeltaE = " << DeltaE ) ;
225 ATH_MSG_DEBUG( " wtot = " << wtot ) ;
226 ATH_MSG_DEBUG( " fracm = " << fracm ) ;
227
228 if ( !pass ){
229 ATH_MSG_DEBUG("REJECT isEM failed");
230 return pass;
231 } else {
232 ATH_MSG_DEBUG("ACCEPT isEM passed");
233 }
234 // Monitor showershapes
235 ATH_MSG_DEBUG( "pass = " << pass );
236
237 return pass;
238
239}
240
242 const float absEta = std::abs(eta);
243
244 auto binIterator = std::adjacent_find( m_etabin.begin(), m_etabin.end(), [=](float left, float right){ return left < absEta and absEta < right; } );
245 if ( binIterator == m_etabin.end() ) {
246 return -1;
247 }
248 return binIterator - m_etabin.begin();
249}
250
251
252StatusCode TrigEgammaPrecisionPhotonHypoTool::decide( std::vector<PhotonInfo>& input ) const {
253 for ( auto& i: input ) {
254 if ( TCU::passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
255 if ( decide( i ) ) {
256 TCU::addDecisionID( m_decisionId, i.decision );
257 }
258 }
259 }
260 return StatusCode::SUCCESS;
261}
#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_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Header file to be included by clients of the Monitored infrastructure.
#define CHECK_SIZE(__n)
TrigCompositeUtils::DecisionID numeric() const
numeric ID
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced container present in SG?
Gaudi::Property< std::vector< float > > m_eTthr
TrigEgammaPrecisionPhotonHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< std::vector< float > > m_etabin
selection variable for PRECISION calo selection:eta bins
virtual StatusCode decide(std::vector< ITrigEgammaPrecisionPhotonHypoTool::PhotonInfo > &input) const override
ToolHandle< GenericMonitoringTool > m_monTool
SG::ReadDecorHandleKey< xAOD::EventInfo > m_avgMuKey
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