hpstr
The Heavy Photon Search Toolkit for Reconstruction (hpstr) provides an interface to physics data from the HPS experiment saved in the LCIO format and converts it into an ROOT based format.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
HistogramHelpers.cxx
Go to the documentation of this file.
1//Authors: F.Sforza, PF, Alignment Team
2
3#include "HistogramHelpers.h"
4#include "TMath.h"
5
6double HistogramHelpers::GaussExpTails_f(double* x, double *par) {
7 //core Gaussian with exponential tails starting K
8 const double norm = par[0];
9 const double fracT = par[1];
10 //const double fracTL = par[1];
11 //const double fracTH = par[2];
12 const double meanG = par[2];
13 const double sigmaG = par[3];
14 const double K = par[4];
15 //const double KL = par[5];
16 //const double KH = par[6];
17
18
19 const double GFact = TMath::Sqrt(2*TMath::Pi());
20 const double GausExpNorm = (GFact*sigmaG) *
21 ( TMath::Erf( 0.70710678*K ) + exp( -K*K/2 ) * sqrt( 2/TMath::Pi() )/K);
22
23 //const double GausExpNormL = (GFact*sigmaG) *
24 //( TMath::Erf( 0.70710678*KL ) + exp( -KL*KL/2 ) * sqrt( 2/TMath::Pi() )/KL);
25
26 //const double GausExpNormH = (GFact*sigmaG) *
27 //( TMath::Erf( 0.70710678*KH ) + exp( -KH*KH/2 ) * sqrt( 2/TMath::Pi() )/KH);
28
29 //return norm*fracT/GausExpNorm*exp( -K *fabs(x[0]-meanG)/sigmaG + K*K/2) +
30 //norm*(1-fracT)/(GFact*sigmaG)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaG,2)));
31
32 //if(fabs(x[0]-meanG)> sigmaG*K) {
33 return norm*fracT/GausExpNorm*exp( -K *fabs(x[0]-meanG)/sigmaG + K*K/2) +
34 norm*(1-fracT)/(GFact*sigmaG)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaG,2)));
35 //}
36 // return norm/(GFact*sigmaG)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaG,2)));
37
38
39
40}
41
42double HistogramHelpers::twoGaussExp_f(double *x, double *par){
43 //2 core Gaussian with exponential tails starting K
44 const double norm = par[0];
45 const double fracT = par[1];
46 const double meanG = par[2];
47 const double sigmaGT = par[3];
48 const double sigmaGC = par[4];
49 const double K = par[5];
50
51 const double GFact = TMath::Sqrt(2*TMath::Pi());
52 const double GausExpNorm = (GFact*sigmaGT) *
53 ( TMath::Erf( 0.70710678*K ) + exp( -K*K/2 ) * sqrt( 2/TMath::Pi() )/K);
54
55 if(fabs(x[0]-meanG)> sigmaGT*K) {
56 return norm*fracT/GausExpNorm*exp( -K *fabs(x[0]-meanG)/sigmaGT + K*K/2) +
57 norm*(1-fracT)/(GFact*sigmaGC)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaGC,2)));
58 }
59 return norm*fracT/GausExpNorm*exp(-pow( (x[0]-meanG), 2)/(2*pow(sigmaGT,2))) +
60 norm*(1-fracT)/(GFact*sigmaGC)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaGC,2)));
61}
62
63double HistogramHelpers::twoGauss_f(double *x, double *par){
64 //two Gaussians, Tail and Core, normalized to a total integral par[0] and of tail fraction par[1]
65 const double norm = par[0];
66 const double fracT = par[1];
67 const double meanG = par[2];
68 const double sigmaGT = par[3];
69 const double sigmaGC = par[4];
70 const double GFact = TMath::Sqrt(2*TMath::Pi());
71 return
72 norm*(1-fracT)/(GFact*sigmaGC)*exp(-pow( (x[0]-meanG),2)/(2*pow(sigmaGC,2))) +
73 norm*fracT/(GFact*sigmaGT)*exp(-pow( (x[0]-meanG), 2)/(2*pow(sigmaGT,2)));
74}
75
76
77//-------------------------------------------------------------
78void HistogramHelpers::profileZwithIterativeGaussFit(TH3* hist, TH2* mu_graph, TH2* sigma_graph, int num_bins, TH2* mu_err_graph, TH2* sigma_err_graph)
79{
80 if (!hist) {
81 cout<< "ProfileZwithIterativeGaussFit(): No histogram supplied!"<<endl;
82 return;
83 }
84
85
86 int num_bins_x = hist->GetXaxis()->GetNbins();
87 int num_bins_y = hist->GetYaxis()->GetNbins();
88
89
90 int minEntries = 50;
91 int fDebug = 0;
92
93
94 double num_not_converged = 0;
95 int num_skipped = 0;
96
97 double max_sigma = 0;
98 double min_sigma = 0;
99
100 double max_mu = 0;
101 double min_mu = 0;
102
103 TH1D* current_proj;
104 if (fDebug || false) std::cout << " ** profileZwithIterativeGaussFit ** target: " << mu_graph->GetName() << " ** " << std::endl;
105
106 for (int i = 1; i < num_bins_x+(num_bins==1); i+=num_bins) {
107
108 for (int j = 1; j < num_bins_y+(num_bins==1); j+=num_bins) {
109
110 int index = i/num_bins;
111 int index_y = j/num_bins;
112
113 current_proj = hist->ProjectionZ(Form("%s_GaussProjection_%i_%i",hist->GetName(),index, index_y),i,i+num_bins-1,j,j+num_bins-1);
114 current_proj->SetTitle(Form("%s - Bin %i x %i",hist->GetName(), index,index_y));
115
116 double current_mu,current_err_mu, current_sigma, current_err_sigma;
117
118 if(current_proj->GetEntries() < minEntries) {
119 //if (m_PrintLevel >= 3) cout << " ** profileZwithIterativeGaussFit ** fitting " << hist->GetName() << " bin (" << index << ", " << index_y << ") "
120 // << " Not enough entries " << current_proj->GetEntries() << " < " << minEntries << endl;
121 //current_mu = -999;
122 current_mu = 0;
123 current_sigma = 0;
124 current_err_mu = 1;
125 current_err_sigma = 1;
126
127 if (fDebug) std::cout<<"WARNING: Only "<<current_proj->GetEntries()<<" entries in bin "<<index<<","<<index_y<< " in histogram " <<hist->GetName()<< std::endl;
128 num_skipped++;
129
130 }
131 else {
132 //if (m_PrintLevel >= 3) cout << " ** profileZwithIterativeGaussFit ** fitting " << hist->GetName()
133 // << " bin (" << index << ", " << index_y << ") "
134 // << " entries: "<< current_proj->GetEntries()
135 // << endl;
136
137 IterativeGaussFit(current_proj, current_mu, current_err_mu, current_sigma, current_err_sigma);
138
139 if (current_sigma > max_sigma || max_sigma == 0) max_sigma = current_sigma;
140 if (current_sigma < min_sigma || min_sigma == 0) min_sigma = current_sigma;
141 if (current_mu > max_mu || max_mu == 0) max_mu = current_mu;
142 if (current_mu < min_mu || min_mu == 0) min_mu = current_mu;
143
144 }//end if entries < minEntries
145
146 float x_coord = (hist->GetXaxis()->GetBinLowEdge(i) + hist->GetXaxis()->GetBinUpEdge(i+num_bins-1))/2;
147 float y_coord = (hist->GetYaxis()->GetBinLowEdge(j) + hist->GetYaxis()->GetBinUpEdge(j+num_bins-1))/2;
148
149 int binx = mu_graph->GetXaxis()->FindBin(x_coord);
150 int biny = mu_graph->GetYaxis()->FindBin(y_coord);
151 if (mu_graph) {
152 mu_graph->Fill(x_coord,y_coord,current_mu);
153 mu_graph->SetBinError(binx,biny, current_err_mu);
154 if (fDebug || false) std::cout << " ** profileZwithIterativeGaussFit ** target: " << mu_graph->GetName()
155 << " bin(" << binx << ", " << biny << ") = " << current_mu
156 << " +- " << current_err_mu << std::endl;
157 }
158 //should probably be replace bin content, not fill?
159 if (sigma_graph) sigma_graph->SetBinContent(binx, biny, current_sigma);
160 if (sigma_err_graph) sigma_err_graph->SetBinContent(binx, biny, current_err_sigma);
161 if (mu_err_graph) mu_err_graph->SetBinContent(binx, biny,current_err_mu);
162
163 delete current_proj;
164
165 } //end loop on j (y)
166 } //end loop on i (x)
167
168 if (mu_graph) {
169 mu_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
170 mu_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
171 mu_graph->GetYaxis()->SetTitleOffset(1);
172 mu_graph->GetZaxis()->SetTitle(hist->GetZaxis()->GetTitle());
173 mu_graph->GetZaxis()->SetTitleOffset(1.2);
174 mu_graph->SetTitle(hist->GetTitle() );
175 //mu_graph->SetMaximum(max_mu + 0.1* (max_mu-min_mu));
176 //mu_graph->SetMinimum(min_mu - 0.1* (max_mu-min_mu));
177 }
178
179 if (sigma_graph) {
180 sigma_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
181 sigma_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
182 sigma_graph->GetYaxis()->SetTitleOffset(1);
183 sigma_graph->GetZaxis()->SetTitle(hist->GetZaxis()->GetTitle());
184 sigma_graph->GetZaxis()->SetTitleOffset(1.2);
185 sigma_graph->SetTitle( hist->GetTitle() );
186 //sigma_graph->SetMaximum(max_sigma + 0.1* (max_sigma-min_sigma));
187 //sigma_graph->SetMinimum(min_sigma - 0.1* (max_sigma-min_sigma));
188 }
189
190 if (mu_err_graph) {
191 mu_err_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
192 mu_err_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
193 mu_err_graph->GetYaxis()->SetTitleOffset(1);
194 mu_err_graph->GetZaxis()->SetTitle(Form("Error of fit #mu: %s",hist->GetZaxis()->GetTitle()));
195 mu_err_graph->GetZaxis()->SetTitleOffset(1.2);
196 mu_err_graph->SetTitle(hist->GetTitle());
197 //mu_err_graph->SetMaximum(max_mu + 0.1* (max_mu-min_mu));
198 //mu_err_graph->SetMinimum(min_mu - 0.1* (max_mu-min_mu));
199 }
200
201 if (sigma_err_graph) {
202 sigma_err_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
203 sigma_err_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
204 sigma_err_graph->GetYaxis()->SetTitleOffset(1);
205 sigma_err_graph->GetZaxis()->SetTitle(Form("Error of fit #sigma: %s",hist->GetZaxis()->GetTitle()));
206 sigma_err_graph->GetZaxis()->SetTitleOffset(1.2);
207 sigma_err_graph->SetTitle(hist->GetTitle());
208 //sigma_err_graph->SetMaximum(max_mu + 0.1* (max_mu-min_mu));
209 //sigma_err_graph->SetMinimum(min_mu - 0.1* (max_mu-min_mu));
210 }
211
212
213 if (num_not_converged || num_skipped) std::cout<<"Fit Results for histogram: "<< hist->GetName()<<std::endl;
214 if (num_not_converged) std::cout<<"Non Convergent Bin Fraction: "<<num_not_converged<< " / " <<num_bins_x*num_bins_y - num_skipped<<std::endl;
215 if (num_skipped) std::cout<<"Number skipped bins: "<<num_skipped<< " / " <<num_bins_x*num_bins_y<<std::endl;
216
217 return;
218}
219
220
221
222
223
224//-----------------------------------------------------------------------------
225void HistogramHelpers::profileYwithIterativeGaussFit(TH2* hist, TH1* mu_graph, TH1* sigma_graph, int num_bins,int m_PrintLevel)
226{
227
228 if (!hist) {
229 std::cout << "Error in ProfileYwithIterativeGaussFit(): Histogram not found" <<std::endl;
230 return;
231 }
232
233 if (num_bins < 1 ) {
234 std::cout << "Error in ProfileYwithIterativeGaussFit(): Invalid number of bins to integrate over." <<std::endl;
235 return;
236 }
237
238 const int minEntries = 50;
239 const int fDebug = 0;
240
241 int num_bins_x = hist->GetXaxis()->GetNbins();
242
243 if (mu_graph) mu_graph->Rebin(num_bins);
244 if (sigma_graph) sigma_graph->Rebin(num_bins);
245
246 double* errs_mu = new double[num_bins_x/num_bins + 2]; // +2 for overflow!!
247 double* errs_sigma = new double[num_bins_x/num_bins + 2];
248
249 errs_mu[0] = 0;
250 errs_mu[num_bins_x/num_bins + 1] = 0;
251
252 errs_sigma[0] = 0;
253 errs_sigma[num_bins_x/num_bins + 1] = 0;
254
255 double min_sigma = 0;
256 double max_sigma = 0;
257 double min_mu = 0;
258 double max_mu = 0;
259
260 int num_skipped = 0;
261
262 TH1D* current_proj;
263
264 for (int i = 1; i < (num_bins_x + (num_bins == 1)); i+=num_bins) {
265
266 int index = i/num_bins;
267 if (num_bins == 1) index--;
268
269 current_proj = hist->ProjectionY(Form("%s_projection_%i",hist->GetName(),index),i,i+num_bins-1);
270
271 double mu, mu_err, sigma, sigma_err;
272
273 if(current_proj->GetEntries() < minEntries) {
274 mu = 0;
275 mu_err = 0;
276 sigma = 0;
277 sigma_err = 0;
278 num_skipped++;
279 if ( fDebug ) std::cout<<"WARNING: Not enough entries in bin "<<index<<std::endl;
280 } else {
281
282 IterativeGaussFit(current_proj, mu, mu_err, sigma, sigma_err,m_PrintLevel);
283
284 if (sigma > max_sigma || max_sigma == 0) max_sigma = sigma;
285 if (sigma < min_sigma || min_sigma == 0) min_sigma = sigma;
286 if (mu > max_mu || max_mu == 0) max_mu = mu;
287 if (mu < min_mu || min_mu == 0) min_mu = mu;
288
289 }
290
291 double value_x = (hist->GetXaxis()->GetBinLowEdge(i) + hist->GetXaxis()->GetBinUpEdge(i+num_bins-1))/2;
292
293 //Important!! Use Fill to increment the graph with each iteration, or SetBinContent to replace contents...
294
295 if (sigma_graph) sigma_graph->Fill(value_x, sigma);
296 if (mu_graph) mu_graph->Fill(value_x, mu);
297
298 errs_mu[index + 1] = mu_err;
299 errs_sigma[index + 1] = sigma_err;
300
301 /*
302 std::cout<<hist->GetName()<<" "<<index+1<<" mu = " <<mu<<"+/-"<<mu_err<<std::endl;
303 std::cout<<hist->GetName()<<" "<<index+1<<" sigma = " <<sigma<<"+/-"<<sigma_err<<std::endl;
304 */
305
306 delete current_proj;
307 }
308
309 if (sigma_graph) {
310 sigma_graph->SetError(errs_sigma);
311 //sigma_graph->SetMaximum(max_sigma+0.15*(max_sigma - min_sigma));
312 //sigma_graph->SetMinimum(min_sigma-0.15*(max_sigma - min_sigma));
313 sigma_graph->GetYaxis()->SetTitleOffset(1.5);
314 //sigma_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
315 //sigma_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
316 sigma_graph->GetYaxis()->SetTitle(sigma_graph->GetYaxis()->GetTitle());
317 sigma_graph->GetXaxis()->SetTitle(sigma_graph->GetXaxis()->GetTitle());
318 sigma_graph->SetTitle("");
319 }
320
321 if (mu_graph) {
322 mu_graph->SetError(errs_mu);
323 //mu_graph->SetMaximum(max_mu+0.15*(max_mu - min_mu));
324 //mu_graph->SetMinimum(min_mu-0.15*(max_mu - min_mu));
325 mu_graph->GetYaxis()->SetTitleOffset(1.5);
326 // mu_graph->GetYaxis()->SetTitle(hist->GetYaxis()->GetTitle());
327 // mu_graph->GetXaxis()->SetTitle(hist->GetXaxis()->GetTitle());
328 mu_graph->GetYaxis()->SetTitle(mu_graph->GetYaxis()->GetTitle());
329 mu_graph->GetXaxis()->SetTitle(mu_graph->GetXaxis()->GetTitle());
330 mu_graph->SetTitle("");
331 }
332
333 if (fDebug && num_skipped) std::cout<<" Number of skipped bins: "<<num_skipped<<std::endl;
334
335 return;
336
337}
338
339
340//@par1 histogram to fit
341//@par2 pointer to function (which needs to be defined as double fcn(double*,double*)
342//@par3 initialParams
343//@par4 fitRange
344//@par5 FitResultPtr
345//@return Pointer to the fit function
346TF1* HistogramHelpers::IterativeGeneralFit(TH1* hist, double(*fcn)(double *, double *),const std::vector<float>& initial, const std::vector<float>& fitRange, TFitResultPtr *fitr_p, int m_PrintLevel) {
347
348 const int iteration_limit = 20;
349 const float percent_limit = 0.01;
350 const int fDebug = 0;
351
352 int minEntries = 50;
353
354 if (!hist) {
355 if (fDebug) std::cout<<"IterativeGeneralFit:: Histogram to be fit is missing. Return nullptr"<<std::endl;
356 return nullptr;
357 }
358
359 if (hist->GetEntries() < minEntries) {
360 if (fDebug) std::cout<<"IterativeGeneralFit::Histogram to be fit is too low-stat. Return nullptr"<<std::endl;
361 return nullptr;
362 }
363
364 if (fitRange.size() < 2) {
365 if (fDebug) std::cout<<"IterativeGeneralFit::Provide the fit range. Return nullptr"<<std::endl;
366 return nullptr;
367 }
368
369 if (initial.size() < 1) {
370 if (fDebug) std::cout<<"IterativeGeneralFit. At least a free parameter is necessary. Return nullptr"<<std::endl;
371 return nullptr;
372 }
373
374
376
377 TF1* fit_func = new TF1("fit_func",fcn,fitRange[0],fitRange[1],initial.size());
378 //Setting the initial parameters
379 for (unsigned int i=0; i<initial.size();++i) {
380 fit_func->SetParameter(i,initial[i]);
381 }
382 return fit_func;
383}
384
385
386int HistogramHelpers::IterativeGaussFit(TH1* hist, double &mu, double &mu_err, double &sigma, double &sigma_err, int m_PrintLevel)
387{
388
389 //constants for fitting algorithm
390 const int iteration_limit = 20;
391 const float percent_limit = 0.01;
392 const float fit_range_multiplier = 1.5;
393 const int fDebug = 0;
394
395 double last_mu;
396 double last_sigma;
397 double current_mu = 0;
398 double current_sigma = 0;
399 double mu_percent_diff;
400 double sigma_percent_diff;
401
402 int minEntries = 25;
403
404 if (!hist) {
405 if (fDebug) std::cout<< "Error in Anp::IterativeGaussFit(): Histogram to be fit is missing" <<std::endl;
406 return 1;
407 }
408 if (hist->GetEntries() < minEntries) {
409 if (fDebug) std::cout<< "Error in Anp::IterativeGaussFit(): Histogram has too few entries " << hist->GetEntries() << std::endl;
410 return 1;
411 }
412
414
415 TF1* fit_func = new TF1("fit_func","gaus");
416
417 int bad_fit = hist->Fit(fit_func,"QN");
418
419 if (fDebug && bad_fit) std::cout <<"BAD INITIAL FIT: "<< hist->GetTitle() << std::endl;
420
421 last_mu = fit_func->GetParameter(1);
422 last_sigma = fit_func->GetParameter(2);
423
424 if (bad_fit) last_mu = hist->GetMean();
425
426 // check as well that the value of last_mu is reasonable
427 if (fabs(last_mu - hist->GetMean()) > 3*hist->GetBinWidth(1)) {
428 last_mu = hist->GetMean();
429 last_sigma = hist->GetRMS();
430 }
431
432 // intial fit range
433 // fit_func->SetRange(last_mu-fit_range_multiplier*last_sigma,last_mu+fit_range_multiplier*last_sigma);
434 // superseeded below
435
436 int iteration = 0;
437 while ( iteration < iteration_limit ) {
438
439 iteration++;
440
441 double FitRangeLower = last_mu-fit_range_multiplier*last_sigma;
442 double FitRangeUpper = last_mu+fit_range_multiplier*last_sigma;
443
444 // if range is to narrow --> broaden it
445 if ((FitRangeUpper-FitRangeLower)/hist->GetBinWidth(1) < 5) {
446 FitRangeLower -= hist->GetBinWidth(1);
447 FitRangeUpper += hist->GetBinWidth(1);
448 }
449
450 fit_func->SetRange(FitRangeLower, FitRangeUpper);
451 if (m_PrintLevel >= 3) cout << " ** IterativeGaussFit ** fit iter # " << iteration
452 << " new fit range: " << FitRangeLower << " --> " << FitRangeUpper << endl;
453
454 bad_fit = hist->Fit(fit_func, "RQN");
455 // check that fit result is sound
456 // 1) the mean must be within the histogram range
457 if (fit_func->GetParameter(1) < hist->GetXaxis()->GetXmin() || fit_func->GetParameter(1) > hist->GetXaxis()->GetXmax()) bad_fit = 1;
458 // 2) the sigma can not be broader than the histogram range
459 if (fit_func->GetParameter(2) > hist->GetXaxis()->GetXmax()-hist->GetXaxis()->GetXmin()) bad_fit = 1;
460
461 if (fDebug && bad_fit) std::cout<<" ** BAD FIT ** : bin "<< hist->GetTitle() <<" iteration "<<iteration<<std::endl;
462
463 if (bad_fit) { // in case the fit looks odd, then rebin the histogram and refit with smallest divisor.
464 int rebinFactor = 1;
465 for (int i_div = 2; i_div < (hist->GetXaxis()->GetNbins()/2)+1; ++i_div)
466 if ((hist->GetXaxis()->GetNbins() % i_div) == 0) {
467 rebinFactor = i_div;
468 break;
469 }
470 //std::cout<<"Rebinning by factor:"<<rebinFactor<<std::endl;
471 hist->Rebin(rebinFactor);
472 hist->Fit(fit_func, "RQN");
473 }
474
475 // extract the correction for this iteration
476 current_mu = fit_func->GetParameter(1);
477 current_sigma = fit_func->GetParameter(2);
478
479 float average_mu = (last_mu+current_mu)/2;
480 float average_sigma = (last_sigma+current_sigma)/2;
481
482 if (average_mu == 0) {
483 if ( fDebug ) std::cout<<" Average mu = 0 in bin "<< hist->GetTitle() <<std::endl;
484 average_mu = current_mu;
485 }
486
487 if (average_sigma == 0) {
488 if ( fDebug ) std::cout<<"Average sigma = 0; Fit Problem in "<< hist->GetTitle() <<". "<<last_sigma<<" "<<current_sigma<<std::endl;
489 average_sigma = current_sigma;
490 }
491
492 mu_percent_diff = fabs((last_mu-current_mu)/average_mu);
493 sigma_percent_diff = fabs((last_sigma-current_sigma)/average_sigma);
494
495 if ( mu_percent_diff < percent_limit && sigma_percent_diff < percent_limit ) break;
496
497 if (iteration != iteration_limit) { //necessary?
498 last_mu = current_mu;
499 last_sigma = current_sigma;
500 }
501 // check as well that the last_mu is reasonable
502 if (fabs(last_mu - hist->GetMean()) > 5*hist->GetBinWidth(1)) {
503 if (m_PrintLevel >= 3) cout << " ** IterativeGaussFit ** fit iter # " << iteration
504 << " ** WARNING ** last_mu looks bad: " << last_mu
505 << " this iter mu: " << fit_func->GetParameter(1)
506 << " proposed mu: " << hist->GetMean()
507 << endl;
508 last_mu = hist->GetMean();
509 }
510 }
511
512 if (iteration == iteration_limit) {
513 if (fDebug ) std::cout<<"WARNING: Fit did not converge to < "<<percent_limit*100<<"% in "<< hist->GetTitle() <<" in "<<iteration_limit<<" iterations. Percent Diffs: "<<mu_percent_diff*100<<"% (Mu),"<<" "<<sigma_percent_diff*100<<"% (Sigma)"<<std::endl;
514 //possibly return a value other than 0 to indicate not converged?
515 }
516
517 mu = current_mu;
518 mu_err = fit_func->GetParError(1);
519 sigma = current_sigma;
520 sigma_err = fit_func->GetParError(2);
521
522 hist->GetListOfFunctions()->Add(fit_func);
523
524 if (m_PrintLevel >= 1 ) {
525 cout << " ** IterativeGaussFit ** fit result: histo name " << hist->GetName() << " title: " << hist->GetTitle() << endl
526 << " mu = " << mu << " +- " << mu_err << endl
527 << " sigma = " << sigma << " +- " << sigma_err
528 << endl;
529 //if (TempCanvasIterGaussFit == NULL) {
530 //TempCanvasIterGaussFit = new TCanvas ("TempCanvasIterGaussFit","Iter Gauss fit", 400, 400);
531 //}
532 //hist->DrawCopy();
533 //TempCanvasIterGaussFit->Update();
534 //hist->Print();
535 string input = "";
536 cout << " ** IterativeGaussFit ** Please type RETURN to continue:\n>";
537 getline(cin, input);
538 }
539
540
541 if (outFile_for_projections->IsOpen()) {
542 TCanvas q;
543 q.cd();
544 hist->Draw();
545 fit_func->Draw("same");
546 std::string str = "";
547 //q.SaveAs((str+"_"+hist->GetName()+".pdf").c_str());
549 q.Write((str+"_"+hist->GetName()).c_str());
550 }
551
552 return 0;
553}
554
556 outFile_for_projections = new TFile("debug_projections_histogramHelpers.root","RECREATE");
557}
558
564
565
566void HistogramHelpers::HistogramConditioning (TH1* hist,int m_PrintLevel)
567{
568 if (m_PrintLevel>=3) cout << " ** HistogramConditioning ** START ** hist = " << hist->GetName() << endl;
569
570 double MinEntriesMPB = 15;
571 Int_t NGroupBins = 2;
572
573 // goal:
574 // make sure that the most populated bin has a minimum number of entries
575 Int_t MostPopulatedBin = (hist->GetMaximumBin());
576 double EntriesMPB = hist->GetBinContent(MostPopulatedBin);
577 if (EntriesMPB < MinEntriesMPB) {
578 // check the entries of the neighbour channels
579 if ((EntriesMPB + hist->GetBinContent(MostPopulatedBin+1) + hist->GetBinContent(MostPopulatedBin-1)) > MinEntriesMPB) {
580 NGroupBins = 2;
581 }
582 else {
583 NGroupBins = 3;
584 }
585
586 // now find the first divisor (factor of ) the original number of bins
587 Bool_t DivisorFound = false;
588 while (!DivisorFound) {
589 if ( hist->GetNbinsX() % NGroupBins == 0) {
590 DivisorFound = true;
591 }
592 else {
593 DivisorFound = false;
594 NGroupBins++;
595 }
596 }
597 Int_t NBinsWas = hist->GetNbinsX();
598 hist = hist->Rebin(NGroupBins);
599 if (m_PrintLevel>=1) cout << " ** HistogramConditioning ** histogram had to be rebinned by: " << NGroupBins
600 << " NBins was: " << NBinsWas << " and now is: " << hist->GetNbinsX() << endl;
601
602 }
603
604
605 return;
606}
607
void profileYwithIterativeGaussFit(TH2 *hist, TH1 *mu_graph, TH1 *sigma_graph, int num_bins=1, int m_PrintLevel=0)
description
TF1 * IterativeGeneralFit(TH1 *hist, double(*fcn)(double *, double *), const std::vector< float > &initial, const std::vector< float > &fitRange, TFitResultPtr *fitr_p, int m_PrintLevel)
description
int IterativeGaussFit(TH1 *hist, double &mu, double &mu_err, double &sigma, double &sigma_err, int m_PrintLevel=0)
description
double twoGauss_f(double *x, double *par)
description
double twoGaussExp_f(double *x, double *par)
description
void OpenProjectionFile()
description
TFile * outFile_for_projections
void CloseProjectionFile()
description
void profileZwithIterativeGaussFit(TH3 *hist, TH2 *mu_graph, TH2 *sigma_graph, int num_bins, TH2 *mu_err_graph, TH2 *sigma_err_graph)
description
double GaussExpTails_f(double *x, double *par)
description
void HistogramConditioning(TH1 *hist, int m_PrintLevel=0)
description