ATLAS Offline Software
Loading...
Searching...
No Matches
CaloFillRectangularCluster.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
11
14#include "CaloEvent/CaloCell.h"
15#include "CaloDetDescr/CaloDetDescrElement.h"
19
23#include <algorithm>
24#include <utility>
25
26#include "CLHEP/Units/SystemOfUnits.h"
27#include "CLHEP/Units/PhysicalConstants.h"
28
30using CLHEP::GeV;
31using CLHEP::pi;
32using CLHEP::twopi;
33
34namespace {
35const double deta = 0.2;
36const double dphi = twopi / 64. + pi / 64.; // ~ 0.15 rad
37} // anonymous namespace
38
39
40
41
42namespace CaloClusterCorr {
43
44
45//**************************************************************************
46
47
65 double eta,
66 double phi,
68 double& deta,
69 double& dphi)
70{
71 deta = 0;
72 dphi = 0;
73
74 // Get the DD element for the central cell.
75 const CaloDetDescrElement* elt = dd_man.get_element_raw (sampling, eta, phi);
76 if (!elt) return;
77
78 // Should be smaller than the eta half-width of any cell.
79 const double eps = 0.001;
80
81 // Now look in the negative eta direction.
82 const CaloDetDescrElement* elt_l = dd_man.get_element_raw
83 (sampling,
84 eta - elt->deta() - eps,
85 phi);
86 double deta_l = 0; // Eta difference on the low (left) side.
87 if (elt_l)
88 deta_l = std::abs (eta - elt_l->eta_raw()) + eps;
89
90 // Now look in the positive eta direction.
91 const CaloDetDescrElement* elt_r = dd_man.get_element_raw
92 (sampling,
93 eta + elt->deta() + eps,
94 phi);
95 double deta_r = 0; // Eta difference on the high (right) side.
96 if (elt_r)
97 deta_r = std::abs (eta - elt_r->eta_raw()) + eps;
98
99 // Total deta is twice the maximum.
100 deta = 2 * std::max (deta_r, deta_l);
101
102 // Now for the phi variation.
103 // The phi size can change as a function of eta, but not of phi.
104 // Thus we have to look again at the adjacent eta cells, and
105 // take the largest variation.
106
107 // Now look in the negative eta direction.
108 elt_l = dd_man.get_element_raw
109 (sampling,
110 eta - elt->deta() - eps,
111 CaloPhiRange::fix (phi - elt->dphi() - eps));
112 double dphi_l = 0; // Phi difference on the low-eta () side.
113 if (elt_l)
114 dphi_l = std::abs (CaloPhiRange::fix (phi - elt_l->phi_raw())) + eps;
115
116 // Now look in the positive eta direction.
117 elt_r = dd_man.get_element_raw
118 (sampling,
119 eta + elt->deta() + eps,
120 CaloPhiRange::fix (phi - elt->dphi() - eps));
121 double dphi_r = 0; // Phi difference on the positive (down) side.
122 if (elt_r)
123 dphi_r = std::abs (CaloPhiRange::fix (phi - elt_r->phi_raw())) + eps;
124
125 // Total dphi is twice the maximum.
126 dphi = 2 * std::max (dphi_l, dphi_r);
127}
128
129
130//**************************************************************************
131
132
133// Helper to get calorimeter segmentation.
134// We need to defer this until after initialize(), when the detector
135// description is available.
137{
138public:
139 Segmentation (const CaloDetDescrManager* dd_man);
141 double m_detas2;
142 double m_dphis2;
143};
144
146{
147 if(dd_man == nullptr){
148 m_detas2 = 0;
149 m_dphis2 = 0;
150 }
151 else {
152 const CaloDetDescrElement* elt = dd_man->get_element (CaloCell_ID::EMB2,
153 0.001,
154 0.001);
155 if (elt) {
156 m_detas2 = elt->deta();
157 m_dphis2 = elt->dphi();
158 }
159 else {
160 // various TB configurations might have other eta/phi ranges or
161 // no access at all to EMB2 but would need still the standard
162 // EMB2 cell width as reference. Therefore the nominal eta and
163 // phi width is assumed here
164 m_detas2 = 0.025;
165 m_dphis2 = M_PI/128.;
166 }
167 }
168}
169
170
171//**************************************************************************
172
173
186{
187public:
197
198
200 virtual ~SamplingHelper() = default;
201
202
221 virtual void
222 calculate (double eta,
223 double phi,
224 double deta,
225 double dphi,
227 bool dofill = false) = 0;
228
229
231 virtual const CaloCell* max_et_cell() const = 0;
232
234 virtual bool empty() const = 0;
235
236
251 void
252 calculate_cluster (double eta,
253 double phi,
254 double deta,
255 double dphi,
256 CaloSampling::CaloSample sampling);
257
258
285 void
286 calculate_and_set (double eta,
287 double phi,
288 int layer,
289 int fallback_layer,
290 const CaloSampling::CaloSample samplings[4],
291 bool allow_badpos = false);
292
293
296
298 double etam() const;
299
301 double phim() const;
302
304 double etamax() const;
305
307 double phimax() const;
308
309 // return also the real value (now that the raw value are returned instead)
310 double etareal() const { return m_calc.etam(); }
311
312 // Return cluster window size for a given layer.
313 double deta (int layer) const { return m_windows[layer].first; }
314 double dphi (int layer) const { return m_windows[layer].second; }
315
316
317protected:
320
323
326
329
331 double m_etam;
332
334 double m_phim;
335};
336
337
354
355
382void
384 (double eta,
385 double phi,
386 int layer,
387 int fallback_layer,
388 const CaloSampling::CaloSample samplings[4],
389 bool allow_badpos)
390{
391 calculate (eta, phi, deta(layer), dphi(layer), samplings[layer], true);
392
393 double seteta = m_calc.etam();
394 double setphi = m_calc.phim();
395
396 double fallback_eta = eta;
397 double fallback_phi = phi;
398 if ((seteta == -999 || setphi == -999) && fallback_layer >= 0 && fallback_layer < 4) {
399 // In the calo frame
400 fallback_eta = m_cluster->etaSample (samplings[fallback_layer]);
401 fallback_phi = m_cluster->phiSample (samplings[fallback_layer]);
402 }
403
404 if (!allow_badpos) {
405 //if (m_etam == -999) m_etam = fallback_eta;
406 //if (m_phim == -999) m_phim = fallback_phi;
407 if (seteta == -999) seteta = fallback_eta;
408 if (setphi == -999) setphi = fallback_phi;
409 }
410
411 //FIXME: Sampling pattern not yet set!
412 m_parent.setsample (m_cluster,
413 samplings[layer],
414 m_calc.em(),
415 seteta,
416 setphi,
417 m_calc.emax(),
418 m_calc.etamax(),
419 m_calc.phimax(),
420 m_calc.etas(),
421 m_calc.phis());
422 if (allow_badpos) {
423 if (m_etam == -999) m_etam = fallback_eta;
424 if (m_phim == -999) m_phim = fallback_phi;
425 }
426}
427
428
443void
445 (double eta,
446 double phi,
447 double deta,
448 double dphi,
450{
451 m_calc.fill (m_cluster->cell_begin(), m_cluster->cell_end(),
452 eta, phi, deta, dphi, sampling);
453 m_etam = m_calc.etamr();
454 m_phim = m_calc.phimr();
455}
456
457
459inline
464
465
467inline
469{
470 return m_etam;
471}
472
473
475inline
477{
478 return m_phim;
479}
480
481
483inline
485{
486 return m_calc.etarmax();
487}
488
489
491inline
493{
494 return m_calc.phirmax();
495}
496
497
506{
507 bool operator() (const CaloCell* a, const CaloCell* b);
508 static double et (const CaloCell* cell);
509};
510
511
513 const CaloCell* b)
514{
515 return et(a) < et(b);
516}
517
518
520{
521 double et = cell->et();
522 if (cell->caloDDE()->getSubCalo() != CaloCell_ID::LAREM)
523 et -= 1000*GeV;
524 return et;
525}
526
527
528//**************************************************************************
529
530
535 : public SamplingHelper
536{
537public:
549 const CaloCellList& list,
550 const CaloCellContainer* cell_container);
551
552
569 virtual void
570 calculate (double eta,
571 double phi,
572 double deta,
573 double dphi,
575 bool dofill = false);
576
577
579 virtual const CaloCell* max_et_cell() const;
580
582 virtual bool empty() const;
583
584
585private:
588};
589
590
609
610
627void
629 (double eta,
630 double phi,
631 double deta,
632 double dphi,
634 bool dofill)
635{
636 m_calc.fill (m_list.begin(), m_list.end(),
637 eta, phi, deta, dphi, sampling,
638 dofill ? m_cluster : nullptr);
639 // use the calo frame to gather the cells
640 m_etam = m_calc.etamr();
641 m_phim = m_calc.phimr();
642}
643
644
647{
648 return *std::max_element (m_list.begin(), m_list.end(),
650}
651
652
655{
656 return m_list.begin() == m_list.end();
657}
658
659
660//**************************************************************************
661
662
667 : public SamplingHelper
668{
669public:
679
695 virtual void
696 calculate (double eta,
697 double phi,
698 double deta,
699 double dphi,
701 bool dofill = false);
702
704 virtual const CaloCell* max_et_cell() const;
705
707 virtual bool empty() const;
708};
709
710
723
724
740void
742 (double eta,
743 double phi,
744 double deta,
745 double dphi,
747 bool /*dofill*/)
748{
749 calculate_cluster (eta, phi, deta, dphi, sampling);
750}
751
752
755{
756 return *std::max_element(std::as_const(*m_cluster).cell_begin(),
757 std::as_const(*m_cluster).cell_end(),
759}
760
761
764{
765 return m_cluster->size()==0;
766}
767
768
769} // namespace CaloClusterCorr
770
771
772//**************************************************************************
773
774
782 (const std::string& type,
783 const std::string& name,
784 const IInterface* parent)
785 : CaloClusterCorrection(type, name, parent)
786{
787}
788
789
796{
797 // The method from the base class.
799 if (!m_cellsName.key().empty()){
800 CHECK( m_cellsName.initialize() );
801 }
802
803 ATH_CHECK(m_caloMgrKey.initialize());
804 return StatusCode::SUCCESS;
805}
806
807
808/*
809 * @brief Actually make the correction for one region (barrel or endcap).
810 * @param ctx The event context.
811 * @param helper Sampling calculation helper object.
812 * @param eta The @f$\eta@f$ seed of the cluster.
813 * @param phi The @f$\phi@f$ seed of the cluster.
814 * @param samplings List of samplings for this region.
815 */
816void
818 const CaloDetDescrManager& dd_man,
820 helper,
821 double eta,
822 double phi,
824 samplings[4]) const
825{
826 // Do sampling 2.
827 helper.calculate_and_set (eta, phi, 2, -1, samplings, true);
828 // the etam and phim of the helper are now filled with etamr and phimr from the CaloLayerCalculator
829 double eta2 = helper.etam();
830 double phi2 = helper.phim();
831 // Make sure that we have a seed. Assume the input cluster has a good (eta,phi)
832 if (eta2 == -999.) eta2 = eta;
833 if (phi2 == -999.) phi2 = phi;
834
835 // Now do sampling 1; use the result from sampling 2 as the seed.
836 helper.calculate_and_set (eta2, phi2, 1, -1, samplings);
837 double eta1 = helper.etam();
838 double phi1 = helper.phim();
839 bool refine = true;
840 if (eta1 == -999. || phi1 == -999.) {
841 // Make sure that we have a seed. If eta,phi1 not OK, (e.g. deadOTX), take (eta2,phi2)
842 if (eta1 == -999.) eta1 = eta2;
843 if (phi1 == -999.) phi1 = phi2;
844 refine = false;
845 }
846
847 // For some silly reason, we have TWO different sampling enums.
848 // The clusters use one, the detector description uses the other.
850 if (samplings[1] == CaloSampling::EMB1)
851 xsample = CaloCell_ID::EMB1;
852 else
853 xsample = CaloCell_ID::EME1;
854
855 // Now refine the eta position using +-1 strip around hot cell
856 // This only makes sense if the previous step was OK
857 if (refine) {
858 double detastr, dphistr;
859 CaloClusterCorr::etaphi_range (dd_man,helper.etamax(), helper.phimax(),
860 xsample,
861 detastr, dphistr);
862
863 if (detastr > 0 && dphistr > 0) {
864 helper.calculate_cluster (helper.etamax(), helper.phimax(),
865 detastr, dphistr, samplings[1]);
866
867 if (helper.etam()!=-999.) {
868 eta1 = helper.etam();
869 double eta1r = helper.etareal();
870 helper.cluster()->setEta(samplings[1], eta1r);
871 }
872 }
873 }
874
875 // Now do sampling 0 using the eta1 point:
876 helper.calculate_and_set (eta1, phi2, 0, 1, samplings);
877
878 // Do for sampling 3 (using the sampling 2 seed).
879 helper.calculate_and_set (eta2, phi2, 3, -1, samplings);
880
881 // Crack;
882 // Check if the cluster has TileGap3 sampling and avoid to calculate the TileGap3 energy twice
883 if ( helper.cluster()->hasSampling(CaloSampling::TileGap3) && samplings[0]==CaloSampling::PreSamplerE )
884 {
885 //By default, use the original cell container
886 const CaloCellContainer* cc = helper.cluster()->getCellLinks()->getCellContainer();
887
888 //Leave the option to use a different cell container
889 if (!m_cellsName.key().empty()) {
891 if (!cchand.isValid()) {
892 REPORT_ERROR(StatusCode::FAILURE)
893 << "Can't retrieve cell container " << m_cellsName.key();
894 return;
895 }
896 cc = cchand.cptr();
897 }
898
899 if(!cc) //cover the case when the cluster does not give a cell container and the name is empty
900 {
901 REPORT_ERROR(StatusCode::FAILURE)
902 << "Can't find cell container; cluster does not give a cell container";
903 return;
904 }
905
906 // Add up the tile scintillator energy in the region around the cluster.
907 double eh_scint = 0;
909 cc->beginConstCalo(CaloCell_ID::TILE);
911 cc->endConstCalo(CaloCell_ID::TILE);
912
913 for ( ; f_cell!=l_cell; ++f_cell)
914 {
915 const CaloCell* cell = (*f_cell) ;
916
917 if (CaloCell_ID::TileGap3 == cell->caloDDE()->getSampling()) {
918 // consider only E4 cell
919 if( fabs(cell->eta()) < 1.4 || fabs(cell->eta()) > 1.6 ) continue;
920 double phic = cell->phi();
921 double etac = cell->eta();
922
923 float diffeta = etac-eta2;
924 float diffphi = phic-phi2;
925 if (diffphi < -pi) diffphi += twopi;
926 if (diffphi > pi) diffphi -= twopi;
927
928 if(fabs(diffeta)<deta && fabs(diffphi)<dphi){
929 eh_scint += cell->e();
930 }
931 }
932 }
933 //Set the TileGap3 sampling energy to the cluster; Needed for MVA calibration
934 helper.cluster()->setEnergy(CaloSampling::TileGap3,eh_scint);
935
936 helper.cluster()->setEta(CaloSampling::TileGap3, eta2);
937 helper.cluster()->setPhi(CaloSampling::TileGap3, phi2);
938 }
939}
940
941
942/*
943 * @brief Execute the correction, given a helper object.
944 * @param ctx The event context.
945 * @param helper Sampling calculation helper object.
946 */
947void
949 const CaloDetDescrManager& dd_man,
951 helper) const
952{
953
954 // Don't do anything if we don't have any cells.
955 if (helper.empty())
956 return;
957
958 // Get the seed position of the cluster.
959 CaloCluster* cluster = helper.cluster();
960 double eta, phi;
961 get_seed (helper, cluster, eta, phi);
962 double aeta = fabs(eta);
963
964 // set the appropriate cluster size
965 int neta = cluster->getClusterEtaSize();
966 int nphi = cluster->getClusterPhiSize();
967
968 if (m_neta != neta || m_nphi != nphi) {
969 CaloCluster::ClusterSize oldSize = cluster->clusterSize();
970 CaloCluster::ClusterSize newSize = oldSize;
971 switch(oldSize) {
973 break;
977 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
978 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
979 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
980 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
981 break;
985 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55gam;
986 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35gam;
987 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37gam;
988 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
989 break;
993 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55Econv;
994 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35Econv;
995 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37Econv;
996 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
997 break;
998 default:
999 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
1000 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
1001 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
1002 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
1003 break;
1004 }
1005 cluster->setClusterSize(newSize);
1006 }
1007
1008 // Lists of samplings in the barrel and endcap.
1009 static const CaloSampling::CaloSample samplings_b[4] =
1010 { CaloSampling::PreSamplerB, CaloSampling::EMB1,
1011 CaloSampling::EMB2, CaloSampling::EMB3 };
1012 static const CaloSampling::CaloSample samplings_e[4] =
1013 { CaloSampling::PreSamplerE, CaloSampling::EME1,
1014 CaloSampling::EME2, CaloSampling::EME3 };
1015
1016 // We need to calculate sampling properties for barrel and endcap
1017 // separately.
1018 // FIXME: the overlap with barrel should be checked!!
1019
1020 //Now set the sampling pattern for this cluster
1021 //Can't set sampling variables w/o setting the sampling pattern before
1022 uint32_t samplingPattern_b=0xf; //first four bits: The barrel sampling (PS to Back)
1023 uint32_t samplingPattern_e=0xf0; //bits 4-7: The EMEC samplings (PS to back)
1024 uint32_t samplingPattern=0;
1025
1026 if (aeta < 1.6)
1027 samplingPattern |=samplingPattern_b;
1028
1029 if (aeta > 1.3)
1030 samplingPattern |=samplingPattern_e;
1031
1032 if (aeta > 1.37 && aeta < 1.63)
1033 samplingPattern |=(1<<(uint32_t)CaloSampling::TileGap3);
1034
1035 cluster->setSamplingPattern(samplingPattern);
1036
1037 // Barrel
1038 if (aeta < 1.6) {
1039 makeCorrection1 (ctx, dd_man,helper, eta, phi, samplings_b);
1040 }
1041
1042 // Endcap
1043 if (aeta > 1.3) {
1044 makeCorrection1 (ctx, dd_man,helper, eta, phi, samplings_e);
1045 }
1046
1047 // Set the total cluster energy to the sum over all samplings.
1048 double cl_ene = 0;
1049 for(int i=0; i<4; i++ ){
1050 cl_ene += cluster->eSample(samplings_b[i]);
1051 cl_ene += cluster->eSample(samplings_e[i]);
1052 }
1053 cluster->setE(cl_ene);
1054
1055 if (m_setRawState) {
1056 cluster->setRawE(cl_ene);
1057 cluster->setRawEta(eta);
1058 cluster->setRawPhi(phi);
1059 }
1060
1061}
1062
1063
1069void CaloFillRectangularCluster::makeCorrection (const Context& myctx,
1070 CaloCluster* cluster) const
1071{
1072 ATH_MSG_DEBUG( "Executing CaloFillRectangularCluster" << endmsg) ;
1073
1074 // retrieve CaloDetDescr
1075 SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle { m_caloMgrKey, myctx.ctx()};
1076 if(!caloDetDescrMgrHandle.isValid()){
1077 ATH_MSG_ERROR ("Failed to retrieve CaloDetDescrManager : CaloMgr");
1078 }
1079
1080 const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
1081
1082 CaloClusterCorr::Segmentation seg (calodetdescrmgr);
1083 if (seg.m_detas2 == 0) {
1084 ATH_MSG_ERROR ("Retrieving cell segmentation");
1085 return;
1086 }
1088 seg.m_detas2, seg.m_dphis2);
1089
1090 if (m_fill_cluster) {
1091
1092 //By default, use the original cell container
1093 const CaloCellContainer* cell_container = cluster->getCellLinks()->getCellContainer();
1094 // We're filling the cluster with cells from StoreGate.
1095 // First, remove existing cells.
1096 cluster->getOwnCellLinks()->clear();
1097
1098 //Leave the option to use a different cell container
1099 if (!m_cellsName.key().empty()) {
1100 SG::ReadHandle<CaloCellContainer> cchand (m_cellsName, myctx.ctx());
1101 if (!cchand.isValid()) {
1102 REPORT_ERROR(StatusCode::FAILURE)
1103 << "Can't retrieve cell container " << m_cellsName.key();
1104 return;
1105 }
1106 cell_container = cchand.cptr();
1107 }
1108
1109
1110 // Define the center for building the list of candidate cells.
1111 double eta = cluster->eta0();
1112 double phi = cluster->phi0();
1114
1115 // Build the candidate cell list.
1116 // This 5 is a safe margin for cell_list calculation
1117 // and should not be changed.
1118 CaloCellList cell_list(calodetdescrmgr,cell_container);
1119 cell_list.select(eta,phi,seg.m_detas2*(m_neta+5),seg.m_dphis2*(m_nphi+5));
1120
1121 // Do the calculation.
1122 CaloClusterCorr::SamplingHelper_CaloCellList helper (*this,
1123 windows,
1124 cluster,
1125 cell_list,
1126 cell_container);
1127 makeCorrection2 (myctx.ctx(), *calodetdescrmgr, helper);
1128 }
1129 else {
1130 // We're recalculating a cluster using the existing cells.
1131 CaloClusterCorr::SamplingHelper_Cluster helper (*this, windows, cluster);
1132 makeCorrection2 (myctx.ctx(), *calodetdescrmgr,helper);
1133 }
1134}
1135
1136
1137/*
1138 * @brief Return the seed position of a cluster.
1139 * @param helper Sampling calculation helper object.
1140 * @param cluster The cluster on which to operate.
1141 * @param[out] eta The @f$\eta@f$ location of the cluster seed.
1142 * @param[out] phi The @f$\phi@f$ location of the cluster seed.
1143 *
1144 * The cluster seed is the center of rectangular cluster windows.
1145 * This may be overridden by derived classes to change the seed definition.
1146 */
1148 const CaloCluster* cluster,
1149 double& eta,
1150 double& phi) const
1151{
1152 const CaloCell* max_et_cell = helper.max_et_cell();
1153
1155 // a.b.c 2004 : for barrel, correct for the alignment before
1156 // comparing the Tower direction and the cell's
1157 // ( for Atlas the difference is null, but it's not true for TB )
1158 const CaloDetDescrElement* elt = max_et_cell->caloDDE();
1159 double phi_shift = elt->phi()-elt->phi_raw();
1160 double eta_shift = elt->eta()-elt->eta_raw();
1161 eta = cluster->eta0()+eta_shift;
1162 phi = CaloPhiRange::fix(cluster->phi0()+phi_shift);
1163
1164 // Special case to handle a pathology seen at the edge of the calorimeter
1165 // with clusters with an eta size of 3. The cluster size used for the SW
1166 // clustering is 5x5. The SW clustering will find the window that contains
1167 // the maximum amount of energy. So, suppose that there's a cluster
1168 // near the edge of the calorimeter such that the most energetic cell
1169 // is right at the edge of the calorimeter. In this case, the SW clustering
1170 // is likely to position the seed cell two cells from the edge
1171 // (the next-to-next-to-last cell), as in that case, all 5 eta cells
1172 // are contained within the calorimeter. But in that case, if we then
1173 // build a cluster of size 3 around this seed, then we'll be missing
1174 // the cell with the highest energy! This will severely bias the
1175 // energy and eta measurements.
1176 //
1177 // So, what I'll do is this. If the maximum cell is at the outer
1178 // edge of the (outer) EC and it is not within our eta window, then I'll
1179 // use the maximum cell position as the seed instead of what
1180 // the SW clustering gives. I restrict this to the outer edge
1181 // of the EC to avoid any chance of changing the clustering results
1182 // in the bulk of the calorimeter.
1183 // Also do this if the maximum cell is on the edge of the inner endcap ---
1184 // we can get the same effect.
1185 if ((elt->is_lar_em_endcap_inner() &&
1186 std::abs(elt->eta_raw()) - elt->deta() <
1187 elt->descriptor()->calo_eta_min()) ||
1188 (elt->is_lar_em_endcap_outer() &&
1189 std::abs(elt->eta_raw()) + elt->deta() >
1190 elt->descriptor()->calo_eta_max()))
1191 {
1192 // Max cell is at the edge. Is it outside the window?
1193 if (std::abs (eta - elt->eta()) > helper.deta(2)/2) {
1194 // Yes --- change the seed.
1195 eta = elt->eta();
1196 }
1197 }
1198
1199 // stay in the calo frame and do not cook for cluster on edge
1200 // (inputs are now 3x5 so there should not be problems anymore)
1201 eta = cluster->eta0();
1202 phi = CaloPhiRange::fix(cluster->phi0());
1203
1204}
1205
1206
1211StatusCode
1213 (const std::string& name)
1214{
1215 return this->setProperty (StringProperty ("cells_name", name));
1216}
1217
1218
1230 const int nphi,
1231 const double detas2,
1232 const double dphis2) const
1233{
1235
1236 // set up the sampling windows:
1237 w[0].first = detas2*neta;
1238 w[0].second = dphis2*4;
1239
1240 if (nphi >= 7)
1241 w[0].second *= 2;
1242 else
1243 w[0].second *= 1.5;
1244
1245 w[1].first = w[0].first;
1246 w[1].second = w[0].second;
1247
1248 w[2].first = detas2*neta;
1249 w[2].second = dphis2*nphi;
1250
1251 w[3].first = (2*detas2)*(0.5 + (neta/2.));
1252 w[3].second = w[2].second;
1253
1254 return w;
1255}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescriptor.
Calculates the per-layer position, size, etc. of a cluster. Optionally, fills the cluster with cells ...
Calculate total energy, position, etc. for a given layer of a cluster.
CaloPhiRange class declaration.
Helpers for checking error return status codes and reporting errors.
#define REPORT_ERROR(SC)
Report an error.
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t a
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
Handle class for reading from StoreGate.
#define pi
constexpr double twopi
Container class for CaloCell.
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
virtual bool empty() const
Test for empty candidate cell list.
virtual const CaloCell * max_et_cell() const
Return the cell with the maximum energy.
SamplingHelper_CaloCellList(const CaloClusterCorrection &parent, const CaloFillRectangularCluster::WindowArray_t &windows, CaloCluster *cluster, const CaloCellList &list, const CaloCellContainer *cell_container)
Constructor.
virtual void calculate(double eta, double phi, double deta, double dphi, CaloSampling::CaloSample sampling, bool dofill=false)
Calculate layer variables.
SamplingHelper_Cluster(const CaloClusterCorrection &parent, const CaloFillRectangularCluster::WindowArray_t &windows, CaloCluster *cluster)
Constructor.
virtual const CaloCell * max_et_cell() const
Return the cell with the maximum energy.
virtual void calculate(double eta, double phi, double deta, double dphi, CaloSampling::CaloSample sampling, bool dofill=false)
Calculate layer variables.
virtual bool empty() const
Test for empty candidate cell list.
Sampling calculator helper class.
double etamax() const
Return the maximum position from the last calculation.
CaloLayerCalculator m_calc
The calculator object.
virtual ~SamplingHelper()=default
Destructor — just to get a vtable.
virtual const CaloCell * max_et_cell() const =0
Return the cell with the maximum energy — abstract method.
SamplingHelper(const CaloClusterCorrection &parent, const CaloFillRectangularCluster::WindowArray_t &windows, CaloCluster *cluster)
Constructor.
virtual void calculate(double eta, double phi, double deta, double dphi, CaloSampling::CaloSample sampling, bool dofill=false)=0
Calculate layer variables — abstract method.
double phim() const
Return the position from the last calculation.
const CaloClusterCorrection & m_parent
The correction object using us.
double etam() const
Return the position from the last calculation.
double m_phim
position from last calculation.
void calculate_and_set(double eta, double phi, int layer, int fallback_layer, const CaloSampling::CaloSample samplings[4], bool allow_badpos=false)
Calculate layer variables and update cluster.
CaloCluster * m_cluster
The cluster we're updating.
CaloCluster * cluster()
Return the cluster we're updating.
double phimax() const
Return the maximum position from the last calculation.
double m_etam
position from last calculation.
virtual bool empty() const =0
Test for empty candidate cell list — abstract method.
CaloFillRectangularCluster::WindowArray_t m_windows
Window size, per layer.
void calculate_cluster(double eta, double phi, double deta, double dphi, CaloSampling::CaloSample sampling)
Calculate layer variables for cells in the cluster.
double m_detas2
middle layer cell segmentation size
Segmentation(const CaloDetDescrManager *dd_man)
virtual StatusCode initialize() override
Initialize method.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Principal data class for CaloCell clusters.
double eta0() const
Returns raw of cluster seed.
void setRawEta(double eta)
Set raw eta.
double eSample(sampling_type sampling) const
Retrieve energy in a given sampling.
unsigned int getClusterEtaSize() const
void setRawPhi(double phi)
Set raw phi.
void setRawE(double e)
Set raw energy.
void setClusterSize(unsigned int theClusterSize)
Set cluster size.
unsigned int getClusterPhiSize() const
double phi0() const
Returns raw of cluster seed.
virtual void setE(double e)
Set energy.
const CaloCellContainer * getCellContainer(const CaloCell *pCell) const
Retrieve the pointer to the original cell container for a given cell.
This class groups all DetDescr information related to a CaloCell.
bool is_lar_em_endcap_outer() const
cell belongs to the outer wheel of EM end cap
bool is_lar_em_endcap_inner() const
cell belongs to the inner wheel of EM end cap
const CaloDetDescriptor * descriptor() const
cell descriptor
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
const CaloDetDescrElement * get_element_raw(CaloCell_ID::CaloSample sample, double eta, double phi) const
Get element from raw quantities (to build real fixed size clusters)
This class provides the client interface for accessing the detector description information common to...
double calo_eta_min() const
'ideal' geometry: eta minimal
double calo_eta_max() const
'ideal' geometry: eta maximal
Gaudi::Property< int > m_neta
cluster size. These are properties.
Gaudi::Property< bool > m_fill_cluster
Fill-cluster flag.
SG::ReadHandleKey< CaloCellContainer > m_cellsName
The StoreGate key for the container of our input cells.
Gaudi::Property< bool > m_setRawState
Property to tell if the raw energy, eta0 and phi0 should be saved as uncalibrated signal state.
virtual void get_seed(CaloClusterCorr::SamplingHelper &helper, const xAOD::CaloCluster *cluster, double &eta, double &phi) const
std::array< std::pair< double, double >, 4 > WindowArray_t
Holds the per-layer window sizes.
void makeCorrection2(const EventContext &ctx, const CaloDetDescrManager &dd_man, CaloClusterCorr::SamplingHelper &helper) const
CaloFillRectangularCluster()=delete
This isn't allowed.
virtual void makeCorrection(const Context &myctx, xAOD::CaloCluster *cluster) const override
CaloClusterCorrection virtual method.
void makeCorrection1(const EventContext &ctx, const CaloDetDescrManager &dd_man, CaloClusterCorr::SamplingHelper &helper, double eta, double phi, const CaloSampling::CaloSample samplings[4]) const
virtual WindowArray_t initWindows(const int neta, const int nphi, const double detas2, const double dphis2) const
Set up layer-by-layer cluster window sizes.
virtual StatusCode initialize() override
Standard Gaudi initialize method.
virtual StatusCode setCaloCellContainerName(const std::string &name) override
Change the name of the CaloCellContainer used by this tool.
static double fix(double phi)
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
ClusterSize
Enumeration to identify different cluster sizes.
void etaphi_range(const CaloDetDescrManager &dd_man, double eta, double phi, CaloCell_ID::CaloSample sampling, double &deta, double &dphi)
Return eta/phi ranges encompassing +- 1 cell.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
bool operator()(const CaloCell *a, const CaloCell *b)
int windows(float distance, float eta_pivot, int thr, int sector)
Definition windows.cxx:14