ATLAS Offline Software
Loading...
Searching...
No Matches
TFCSHistoLateralShapeParametrization.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "CLHEP/Random/RandFlat.h"
6#include "CLHEP/Random/RandPoisson.h"
7
12
13#include "TFile.h"
14#include "TMath.h"
15#include "TH2.h"
16
17#include "HepPDT/ParticleData.hh"
18#include "HepPDT/ParticleDataTable.hh"
19
20#include <cmath>
21
22//=============================================
23//======= TFCSHistoLateralShapeParametrization =========
24//=============================================
25
32
34#ifdef USE_GPU
35 delete m_LdFH;
36#endif
37}
38
41 if (!m_hist.get_HistoContents().empty()) {
42 int first_fix_bin = -1;
43 for (int i = (int)(m_hist.get_HistoContents().size() - 1); i >= 0; --i) {
44 if (std::isnan(m_hist.get_HistoContents()[i])) {
45 ATH_MSG_DEBUG("nan in histo content for "
46 << GetTitle() << ", bin[" << i
47 << "]=" << m_hist.get_HistoContents()[i] << " -> 1");
48 m_hist.get_HistoContents()[i] = 1;
49 first_fix_bin = i;
50 }
51 }
52 if (first_fix_bin < 0)
53 return;
54
55 if (first_fix_bin == 0) {
56 ATH_MSG_WARNING("nan in histo content for "
57 << GetTitle()
58 << " for all bins. Fixed to probability 1 causing hits "
59 "to be deposited in the shower center");
60 } else {
61 int last_fix_bin = -1;
62 for (size_t i = 0; i < m_hist.get_HistoContents().size(); ++i) {
63 if (std::isnan(m_hist.get_HistoContents()[i])) {
64 ATH_MSG_DEBUG("nan in histo content for "
65 << GetTitle() << ", bin[" << i
66 << "]=" << m_hist.get_HistoContents()[i] << " -> 0");
67 m_hist.get_HistoContents()[i] = 0;
68 last_fix_bin = i;
69 }
70 }
71 ATH_MSG_WARNING("nan in histo content for "
72 << GetTitle() << ". Fixed up to bin " << last_fix_bin
73 << " with probability 0 and beyond bin " << first_fix_bin
74 << " with probability 1.");
75 }
76 }
77}
78
80 TFCSSimulationState & /*simulstate*/, const TFCSTruthState * /*truth*/,
81 const TFCSExtrapolationState * /*extrapol*/) const {
82 // Limit to factor 1000 fluctuations
83 if (m_nhits < 0.001)
84 return 1000;
85 return 1.0 / m_nhits;
86}
87
89 TFCSSimulationState &simulstate, const TFCSTruthState * /*truth*/,
90 const TFCSExtrapolationState * /*extrapol*/) const {
91 if (!simulstate.randomEngine()) {
92 return -1;
93 }
94
95 return CLHEP::RandPoisson::shoot(simulstate.randomEngine(), m_nhits);
96}
97
101
103 Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth,
104 const TFCSExtrapolationState * /*extrapol*/) {
105 if (!simulstate.randomEngine()) {
106 return FCSFatal;
107 }
108
109 const int pdgId = truth->pdgid();
110 const double charge = HepPDT::ParticleID(pdgId).charge();
111
112 const int cs = calosample();
113 const double center_eta = hit.center_eta();
114 const double center_phi = hit.center_phi();
115 const double center_r = hit.center_r();
116 const double center_z = hit.center_z();
117
118 if (TMath::IsNaN(center_r) or TMath::IsNaN(center_z) or
119 TMath::IsNaN(center_eta) or
120 TMath::IsNaN(center_phi)) { // Check if extrapolation fails
121 return FCSFatal;
122 }
123
124 float alpha, r, rnd1, rnd2;
125 rnd1 = CLHEP::RandFlat::shoot(simulstate.randomEngine());
126 rnd2 = CLHEP::RandFlat::shoot(simulstate.randomEngine());
127 if (is_phi_symmetric()) {
128 if (rnd2 >= 0.5) { // Fill negative phi half of shape
129 rnd2 -= 0.5;
130 rnd2 *= 2;
131 m_hist.rnd_to_fct(alpha, r, rnd1, rnd2);
132 alpha = -alpha;
133 } else { // Fill positive phi half of shape
134 rnd2 *= 2;
135 m_hist.rnd_to_fct(alpha, r, rnd1, rnd2);
136 }
137 } else {
138 m_hist.rnd_to_fct(alpha, r, rnd1, rnd2);
139 }
140 if (TMath::IsNaN(alpha) || TMath::IsNaN(r)) {
141 ATH_MSG_ERROR(" Histogram: "
142 << m_hist.get_HistoBordersx().size() - 1 << "*"
143 << m_hist.get_HistoBordersy().size() - 1
144 << " bins, #hits=" << m_nhits << " alpha=" << alpha
145 << " r=" << r << " rnd1=" << rnd1 << " rnd2=" << rnd2);
146 alpha = 0;
147 r = 0.001;
148
149 ATH_MSG_ERROR(" This error could probably be retried");
150 return FCSFatal;
151 }
152
153 r *= m_r_scale;
154 r += m_r_offset;
155 if (r < 0)
156 r = 0;
157
158 float delta_eta_mm = r * cos(alpha);
159 float delta_phi_mm = r * sin(alpha);
160
161 // Particles with negative eta are expected to have the same shape as those
162 // with positive eta after transformation: delta_eta --> -delta_eta
163 if (center_eta < 0.)
164 delta_eta_mm = -delta_eta_mm;
165 // We derive the shower shapes for electrons and positively charged hadrons.
166 // Particle with the opposite charge are expected to have the same shower shape
167 // after the transformation: delta_phi --> -delta_phi
168 if ((charge < 0. && pdgId!=11) || pdgId==-11)
169 delta_phi_mm = -delta_phi_mm;
170
171 const float dist000 = TMath::Sqrt(center_r * center_r + center_z * center_z);
172 const float eta_jakobi = TMath::Abs(2.0 * TMath::Exp(-center_eta) /
173 (1.0 + TMath::Exp(-2 * center_eta)));
174
175 const float delta_eta = delta_eta_mm / eta_jakobi / dist000;
176 const float delta_phi = delta_phi_mm / center_r;
177
178 hit.setEtaPhiZE(center_eta + delta_eta, center_phi + delta_phi, center_z,
179 hit.E());
180
181 ATH_MSG_DEBUG("HIT: E=" << hit.E() << " cs=" << cs << " eta=" << hit.eta()
182 << " phi=" << hit.phi() << " z=" << hit.z()
183 << " r=" << r << " alpha=" << alpha);
184
185 return FCSSuccess;
186}
187
189 if (!hist)
190 return false;
191 m_hist.Initialize(hist);
192 if (m_hist.get_HistoContents().empty())
193 return false;
194
195 set_number_of_hits(hist->Integral());
196
197 return true;
198}
199
201 const char *histname) {
202 // input file with histogram to fit
203 std::unique_ptr<TFile> inputfile(TFile::Open(filepath, "READ"));
204 if (inputfile == nullptr)
205 return false;
206
207 // histogram with hit pattern
208 TH2 *inputShape = (TH2 *)inputfile->Get(histname);
209 if (inputShape == nullptr)
210 return false;
211
212 bool OK = Initialize(inputShape);
213
214 inputfile->Close();
215
216 return OK;
217}
218
220 TString opt(option);
221 bool shortprint = opt.Index("short") >= 0;
222 bool longprint = msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
223 TString optprint = opt;
224 optprint.ReplaceAll("short", "");
226
227 if (longprint) {
228 if (is_phi_symmetric()) {
229 ATH_MSG_INFO(optprint
230 << " Histo: " << m_hist.get_HistoBordersx().size() - 1
231 << "*" << m_hist.get_HistoBordersy().size() - 1
232 << " bins, #hits=" << m_nhits << ", r scale=" << m_r_scale
233 << ", r offset=" << m_r_offset << "mm (phi symmetric)");
234 } else {
235 ATH_MSG_INFO(optprint
236 << " Histo: " << m_hist.get_HistoBordersx().size() - 1
237 << "*" << m_hist.get_HistoBordersy().size() - 1
238 << " bins, #hits=" << m_nhits << ", r scale=" << m_r_scale
239 << ", r offset=" << m_r_offset << "mm (not phi symmetric)");
240 }
241 }
242}
243
244#ifdef USE_GPU
245void TFCSHistoLateralShapeParametrization::LoadHistFuncs() {
246
247 if (m_LdFH)
248 return;
249
250 m_LdFH = new LoadGpuFuncHist();
251 FH2D fh = {0, 0, 0, 0, 0};
252
253 fh.nbinsx = m_hist.get_HistoBordersx().size() - 1;
254 fh.nbinsy = m_hist.get_HistoBordersy().size() - 1;
255
256 fh.h_bordersx = &(m_hist.get_HistoBordersx()[0]);
257 fh.h_bordersy = &(m_hist.get_HistoBordersy()[0]);
258
259 fh.h_contents = &(m_hist.get_HistoContents()[0]);
260
261 m_LdFH->set_hf2d(&fh);
262 m_LdFH->LD2D();
263}
264#endif
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
bool msgLvl(const MSG::Level lvl) const
Check whether the logging system is active at the provided verbosity level.
Definition MLogging.h:222
virtual void set_geometry(ICaloGeometry *geo) override
will actually not store the geometry information, but rather used to check the validity of the 2D sha...
virtual int get_number_of_hits(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
default for this class is to simulate get_number_of_expected_hits() hits
virtual FCSReturnCode simulate_hit(Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) override
simulated one hit position with weight that should be put into simulstate sometime later all hit weig...
TFCS2DFunctionHistogram m_hist
Histogram to be used for the shape simulation.
TFCSHistoLateralShapeParametrization(const char *name=nullptr, const char *title=nullptr)
void set_number_of_hits(float nhits)
set the integral of the histogram to the desired number of hits
virtual double get_sigma2_fluctuation(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
default for this class is to simulate get_number_of_expected_hits() hits, which gives fluctuations si...
void setEtaPhiZE(float eta, float phi, float z, float E)
TFCSLateralShapeParametrizationHitBase(const char *name=nullptr, const char *title=nullptr)
void Print(Option_t *option="") const override
virtual void set_geometry(ICaloGeometry *geo)
Method to set the geometry access pointer.
virtual unsigned int size() const
Some derived classes have daughter instances of TFCSParametrizationBase objects The size() and operat...
CLHEP::HepRandomEngine * randomEngine()
int pdgid() const
int r
Definition globals.cxx:22
float * h_contents
Definition FH_structs.h:34
float * h_bordersy
Definition FH_structs.h:33
int nbinsx
Definition FH_structs.h:30
float * h_bordersx
Definition FH_structs.h:32
int nbinsy
Definition FH_structs.h:31