ATLAS Offline Software
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__
11 namespace Gaudi {
12 namespace Units {
13 constexpr double megaelectronvolt = 1.;
14 constexpr double kiloelectronvolt = 1.e-3 * megaelectronvolt;
15 constexpr 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)
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 
88 double
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 
110 void TFCSEnergyInterpolationPiecewiseLinear::Print(Option_t *option) const {
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 
128 void 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)
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 }
FCSReturnCode
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
Definition: TFCSParametrizationBase.h:41
TFCSEnergyInterpolationPiecewiseLinear::m_response
std::vector< double > m_response
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:64
TFCSEnergyInterpolationPiecewiseLinear::InitFromArrayInEkin
void InitFromArrayInEkin(Int_t np, const Double_t Ekin[], const Double_t response[])
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:43
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
make_coralServer_rep.opt
opt
Definition: make_coralServer_rep.py:19
response
MDT_Response response
Definition: MDT_ResponseTest.cxx:28
gr
#define gr
TFCSEnergyInterpolationPiecewiseLinear
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:19
TFCSEnergyInterpolationPiecewiseLinear::simulate
virtual FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:51
TrigInDetValidation_Base.test
test
Definition: TrigInDetValidation_Base.py:147
TFCSExtrapolationState
Definition: TFCSExtrapolationState.h:13
RunActsMaterialValidation.extrapol
extrapol
Definition: RunActsMaterialValidation.py:91
PlotPulseshapeFromCool.np
np
Definition: PlotPulseshapeFromCool.py:64
TFCSEnergyInterpolationPiecewiseLinear::m_logEkin
std::vector< double > m_logEkin
Do not persistify.
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:63
TFCSEnergyInterpolationPiecewiseLinear::m_linInterpol
ROOT::Math::Interpolator m_linInterpol
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:61
python.SystemOfUnits.keV
int keV
Definition: SystemOfUnits.py:156
kLINEAR
@ kLINEAR
Scale trigger linearly with luminosity.
Definition: RatesHistoBase.h:31
lumiFormat.i
int i
Definition: lumiFormat.py:85
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TFCSTruthState::Ekin
double Ekin() const
Definition: TFCSTruthState.h:26
covarianceTool.title
title
Definition: covarianceTool.py:542
python.SystemOfUnits.megaelectronvolt
int megaelectronvolt
Definition: SystemOfUnits.py:144
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
TFCSParametrizationBase::Print
void Print(Option_t *option="") const
Print object information.
Definition: TFCSParametrizationBase.cxx:52
FCSSuccess
@ FCSSuccess
Definition: TFCSParametrizationBase.h:41
python.SystemOfUnits.kiloelectronvolt
int kiloelectronvolt
Definition: SystemOfUnits.py:146
Athena::Units
Definition: Units.h:45
TFCSParametrization
Definition: TFCSParametrization.h:10
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
TFCSEnergyInterpolationPiecewiseLinear::m_MinMaxlogEkin
std::pair< double, double > m_MinMaxlogEkin
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:65
TFCSSimulationState::set_E
void set_E(int sample, double Esample)
Definition: TFCSSimulationState.h:48
TFCSEnergyInterpolationPiecewiseLinear::unit_test
static void unit_test(TFCSSimulationState *simulstate=nullptr, TFCSTruthState *truth=nullptr, const TFCSExtrapolationState *extrapol=nullptr, TGraph *grlinear=nullptr)
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:142
TFCSEnergyInterpolationPiecewiseLinear::TFCSEnergyInterpolationPiecewiseLinear
TFCSEnergyInterpolationPiecewiseLinear(const char *name=nullptr, const char *title=nullptr)
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:26
TFCSEnergyInterpolationPiecewiseLinear::OnlyScaleEnergy
bool OnlyScaleEnergy() const
Definition: TFCSEnergyInterpolationPiecewiseLinear.h:31
TFCSTruthState.h
TFCSExtrapolationState.h
DEBUG
#define DEBUG
Definition: page_access.h:11
TFCSEnergyInterpolationPiecewiseLinear.h
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
TFCSEnergyInterpolationPiecewiseLinear::evaluate
double evaluate(const double &Ekin) const
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:89
TFCSSimulationState::E
double E() const
Definition: TFCSSimulationState.h:42
TFCSSimulationState.h
TFCSTruthState
Definition: TFCSTruthState.h:13
TFCSEnergyInterpolationPiecewiseLinear::Print
void Print(Option_t *option="") const override
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:110
python.compressB64.c
def c
Definition: compressB64.py:93
TFCSSimulationState
Definition: TFCSSimulationState.h:32
ROOT
Selection rules: declare transient members.
Definition: DataVector.h:580
ISF_FCS::MLogging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Check whether the logging system is active at the provided verbosity level.
Definition: MLogging.h:222
TFCSTruthState::set_pdgid
void set_pdgid(int val)
Definition: TFCSTruthState.h:18
TFCSEnergyInterpolationPiecewiseLinear::InitFromArrayInLogEkin
void InitFromArrayInLogEkin(Int_t np, const Double_t logEkin[], const Double_t response[])
Definition: TFCSEnergyInterpolationPiecewiseLinear.cxx:31