ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaPrecisionPhotonCaloIsoHypoTool.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/*
6 * =====================================================================================
7 *
8 * Filename: TrigEgammaPrecisionPhotonCaloIsoHypoTool.cxx
9 *
10 * Description: Hypo tool for Calorimeter isolation applied HLT precision step for photon triggers
11 *
12 * Created: 08/09/2022 11:19:55 AM
13 *
14 * Author: Fernando Monticelli (), Fernando.Monticelli@cern.ch
15 * Organization: UNLP/IFLP/CONICET
16 *
17 * =====================================================================================
18 */
19#include <algorithm>
24#include "xAODEgamma/Photon.h"
26
28
29namespace TCU = TrigCompositeUtils;
30
32 const std::string& name,
33 const IInterface* parent )
34 : base_class( type, name, parent ),
35 m_decisionId( HLT::Identifier::fromToolName( name ) ) {
36}
37
38
40{
41 ATH_MSG_DEBUG( "Initialization completed successfully" );
42 ATH_MSG_DEBUG( "EtaBins = " << m_etabin );
43
44 if ( m_etabin.empty() ) {
45 ATH_MSG_ERROR( " There are no cuts set (EtaBins property is an empty list)" );
46 return StatusCode::FAILURE;
47 }
48
49 // Now we try to retrieve the ElectronPhotonSelectorTools that we will use to apply the photon Identification. This is a *must*
50
51
52 // Retrieving Luminosity info
53 ATH_MSG_DEBUG( "Retrieving luminosityCondData..." );
54 ATH_CHECK( m_avgMuKey.initialize() );
55
56 ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
57
58 if ( not m_monTool.name().empty() )
59 CHECK( m_monTool.retrieve() );
60
61 return StatusCode::SUCCESS;
62}
63
64
66{
67
68 bool pass = false;
69
70 auto mon_ET = Monitored::Scalar( "Et_em", -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 auto mon_etcone20 = Monitored::Scalar("etcone20", -99.);
76 auto mon_topoetcone20 = Monitored::Scalar("topoetcone20", -99.);
77 auto mon_reletcone20 = Monitored::Scalar("reletcone20", -99.);
78 auto mon_reltopoetcone20 = Monitored::Scalar("reltopoetcone20", -99.);
79
80 auto mon_etcone30 = Monitored::Scalar("etcone30", -99.);
81 auto mon_topoetcone30 = Monitored::Scalar("topoetcone30", -99.);
82 auto mon_reletcone30 = Monitored::Scalar("reletcone30", -99.);
83 auto mon_reltopoetcone30 = Monitored::Scalar("reltopoetcone30", -99.);
84
85 auto mon_etcone40 = Monitored::Scalar("etcone40", -99.);
86 auto mon_topoetcone40 = Monitored::Scalar("topoetcone40", -99.);
87 auto mon_reletcone40 = Monitored::Scalar("reletcone40", -99.);
88 auto mon_reltopoetcone40 = Monitored::Scalar("reltopoetcone40", -99.);
89
90 auto PassedCuts = Monitored::Scalar<int>( "CutCounter", -1 );
91 auto monitorIt = Monitored::Group( m_monTool,
92 mon_etaBin, mon_Eta, mon_Phi, mon_mu,
93 mon_etcone20, mon_topoetcone20, mon_reletcone20, mon_reltopoetcone20,
94 mon_etcone30, mon_topoetcone30, mon_reletcone30, mon_reltopoetcone30,
95 mon_etcone40, mon_topoetcone40, mon_reletcone40, mon_reltopoetcone40,
96 PassedCuts );
97
98 // when leaving scope it will ship data to monTool
99 PassedCuts = PassedCuts + 1; //got called (data in place)
100
101 float ET(0);
102
103 auto roiDescriptor = input.roi;
104
105 if ( fabs( roiDescriptor->eta() ) > 2.6 ) {
106 ATH_MSG_DEBUG( "REJECT The photon had eta coordinates beyond the EM fiducial volume : "
107 << roiDescriptor->eta() << "; stop the chain now" );
108 pass=false; // special case
109 return pass;
110 }
111
112 ATH_MSG_DEBUG( "; RoI ID = " << roiDescriptor->roiId()
113 << ": Eta = " << roiDescriptor->eta()
114 << ", Phi = " << roiDescriptor->phi() );
115
116
117 auto pClus = input.photon->caloCluster();
118
119 float absEta = fabs( pClus->eta() );
120 const int cutIndex = findCutIndex( absEta );
121
122 ET = pClus->et();
123 // eta = pClus->eta();
124 // phi = pClus->phi();
125
126 // eta range
127 if ( !m_acceptAll && cutIndex == -1 ) { // VD
128 ATH_MSG_DEBUG( "Photon : " << absEta << " outside eta range " << m_etabin[m_etabin.size()-1] );
129 return pass;
130 } else {
131 ATH_MSG_DEBUG( "eta bin used for cuts " << cutIndex << " AcceptAll = " << m_acceptAll );
132 }
133 mon_etaBin = m_etabin[cutIndex];
134 PassedCuts = PassedCuts + 1; // passed eta cut
135
136 mon_ET = ET;
137
138 // get average luminosity information to calculate LH
139 float avg_mu = 0;
141 if(eventInfoDecor.isPresent()) {
142 avg_mu = eventInfoDecor(0);
143 ATH_MSG_DEBUG("Average mu " << avg_mu);
144 }
145 mon_mu = avg_mu;
146
147 float ptcone20(999), ptcone30(999), ptcone40(999),
148 etcone20(999), etcone30(999), etcone40(999),
149 topoetcone20(999), topoetcone30(999), topoetcone40(999),
150 reletcone20(999), reletcone30(999), reletcone40(999),
151 reltopoetcone20(999), reltopoetcone30(999), reltopoetcone40(999);
152
153
154 // isolation variables
155 input.photon->isolationValue(ptcone20, xAOD::Iso::ptcone20);
156
157 input.photon->isolationValue(ptcone30, xAOD::Iso::ptcone30);
158
159 input.photon->isolationValue(ptcone40, xAOD::Iso::ptcone40);
160
161 input.photon->isolationValue(etcone20, xAOD::Iso::etcone20);
162
163 input.photon->isolationValue(etcone30, xAOD::Iso::etcone30);
164
165 input.photon->isolationValue(etcone40, xAOD::Iso::etcone40);
166
167 input.photon->isolationValue(topoetcone20, xAOD::Iso::topoetcone20);
168
169 input.photon->isolationValue(topoetcone30, xAOD::Iso::topoetcone30);
170
171 input.photon->isolationValue(topoetcone40, xAOD::Iso::topoetcone40);
172
173 ATH_MSG_DEBUG( " ptcone20 = " << ptcone20 ) ;
174 ATH_MSG_DEBUG( " ptcone30 = " << ptcone30 ) ;
175 ATH_MSG_DEBUG( " ptcone40 = " << ptcone40 ) ;
176 ATH_MSG_DEBUG( " etcone20 = " << etcone20 ) ;
177 ATH_MSG_DEBUG( " etcone30 = " << etcone30 ) ;
178 ATH_MSG_DEBUG( " etcone40 = " << etcone40 ) ;
179 ATH_MSG_DEBUG( " topoetcone20 = " << topoetcone20 ) ;
180 ATH_MSG_DEBUG( " topoetcone30 = " << topoetcone30 ) ;
181 ATH_MSG_DEBUG( " topoetcone40 = " << topoetcone40 ) ;
182
183 // Monitor showershapes
184 float photon_eT = input.photon->caloCluster()->et();
185 mon_etcone20 = etcone20;
186 reletcone20 = etcone20/photon_eT;
187 ATH_MSG_DEBUG("reletcone20 = " <<reletcone20 );
188 mon_reletcone20 = reletcone20;
189
190 mon_topoetcone20 = topoetcone20;
191 reltopoetcone20 = topoetcone20/photon_eT;
192 ATH_MSG_DEBUG("reltopoetcone20 = " <<reltopoetcone20 );
193 mon_reltopoetcone20 = reltopoetcone20;
194
195 mon_etcone30 = etcone30;
196 reletcone30 = etcone30/photon_eT;
197 ATH_MSG_DEBUG("reletcone30 = " <<reletcone30 );
198 mon_reletcone30 = reletcone30;
199
200 mon_topoetcone30 = topoetcone30;
201 reltopoetcone30 = topoetcone30/photon_eT;
202 ATH_MSG_DEBUG("reltopoetcone30 = " <<reltopoetcone30 );
203 mon_reltopoetcone30 = reltopoetcone30;
204
205 mon_etcone40 = etcone40;
206 reletcone40 = etcone40/photon_eT;
207 ATH_MSG_DEBUG("reletcone40 = " <<reletcone40 );
208 mon_reletcone40 = reletcone40;
209
210 mon_topoetcone40 = topoetcone40;
211 reltopoetcone40 = topoetcone40/photon_eT;
212 ATH_MSG_DEBUG("reltopoetcone40 = " <<reltopoetcone40 );
213 mon_reltopoetcone40 = reltopoetcone40;
214
215 // Place here all etcone variables to apply the cuts within the loop on cone sizes
216 std::vector<float> reltopoetcone;
217 reltopoetcone.push_back(reltopoetcone20);
218 reltopoetcone.push_back(reltopoetcone30);
219 reltopoetcone.push_back(reltopoetcone40);
220
221 std::vector<float> reletcone;
222 reletcone.push_back(etcone20);
223 reletcone.push_back(etcone30);
224 reletcone.push_back(etcone40);
225
226
227 bool pass_reletcone = true; // If cut is not succeeded, this will be "AND"ed with a False result
228 bool pass_reltopoetcone = true;
229
230 // Loop over three indices 0,1 and 2, each referring to cones 20 30 and 40 and checking whether it passes or not
231 for (unsigned int conesize=0; conesize<3; conesize++){
232 ATH_MSG_DEBUG("m_RelEtConeCut[" << conesize << "] = " << m_RelEtConeCut[conesize] );
233 ATH_MSG_DEBUG("m_RelTopoEtConeCut[" << conesize << "] = " << m_RelTopoEtConeCut[conesize] );
234 ATH_MSG_DEBUG("m_CutOffset[" << conesize << "] = " << m_CutOffset[conesize] );
235
236 // Check if need to apply isolation
237 // First check logic. if cut is very big, then no isolation cut is defined
238 // Applies to both reletcone[20,30,40] and reltopoetcone[20,30,40]
239 if (m_RelEtConeCut[conesize] > 900){ // I guess we want to deprecate this?
240 ATH_MSG_DEBUG(" not applying etcone[" << conesize << "] isolation.");
241 }
242 if (m_RelTopoEtConeCut[conesize] > 900){ // I guess we want to deprecate this?
243 ATH_MSG_DEBUG(" not applying topoetcone[" << conesize << "] isolation.");
244 }
245 bool pass_this_reletcone = ( m_RelEtConeCut[conesize] > 900 || ( reletcone[conesize] - m_CutOffset[conesize]/photon_eT < m_RelEtConeCut[conesize]));
246 bool pass_this_reltopoetcone = ( m_RelTopoEtConeCut[conesize] > 900 || ( reltopoetcone[conesize] - m_CutOffset[conesize]/photon_eT < m_RelTopoEtConeCut[conesize]));
247
248 ATH_MSG_DEBUG(" pass_reletcone[" << conesize << "] = " << reletcone[conesize] << " - " << m_CutOffset[conesize] << "/" << photon_eT << " < " << m_RelEtConeCut[conesize] << " = " << pass_reletcone);
249 ATH_MSG_DEBUG(" pass_reltopoetcone[" << conesize << "] = " << reltopoetcone[conesize] << " - " << m_CutOffset[conesize] << "/" << photon_eT << " < " << m_RelEtConeCut[conesize] << " = " << pass_reltopoetcone);
250
251 pass_reletcone = pass_reletcone && pass_this_reletcone ;
252 pass_reltopoetcone = pass_reltopoetcone && pass_this_reltopoetcone ;
253 }
254 // Reach this point successfully
255 pass = m_acceptAll || (pass_reletcone && pass_reltopoetcone);
256 ATH_MSG_DEBUG( "AcceptAll = " << m_acceptAll );
257 ATH_MSG_DEBUG( "pass_reletcone = " << pass_reletcone );
258 ATH_MSG_DEBUG( "pass_reltopoetcone = " << pass_reltopoetcone );
259 ATH_MSG_DEBUG( "pass = " << pass );
260
261 return pass;
262
263}
264
266 const float absEta = std::abs(eta);
267
268 auto binIterator = std::adjacent_find( m_etabin.begin(), m_etabin.end(), [=](float left, float right){ return left < absEta and absEta < right; } );
269 if ( binIterator == m_etabin.end() ) {
270 return -1;
271 }
272 return binIterator - m_etabin.begin();
273}
274
275
276StatusCode TrigEgammaPrecisionPhotonCaloIsoHypoTool::decide( std::vector<PhotonInfo>& input ) const {
277 for ( auto& i: input ) {
278 if ( TCU::passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
279 if ( decide( i ) ) {
280 TCU::addDecisionID( m_decisionId, i.decision );
281 }
282 }
283 }
284 return StatusCode::SUCCESS;
285}
Scalar eta() const
pseudorapidity 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.
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_etabin
selection variable for PRECISION calo selection:eta bins
TrigEgammaPrecisionPhotonCaloIsoHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode decide(std::vector< ITrigEgammaPrecisionPhotonCaloIsoHypoTool::PhotonInfo > &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.
@ topoetcone20
Topo-cluster ET-sum.
@ etcone20
Calorimeter isolation.
@ ptcone20
Track isolation.