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