ATLAS Offline Software
Loading...
Searching...
No Matches
egammaStripsShape.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4
8#include "CLHEP/Units/SystemOfUnits.h"
12#include <cfloat>
13#include <cmath>
14#include <vector>
15
16using CLHEP::GeV;
17
18namespace {
19// 5 cells second sampling granularity ~0.025 in eta
20constexpr int neta = 5;
21// 2 strips in phi and cover a region of +-1.1875
22constexpr int nphi = 2;
23// 8 strips per cell in barrel
24constexpr int STRIP_ARRAY_SIZE = 8 * neta;
25
26double
27proxim(const double b, const double a)
28{
29 return b + 2. * M_PI * round((a - b) / (2. * M_PI));
30}
31
32double
33dim(const double a, const double b)
34{
35 return a - std::min(a, b);
36}
37
38struct StripArrayHelper
39{
40 StripArrayHelper()
41 : eta(0.)
42 , etaraw(0.)
43 , energy(0.)
44 , deta(0.)
45 , ncell(0.)
46 {}
47 bool operator<(const StripArrayHelper& cell2) const
48 {
49 return etaraw < cell2.etaraw;
50 }
51 double eta;
52 double etaraw;
53 double energy;
54 double deta;
55 int ncell;
56};
57
58/*
59From the original (eta,phi) position, find the location
60 (sampling, barrel/end-cap, granularity)
61set an array of energies,eta,phi in ~40 strips around max
62 */
63void
64setArray(const xAOD::CaloCluster& cluster,
65 const CaloDetDescrManager& cmgr,
67 double eta,
68 double phi,
69 double deta,
70 double dphi,
71 double* enecell,
72 double* etacell,
73 double* gracell,
74 int* ncell)
75{
76 // Raw --> Calo Frame
77 // Difference is important in end-cap which is shifted by about 4 cm
78 double etaraw = eta;
79 double phiraw = phi;
80 // look for the corresponding DetDescrElement
81 const CaloDetDescrElement* dde = cmgr.get_element(
82 sam == CaloSampling::EMB1 ? CaloCell_ID::EMB1 : CaloCell_ID::EME1,
83 eta,
84 phi);
85 // if dde is found
86 if (dde) {
87 etaraw = dde->eta_raw();
88 phiraw = dde->phi_raw();
89 } else {
90 return;
91 }
92 // The selection will be done in Raw co-ordinates
93 // defines the boundaries around which to select cells
94 double etamin = etaraw - deta;
95 double etamax = etaraw + deta;
96 double phimin = phiraw - dphi;
97 double phimax = phiraw + dphi;
98 // Loop over all cells in the cluster
101 // fill in a std::vector the energies,eta,phi values contained in
102 // a window (deta,dphi)
103 std::vector<StripArrayHelper> stripArray;
104 stripArray.reserve(2 * STRIP_ARRAY_SIZE);
105 // positon of elements
106 double eta_cell = 0.;
107 double phi_cell0 = 0.;
108 double phi_cell = 0.;
109
110 for (; first != last; ++first) {
111 // ensure we are in 1st sampling
112 const CaloCell* theCell = *first;
113 if (!theCell) {
114 continue;
115 }
116 if (theCell->caloDDE()->getSampling() == sam) {
117 // retrieve the eta,phi of the cell
118 eta_cell = theCell->caloDDE()->eta_raw();
119 // adjust for possible 2*pi offset.
120 phi_cell0 = theCell->caloDDE()->phi_raw();
121 phi_cell = proxim(phi_cell0, phiraw);
122 // check if we are within boundaries
123 if (eta_cell >= etamin && eta_cell <= etamax) {
124 if (phi_cell >= phimin && phi_cell <= phimax) {
125 StripArrayHelper stripHelp;
126 // energy
127 stripHelp.energy = theCell->energy() * (first.weight());
128 // eta
129 stripHelp.eta = theCell->eta();
130 // eta raw
131 stripHelp.etaraw = theCell->caloDDE()->eta_raw();
132 // eta granularity
133 stripHelp.deta = theCell->caloDDE()->deta();
134 // index/number of cells in the array
135 stripHelp.ncell++;
136 stripArray.push_back(stripHelp);
137 }
138 }
139 }
140 }
141 const size_t elementCount = stripArray.size();
142 // Exit early if no cells.
143 if (elementCount == 0) {
144 return;
145 }
146 // sort vector in eta
147 std::sort(stripArray.begin(), stripArray.end());
148 // loop on intermediate array and merge two cells in phi (when they exist)
149 int ieta = 0;
150 bool next = false;
151 // merge in phi
152 for (size_t i = 0; i < (elementCount - 1); ++i) {
153 // Maximum STRIP_ARRAY_SIZE elements
154 if (ieta < STRIP_ARRAY_SIZE) {
155 // energy
156 enecell[ieta] += stripArray[i].energy;
157 // eta
158 etacell[ieta] = stripArray[i].eta;
159 // eta granularity
160 gracell[ieta] = stripArray[i].deta;
161 // index/number of cells in the array
162 ++ncell[ieta];
163 // check if eta of this element is equal to the pevious one
164 // in which case the two cells have to be merged
165 if (std::abs(stripArray[i].etaraw - stripArray[i + 1].etaraw) > 1e-05)
166 next = true;
167 if (next) {
168 // Increment the final array only if do not want to merge
169 // otherwise continue as to merge
170 ieta++;
171 next = false;
172 }
173 }
174 }
175 // special case for last element which was not treated yet
176 int index = elementCount - 1;
177 // if previous element had a different eta then append the array
178 // NB: this could happen if only one cell in phi was available
179 if (index == 0 || std::abs(stripArray[index].etaraw -
180 stripArray[index - 1].etaraw) > 1e-05) {
181 // energy
182 enecell[ieta] = stripArray[index].energy;
183 }
184 if (index != 0 && std::abs(stripArray[index].etaraw -
185 stripArray[index - 1].etaraw) < 1e-05) {
186 // energy
187 enecell[ieta] += stripArray[index].energy;
188 }
189 // eta
190 etacell[ieta] = stripArray[index].eta;
191 // eta granularity
192 gracell[ieta] = stripArray[index].deta;
193 // index/number of cells in the array
194 ++ncell[ieta];
195}
196
198void
199setIndexSeed(egammaStripsShape::Info& info,
200 const double* etacell,
201 const double* gracell)
202{
203 //
204 // Look for the index of the seed in the array previously filled
205 //
206 double demi_eta = 0.;
207 double eta_min = 0.;
208 double eta_max = 0.;
209 for (int ieta = 0; ieta < STRIP_ARRAY_SIZE - 1; ieta++) {
210 // from the eta of the cell it is necessary
211 // to have the boundaries of this cell +/- half of its granularity
212 demi_eta = gracell[ieta] / 2.;
213 eta_min = etacell[ieta] - demi_eta;
214 eta_max = etacell[ieta] + demi_eta;
215 // Beware that list is arranged from larger values to smaller ones
216 if ((std::abs(info.etaseed) > std::abs(eta_min) &&
217 std::abs(info.etaseed) <= std::abs(eta_max)) ||
218 (std::abs(info.etaseed) <= std::abs(eta_min) &&
219 std::abs(info.etaseed) > std::abs(eta_max)))
220 info.ncetaseed = ieta;
221 }
222}
223
225void
226setWstot(egammaStripsShape::Info& info,
227 double deta,
228 const double* enecell,
229 const double* etacell,
230 const int* ncell)
231{
232 //
233 // calculate width in half the region (that's the one used for e-ID)
234 //
235 // We take only half of the region in eta not in phi
236 double etamin = info.etamax - deta / 2.;
237 double etamax = info.etamax + deta / 2.;
238 double mean = 0.;
239 double wtot = 0.;
240 double etot = 0.;
241 // loop on each element of the array
242 for (int ieta = 0; ieta < STRIP_ARRAY_SIZE; ieta++) {
243 if (ncell[ieta] == 0)
244 continue;
245 if (etacell[ieta] >= etamin && etacell[ieta] <= etamax) {
246 wtot += enecell[ieta] * (ieta - info.ncetamax) * (ieta - info.ncetamax);
247 mean += enecell[ieta] * (ieta - info.ncetamax);
248 etot += enecell[ieta];
249 }
250 }
251 // width is defined only if total energy is positive
252 if (etot > 0) {
253 info.etot = etot;
254 wtot = wtot / etot;
255 mean = mean / etot;
256 info.wstot = wtot > 0 ? std::sqrt(wtot) : -9999.;
257 }
258}
259
261void
262setF2(egammaStripsShape::Info& info,
263 const double* enecell,
264 const double eallsamples)
265{
266 //
267 // Fraction of energy in two highest energy strips
268 //
269 double e1 = info.emaxs1;
270 // strip on left of highest energetic strips
271 double eleft = info.ncetamax > 0 ? enecell[info.ncetamax - 1] : 0;
272 // strip on right of highest energetic strip
273 double eright =
274 info.ncetamax < STRIP_ARRAY_SIZE - 1 ? enecell[info.ncetamax + 1] : 0;
275 // find hottest of these strips
276 double e2 = std::max(eleft, eright);
277 // calculate fraction of the two highest energy strips
278 info.f2 = eallsamples > 0. ? (e1 + e2) / eallsamples : 0.;
279}
280
282void
283setEnergy(egammaStripsShape::Info& info, const double* enecell)
284{
285 //
286 // Energy in the strips in a cluster of 15 strips
287 // and in a cluster of 3 strips - two cells are merge in phi
288 //
289 if (info.ncetamax < 0 || info.ncetamax > STRIP_ARRAY_SIZE)
290 return;
291 double energy = 0.;
292 int nlo = std::max(info.ncetamax - 1, 0);
293 int nhi = std::min(info.ncetamax + 1, STRIP_ARRAY_SIZE - 1);
294 for (int ieta = nlo; ieta <= nhi; ieta++) {
295 energy += enecell[ieta];
296 }
297 info.e132 = energy;
298
299 energy = 0.;
300 nlo = std::max(info.ncetamax - 7, 0);
301 nhi = std::min(info.ncetamax + 7, STRIP_ARRAY_SIZE - 1);
302 for (int ieta = nlo; ieta <= nhi; ieta++) {
303 energy += enecell[ieta];
304 }
305 info.e1152 = energy;
306}
307
309void
310setAsymmetry(egammaStripsShape::Info& info, const double* enecell)
311{
312 //
313 // Asymmetry of the shower in +/- 3 strips
314 // (E(-1)-E(+1))/(E(-1)+E(+1))
315 //
316 if (info.ncetamax < 0 || info.ncetamax > STRIP_ARRAY_SIZE)
317 return;
318 double asl = 0.;
319 double asr = 0.;
320
321 // define index of the array from max-1 strips (if possible)
322 int nlo = std::max(info.ncetamax - 1, 0);
323 // define index of the array from max+1 strips (if possible)
324 int nhi = std::min(info.ncetamax + 1, STRIP_ARRAY_SIZE - 1);
325 for (int ieta = nlo; ieta <= info.ncetamax; ieta++)
326 asl += enecell[ieta];
327 for (int ieta = info.ncetamax; ieta <= nhi; ieta++)
328 asr += enecell[ieta];
329
330 if (asl + asr > 0.)
331 info.asymmetrys3 = (asl - asr) / (asl + asr);
332}
333
335void
336setWs3(egammaStripsShape::Info& info,
338 const xAOD::CaloCluster& cluster,
339 const double* enecell,
340 const double* etacell,
341 const int* ncell)
342{
343 //
344 // Width in three strips centered on the strip with the largest energy
345 //
346
347 double energy = 0.;
348 double width3 = 0.;
349 double eta1 = 0.;
350 // highest and lowest indexes
351 int nlo = std::max(info.ncetamax - 1, 0);
352 int nhi = std::min(info.ncetamax + 1, STRIP_ARRAY_SIZE - 1);
353 for (int ieta = nlo; ieta <= nhi; ieta++) {
354 if (ncell[ieta] == 0)
355 continue;
356 width3 += enecell[ieta] * (ieta - info.ncetamax) * (ieta - info.ncetamax);
357 eta1 += enecell[ieta] * etacell[ieta];
358 energy += enecell[ieta];
359 }
360
361 if (energy > 0) {
362 if (width3 > 0) {
363 info.ws3 = std::sqrt(width3 / energy);
364 }
365 info.etas3 = eta1 / energy;
366 // corrected width for position inside the cell
367 // estimated from the first sampling
369 cluster.etaSample(sam), cluster.etamax(sam), info.ws3);
370 info.poscs1 =
371 egammaqweta1c::RelPosition(cluster.etaSample(sam), cluster.etamax(sam));
372 }
373}
374
376double
377setDeltaEtaTrackShower(int nstrips, int ieta, const double* enecell)
378{
379 //
380 // Shower position
381 // using +/- "nstrips" strips centered on the strip ieta
382 // this could be the hottest cell or the seed cell
383 double energy = 0.;
384 double pos = 0.;
385 if (ieta < 0) {
386 return -9999.;
387 }
388 // define index of the array from max-n strips strips (if possible)
389 int nlo = std::max(ieta - nstrips, 0);
390 // define index of the array from max+n strips strips (if possible)
391 int nhi = std::min(ieta + nstrips, STRIP_ARRAY_SIZE - 1);
392 // loop on all strips
393 for (int i = nlo; i <= nhi; i++) {
394 // position in number of cells (wrt ieta) weighted by energy
395 pos += enecell[i] * (i - ieta);
396 // sum of energy
397 energy += enecell[i];
398 }
399 // delta eta value is defined only if total energy is positive
400 if (energy > 0) {
401 pos = pos / energy;
402 return pos;
403 }
404 pos *= -1;
405 return -9999.;
406}
407
409void
410setWidths5(egammaStripsShape::Info& info, const double* enecell)
411{
412 //
413 // Shower width using 5 strips
414 //
415 // threshold (tuned ?)
416 double Small = 1.e-10;
417 double eall = 0.;
418 double eave = 0.;
419 double width5 = 0.;
420 // define index of the array from max-2 strips strips (if possible)
421 int nlo = std::max(info.ncetamax - 2, 0);
422 // define index of the array from max+2 strips strips (if possible)
423 int nhi = std::min(info.ncetamax + 2, STRIP_ARRAY_SIZE - 1);
424 // loop on all strips
425 for (int ieta = nlo; ieta <= nhi; ieta++) {
426 if (ieta >= 0 && ieta < STRIP_ARRAY_SIZE) {
427 // sum of energy
428 eall += enecell[ieta];
429 // position in number of cells (wrt ncetamax) weighted by energy
430 eave += enecell[ieta] * (ieta - info.ncetamax);
431 // width
432 width5 += enecell[ieta] * (ieta - info.ncetamax) * (ieta - info.ncetamax);
433 }
434 }
435
436 if (eall < Small) {
437 return;
438 }
439 eave = eave / eall;
440 width5 = width5 / eall;
441 width5 = width5 - eave * eave;
442 if (width5 < 0) {
443 return;
444 }
445
446 info.widths5 = std::sqrt(width5);
447}
448
450void
451setEmax(egammaStripsShape::Info& info, const double* enecell)
452{
453 //
454 // calculate energy of strip with maximum energy
455 //
456 for (int ieta = 0; ieta < STRIP_ARRAY_SIZE; ieta++) {
457 if (enecell[ieta] > info.emaxs1) {
458 info.emaxs1 = enecell[ieta];
459 info.ncetamax = ieta;
460 }
461 }
462}
463
465int
466setEmax2(egammaStripsShape::Info& info,
467 const double* enecell,
468 const double* gracell,
469 const int* ncell)
470{
471 //
472 // energy of the second local maximum (info.esec)
473 // energy of the strip with second max 2 (info.esec1)
474 //
475 int ncetasec1 = 0;
476 double ecand;
477 double ecand1;
478 double escalesec = 0;
479 double escalesec1 = 0;
480
481 for (int ieta = 1; ieta < STRIP_ARRAY_SIZE - 1; ieta++) {
482 if (ncell[ieta] == 0)
483 continue;
484
485 int ieta_left = ieta - 1;
486 while (ieta_left >= 0 && ncell[ieta_left] == 0) {
487 --ieta_left;
488 }
489 if (ieta_left < 0) {
490 continue;
491 }
492
493 int ieta_right = ieta + 1;
494 while (ieta_right < STRIP_ARRAY_SIZE && ncell[ieta_right] == 0) {
495 ++ieta_right;
496 }
497 if (ieta_right >= STRIP_ARRAY_SIZE) {
498 continue;
499 }
500
501 double e = enecell[ieta] / gracell[ieta];
502 double e_left = enecell[ieta_left] / gracell[ieta_left];
503 double e_right = enecell[ieta_right] / gracell[ieta_right];
504 // check that cell is hotter than left or right one
505 if (e > e_left && e > e_right) {
506 // this ensure that this cell is not the hottest one
507 // this + previous line implies that hottest cell and 2nd one
508 // are separated by more than one strip
509 if (ieta != info.ncetamax) {
510 ecand = enecell[ieta] + enecell[ieta_left] + enecell[ieta_right];
511 double escalecand = e + e_left + e_right;
512 ecand1 = enecell[ieta];
513
514 // test energy of the three strips
515 if (escalecand > escalesec) {
516 escalesec = escalecand;
517 info.esec = ecand;
518 // ncetasec = ieta;
519 }
520 // test energy of 2nd hottest local maximum
521 if (e > escalesec1) {
522 escalesec1 = e;
523 info.esec1 = ecand1;
524 ncetasec1 = ieta;
525 }
526 }
527 }
528 }
529 return ncetasec1;
530}
531
533void
534setEmin(int ncsec1,
536 const double* enecell,
537 const double* gracell,
538 const int* ncell)
539{
540 //
541 // energy deposit in the strip with the minimal value
542 // between the first and the second maximum
543 //
544 info.emins1 = 0.;
545 // Divide by a number smaller than the eta-width of any cell.
546 double escalemin = info.emaxs1 / 0.001;
547
548 if (ncsec1 <= 0)
549 return;
550
551 // define index of the array from max+1 strips strips (if possible)
552 int nlo = std::min(info.ncetamax, ncsec1) + 1;
553 // define index of the array from max-1 strips strips (if possible)
554 int nhi = std::max(info.ncetamax, ncsec1) - 1;
555 // loop on these strips
556 for (int ieta = nlo; ieta <= nhi; ieta++) {
557 if (ncell[ieta] == 0)
558 continue;
559 // correct energy of the strips with its granularity
560 // in order to be compared with other energy strips
561 // (potentially in other regions of granularity)
562 double escale = enecell[ieta] / gracell[ieta];
563 if (escale < escalemin) {
564 escalemin = escale;
565 info.emins1 = enecell[ieta];
566 }
567 }
568}
569
571void
572setValley(egammaStripsShape::Info& info, double* enecell)
573{
574 //
575 // Variable defined originally by Michal Seman
576 // (was tuned on DC0 data ! never since !!!)
577 //
578
579 double Ehsthr = 0.06 * GeV;
580 double val = 0.;
581
582 // search for second peak to the right
583 for (int ieta = info.ncetamax + 2; ieta < STRIP_ARRAY_SIZE - 1; ieta++) {
584 if (enecell[ieta] > Ehsthr &&
585 enecell[ieta] > std::max(enecell[ieta - 1], enecell[ieta + 1])) {
586 double valley = 0;
587 for (int jc = info.ncetamax; jc <= ieta - 1; jc++) {
588 valley += dim(enecell[ieta], enecell[jc]);
589 }
590 if (valley > val)
591 val = valley;
592 }
593 }
594
595 // search for second peak to the left
596 for (int ieta = 1; ieta <= info.ncetamax - 2; ieta++) {
597 if (enecell[ieta] > Ehsthr &&
598 enecell[ieta] > std::max(enecell[ieta - 1], enecell[ieta + 1])) {
599 double valley = 0;
600 for (int jc = ieta + 1; jc <= info.ncetamax; jc++) {
601 valley += dim(enecell[ieta], enecell[jc]);
602 }
603 if (valley > val)
604 val = valley;
605 }
606 }
607
608 // energy of hottest strip
609 double e1 = info.emaxs1;
610 // energy of strip on the left
611 double eleft = info.ncetamax > 0 ? enecell[info.ncetamax - 1] : 0;
612 // energy of strip on the right
613 double eright =
614 info.ncetamax < STRIP_ARRAY_SIZE - 1 ? enecell[info.ncetamax + 1] : 0;
615 // find hottest of these strips
616 double e2 = std::max(eleft, eright);
617
618 if (std::abs(e1 + e2) > 0.)
619 info.val = val / (e1 + e2);
620}
623
624void
625setFside(egammaStripsShape::Info& info,
626 const double* enecell,
627 const double* gracell,
628 const int* ncell)
629{
630 //
631 // fraction of energy outside shower core
632 // (E(+/-3strips)-E(+/-1strips))/ E(+/-1strips)
633 //
634 // NB: threshold defined by M. Seman for DC0 data (or before ?), never tuned
635 // since
636 double Ehsthr = 0.06 * GeV;
637 // Local variable with max energy in strips
638 double e1 = info.emaxs1;
639 // left index defined as max-1
640 int ileft = info.ncetamax - 1;
641 while (ileft > 0 && ncell[ileft] == 0) {
642 --ileft;
643 }
644 double eleft = ileft >= 0 ? enecell[ileft] : 0;
645
646 // right index defined as max+1
647 int iright = info.ncetamax + 1;
648 while (iright < STRIP_ARRAY_SIZE - 1 && ncell[iright] == 0) {
649 ++iright;
650 }
651 double eright = iright < STRIP_ARRAY_SIZE ? enecell[iright] : 0;
652
653 double fracm = 0.;
654
655 // define index of the array from max-3 strips strips (if possible)
656 int nlo = std::max(info.ncetamax - 3, 0);
657 // define index of the array from max+3 strips strips (if possible)
658 int nhi = std::min(info.ncetamax + 3, STRIP_ARRAY_SIZE - 1);
659
660 if (e1 > Ehsthr) {
661 for (int ieta = nlo; ieta <= nhi; ieta++) {
662 if (ncell[ieta] == 0)
663 continue;
664 fracm += (gracell[ieta] > DBL_MIN) ? (enecell[ieta] / gracell[ieta]) : 0.;
665 }
666 if (std::abs(eleft + eright + e1) > 0.) {
667 if ((e1 != 0) && (gracell[info.ncetamax] > DBL_MIN))
668 e1 /= gracell[info.ncetamax];
669 if (eleft != 0)
670 eleft /= gracell[ileft];
671 if (eright != 0)
672 eright /= gracell[iright];
673
674 info.fside = (std::abs(eleft + eright + e1) > 0.)
675 ? fracm / (eleft + eright + e1) - 1.
676 : 0.;
677 }
678 }
679}
680
682void
683setF1core(egammaStripsShape::Info& info, const xAOD::CaloCluster& cluster)
684{
685 // Fraction of energy reconstructed in the core of the shower
686 // core = e132, i.e energy in 3 strips
687 //
688 double x = -9999.;
689 // energy in 3 strips in the 1st sampling
690 double e132 = (info.e132 > x) ? info.e132 : 0.;
691 // total ennergy
692 double energy = cluster.e();
693 // build fraction only if both quantities are well defined
694 if (std::abs(energy) > 0. && e132 > x) {
695 info.f1core = e132 / energy;
696 }
697}
698
699} // end of anonymous namespace
700
701StatusCode
703 const CaloDetDescrManager& cmgr,
704 Info& info,
705 bool ExecAllVariables)
706{
707 //
708 // Estimate shower shapes from first compartment
709 // based on hottest cell in 2nd sampling , the deta,dphi,
710 // And the barycenter in the 1st sampling (seed)
711 //
712
713 // check if cluster is in barrel or in the end-cap
714 if (!cluster.inBarrel() && !cluster.inEndcap()) {
715 return StatusCode::SUCCESS;
716 }
717 // retrieve energy in all samplings
718 const double eallsamples = egammaEnergyPositionAllSamples::e(cluster);
719 // retrieve energy in 1st sampling
720 const double e1 = egammaEnergyPositionAllSamples::e1(cluster);
721
722 // sam is used in SetArray to check that cells belong to strips
723 // samgran is used to estimate the window to use cells in eta
724 // it is based on the granularity of the middle layer
725 // For phi we use the strip layer granularity
726
727 // check if cluster is in barrel or end-cap
728 const bool in_barrel = egammaEnergyPositionAllSamples::inBarrel(cluster, 2);
729
730 // define accordingly the position of CaloSampling
731 const CaloSampling::CaloSample sam = in_barrel ? CaloSampling::EMB1 : CaloSampling::EME1;
732 const CaloSampling::CaloSample samgran = in_barrel ? CaloSampling::EMB2 : CaloSampling::EME2;
733
735
736 // get eta and phi of the seed
737 info.etaseed = cluster.etaSample(sam);
738 info.phiseed = cluster.phiSample(sam);
739 // get eta and phi of the hottest cell in the second sampling
740 info.etamax = cluster.etamax(samgran);
741 info.phimax = cluster.phimax(samgran);
742 // possible for soft electrons to be at -999
743 if ((info.etamax == 0. && info.phimax == 0.) ||
744 std::abs(info.etamax) > 100.) {
745 return StatusCode::SUCCESS;
746 }
747 // check if we are in a crack or outside area where strips are well defined
748 if (std::abs(info.etamax) > 2.4) {
749 return StatusCode::SUCCESS;
750 }
751 if (std::abs(info.etamax) > 1.4 && std::abs(info.etamax) < 1.5) {
752 return StatusCode::SUCCESS;
753 }
754 // We eeds both enums: subCalo and CaloSample
755 // use samgran = granularity in second sampling for eta !!!!
756 double deta = 0;
757 double dphi = 0;
758 bool barrel = false;
759 int sampling_or_module = 0;
761 subcalo, barrel, sampling_or_module, (CaloCell_ID::CaloSample)samgran);
762 const CaloDetDescrElement* dde = cmgr.get_element(
763 subcalo, sampling_or_module, barrel, info.etamax, info.phimax);
764 // if no object then exit
765 if (!dde) {
766 return StatusCode::SUCCESS;
767 }
768 // width in eta is granularity (dde->deta()) times number of cells (neta)
769 deta = dde->deta() * neta / 2.0;
770 // use samgran = granularity in first sampling for phi
772 subcalo, barrel, sampling_or_module, (CaloCell_ID::CaloSample)sam);
773 dde = cmgr.get_element(
774 subcalo, sampling_or_module, barrel, info.etamax, info.phimax);
775 // if no object then exit
776 if (!dde) {
777 return StatusCode::SUCCESS;
778 }
779 // width in phi is granularity (dde->dphi()) times number of cells (nphi)
780 dphi = dde->dphi() * nphi / 2.0;
781
782 /* initialize the arrays*/
783 double enecell[STRIP_ARRAY_SIZE] = { 0 };
784 double etacell[STRIP_ARRAY_SIZE] = { 0 };
785 double gracell[STRIP_ARRAY_SIZE] = { 0 };
786 int ncell[STRIP_ARRAY_SIZE] = { 0 };
787
788 // Fill the array in energy and eta from which all relevant
789 // quantities are estimated
790 setArray(cluster,
791 cmgr,
792 sam,
793 info.etamax,
794 info.phimax,
795 deta,
796 dphi,
797 enecell,
798 etacell,
799 gracell,
800 ncell);
801 /* Fill the the rest of the shapes*/
802 // find the corresponding index of the seed
803 setIndexSeed(info, etacell, gracell);
804 // calculate fraction of energy in strips
805 info.f1 = std::abs(eallsamples) > 0. ? e1 / eallsamples : 0.;
806 // calculate energy and bin where the energy strip is maximum
807 setEmax(info, enecell);
808 // calculate total width
809 setWstot(info, deta, enecell, etacell, ncell);
810 // width in three strips
811 setWs3(info, sam, cluster, enecell, etacell, ncell);
812 // Energy in in +/-1 and in +/-7 strips
813 if (ExecAllVariables) {
814 setEnergy(info, enecell);
815 setF1core(info, cluster);
816
817 setAsymmetry(info, enecell);
818 // Using strips centered on the hottest cell
819 // position in eta from +/- 1 strips
820 info.deltaEtaTrackShower =
821 setDeltaEtaTrackShower(1, info.ncetamax, enecell);
822 // Using strips centered on the seed cell
823 // position in eta from +/- 7 strips
824 info.deltaEtaTrackShower7 =
825 setDeltaEtaTrackShower(7, info.ncetaseed, enecell);
826 // calculate the fraction of energy int the two highest energy strips
827 setF2(info, enecell, eallsamples);
828 // Shower width in 5 strips around the highest energy strips
829 setWidths5(info, enecell);
830 // calculate energy of the second local maximum
831 int ncsec1 = setEmax2(info, enecell, gracell, ncell);
832 // calculate the energy of the strip with the minimum energy
833 setEmin(ncsec1, info, enecell, gracell, ncell);
834 // calculate M.S's valley
835 setValley(info, enecell);
836 // calculate M.S's fraction
837 setFside(info, enecell, gracell, ncell);
838 info.success = true;
839 }
840 return StatusCode::SUCCESS;
841}
842
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Calculate total energy, position, etc. for a given layer of a cluster.
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
static Double_t a
#define x
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
double energy() const
get energy (data member)
Definition CaloCell.h:327
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition CaloCell.h:382
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
static void decode_sample(CaloCell_ID::SUBCALO &subCalo, bool &barrel, int &sampling_or_module, CaloCell_ID::CaloSample sample)
translate between the 2 ways to label a sub-detector:
This class provides the client interface for accessing the detector description information common to...
float phiSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
virtual double e() const
The total energy of the particle.
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version)
const_cell_iterator cell_end() const
bool inBarrel() const
Returns true if at least one clustered cell in the barrel.
bool inEndcap() const
Returns true if at least one clustered cell in the endcap.
float etamax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
float etaSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
float phimax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
CaloSampling::CaloSample CaloSample
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
bool first
Definition DeMoScan.py:534
float round(const float toRound, const unsigned int decimals)
Definition Mdt.cxx:27
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
bool inBarrel(const xAOD::CaloCluster &cluster, int is)
return boolean to know if we are in barrel/end-cap
double e(const xAOD::CaloCluster &cluster)
return the uncorrected sum of energy in all samples
double RelPosition(const float eta, const float etacell)
returns relative position within the cell
float Correct(const float eta, const float etacell, const float width)
returns corrected width at eta
Definition index.py:1
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ e132
uncalibrated energy (sum of cells) in strips in a 3x2 window in cells in eta X phi
Definition EgammaEnums.h:37
setEt setPhi setE277 setWeta2 eta1
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
double proxim(double b, double a)
Definition proxim.h:17
static StatusCode execute(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &cmgr, Info &info, bool ExecAllVariables=true)
AlgTool main method.