ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/PeakFinder.C
Revision: 1.2
Committed: Thu Jun 30 09:37:29 2011 UTC (13 years, 10 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.1: +16 -0 lines
Log Message:
Looking into Z+Jets and TTbar shapes (from data); Added band for LogParabola

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 buchmann 1.2 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 buchmann 1.1 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    
63     Double_t KrystalMallLogPar(double *x, double *par)
64     {
65     //parameters:
66     //N: the way we scale the function
67     //alpha (where the function changes)
68     //n: exponent of the power expression in the left area
69     //xbar: peak of the gaussian part (RHS)
70     //sigma: width of the gaussian part (RHS)
71     float N=par[0];
72     float alpha=par[1];
73     float n=par[2];
74     float xbar=par[3];
75     float sigma=par[4];
76     float altX=x[0];
77     float result=-999;
78     if(doreject&&x[0]>low_reject&&x[0]<hi_reject)
79     {
80     TF1::RejectPoint();
81     return 0;
82     }
83     if(((altX-xbar)/sigma>-alpha)&&((altX-xbar)/sigma<alpha)){
84     result=N*TMath::Exp(-(altX-xbar)*(altX-xbar)/(2*sigma*sigma));
85     }
86     else
87     {
88     //if we are outside the central (Gaussian) area things become more difficult ...
89     float A=TMath::Power(n/TMath::Abs(alpha),n)*TMath::Exp(-alpha*alpha/2);
90     float B=n/TMath::Abs(alpha) - TMath::Abs(alpha);
91     if((altX-xbar)/sigma<=-alpha) result=N*A*TMath::Power((B-((altX-xbar)/sigma)),-n);
92     if((altX-xbar)/sigma>=alpha) result=N*A*TMath::Power((B+((altX-xbar)/sigma)),-n);
93     }
94    
95     if(addparabola) {
96     if(dofixed) {
97     result+=parabola_height*TMath::Exp(-parabola_inclination*(x[0]-parabola_pointzero)*(x[0]-parabola_pointzero)); // we're adding a "logarithmic parabola" :-)
98     }
99     else {
100     result+=par[5]*TMath::Exp(-par[6]*(x[0]-par[7])*(x[0]-par[7])); // we're adding a "logarithmic parabola" :-)
101     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.
102     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)
103     }
104     }
105     return result;
106     }
107    
108    
109     void do_ttbar_fit(TH1F *ttbar,TF1 *logpar, TF1 *KM)
110     {
111     logpar->SetParameters(10,2,3);
112     ttbar->Fit(logpar,"NQ");
113     ttbar->Fit(logpar,"NQ");
114     ttbar->Fit(logpar,"NQ");
115     ttbar->Fit(logpar,"NQ");
116     ttbar->SetStats(0);
117     parabola_height=logpar->GetParameter(0);
118     parabola_inclination=logpar->GetParameter(1);
119     parabola_pointzero=logpar->GetParameter(2);
120     }
121    
122     void draw_complete_fit(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, TF1 *KM)
123     {
124     TCanvas *fitsummary;
125     if(is_data) {
126     fitsummary= new TCanvas("fitsummary","Fit Summary",1000,500);
127     fitsummary->Divide(2,1);
128     }
129     else {
130     fitsummary= new TCanvas("fitsummary","Fit Summary",1200,400);
131     fitsummary->Divide(3,1);
132     }
133     TF1 *logpar = new TF1("logpar",LogParabola,minfit,maxfit,3);
134    
135     logpar->SetParameters(KM->GetParameter(5),KM->GetParameter(6),KM->GetParameter(7));
136     logpar->SetLineColor(kOrange);
137     logpar->SetLineStyle(2);
138     if(!is_data)
139     {
140     ttbar->GetXaxis()->SetTitle("JZB (GeV/c)");
141     ttbar->GetYaxis()->SetTitle("events");
142     ttbar->GetXaxis()->CenterTitle();
143     ttbar->GetYaxis()->CenterTitle();
144     ttbar->SetLineColor(kRed);
145     fitsummary->cd(1);
146     ttbar->Draw();
147     fitsummary->cd(1);
148     logpar->Draw("same");
149     TLegend *leg = new TLegend(0.3,0.25,0.65,0.4);
150     leg->AddEntry(ttbar,"t#bar{t} (mc)","l");
151     leg->AddEntry(logpar,"Fit with Log. Parabola","l");
152     leg->SetLineColor(kWhite);
153     leg->SetFillColor(kWhite);
154     leg->Draw();
155     TText *title1=write_title("t#bar{t} Distribution and Fit");
156     title1->Draw();
157     }
158     fitsummary->cd(2-int(is_data));
159     fitsummary->cd(2-int(is_data))->SetLogy(1);
160     all->GetYaxis()->SetTitle("events");
161     all->GetYaxis()->CenterTitle();
162     all->Draw();
163     ttbar->SetLineColor(kRed);
164     if(!is_data) ttbar->Draw("same");
165     KM->SetLineWidth(1);
166     KM->Draw("same");
167     logpar->SetLineWidth(1);
168     logpar->Draw("same");
169     if(!is_data)ttbar->Draw("same");
170     TLegend *leg2 = new TLegend(0.65,0.65,0.89,0.89);
171     if(is_data) leg2->AddEntry(all,"Data","l");
172     else leg2->AddEntry(all,"Stacked MC","l");
173     leg2->AddEntry(KM,"Fitted KM Function","l");
174     if(!is_data) leg2->AddEntry(ttbar,"t#bar{t} MC","l");
175     leg2->AddEntry(logpar,"t#bar{t} (Fit)","l");
176     leg2->SetFillColor(kWhite);
177     leg2->SetLineColor(kWhite);
178     leg2->Draw();
179     TText *title2=write_title("Distribution and Fits (log.)");
180     title2->Draw();
181     fitsummary->cd(3-is_data);
182     all->Draw();
183     KM->Draw("same");
184     float peaklocation=KM->GetParameter(3);
185     TLine *muline = new TLine(peaklocation,0,peaklocation,all->GetMaximum());
186     muline->SetLineColor(kBlue);
187     muline->SetLineStyle(2);
188     muline->Draw();
189     TLegend *leg = new TLegend(0.6,0.6,0.89,0.89);
190     if(is_data) leg2->AddEntry(all,"Data","l");
191     else leg->AddEntry(all,"Stacked MC","l");
192     leg->AddEntry(KM,"Fitted KM Function","l");
193     stringstream mulinelabel;
194     mulinelabel<<"Peak position at #mu="<<peaklocation;
195     leg->AddEntry(muline,mulinelabel.str().c_str(),"l");
196     leg->SetLineColor(kWhite);
197     leg->SetFillColor(kWhite);
198     leg->Draw();
199     mulinelabel<<"+/-"<<TMath::Abs(KM->GetParError(3));
200     TText *title3=write_title("Distribution and Fits");
201     title3->Draw();
202     TText *titlel=write_title_low(mulinelabel.str().c_str());
203     titlel->Draw();
204    
205     stringstream printtop;
206     printtop << "#mu="<<std::setprecision(3)<<KM->GetParameter(3)<<"+/-"<<std::setprecision(3)<<KM->GetParError(3);
207     TLatex *toptext = new TLatex(0,all->GetMaximum()*1.3,printtop.str().c_str());
208     toptext->SetTextAlign(22);
209     // toptext->Draw();
210    
211     doreject=false;
212     TF1 *wholefitfunc=(TF1*)KM->Clone();
213     doreject=true;
214     wholefitfunc->SetLineColor(kRed);
215     wholefitfunc->SetLineStyle(2);
216     wholefitfunc->Draw("same");
217    
218     fitsummary->cd(2-is_data);
219     wholefitfunc->Draw("same");
220    
221     if(is_data) CompleteSave(fitsummary, "fit/Fit_Summary_Data");
222     else CompleteSave(fitsummary,"fit/Fit_Summary_MC");
223    
224     }
225    
226     float Kostas_algorithm(TH1F *hist, float &error, float &sigma, TF1* fitFunc, float lowlimit, float highlimit,bool is_data)
227     {
228     float mean = hist->GetBinCenter( hist->GetMaximumBin());
229     float rms = hist->GetRMS();
230    
231     mean = hist->GetBinCenter( hist->GetMaximumBin());
232    
233     fitFunc->SetParameter(1,mean);
234    
235     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
236    
237     mean=fitFunc->GetParameter(1);
238     rms=fitFunc->GetParameter(2);
239     error=fitFunc->GetParError(1);
240    
241     bool printOut = false; // print the peak estimate in the i-th iteration
242    
243     // --- perform iterations
244     int numIterations=5;
245    
246     if(printOut) std::cout << " ( ";
247     for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
248     {
249     hist->Fit(fitFunc,"QLLN","same",mean - lowlimit*rms, mean + highlimit*rms); // fit -2 +1 sigma from previous iteration
250     mean=fitFunc->GetParameter(1);
251     fitFunc->SetRange(mean - lowlimit*rms, mean + highlimit*rms);
252     if(printOut) std::cout << mean << ",";
253     }
254     if(printOut) std::cout << " ) ";
255     if(printOut) std::cout << endl;
256     mean=fitFunc->GetParameter(1);
257     sigma=fitFunc->GetParameter(2);
258     error=1.0*fitFunc->GetParError(1);
259    
260     // below this point we're merely doing cosmetics :-)
261     TCanvas *fitcanvas = new TCanvas("fitcanvas","Fitting Canvas");
262     fitcanvas->cd();
263     hist->SetMinimum(0);
264     if(is_data) hist->Draw("e1");
265     else hist->Draw("histo");
266     fitFunc->SetLineColor(kBlue);
267     fitFunc->SetLineWidth(1);
268     fitFunc->Draw("same");
269     hist->SetStats(0);
270     TLegend *leg;
271     if(is_data) {
272     leg= make_legend("Fit (Data)");
273     leg->AddEntry(hist,"Data","p");
274     }
275     else {
276     leg= make_legend("Fit (MC)");
277     leg->AddEntry(hist,"MC","l");
278     }
279    
280     leg->AddEntry(fitFunc,"Fit","l");
281     leg->Draw();
282    
283     TText *ftitle=write_text(0.20,0.86,"Fit results:");
284     ftitle->SetTextSize(0.03);
285     ftitle->SetTextAlign(11);
286     stringstream fitresult;
287     fitresult << "#mu=" << std::setprecision(4) << mean << "+/-" << std::setprecision(4) << error;
288     // TText *title1=write_text(0.20,0.96,fitresult.str().c_str());
289     TText *title1=write_text(0.20,0.82,fitresult.str().c_str());
290     title1->SetTextSize(0.03);
291     title1->SetTextAlign(11);
292     stringstream sigmainfo;
293     sigmainfo << "#sigma=" << std::setprecision(4) << fitFunc->GetParameter(2) << "+/-" << std::setprecision(4) << fitFunc->GetParError(2);
294     // TText *sigmatext=write_text(0.80,0.96,sigmainfo.str().c_str());
295     TText *sigmatext=write_text(0.20,0.78,sigmainfo.str().c_str());
296     sigmatext->SetTextSize(0.03);
297     sigmatext->SetTextAlign(11);
298    
299     TText* toptitle;
300     if(is_data) toptitle = write_title("Fit Result (data)");
301     else toptitle = write_title("Fit Result (MC)");
302     toptitle->Draw();
303     ftitle->Draw();
304     title1->Draw();
305     sigmatext->Draw();
306     if(!is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_MC");
307     if(is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_Data");
308    
309    
310    
311     // cout << "[" << fitFunc->GetParameter(1) << " , " << fitFunc->GetParError(1) << "]" << endl;
312     return mean;
313     }
314    
315    
316    
317     float find_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma, int method)
318     {
319     float peak_position;
320     if(method==0||method>1) {
321     //looking at a gaus request
322     int numsig=1;
323     if(method>1) numsig=method;
324     peak_position=find_Gauss_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma,numsig);
325     }
326     if(method==1) {
327     //looking at a KM request
328     peak_position=find_KM_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma);
329     }
330     if(method==-99) { // KOSTAS!!
331     TF1 *f1 = new TF1("f1","gaus",-40,40);
332     peak_position=Kostas_algorithm(all,error,Sigma,f1,2.5,2.5,is_data);
333     }
334     return peak_position;
335     }
336    
337    
338     float get_Gaussian_peak(TH1F *hist, float &error, float &sigma, TF1* fitFunc, float lowlimit, float highlimit,bool is_data,int numsig)
339     {
340     TCanvas *fitcanvas = new TCanvas("fitcanvas","fitcanvas");
341     float mean = hist->GetBinCenter( hist->GetMaximumBin());
342     float rms = hist->GetRMS();
343    
344     mean = hist->GetBinCenter( hist->GetMaximumBin());
345    
346     fitFunc->SetParameter(1,mean);
347    
348     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
349    
350     mean=fitFunc->GetParameter(1);
351     rms=fitFunc->GetParameter(2);
352     error=fitFunc->GetParError(1);
353    
354     bool printOut = false; // print the peak estimate in the i-th iteration
355    
356     // --- perform iterations
357     int numIterations=5;
358    
359     if(printOut) std::cout << " ( ";
360     for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
361     {
362     hist->Fit(fitFunc,"QLLN","same",mean - numsig*rms, mean + numsig*rms); // fit -2 +1 sigma from previous iteration
363     mean=fitFunc->GetParameter(1);
364     fitFunc->SetRange(mean - numsig*rms, mean + numsig*rms);
365     if(printOut) std::cout << mean << ",";
366     }
367     if(printOut) std::cout << " ) ";
368     if(printOut) std::cout << endl;
369     mean=fitFunc->GetParameter(1);
370     sigma=fitFunc->GetParameter(2);
371     error=1.0*fitFunc->GetParError(1);
372     fitcanvas->cd();
373     hist->SetMinimum(0);
374     if(is_data) hist->Draw("e1");
375     else hist->Draw("histo");
376     fitFunc->SetLineColor(kBlue);
377     fitFunc->SetLineWidth(1);
378     fitFunc->Draw("same");
379     hist->SetStats(0);
380     TLegend *leg;
381     if(is_data) {
382     leg= make_legend("Fit (Data)");
383     leg->AddEntry(hist,"Data","p");
384     }
385     else {
386     leg= make_legend("Fit (MC)");
387     leg->AddEntry(hist,"MC","l");
388     }
389    
390     leg->AddEntry(fitFunc,"Fit","l");
391     leg->Draw();
392    
393     TText *ftitle=write_text(0.20,0.86,"Fit results:");
394     ftitle->SetTextSize(0.03);
395     ftitle->SetTextAlign(11);
396     stringstream fitresult;
397     fitresult << "#mu=" << std::setprecision(4) << mean << "+/-" << std::setprecision(4) << error;
398     // TText *title1=write_text(0.20,0.96,fitresult.str().c_str());
399     TText *title1=write_text(0.20,0.82,fitresult.str().c_str());
400     title1->SetTextSize(0.03);
401     title1->SetTextAlign(11);
402     stringstream sigmainfo;
403     sigmainfo << "#sigma=" << std::setprecision(4) << fitFunc->GetParameter(2) << "+/-" << std::setprecision(4) << fitFunc->GetParError(2);
404     // TText *sigmatext=write_text(0.80,0.96,sigmainfo.str().c_str());
405     TText *sigmatext=write_text(0.20,0.78,sigmainfo.str().c_str());
406     sigmatext->SetTextSize(0.03);
407     sigmatext->SetTextAlign(11);
408    
409     TText* toptitle;
410     if(is_data) toptitle = write_title("Fit Result (data)");
411     else toptitle = write_title("Fit Result (MC)");
412     toptitle->Draw();
413     ftitle->Draw();
414     title1->Draw();
415     sigmatext->Draw();
416     if(!is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_MC");
417     if(is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_Data");
418    
419    
420     // cout << "[" << fitFunc->GetParameter(1) << " , " << fitFunc->GetParError(1) << "]" << endl;
421     return mean;
422     }
423    
424    
425     float find_Gauss_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma,int numsig)
426     {
427     TF1 *fitfunc = new TF1("fitfunc","gaus",minfit,maxfit);
428     float peakpos = get_Gaussian_peak(all,error,Sigma,fitfunc, minfit, maxfit,is_data,numsig);
429     return peakpos;
430     }
431    
432     float find_KM_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma)
433     {
434     all->SetLineColor(kBlue);
435     all->SetStats(0);
436     all->SetTitle("");
437     all->GetXaxis()->SetTitle("JZB (GeV/c)");
438     all->GetYaxis()->SetTitle("events");
439     all->GetXaxis()->CenterTitle();
440     all->GetYaxis()->CenterTitle();
441     TF1 *fitfunc = new TF1("fitfunc",KrystalMallLogPar,0.8*minfit,0.8*maxfit,8);
442     if(!is_data)
443     {
444     TF1 *logpar = new TF1("logpar",LogParabola,minfit,maxfit,3);
445     do_ttbar_fit(ttbar,logpar,fitfunc);
446     fitfunc->SetParameters(1000,2,2.5,-1.6,4,logpar->GetParameter(0),logpar->GetParameter(1),logpar->GetParameter(2));
447     parabola_height=logpar->GetParameter(0);
448     parabola_inclination=logpar->GetParameter(1);
449     parabola_pointzero=logpar->GetParameter(2);
450     dofixed=true;//ttbar is known so we can fix the parameters and don't need to use them for fitting!
451     }
452     else
453     {
454     fitfunc->SetParameters(1000,2,2.5,-1.6,4,5.45039,0.000324593,12.3528);
455     dofixed=false;
456     }
457    
458     vector<float> chi2values;
459     addparabola=true;
460     for (int ifit=0;ifit<100;ifit++)
461     {
462     all->Fit(fitfunc,"NQ");
463     chi2values.push_back(fitfunc->GetChisquare());
464     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
465     }
466     /*
467     The parameters represent the following quantities:
468     float N=par[0];
469     float alpha=par[1];
470     float n=par[2];
471     float xbar=par[3];
472     float sigma=par[4];
473     */
474     //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".
475     low_reject=-2*fitfunc->GetParameter(4)+fitfunc->GetParameter(3);
476     hi_reject=fitfunc->GetParameter(3)+2*fitfunc->GetParameter(4);
477     if(low_reject>-15) low_reject=-10;
478     if(hi_reject<15) hi_reject=10;
479     doreject=true;//activating the rejection :-)
480    
481     for (int ifit=0;ifit<100;ifit++)
482     {
483     all->Fit(fitfunc,"NQ");
484     chi2values.push_back(fitfunc->GetChisquare());
485     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
486     }
487    
488     draw_complete_fit(all,ttbar,minfit,maxfit,is_data,fitfunc);
489     doreject=true;
490     error=fitfunc->GetParError(3);
491     Sigma=fitfunc->GetParameter(4);//sigma
492    
493     return fitfunc->GetParameter(3);
494     }
495    
496     Double_t InvCrystalBall(Double_t *x,Double_t *par)
497     {
498     Double_t arg1=0,arg2=0,A=0,B=0;
499     Double_t f1=0;
500     Double_t f2=0;
501     Double_t lim=0;
502     Double_t fitval=0;
503     Double_t N=0;
504     Double_t n=par[4];
505    
506     Double_t invX = -x[0];
507    
508     if (par[2] != 0)
509     arg1 = (invX-par[1])/par[2];
510    
511     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
512    
513     if (par[3] != 0)
514     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
515    
516     if (par[3] != 0)
517     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
518    
519     f1 = TMath::Exp(-0.5*arg1*arg1);
520     if (par[2] != 0)
521     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
522    
523     if (par[2] != 0)
524     lim = ( par[1] - invX ) / par[2] ;
525    
526     N = par[0];
527    
528    
529    
530     if(lim < par[3])
531     fitval = N * f1;
532     if(lim >= par[3])
533     fitval = N * f2;
534    
535     return fitval;
536     }
537    
538     Double_t InvCrystalBallP(Double_t *x,Double_t *par)
539     {
540     Double_t arg1=0,arg2=0,A=0,B=0;
541     Double_t f1=0;
542     Double_t f2=0;
543     Double_t lim=0;
544     Double_t fitval=0;
545     Double_t N=0;
546     Double_t n=par[4];
547    
548     Double_t invX = -x[0];
549    
550     if (par[2] != 0)
551     arg1 = (invX-par[1])/par[2];
552    
553     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
554    
555     if (par[3] != 0)
556     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
557    
558     if (par[3] != 0)
559     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
560    
561     f1 = TMath::Exp(-0.5*arg1*arg1);
562     if (par[2] != 0)
563     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
564    
565     if (par[2] != 0)
566     lim = ( par[1] - invX ) / par[2] ;
567    
568     N = par[0];
569    
570    
571    
572     if(lim < par[3])
573     fitval = N * f1;
574     if(lim >= par[3])
575     fitval = N * f2;
576    
577     fitval+= statErrorP(fitval);
578     return fitval;
579     }
580    
581     Double_t InvCrystalBallN(Double_t *x,Double_t *par)
582     {
583     Double_t arg1=0,arg2=0,A=0,B=0;
584     Double_t f1=0;
585     Double_t f2=0;
586     Double_t lim=0;
587     Double_t fitval=0;
588     Double_t N=0;
589     Double_t n=par[4];
590    
591     Double_t invX = -x[0];
592    
593     if (par[2] != 0)
594     arg1 = (invX-par[1])/par[2];
595    
596     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
597    
598     if (par[3] != 0)
599     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
600    
601     if (par[3] != 0)
602     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
603    
604     f1 = TMath::Exp(-0.5*arg1*arg1);
605     if (par[2] != 0)
606     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
607    
608     if (par[2] != 0)
609     lim = ( par[1] - invX ) / par[2] ;
610    
611     N = par[0];
612    
613    
614    
615     if(lim < par[3])
616     fitval = N * f1;
617     if(lim >= par[3])
618     fitval = N * f2;
619    
620     fitval-= statErrorN(fitval);
621     return fitval;
622     }
623    
624