ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/PeakFinder.C
Revision: 1.2
Committed: Mon Jun 11 20:43:44 2012 UTC (12 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.1: +7 -4 lines
Log Message:
adapted peak finding for btag case

File Contents

# User Rev Content
1 buchmann 1.1 /****
2    
3     Off peak status (RestrictToMassPeak) :
4    
5     x Necessary adaptations identified
6     x Started working on necessary adaptations
7     x Necessary adaptations implemented
8     x Necessary adaptations tested
9    
10     NO ADAPTATIONS REQUIRED
11    
12    
13     ****/
14     #include <iostream>
15     #include <sstream>
16     #include <iomanip>
17     #include <TFile.h>
18     #include <TTree.h>
19     #include <TH1.h>
20     #include <TF1.h>
21     #include <TMath.h>
22     #include <TCanvas.h>
23     #include <vector>
24     #include <TROOT.h>
25     #include <TLine.h>
26     #include <TLegend.h>
27     #include <TLatex.h>
28     #include <TRandom.h>
29     #ifndef GeneralToolBoxLoaded
30     #include "GeneralToolBox.C"
31     #endif
32     #ifndef Verbosity
33     #define Verbosity 0
34     #endif
35    
36     using namespace std;
37    
38     Double_t LogParabola(Double_t *x,Double_t *par)
39     {
40     return par[0]*TMath::Exp(-par[1]*(x[0]-par[2])*(x[0]-par[2])); // we're adding a "logarithmic parabola" :-)
41     //note: the abs() around the first parameter ensures that, when fitting, no negative values are chosen.
42     }
43    
44     Double_t LogParabolaP(Double_t *x,Double_t *par)
45     {
46     float fitval = par[0]*TMath::Exp(-par[1]*(x[0]-par[2])*(x[0]-par[2])); // we're adding a "logarithmic parabola" :-)
47     fitval+= statErrorP(fitval);
48     return fitval;
49     }
50    
51     Double_t LogParabolaN(Double_t *x,Double_t *par)
52     {
53     float fitval = par[0]*TMath::Exp(-par[1]*(x[0]-par[2])*(x[0]-par[2])); // we're adding a "logarithmic parabola" :-)
54     fitval-= statErrorN(fitval);
55     return fitval;
56     }
57    
58    
59    
60     bool doreject=false;
61     float low_reject=-10;
62     float hi_reject=10;
63    
64     bool dofixed=true;
65    
66    
67     bool addparabola=true;
68     float parabola_height=0;
69     float parabola_inclination=0;
70     float parabola_pointzero=0;
71    
72     float find_KM_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma);
73     float find_Gauss_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma,int numsig);
74    
75     Double_t CrystalBallPlusLogParabola(double *x, double *par)
76     {
77     //parameters:
78     //N: the way we scale the function
79     //alpha (where the function changes)
80     //n: exponent of the power expression in the left area
81     //xbar: peak of the gaussian part (RHS)
82     //sigma: width of the gaussian part (RHS)
83     float N=par[0];
84     float alpha=par[3]; //verified (orig: 1)
85     float n=par[4]; // verified (orig: 2)
86     float xbar=par[1]; //verified (orig: 3)
87     float sigma=par[2]; //verified (orig: 4)
88     float altX=-x[0];
89     float result=-999;
90     if(((altX-xbar)/sigma>-alpha)){
91     result=N*TMath::Exp(-(altX-xbar)*(altX-xbar)/(2*sigma*sigma));
92     }
93     else
94     {
95     //if we are outside the central (Gaussian) area things become more difficult ...
96     float A=TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-alpha*alpha/2);
97     float B=n/TMath::Abs(alpha) - TMath::Abs(alpha);
98     if((altX-xbar)/sigma<=-alpha) result=N*A*TMath::Power((B-((altX-xbar)/sigma)),-n);
99     if((altX-xbar)/sigma>=alpha) result=N*A*TMath::Power((B+((altX-xbar)/sigma)),-n);
100     }
101    
102     result+=par[5]*TMath::Exp(-par[6]*(x[0]-par[7])*(x[0]-par[7])); // we're adding a "logarithmic parabola" :-)
103     if(par[5]<0) return -999; // there can be no negative ttbar contribution, so just return a value which is going to be a horrible fit.
104     if(par[6]<0) return -999; // the parabola needs to close (i.e. tend to negative values for large |jzb|, not to large positive values)
105    
106     return result;
107     }
108    
109     Double_t CrystalBallPlusLogParabolaP(double *x, double *par)
110     {
111     float parameter_bkp=par[5];
112     par[5]=0;
113     float zjetsresult=CrystalBallPlusLogParabola(x,par);
114     par[5]=parameter_bkp;
115     parameter_bkp=par[0];
116     par[0]=0;
117     float ttbarresult=CrystalBallPlusLogParabola(x,par);
118     par[0]=parameter_bkp;
119     return zjetsresult+ttbarresult+TMath::Sqrt(zjetsresult+(1.0/3.0)*ttbarresult);
120     }
121    
122     Double_t CrystalBallPlusLogParabolaN(double *x, double *par)
123     {
124     float parameter_bkp=par[5];
125     par[5]=0;
126     float zjetsresult=CrystalBallPlusLogParabola(x,par);
127     par[5]=parameter_bkp;
128     parameter_bkp=par[0];
129     par[0]=0;
130     float ttbarresult=CrystalBallPlusLogParabola(x,par);
131     par[0]=parameter_bkp;
132     return zjetsresult+ttbarresult-TMath::Sqrt(zjetsresult+(1.0/3.0)*ttbarresult);
133     }
134    
135     Double_t KrystalMallLogPar(double *x, double *par)
136     {
137     //parameters:
138     //N: the way we scale the function
139     //alpha (where the function changes)
140     //n: exponent of the power expression in the left area
141     //xbar: peak of the gaussian part (RHS)
142     //sigma: width of the gaussian part (RHS)
143     float N=par[0];
144     float alpha=par[1];
145     float n=par[2];
146     float xbar=par[3];
147     float sigma=par[4];
148     float altX=x[0];
149     float result=-999;
150     if(doreject&&x[0]>low_reject&&x[0]<hi_reject)
151     {
152     TF1::RejectPoint();
153     return 0;
154     }
155     if(((altX-xbar)/sigma>-alpha)&&((altX-xbar)/sigma<alpha)){
156     result=N*TMath::Exp(-(altX-xbar)*(altX-xbar)/(2*sigma*sigma));
157     }
158     else
159     {
160     //if we are outside the central (Gaussian) area things become more difficult ...
161     float A=TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-alpha*alpha/2);
162     float B=n/TMath::Abs(alpha) - TMath::Abs(alpha);
163     if((altX-xbar)/sigma<=-alpha) result=N*A*TMath::Power((B-((altX-xbar)/sigma)),-n);
164     if((altX-xbar)/sigma>=alpha) result=N*A*TMath::Power((B+((altX-xbar)/sigma)),-n);
165     }
166    
167     if(addparabola) {
168     if(dofixed) {
169     result+=parabola_height*TMath::Exp(-parabola_inclination*(x[0]-parabola_pointzero)*(x[0]-parabola_pointzero)); // we're adding a "logarithmic parabola" :-)
170     }
171     else {
172     result+=par[5]*TMath::Exp(-par[6]*(x[0]-par[7])*(x[0]-par[7])); // we're adding a "logarithmic parabola" :-)
173     if(par[5]<0) return -999; // there can be no negative ttbar contribution, so just return a value which is going to be a horrible fit.
174     if(par[6]<0) return -999; // the parabola needs to close (i.e. tend to negative values for large |jzb|, not to large positive values)
175     }
176     }
177     return result;
178     }
179    
180    
181     void do_ttbar_fit(TH1F *ttbar,TF1 *logpar, TF1 *KM)
182     {
183     logpar->SetParameters(10,2,3);
184     ttbar->Fit(logpar,"NQ");
185     ttbar->Fit(logpar,"NQ");
186     ttbar->Fit(logpar,"NQ");
187     ttbar->Fit(logpar,"NQ");
188     ttbar->SetStats(0);
189     parabola_height=logpar->GetParameter(0);
190     parabola_inclination=logpar->GetParameter(1);
191     parabola_pointzero=logpar->GetParameter(2);
192     }
193    
194     void draw_complete_fit(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, TF1 *KM)
195     {
196     TCanvas *fitsummary;
197     if(is_data) {
198     fitsummary= new TCanvas("fitsummary","Fit Summary",1000,500);
199     fitsummary->Divide(2,1);
200     }
201     else {
202     fitsummary= new TCanvas("fitsummary","Fit Summary",1200,400);
203     fitsummary->Divide(3,1);
204     }
205     TF1 *logpar = new TF1("logpar",LogParabola,minfit,maxfit,3);
206    
207     logpar->SetParameters(KM->GetParameter(5),KM->GetParameter(6),KM->GetParameter(7));
208     logpar->SetLineColor(kOrange);
209     logpar->SetLineStyle(2);
210     if(!is_data)
211     {
212     ttbar->GetXaxis()->SetTitle("JZB (GeV/c)");
213     ttbar->GetYaxis()->SetTitle("events");
214     ttbar->GetXaxis()->CenterTitle();
215     ttbar->GetYaxis()->CenterTitle();
216     ttbar->SetLineColor(kRed);
217     fitsummary->cd(1);
218     ttbar->Draw();
219     fitsummary->cd(1);
220     logpar->Draw("same");
221     TLegend *leg = new TLegend(0.3,0.25,0.65,0.4);
222     leg->AddEntry(ttbar,"t#bar{t} (mc)","l");
223     leg->AddEntry(logpar,"Fit with Log. Parabola","l");
224     leg->SetLineColor(kWhite);
225     leg->SetFillColor(kWhite);
226     leg->Draw();
227     TText *title1=write_title("t#bar{t} Distribution and Fit");
228     title1->Draw();
229     }
230     fitsummary->cd(2-int(is_data));
231     fitsummary->cd(2-int(is_data))->SetLogy(1);
232     all->GetYaxis()->SetTitle("events");
233     all->GetYaxis()->CenterTitle();
234     all->Draw();
235     ttbar->SetLineColor(kRed);
236     if(!is_data) ttbar->Draw("same");
237     KM->SetLineWidth(1);
238     KM->Draw("same");
239     logpar->SetLineWidth(1);
240     logpar->Draw("same");
241     if(!is_data)ttbar->Draw("same");
242     TLegend *leg2 = new TLegend(0.65,0.65,0.89,0.89);
243     if(is_data) leg2->AddEntry(all,"Data","l");
244     else leg2->AddEntry(all,"Stacked MC","l");
245     leg2->AddEntry(KM,"Fitted KM Function","l");
246     if(!is_data) leg2->AddEntry(ttbar,"t#bar{t} MC","l");
247     leg2->AddEntry(logpar,"t#bar{t} (Fit)","l");
248     leg2->SetFillColor(kWhite);
249     leg2->SetLineColor(kWhite);
250     leg2->Draw();
251     TText *title2=write_title("Distribution and Fits (log.)");
252     title2->Draw();
253     fitsummary->cd(3-is_data);
254     all->Draw();
255     KM->Draw("same");
256     float peaklocation=KM->GetParameter(3);
257     TLine *muline = new TLine(peaklocation,0,peaklocation,all->GetMaximum());
258     muline->SetLineColor(kBlue);
259     muline->SetLineStyle(2);
260     muline->Draw();
261     TLegend *leg = new TLegend(0.75,0.75,0.89,0.89);
262     if(is_data) leg2->AddEntry(all,"Data","l");
263     else leg->AddEntry(all,"Stacked MC","l");
264     leg->AddEntry(KM,"Fitted KM Function","l");
265     stringstream mulinelabel;
266     mulinelabel<<"Peak position at #mu="<<peaklocation;
267     leg->AddEntry(muline,mulinelabel.str().c_str(),"l");
268     leg->SetLineColor(kWhite);
269     leg->SetFillColor(kWhite);
270     leg->Draw();
271     mulinelabel<<"+/-"<<TMath::Abs(KM->GetParError(3));
272     TText *title3=write_title("Distribution and Fits");
273     title3->Draw();
274     TText *titlel=write_title_low(mulinelabel.str().c_str());
275     titlel->Draw();
276    
277     stringstream printtop;
278     printtop << "#mu="<<std::setprecision(3)<<KM->GetParameter(3)<<"+/-"<<std::setprecision(3)<<KM->GetParError(3);
279     TLatex *toptext = new TLatex(0,all->GetMaximum()*1.3,printtop.str().c_str());
280     toptext->SetTextAlign(22);
281     // toptext->Draw();
282    
283     doreject=false;
284     TF1 *wholefitfunc=(TF1*)KM->Clone();
285     doreject=true;
286     wholefitfunc->SetLineColor(kRed);
287     wholefitfunc->SetLineStyle(2);
288     wholefitfunc->Draw("same");
289    
290     fitsummary->cd(2-is_data);
291     wholefitfunc->Draw("same");
292    
293     if(is_data) CompleteSave(fitsummary, "fit/Fit_Summary_Data");
294     else CompleteSave(fitsummary,"fit/Fit_Summary_MC");
295    
296     }
297    
298     float Kostas_algorithm(TH1F *hist, float &error, float &sigma, TF1* fitFunc, float lowlimit, float highlimit,bool is_data)
299     {
300     float mean = hist->GetBinCenter( hist->GetMaximumBin());
301     float rms = hist->GetRMS();
302     mean = hist->GetBinCenter( hist->GetMaximumBin());
303    
304     fitFunc->SetParameter(1,mean);
305    
306     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
307    
308     mean=fitFunc->GetParameter(1);
309     rms=fitFunc->GetParameter(2);
310     error=fitFunc->GetParError(1);
311    
312     bool printOut = false; // print the peak estimate in the i-th iteration
313    
314     // --- perform iterations
315     int numIterations=5;
316 buchmann 1.2
317     float rmsMultiplier=1.0;
318     if(PlottingSetup::DoBTag) rmsMultiplier=2.0;
319 buchmann 1.1
320     if(printOut) dout << " ( ";
321     for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
322     {
323 buchmann 1.2 hist->Fit(fitFunc,"QLLN","same",mean - rmsMultiplier*lowlimit*rms, mean + rmsMultiplier*highlimit*rms); // fit -2 +1 sigma from previous iteration
324     mean=fitFunc->GetParameter(1);
325     fitFunc->SetRange(mean - rmsMultiplier*lowlimit*rms, mean + rmsMultiplier*highlimit*rms);
326     if(printOut) dout << mean << ",";
327 buchmann 1.1 }
328     if(printOut) dout << " ) ";
329     if(printOut) dout << endl;
330     mean=fitFunc->GetParameter(1);
331     sigma=fitFunc->GetParameter(2);
332     error=1.0*fitFunc->GetParError(1);
333    
334     // below this point we're merely doing cosmetics :-)
335     TCanvas *peakfitcanvas = new TCanvas("peakfitcanvas","Fitting Canvas");
336     peakfitcanvas->cd();
337    
338     hist->SetMinimum(0);
339     if(is_data) hist->Draw("e1");
340     else hist->Draw("histo");
341     fitFunc->SetLineColor(kBlue);
342     fitFunc->SetLineWidth(1);
343     fitFunc->Draw("same");
344     hist->SetStats(0);
345     TLegend *leg;
346     if(is_data) {
347     leg= make_legend("Fit (Data)");
348     leg->AddEntry(hist,"Data","p");
349     }
350     else {
351     leg= make_legend("Fit (MC)");
352     leg->AddEntry(hist,"MC","l");
353     }
354    
355     leg->AddEntry(fitFunc,"Fit","l");
356     leg->SetX1(0.7);
357     leg->SetY1(0.7);
358     leg->Draw();
359    
360     TText *ftitle=write_text(0.20,0.86,"Fit results:");
361     ftitle->SetTextSize(0.03);
362     ftitle->SetTextAlign(11);
363     stringstream fitresult;
364     fitresult << "#mu=" << std::setprecision(4) << mean << "+/-" << std::setprecision(4) << error;
365     // TText *title1=write_text(0.20,0.96,fitresult.str().c_str());
366     TText *title1=write_text(0.20,0.82,fitresult.str().c_str());
367     title1->SetTextSize(0.03);
368     title1->SetTextAlign(11);
369     stringstream sigmainfo;
370     sigmainfo << "#sigma=" << std::setprecision(4) << fitFunc->GetParameter(2) << "+/-" << std::setprecision(4) << fitFunc->GetParError(2);
371     // TText *sigmatext=write_text(0.80,0.96,sigmainfo.str().c_str());
372     TText *sigmatext=write_text(0.20,0.78,sigmainfo.str().c_str());
373     sigmatext->SetTextSize(0.03);
374     sigmatext->SetTextAlign(11);
375    
376     // TText* toptitle;
377     // if(is_data) toptitle = write_title("Fit Result (data)");
378     // else toptitle = write_title("Fit Result (MC)");
379     // toptitle->Draw();
380     ftitle->Draw();
381     title1->Draw();
382     sigmatext->Draw();
383     if(!is_data) {
384     CompleteSave(peakfitcanvas,"fit/Fit_Summary_MC");
385     PlottingSetup::JZBPeakPositionMC=mean;
386     PlottingSetup::JZBPeakWidthMC=fitFunc->GetParameter(2);
387     } else {
388     CompleteSave(peakfitcanvas,"fit/Fit_Summary_Data");
389     PlottingSetup::JZBPeakPositionData=mean;
390     PlottingSetup::JZBPeakWidthData=fitFunc->GetParameter(2);
391     }
392     delete peakfitcanvas;
393    
394     return mean;
395     }
396    
397    
398    
399     float find_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma, int method)
400     {
401     float peak_position=0;
402     if(method==0||method>1) {
403     //looking at a gaus request
404     int numsig=1;
405     if(method>1) numsig=method;
406     peak_position=find_Gauss_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma,numsig);
407     }
408     if(method==1) {
409     //looking at a KM request
410     peak_position=find_KM_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma);
411     }
412     if(method==-99) { // KOSTAS!!
413     TF1 *f1 = new TF1("f1","gaus",-40,40);
414     peak_position=Kostas_algorithm(all,error,Sigma,f1,2.5,2.5,is_data);
415     }
416     return peak_position;
417     }
418    
419    
420     float get_Gaussian_peak(TH1F *hist, float &error, float &sigma, TF1* fitFunc, float lowlimit, float highlimit,bool is_data,int numsig)
421     {
422     TCanvas *fitcanvas = new TCanvas("fitcanvas","fitcanvas");
423     float mean = hist->GetBinCenter( hist->GetMaximumBin());
424     float rms = hist->GetRMS();
425    
426     mean = hist->GetBinCenter( hist->GetMaximumBin());
427    
428     fitFunc->SetParameter(1,mean);
429    
430     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
431    
432     mean=fitFunc->GetParameter(1);
433     rms=fitFunc->GetParameter(2);
434     error=fitFunc->GetParError(1);
435    
436     bool printOut = false; // print the peak estimate in the i-th iteration
437    
438     // --- perform iterations
439     int numIterations=5;
440    
441     if(printOut) dout << " ( ";
442     for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
443     {
444     hist->Fit(fitFunc,"QLLN","same",mean - numsig*rms, mean + numsig*rms); // fit -2 +1 sigma from previous iteration
445     mean=fitFunc->GetParameter(1);
446     fitFunc->SetRange(mean - numsig*rms, mean + numsig*rms);
447     if(printOut) dout << mean << ",";
448     }
449     if(printOut) dout << " ) ";
450     if(printOut) dout << endl;
451     mean=fitFunc->GetParameter(1);
452     sigma=fitFunc->GetParameter(2);
453     error=1.0*fitFunc->GetParError(1);
454     fitcanvas->cd();
455     hist->SetMinimum(0);
456     if(is_data) hist->Draw("e1");
457     else hist->Draw("histo");
458     fitFunc->SetLineColor(kBlue);
459     fitFunc->SetLineWidth(1);
460     fitFunc->Draw("same");
461     hist->SetStats(0);
462     TLegend *leg;
463     if(is_data) {
464     leg= make_legend("Fit (Data)");
465     leg->AddEntry(hist,"Data","p");
466     }
467     else {
468     leg= make_legend("Fit (MC)");
469     leg->AddEntry(hist,"MC","l");
470     }
471    
472     leg->AddEntry(fitFunc,"Fit","l");
473     leg->Draw();
474    
475     TText *ftitle=write_text(0.20,0.86,"Fit results:");
476     ftitle->SetTextSize(0.03);
477     ftitle->SetTextAlign(11);
478     stringstream fitresult;
479     fitresult << "#mu=" << std::setprecision(4) << mean << "+/-" << std::setprecision(4) << error;
480     // TText *title1=write_text(0.20,0.96,fitresult.str().c_str());
481     TText *title1=write_text(0.20,0.82,fitresult.str().c_str());
482     title1->SetTextSize(0.03);
483     title1->SetTextAlign(11);
484     stringstream sigmainfo;
485     sigmainfo << "#sigma=" << std::setprecision(4) << fitFunc->GetParameter(2) << "+/-" << std::setprecision(4) << fitFunc->GetParError(2);
486     // TText *sigmatext=write_text(0.80,0.96,sigmainfo.str().c_str());
487     TText *sigmatext=write_text(0.20,0.78,sigmainfo.str().c_str());
488     sigmatext->SetTextSize(0.03);
489     sigmatext->SetTextAlign(11);
490    
491     // TText* toptitle;
492     // if(is_data) toptitle = write_title("Fit Result (data)");
493     // else toptitle = write_title("Fit Result (MC)");
494     // toptitle->Draw();
495     ftitle->Draw();
496     title1->Draw();
497     sigmatext->Draw();
498     if(!is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_MC");
499     if(is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_Data");
500    
501    
502     // dout << "[" << fitFunc->GetParameter(1) << " , " << fitFunc->GetParError(1) << "]" << endl;
503     return mean;
504     }
505    
506    
507     float find_Gauss_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma,int numsig)
508     {
509     TF1 *fitfunc = new TF1("fitfunc","gaus",minfit,maxfit);
510     float peakpos = get_Gaussian_peak(all,error,Sigma,fitfunc, minfit, maxfit,is_data,numsig);
511     return peakpos;
512     }
513    
514     float find_KM_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma)
515     {
516     all->SetLineColor(kBlue);
517     all->SetStats(0);
518     all->SetTitle("");
519     all->GetXaxis()->SetTitle("JZB (GeV/c)");
520     all->GetYaxis()->SetTitle("events");
521     all->GetXaxis()->CenterTitle();
522     all->GetYaxis()->CenterTitle();
523     TF1 *fitfunc = new TF1("fitfunc",KrystalMallLogPar,0.8*minfit,0.8*maxfit,8);
524     if(!is_data)
525     {
526     TF1 *logpar = new TF1("logpar",LogParabola,minfit,maxfit,3);
527     do_ttbar_fit(ttbar,logpar,fitfunc);
528     fitfunc->SetParameters(1000,2,2.5,-1.6,4,logpar->GetParameter(0),logpar->GetParameter(1),logpar->GetParameter(2));
529     parabola_height=logpar->GetParameter(0);
530     parabola_inclination=logpar->GetParameter(1);
531     parabola_pointzero=logpar->GetParameter(2);
532     dofixed=true;//ttbar is known so we can fix the parameters and don't need to use them for fitting!
533     }
534     else
535     {
536     fitfunc->SetParameters(1000,2,2.5,-1.6,4,5.45039,0.000324593,12.3528);
537     dofixed=false;
538     }
539    
540     vector<float> chi2values;
541     addparabola=true;
542     for (int ifit=0;ifit<100;ifit++)
543     {
544     all->Fit(fitfunc,"NQ");
545     chi2values.push_back(fitfunc->GetChisquare());
546     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
547     }
548     /*
549     The parameters represent the following quantities:
550     float N=par[0];
551     float alpha=par[1];
552     float n=par[2];
553     float xbar=par[3];
554     float sigma=par[4];
555     */
556     //we are clearing an area of two sigma to the left and to the right of the center of the function for the "real fit".
557     low_reject=-2*fitfunc->GetParameter(4)+fitfunc->GetParameter(3);
558     hi_reject=fitfunc->GetParameter(3)+2*fitfunc->GetParameter(4);
559     if(low_reject>-15) low_reject=-10;
560     if(hi_reject<15) hi_reject=10;
561     doreject=true;//activating the rejection :-)
562    
563     for (int ifit=0;ifit<100;ifit++)
564     {
565     all->Fit(fitfunc,"NQ");
566     chi2values.push_back(fitfunc->GetChisquare());
567     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
568     }
569    
570     draw_complete_fit(all,ttbar,minfit,maxfit,is_data,fitfunc);
571     doreject=true;
572     error=fitfunc->GetParError(3);
573     Sigma=fitfunc->GetParameter(4);//sigma
574    
575     return fitfunc->GetParameter(3);
576     }
577    
578     Double_t InvCrystalBall(Double_t *x,Double_t *par)
579     {
580     Double_t arg1=0,arg2=0,A=0,B=0;
581     Double_t f1=0;
582     Double_t f2=0;
583     Double_t lim=0;
584     Double_t fitval=0;
585     Double_t N=0;
586     Double_t n=par[4];
587    
588     Double_t invX = -x[0];
589    
590     if (par[2] != 0)
591     arg1 = (invX-par[1])/par[2];
592    
593     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
594    
595     if (par[3] != 0)
596     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
597    
598     if (par[3] != 0)
599     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
600    
601     f1 = TMath::Exp(-0.5*arg1*arg1);
602     if (par[2] != 0)
603     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
604    
605     if (par[2] != 0)
606     lim = ( par[1] - invX ) / par[2] ;
607    
608     N = par[0];
609    
610    
611    
612     if(lim < par[3])
613     fitval = N * f1;
614     if(lim >= par[3])
615     fitval = N * f2;
616    
617     return fitval;
618     }
619    
620    
621     Double_t DoubleInvCrystalBall(Double_t *x,Double_t *par)
622     {
623     Double_t arg1=0,arg2=0,A=0,B=0;
624     Double_t f1=0;
625     Double_t f2=0;
626     Double_t lim=0;
627     Double_t fitval=0;
628     Double_t N=0;
629     Double_t n=par[4];
630    
631     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
632     Double_t Sf1=0;
633     Double_t Sf2=0;
634     Double_t Slim=0;
635     Double_t Sfitval=0;
636     Double_t SN=0;
637     Double_t Sn=par[9];
638    
639     Double_t invX = -x[0];
640    
641     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
642    
643     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
644    
645     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
646     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
647    
648     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
649     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
650    
651     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
652     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
653    
654     f1 = TMath::Exp(-0.5*arg1*arg1);
655     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
656    
657     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
658     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
659    
660     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
661     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
662    
663     N = par[0];
664     SN = par[5];
665    
666    
667    
668     if(lim < par[3]) fitval = N * f1;
669     if(lim >= par[3]) fitval = N * f2;
670    
671     if(Slim < par[8]) Sfitval = SN * Sf1;
672     if(Slim >= par[8]) Sfitval = SN * Sf2;
673    
674     return fitval+Sfitval;
675     }
676    
677     Double_t DoubleInvCrystalBallP(Double_t *x,Double_t *par)
678     {
679     Double_t arg1=0,arg2=0,A=0,B=0;
680     Double_t f1=0;
681     Double_t f2=0;
682     Double_t lim=0;
683     Double_t fitval=0;
684     Double_t N=0;
685     Double_t n=par[4];
686    
687     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
688     Double_t Sf1=0;
689     Double_t Sf2=0;
690     Double_t Slim=0;
691     Double_t Sfitval=0;
692     Double_t SN=0;
693     Double_t Sn=par[9];
694    
695     Double_t invX = -x[0];
696    
697     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
698    
699     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
700    
701     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
702     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
703    
704     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
705     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
706    
707     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
708     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
709    
710     f1 = TMath::Exp(-0.5*arg1*arg1);
711     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
712    
713     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
714     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
715    
716     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
717     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
718    
719     N = par[0];
720     SN = par[5];
721    
722    
723    
724     if(lim < par[3]) fitval = N * f1;
725     if(lim >= par[3]) fitval = N * f2;
726    
727     if(Slim < par[8]) Sfitval = SN * Sf1;
728     if(Slim >= par[8]) Sfitval = SN * Sf2;
729    
730     fitval+=Sfitval;
731     fitval+=statErrorP(fitval);
732    
733     return fitval;
734     }
735    
736     Double_t DoubleInvCrystalBallN(Double_t *x,Double_t *par)
737     {
738     Double_t arg1=0,arg2=0,A=0,B=0;
739     Double_t f1=0;
740     Double_t f2=0;
741     Double_t lim=0;
742     Double_t fitval=0;
743     Double_t N=0;
744     Double_t n=par[4];
745    
746     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
747     Double_t Sf1=0;
748     Double_t Sf2=0;
749     Double_t Slim=0;
750     Double_t Sfitval=0;
751     Double_t SN=0;
752     Double_t Sn=par[9];
753    
754     Double_t invX = -x[0];
755    
756     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
757    
758     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
759    
760     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
761     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
762    
763     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
764     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
765    
766     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
767     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
768    
769     f1 = TMath::Exp(-0.5*arg1*arg1);
770     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
771    
772     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
773     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
774    
775     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
776     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
777    
778     N = par[0];
779     SN = par[5];
780    
781    
782    
783     if(lim < par[3]) fitval = N * f1;
784     if(lim >= par[3]) fitval = N * f2;
785    
786     if(Slim < par[8]) Sfitval = SN * Sf1;
787     if(Slim >= par[8]) Sfitval = SN * Sf2;
788    
789     fitval+=Sfitval;
790     fitval-=statErrorN(fitval);
791    
792     return fitval;
793     }
794    
795     Double_t InvCrystalBallP(Double_t *x,Double_t *par)
796     {
797     Double_t arg1=0,arg2=0,A=0,B=0;
798     Double_t f1=0;
799     Double_t f2=0;
800     Double_t lim=0;
801     Double_t fitval=0;
802     Double_t N=0;
803     Double_t n=par[4];
804    
805     Double_t invX = -x[0];
806    
807     if (par[2] != 0)
808     arg1 = (invX-par[1])/par[2];
809    
810     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
811    
812     if (par[3] != 0)
813     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
814    
815     if (par[3] != 0)
816     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
817    
818     f1 = TMath::Exp(-0.5*arg1*arg1);
819     if (par[2] != 0)
820     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
821    
822     if (par[2] != 0)
823     lim = ( par[1] - invX ) / par[2] ;
824    
825     N = par[0];
826    
827    
828    
829     if(lim < par[3])
830     fitval = N * f1;
831     if(lim >= par[3])
832     fitval = N * f2;
833    
834     fitval+= statErrorP(fitval);
835     return fitval;
836     }
837    
838     Double_t InvCrystalBallN(Double_t *x,Double_t *par)
839     {
840     Double_t arg1=0,arg2=0,A=0,B=0;
841     Double_t f1=0;
842     Double_t f2=0;
843     Double_t lim=0;
844     Double_t fitval=0;
845     Double_t N=0;
846     Double_t n=par[4];
847    
848     Double_t invX = -x[0];
849    
850     if (par[2] != 0)
851     arg1 = (invX-par[1])/par[2];
852    
853     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
854    
855     if (par[3] != 0)
856     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
857    
858     if (par[3] != 0)
859     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
860    
861     f1 = TMath::Exp(-0.5*arg1*arg1);
862     if (par[2] != 0)
863     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
864    
865     if (par[2] != 0)
866     lim = ( par[1] - invX ) / par[2] ;
867    
868     N = par[0];
869    
870    
871    
872     if(lim < par[3])
873     fitval = N * f1;
874     if(lim >= par[3])
875     fitval = N * f2;
876    
877     fitval-= statErrorN(fitval);
878     return fitval;
879     }
880    
881