ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/AnalysisFramework/Plotting/Modules/PeakFinder.C
Revision: 1.6
Committed: Wed Jul 20 08:51:33 2011 UTC (13 years, 9 months ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.5: +10 -11 lines
Log Message:
Adapted the output; all output is now written on screen and to a file simultaneously

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     mean = hist->GetBinCenter( hist->GetMaximumBin());
231    
232     fitFunc->SetParameter(1,mean);
233    
234     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
235    
236     mean=fitFunc->GetParameter(1);
237     rms=fitFunc->GetParameter(2);
238     error=fitFunc->GetParError(1);
239    
240     bool printOut = false; // print the peak estimate in the i-th iteration
241    
242     // --- perform iterations
243     int numIterations=5;
244    
245 buchmann 1.6 if(printOut) dout << " ( ";
246 buchmann 1.1 for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
247     {
248     hist->Fit(fitFunc,"QLLN","same",mean - lowlimit*rms, mean + highlimit*rms); // fit -2 +1 sigma from previous iteration
249     mean=fitFunc->GetParameter(1);
250     fitFunc->SetRange(mean - lowlimit*rms, mean + highlimit*rms);
251 buchmann 1.6 if(printOut) dout << mean << ",";
252 buchmann 1.1 }
253 buchmann 1.6 if(printOut) dout << " ) ";
254     if(printOut) dout << endl;
255 buchmann 1.1 mean=fitFunc->GetParameter(1);
256     sigma=fitFunc->GetParameter(2);
257     error=1.0*fitFunc->GetParError(1);
258    
259     // below this point we're merely doing cosmetics :-)
260 buchmann 1.4 TCanvas *peakfitcanvas = new TCanvas("peakfitcanvas","Fitting Canvas");
261     peakfitcanvas->cd();
262    
263 buchmann 1.1 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 buchmann 1.4
280 buchmann 1.1 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 buchmann 1.5 // TText* toptitle;
300     // if(is_data) toptitle = write_title("Fit Result (data)");
301     // else toptitle = write_title("Fit Result (MC)");
302     // toptitle->Draw();
303 buchmann 1.1 ftitle->Draw();
304     title1->Draw();
305     sigmatext->Draw();
306 buchmann 1.4 if(!is_data) CompleteSave(peakfitcanvas,"fit/Fit_Summary_MC");
307     if(is_data) CompleteSave(peakfitcanvas,"fit/Fit_Summary_Data");
308     delete peakfitcanvas;
309 buchmann 1.1
310 buchmann 1.6 // dout << "[" << fitFunc->GetParameter(1) << " , " << fitFunc->GetParError(1) << "]" << endl;
311 buchmann 1.1 return mean;
312     }
313    
314    
315    
316     float find_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma, int method)
317     {
318 buchmann 1.4 float peak_position=0;
319 buchmann 1.1 if(method==0||method>1) {
320     //looking at a gaus request
321     int numsig=1;
322     if(method>1) numsig=method;
323     peak_position=find_Gauss_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma,numsig);
324     }
325     if(method==1) {
326     //looking at a KM request
327     peak_position=find_KM_peak(all,ttbar,minfit,maxfit,is_data,error,Sigma);
328     }
329     if(method==-99) { // KOSTAS!!
330     TF1 *f1 = new TF1("f1","gaus",-40,40);
331     peak_position=Kostas_algorithm(all,error,Sigma,f1,2.5,2.5,is_data);
332     }
333     return peak_position;
334     }
335    
336    
337     float get_Gaussian_peak(TH1F *hist, float &error, float &sigma, TF1* fitFunc, float lowlimit, float highlimit,bool is_data,int numsig)
338     {
339     TCanvas *fitcanvas = new TCanvas("fitcanvas","fitcanvas");
340     float mean = hist->GetBinCenter( hist->GetMaximumBin());
341     float rms = hist->GetRMS();
342    
343     mean = hist->GetBinCenter( hist->GetMaximumBin());
344    
345     fitFunc->SetParameter(1,mean);
346    
347     hist->Fit(fitFunc,"QLL0","",mean-10,mean+10);
348    
349     mean=fitFunc->GetParameter(1);
350     rms=fitFunc->GetParameter(2);
351     error=fitFunc->GetParError(1);
352    
353     bool printOut = false; // print the peak estimate in the i-th iteration
354    
355     // --- perform iterations
356     int numIterations=5;
357    
358 buchmann 1.6 if(printOut) dout << " ( ";
359 buchmann 1.1 for(int i=1;i<numIterations+1;i++) //--- modify the number of iterations until peak is stable
360     {
361     hist->Fit(fitFunc,"QLLN","same",mean - numsig*rms, mean + numsig*rms); // fit -2 +1 sigma from previous iteration
362     mean=fitFunc->GetParameter(1);
363     fitFunc->SetRange(mean - numsig*rms, mean + numsig*rms);
364 buchmann 1.6 if(printOut) dout << mean << ",";
365 buchmann 1.1 }
366 buchmann 1.6 if(printOut) dout << " ) ";
367     if(printOut) dout << endl;
368 buchmann 1.1 mean=fitFunc->GetParameter(1);
369     sigma=fitFunc->GetParameter(2);
370     error=1.0*fitFunc->GetParError(1);
371     fitcanvas->cd();
372     hist->SetMinimum(0);
373     if(is_data) hist->Draw("e1");
374     else hist->Draw("histo");
375     fitFunc->SetLineColor(kBlue);
376     fitFunc->SetLineWidth(1);
377     fitFunc->Draw("same");
378     hist->SetStats(0);
379     TLegend *leg;
380     if(is_data) {
381     leg= make_legend("Fit (Data)");
382     leg->AddEntry(hist,"Data","p");
383     }
384     else {
385     leg= make_legend("Fit (MC)");
386     leg->AddEntry(hist,"MC","l");
387     }
388    
389     leg->AddEntry(fitFunc,"Fit","l");
390     leg->Draw();
391    
392     TText *ftitle=write_text(0.20,0.86,"Fit results:");
393     ftitle->SetTextSize(0.03);
394     ftitle->SetTextAlign(11);
395     stringstream fitresult;
396     fitresult << "#mu=" << std::setprecision(4) << mean << "+/-" << std::setprecision(4) << error;
397     // TText *title1=write_text(0.20,0.96,fitresult.str().c_str());
398     TText *title1=write_text(0.20,0.82,fitresult.str().c_str());
399     title1->SetTextSize(0.03);
400     title1->SetTextAlign(11);
401     stringstream sigmainfo;
402     sigmainfo << "#sigma=" << std::setprecision(4) << fitFunc->GetParameter(2) << "+/-" << std::setprecision(4) << fitFunc->GetParError(2);
403     // TText *sigmatext=write_text(0.80,0.96,sigmainfo.str().c_str());
404     TText *sigmatext=write_text(0.20,0.78,sigmainfo.str().c_str());
405     sigmatext->SetTextSize(0.03);
406     sigmatext->SetTextAlign(11);
407    
408     TText* toptitle;
409     if(is_data) toptitle = write_title("Fit Result (data)");
410     else toptitle = write_title("Fit Result (MC)");
411     toptitle->Draw();
412     ftitle->Draw();
413     title1->Draw();
414     sigmatext->Draw();
415     if(!is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_MC");
416     if(is_data) CompleteSave(fitcanvas,"fit/Fit_Summary_Data");
417    
418    
419 buchmann 1.6 // dout << "[" << fitFunc->GetParameter(1) << " , " << fitFunc->GetParError(1) << "]" << endl;
420 buchmann 1.1 return mean;
421     }
422    
423    
424     float find_Gauss_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma,int numsig)
425     {
426     TF1 *fitfunc = new TF1("fitfunc","gaus",minfit,maxfit);
427     float peakpos = get_Gaussian_peak(all,error,Sigma,fitfunc, minfit, maxfit,is_data,numsig);
428     return peakpos;
429     }
430    
431     float find_KM_peak(TH1F *all, TH1F *ttbar, float minfit, float maxfit, bool is_data, float &error,float &Sigma)
432     {
433     all->SetLineColor(kBlue);
434     all->SetStats(0);
435     all->SetTitle("");
436     all->GetXaxis()->SetTitle("JZB (GeV/c)");
437     all->GetYaxis()->SetTitle("events");
438     all->GetXaxis()->CenterTitle();
439     all->GetYaxis()->CenterTitle();
440     TF1 *fitfunc = new TF1("fitfunc",KrystalMallLogPar,0.8*minfit,0.8*maxfit,8);
441     if(!is_data)
442     {
443     TF1 *logpar = new TF1("logpar",LogParabola,minfit,maxfit,3);
444     do_ttbar_fit(ttbar,logpar,fitfunc);
445     fitfunc->SetParameters(1000,2,2.5,-1.6,4,logpar->GetParameter(0),logpar->GetParameter(1),logpar->GetParameter(2));
446     parabola_height=logpar->GetParameter(0);
447     parabola_inclination=logpar->GetParameter(1);
448     parabola_pointzero=logpar->GetParameter(2);
449     dofixed=true;//ttbar is known so we can fix the parameters and don't need to use them for fitting!
450     }
451     else
452     {
453     fitfunc->SetParameters(1000,2,2.5,-1.6,4,5.45039,0.000324593,12.3528);
454     dofixed=false;
455     }
456    
457     vector<float> chi2values;
458     addparabola=true;
459     for (int ifit=0;ifit<100;ifit++)
460     {
461     all->Fit(fitfunc,"NQ");
462     chi2values.push_back(fitfunc->GetChisquare());
463     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
464     }
465     /*
466     The parameters represent the following quantities:
467     float N=par[0];
468     float alpha=par[1];
469     float n=par[2];
470     float xbar=par[3];
471     float sigma=par[4];
472     */
473     //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".
474     low_reject=-2*fitfunc->GetParameter(4)+fitfunc->GetParameter(3);
475     hi_reject=fitfunc->GetParameter(3)+2*fitfunc->GetParameter(4);
476     if(low_reject>-15) low_reject=-10;
477     if(hi_reject<15) hi_reject=10;
478     doreject=true;//activating the rejection :-)
479    
480     for (int ifit=0;ifit<100;ifit++)
481     {
482     all->Fit(fitfunc,"NQ");
483     chi2values.push_back(fitfunc->GetChisquare());
484     if(ifit>5&&chi2values[ifit-2]==chi2values[ifit]) break;
485     }
486    
487     draw_complete_fit(all,ttbar,minfit,maxfit,is_data,fitfunc);
488     doreject=true;
489     error=fitfunc->GetParError(3);
490     Sigma=fitfunc->GetParameter(4);//sigma
491    
492     return fitfunc->GetParameter(3);
493     }
494    
495     Double_t InvCrystalBall(Double_t *x,Double_t *par)
496     {
497     Double_t arg1=0,arg2=0,A=0,B=0;
498     Double_t f1=0;
499     Double_t f2=0;
500     Double_t lim=0;
501     Double_t fitval=0;
502     Double_t N=0;
503     Double_t n=par[4];
504    
505     Double_t invX = -x[0];
506    
507     if (par[2] != 0)
508     arg1 = (invX-par[1])/par[2];
509    
510     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
511    
512     if (par[3] != 0)
513     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
514    
515     if (par[3] != 0)
516     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
517    
518     f1 = TMath::Exp(-0.5*arg1*arg1);
519     if (par[2] != 0)
520     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
521    
522     if (par[2] != 0)
523     lim = ( par[1] - invX ) / par[2] ;
524    
525     N = par[0];
526    
527    
528    
529     if(lim < par[3])
530     fitval = N * f1;
531     if(lim >= par[3])
532     fitval = N * f2;
533    
534     return fitval;
535     }
536    
537 buchmann 1.3 Double_t OUTDoubleInvCrystalBall(Double_t *x,Double_t *par) {
538     Double_t secondpar[5];
539     for(int i=5;i<10;i++) {
540     secondpar[i]=par[i-5];
541     }
542     return InvCrystalBall(x,par)+InvCrystalBall(x,secondpar);
543     }
544    
545     Double_t DoubleInvCrystalBall(Double_t *x,Double_t *par)
546     {
547     Double_t arg1=0,arg2=0,A=0,B=0;
548     Double_t f1=0;
549     Double_t f2=0;
550     Double_t lim=0;
551     Double_t fitval=0;
552     Double_t N=0;
553     Double_t n=par[4];
554    
555     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
556     Double_t Sf1=0;
557     Double_t Sf2=0;
558     Double_t Slim=0;
559     Double_t Sfitval=0;
560     Double_t SN=0;
561     Double_t Sn=par[9];
562    
563     Double_t invX = -x[0];
564    
565     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
566    
567     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
568    
569     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
570     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
571    
572     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
573     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
574    
575     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
576     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
577    
578     f1 = TMath::Exp(-0.5*arg1*arg1);
579     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
580    
581     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
582     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
583    
584     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
585     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
586    
587     N = par[0];
588     SN = par[5];
589    
590    
591    
592     if(lim < par[3]) fitval = N * f1;
593     if(lim >= par[3]) fitval = N * f2;
594    
595     if(Slim < par[8]) Sfitval = SN * Sf1;
596     if(Slim >= par[8]) Sfitval = SN * Sf2;
597    
598     return fitval+Sfitval;
599     }
600    
601 buchmann 1.4 Double_t DoubleInvCrystalBallP(Double_t *x,Double_t *par)
602     {
603     Double_t arg1=0,arg2=0,A=0,B=0;
604     Double_t f1=0;
605     Double_t f2=0;
606     Double_t lim=0;
607     Double_t fitval=0;
608     Double_t N=0;
609     Double_t n=par[4];
610    
611     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
612     Double_t Sf1=0;
613     Double_t Sf2=0;
614     Double_t Slim=0;
615     Double_t Sfitval=0;
616     Double_t SN=0;
617     Double_t Sn=par[9];
618    
619     Double_t invX = -x[0];
620    
621     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
622    
623     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
624    
625     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
626     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
627    
628     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
629     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
630    
631     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
632     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
633    
634     f1 = TMath::Exp(-0.5*arg1*arg1);
635     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
636    
637     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
638     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
639    
640     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
641     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
642    
643     N = par[0];
644     SN = par[5];
645    
646    
647    
648     if(lim < par[3]) fitval = N * f1;
649     if(lim >= par[3]) fitval = N * f2;
650    
651     if(Slim < par[8]) Sfitval = SN * Sf1;
652     if(Slim >= par[8]) Sfitval = SN * Sf2;
653    
654     fitval+=Sfitval;
655     fitval+=statErrorP(fitval);
656    
657     return fitval;
658     }
659    
660     Double_t DoubleInvCrystalBallN(Double_t *x,Double_t *par)
661     {
662     Double_t arg1=0,arg2=0,A=0,B=0;
663     Double_t f1=0;
664     Double_t f2=0;
665     Double_t lim=0;
666     Double_t fitval=0;
667     Double_t N=0;
668     Double_t n=par[4];
669    
670     Double_t Sarg1=0,Sarg2=0,SA=0,SB=0;
671     Double_t Sf1=0;
672     Double_t Sf2=0;
673     Double_t Slim=0;
674     Double_t Sfitval=0;
675     Double_t SN=0;
676     Double_t Sn=par[9];
677    
678     Double_t invX = -x[0];
679    
680     if (par[2] != 0) arg1 = (invX-par[1])/par[2];
681    
682     if (par[7] != 0) Sarg1 = (invX-par[6])/par[7];
683    
684     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
685     Sarg2 = ( -pow( TMath::Abs(par[8]) , 2 ) ) / 2 ;
686    
687     if (par[3] != 0) A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
688     if (par[8] != 0) SA = pow( ( Sn / TMath::Abs( par[8] ) ) , Sn) * TMath::Exp(Sarg2);
689    
690     if (par[3] != 0) B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
691     if (par[8] != 0) SB = Sn / TMath::Abs(par[8]) - TMath::Abs(par[8]);
692    
693     f1 = TMath::Exp(-0.5*arg1*arg1);
694     Sf1 = TMath::Exp(-0.5*Sarg1*Sarg1);
695    
696     if (par[2] != 0) f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
697     if (par[7] != 0) Sf2 = SA * pow( ( SB - (invX - par[6])/par[7] ) , -Sn );
698    
699     if (par[2] != 0) lim = ( par[1] - invX ) / par[2] ;
700     if (par[7] != 0) Slim = ( par[6] - invX ) / par[7] ;
701    
702     N = par[0];
703     SN = par[5];
704    
705    
706    
707     if(lim < par[3]) fitval = N * f1;
708     if(lim >= par[3]) fitval = N * f2;
709    
710     if(Slim < par[8]) Sfitval = SN * Sf1;
711     if(Slim >= par[8]) Sfitval = SN * Sf2;
712    
713     fitval+=Sfitval;
714     fitval-=statErrorN(fitval);
715    
716     return fitval;
717     }
718 buchmann 1.3
719 buchmann 1.1 Double_t InvCrystalBallP(Double_t *x,Double_t *par)
720     {
721     Double_t arg1=0,arg2=0,A=0,B=0;
722     Double_t f1=0;
723     Double_t f2=0;
724     Double_t lim=0;
725     Double_t fitval=0;
726     Double_t N=0;
727     Double_t n=par[4];
728    
729     Double_t invX = -x[0];
730    
731     if (par[2] != 0)
732     arg1 = (invX-par[1])/par[2];
733    
734     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
735    
736     if (par[3] != 0)
737     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
738    
739     if (par[3] != 0)
740     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
741    
742     f1 = TMath::Exp(-0.5*arg1*arg1);
743     if (par[2] != 0)
744     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
745    
746     if (par[2] != 0)
747     lim = ( par[1] - invX ) / par[2] ;
748    
749     N = par[0];
750    
751    
752    
753     if(lim < par[3])
754     fitval = N * f1;
755     if(lim >= par[3])
756     fitval = N * f2;
757    
758     fitval+= statErrorP(fitval);
759     return fitval;
760     }
761    
762     Double_t InvCrystalBallN(Double_t *x,Double_t *par)
763     {
764     Double_t arg1=0,arg2=0,A=0,B=0;
765     Double_t f1=0;
766     Double_t f2=0;
767     Double_t lim=0;
768     Double_t fitval=0;
769     Double_t N=0;
770     Double_t n=par[4];
771    
772     Double_t invX = -x[0];
773    
774     if (par[2] != 0)
775     arg1 = (invX-par[1])/par[2];
776    
777     arg2 = ( -pow( TMath::Abs(par[3]) , 2 ) ) / 2 ;
778    
779     if (par[3] != 0)
780     A = pow( ( n / TMath::Abs( par[3] ) ) , n) * TMath::Exp(arg2);
781    
782     if (par[3] != 0)
783     B = n / TMath::Abs(par[3]) - TMath::Abs(par[3]);
784    
785     f1 = TMath::Exp(-0.5*arg1*arg1);
786     if (par[2] != 0)
787     f2 = A * pow( ( B - (invX - par[1])/par[2] ) , -n );
788    
789     if (par[2] != 0)
790     lim = ( par[1] - invX ) / par[2] ;
791    
792     N = par[0];
793    
794    
795    
796     if(lim < par[3])
797     fitval = N * f1;
798     if(lim >= par[3])
799     fitval = N * f2;
800    
801     fitval-= statErrorN(fitval);
802     return fitval;
803     }
804    
805