ATLAS Offline Software
CaloSwEtaoff_v3.cxx
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 /*
3  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 */
13 #include "CaloSwEtaoff_v3.h"
15 #include <cmath>
16 #include <cassert>
17 
18 
40  xAOD::CaloCluster* cluster,
41  const CaloDetDescrElement* elt,
42  float eta,
43  float adj_eta,
44  float /*phi*/,
45  float /*adj_phi*/,
46  CaloSampling::CaloSample samp) const
47 {
48  // Find u, the normalized displacement of the cluster within the cell.
49  // In the range -1...1, with 0 at the center.
50  float u = (eta - elt->eta()) / elt->deta() * 2;
51  if (elt->eta_raw() < 0)
52  u = -u;
53 
54  // u can sometimes be outside of the prescribed range, due to DD bugs.
55  if (u > 1)
56  u = 1;
57  else if (u < -1)
58  u = -1;
59 
60  const CxxUtils::Array<2> regions = m_regions (myctx);
61  assert (regions.size(1) == REG_ENTRIES);
62 
63  // Look up the region for this correction. Give up if we're outsize
64  // the range of the table.
65  float adj_aeta = std::abs (adj_eta);
66  int region_ndx = find_region (regions, adj_aeta);
67  if (region_ndx < 0)
68  return;
69 
71  const CxxUtils::Array<2> forms = m_forms (myctx);
72 
73  // In a few regions, the fit was done using a cell size different
74  // from what we actually have. Need to recalculate u in this case.
75  if (std::abs (regions[region_ndx][REG_CELLSIZE] - elt->deta()) > 1e-3) {
76  float cellsize = regions[region_ndx][REG_CELLSIZE];
77  u = fmod (adj_aeta, cellsize) / cellsize * 2 - 1;
78  }
79 
80  // Calculate the correction for each energy.
81  float offs = energy_interpolation (cluster->e(),
83  regions,
84  forms,
85  adj_aeta,
86  u,
87  region_ndx),
88  m_energies(myctx),
89  m_energy_degree(myctx));
90 
91  // Apply the offset correction to the cluster.
92  if (adj_eta < 0)
93  offs = -offs;
94  cluster->setEta (samp, eta + offs);
95 }
96 
97 
104  float aeta)
105 {
106  // ??? Would a binary search be better here?
107  // The table shouldn't be very large, so I'll leave it like
108  // this for now.
109  unsigned int nreg = regions.size();
110  for (unsigned int i=0; i < nreg; i++) {
111  if (aeta >= regions[i][REG_LO] && aeta < regions[i][REG_HI])
112  return i;
113  }
114  return -1;
115 }
116 
117 
130  const CxxUtils::Array<2>& regions,
131  const CxxUtils::Array<2>& forms,
132  float aeta,
133  float u,
134  int region_ndx)
135  : m_correction (correction),
136  m_regions (regions),
137  m_forms (forms),
138  m_region_ndx (region_ndx),
139  m_aeta (aeta),
140  m_u (u),
141  m_form (regions[region_ndx][REG_FORM])
142 {
143 }
144 
145 
152 float CaloSwEtaoff_v3::Builder::calculate (int energy_ndx, bool& good) const
153 {
154  // Find the proper array of coefficients.
155  CaloRec::Array<2> coef = m_correction[energy_ndx][m_region_ndx];
156 
157  // If we don't have coefficients for this energy/region, skip it.
158  if (coef[0].end()[-1] == 0) {
159  good = false;
160  return 0;
161  }
162 
163  // Which functional form to use?
164  int form;
165  if (m_forms.size() != 0 && m_forms.size(1) != 0)
166  form = m_forms[m_region_ndx][energy_ndx];
167  else
168  form = m_form;
169 
170  // Evaluate the correction!
171  good = true;
172  float ret = 0;
173 
174  // Required just for case 13
175  float xlo=0 ;
176  float xhi=0 ;
177  unsigned int reg_n = m_regions.size();
178 
179  switch (form) {
180  case 0:
181  ret = calc0 (m_aeta, m_u, coef);
182  break;
183  case 3:
184  ret = calc3 (m_aeta, m_u, coef);
185  break;
186  case 4:
187  ret = calc4 (m_aeta, m_u, coef);
188  break;
189  case 5:
190  ret = calc5 (m_aeta, m_u, coef);
191  break;
192  case 10:
193  ret = calc10 (m_aeta, m_u, coef);
194  break;
195  case 11:
196  ret = calc11 (m_aeta, m_u, coef);
197  break;
198  case 13:
199 
200  for (unsigned int i=0; i < reg_n; i++) {
201  if (m_aeta >= m_regions[i][REG_LO] && m_aeta < m_regions[i][REG_HI])
202  {
203  xlo = m_regions[i][REG_LO] ;
204  xhi = m_regions[i][REG_HI] ;
205  }
206  }
207 
208  ret = calc13 (m_aeta, m_u, coef, xlo, xhi);
209  break;
210  default:
211  abort();
212  }
213 
214  // Protection against correction blowing up due to numerical
215  // problems in calculating the polynomial interpolation.
216  if (fabs(ret) > 0.025) {
217  ret = 0;
218  good = false;
219  }
220 
221  return ret;
222 }
223 
224 
225 namespace {
226 
227 
235 void poly_eval (float aeta,
236  const CaloRec::Array<2>& coef,
237  unsigned int npar,
238  double pars[])
239 {
240  assert (npar <= coef.size(0));
241 
242  // Take polynomial degree from the array size.
243  unsigned int degree = coef.size(1);
244 
245  // Loop over parameters.
246  for (unsigned int i=0; i < npar; i++) {
247  // Coefficients for this parameter.
248  CaloRec::Array<1> xcoef = coef[i];
249 
250  // Evaluate polynomial in @c aeta with coefficients @c xcoef.
251  double out = xcoef[0];
252  for (unsigned int j = 1; j < degree; j++)
253  out = out * aeta + xcoef[j];
254  pars[i] = out;
255  }
256 }
257 
258 
259 } // anonymous namespace
260 
261 
269  float u,
270  const CaloRec::Array<2>& coef)
271 {
272  const unsigned int NPAR = 5;
273  double pars[NPAR];
274  poly_eval (aeta, coef, NPAR, pars);
275  double c = (u>=0) ? pars[2] : pars[3];
276  return pars[0] * (std::atan (pars[1] * u) + c*u + pars[4]);
277 }
278 
279 
287  float u,
288  const CaloRec::Array<2>& coef)
289 {
290  const unsigned int NPAR = 4;
291  double pars[NPAR];
292  poly_eval (aeta, coef, NPAR, pars);
293  double c = pars[2];
294  if (u < 0)
295  c = -c - 2*std::atan(pars[1]);
296  return pars[0] * (std::atan (pars[1] * u) + c*u + pars[3]);
297 }
298 
299 
307  float u,
308  const CaloRec::Array<2>& coef)
309 {
310  const unsigned int NPAR = 3;
311  double pars[NPAR];
312  poly_eval (aeta, coef, NPAR, pars);
313  double b = std::max ((double)pars[1], 1e-5);
314  double atanb = std::atan(b);
315  double sq = std::sqrt (b/atanb - 1);
316  double den = (sq/b*atanb - std::atan(sq));
317  return pars[0]* ((- std::atan (b*u) + u*atanb) / den +
318  pars[2]*(1-std::abs(u)));
319 }
320 
321 
329  float /*u*/,
330  const CaloRec::Array<2>& coef)
331 {
332  const unsigned int NPAR = 1;
333  double pars[NPAR];
334  poly_eval (aeta, coef, NPAR, pars);
335  return pars[0];
336 }
337 
338 
346  float u,
347  const CaloRec::Array<2>& coef)
348 {
349  const unsigned int NPAR = 7;
350  double pars[NPAR];
351  poly_eval (aeta, coef, NPAR, pars);
352  double c = pars[2];
353  if (u < 0)
354  c = -c - 2*std::atan(pars[1]);
355 
356  double offs = pars[0] * (atan (pars[1] * u) + c*u + pars[3]) +
357  pars[4] * std::cos (u * pars[5] * M_PI + pars[6]);
358  if (u > 0.9 || u < -0.9) {
359  double xdiff = pars[4] * (std::cos (pars[5] * M_PI + pars[6]) -
360  std::cos (- pars[5] * M_PI + pars[6]));
361  if (u > 0.9)
362  offs -= (u-0.9)*(1./0.1) * xdiff/2;
363  else
364  offs += (-0.9-u)*(1./0.1) * xdiff/2;
365  }
366  return offs;
367 }
368 
369 
377  float u,
378  const CaloRec::Array<2>& coef)
379 {
380  const unsigned int NPAR = 8;
381  double pars[NPAR];
382  poly_eval (aeta, coef, NPAR, pars);
383  double c = (u>=0) ? pars[2] : pars[3];
384  return pars[0] * (std::atan (pars[1] * u) + c*u + pars[4])
385  + pars[5] * std::cos (u * pars[6] * M_PI + pars[7]);
386 }
387 
388 
396  float /*u*/,
397  const CaloRec::Array<2>& coef,
398  float xlo,
399  float xhi)
400 {
401  const unsigned int NPAR = 1;
402  double pars[NPAR];
403  float x = (aeta - xlo) / (xhi - xlo) ;
404  poly_eval (x, coef, NPAR, pars);
405  return pars[0];
406 }
407 
408 
409 /*
410 from python code for writing calc 13
411 
412 # D3PD edit - udpated by Ewan since Scott only half implemented it
413 # "Scaled Polynomial" fit function
414 def _calc13 (aeta, u, ptab, m_xlo, m_xhi):
415  x = (aeta - m_xlo) / (m_xhi - m_xlo);
416  p = [_poly_eval (x, pp) for pp in ptab]
417  return p[0]
418 */
CaloDetDescrElement::deta
float deta() const
cell deta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:356
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
CaloSwEtaoff_v3::Builder::calc4
static float calc4(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 4.
Definition: CaloSwEtaoff_v3.cxx:306
CaloSwEtaoff_v3::find_region
static int find_region(const CxxUtils::Array< 2 > &regions, float aeta)
Find the index of the region containing a given value.
Definition: CaloSwEtaoff_v3.cxx:103
max
#define max(a, b)
Definition: cfImp.cxx:41
CaloSwEtaoff_v3::Builder
Helper class for calculating the energy interpolation table.
Definition: CaloSwEtaoff_v3.h:174
CaloSwEtaoff_v3::REG_CELLSIZE
@ REG_CELLSIZE
Definition: CaloSwEtaoff_v3.h:271
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
CaloSwEtaoff_v3::REG_LO
@ REG_LO
Definition: CaloSwEtaoff_v3.h:268
CxxUtils::Array::size
unsigned int size(unsigned int dim=0) const
Return the size of the array along one dimension.
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
CaloSwEtaoff_v3::Builder::Builder
Builder(const CxxUtils::Array< 4 > &correction, const CxxUtils::Array< 2 > &regions, const CxxUtils::Array< 2 > &forms, float aeta, float u, int region_ndx)
Constructor.
Definition: CaloSwEtaoff_v3.cxx:129
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
M_PI
#define M_PI
Definition: ActiveFraction.h:11
CaloSwEtaoff_v3::Builder::calc13
static float calc13(float aeta, float u, const CaloRec::Array< 2 > &coef, float xlo, float xhi)
Evaluate the function Form 13.
Definition: CaloSwEtaoff_v3.cxx:395
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
CaloSwEtaoff_v3::Builder::calc11
static float calc11(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 11.
Definition: CaloSwEtaoff_v3.cxx:376
x
#define x
CaloSwEtaoff_v3::Builder::calc0
static float calc0(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 0.
Definition: CaloSwEtaoff_v3.cxx:268
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
tools.zlumi_mc_cf.correction
def correction(mu, runmode, campaign, run=None)
Definition: zlumi_mc_cf.py:4
CaloSwEtaoff_v3::Builder::calc3
static float calc3(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 3.
Definition: CaloSwEtaoff_v3.cxx:286
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
WritePulseShapeToCool.xhi
xhi
Definition: WritePulseShapeToCool.py:152
CaloSwEtaoff_v3::REG_HI
@ REG_HI
Definition: CaloSwEtaoff_v3.h:269
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
CaloSwEtaoff_v3::Builder::calculate
virtual float calculate(int energy_ndx, bool &good) const
Calculate the correction for tabulated energy ENERGY_NDX.
Definition: CaloSwEtaoff_v3.cxx:152
CaloSwEtaoff_v3::Builder::calc5
static float calc5(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 5.
Definition: CaloSwEtaoff_v3.cxx:328
sq
#define sq(x)
Definition: CurvedSegmentFinder.cxx:6
CxxUtils::Array< 2 >
CaloSwEtaoff_v3::makeTheCorrection
virtual void makeTheCorrection(const Context &myctx, xAOD::CaloCluster *cluster, const CaloDetDescrElement *elt, float eta, float adj_eta, float phi, float adj_phi, CaloSampling::CaloSample samp) const override
Virtual function for the correction-specific code.
Definition: CaloSwEtaoff_v3.cxx:39
WritePulseShapeToCool.xlo
xlo
Definition: WritePulseShapeToCool.py:133
CaloSwEtaoff_v3::m_energies
Constant< CxxUtils::Array< 1 > > m_energies
Calibration constant: table of energies at which the correction was tabulated.
Definition: CaloSwEtaoff_v3.h:279
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CaloSwEtaoff_v3::m_forms
Constant< CxxUtils::Array< 2 > > m_forms
Calibration constant: Functional form to use per region per energy.
Definition: CaloSwEtaoff_v3.h:289
CaloSwEtaoff_v3::m_regions
Constant< CxxUtils::Array< 2 > > m_regions
Calibration constant: table of regions.
Definition: CaloSwEtaoff_v3.h:265
CaloSwEtaoff_v3.h
EM calorimeter eta offset (S-shape) corrections, version 3.
ReadBchFromCool.good
good
Definition: ReadBchFromCool.py:433
CaloClusterCorrectionCommon::energy_interpolation
static float energy_interpolation(float energy, const TableBuilder &builder, const CaloRec::Array< 1 > &energies, int energy_degree)
Many of the corrections use the same method for doing the final interpolation in energy.
Definition: CaloClusterCorrectionCommon.cxx:575
CaloSwEtaoff_v3::m_energy_degree
Constant< int > m_energy_degree
Calibration constant: degree of the polynomial interpolation in energy.
Definition: CaloSwEtaoff_v3.h:283
CaloSwEtaoff_v3::Builder::calc10
static float calc10(float aeta, float u, const CaloRec::Array< 2 > &coef)
Evaluate the function Form 10.
Definition: CaloSwEtaoff_v3.cxx:345
CaloUtils::ToolConstantsContext
Context object for retrieving ToolConstant values.
Definition: ToolWithConstants.h:61
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
xAOD::CaloCluster_v1::setEta
bool setEta(const CaloSample sampling, const float eta)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
Definition: CaloCluster_v1.cxx:541
python.compressB64.c
def c
Definition: compressB64.py:93
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
WriteCalibToCool.coef
coef
Definition: WriteCalibToCool.py:582
CaloSwEtaoff_v3::REG_ENTRIES
@ REG_ENTRIES
Definition: CaloSwEtaoff_v3.h:273
CaloSwEtaoff_v3::m_correction
Constant< CxxUtils::Array< 4 > > m_correction
Calibration constant: tabulated arrays of function parameters.
Definition: CaloSwEtaoff_v3.h:252