ATLAS Offline Software
Loading...
Searching...
No Matches
TFCSLateralShapeParametrizationFluctChain.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include "CLHEP/Random/RandGaussZiggurat.h"
9
10#include "TMath.h"
11
12//=============================================
13//======= TFCSLateralShapeParametrizationFluctChain =========
14//=============================================
15
20
25
27 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
28 const TFCSExtrapolationState *extrapol) const {
29 const float sigma2 = get_sigma2_fluctuation(simulstate, truth, extrapol);
30 const int sample = calosample();
31 if (sigma2 <= 0 || sample < 0)
32 return -1.;
33 const float maxWeight = getMaxWeight();
34
35 if (maxWeight > 0)
36 return simulstate.E(sample) * sigma2 / maxWeight;
37 else
38 return simulstate.E(sample) * sigma2;
39}
40
42 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
43 const TFCSExtrapolationState *extrapol) const {
44 MSG::Level old_level = level();
45 const bool debug = msgLvl(MSG::DEBUG);
46
47 // Execute the first get_nr_of_init() simulate calls only once. Used for
48 // example to initialize the center position
50 if (init_hit(hit, simulstate, truth, extrapol) != FCSSuccess) {
51 ATH_MSG_ERROR("init_hit() failed");
52 return FCSFatal;
53 }
54
55 // Initialize hit energy only now, as init loop above might change the layer
56 // energy
57 const float Elayer = simulstate.E(calosample());
58 if (Elayer == 0) {
59 ATH_MSG_VERBOSE("Elayer=0, nothing to do");
60 return FCSSuccess;
61 }
62
63 // Call get_sigma2_fluctuation only once, as it could contain a random number
64 float sigma2 = get_sigma2_fluctuation(simulstate, truth, extrapol);
65 if (sigma2 >= s_max_sigma2_fluctuation) {
66 ATH_MSG_ERROR("TFCSLateralShapeParametrizationFluctChain::simulate(): "
67 "fluctuation of hits could not be calculated");
68 return FCSFatal;
69 }
70
71 // Limit to relative precision of 10^-4=0.01%. ATLAS calorimeter is ~0.1% at
72 // best
73 if (sigma2 < 1e-8)
74 sigma2 = 1e-8;
75
76 // Make a good guess of the needed hit energy, assuming all hits would have
77 // the same energy
78 const float Eavghit = get_E_hit(simulstate, truth, extrapol);
79 const float absEavghit_tenth = std::abs(Eavghit / 10);
80 float sumEhit = 0;
81 float error2_sumEhit = 0;
82 float error2 = 2 * s_max_sigma2_fluctuation;
83
84 if (debug) {
85 PropagateMSGLevel(old_level);
86 ATH_MSG_DEBUG("E(" << calosample() << ")=" << Elayer
87 << " sigma2=" << sigma2);
88 }
89
90 auto hitloopstart = m_chain.begin() + get_nr_of_init();
91 int ihit = 0;
92 int ifail = 0;
93 int itotalfail = 0;
94 int retry_warning = 1;
95 int retry = 0;
96 do {
97 hit.reset();
98 // hit.E()=Eavghit;
99 do {
100 hit.E() = CLHEP::RandGaussZiggurat::shoot(simulstate.randomEngine(),
101 Eavghit, m_RMS * Eavghit);
102 } while (std::abs(hit.E()) < absEavghit_tenth);
103 bool failed = false;
104 if (debug)
105 if (ihit == 2) {
106 // Switch debug output back to INFO to avoid huge logs
107 PropagateMSGLevel(MSG::INFO);
108 }
109 for (auto hititr = hitloopstart; hititr != m_chain.end(); ++hititr) {
111
112 FCSReturnCode status =
113 hitsim->simulate_hit(hit, simulstate, truth, extrapol);
114
115 if (status == FCSSuccess)
116 continue;
117 if (status == FCSFatal) {
118 if (debug)
119 PropagateMSGLevel(old_level);
120 return FCSFatal;
121 }
122 failed = true;
123 ++ifail;
124 ++itotalfail;
125 retry = status - FCSRetry;
126 retry_warning = retry >> 1;
127 if (retry_warning < 1)
128 retry_warning = 1;
129 break;
130 }
131 if (!failed) {
132 ifail = 0;
133 ++ihit;
134 const float Ehit = hit.E();
135 sumEhit += Ehit;
136 float sumEhit2 = sumEhit * sumEhit;
137 error2_sumEhit += Ehit * Ehit;
138 if (sumEhit2 > 0)
139 error2 = error2_sumEhit / sumEhit2;
140 } else {
141 if (ifail >= retry) {
142 ATH_MSG_ERROR("TFCSLateralShapeParametrizationFluctChain::simulate(): "
143 "simulate_hit call failed after "
144 << ifail << "/" << retry
145 << "retries, total fails=" << itotalfail);
146 if (debug)
147 PropagateMSGLevel(old_level);
148 return FCSFatal;
149 }
150 if (ifail >= retry_warning) {
151 ATH_MSG_WARNING("TFCSLateralShapeParametrizationFluctChain::simulate():"
152 " retry simulate_hit calls "
153 << ifail << "/" << retry
154 << ", total fails=" << itotalfail);
155 }
156 }
157 } while (error2 > sigma2);
158
159 if (debug) {
160 PropagateMSGLevel(old_level);
161 ATH_MSG_DEBUG("E(" << calosample() << ")=" << Elayer << " sumE=" << sumEhit
162 << "+-" << TMath::Sqrt(error2_sumEhit) << " ~ "
163 << TMath::Sqrt(error2_sumEhit) / sumEhit * 100
164 << "% rel error^2=" << error2 << " sigma^2=" << sigma2
165 << " ~ " << TMath::Sqrt(sigma2) * 100
166 << "% hits=" << ihit << " fail=" << itotalfail);
167 }
168
169 return FCSSuccess;
170}
171
173 TString opt(option);
174 bool shortprint = opt.Index("short") >= 0;
175 bool longprint = msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
176 TString optprint = opt;
177 optprint.ReplaceAll("short", "");
179
180 if (longprint)
181 ATH_MSG_INFO(optprint << " hit energy fluctuation RMS=" << m_RMS);
182}
#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)
const bool debug
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
MSG::Level level() const
Retrieve output level.
Definition MLogging.h:201
TFCSLateralShapeParametrizationFluctChain(const char *name=nullptr, const char *title=nullptr, float RMS=1.0)
virtual FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
virtual float get_E_hit(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Get hit energy from layer energy and number of hits.
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.
TFCSLateralShapeParametrizationHitChain(const char *name=nullptr, const char *title=nullptr)
void Print(Option_t *option="") const override
Do not persistify!
virtual FCSReturnCode init_hit(TFCSLateralShapeParametrizationHitBase::Hit &hit, TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const
CLHEP::HepRandomEngine * randomEngine()