ATLAS Offline Software
TFCS2DFunction.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 #include "TH2.h"
9 #include "TCanvas.h"
10 #include "TH2F.h"
11 #include "TRandom.h"
12 #include "TFile.h"
13 
14 #include <iostream>
15 
16 //=============================================
17 //======= TFCS2DFunction =========
18 //=============================================
19 
20 void TFCS2DFunction::rnd_to_fct(float value[], const float rnd[]) const {
21  rnd_to_fct(value[0], value[1], rnd[0], rnd[1]);
22 }
23 
24 //================================================================================================================================
25 
27  const TH2 *hist, std::vector<double> &integral_vec, int &first, int &last) {
29  Int_t nbinsx = hist->GetNbinsX();
30  Int_t nbinsy = hist->GetNbinsY();
31  Int_t nbins = nbinsx * nbinsy;
32 
33  float integral = 0.0;
34  float hint = hist->Integral();
35  integral_vec.resize(nbins);
36 
37  for (int ix = 1; ix <= nbinsx; ix++) {
38  for (int iy = 1; iy <= nbinsy; iy++) {
39  int globalbin = (ix - 1) * nbinsy + iy - 1;
40  float binval = hist->GetBinContent(ix, iy);
41  if (binval < 0) {
42  // Can't work if a bin is negative, forcing bins to 0 in this case
43  double fraction = binval / hint;
44  if (TMath::Abs(fraction) > 1e-5) {
46  "Warning: bin content is negative in histogram "
47  << hist->GetName() << " : " << hist->GetTitle()
48  << " binval=" << binval << " " << fraction * 100
49  << "% of integral=" << hist->Integral()
50  << ". Forcing bin to 0.");
51  }
52  binval = 0;
53  }
54  integral += binval;
55  integral_vec[globalbin] = integral;
56  }
57  }
58 
59  for (first = 0; first < nbins; first++)
60  if (integral_vec[first] != 0)
61  break;
62  for (last = nbins - 1; last > 0; last--)
63  if (integral_vec[last] != integral)
64  break;
65  last++;
66 
67  if (integral <= 0) {
68  ATH_MSG_NOCLASS(logger, "Error: histogram "
69  << hist->GetName() << " : " << hist->GetTitle()
70  << " integral=" << integral << " is <=0");
71  }
72 
73  return integral;
74 }
75 
76 TH2 *create_random_TH2 ATLAS_NOT_THREAD_SAFE(int nbinsx = 64, int nbinsy = 64) {
77  TH2 *hist = new TH2F("test2D", "test2D", nbinsx, 0, 1, nbinsy, 0, 1);
78  hist->Sumw2();
79  for (int ix = 1; ix <= nbinsx; ++ix) {
80  for (int iy = 1; iy <= nbinsy; ++iy) {
81  hist->SetBinContent(ix, iy,
82  (0.5 + gRandom->Rndm()) * (nbinsx + ix) *
83  (nbinsy * nbinsy / 2 + iy * iy));
84  if (gRandom->Rndm() < 0.1)
85  hist->SetBinContent(ix, iy, 0);
86  hist->SetBinError(ix, iy, 0);
87  }
88  }
89  return hist;
90 }
91 
92 void TFCS2DFunction::unit_test ATLAS_NOT_THREAD_SAFE(TH2 *hist,
93  TFCS2DFunction *rtof,
94  const char *outfilename,
95  int nrnd) {
97  if (hist == nullptr)
98  hist = create_random_TH2();
99  if (rtof == nullptr)
100  rtof = new TFCS2DFunctionHistogram(hist);
101 
102  int nbinsx = hist->GetNbinsX();
103  int nbinsy = hist->GetNbinsY();
104 
105  float value[2];
106  float rnd[2];
107  //cppcheck-suppress uninitvar
108  for (rnd[0] = 0; rnd[0] < 0.9999; rnd[0] += 0.25) {
109  for (rnd[1] = 0; rnd[1] < 0.9999; rnd[1] += 0.25) {
110  rtof->rnd_to_fct(value, rnd);
111  ATH_MSG_NOCLASS(logger, "rnd0=" << rnd[0] << " rnd1=" << rnd[1]
112  << " -> x=" << value[0]
113  << " y=" << value[1]);
114  }
115  }
116 
117  // TH2F* hist_val=new
118  // TH2F("val2D","val2D",16,hist->GetXaxis()->GetXmin(),hist->GetXaxis()->GetXmax(),
119  // 16,hist->GetYaxis()->GetXmin(),hist->GetYaxis()->GetXmax());
120  TH2F *hist_val =
121  (TH2F *)hist->Clone(TString(hist->GetName()) + "_" + rtof->ClassName());
122  hist_val->Reset();
123 
124  float weight = hist->Integral() / nrnd;
125  hist_val->Sumw2();
126  for (int i = 0; i < nrnd; ++i) {
127  rnd[0] = gRandom->Rndm();
128  rnd[1] = gRandom->Rndm();
129  rtof->rnd_to_fct(value, rnd);
130  hist_val->Fill(value[0], value[1], weight);
131  }
132  hist_val->Add(hist, -1);
133 
134  TH1F *hist_pull =
135  new TH1F(TString("pull_") + rtof->ClassName(),
136  TString("pull for ") + rtof->ClassName(), 80, -4, 4);
137  for (int ix = 1; ix <= nbinsx; ++ix) {
138  for (int iy = 1; iy <= nbinsy; ++iy) {
139  float val = hist_val->GetBinContent(ix, iy);
140  float err = hist_val->GetBinError(ix, iy);
141  if (err > 0)
142  hist_pull->Fill(val / err);
143  // ATH_MSG_NOCLASS(logger,"val="<<val<<" err="<<err);
144  }
145  }
146 
147  std::unique_ptr<TFile> outputfile(TFile::Open(outfilename, "UPDATE"));
148  if (outputfile != nullptr) {
149  hist->Write();
150  hist_val->Write();
151  hist_pull->Write();
152  outputfile->ls();
153  }
154 
155 // Screen output in athena won't make sense and would require linking of
156 // additional libraries
157 #if defined(__FastCaloSimStandAlone__)
158  new TCanvas(hist->GetName(), hist->GetTitle());
159  hist->Draw("colz");
160 
161  new TCanvas(hist_val->GetName(), hist_val->GetTitle());
162  hist_val->Draw("colz");
163 
164  new TCanvas(hist_pull->GetName(), hist_pull->GetTitle());
165  hist_pull->Draw();
166 #endif
167 }
168 
169 void TFCS2DFunction::unit_tests
170 ATLAS_NOT_THREAD_SAFE(TH2 *hist, const char *outfilename, int nrnd) {
171  if (hist == nullptr)
172  hist = create_random_TH2(16, 16);
173 
174  const int ntest = 4;
175  TFCS2DFunction *tests[ntest];
180 
181  for (int i = 0; i < ntest; ++i) {
182  unit_test(hist, tests[i], outfilename, nrnd);
183  }
184 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
ISF_FCS::MLogging
Cut down AthMessaging.
Definition: MLogging.h:176
TFCS2DFunctionInt8Int8Int32Histogram
Definition: TFCS2DFunctionTemplateHistogram.h:283
integral
double integral(TH1 *h)
Definition: computils.cxx:58
plotBeamSpotVxVal.globalbin
globalbin
Definition: plotBeamSpotVxVal.py:247
plotmaker.hist
hist
Definition: plotmaker.py:148
TFCS2DFunction.h
athena.value
value
Definition: athena.py:124
TFCS2DFunctionHistogram
Definition: TFCS2DFunctionHistogram.h:15
python.setupRTTAlg.tests
list tests
Definition: setupRTTAlg.py:40
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
TFCS2DFunctionInt8Int8Int16Histogram
Definition: TFCS2DFunctionTemplateHistogram.h:269
TFCS2DFunction::CheckAndIntegrate2DHistogram
static double CheckAndIntegrate2DHistogram(const TH2 *hist, std::vector< double > &integral_vec, int &first, int &last)
Definition: TFCS2DFunction.cxx:26
outputfile
ofstream outputfile
Definition: CellClusterLinkTool.h:25
TFCS2DFunction::rnd_to_fct
virtual void rnd_to_fct(float &valuex, float &valuey, float rnd0, float rnd1) const =0
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
lumiFormat.i
int i
Definition: lumiFormat.py:85
ATLAS_NOT_THREAD_SAFE
TH2 *create_random_TH2 ATLAS_NOT_THREAD_SAFE(int nbinsx=64, int nbinsy=64)
Definition: TFCS2DFunction.cxx:76
TFCS2DFunctionInt8Int8Int8Histogram
Definition: TFCS2DFunctionTemplateHistogram.h:255
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
ATH_MSG_NOCLASS
#define ATH_MSG_NOCLASS(logger_name, x)
Definition: MLogging.h:52
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
TFCS2DFunctionHistogram.h
DeMoScan.first
bool first
Definition: DeMoScan.py:536
TFCS2DFunction
Definition: TFCS2DFunction.h:15
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
TFCS2DFunctionTemplateHistogram.h
python.CreateTierZeroArgdict.outfilename
outfilename
Definition: CreateTierZeroArgdict.py:236
python.iconfTool.gui.pad.logger
logger
Definition: pad.py:14