ATLAS Offline Software
TFCSPCAEnergyParametrization.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "CLHEP/Random/RandGaussZiggurat.h"
6 #include "CLHEP/Random/RandFlat.h"
7 
10 
13 
14 #include "TFile.h"
15 #include "TKey.h"
16 #include "TClass.h"
17 #include "TMatrixD.h"
18 #include "TMatrixDSymEigen.h"
19 #include "TMath.h"
20 #include "TH1.h"
21 #include "CxxUtils/restrict.h"
22 
23 //=============================================
24 //======= TFCSPCAEnergyParametrization =========
25 //=============================================
26 
28  const char *title)
30  m_numberpcabins = 1;
31  do_rescale = 1;
32 }
33 
35  if (Ekin_bin >= 1 && Ekin_bin <= n_bins())
36  return true;
37  return false;
38 }
39 
41  for (unsigned int i = 0; i < m_RelevantLayers.size(); i++) {
42  if (m_RelevantLayers[i] == calosample)
43  return true;
44  }
45  return false;
46 }
47 
48 void TFCSPCAEnergyParametrization::Print(Option_t *option) const {
49  TString opt(option);
50  bool shortprint = opt.Index("short") >= 0;
51  bool longprint = msgLvl(MSG::DEBUG) || (msgLvl(MSG::INFO) && !shortprint);
52  TString optprint = opt;
53  optprint.ReplaceAll("short", "");
55 
56  if (longprint) {
57  ATH_MSG(INFO) << optprint << " #bins=" << m_numberpcabins
58  << ", Enorm=" << m_total_energy_normalization << ", layers=";
59  for (unsigned int i = 0; i < m_RelevantLayers.size(); i++) {
60  if (i > 0)
61  ATH_MSG(INFO) << ", ";
63  }
64  ATH_MSG(INFO) << END_MSG(INFO);
65  }
66 }
67 
68 float interpolate_get_y(TH1 *hist, float x) {
69  float m = 0;
70  float n = 0;
71  float x1 = 1;
72  float x2 = 0;
73  float y1 = 0;
74  float y2 = 0;
75  if (x <= hist->GetBinCenter(1))
76  return hist->GetBinContent(1);
77  if (x >= hist->GetBinCenter(hist->GetNbinsX()))
78  return hist->GetBinContent(hist->GetNbinsX());
79 
80  int bin = hist->FindBin(x);
81  // is x above the bin center -> interpolate with next bin
82  if (x > hist->GetBinCenter(bin)) {
83  x1 = hist->GetBinCenter(bin);
84  y1 = hist->GetBinContent(bin);
85  x2 = hist->GetBinCenter(bin + 1);
86  y2 = hist->GetBinContent(bin + 1);
87  }
88 
89  // is x below bin center -> interpolate with previous bin
90  if (x <= hist->GetBinCenter(bin)) {
91  x1 = hist->GetBinCenter(bin - 1);
92  y1 = hist->GetBinContent(bin - 1);
93  x2 = hist->GetBinCenter(bin);
94  y2 = hist->GetBinContent(bin);
95  }
96 
97  m = (y1 - y2) / (x1 - x2);
98  n = y2 - m * x2;
99  return m * x + n;
100 }
101 
103  TH1 *hist) {
104  if (Ekin_bin < 1)
105  return;
106  if (Ekin_bin - 1 >= (int)m_totalE_probability_ratio.size())
107  return;
108  m_totalE_probability_ratio[Ekin_bin - 1] = hist;
109 }
110 
112  int Ekin_bin) const {
113  if (Ekin_bin < 1)
114  return nullptr;
115  if (Ekin_bin - 1 >= (int)m_totalE_probability_ratio.size())
116  return nullptr;
117  return m_totalE_probability_ratio[Ekin_bin - 1];
118 }
119 
121  TFCSSimulationState &simulstate, const TFCSTruthState * /*truth*/,
122  const TFCSExtrapolationState * /*extrapol*/) const {
123 
124  if (!simulstate.randomEngine()) {
125  return FCSFatal;
126  }
127 
128  int pcabin = simulstate.Ebin();
129 
130  if (pcabin == 0) {
131  simulstate.set_E(0);
132  for (int s = 0; s < CaloCell_ID_FCS::MaxSample; s++) {
133  simulstate.set_E(s, 0.0);
134  simulstate.set_Efrac(s, 0.0);
135  }
136  } else {
137 
138  TMatrixD *EV = m_EV[pcabin - 1];
139  TVectorD *MeanValues = m_MeanValues[pcabin - 1];
140  TVectorD *SigmaValues = m_SigmaValues[pcabin - 1];
141  TVectorD *Gauss_means = m_Gauss_means[pcabin - 1];
142  TVectorD *Gauss_rms = m_Gauss_rms[pcabin - 1];
143  std::vector<TFCS1DFunction *> cumulative = m_cumulative[pcabin - 1];
144 
145  const std::vector<int> &layerNr = m_RelevantLayers;
146 
147  double *vals_gauss_means = (double *)Gauss_means->GetMatrixArray();
148  double *vals_gauss_rms = Gauss_rms->GetMatrixArray();
149 
150  double *output_data = new double[layerNr.size() + 1];
151  double *input_data = new double[layerNr.size() + 1];
152 
153  for (unsigned int l = 0; l <= layerNr.size(); l++) {
154  double mean = vals_gauss_means[l];
155  double rms = vals_gauss_rms[l];
156  double gauszz =
157  CLHEP::RandGaussZiggurat::shoot(simulstate.randomEngine(), mean, rms);
158  input_data[l] = gauszz;
159  }
160 
161  P2X(SigmaValues, MeanValues, EV, layerNr.size() + 1, input_data,
162  output_data, layerNr.size() + 1);
163 
164  double *simdata = new double[layerNr.size() + 1];
165  double sum_fraction = 0.0;
166  for (unsigned int l = 0; l <= layerNr.size(); l++) {
167  double simdata_uniform =
168  (TMath::Erf(output_data[l] / 1.414213562) + 1) / 2.f;
169 
170  simdata[l] = cumulative[l]->rnd_to_fct(simdata_uniform);
171 
172  if (l != layerNr.size()) // sum up the fractions, but not the totalE
173  sum_fraction += simdata[l];
174  }
175 
176  double scalefactor = 1.0 / sum_fraction;
177  if (!do_rescale)
178  scalefactor = 1.0;
179 
180  // Using signed int for better loop optimization and vectorization where
181  // possible
182  int layerNrsize = static_cast<int>(layerNr.size());
183  for (int l = 0; l < layerNrsize; l++) {
184  simdata[l] *= scalefactor;
185  }
186 
187  // Apply hit-and-miss reweighting of total energy response
188  // This needs to run before simulstate is modified, otherwise a clean retry
189  // is not possible
190  TH1 *h_totalE_ratio = get_totalE_probability_ratio(pcabin);
191  if (h_totalE_ratio) {
192  float pass_probability = 0;
193  float Etot = simdata[layerNr.size()];
194  if (Etot > h_totalE_ratio->GetXaxis()->GetXmin() &&
195  Etot < h_totalE_ratio->GetXaxis()->GetXmax()) {
196  pass_probability = interpolate_get_y(h_totalE_ratio, Etot);
197  }
198  float random = CLHEP::RandFlat::shoot(simulstate.randomEngine());
199  if (random > pass_probability) {
200  delete[] output_data;
201  delete[] input_data;
202  delete[] simdata;
203 
204  return (FCSReturnCode)FCSRetryPCA;
205  }
206  }
207 
208  double total_energy =
209  simdata[layerNr.size()] * simulstate.E() / m_total_energy_normalization;
210  simulstate.set_E(total_energy);
211  ATH_MSG_DEBUG("set E to total_energy=" << total_energy);
212 
213  for (int s = 0; s < CaloCell_ID_FCS::MaxSample; s++) {
214  double energyfrac = 0.0;
215  for (unsigned int l = 0; l < layerNr.size(); l++) {
216  if (layerNr[l] == s)
217  energyfrac = simdata[l];
218  }
219  simulstate.set_Efrac(s, energyfrac);
220  simulstate.set_E(s, energyfrac * total_energy);
221  simulstate.set_SF(scalefactor);
222  }
223 
224  delete[] output_data;
225  delete[] input_data;
226  delete[] simdata;
227  }
228 
229  return FCSSuccess;
230 }
231 
232 void TFCSPCAEnergyParametrization::P2X(TVectorD *SigmaValues,
233  TVectorD *MeanValues, TMatrixD *EV,
234  int gNVariables, const double *p,
235  double *ATH_RESTRICT x, int nTest) {
236 
237  const double *gSigmaValues = SigmaValues->GetMatrixArray();
238  const double *gMeanValues = MeanValues->GetMatrixArray();
239  const double *gEigenVectors = EV->GetMatrixArray();
240 
241  for (int i = 0; i < gNVariables; i++) {
242  x[i] = gMeanValues[i];
243  for (int j = 0; j < nTest; j++) {
244  x[i] +=
245  p[j] * gSigmaValues[i] * (double)(gEigenVectors[i * gNVariables + j]);
246  }
247  }
248 }
249 
251  return loadInputs(file, "");
252 }
253 
255  const std::string &folder) {
256 
257  bool load_ok = 1;
258 
259  int trynext = 1;
260  TString x;
261  if (folder.empty())
262  x = "bin";
263  else
264  x = folder + "/bin";
265  while (trynext) {
266  IntArray *test = (IntArray *)file->Get(
267  x + Form("%i/pca/RelevantLayers", m_numberpcabins));
268  if (test) {
269  m_numberpcabins++;
270  delete test;
271  } else
272  trynext = 0;
273  }
274  m_numberpcabins -= 1;
275 
276  file->cd(x + "1/pca");
277  IntArray *RelevantLayers = (IntArray *)gDirectory->Get("RelevantLayers");
278  if (RelevantLayers == nullptr) {
279  ATH_MSG_ERROR("TFCSPCAEnergyParametrization::m_RelevantLayers in first "
280  "pcabin is null!");
281  load_ok = false;
282  }
283 
284  if (!load_ok)
285  return false;
286 
287  m_RelevantLayers.reserve(RelevantLayers->GetSize());
288  for (int i = 0; i < RelevantLayers->GetSize(); i++)
289  m_RelevantLayers.push_back(RelevantLayers->GetAt(i));
290 
291  for (int bin = 1; bin <= m_numberpcabins; bin++) {
292 
293  file->cd(x + Form("%i/pca", bin));
294 
295  TMatrixDSym *symCov = (TMatrixDSym *)gDirectory->Get("symCov");
296  TVectorD *MeanValues = (TVectorD *)gDirectory->Get("MeanValues");
297  TVectorD *SigmaValues = (TVectorD *)gDirectory->Get("SigmaValues");
298  TVectorD *Gauss_means = (TVectorD *)gDirectory->Get("Gauss_means");
299  TVectorD *Gauss_rms = (TVectorD *)gDirectory->Get("Gauss_rms");
300 
301  if (symCov == nullptr) {
302  ATH_MSG_WARNING("TFCSPCAEnergyParametrization::symCov in pcabin "
303  << bin << " is null!");
304  load_ok = false;
305  }
306  if (MeanValues == nullptr) {
307  ATH_MSG_WARNING("TFCSPCAEnergyParametrization::MeanValues in pcabin "
308  << bin << " is null!");
309  load_ok = false;
310  }
311  if (SigmaValues == nullptr) {
312  ATH_MSG_WARNING("TFCSPCAEnergyParametrization::SigmaValues in pcabin "
313  << bin << " is null!");
314  load_ok = false;
315  }
316  if (Gauss_means == nullptr) {
317  ATH_MSG_WARNING("TFCSPCAEnergyParametrization::Gauss_means in pcabin "
318  << bin << " is null!");
319  load_ok = false;
320  }
321  if (Gauss_rms == nullptr) {
322  ATH_MSG_WARNING("TFCSPCAEnergyParametrization::Gause_rms in pcabin "
323  << bin << " is null!");
324  load_ok = false;
325  }
326 
327  if (!load_ok)
328  return false;
329 
330  TMatrixDSymEigen cov_eigen(*symCov);
331  TMatrixD *EV = new TMatrixD(cov_eigen.GetEigenVectors());
332  m_EV.push_back(EV);
333  m_MeanValues.push_back(MeanValues);
334  m_SigmaValues.push_back(SigmaValues);
335  m_Gauss_means.push_back(Gauss_means);
336  m_Gauss_rms.push_back(Gauss_rms);
337 
338  std::vector<std::string> layer;
339  const std::vector<int> &layerNr = m_RelevantLayers;
340 
341  for (unsigned int i = 0; i < layerNr.size(); i++) {
342  layer.emplace_back(Form("layer%i", layerNr[i]));
343  }
344  layer.emplace_back("totalE");
345 
346  std::vector<TFCS1DFunction *> cumulative;
347  cumulative.reserve(layer.size());
348 
349  for (unsigned int l = 0; l < layer.size(); l++) {
350  file->cd(Form("%s/bin%i/%s", folder.c_str(), bin, layer[l].c_str()));
351 
353  fct = (TFCS1DFunction *)gDirectory->Get("TFCS1DFunctionRegression");
354  if (!fct)
355  fct = (TFCS1DFunction *)gDirectory->Get("TFCS1DFunctionRegressionTF");
356  if (!fct)
357  fct = (TFCS1DFunction *)gDirectory->Get("TFCS1DFunctionHistogram");
358  cumulative.push_back(fct);
359  }
360 
361  m_cumulative.emplace_back(std::move(cumulative));
362  }
363  m_totalE_probability_ratio.resize(m_numberpcabins - 1, nullptr);
364 
365  return true;
366 }
367 
369  for (unsigned int i = 0; i < m_EV.size(); i++)
370  delete m_EV[i];
371 }
372 
373 void TFCSPCAEnergyParametrization::Streamer(TBuffer &R__b) {
374  // Stream an object of class TFCSPCAEnergyParametrization
375 
376  if (R__b.IsReading()) {
377  UInt_t R__s, R__c;
378  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
379  R__b.SetBufferOffset(R__s);
380 
381  R__b.ReadClassBuffer(TFCSPCAEnergyParametrization::Class(), this);
382 
383  if (R__v == 1) {
385  // Check if min and max range is a factor 2 within 1 MeV tolerance
386  // If yes, the nominal to log-avergage
387  if (TMath::Abs(Ekin_max() - 2 * Ekin_min()) < 1) {
388  set_Ekin_nominal(Ekin_max() / TMath::Sqrt(2));
389  }
390  }
391  if (R__v <= 2) {
392  m_totalE_probability_ratio.resize(m_numberpcabins - 1, nullptr);
393  }
394  } else {
395  R__b.WriteClassBuffer(TFCSPCAEnergyParametrization::Class(), this);
396  }
397 }
TFCSParametrization::set_Ekin_nominal
virtual void set_Ekin_nominal(double min)
Definition: TFCSParametrization.cxx:39
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
FCSReturnCode
FCSReturnCode
Base class for all FastCaloSim parametrizations Functionality in derivde classes is provided through ...
Definition: TFCSParametrizationBase.h:41
TFCSPCAEnergyParametrization::m_SigmaValues
std::vector< TVectorD * > m_SigmaValues
Definition: TFCSPCAEnergyParametrization.h:72
TFCSPCAEnergyParametrization::m_RelevantLayers
std::vector< int > m_RelevantLayers
Definition: TFCSPCAEnergyParametrization.h:68
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
mean
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:254
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ATH_MSG
#define ATH_MSG(lvl)
Definition: AthMsgStreamMacros.h:38
TFCSPCAEnergyParametrization::m_Gauss_rms
std::vector< TVectorD * > m_Gauss_rms
Definition: TFCSPCAEnergyParametrization.h:74
TFCSEnergyParametrization
Definition: TFCSEnergyParametrization.h:10
TFCSParametrization::Ekin_max
double Ekin_max() const override
Definition: TFCSParametrization.h:37
TFCSPCAEnergyParametrization::simulate
virtual FCSReturnCode simulate(TFCSSimulationState &simulstate, const TFCSTruthState *truth, const TFCSExtrapolationState *extrapol) const override
Method in all derived classes to do some simulation.
Definition: TFCSPCAEnergyParametrization.cxx:120
plotmaker.hist
hist
Definition: plotmaker.py:148
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
TFCSPCAEnergyParametrization::m_total_energy_normalization
float m_total_energy_normalization
Definition: TFCSPCAEnergyParametrization.h:81
TFCSPCAEnergyParametrization::P2X
static void P2X(TVectorD *, TVectorD *, TMatrixD *, int, const double *, double *, int)
Definition: TFCSPCAEnergyParametrization.cxx:232
TFCSPCAEnergyParametrization::is_match_Ekin_bin
virtual bool is_match_Ekin_bin(int Ekin_bin) const override
Definition: TFCSPCAEnergyParametrization.cxx:34
TFCSPCAEnergyParametrization::TFCSPCAEnergyParametrization
TFCSPCAEnergyParametrization(const char *name=nullptr, const char *title=nullptr)
Definition: TFCSPCAEnergyParametrization.cxx:27
TFCSPCAEnergyParametrization::loadInputs
bool loadInputs(TFile *file)
Definition: TFCSPCAEnergyParametrization.cxx:250
bin
Definition: BinsDiffFromStripMedian.h:43
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
TrigInDetValidation_Base.test
test
Definition: TrigInDetValidation_Base.py:146
TFCSExtrapolationState
Definition: TFCSExtrapolationState.h:13
TFCSSimulationState::randomEngine
CLHEP::HepRandomEngine * randomEngine()
Definition: TFCSSimulationState.h:36
python.AthDsoLogger.fct
fct
Definition: AthDsoLogger.py:43
x
#define x
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
TFCSPCAEnergyParametrization::n_bins
virtual int n_bins() const override
Definition: TFCSPCAEnergyParametrization.h:38
TFCSPCAEnergyParametrization::m_EV
std::vector< TMatrixD * > m_EV
Definition: TFCSPCAEnergyParametrization.h:70
ATH_RESTRICT
#define ATH_RESTRICT
Definition: restrict.h:31
TFCSPCAEnergyParametrization.h
TFCSSimulationState::set_SF
void set_SF(double mysf)
Definition: TFCSSimulationState.h:81
CaloCell_ID_FCS::MaxSample
@ MaxSample
Definition: FastCaloSim_CaloCell_ID.h:47
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
TFCSPCAEnergyParametrization::get_totalE_probability_ratio
TH1 * get_totalE_probability_ratio(int Ekin_bin) const
Definition: TFCSPCAEnergyParametrization.cxx:111
lumiFormat.i
int i
Definition: lumiFormat.py:92
TFCSPCAEnergyParametrization::Print
void Print(Option_t *option="") const override
Definition: TFCSPCAEnergyParametrization.cxx:48
TFCSSimulationState::Ebin
int Ebin() const
Definition: TFCSSimulationState.h:45
beamspotman.n
n
Definition: beamspotman.py:731
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
covarianceTool.title
title
Definition: covarianceTool.py:542
file
TFile * file
Definition: tile_monitor.h:29
TFCSParametrization::Ekin_min
double Ekin_min() const override
Definition: TFCSParametrization.h:36
TFCSParametrizationBase::Print
void Print(Option_t *option="") const
Print object information.
Definition: TFCSParametrizationBase.cxx:52
TFCSPCAEnergyParametrization::m_MeanValues
std::vector< TVectorD * > m_MeanValues
Definition: TFCSPCAEnergyParametrization.h:71
FCSFatal
@ FCSFatal
Definition: TFCSParametrizationBase.h:41
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
FCSSuccess
@ FCSSuccess
Definition: TFCSParametrizationBase.h:41
TFCSPCAEnergyParametrization::set_totalE_probability_ratio
void set_totalE_probability_ratio(int Ekin_bin, TH1 *hist)
Definition: TFCSPCAEnergyParametrization.cxx:102
restrict.h
Macro wrapping the nonstandard restrict keyword.
TFCSPCAEnergyParametrization::m_cumulative
std::vector< std::vector< TFCS1DFunction * > > m_cumulative
Definition: TFCSPCAEnergyParametrization.h:75
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
pmontree.opt
opt
Definition: pmontree.py:16
TFCSPCAEnergyParametrization::m_totalE_probability_ratio
std::vector< TH1 * > m_totalE_probability_ratio
Definition: TFCSPCAEnergyParametrization.h:77
TFCSPCAEnergyParametrization::FCSRetryPCA
@ FCSRetryPCA
Definition: TFCSPCAEnergyParametrization.h:27
TFCSSimulationState::set_E
void set_E(int sample, double Esample)
Definition: TFCSSimulationState.h:48
TFCSPCAEnergyParametrization::clean
void clean()
Definition: TFCSPCAEnergyParametrization.cxx:368
TFCSPCAEnergyParametrization::is_match_calosample
virtual bool is_match_calosample(int calosample) const override
Definition: TFCSPCAEnergyParametrization.cxx:40
interpolate_get_y
float interpolate_get_y(TH1 *hist, float x)
Definition: TFCSPCAEnergyParametrization.cxx:68
END_MSG
#define END_MSG(lvl)
Definition: MLogging.h:171
IntArray
Definition: IntArray.h:11
TFCSPCAEnergyParametrization::m_numberpcabins
int m_numberpcabins
Definition: TFCSPCAEnergyParametrization.h:79
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.Constants.INFO
int INFO
Definition: Control/AthenaCommon/python/Constants.py:16
TFCSExtrapolationState.h
TH1
Definition: rootspy.cxx:268
DEBUG
#define DEBUG
Definition: page_access.h:11
beamspotnt.rms
rms
Definition: bin/beamspotnt.py:1266
TFCSParametrization::Ekin_nominal
double Ekin_nominal() const override
Definition: TFCSParametrization.h:35
CaloCondBlobAlgs_fillNoiseFromASCII.folder
folder
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:56
TFCSSimulationState::E
double E() const
Definition: TFCSSimulationState.h:42
TFCSPCAEnergyParametrization::m_Gauss_means
std::vector< TVectorD * > m_Gauss_means
Definition: TFCSPCAEnergyParametrization.h:73
TFCSSimulationState.h
FastCaloSim_CaloCell_ID.h
TFCS1DFunction
Definition: TFCS1DFunction.h:17
TFCSPCAEnergyParametrization::do_rescale
int do_rescale
Definition: TFCSPCAEnergyParametrization.h:65
TFCSTruthState
Definition: TFCSTruthState.h:13
TFCSSimulationState
Definition: TFCSSimulationState.h:32
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
TFCSPCAEnergyParametrization::set_total_energy_normalization
void set_total_energy_normalization(float norm)
Definition: TFCSPCAEnergyParametrization.h:58
TFCSSimulationState::set_Efrac
void set_Efrac(int sample, double Efracsample)
Definition: TFCSSimulationState.h:49