ATLAS Offline Software
Loading...
Searching...
No Matches
EgammaHitsCalibration.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ********************************************************************
6//
7// NAME: EgammaHitsCalibration.cxx
8// PACKAGE: Trigger/TrigTools/EgammaHitsCalibration.cxx
9//
10// AUTHOR: Werner Spolidoro Freund (wsfreund@cern.ch)
11//
12// REFERENCES: Tool to provide Hits Calibration to HLT (BASED ON OFFLINE)
13//
14// Updated: January 14, 2011
15// Modifications on EgammaHitsCalibration updated for offline rev 30069
16//
17// ********************************************************************
18
20//#include "TrigCaloEvent/TrigEMCluster.h"
22#include "GaudiKernel/MsgStream.h"
23// Need Cosh
24#include <math.h>
25
26
28
29 CHECK (base_class::initialize());
30
31 ATH_MSG_DEBUG( "Initialize Tool : " << name() );
32
33
34
35 return StatusCode::SUCCESS;
36}
37
39 ATH_MSG_DEBUG( "Finalize Tool : " << name() );
40 return StatusCode::SUCCESS;
41}
42
44 const void * /*param*/) const{
45
46 const float etamax = m_etamax();
47 const float eta_start_crack = m_eta_start_crack();
48 const float eta_end_crack = m_eta_end_crack();
49 const CxxUtils::Array<3> correction = m_correction();
50
51 float the_aeta = (clus->eta());
52
53 the_aeta = (the_aeta>0)?(the_aeta):(- the_aeta);
54
55 if (the_aeta >= etamax) return;
56
57#ifndef NDEBUG
58 ATH_MSG_DEBUG( "************************************************************************************************" );
59 ATH_MSG_DEBUG( " USING CALIBHITS CALIBRATION " );
60 ATH_MSG_DEBUG( "************************************************************************************************" );
61#endif
62 int si;
63 if (the_aeta < eta_start_crack)
64 si = 0; //barrel
65 else if (the_aeta > eta_end_crack)
66 si = 1; //endcap
67 else {
68 // No corrections are applied for the crack region.
69 return;
70 }
71
72
73 int ibin = (static_cast<int> (the_aeta / etamax * 100));
74 int ibin_frontCorr = ibin;
76 if ( the_aeta>2.35)
77 ibin_frontCorr = (static_cast<int> (235. / etamax ));
78 }
79
80#ifndef NDEBUG
81 ATH_MSG_DEBUG( "Check etas -------------------------------------------------------------------" );
82 ATH_MSG_DEBUG( "Eta --> " << the_aeta << " Bin --> " << ibin <<" Cluster eta = " << clus->eta() );
83
84 ATH_MSG_DEBUG( "Check calibration coefficients -----------------------------------------------" );
85 ATH_MSG_DEBUG( "Accordion : " << correction[0][ibin][0] <<" " << correction[0][ibin][1] << " " << correction[0][ibin][2] << " " << correction[0][ibin][3] );
86 ATH_MSG_DEBUG( "OutOfCOne : " << correction[1][ibin][0] <<" " << correction[1][ibin][1] << " " << correction[1][ibin][2] << " " << correction[1][ibin][3] );
87 ATH_MSG_DEBUG( "Leakage : " << correction[2][ibin][0] <<" " << correction[2][ibin][1] << " " << correction[2][ibin][2] << " " << correction[2][ibin][3] );
88 ATH_MSG_DEBUG( "Front offset: " << correction[3][ibin_frontCorr][0] <<" " <<correction[3][ibin_frontCorr][1] << " " << correction[3][ibin_frontCorr][2] << " " << correction[3][ibin_frontCorr][3] );
89 ATH_MSG_DEBUG( "Front Slope : " << correction[4][ibin_frontCorr][0] <<" " << correction[4][ibin_frontCorr][1] << " " << correction[4][ibin_frontCorr][2] << " " << correction[4][ibin_frontCorr][3] );
90 ATH_MSG_DEBUG( "Second order: " << correction[5][ibin_frontCorr][0] << " " << correction[5][ibin_frontCorr][1] << " " << correction[5][ibin_frontCorr][2] << " " << correction[5][ibin_frontCorr][3] );
91#endif
92
93 EgammaHitsShowerDepth showerDepth;
94 float shower_lbary = showerDepth.depth(the_aeta,
95 eta_start_crack,
96 eta_end_crack,
98 etamax,
99 clus);
100 if (!shower_lbary)
101 return;
102
103 if (shower_lbary < 5. || shower_lbary > 25.){
104 shower_lbary = 15.;
105#ifndef NDEBUG
106 ATH_MSG_DEBUG( "replace pathological depth by 15 X0" );
107#endif
108 }
109
110 // Compute total energy in the Accordion (eacc_base) and
111 // presampler (eps_base)
112
113 float eacc_base = 0;
114 for (int sampling=1; sampling<4; sampling++) {
115 eacc_base += clus->energy(EgammaHitsShowerDepth::m_samps[si][sampling]);
116#ifndef NDEBUG
117 ATH_MSG_DEBUG( "Barrel/endcap = " << si << " Sampling = " << sampling << " Energy -->> " << clus->energy(EgammaHitsShowerDepth::m_samps[si][sampling]) );
118#endif
119 }
120 float eps_base = clus->energy (EgammaHitsShowerDepth::m_samps[si][0]);
121
122#ifndef NDEBUG
123 ATH_MSG_DEBUG( "E accordion base --->>>> " << eacc_base << " Eps base " << eps_base );
124#endif
125
126
127 // Add a protection against large longitudinal barycenter for clusters from
128 // hadrons which may cause over-calibration. A energy dependent upper limit
129 // on the long bary is introduced (from 20 at 0 to 23 at 1 TeV)
130
131 float depth_max = 20. + 3. * (eacc_base+eps_base) * 1e-6; // divided by TeV
132#ifndef NDEBUG
133 ATH_MSG_DEBUG( "Raw energy ---->> " << (eacc_base+eps_base) );
134 ATH_MSG_DEBUG( "Bary max for this event ---->> " << depth_max );
135#endif
136
137 if ( shower_lbary > depth_max ) {
138 shower_lbary = 15.;
139 //shower_lbary = depth_max;
140#ifndef NDEBUG
141 ATH_MSG_DEBUG( " replace pathological depth by 15 X0 " );
142#endif
143 }
144 // -------------------------------------------------------------
145 // Now calibrate the Accordion
146 // -------------------------------------------------------------
147
148 float acc_corr = correction[0][ibin][1] + correction[0][ibin][2] * shower_lbary + correction[0][ibin][3] * shower_lbary * shower_lbary ;
149
150 float e_out_perc = 0;
151 if (the_aeta < eta_start_crack) {
152 e_out_perc = correction[1][ibin][1] + correction[1][ibin][2] * shower_lbary + correction[1][ibin][3] * shower_lbary * shower_lbary ;
153 }
154 else {
155 e_out_perc = correction[1][ibin][1] + correction[1][ibin][2] * shower_lbary + correction[1][ibin][3] / shower_lbary ;
156 }
157
158 float e_acc_reco=acc_corr*(eacc_base )*(1+(e_out_perc)/100);
159
160 // -------------------------------------------------------------
161 // Now estimate the longitudinal leakage
162 // -------------------------------------------------------------
163
164 float e_leak_perc = 0;
165 e_leak_perc = correction[2][ibin][3] + correction[2][ibin][1] * shower_lbary + correction[2][ibin][2] * exp(shower_lbary);
166
167 if (e_leak_perc < 0 ) e_leak_perc = 0.;
168 if (e_leak_perc > 100.) e_leak_perc = 100.;
169 float e_leak_reco = e_leak_perc * (e_acc_reco)/100;
170
171 // -------------------------------------------------------------
172 // Now estimate the energy lost in front of the calorimeter
173 // -------------------------------------------------------------
174
175 float raw_energy=e_acc_reco*.001;
176 float e_front_reco = eps_base;
177
178 if (raw_energy <= 1) {
179 // Protect against log() going negative in pow();
180 // also protect against sqrt() of a negative number and div-by-zero.
181 }
182 else if (the_aeta < 1.8) {
183
184 if (the_aeta < eta_start_crack) {
185 float WpsOff = correction[3][ibin_frontCorr][1] + correction[3][ibin_frontCorr][2] * raw_energy + correction[3][ibin_frontCorr][3] * raw_energy * raw_energy;
186 float WpsSlo = correction[4][ibin_frontCorr][1] * pow(log(raw_energy),correction[4][ibin_frontCorr][2]) + correction[4][ibin_frontCorr][3] *sqrt( raw_energy );
187 e_front_reco=WpsOff + WpsSlo*(eps_base);
188
189#ifndef NDEBUG
190 ATH_MSG_DEBUG( " raw event " << raw_energy );
191 ATH_MSG_DEBUG( " froffset coeff " << correction[3][ibin_frontCorr][1] << " " << correction[3][ibin_frontCorr][2] << " " << correction[3][ibin_frontCorr][3] );
192 ATH_MSG_DEBUG( " frslope coeff " << correction[4][ibin_frontCorr][1] << " " << correction[4][ibin_frontCorr][2] << " " << correction[4][ibin_frontCorr][3] );
193 ATH_MSG_DEBUG( " WpsOff,WpsSlo " << WpsOff << " " << WpsSlo );
194 ATH_MSG_DEBUG( " eps_base, efront_reco " << eps_base << " " << e_front_reco );
195#endif
196 }
197 else{
198
199
200 if (raw_energy<20.) raw_energy=20.;
201
202 float WpsOff = correction[3][ibin_frontCorr][1] + correction[3][ibin_frontCorr][2] * raw_energy + correction[3][ibin_frontCorr][3] * sqrt(raw_energy);
203 float WpsSlo = correction[4][ibin_frontCorr][1] + correction[4][ibin_frontCorr][2] * log(raw_energy) + correction[4][ibin_frontCorr][3] * sqrt(raw_energy);
204 float WpsSlo2 = correction[5][ibin_frontCorr][1] + correction[5][ibin_frontCorr][2] * raw_energy - correction[5][ibin_frontCorr][3] / (raw_energy * raw_energy) ;
205 e_front_reco=WpsOff + WpsSlo*(eps_base) + WpsSlo2*(eps_base)*(eps_base);
206 if (e_front_reco<0.) e_front_reco= eps_base;
207#ifndef NDEBUG
208 ATH_MSG_DEBUG( " raw energy " << raw_energy );
209 ATH_MSG_DEBUG( "p1 " << correction[3][ibin_frontCorr][1] << " " << correction[3][ibin_frontCorr][2] << " " << correction[3][ibin_frontCorr][3] << " " << WpsOff );
210 ATH_MSG_DEBUG( "p2 " << correction[4][ibin_frontCorr][1] << " " << correction[4][ibin_frontCorr][2] << " " << correction[4][ibin_frontCorr][3] << " " << WpsSlo );
211 ATH_MSG_DEBUG( "p3 " << correction[5][ibin_frontCorr][1] << " " << correction[5][ibin_frontCorr][2] << " " << correction[5][ibin_frontCorr][3] << " " << WpsSlo2 );
212 ATH_MSG_DEBUG( " WpsOff, WpsSlo, WpsSlo2 " << WpsOff << " " << WpsSlo << " " << WpsSlo2 );
213 ATH_MSG_DEBUG( " eps_base, efront_reco " << eps_base << " " << e_front_reco );
214#endif
215
216 }
217
218 }
219 else {
220 float p1 = correction[3][ibin_frontCorr][1] + correction[3][ibin_frontCorr][2] * raw_energy + correction[3][ibin_frontCorr][3] * raw_energy * raw_energy ;
221 float p2 = correction[4][ibin_frontCorr][1] + correction[4][ibin_frontCorr][2] * raw_energy + correction[4][ibin_frontCorr][3] * raw_energy * raw_energy ;
222 float p3 = correction[5][ibin_frontCorr][1] + correction[5][ibin_frontCorr][2] * raw_energy + correction[5][ibin_frontCorr][3] * raw_energy * raw_energy ;
223
224#ifndef NDEBUG
225 ATH_MSG_DEBUG( "p1 " << correction[3][ibin_frontCorr][1] << " " << correction[3][ibin_frontCorr][2] << " " << correction[3][ibin_frontCorr][3] );
226 ATH_MSG_DEBUG( "p2 " << correction[4][ibin_frontCorr][1] << " " << correction[4][ibin_frontCorr][2] << " " << correction[4][ibin_frontCorr][3] );
227 ATH_MSG_DEBUG( "p3 " << correction[5][ibin_frontCorr][1] << " " << correction[5][ibin_frontCorr][2] << " " << correction[5][ibin_frontCorr][3] );
228#endif
229
230 e_front_reco= (p1 + p2 * shower_lbary + p3 * shower_lbary * shower_lbary);
231 if (e_front_reco<0.) e_front_reco=eps_base;
232 }
233
234 // -------------------------------------------------------------
235 // Now compute the total energy and finally update the cluster energies
236 // -------------------------------------------------------------
237
238 float e_calo_reco =e_front_reco + e_leak_reco + e_acc_reco;
239
240#ifndef NDEBUG
241 ATH_MSG_DEBUG( "CaloSwCalibrationHits::Final reco energy ---------------------- " << e_calo_reco );
242 ATH_MSG_DEBUG( "CaloSwCalibrationHits::Front ---------------------- " << e_front_reco );
243 ATH_MSG_DEBUG( "CaloSwCalibrationHits::Accordion ------------------ " << e_acc_reco );
244 ATH_MSG_DEBUG( "CaloSwCalibrationHits::out of cone ---------------- " << acc_corr*(eacc_base )*(e_out_perc)/100 );
245 ATH_MSG_DEBUG( "CaloSwCalibrationHits::Leakage -------------------- " << e_leak_reco );
246#endif
247
248
249
250 /*
251 -------------------------------------------------------------
252 Conventions discussed in Dec 2007 larg week to fill energies in the samplings:
253 E = total energy including all corrections
254 E0 = total energy in front of the accordion :
255 presampler energy + energy lost in front + energy lost between PS and strips
256 E1 = energy in the strips with no out of cone corrections
257 E2 = energy in the middle with no out of cone corrections
258 E3 = energy in the back with no out of cone correction + longitudinal leakage
259
260 Please note that E != E0+E1+E2+E3
261 -------------------------------------------------------------
262 */
263
264 // presampler
265 clus->setEnergy (EgammaHitsShowerDepth::m_samps[si][0], e_front_reco );
266
267 // strips and middle
268 for (int sampling=1; sampling<=2; sampling++){
269 clus->setEnergy (EgammaHitsShowerDepth::m_samps[si][sampling], clus->energy(EgammaHitsShowerDepth::m_samps[si][sampling]) * acc_corr );
270 }
271
272 // back
273 clus->setEnergy (EgammaHitsShowerDepth::m_samps[si][3], clus->energy (EgammaHitsShowerDepth::m_samps[si][3]) * acc_corr + e_leak_reco);
274
275#ifndef NDEBUG
276 // total energy
277 float e_temp = 0;
278 for (int nl = 0 ; nl< 4 ; nl++) e_temp += clus->energy (EgammaHitsShowerDepth::m_samps[si][nl]);
279 ATH_MSG_DEBUG( "---------- Sum of the sampling energy --- >> " << e_temp << " EcaloReco = " << e_calo_reco );
280 ATH_MSG_DEBUG( "CaloSwCalibHitsCalibration Energy after correction --> " << clus->energy() );
281#endif
282
283 clus->setEnergy(e_calo_reco);
284
285 clus->setEt(clus->energy()/cosh(the_aeta));
286
287}
288
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
constexpr int pow(int base, int exp) noexcept
Read-only multidimensional array.
Constant< float > m_eta_end_crack
virtual StatusCode initialize() override
Initialization of the tool.
virtual StatusCode finalize() override
Finalization of the tool.
Constant< CxxUtils::Array< 3 > > m_correction
Constant< bool > m_fix_v6_pathologies
Constant< float > m_eta_start_crack
Constant< CxxUtils::Array< 2 > > m_sampling_depth
virtual void makeCorrection(xAOD::TrigEMCluster *, const void *v=nullptr) const override
method to perform the correction.
static const CaloSampling::CaloSample m_samps[2][4]
float depth(const float &aeta, const float start_crack, const float end_crack, const CxxUtils::Array< 2 > &sampling_depth, const float etamax, const xAOD::TrigEMCluster *cluster) const
Calculate the depth of the cluster.
void setEt(float)
set Et (calibrated)
float eta() const
get Eta (calibrated)
void setEnergy(float energy)
set Energy (calibrated)
float energy() const
get Energy (calibrated)
TrigEMCluster_v1 TrigEMCluster
Define the latest version of the trigger EM cluster class.