ATLAS Offline Software
Loading...
Searching...
No Matches
generate.cxx
Go to the documentation of this file.
1
9
10
11#include <cmath>
12#include <vector>
13#include <string>
14#include <iostream>
15
16#include "TFile.h"
17#include "TH1D.h"
18#include "TPad.h"
19#include "TStyle.h"
20
21
22
23#include "BasicRandom.h"
24
25#include "generate.h"
26#include "rmsFrac.h"
27
28namespace generate {
29
30static const bool printPad = false;
31
32void Zero(TH1D* hin) {
33 for ( int i=0 ; i<=hin->GetNbinsX()+1 ; i++ ) {
34 hin->SetBinContent(i, 0);
35 hin->SetBinError(i, 0);
36 }
37}
38
39
40double Entries(TH1D* hin) {
41 double N = 0;
42 for ( int i=1 ; i<=hin->GetNbinsX() ; i++ ) N += hin->GetBinContent(i);
43 return N;
44}
45
46
47double get_mean( const std::vector<double>& m ) {
48 double mean = 0;
49 for ( unsigned i=0 ; i<m.size() ; i++ ) mean += m[i];
50 return mean/m.size();
51}
52
53
54double get_rms( const std::vector<double>& m ) {
55 double mean = get_mean( m );
56 double rms = 0;
57 for ( unsigned i=0 ; i<m.size() ; i++ ) {
58 double r = (m[i]-mean);
59 rms += r*r;
60 }
61 return std::sqrt( rms/m.size() );
62}
63
64
65
66
67
68TH1D* integrate( TH1D* hin ) {
69
70 TH1D* hint = (TH1D*)hin->Clone( (std::string(hin->GetName())+"-cumulative").c_str() );
71
72 Zero(hint);
73
74 hint->SetBinContent(0,0);
75 hint->SetBinContent(hin->GetNbinsX()+1,0);
76
77 for ( int i=1 ; i<=hin->GetNbinsX()+1 ; i++ ) {
78 double c = hin->GetBinContent(i) + hint->GetBinContent(i-1);
79 hint->SetBinContent(i, c);
80 hint->SetBinError(i, std::sqrt(c) );
81 }
82
83 hint->SetBinContent(hin->GetNbinsX()+1, hint->GetBinContent(hin->GetNbinsX()) );
84
85 return hint;
86}
87
88
89
90
91
92void ScaleIntegral(TH1D* hin ) {
93
94 double N = hin->GetBinContent(hin->GetNbinsX());
95
96 for ( int i=0 ; i<=hin->GetNbinsX()+1 ; i++ ) {
97
98 double n = hin->GetBinContent(i);
99
100 double e = n/N;
101
102 double ee = std::sqrt(e*(1-e)/N);
103
104 hin->SetBinContent(i, e);
105 hin->SetBinError(i, ee);
106 }
107}
108
109
110
111
112TH1D* PDF(TH1D* hin) {
113 TH1D* h = integrate( hin );
114 h->SetDirectory(0);
115 ScaleIntegral( h );
116 return h;
117}
118
119
120
121double Gradient(TH1D* hin) {
122 double gmax = 0;
123 double imax = 0;
124 for ( int i=2 ; i<hin->GetNbinsX() ; i++ ) {
125 double g = hin->GetBinContent(i+1)-hin->GetBinContent(i-1);
126 if ( std::fabs(gmax)<std::fabs(g) ) {
127 gmax = g;
128 imax = i;
129 }
130 }
131 return gmax/hin->GetBinError(imax);
132}
133
134
135
136int iGradient(TH1D* hin) {
137 double gmax = 0;
138 double imax = 0;
139 for ( int i=2 ; i<hin->GetNbinsX() ; i++ ) {
140 double g = hin->GetBinContent(i+1)-hin->GetBinContent(i-1);
141 if ( std::fabs(gmax)<std::fabs(g) ) {
142 gmax = g;
143 imax = i;
144 }
145 }
146 return imax;
147}
148
149
150
151
152
153
154
155
158TH1D* smooth( TH1D* hin, bool sym ) {
159
160 TH1D* hsmooth = (TH1D*)hin->Clone( (std::string(hin->GetName())+"-smooth").c_str() );
161 hsmooth->SetDirectory(0);
162
163 Zero( hsmooth );
164
165 // double _w[5] = { -3, 12, 17, 12, -3 };
166 // double w[7] = { -2, 3, 6, 7, 6, 3, -2 };
167 // double _w[11] = { -36, 9, 44, 69, 84, 89, 84, 69, 44, 9, -36 };
168 // double* w = _w+5;
169
170 double mg = 0;
171 int img = 0;
172
173 if ( sym ) {
174
175 TH1D* hint = integrate( hin ) ;
176 hint->SetDirectory(0);
177
178 for ( int i=2 ; i<hsmooth->GetNbinsX() ; i++ ) {
179 double gradient = std::fabs(0.5*(hint->GetBinContent(i+1) - hint->GetBinContent(i-1)));
180 if ( gradient>mg ) {
181 mg = gradient;
182 img = i;
183 }
184 }
185
186 delete hint;
187
188 }
189
190 // double sfac = std::sqrt(Entries(hin)/1000)*0.1;
191 const double sfac = 0.1;
192
193 // std::cout << "max gradient " << img << " " << mg << std::endl;
194
195 for ( int i=1 ; i<=hsmooth->GetNbinsX() ; i++ ) {
196
198 int Nbins = 2*sfac*std::fabs( i-img );
199
200 // Nbins = 0;
201
202 // std::cout << "bin " << i << "\tn " << Nbins << std::endl;
203
204 double sum = 0;
205 int wsum = 0;
206
207 for ( int j=i-Nbins ; j<=i+Nbins ; j++ ) {
208 if ( j<1 ) continue;
209 if ( j>hin->GetNbinsX() ) break;
210 sum += hin->GetBinContent(j);
211 wsum += 1;
212 }
213
214 if ( wsum>0 ) sum /= wsum;
215
216 // std::cout << i << " smoothed " << sum << " " << hin->GetBinContent(i) << std::endl;
217
218 hsmooth->SetBinContent(i, sum);
219 hsmooth->SetBinError(i, 0 );
220
221 }
222
223 return hsmooth;
224
225}
226
227
228
229
230
231 hist_generator::hist_generator(TH1D* h, bool smooth_ ) : m_random(0) {
232
234 m_raw = h;
235
236 if ( smooth_ ) {
238 m_smooth = smooth( h );
239 }
240 else {
242 m_smooth = (TH1D*)h->Clone( (std::string(h->GetName())+"-smooth").c_str() );
243 m_smooth->SetDirectory(0);
244 }
245
246
248 m_s = PDF( m_smooth );
249 delete m_smooth;
250
251 m_s->SetMinimum(0);
252 m_s->SetMaximum(1);
253
254 m_y.push_back( 0 );
255 m_x.push_back( m_s->GetBinLowEdge(1) );
256
257
258 for ( int i=1 ; i<=m_s->GetNbinsX() ; i++ ) {
259 m_x.push_back( m_s->GetBinLowEdge(i+1) );
260 m_y.push_back( m_s->GetBinContent(i) );
261 }
262
263 m_dy.resize(m_x.size());
264 m_dx.resize(m_x.size());
265 m_dxdy.resize(m_x.size());
266
267 // std::cout << "calculating gradients ..." << std::endl;
268
269 for ( unsigned i=0 ; i<m_y.size()-1 ; i++ ) {
270 double dy = m_y[i+1] - m_y[i];
271 double dx = m_x[i+1] - m_x[i];
272
273 double dxdy = dx/dy;
274
275 m_dy[i] = dy;
276 m_dx[i] = dx;
277 m_dxdy[i] = dxdy;
278 }
279
282 m_random = new BasicRandom(true);
285
286}
287
288
289
290
291
293int Nevent_max = 5000;
294
295const double frac = 0.95;
296
301
302experiment::experiment( TH1D* h, int Nexperiments, int fevents )
303 : m_N(Nexperiments) {
304
305 std::vector<double>& mean = m_mean;
306 std::vector<double>& rms = m_rms;
307
308 mean.clear();
309 rms.clear();
310
311 double fnscale = 1;
312
313#if 0
314 std::cout << "mean " << h->GetMean() << " +- " << h->GetMeanError() << " (" << findMean(h,0.95) << ")"
315 << "\trms " << h->GetRMS() << " +- " << h->GetRMSError() << " (" << rms95(h) << ")"
316 << "\thistogram" << std::endl;
317#endif
318
319 // std::cout << "experiment() actual histogram " << std::endl;
320
321 // m_hmean = h->GetMean();
322 // m_hrms = rms95(h, findMean(h,0.95) );
325 // m_hrms = rms95(h, m_hmean );
326
327 // std::cout << "central mean " << m_hmean << "\trms95 " << m_hrms << std::endl;
328
329 h->GetXaxis()->SetRange(1,h->GetNbinsX());
330
331 m_gen = new hist_generator( h );
332 generator_base& g = *m_gen;
333
334
335
336 // int Nevents = Entries(h);
337 int Nevents = h->GetEffectiveEntries()+0.5; // Entries(h);
338
339 // std::cout << "Nevents " << Nevents << "\tfevents " << fevents << std::endl;
340
341 if ( fevents!=0 ) Nevents = fevents;
342
343
344 // std::cout << "Nevents: " << Entries(h) << "\tweights: " << Nevents << " ( max " << Nevent_max << " min " << Nevent_min << ")"; // << std::endl;
345
353
354 double Nevents_ = Nevents;
355
356 if ( Nevents>Nevent_max ) {
358 Nevents = Nevent_max;
359 }
360
361 if ( Nevents<Nevent_min ) Nevents = Nevent_min;
362
364 fnscale = std::sqrt( Nevents/Nevents_ );
365
366 // std::cout << "\tusing: " << Nevents << std::endl;
367
368 TH1D* hmean = 0;
369 TH1D* hrms = 0;
370
371 if ( printPad ) {
372 gStyle->SetOptStat(1111);
373 hmean = new TH1D("mean", "", 500, -0.001, 0.001);
374 hrms = new TH1D("rms", "", 500, 0.001, 0.01);
375 hmean->SetDirectory(0);
376 hrms->SetDirectory(0);
377 }
378
379 // std::cout << "experiment() pseudo data " << std::endl;
380
382
383 m_THrms = new TH1D("rms95", "", 50, 0.0006, 0.0009 );
384 m_THrms->SetDirectory(0);
385
386 for ( int j=0 ; j<m_N ; j++ ) {
387
388 TH1D* h3 = (TH1D*)h->Clone();
389 Zero( h3 );
390
391 for ( int i=Nevents ; i-- ; ) h3->Fill( g.generate() );
392
393 double mean95_ = findMean( h3, frac );
394 // double _rms95 = 1.1479538518*rmsFrac( h3, 0.95, mean95_ );
395 double rms95_ = rmsFrac( h3, frac, mean95_ );
396
397
398#if 0
399 std::cout << j << "\texpt mean " << mean95_ << "\trms95 " << rms95_ << std::endl;
400
401 if ( std::string(h->GetTitle()).find("[ 34.4747 - 42.1697 ]")!=std::string::npos ) {
402
403 std::cout << "mean " << h3->GetMean() << " +- " << h3->GetMeanError()
404 << " (" << mean95_ << ") "
405 << "\trms " << h3->GetRMS() << " +- " << h3->GetRMSError()
406 << " (" << rms95_ << ") "
407 << "\t pseudo data (" << Nevents << " events)"
408 << std::endl;
409 }
410
411#endif
412
413
414 // mean.push_back( h3->GetMean() );
415 mean.push_back( mean95_ );
416 rms.push_back( rms95_ );
417
418 m_THrms->Fill( rms95_ );
419
420 delete h3;
421 }
422
423 // std::cout << "averages" << std::endl;
424
425#if 0
426 if ( std::string(h->GetTitle()).find("[ 34.4747 - 42.1697 ]")!=std::string::npos ) {
428 std::cout << "mean " << h->GetMean() << " +- " << h->GetMeanError() << " (" << findMean(h,0.95) << ")"
429 << "\trms " << h->GetRMS() << " +- " << h->GetRMSError() << " (" << rms95(h) << ")"
430 << "\thistogram" << std::endl;
431
433 std::cout << "mean " << get_mean(mean) << " +- " << get_rms(mean);
434 std::cout << "\trms " << get_mean(rms) << " +- " << get_rms(rms)
435 << " after " << Nexperiments << " experiment" << ( Nexperiments==1 ? "" : "s" )
436 << std::endl;
437 }
438#endif
439
442
444 m_global_rms_error = get_rms(rms)*fnscale;
445 delete m_gen;
446
447
448 // std::cout << "\t\t mean " << m_global_mean << " +- " << m_global_mean_error
449 // << "\t mean " << m_global_rms << " +- " << m_global_rms_error
450 // << std::endl;
451
452}
453
454} // namespace generate
455
a Randomnumber generator with a data member TRandom3 so that we can either use a shared generator or ...
int imax(int i, int j)
Header file for AthHistogramAlgorithm.
double mean() const
Definition generate.h:143
double rms() const
Definition generate.h:146
std::vector< double > m_mean
number of experiments
Definition generate.h:157
double m_global_mean_error
Definition generate.h:165
experiment(TH1D *h, int Nexperiments=10, int fevents=0)
given a distribution, gnerate some number of pseudo experiments to estimate the uncertainties in the ...
Definition generate.cxx:302
double hmean() const
Definition generate.h:140
double hrms() const
Definition generate.h:141
double m_hmean
rms from each experiment
Definition generate.h:160
generator_base * m_gen
Definition generate.h:170
double m_global_rms_error
Definition generate.h:168
double m_hrms
actual histogram mean95
Definition generate.h:161
double m_global_mean
actual histogram rms95
Definition generate.h:164
std::vector< double > m_rms
means from each experiment
Definition generate.h:158
base class for a "generator" class
Definition generate.h:46
generate a distribution according to an input histogram (after smoothing)
Definition generate.h:72
std::vector< double > m_y
Definition generate.h:108
std::vector< double > m_x
Definition generate.h:109
BasicRandom * m_random
Definition generate.h:121
std::vector< double > m_dy
Definition generate.h:113
hist_generator(TH1D *h, bool smooth_=true)
Definition generate.cxx:231
std::vector< double > m_dxdy
Definition generate.h:115
std::vector< double > m_dx
Definition generate.h:112
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="")
int r
Definition globals.cxx:22
TH1D * smooth(TH1D *hin, bool sym)
smooth a distribution about the maximum NB: maximum is not smoothed
Definition generate.cxx:158
void Zero(TH1D *hin)
Definition generate.cxx:32
TH1D * integrate(TH1D *hin)
generate an integrated distribution
Definition generate.cxx:68
void ScaleIntegral(TH1D *hin)
scale a distribution by the integral
Definition generate.cxx:92
double Entries(TH1D *hin)
Definition generate.cxx:40
int iGradient(TH1D *hin)
Definition generate.cxx:136
TH1D * PDF(TH1D *hin)
generate a (normalised) pdf from a distribution
Definition generate.cxx:112
int Nevent_min
Definition generate.cxx:292
const double frac
Definition generate.cxx:295
int Nevent_max
Definition generate.cxx:293
double get_rms(const std::vector< double > &m)
Definition generate.cxx:54
double rms95(TH1D *s, double mean)
get the fraction of the rms95 value with respect to the rms95 value of a gaussian
Definition rmsFrac.cxx:285
double findMean(TH1D *s, double frac=0.95)
Definition rmsFrac.cxx:84
double get_mean(const std::vector< double > &m)
mean and rms
Definition generate.cxx:47
double Gradient(TH1D *hin)
Definition generate.cxx:121
double rmsFrac(TH1D *s, double frac, double mean)
Definition rmsFrac.cxx:193
static const bool printPad
Definition generate.cxx:30