ATLAS Offline Software
Loading...
Searching...
No Matches
CaloFillRectangularCluster.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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 // properties
788 declareProperty("eta_size", m_neta = 5);
789 declareProperty("phi_size", m_nphi = 5);
790 declareProperty("fill_cluster", m_fill_cluster = true);
791 declareProperty("cells_name", m_cellsName = "AllCalo");
792 declareProperty("set_raw_state",m_setRawState=true);
793}
794
795
802{
803 // The method from the base class.
805 if (!m_cellsName.key().empty()){
806 CHECK( m_cellsName.initialize() );
807 }
808
809 ATH_CHECK(m_caloMgrKey.initialize());
810 return StatusCode::SUCCESS;
811}
812
813
814/*
815 * @brief Actually make the correction for one region (barrel or endcap).
816 * @param ctx The event context.
817 * @param helper Sampling calculation helper object.
818 * @param eta The @f$\eta@f$ seed of the cluster.
819 * @param phi The @f$\phi@f$ seed of the cluster.
820 * @param samplings List of samplings for this region.
821 */
822void
824 const CaloDetDescrManager& dd_man,
826 helper,
827 double eta,
828 double phi,
830 samplings[4]) const
831{
832 // Do sampling 2.
833 helper.calculate_and_set (eta, phi, 2, -1, samplings, true);
834 // the etam and phim of the helper are now filled with etamr and phimr from the CaloLayerCalculator
835 double eta2 = helper.etam();
836 double phi2 = helper.phim();
837 // Make sure that we have a seed. Assume the input cluster has a good (eta,phi)
838 if (eta2 == -999.) eta2 = eta;
839 if (phi2 == -999.) phi2 = phi;
840
841 // Now do sampling 1; use the result from sampling 2 as the seed.
842 helper.calculate_and_set (eta2, phi2, 1, -1, samplings);
843 double eta1 = helper.etam();
844 double phi1 = helper.phim();
845 bool refine = true;
846 if (eta1 == -999. || phi1 == -999.) {
847 // Make sure that we have a seed. If eta,phi1 not OK, (e.g. deadOTX), take (eta2,phi2)
848 if (eta1 == -999.) eta1 = eta2;
849 if (phi1 == -999.) phi1 = phi2;
850 refine = false;
851 }
852
853 // For some silly reason, we have TWO different sampling enums.
854 // The clusters use one, the detector description uses the other.
856 if (samplings[1] == CaloSampling::EMB1)
857 xsample = CaloCell_ID::EMB1;
858 else
859 xsample = CaloCell_ID::EME1;
860
861 // Now refine the eta position using +-1 strip around hot cell
862 // This only makes sense if the previous step was OK
863 if (refine) {
864 double detastr, dphistr;
865 CaloClusterCorr::etaphi_range (dd_man,helper.etamax(), helper.phimax(),
866 xsample,
867 detastr, dphistr);
868
869 if (detastr > 0 && dphistr > 0) {
870 helper.calculate_cluster (helper.etamax(), helper.phimax(),
871 detastr, dphistr, samplings[1]);
872
873 if (helper.etam()!=-999.) {
874 eta1 = helper.etam();
875 double eta1r = helper.etareal();
876 helper.cluster()->setEta(samplings[1], eta1r);
877 }
878 }
879 }
880
881 // Now do sampling 0 using the eta1 point:
882 helper.calculate_and_set (eta1, phi2, 0, 1, samplings);
883
884 // Do for sampling 3 (using the sampling 2 seed).
885 helper.calculate_and_set (eta2, phi2, 3, -1, samplings);
886
887 // Crack;
888 // Check if the cluster has TileGap3 sampling and avoid to calculate the TileGap3 energy twice
889 if ( helper.cluster()->hasSampling(CaloSampling::TileGap3) && samplings[0]==CaloSampling::PreSamplerE )
890 {
891 //By default, use the original cell container
892 const CaloCellContainer* cc = helper.cluster()->getCellLinks()->getCellContainer();
893
894 //Leave the option to use a different cell container
895 if (!m_cellsName.key().empty()) {
897 if (!cchand.isValid()) {
898 REPORT_ERROR(StatusCode::FAILURE)
899 << "Can't retrieve cell container " << m_cellsName.key();
900 return;
901 }
902 cc = cchand.cptr();
903 }
904
905 if(!cc) //cover the case when the cluster does not give a cell container and the name is empty
906 {
907 REPORT_ERROR(StatusCode::FAILURE)
908 << "Can't find cell container; cluster does not give a cell container";
909 return;
910 }
911
912 // Add up the tile scintillator energy in the region around the cluster.
913 double eh_scint = 0;
915 cc->beginConstCalo(CaloCell_ID::TILE);
917 cc->endConstCalo(CaloCell_ID::TILE);
918
919 for ( ; f_cell!=l_cell; ++f_cell)
920 {
921 const CaloCell* cell = (*f_cell) ;
922
923 if (CaloCell_ID::TileGap3 == cell->caloDDE()->getSampling()) {
924 // consider only E4 cell
925 if( fabs(cell->eta()) < 1.4 || fabs(cell->eta()) > 1.6 ) continue;
926 double phic = cell->phi();
927 double etac = cell->eta();
928
929 float diffeta = etac-eta2;
930 float diffphi = phic-phi2;
931 if (diffphi < -pi) diffphi += twopi;
932 if (diffphi > pi) diffphi -= twopi;
933
934 if(fabs(diffeta)<deta && fabs(diffphi)<dphi){
935 eh_scint += cell->e();
936 }
937 }
938 }
939 //Set the TileGap3 sampling energy to the cluster; Needed for MVA calibration
940 helper.cluster()->setEnergy(CaloSampling::TileGap3,eh_scint);
941
942 helper.cluster()->setEta(CaloSampling::TileGap3, eta2);
943 helper.cluster()->setPhi(CaloSampling::TileGap3, phi2);
944 }
945}
946
947
948/*
949 * @brief Execute the correction, given a helper object.
950 * @param ctx The event context.
951 * @param helper Sampling calculation helper object.
952 */
953void
955 const CaloDetDescrManager& dd_man,
957 helper) const
958{
959
960 // Don't do anything if we don't have any cells.
961 if (helper.empty())
962 return;
963
964 // Get the seed position of the cluster.
965 CaloCluster* cluster = helper.cluster();
966 double eta, phi;
967 get_seed (helper, cluster, eta, phi);
968 double aeta = fabs(eta);
969
970 // set the appropriate cluster size
971 int neta = cluster->getClusterEtaSize();
972 int nphi = cluster->getClusterPhiSize();
973
974 if (m_neta != neta || m_nphi != nphi) {
975 CaloCluster::ClusterSize oldSize = cluster->clusterSize();
976 CaloCluster::ClusterSize newSize = oldSize;
977 switch(oldSize) {
979 break;
983 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
984 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
985 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
986 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
987 break;
991 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55gam;
992 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35gam;
993 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37gam;
994 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
995 break;
999 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55Econv;
1000 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35Econv;
1001 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37Econv;
1002 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
1003 break;
1004 default:
1005 if (m_neta==5 && m_nphi==5) newSize=CaloCluster::SW_55ele;
1006 if (m_neta==3 && m_nphi==5) newSize=CaloCluster::SW_35ele;
1007 if (m_neta==3 && m_nphi==7) newSize=CaloCluster::SW_37ele;
1008 if (m_neta==7 && m_nphi==11) newSize=CaloCluster::SW_7_11;
1009 break;
1010 }
1011 cluster->setClusterSize(newSize);
1012 }
1013
1014 // Lists of samplings in the barrel and endcap.
1015 static const CaloSampling::CaloSample samplings_b[4] =
1016 { CaloSampling::PreSamplerB, CaloSampling::EMB1,
1017 CaloSampling::EMB2, CaloSampling::EMB3 };
1018 static const CaloSampling::CaloSample samplings_e[4] =
1019 { CaloSampling::PreSamplerE, CaloSampling::EME1,
1020 CaloSampling::EME2, CaloSampling::EME3 };
1021
1022 // We need to calculate sampling properties for barrel and endcap
1023 // separately.
1024 // FIXME: the overlap with barrel should be checked!!
1025
1026 //Now set the sampling pattern for this cluster
1027 //Can't set sampling variables w/o setting the sampling pattern before
1028 uint32_t samplingPattern_b=0xf; //first four bits: The barrel sampling (PS to Back)
1029 uint32_t samplingPattern_e=0xf0; //bits 4-7: The EMEC samplings (PS to back)
1030 uint32_t samplingPattern=0;
1031
1032 if (aeta < 1.6)
1033 samplingPattern |=samplingPattern_b;
1034
1035 if (aeta > 1.3)
1036 samplingPattern |=samplingPattern_e;
1037
1038 if (aeta > 1.37 && aeta < 1.63)
1039 samplingPattern |=(1<<(uint32_t)CaloSampling::TileGap3);
1040
1041 cluster->setSamplingPattern(samplingPattern);
1042
1043 // Barrel
1044 if (aeta < 1.6) {
1045 makeCorrection1 (ctx, dd_man,helper, eta, phi, samplings_b);
1046 }
1047
1048 // Endcap
1049 if (aeta > 1.3) {
1050 makeCorrection1 (ctx, dd_man,helper, eta, phi, samplings_e);
1051 }
1052
1053 // Set the total cluster energy to the sum over all samplings.
1054 double cl_ene = 0;
1055 for(int i=0; i<4; i++ ){
1056 cl_ene += cluster->eSample(samplings_b[i]);
1057 cl_ene += cluster->eSample(samplings_e[i]);
1058 }
1059 cluster->setE(cl_ene);
1060
1061 if (m_setRawState) {
1062 cluster->setRawE(cl_ene);
1063 cluster->setRawEta(eta);
1064 cluster->setRawPhi(phi);
1065 }
1066
1067}
1068
1069
1075void CaloFillRectangularCluster::makeCorrection (const Context& myctx,
1076 CaloCluster* cluster) const
1077{
1078 ATH_MSG_DEBUG( "Executing CaloFillRectangularCluster" << endmsg) ;
1079
1080 // retrieve CaloDetDescr
1081 SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle { m_caloMgrKey, myctx.ctx()};
1082 if(!caloDetDescrMgrHandle.isValid()){
1083 ATH_MSG_ERROR ("Failed to retrieve CaloDetDescrManager : CaloMgr");
1084 }
1085
1086 const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
1087
1088 CaloClusterCorr::Segmentation seg (calodetdescrmgr);
1089 if (seg.m_detas2 == 0) {
1090 ATH_MSG_ERROR ("Retrieving cell segmentation");
1091 return;
1092 }
1094 seg.m_detas2, seg.m_dphis2);
1095
1096 if (m_fill_cluster) {
1097
1098 //By default, use the original cell container
1099 const CaloCellContainer* cell_container = cluster->getCellLinks()->getCellContainer();
1100 // We're filling the cluster with cells from StoreGate.
1101 // First, remove existing cells.
1102 cluster->getOwnCellLinks()->clear();
1103
1104 //Leave the option to use a different cell container
1105 if (!m_cellsName.key().empty()) {
1106 SG::ReadHandle<CaloCellContainer> cchand (m_cellsName, myctx.ctx());
1107 if (!cchand.isValid()) {
1108 REPORT_ERROR(StatusCode::FAILURE)
1109 << "Can't retrieve cell container " << m_cellsName.key();
1110 return;
1111 }
1112 cell_container = cchand.cptr();
1113 }
1114
1115
1116 // Define the center for building the list of candidate cells.
1117 double eta = cluster->eta0();
1118 double phi = cluster->phi0();
1120
1121 // Build the candidate cell list.
1122 // This 5 is a safe margin for cell_list calculation
1123 // and should not be changed.
1124 CaloCellList cell_list(calodetdescrmgr,cell_container);
1125 cell_list.select(eta,phi,seg.m_detas2*(m_neta+5),seg.m_dphis2*(m_nphi+5));
1126
1127 // Do the calculation.
1128 CaloClusterCorr::SamplingHelper_CaloCellList helper (*this,
1129 windows,
1130 cluster,
1131 cell_list,
1132 cell_container);
1133 makeCorrection2 (myctx.ctx(), *calodetdescrmgr, helper);
1134 }
1135 else {
1136 // We're recalculating a cluster using the existing cells.
1137 CaloClusterCorr::SamplingHelper_Cluster helper (*this, windows, cluster);
1138 makeCorrection2 (myctx.ctx(), *calodetdescrmgr,helper);
1139 }
1140}
1141
1142
1143/*
1144 * @brief Return the seed position of a cluster.
1145 * @param helper Sampling calculation helper object.
1146 * @param cluster The cluster on which to operate.
1147 * @param[out] eta The @f$\eta@f$ location of the cluster seed.
1148 * @param[out] phi The @f$\phi@f$ location of the cluster seed.
1149 *
1150 * The cluster seed is the center of rectangular cluster windows.
1151 * This may be overridden by derived classes to change the seed definition.
1152 */
1154 const CaloCluster* cluster,
1155 double& eta,
1156 double& phi) const
1157{
1158 const CaloCell* max_et_cell = helper.max_et_cell();
1159
1161 // a.b.c 2004 : for barrel, correct for the alignment before
1162 // comparing the Tower direction and the cell's
1163 // ( for Atlas the difference is null, but it's not true for TB )
1164 const CaloDetDescrElement* elt = max_et_cell->caloDDE();
1165 double phi_shift = elt->phi()-elt->phi_raw();
1166 double eta_shift = elt->eta()-elt->eta_raw();
1167 eta = cluster->eta0()+eta_shift;
1168 phi = CaloPhiRange::fix(cluster->phi0()+phi_shift);
1169
1170 // Special case to handle a pathology seen at the edge of the calorimeter
1171 // with clusters with an eta size of 3. The cluster size used for the SW
1172 // clustering is 5x5. The SW clustering will find the window that contains
1173 // the maximum amount of energy. So, suppose that there's a cluster
1174 // near the edge of the calorimeter such that the most energetic cell
1175 // is right at the edge of the calorimeter. In this case, the SW clustering
1176 // is likely to position the seed cell two cells from the edge
1177 // (the next-to-next-to-last cell), as in that case, all 5 eta cells
1178 // are contained within the calorimeter. But in that case, if we then
1179 // build a cluster of size 3 around this seed, then we'll be missing
1180 // the cell with the highest energy! This will severely bias the
1181 // energy and eta measurements.
1182 //
1183 // So, what I'll do is this. If the maximum cell is at the outer
1184 // edge of the (outer) EC and it is not within our eta window, then I'll
1185 // use the maximum cell position as the seed instead of what
1186 // the SW clustering gives. I restrict this to the outer edge
1187 // of the EC to avoid any chance of changing the clustering results
1188 // in the bulk of the calorimeter.
1189 // Also do this if the maximum cell is on the edge of the inner endcap ---
1190 // we can get the same effect.
1191 if ((elt->is_lar_em_endcap_inner() &&
1192 std::abs(elt->eta_raw()) - elt->deta() <
1193 elt->descriptor()->calo_eta_min()) ||
1194 (elt->is_lar_em_endcap_outer() &&
1195 std::abs(elt->eta_raw()) + elt->deta() >
1196 elt->descriptor()->calo_eta_max()))
1197 {
1198 // Max cell is at the edge. Is it outside the window?
1199 if (std::abs (eta - elt->eta()) > helper.deta(2)/2) {
1200 // Yes --- change the seed.
1201 eta = elt->eta();
1202 }
1203 }
1204
1205 // stay in the calo frame and do not cook for cluster on edge
1206 // (inputs are now 3x5 so there should not be problems anymore)
1207 eta = cluster->eta0();
1208 phi = CaloPhiRange::fix(cluster->phi0());
1209
1210}
1211
1212
1217StatusCode
1219 (const std::string& name)
1220{
1221 return this->setProperty (StringProperty ("cells_name", name));
1222}
1223
1224
1236 const int nphi,
1237 const double detas2,
1238 const double dphis2) const
1239{
1241
1242 // set up the sampling windows:
1243 w[0].first = detas2*neta;
1244 w[0].second = dphis2*4;
1245
1246 if (nphi >= 7)
1247 w[0].second *= 2;
1248 else
1249 w[0].second *= 1.5;
1250
1251 w[1].first = w[0].first;
1252 w[1].second = w[0].second;
1253
1254 w[2].first = detas2*neta;
1255 w[2].second = dphis2*nphi;
1256
1257 w[3].first = (2*detas2)*(0.5 + (neta/2.));
1258 w[3].second = w[2].second;
1259
1260 return w;
1261}
#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
SG::ReadHandleKey< CaloCellContainer > m_cellsName
The StoreGate key for the container of our input cells.
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.
int m_neta
cluster size. These are properties.
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