ATLAS Offline Software
Loading...
Searching...
No Matches
TFCS2DFunction.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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#include <cmath>
14#include <iostream>
15
16//=============================================
17//======= TFCS2DFunction =========
18//=============================================
19
20void 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 (std::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
76TH2 *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
92void 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
169void TFCS2DFunction::unit_tests
170ATLAS_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];
176 tests[0] = new TFCS2DFunctionHistogram(hist);
177 tests[1] = new TFCS2DFunctionInt8Int8Int8Histogram(hist);
178 tests[2] = new TFCS2DFunctionInt8Int8Int16Histogram(hist);
179 tests[3] = new TFCS2DFunctionInt8Int8Int32Histogram(hist);
180
181 for (int i = 0; i < ntest; ++i) {
182 unit_test(hist, tests[i], outfilename, nrnd);
183 }
184}
ofstream outputfile
static TRandom * rnd
#define ATH_MSG_NOCLASS(logger_name, x)
Definition MLogging.h:52
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
Cut down AthMessaging.
Definition MLogging.h:176
static double CheckAndIntegrate2DHistogram(const TH2 *hist, std::vector< double > &integral_vec, int &first, int &last)
virtual void rnd_to_fct(float &valuex, float &valuey, float rnd0, float rnd1) const =0
double integral(TH1 *h)
Definition computils.cxx:59
static Root::TMsgLogger logger("iLumiCalc")