ATLAS Offline Software
Loading...
Searching...
No Matches
TFCSLateralShapeParametrizationHitChain.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
7
9#include "TMath.h"
10#include <TClass.h>
11#ifdef USE_GPU
23#include "HepPDT/ParticleData.hh"
24// #include "HepPDT/ParticleDataTable.hh"
25#endif
26
27//=============================================
28//======= TFCSLateralShapeParametrizationHitChain =========
29//=============================================
30
31#ifdef USE_GPU
33 TFCSLateralShapeParametrizationHitChain(const char *name, const char *title,
34 ICaloGeometry *geo)
36 m_number_of_hits_simul(nullptr) {}
37
38// override the function for FCS-GPU
42 m_number_of_hits_simul->set_geometry(geo);
43 m_geo = geo;
44}
45
46#else
51#endif
52
56 : TFCSLateralShapeParametrization(TString("hit_chain_") + hitsim->GetName(),
57 TString("hit chain for ") +
58 hitsim->GetTitle()),
59 m_number_of_hits_simul(nullptr) {
61
62 m_chain.push_back(hitsim);
63}
64
67 return m_chain.size() + 1;
68 else
69 return m_chain.size();
70}
71
73 const Chain_t::value_type &value) {
74 if (m_ninit == size()) {
75 chain().push_back(value);
76 } else {
77 const auto it = chain().begin() + m_ninit;
78 chain().insert(it, value);
79 }
80 ++m_ninit;
81}
82
86 if (ind == 0)
88 return m_chain[ind - 1];
89 } else {
90 return m_chain[ind];
91 }
92}
93
97 if (ind == 0)
99 return m_chain[ind - 1];
100 } else {
101 return m_chain[ind];
102 }
103}
104
106 unsigned int ind, TFCSParametrizationBase *param) {
107 TFCSLateralShapeParametrizationHitBase *param_typed = nullptr;
108 if (param != nullptr) {
109 if (!param->InheritsFrom(TFCSLateralShapeParametrizationHitBase::Class())) {
110 ATH_MSG_ERROR("Wrong class type " << param->IsA()->GetName());
111 return;
112 }
113 param_typed = static_cast<TFCSLateralShapeParametrizationHitBase *>(param);
114 }
116 if (ind == 0)
117 m_number_of_hits_simul = param_typed;
118 else
119 m_chain.at(ind - 1) = param_typed;
120 } else {
121 m_chain.at(ind) = param_typed;
122 }
123}
124
126 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
127 const TFCSExtrapolationState *extrapol) const {
128 // TODO: should we still do it?
130 int n =
131 m_number_of_hits_simul->get_number_of_hits(simulstate, truth, extrapol);
132 if (n < 1)
133 n = 1;
134 return n;
135 }
137 int n = hitsim->get_number_of_hits(simulstate, truth, extrapol);
138 if (n > 0)
139 return n;
140 }
141 return 1;
142}
143
146 float weight = hitsim->getMinWeight();
147 if (weight > 0.)
148 return weight;
149 }
150 return -1.;
151}
152
155 float weight = hitsim->getMaxWeight();
156 if (weight > 0.)
157 return weight;
158 }
159 return -1.;
160}
161
163 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
164 const TFCSExtrapolationState *extrapol) const {
165 const int nhits = get_number_of_hits(simulstate, truth, extrapol);
166
167 // Store nhits in the simulation state as the get function may only be
168 // called once per event
169 simulstate.setAuxInfo<int>("FCSHitChainNHits"_FCShash, nhits);
170
171 const int sample = calosample();
172 if (sample < 0)
173 return 0;
174 if (nhits <= 0)
175 return simulstate.E(sample);
176 const float maxWeight =
177 getMaxWeight(); // maxWeight = -1 if shapeWeight class is not in m_chain
178
179 if (maxWeight > 0)
180 return simulstate.E(sample) /
181 (maxWeight *
182 nhits); // maxWeight is used only if shapeWeight class is in m_chain
183 else
184 return simulstate.E(sample) /
185 nhits; // Otherwise, old definition of E_hit is used
186}
187
189 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
190 const TFCSExtrapolationState *extrapol) const {
192 double sigma2 = m_number_of_hits_simul->get_sigma2_fluctuation(
193 simulstate, truth, extrapol);
194 if (sigma2 > 0)
195 return sigma2;
196 }
198 double sigma2 = hitsim->get_sigma2_fluctuation(simulstate, truth, extrapol);
199 if (sigma2 > 0)
200 return sigma2;
201 }
202 // Limit to factor s_max_sigma2_fluctuation fluctuations
204}
205
207 MSG::Level level) const {
209 reset->setLevel(level);
210}
211
214 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
215 const TFCSExtrapolationState *extrapol) const {
216 hit.reset_center();
217 if (get_nr_of_init() > 0) {
218 ATH_MSG_DEBUG("E(" << calosample() << ")=" << simulstate.E(calosample())
219 << " before init");
220
221 auto initloopend = m_chain.begin() + get_nr_of_init();
222 for (auto hititr = m_chain.begin(); hititr != initloopend; ++hititr) {
224
225 FCSReturnCode status =
226 hitsim->simulate_hit(hit, simulstate, truth, extrapol);
227
228 if (status != FCSSuccess) {
229 ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): "
230 "simulate_hit init call failed");
231 return FCSFatal;
232 }
233 }
234 }
235 return FCSSuccess;
236}
237
239 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
240 const TFCSExtrapolationState *extrapol) const {
241 MSG::Level old_level = level();
242 const bool debug = msgLvl(MSG::DEBUG);
243 const bool verbose = msgLvl(MSG::VERBOSE);
244
245 // Execute the first get_nr_of_init() simulate calls only once. Used for
246 // example to initialize the center position
248 if (init_hit(hit, simulstate, truth, extrapol) != FCSSuccess) {
249 ATH_MSG_ERROR("init_hit() failed");
250 return FCSFatal;
251 }
252
253 int cs = calosample();
254 // Initialize hit energy only now, as init loop above might change the layer
255 // energy
256 const float Elayer = simulstate.E(cs);
257 if (Elayer == 0) {
258 ATH_MSG_VERBOSE("Elayer=0, nothing to do");
259 return FCSSuccess;
260 }
261 const float Ehit = get_E_hit(simulstate, truth, extrapol);
262 if (Ehit * Elayer <= 0) {
263 ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): Ehit "
264 "and Elayer have different sign! Ehit="
265 << Ehit << " Elayer=" << Elayer);
266 return FCSFatal;
267 }
268
269 // Call get_number_of_hits() only once inside get_E_hit(...),
270 // as it could contain a random number
271 //TODO: should read simulate value!
272 int nhit_signed = TMath::Nint(Elayer / Ehit);
273 if (nhit_signed < 1)
274 nhit_signed = 1;
275 unsigned int nhit = (unsigned int)nhit_signed;
276
277 float sumEhit = 0;
278
279 if (debug) {
280 PropagateMSGLevel(old_level);
281 ATH_MSG_DEBUG("E(" << cs << ")=" << simulstate.E(cs) << " #hits~" << nhit);
282 }
283
284 //
285 // simulate the hits in GPU
286 //
287#ifdef USE_GPU
288 int ichn = 0;
289 bool our_chainA = false;
290 if (cs > 0 && cs < 8 && cs != 4)
291 our_chainA = true;
292 if (nhit > MIN_GPU_HITS && our_chainA && simulstate.get_geold() != nullptr) {
294 "running FastCaloSim in GPU, nhits = " << nhit << " ; Ehit = " << Ehit);
295 GeoLoadGpu *gld = (GeoLoadGpu *)simulstate.get_geold();
296
297 Chain0_Args args;
298 args.debug = debug;
299 args.cs = cs;
300 args.extrapol_eta_ent = extrapol->eta(cs, SUBPOS_ENT);
301 args.extrapol_eta_ext = extrapol->eta(cs, SUBPOS_EXT);
302 args.extrapol_phi_ent = extrapol->phi(cs, SUBPOS_ENT);
303 args.extrapol_phi_ext = extrapol->phi(cs, SUBPOS_EXT);
304 args.extrapol_r_ent = extrapol->r(cs, SUBPOS_ENT);
305 args.extrapol_r_ext = extrapol->r(cs, SUBPOS_EXT);
306 args.extrapol_z_ent = extrapol->z(cs, SUBPOS_ENT);
307 args.extrapol_z_ext = extrapol->z(cs, SUBPOS_EXT);
308 args.pdgId = truth->pdgid();
309 args.charge = HepPDT::ParticleID(args.pdgId).charge();
310 args.nhits = nhit;
311 args.rand = 0;
312 args.geo = gld->get_geoPtr();
313 args.rd4h = simulstate.get_gpu_rand();
314 args.ncells = gld->get_ncells();
315 ichn = 0;
316 // reweight the cell energies for pion
317 bool reweight = false;
318 for (auto hitsim : m_chain) {
319 if (ichn == 0) {
320 args.extrapWeight =
321 ((TFCSCenterPositionCalculation *)hitsim)->getExtrapWeight();
322 }
323
324 if (ichn == 1) {
325
326 args.is_phi_symmetric = ((TFCSHistoLateralShapeParametrization *)hitsim)
327 ->is_phi_symmetric();
328 args.fh2d =
329 ((TFCSHistoLateralShapeParametrization *)hitsim)->LdFH()->hf2d_d();
330 args.fh2d_h = *(
331 ((TFCSHistoLateralShapeParametrization *)hitsim)->LdFH()->hf2d_h());
332 }
333 if (ichn == 2 && m_chain.size() == 4) {
334 args.fh1d =
335 ((TFCSHistoLateralShapeGausLogWeight *)hitsim)->LdFH()->hf1d_d();
336 args.fh1d_h =
337 *(((TFCSHistoLateralShapeGausLogWeight *)hitsim)->LdFH()->hf1d_h());
338 reweight = true;
339 }
340 if ((ichn == 2 && m_chain.size() == 3) ||
341 (ichn == 3 && m_chain.size() == 4)) {
342 // ATH_MSG_DEBUG("---NumberOfBins :" << ( (TFCSHitCellMappingWi
343 // ggle*)hitsim )->get_number_of_bins() );
344 args.fhs = ((TFCSHitCellMappingWiggle *)hitsim)->LdFH()->hf_d();
345 args.fhs_h = *(((TFCSHitCellMappingWiggle *)hitsim)->LdFH()->hf_h());
346 }
347
348 ichn++;
349 }
350 if (reweight)
351 CaloGpuGeneral::simulate_hits(Ehit, 1.2 * nhit, args, reweight);
352 else
353 CaloGpuGeneral::simulate_hits(Ehit, nhit, args, reweight);
354
355 for (unsigned int ii = 0; ii < args.ct; ++ii) {
356
357 const CaloDetDescrElement_Gpu *cellele =
358 gld->index2cell(args.hitcells_E_h[ii].cellid);
359 const CaloDetDescrElement *cell_h =
360 m_geo->getDDE(cs, cellele->eta(), cellele->phi());
361 sumEhit += args.hitcells_E_h[ii].energy;
362 if (reweight) {
363 if (std::abs(sumEhit) > std::abs(Elayer))
364 simulstate.deposit(cell_h, args.hitcells_E_h[ii].energy);
365 }
366 }
367 } else
368#endif
369 {
370
371 auto hitloopstart = m_chain.begin() + get_nr_of_init();
372 hit.idx() = 0;
373 int ifail = 0;
374 int itotalfail = 0;
375 int retry_warning = 1;
376 int retry = 0;
377 bool failed = false;
378 do {
379 hit.reset();
380 hit.E() = Ehit;
381 failed = false;
382 if (debug)
383 if (hit.idx() == 2)
384 if (!verbose) {
385 // Switch debug output back to INFO to avoid huge logs, but keep
386 // full log in verbose
387 PropagateMSGLevel(MSG::INFO);
388 }
389 for (auto hititr = hitloopstart; hititr != m_chain.end(); ++hititr) {
391
392 FCSReturnCode status =
393 hitsim->simulate_hit(hit, simulstate, truth, extrapol);
394
395 if (status == FCSSuccess)
396 continue;
397 if (status == FCSFatal) {
398 if (debug)
399 PropagateMSGLevel(old_level);
400 return FCSFatal;
401 }
402 failed = true;
403 ++ifail;
404 ++itotalfail;
405 retry = status - FCSRetry;
406 retry_warning = retry >> 1;
407 if (retry_warning < 1)
408 retry_warning = 1;
409 break;
410 }
411 if (!failed) {
412 ifail = 0;
413 sumEhit += hit.E();
414 ++hit.idx();
415
416 // TODO: Different signedness:
417 if (((hit.idx() == 20 * nhit) || (hit.idx() == 100 * nhit)) && hit.idx() >= 100) {
419 "TFCSLateralShapeParametrizationHitChain::simulate(): Iterated "
420 << hit.idx() << " times, expected " << nhit << " times. Deposited E("
421 << cs << ")=" << sumEhit << " expected E=" << Elayer);
422 }
423 if (hit.idx() >= 1000 * nhit && hit.idx() >= 1000) {
424 ATH_MSG_DEBUG("TFCSLateralShapeParametrizationHitChain::simulate():"
425 " Aborting hit chain, iterated "
426 << hit.idx() << " times, expected " << nhit
427 << " times. Deposited E(" << cs << ")=" << sumEhit
428 << " expected E=" << Elayer << ", caused by:");
429 if (debug) Print();
430 break;
431 }
432 } else {
433 if (ifail >= retry) {
434 ATH_MSG_ERROR("TFCSLateralShapeParametrizationHitChain::simulate(): "
435 "simulate_hit call failed after "
436 << ifail << "/" << retry
437 << "retries, total fails=" << itotalfail);
438 if (debug)
439 PropagateMSGLevel(old_level);
440 return FCSFatal;
441 }
442 if (ifail >= retry_warning) {
443 ATH_MSG_WARNING("TFCSLateralShapeParametrizationHitChain::simulate():"
444 " retry simulate_hit calls "
445 << ifail << "/" << retry
446 << ", total fails=" << itotalfail);
447 }
448 }
449 } while (!check_all_hits_simulated(hit, simulstate, truth, extrapol, !failed));
450 }
451
452 if (debug)
453 PropagateMSGLevel(old_level);
454 return FCSSuccess;
455}
456
459 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
460 const TFCSExtrapolationState *extrapol, bool success) const {
461
462 (void)truth; // unused parameter
463 (void)extrapol; // unused parameter
464
465 if (!success) {
466 // The hit simulation failed => Nothing changed => Still not done
467 return false;
468 }
469
470 float sumEhit = 0;
471 if (simulstate.hasAuxInfo("FCSHitChainEnergySum"_FCShash) && hit.idx() > 1) {
472 sumEhit = simulstate.getAuxInfo<float>("FCSHitChainEnergySum"_FCShash);
473 }
474
475 sumEhit += hit.E();
476
477 simulstate.setAuxInfo<float>("FCSHitChainEnergySum"_FCShash, sumEhit);
478
479 float Elayer = simulstate.E(calosample());
480 return (std::abs(sumEhit) >= std::abs(Elayer));
481}
482
485 TString opt(option);
486 bool shortprint = opt.Index("short") >= 0;
487 bool longprint = msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
488 TString optprint = opt;
489 optprint.ReplaceAll("short", "");
490
492 if (longprint)
493 ATH_MSG_INFO(optprint << "#:Number of hits simulation:");
494 m_number_of_hits_simul->Print(opt + "#:");
495 }
496 if (longprint && get_nr_of_init() > 0)
497 ATH_MSG_INFO(optprint << "> Simulation init chain:");
498 auto hitloopstart = m_chain.begin() + get_nr_of_init();
499 for (auto hititr = m_chain.begin(); hititr != hitloopstart; ++hititr) {
501 hitsim->Print(opt + "> ");
502 }
503 if (longprint)
504 ATH_MSG_INFO(optprint << "- Simulation chain:");
505 char count = 'A';
506 for (auto hititr = hitloopstart; hititr != m_chain.end(); ++hititr) {
508 hitsim->Print(opt + count + " ");
509 count++;
510 }
511}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define MIN_GPU_HITS
const bool debug
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
CUDA_HOSTDEV float phi() const
cell phi
CUDA_HOSTDEV float eta() const
cell eta
This class groups all DetDescr information related to a CaloCell.
unsigned long get_ncells() const
Definition GeoLoadGpu.h:46
GeoGpu * get_geoPtr() const
Definition GeoLoadGpu.h:44
const CaloDetDescrElement_Gpu * index2cell(unsigned long index)
Definition GeoLoadGpu.h:34
bool msgLvl(const MSG::Level lvl) const
Check whether the logging system is active at the provided verbosity level.
Definition MLogging.h:222
MSG::Level level() const
Retrieve output level.
Definition MLogging.h:201
virtual FCSReturnCode simulate_hit(Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol)
simulated one hit position with some energy.
virtual float get_sigma2_fluctuation(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
Give the effective size sigma^2 of the fluctuations that should be generated.
virtual const TFCSParametrizationBase * operator[](unsigned int ind) const override
Some derived classes have daughter instances of TFCSParametrizationBase objects The size() and operat...
TFCSLateralShapeParametrizationHitChain(const char *name=nullptr, const char *title=nullptr)
virtual FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
virtual unsigned int size() const override
Some derived classes have daughter instances of TFCSParametrizationBase objects The size() and operat...
virtual bool check_all_hits_simulated(TFCSLateralShapeParametrizationHitBase::Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol, bool success) const
void Print(Option_t *option="") const override
Do not persistify!
virtual float getMinWeight() const
Get minimum and maximum value of weight for hit energy reweighting.
TFCSLateralShapeParametrizationHitBase * m_number_of_hits_simul
virtual void set_daughter(unsigned int ind, TFCSParametrizationBase *param) override
Some derived classes have daughter instances of TFCSParametrizationBase objects The set_daughter meth...
virtual FCSReturnCode init_hit(TFCSLateralShapeParametrizationHitBase::Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
virtual float get_E_hit(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
Get hit energy from layer energy and number of hits.
virtual int get_number_of_hits(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
Call get_number_of_hits() only once, as it could contain a random number.
void Print(Option_t *option="") const override
TFCSLateralShapeParametrization(const char *name=nullptr, const char *title=nullptr)
virtual void set_pdgid_Ekin_eta_Ekin_bin_calosample(const TFCSLateralShapeParametrization &ref)
virtual void set_geometry(ICaloGeometry *geo)
Method to set the geometry access pointer.
TFCSParametrizationBase(const char *name=nullptr, const char *title=nullptr)
bool hasAuxInfo(std::uint32_t index) const
const T getAuxInfo(std::uint32_t index) const
void deposit(const CaloDetDescrElement *cellele, float E)
void setAuxInfo(std::uint32_t index, const T &val)
int pdgid() const
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
bool verbose
Definition hcg.cxx:73
void simulate_hits(float, int, Chain0_Args &, bool)