ATLAS Offline Software
TFCS2DFunctionHistogram.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include <algorithm>
7 #include <iostream>
8 #include "TMath.h"
9 #include "TCanvas.h"
10 #include "TH2F.h"
11 #include "TRandom.h"
12 #include "TFile.h"
13 
14 //=============================================
15 //======= TFCS2DFunctionHistogram =========
16 //=============================================
17 
19  Int_t nbinsx = hist->GetNbinsX();
20  Int_t nbinsy = hist->GetNbinsY();
21  Int_t nbins = nbinsx * nbinsy;
22 
23  float integral = 0;
24  m_HistoBorders.resize(nbinsx + 1);
25  m_HistoBordersy.resize(nbinsy + 1);
26  m_HistoContents.resize(nbins);
27  int ibin = 0;
28  for (int iy = 1; iy <= nbinsy; iy++) {
29  for (int ix = 1; ix <= nbinsx; ix++) {
30  float binval = hist->GetBinContent(ix, iy);
31  if (binval < 0) {
32  // Can't work if a bin is negative, forcing bins to 0 in this case
33  double fraction = binval / hist->Integral();
34  if (TMath::Abs(fraction) > 1e-5) {
35  ATH_MSG_WARNING("bin content is negative in histogram "
36  << hist->GetName() << " : " << hist->GetTitle()
37  << " binval=" << binval << " " << fraction * 100
38  << "% of integral=" << hist->Integral()
39  << ". Forcing bin to 0.");
40  }
41  binval = 0;
42  }
43  integral += binval;
44  m_HistoContents[ibin] = integral;
45  ++ibin;
46  }
47  }
48  if (integral <= 0) {
49  ATH_MSG_ERROR("histogram " << hist->GetName() << " : " << hist->GetTitle()
50  << " integral=" << integral << " is <=0");
51  m_HistoBorders.resize(0);
52  m_HistoBordersy.resize(0);
53  m_HistoContents.resize(0);
54  return;
55  }
56 
57  for (int ix = 1; ix <= nbinsx; ix++)
58  m_HistoBorders[ix - 1] = hist->GetXaxis()->GetBinLowEdge(ix);
59  m_HistoBorders[nbinsx] = hist->GetXaxis()->GetXmax();
60 
61  for (int iy = 1; iy <= nbinsy; iy++)
62  m_HistoBordersy[iy - 1] = hist->GetYaxis()->GetBinLowEdge(iy);
63  m_HistoBordersy[nbinsy] = hist->GetYaxis()->GetXmax();
64 
65  for (ibin = 0; ibin < nbins; ++ibin)
66  m_HistoContents[ibin] /= integral;
67 }
68 
69 void TFCS2DFunctionHistogram::rnd_to_fct(float &valuex, float &valuey,
70  float rnd0, float rnd1) const {
71  if (m_HistoContents.empty()) {
72  valuex = 0;
73  valuey = 0;
74  return;
75  }
76  auto it =
77  std::upper_bound(m_HistoContents.begin(), m_HistoContents.end(), rnd0);
78  int ibin = std::distance(m_HistoContents.begin(), it);
79  if (ibin >= (int)m_HistoContents.size())
80  ibin = m_HistoContents.size() - 1;
81  Int_t nbinsx = m_HistoBorders.size() - 1;
82  Int_t biny = ibin / nbinsx;
83  Int_t binx = ibin - nbinsx * biny;
84 
85  float basecont = 0;
86  if (ibin > 0)
87  basecont = m_HistoContents[ibin - 1];
88 
89  float dcont = m_HistoContents[ibin] - basecont;
90  if (dcont > 0) {
91  valuex = m_HistoBorders[binx] +
92  (m_HistoBorders[binx + 1] - m_HistoBorders[binx]) *
93  (rnd0 - basecont) / dcont;
94  } else {
95  valuex = m_HistoBorders[binx] +
96  (m_HistoBorders[binx + 1] - m_HistoBorders[binx]) / 2;
97  }
98  valuey = m_HistoBordersy[biny] +
99  (m_HistoBordersy[biny + 1] - m_HistoBordersy[biny]) * rnd1;
100 }
101 
102 void TFCS2DFunctionHistogram::unit_test ATLAS_NOT_THREAD_SAFE(TH2 *hist) {
104  int nbinsx;
105  int nbinsy;
106  if (hist == nullptr) {
107  // hist=new TH2F("test2D","test2D",5,0,5,5,0,10);
108  nbinsx = 64;
109  nbinsy = 64;
110  hist = new TH2F("test2D", "test2D", nbinsx, 0, 1, nbinsy, 0, 1);
111  hist->Sumw2();
112  for (int ix = 1; ix <= nbinsx; ++ix) {
113  for (int iy = 1; iy <= nbinsy; ++iy) {
114  hist->SetBinContent(ix, iy,
115  (0.5 + gRandom->Rndm()) * (nbinsx + ix) *
116  (nbinsy * nbinsy / 2 + iy * iy));
117  if (gRandom->Rndm() < 0.1)
118  hist->SetBinContent(ix, iy, 0);
119  hist->SetBinError(ix, iy, 0);
120  }
121  }
122  }
124  nbinsx = hist->GetNbinsX();
125  nbinsy = hist->GetNbinsY();
126 
127  float value[2];
128  float rnd[2];
129  //cppcheck-suppress uninitvar
130  for (rnd[0] = 0; rnd[0] < 0.9999; rnd[0] += 0.25) {
131  for (rnd[1] = 0; rnd[1] < 0.9999; rnd[1] += 0.25) {
132  rtof.rnd_to_fct(value, rnd);
133  ATH_MSG_NOCLASS(logger, "rnd0=" << rnd[0] << " rnd1=" << rnd[1]
134  << " -> x=" << value[0]
135  << " y=" << value[1]);
136  }
137  }
138 
139  // TH2F* hist_val=new
140  // TH2F("val2D","val2D",16,hist->GetXaxis()->GetXmin(),hist->GetXaxis()->GetXmax(),
141  // 16,hist->GetYaxis()->GetXmin(),hist->GetYaxis()->GetXmax());
142  TH2F *hist_val = (TH2F *)hist->Clone("hist_val");
143  hist_val->Reset();
144  int nrnd = 100000000;
145  float weight = hist->Integral() / nrnd;
146  hist_val->Sumw2();
147  for (int i = 0; i < nrnd; ++i) {
148  rnd[0] = gRandom->Rndm();
149  rnd[1] = gRandom->Rndm();
150  rtof.rnd_to_fct(value, rnd);
151  hist_val->Fill(value[0], value[1], weight);
152  }
153  hist_val->Add(hist, -1);
154 
155  TH1F *hist_pull = new TH1F("pull", "pull", 80, -4, 4);
156  for (int ix = 1; ix <= nbinsx; ++ix) {
157  for (int iy = 1; iy <= nbinsy; ++iy) {
158  float val = hist_val->GetBinContent(ix, iy);
159  float err = hist_val->GetBinError(ix, iy);
160  if (err > 0)
161  hist_pull->Fill(val / err);
162  ATH_MSG_NOCLASS(logger, "val=" << val << " err=" << err);
163  }
164  }
165 
166  std::unique_ptr<TFile> outputfile(
167  TFile::Open("TFCS2DFunctionHistogram_unit_test.root", "RECREATE"));
168  if (outputfile != nullptr) {
169  hist->Write();
170  hist_val->Write();
171  hist_pull->Write();
172  outputfile->ls();
173  outputfile->Close();
174  }
175 
176 // Screen output in athena won't make sense and would require linking of
177 // additional libraries
178 #if defined(__FastCaloSimStandAlone__)
179  new TCanvas("input", "Input");
180  hist->Draw("colz");
181 
182  new TCanvas("validation", "Validation");
183  hist_val->Draw("colz");
184 
185  new TCanvas("pull", "Pull");
186  hist_pull->Draw();
187 #endif
188 }
ATLAS_NOT_THREAD_SAFE
void TFCS2DFunctionHistogram::unit_test ATLAS_NOT_THREAD_SAFE(TH2 *hist)
Definition: TFCS2DFunctionHistogram.cxx:102
ISF_FCS::MLogging
Cut down AthMessaging.
Definition: MLogging.h:176
integral
double integral(TH1 *h)
Definition: computils.cxx:57
TH2F
Definition: rootspy.cxx:420
plotmaker.hist
hist
Definition: plotmaker.py:148
skel.it
it
Definition: skel.GENtoEVGEN.py:423
TFCS2DFunctionHistogram::m_HistoContents
std::vector< float > m_HistoContents
Definition: TFCS2DFunctionHistogram.h:47
athena.value
value
Definition: athena.py:122
TFCS2DFunctionHistogram
Definition: TFCS2DFunctionHistogram.h:15
TFCS2DFunctionHistogram::Initialize
void Initialize(TH2 *hist)
Definition: TFCS2DFunctionHistogram.cxx:18
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:200
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
outputfile
ofstream outputfile
Definition: CellClusterLinkTool.h:25
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:193
lumiFormat.i
int i
Definition: lumiFormat.py:92
TH2
Definition: rootspy.cxx:373
TH2F::GetBinContent
double GetBinContent(int) const
Definition: rootspy.cxx:425
TFCS2DFunctionHistogram::rnd_to_fct
virtual void rnd_to_fct(float &valuex, float &valuey, float rnd0, float rnd1) const
Definition: TFCS2DFunctionHistogram.cxx:69
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
ATH_MSG_NOCLASS
#define ATH_MSG_NOCLASS(logger_name, x)
Definition: MLogging.h:52
TH1F
Definition: rootspy.cxx:320
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
TFCS2DFunctionHistogram.h
TFCS2DFunctionHistogram::m_HistoBorders
std::vector< float > m_HistoBorders
Definition: TFCS2DFunctionHistogram.h:45
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
python.iconfTool.gui.pad.logger
logger
Definition: pad.py:14
TFCS2DFunctionHistogram::m_HistoBordersy
std::vector< float > m_HistoBordersy
Definition: TFCS2DFunctionHistogram.h:46