ATLAS Offline Software
Loading...
Searching...
No Matches
CaloCalibClusterDecoratorToolDM.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef CALOCALIBHITREC_CALOCALIBCLUSTERDECORATORTOOLDM_H
6#define CALOCALIBHITREC_CALOCALIBCLUSTERDECORATORTOOLDM_H
7
8class CaloCell_ID;
10
11#include "GaudiKernel/ToolHandle.h"
12
18#include "CLHEP/Units/SystemOfUnits.h"
19
20#include <array>
21#include <cmath>
22#include <atomic>
23#include <string>
24#include <vector>
25
37 : public AthAlgTool,
39{
40public:
46
47 CaloCalibClusterDecoratorToolDM(const std::string& type,
48 const std::string& name,
49 const IInterface* parent);
50
52 virtual StatusCode execute(const EventContext& ctx,
53 xAOD::CaloClusterContainer* theClusColl) const override;
54 virtual StatusCode initialize() override;
55
56private:
58
61 this,
62 "CaloClusterWriteDecorHandleKey_NLeadingTruthParticlesDM",
63 "CaloTopoClustersNew.calclus_NLeadingTruthParticleBarcodeEnergyPairs_DM",
64 "Dead-material truth-particle barcode/energy decoration"};
65
66 Gaudi::Property<unsigned int> m_numTruthParticles{
67 this,
68 "NumTruthParticles",
69 100,
70 "Number of truth particles per CaloCluster/PFO for which to store dead-material calibration-hit energy"};
71
73 this,
74 "CalibrationHitContainerNames",
75 {},
76 "Calibration-hit containers inside the calorimeter volume"};
77
79 this,
80 "DMCalibrationHitContainerNames",
81 {},
82 "Dead-material calibration-hit containers"};
83
84 const CaloCell_ID* m_calo_id{nullptr};
86
87 int m_n_phi_out{127};
88 int m_n_eta_out{127};
90 double m_out_eta_max{6.0};
91 double m_rmaxOut[3]{1.0, 0.5, 0.3};
92 std::array<std::vector<std::vector<CalibHitIPhiIEtaRange> >, 3> m_i_phi_eta;
93
94 Gaudi::Property<int> m_MatchDmType{
95 this,
96 "MatchDmType",
98 "Dead-material matching type: 0=off, 1=loose, 2=medium, 3=tight"};
99
100 Gaudi::Property<bool> m_useParticleID{
101 this,
102 "UseParticleID",
103 true,
104 "Use calibration-hit particle uniqueID for dead-material truth attribution"};
105
106 Gaudi::Property<float> m_energyMin{
107 this,
108 "EnergyMin",
109 200.0 * CLHEP::MeV,
110 "Minimum cluster energy used in dead-material sharing"};
111
112 Gaudi::Property<float> m_energyMinCalib{
113 this,
114 "EnergyMinCalib",
115 20.0 * CLHEP::MeV,
116 "Minimum in-cluster calibration energy used in dead-material sharing"};
117
118 Gaudi::Property<float> m_apars_alpha{
119 this,
120 "AparsAlpha",
121 0.5,
122 "Power-law exponent for dead-material sharing effective energy"};
123
124 Gaudi::Property<float> m_apars_r0{
125 this,
126 "AparsR0",
127 0.2,
128 "Distance scale for dead-material sharing effective energy"};
129
130 template <class AddDeadMaterialEnergy>
132 const std::vector<const CaloCalibrationHitContainer*>& v_dmcchc,
133 const xAOD::CaloClusterContainer& theClusColl,
134 const ClusInfo_t& clusInfoVec,
135 const ClusList& clusList,
136 bool useParticleID,
137 AddDeadMaterialEnergy&& addDeadMaterialEnergy) const
138 {
139 for (const CaloCalibrationHitContainer* dmcchc : v_dmcchc) {
140 for (const CaloCalibrationHit* hit : *dmcchc) {
141 const Identifier myId = hit->cellID();
142 if (!m_calo_id->is_lar_dm(myId) && !m_calo_id->is_tile_dm(myId)) {
143 continue;
144 }
145
146 const CaloDmDescrElement* myCDDE = m_caloDmDescrManager->get_element(myId);
147 if (!myCDDE) {
148 continue;
149 }
150
151 int uniqueID = HepMC::UNDEFINED_ID;
152 if (useParticleID) {
153 uniqueID = HepMC::uniqueID(hit);
154 }
155
156 const int jeO = static_cast<int>(std::floor(m_n_eta_out * (myCDDE->eta() / m_out_eta_max)));
157 if (jeO < -m_n_eta_out || jeO >= m_n_eta_out) {
158 continue;
159 }
160
161 int jpO = static_cast<int>(std::floor(m_n_phi_out * (myCDDE->phi() / m_out_phi_max)));
162 if (jpO < -m_n_phi_out) {
163 jpO += 2 * m_n_phi_out;
164 }
165 if (jpO >= m_n_phi_out) {
166 jpO -= 2 * m_n_phi_out;
167 }
168
169 const int nDmArea = m_caloDmDescrManager->get_dm_area(myId);
170 const CaloDmRegion* dmRegion = m_caloDmDescrManager->get_dm_region(myId);
171 if (!dmRegion) {
172 continue;
173 }
174
175 std::vector<int> hitClusIndex;
176 std::vector<double> hitClusEffEnergy;
177 hitClusIndex.reserve(theClusColl.size());
178 hitClusEffEnergy.reserve(theClusColl.size());
179 double hitClusNorm = 0.0;
180
181 const std::vector<int>& matchingClusters =
182 clusList[(jpO + m_n_phi_out) * (2 * m_n_eta_out + 1) + jeO + m_n_eta_out];
183
184 for (int iClus : matchingClusters) {
185 const xAOD::CaloCluster* theCluster = theClusColl.at(iClus);
186 const auto& clusInfo = clusInfoVec[iClus];
187 auto pos = clusInfo.engCalibParticle.find(uniqueID);
188 if (pos == clusInfo.engCalibParticle.end()) {
189 continue;
190 }
191
192 const double engClusTruthUniqueIDCalib = pos->second.engTot;
193 if (engClusTruthUniqueIDCalib <= m_energyMinCalib || theCluster->e() <= m_energyMin) {
194 continue;
195 }
196
197 double sum_smp_energy = 0.0;
198 for (unsigned int i_smp = 0; i_smp < dmRegion->m_CaloSampleNeighbours.size(); ++i_smp) {
199 const CaloSampling::CaloSample nsmp =
200 static_cast<CaloSampling::CaloSample>(dmRegion->m_CaloSampleNeighbours[i_smp]);
201 if ((dmRegion->m_CaloSampleEtaMin[i_smp] - 0.5) <= theCluster->eta() &&
202 theCluster->eta() <= (dmRegion->m_CaloSampleEtaMax[i_smp] + 0.5)) {
203 sum_smp_energy += pos->second.engSmp[nsmp];
204 }
205 }
206 if (sum_smp_energy <= 0.0) {
207 continue;
208 }
209
210 double phi_diff = myCDDE->phi() - theCluster->phi();
211 if (phi_diff <= -M_PI) {
212 phi_diff += 2. * M_PI;
213 }
214 else if (phi_diff > M_PI) {
215 phi_diff -= 2. * M_PI;
216 }
217 const double eta_diff = myCDDE->eta() - theCluster->eta();
218 const float distance = std::sqrt(eta_diff * eta_diff + phi_diff * phi_diff);
219 const double effEner = std::pow(sum_smp_energy, m_apars_alpha.value()) * std::exp(-distance / m_apars_r0.value());
220
221 hitClusIndex.push_back(iClus);
222 hitClusEffEnergy.push_back(effEner);
223 hitClusNorm += effEner;
224 }
225
226 if (hitClusNorm <= 0.0) {
227 continue;
228 }
229
230 const double inv_hitClusNorm = 1.0 / hitClusNorm;
231 for (std::size_t i = 0; i < hitClusIndex.size(); ++i) {
232 const int iClus = hitClusIndex[i];
233 const double dm_weight = hitClusEffEnergy[i] * inv_hitClusNorm;
234 addDeadMaterialEnergy(iClus, uniqueID, nDmArea, hit->energyTotal() * dm_weight);
235 }
236 }
237 }
238 }
239
240 mutable std::atomic<bool> m_foundAllContainers{false};
241};
242
243#endif // CALOCALIBHITREC_CALOCALIBCLUSTERDECORATORTOOLDM_H
#define M_PI
Base class for cluster processing tools called from CaloClusterMaker.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_DMCalibrationHitContainerNames
SG::WriteDecorHandleKey< xAOD::CaloClusterContainer > m_caloClusterWriteDecorHandleKeyNLeadingTruthParticlesDM
CaloCalibClusterMomentsMaker2::ClusList ClusList
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_CalibrationHitContainerNames
Gaudi::Property< unsigned int > m_numTruthParticles
CaloCalibClusterMomentsMaker2::CalibHitIPhiIEtaRange CalibHitIPhiIEtaRange
std::array< std::vector< std::vector< CalibHitIPhiIEtaRange > >, 3 > m_i_phi_eta
CaloCalibClusterMomentsMaker2::CellInfoSet_t CellInfoSet_t
CaloCalibClusterDecoratorToolDM(const std::string &type, const std::string &name, const IInterface *parent)
CaloCalibClusterMomentsMaker2::ClusInfo_t ClusInfo_t
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override
Execute on an entire collection of clusters.
void accumulateDeadMaterialEnergy(const std::vector< const CaloCalibrationHitContainer * > &v_dmcchc, const xAOD::CaloClusterContainer &theClusColl, const ClusInfo_t &clusInfoVec, const ClusList &clusList, bool useParticleID, AddDeadMaterialEnergy &&addDeadMaterialEnergy) const
std::map< Identifier, MyCellInfo > CellInfoSet_t
std::vector< std::vector< int > > ClusList
Class to store calorimeter calibration hit.
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *collection) const =0
Execute on an entire collection of clusters.
std::vector< short > m_CaloSampleNeighbours
std::vector< float > m_CaloSampleEtaMin
std::vector< float > m_CaloSampleEtaMax
const T * at(size_type n) const
Access an element, as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
int uniqueID(const T &p)
constexpr int UNDEFINED_ID
HandleKeyArray< ReadHandle< T >, ReadHandleKey< T >, Gaudi::DataHandle::Reader > ReadHandleKeyArray
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.