ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Simulation
ISF
ISF_FastCaloSim
ISF_FastCaloSimEvent
src
TFCS1DFunctionHistogram.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
ISF_FastCaloSimEvent/TFCS1DFunctionHistogram.h
"
6
#include "TMath.h"
7
#include "TFile.h"
8
#include <iostream>
9
10
using namespace
std
;
11
12
//=============================================
13
//======= TFCS1DFunctionHistogram =========
14
//=============================================
15
16
TFCS1DFunctionHistogram::TFCS1DFunctionHistogram
(TH1 *hist,
double
cut_maxdev) {
17
Initialize
(hist, cut_maxdev);
18
}
19
20
void
TFCS1DFunctionHistogram::Initialize
(TH1 *hist,
double
cut_maxdev) {
21
smart_rebin_loop
(hist, cut_maxdev);
22
}
23
24
std::unique_ptr<double[]>
25
TFCS1DFunctionHistogram::histo_to_array
(TH1 *hist) {
26
27
TH1D *h_clone = (TH1D *)hist->Clone(
"h_clone"
);
28
h_clone->Scale(1.0 / h_clone->Integral());
29
30
auto
histoVals = std::make_unique<double[]>(h_clone->GetNbinsX());
31
histoVals[0] = h_clone->GetBinContent(1);
32
for
(
int
i = 1; i < h_clone->GetNbinsX(); i++) {
33
histoVals[i] = histoVals[i - 1] + h_clone->GetBinContent(i + 1);
34
}
35
delete
h_clone;
36
return
histoVals;
37
}
38
39
double
TFCS1DFunctionHistogram::sample_from_histo
(TH1 *hist,
double
random) {
40
41
auto
histoVals =
histo_to_array
(hist);
42
double
value = 0.0;
43
int
chosenBin =
44
(int)TMath::BinarySearch(hist->GetNbinsX(), histoVals.get(), random);
45
value = hist->GetBinCenter(chosenBin + 2);
46
47
// cleanup
48
49
return
value;
50
}
51
52
double
TFCS1DFunctionHistogram::sample_from_histovalues
(
double
random) {
53
double
value = 0.0;
54
55
TH1 *hist =
vector_to_histo
();
56
hist->SetName(
"hist"
);
57
auto
histoVals =
histo_to_array
(hist);
58
int
chosenBin =
59
(int)TMath::BinarySearch(hist->GetNbinsX(), histoVals.get(), random);
60
value = hist->GetBinCenter(chosenBin + 2);
61
62
return
value;
63
}
64
65
TH1 *
TFCS1DFunctionHistogram::vector_to_histo
() {
66
67
double
*
bins
=
new
double
[
m_HistoBorders
.size()];
68
for
(
unsigned
int
i = 0; i <
m_HistoBorders
.size(); i++)
69
bins
[i] =
m_HistoBorders
[i];
70
71
TH1 *h_out =
new
TH1D(
"h_out"
,
"h_out"
,
m_HistoBorders
.size() - 1,
bins
);
72
for
(
int
b = 1; b <= h_out->GetNbinsX(); b++)
73
h_out->SetBinContent(b,
m_HistoContents
[b - 1]);
74
75
delete
[]
bins
;
76
77
return
h_out;
78
}
79
80
void
TFCS1DFunctionHistogram::smart_rebin_loop
(TH1 *hist,
double
cut_maxdev) {
81
82
m_HistoContents
.clear();
83
m_HistoBorders
.clear();
84
85
double
change =
86
get_change
(hist) * 1.000001;
// increase slighlty for comparison of floats
87
88
double
maxdev = -1;
89
90
TH1D *h_input = (TH1D *)hist->Clone(
"h_input"
);
91
TH1D *h_output =
nullptr
;
92
93
int
i = 0;
94
while
(1) {
95
96
TH1D *h_out;
97
if
(i == 0) {
98
h_out = (TH1D *)h_input->Clone(
"h_out"
);
99
}
else
{
100
h_out =
smart_rebin
(h_input);
101
h_out->SetName(
"h_out"
);
102
}
103
104
maxdev =
get_maxdev
(hist, h_out);
105
maxdev *= 100.0;
106
107
if
(i % 100 == 0)
108
ATH_MSG_INFO
(
"Iteration nr. "
<< i <<
" -----> change "
<< change
109
<<
" bins "
<< h_out->GetNbinsX()
110
<<
" -> maxdev="
<< maxdev);
111
112
if
(maxdev < cut_maxdev && h_out->GetNbinsX() > 5 && i < 1000) {
113
delete
h_input;
114
h_input = (TH1D *)h_out->Clone(
"h_input"
);
115
change =
get_change
(h_input) * 1.000001;
116
delete
h_out;
117
i++;
118
}
else
{
119
h_output = (TH1D *)h_input->Clone(
"h_output"
);
120
delete
h_out;
121
break
;
122
}
123
}
124
125
ATH_MSG_INFO
(
"Info: Rebinned histogram has "
<< h_output->GetNbinsX()
126
<<
" bins."
);
127
128
// store:
129
130
for
(
int
b = 1; b <= h_output->GetNbinsX(); b++)
131
m_HistoBorders
.push_back((
float
)h_output->GetBinLowEdge(b));
132
m_HistoBorders
.push_back((
float
)h_output->GetXaxis()->GetXmax());
133
134
for
(
int
b = 1; b < h_output->GetNbinsX(); b++)
135
m_HistoContents
.push_back(h_output->GetBinContent(b));
136
m_HistoContents
.push_back(1);
137
}
138
139
double
TFCS1DFunctionHistogram::get_maxdev
(TH1 *h_in, TH1D *h_out) {
140
141
double
maxdev = 0;
142
for
(
int
i = 1; i <= h_in->GetNbinsX(); i++) {
143
int
bin
= h_out->FindBin(h_in->GetBinCenter(i));
144
double
val = fabs(h_out->GetBinContent(
bin
) - h_in->GetBinContent(i));
145
if
(val > maxdev)
146
maxdev = val;
147
}
148
return
maxdev;
149
}
150
151
double
TFCS1DFunctionHistogram::get_change
(TH1 *histo) {
152
// return the smallest change between 2 bin contents, but don't check the last
153
// bin, because that one never gets merged
154
double
minchange = 100.0;
155
for
(
int
b = 2; b < histo->GetNbinsX(); b++) {
156
double
diff
= histo->GetBinContent(b) - histo->GetBinContent(b - 1);
157
if
(
diff < minchange && diff >
0)
158
minchange =
diff
;
159
}
160
161
return
minchange;
162
}
163
164
TH1D *
TFCS1DFunctionHistogram::smart_rebin
(TH1D *h_input) {
165
166
TH1D *h_out1 = (TH1D *)h_input->Clone(
"h_out1"
);
167
168
// get the smallest change
169
double
change =
get_change
(h_out1) * 1.00001;
170
171
vector<double> content;
172
vector<double> binborder;
173
174
binborder.push_back(h_out1->GetXaxis()->GetXmin());
175
176
int
merged = 0;
177
int
skip
= 0;
178
int
secondlastbin_merge = 0;
179
for
(
int
b = 1; b < h_out1->GetNbinsX() - 1; b++)
// never touch the last bin
180
{
181
double
thisBin = h_out1->GetBinContent(b);
182
double
nextBin = h_out1->GetBinContent(b + 1);
183
double
width
= h_out1->GetBinWidth(b);
184
double
nextwidth = h_out1->GetBinWidth(b + 1);
185
double
diff
= fabs(nextBin - thisBin);
186
if
(!
skip
&& (
diff
> change || merged)) {
187
binborder.push_back(h_out1->GetBinLowEdge(b + 1));
188
content.push_back(thisBin);
189
}
190
skip
= 0;
191
if
(
diff
<= change && !merged) {
192
double
sum = thisBin *
width
+ nextBin * nextwidth;
193
double
sumwidth =
width
+ nextwidth;
194
binborder.push_back(h_out1->GetBinLowEdge(b + 2));
195
content.push_back(sum / sumwidth);
196
merged = 1;
197
skip
= 1;
198
if
(b == (h_out1->GetNbinsX() - 2))
199
secondlastbin_merge = 1;
200
}
201
}
// for b
202
if
(!secondlastbin_merge) {
203
binborder.push_back(h_out1->GetBinLowEdge(h_out1->GetNbinsX()));
204
content.push_back(h_out1->GetBinContent(h_out1->GetNbinsX() - 1));
205
}
206
binborder.push_back(h_out1->GetXaxis()->GetXmax());
207
content.push_back(h_out1->GetBinContent(h_out1->GetNbinsX()));
208
209
double
*
bins
=
new
double
[content.size() + 1];
210
for
(
unsigned
int
i = 0; i < binborder.size(); i++)
211
bins
[i] = binborder[i];
212
213
TH1D *h_out2 =
new
TH1D(
"h_out2"
,
"h_out2"
, content.size(),
bins
);
214
for
(
unsigned
int
b = 1; b <= content.size(); b++)
215
h_out2->SetBinContent(b, content[b - 1]);
216
217
delete
[]
bins
;
218
delete
h_out1;
219
220
return
h_out2;
221
}
222
223
double
TFCS1DFunctionHistogram::rnd_to_fct
(
double
rnd
)
const
{
224
225
double
value2 =
get_inverse
(
rnd
);
226
227
return
value2;
228
}
229
230
double
TFCS1DFunctionHistogram::linear
(
double
y1,
double
y2,
double
x1,
231
double
x2,
double
y
) {
232
double
x
= -1;
233
234
double
eps = 0.0000000001;
235
if
((y2 - y1) < eps)
236
x
= x1;
237
else
{
238
double
m = (y2 - y1) / (x2 - x1);
239
double
n = y1 - m * x1;
240
x
= (
y
- n) / m;
241
}
242
243
return
x
;
244
}
245
246
double
TFCS1DFunctionHistogram::non_linear
(
double
y1,
double
y2,
double
x1,
247
double
x2,
double
y
) {
248
double
x
= -1;
249
double
eps = 0.0000000001;
250
if
((y2 - y1) < eps)
251
x
= x1;
252
else
{
253
double
b = (x1 - x2) / (sqrt(y1) - sqrt(y2));
254
double
a
= x1 - b * sqrt(y1);
255
x
=
a
+ b * sqrt(
y
);
256
}
257
return
x
;
258
}
259
260
double
TFCS1DFunctionHistogram::get_inverse
(
double
rnd
)
const
{
261
262
double
value = 0.;
263
264
if
(
rnd
<
m_HistoContents
[0]) {
265
double
x1 =
m_HistoBorders
[0];
266
double
x2 =
m_HistoBorders
[1];
267
double
y1 = 0;
268
double
y2 =
m_HistoContents
[0];
269
double
x
=
non_linear
(y1, y2, x1, x2,
rnd
);
270
value =
x
;
271
}
else
{
272
// find the first HistoContent element that is larger than rnd:
273
vector<float>::const_iterator larger_element =
274
std::upper_bound(
m_HistoContents
.begin(),
m_HistoContents
.end(),
rnd
);
275
size_t
index
= larger_element -
m_HistoContents
.begin();
276
if
(
index
>=
m_HistoContents
.size()) {
277
--
index
;
278
}
279
double
y
=
m_HistoContents
[
index
];
280
double
x1 =
m_HistoBorders
[
index
];
281
double
x2 =
m_HistoBorders
[
index
+ 1];
282
double
y1 =
m_HistoContents
[
index
- 1];
283
double
y2 =
y
;
284
if
((
index
+ 1) == (
m_HistoContents
.size() - 1)) {
285
x2 =
m_HistoBorders
[
m_HistoBorders
.size() - 1];
286
y2 =
m_HistoContents
[
m_HistoContents
.size() - 1];
287
}
288
double
x
=
non_linear
(y1, y2, x1, x2,
rnd
);
289
value =
x
;
290
}
291
292
return
value;
293
}
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition
AthMsgStreamMacros.h:31
a
static Double_t a
Definition
LArPhysWaveHECTool.cxx:38
rnd
static TRandom * rnd
Definition
LArWheelSliceSolidTests.cxx:68
bins
static const std::vector< std::string > bins
Definition
MuonTriggerSFFilesTest.cxx:22
diff
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition
Jet.cxx:631
TFCS1DFunctionHistogram.h
width
const double width
Definition
TTileTripReader.cxx:24
skip
bool skip
Definition
TrigGlobEffCorrValidation.cxx:190
y
#define y
x
#define x
TFCS1DFunctionHistogram::linear
static double linear(double y1, double y2, double x1, double x2, double x)
Definition
TFCS1DFunctionHistogram.cxx:230
TFCS1DFunctionHistogram::sample_from_histovalues
double sample_from_histovalues(double)
Definition
TFCS1DFunctionHistogram.cxx:52
TFCS1DFunctionHistogram::m_HistoBorders
std::vector< float > m_HistoBorders
Definition
TFCS1DFunctionHistogram.h:41
TFCS1DFunctionHistogram::rnd_to_fct
virtual double rnd_to_fct(double rnd) const
Function gets random number rnd in the range [0,1) as argument and returns function value.
Definition
TFCS1DFunctionHistogram.cxx:223
TFCS1DFunctionHistogram::histo_to_array
static std::unique_ptr< double[]> histo_to_array(TH1 *)
Definition
TFCS1DFunctionHistogram.cxx:25
TFCS1DFunctionHistogram::get_inverse
double get_inverse(double rnd) const
Definition
TFCS1DFunctionHistogram.cxx:260
TFCS1DFunctionHistogram::get_maxdev
static double get_maxdev(TH1 *, TH1D *)
Definition
TFCS1DFunctionHistogram.cxx:139
TFCS1DFunctionHistogram::TFCS1DFunctionHistogram
TFCS1DFunctionHistogram()
Definition
TFCS1DFunctionHistogram.h:16
TFCS1DFunctionHistogram::sample_from_histo
static double sample_from_histo(TH1 *hist, double)
Definition
TFCS1DFunctionHistogram.cxx:39
TFCS1DFunctionHistogram::Initialize
void Initialize(TH1 *hist, double)
Definition
TFCS1DFunctionHistogram.cxx:20
TFCS1DFunctionHistogram::m_HistoContents
std::vector< float > m_HistoContents
Definition
TFCS1DFunctionHistogram.h:42
TFCS1DFunctionHistogram::get_change
static double get_change(TH1 *)
Definition
TFCS1DFunctionHistogram.cxx:151
TFCS1DFunctionHistogram::non_linear
static double non_linear(double y1, double y2, double x1, double x2, double x)
Definition
TFCS1DFunctionHistogram.cxx:246
TFCS1DFunctionHistogram::vector_to_histo
TH1 * vector_to_histo()
Definition
TFCS1DFunctionHistogram.cxx:65
TFCS1DFunctionHistogram::smart_rebin_loop
void smart_rebin_loop(TH1 *hist, double)
Definition
TFCS1DFunctionHistogram.cxx:80
TFCS1DFunctionHistogram::smart_rebin
static TH1D * smart_rebin(TH1D *)
Definition
TFCS1DFunctionHistogram.cxx:164
bin
Definition
BinsDiffFromStripMedian.h:43
index
Definition
index.py:1
std
STL namespace.
Generated on
for ATLAS Offline Software by
1.17.0