ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/PeakFinder.C
Revision: 1.3
Committed: Mon Jun 18 14:06:27 2012 UTC (12 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.2: +5 -18 lines
Log Message:
Added separate peak finding for electrons and muons

File Contents

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