ATLAS Offline Software
Loading...
Searching...
No Matches
TFCSEnergyInterpolationPiecewiseLinear.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#ifdef __FastCaloSimStandAlone__
11namespace Gaudi {
12namespace Units {
13constexpr double megaelectronvolt = 1.;
14constexpr double kiloelectronvolt = 1.e-3 * megaelectronvolt;
15constexpr double keV = kiloelectronvolt;
16} // namespace Units
17} // namespace Gaudi
18#else
19#include "GaudiKernel/SystemOfUnits.h"
20#endif
21
22//========================================================
23//======= TFCSEnergyInterpolationPiecewiseLinear =========
24//========================================================
25
27 const char *name, const char *title)
28 : TFCSParametrization(name, title),
29 m_linInterpol(0, ROOT::Math::Interpolation::kLINEAR) {}
30
32 Int_t np, const Double_t logEkin[], const Double_t response[]) {
33 // save logEkin and response as std::vector class members
34 // this is required for using the custom streamer
35 m_logEkin.assign(logEkin, logEkin + np);
36 m_response.assign(response, response + np);
38
39 auto min_max = std::minmax_element(m_logEkin.begin(), m_logEkin.end());
40 m_MinMaxlogEkin = std::make_pair(*min_max.first, *min_max.second);
41}
42
44 Int_t np, const Double_t Ekin[], const Double_t response[]) {
45 std::vector<Double_t> logEkin(np);
46 for (int i = 0; i < np; i++)
47 logEkin[i] = TMath::Log(Ekin[i]);
48 InitFromArrayInLogEkin(np, logEkin.data(), response);
49}
50
52 TFCSSimulationState &simulstate, const TFCSTruthState *truth,
53 const TFCSExtrapolationState *) const {
54
55 const float Ekin = truth->Ekin();
56 const float Einit = OnlyScaleEnergy() ? simulstate.E() : Ekin;
57
58 // catch very small values of Ekin (use 1 keV here) and fix the interpolation
59 // lookup to the 1keV value
60 const float logEkin = Ekin > Gaudi::Units::keV
61 ? TMath::Log(Ekin)
62 : TMath::Log(Gaudi::Units::keV);
63
64 float Emean;
65 if (logEkin < m_MinMaxlogEkin.first) {
66 Emean = m_linInterpol.Eval(m_MinMaxlogEkin.first) * Einit;
67 } else if (logEkin > m_MinMaxlogEkin.second) {
68 Emean = (m_linInterpol.Eval(m_MinMaxlogEkin.second) +
69 m_linInterpol.Deriv(m_MinMaxlogEkin.second) *
70 (logEkin - m_MinMaxlogEkin.second)) *
71 Einit;
72 } else {
73 Emean = m_linInterpol.Eval(logEkin) * Einit;
74 }
75
76 if (OnlyScaleEnergy())
77 ATH_MSG_DEBUG("set E=" << Emean << " for true Ekin=" << Ekin
78 << " and E=" << Einit);
79 else
80 ATH_MSG_DEBUG("set E=" << Emean << " for true Ekin=" << Ekin);
81
82 // set mean energy of simulstate
83 simulstate.set_E(Emean);
84
85 return FCSSuccess;
86}
87
88double
90 // returns simple evaluation of the interpolation
91 // if the lookup is below the minimum interpolation value, will return minimum
92 // evaluation if the lookup is above the maximum interpolation value, will
93 // return maximum evalution this means no extrapolation beyond the
94 // interpolation will be performed
95
96 // catch very small values of Ekin (use 1 keV here) and fix the interpolation
97 // lookup to the 1keV value
98 const float logEkin = Ekin > Gaudi::Units::keV
99 ? TMath::Log(Ekin)
100 : TMath::Log(Gaudi::Units::keV);
101
102 if (logEkin < m_MinMaxlogEkin.first)
103 return m_linInterpol.Eval(m_MinMaxlogEkin.first);
104 else if (logEkin > m_MinMaxlogEkin.second)
105 return m_linInterpol.Eval(m_MinMaxlogEkin.second);
106 else
107 return m_linInterpol.Eval(logEkin);
108}
109
111
112 TString opt(option);
113 bool shortprint = opt.Index("short") >= 0;
114 bool longprint = msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
115 TString optprint = opt;
116 optprint.ReplaceAll("short", "");
118
119 if (longprint)
120 ATH_MSG_INFO(optprint << (OnlyScaleEnergy() ? " E()*" : " Ekin()*")
121 << "linInterpol N=" << m_logEkin.size() << " "
122 << m_MinMaxlogEkin.first
123 << "<=log(Ekin)<=" << m_MinMaxlogEkin.second << " "
124 << TMath::Exp(m_MinMaxlogEkin.first)
125 << "<=Ekin<=" << TMath::Exp(m_MinMaxlogEkin.second));
126}
127
128void TFCSEnergyInterpolationPiecewiseLinear::Streamer(TBuffer &R__b) {
129 // Stream an object of class TFCSEnergyInterpolationPiecewiseLinear
130 if (R__b.IsReading()) {
131 // read the class buffer
132 R__b.ReadClassBuffer(TFCSEnergyInterpolationPiecewiseLinear::Class(), this);
133 // initialize interpolation from saved class members
135 m_response.data());
136 } else {
137 R__b.WriteClassBuffer(TFCSEnergyInterpolationPiecewiseLinear::Class(),
138 this);
139 }
140}
141
143 TFCSSimulationState *simulstate, TFCSTruthState *truth,
144 const TFCSExtrapolationState *extrapol, TGraph *grlinear) {
145 if (!simulstate)
146 simulstate = new TFCSSimulationState();
147 if (!truth)
148 truth = new TFCSTruthState();
149 if (!extrapol)
150 extrapol = new TFCSExtrapolationState();
151
152 if (!grlinear) {
153 const int Graph0_n = 9;
154 Double_t Graph0_fx1001[Graph0_n] = {1.024, 2.048, 4.094, 8.192, 16.384,
155 32.768, 65.536, 131.072, 262.144};
156
157 for (int i = 0; i < Graph0_n; ++i)
158 Graph0_fx1001[i] *= 1000;
159 Double_t Graph0_fy1001[Graph0_n] = {0.6535402, 0.6571529, 0.6843001,
160 0.7172835, 0.7708416, 0.798819,
161 0.8187628, 0.8332745, 0.8443931};
162 grlinear = new TGraph(Graph0_n, Graph0_fx1001, Graph0_fy1001);
163 }
164
165 TGraph *grdraw = (TGraph *)grlinear->Clone();
166 grdraw->SetMarkerColor(46);
167 grdraw->SetMarkerStyle(8);
168
170 "testTFCSEnergyInterpolationPieceWiseLinear",
171 "test TFCSEnergyInterpolationPiecewiseLinear");
172 test.set_pdgid(22);
173 test.set_Ekin_nominal(
174 0.5 * (grdraw->GetX()[0] + grdraw->GetX()[grdraw->GetN() - 1]));
175 test.set_Ekin_min(grdraw->GetX()[0]);
176 test.set_Ekin_max(grdraw->GetX()[grdraw->GetN() - 1]);
177 test.set_eta_nominal(0.225);
178 test.set_eta_min(0.2);
179 test.set_eta_max(0.25);
180 test.InitFromArrayInEkin(grlinear->GetN(), grlinear->GetX(),
181 grlinear->GetY());
182 // test.set_OnlyScaleEnergy();
183 test.Print();
184
185 truth->set_pdgid(22);
186
187 TGraph *gr = new TGraph();
188 gr->SetNameTitle("testTFCSEnergyInterpolationPiecewiseLogX",
189 "test TFCSEnergyInterpolationPiecewiseLinear log x-axis");
190 gr->GetXaxis()->SetTitle("Ekin [MeV]");
191 gr->GetYaxis()->SetTitle("<E(reco)>/Ekin(true)");
192
193 int ip = 0;
194 for (float Ekin = test.Ekin_min() * 0.25; Ekin <= test.Ekin_max() * 4;
195 Ekin *= 1.05) {
196 // Init LorentzVector for truth. For photon Ekin=E
197 truth->SetPxPyPzE(Ekin, 0, 0, Ekin);
198 simulstate->set_E(Ekin);
199 if (test.simulate(*simulstate, truth, extrapol) != FCSSuccess) {
200 return;
201 }
202 gr->SetPoint(ip, Ekin, simulstate->E() / Ekin);
203 ++ip;
204 }
205
206// Drawing doesn't make sense inside athena and necessary libraries not linked
207// by default
208#if defined(__FastCaloSimStandAlone__)
209 TCanvas *c = new TCanvas(gr->GetName(), gr->GetTitle());
210 gr->Draw("APL");
211 grdraw->Draw("Psame");
212 c->SetLogx();
213#endif
214}
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define gr
MDT_Response response
@ kLINEAR
Scale trigger linearly with luminosity.
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 FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
static void unit_test(TFCSSimulationState *simulstate=nullptr, TFCSTruthState *truth=nullptr, const TFCSExtrapolationState *extrapol=nullptr, TGraph *grlinear=nullptr)
void InitFromArrayInLogEkin(Int_t np, const Double_t logEkin[], const Double_t response[])
void InitFromArrayInEkin(Int_t np, const Double_t Ekin[], const Double_t response[])
TFCSEnergyInterpolationPiecewiseLinear(const char *name=nullptr, const char *title=nullptr)
void Print(Option_t *option="") const
Print object information.
TFCSParametrization(const char *name=nullptr, const char *title=nullptr)
void set_E(int sample, double Esample)
void set_pdgid(int val)
double Ekin() const
=============================================================================
Selection rules: declare transient members.
Definition DataVector.h:581