1 /**************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /////////////////////////////////////////////////////////////
18 // AliHFMassFitter for the fit of invariant mass distribution
21 // Author: C.Bianchin, chiara.bianchin@pd.infn.it
22 /////////////////////////////////////////////////////////////
24 #include <Riostream.h>
32 #include <TVirtualPad.h>
34 #include <TVirtualFitter.h>
37 #include <TPaveText.h>
39 #include "AliHFMassFitter.h"
43 ClassImp(AliHFMassFitter)
45 //************** constructors
46 AliHFMassFitter::AliHFMassFitter() :
69 // default constructor
71 cout<<"Default constructor:"<<endl;
72 cout<<"Remember to set the Histo, the Type, the FixPar"<<endl;
76 //___________________________________________________________________________
78 AliHFMassFitter::AliHFMassFitter (const TH1F *histoToFit, Double_t minvalue, Double_t maxvalue, Int_t rebin,Int_t fittypeb,Int_t fittypes):
101 // standard constructor
103 fhistoInvMass= (TH1F*)histoToFit->Clone("fhistoInvMass");
104 fhistoInvMass->SetDirectory(0);
107 if(rebin!=1) RebinMass(rebin);
108 else fNbin=(Int_t)fhistoInvMass->GetNbinsX();
110 ftypeOfFit4Bkg=fittypeb;
111 ftypeOfFit4Sgn=fittypes;
112 if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2) fWithBkg=kFALSE;
114 if (!fWithBkg) cout<<"Fit Histogram of Signal only"<<endl;
115 else cout<<"Type of fit For Background = "<<ftypeOfFit4Bkg<<endl;
118 fFitPars=new Float_t[fParsSize];
120 SetDefaultFixParam();
122 fContourGraph=new TList();
123 fContourGraph->SetOwner();
128 AliHFMassFitter::AliHFMassFitter(const AliHFMassFitter &mfit):
130 fhistoInvMass(mfit.fhistoInvMass),
131 fminMass(mfit.fminMass),
132 fmaxMass(mfit.fmaxMass),
134 fParsSize(mfit.fParsSize),
135 fNFinalPars(mfit.fNFinalPars),
137 fWithBkg(mfit.fWithBkg),
138 ftypeOfFit4Bkg(mfit.ftypeOfFit4Bkg),
139 ftypeOfFit4Sgn(mfit.ftypeOfFit4Sgn),
140 ffactor(mfit.ffactor),
141 fntuParam(mfit.fntuParam),
143 fSigmaSgn(mfit.fSigmaSgn),
144 fSideBands(mfit.fSideBands),
146 fSideBandl(mfit.fSideBandl),
147 fSideBandr(mfit.fSideBandr),
148 fcounter(mfit.fcounter),
149 fContourGraph(mfit.fContourGraph)
153 if(mfit.fParsSize > 0){
154 fFitPars=new Float_t[fParsSize];
155 fFixPar=new Bool_t[fNFinalPars];
156 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
157 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Bool_t));
159 //for(Int_t i=0;i<fParsSize;i++) fFitPars[i]=mfit.fFitPars[i];
162 //_________________________________________________________________________
164 AliHFMassFitter::~AliHFMassFitter() {
168 cout<<"AliHFMassFitter destructor called"<<endl;
170 cout<<"deleting histogram..."<<endl;
171 delete fhistoInvMass;
175 cout<<"deleting ntuple..."<<endl;
183 cout<<"deleting parameter array..."<<endl;
189 cout<<"deleting bool array..."<<endl;
196 //_________________________________________________________________________
198 AliHFMassFitter& AliHFMassFitter::operator=(const AliHFMassFitter &mfit){
200 //assignment operator
202 if(&mfit == this) return *this;
203 fhistoInvMass= mfit.fhistoInvMass;
204 fminMass= mfit.fminMass;
205 fmaxMass= mfit.fmaxMass;
207 fParsSize= mfit.fParsSize;
208 fWithBkg= mfit.fWithBkg;
209 ftypeOfFit4Bkg= mfit.ftypeOfFit4Bkg;
210 ftypeOfFit4Sgn= mfit.ftypeOfFit4Sgn;
211 ffactor= mfit.ffactor;
212 fntuParam= mfit.fntuParam;
214 fSigmaSgn= mfit.fSigmaSgn;
215 fSideBands= mfit.fSideBands;
216 fSideBandl= mfit.fSideBandl;
217 fSideBandr= mfit.fSideBandr;
218 fcounter= mfit.fcounter;
219 fContourGraph= mfit.fContourGraph;
221 if(mfit.fParsSize > 0){
226 fFitPars=new Float_t[fParsSize];
227 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
233 fFixPar=new Bool_t[fNFinalPars];
234 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Float_t));
236 // fFitPars=new Float_t[fParsSize];
237 // for(Int_t i=0;i<fParsSize;i++) fFitPars[i]=mfit.fFitPars[i];
242 //************ tools & settings
244 //__________________________________________________________________________
246 void AliHFMassFitter::ComputeNFinalPars() {
248 //compute the number of parameters of the total (signal+bgk) function
249 cout<<"Info:ComputeNFinalPars... ";
250 switch (ftypeOfFit4Bkg) {//npar background func
264 cout<<"Error in computing fNFinalPars: check ftypeOfFit4Bkg"<<endl;
268 fNFinalPars+=3; //gaussian signal
269 cout<<": "<<fNFinalPars<<endl;
271 //__________________________________________________________________________
273 void AliHFMassFitter::ComputeParSize() {
275 //compute the size of the parameter array and set the data member
277 switch (ftypeOfFit4Bkg) {//npar background func
291 cout<<"Error in computing fParsSize: check ftypeOfFit4Bkg"<<endl;
295 fParsSize += 3; // npar refl
296 fParsSize += 3; // npar signal gaus
298 fParsSize*=2; // add errors
299 cout<<"Parameters array size "<<fParsSize<<endl;
302 //___________________________________________________________________________
303 void AliHFMassFitter::SetDefaultFixParam(){
305 //Set default values for fFixPar (only total integral fixed)
308 fFixPar=new Bool_t[fNFinalPars];
310 fFixPar[0]=kTRUE; //default: IntTot fixed
311 cout<<"Parameter 0 is fixed"<<endl;
312 for(Int_t i=1;i<fNFinalPars;i++){
318 //___________________________________________________________________________
319 Bool_t AliHFMassFitter::SetFixThisParam(Int_t thispar,Bool_t fixpar){
321 //set the value (kFALSE or kTRUE) of one element of fFixPar
322 //return kFALSE if something wrong
324 if(thispar>=fNFinalPars) {
325 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
329 cout<<"Initializing fFixPar...";
330 SetDefaultFixParam();
331 cout<<" done."<<endl;
334 fFixPar[thispar]=fixpar;
335 cout<<"Parameter "<<thispar<<" is now fixed"<<endl;
339 //___________________________________________________________________________
340 Bool_t AliHFMassFitter::GetFixThisParam(Int_t thispar)const{
341 //return the value of fFixPar[thispar]
342 if(thispar>=fNFinalPars) {
343 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
347 cout<<"Error! Parameters to be fixed still not set"<<endl;
351 return fFixPar[thispar];
355 //___________________________________________________________________________
356 void AliHFMassFitter::SetHisto(const TH1F *histoToFit){
357 //fhistoInvMass = (TH1F*)histoToFit->Clone();
358 fhistoInvMass = new TH1F(*histoToFit);
359 fhistoInvMass->SetDirectory(0);
360 cout<<"SetHisto pointer "<<fhistoInvMass<<endl;
363 //___________________________________________________________________________
365 void AliHFMassFitter::SetType(Int_t fittypeb, Int_t fittypes) {
367 //set the type of fit to perform for signal and background
369 ftypeOfFit4Bkg = fittypeb;
370 ftypeOfFit4Sgn = fittypes;
379 fFitPars = new Float_t[fParsSize];
386 SetDefaultFixParam();
391 //___________________________________________________________________________
393 void AliHFMassFitter::Reset() {
395 //delete the histogram and reset the mean and sigma to default
397 cout<<"Reset called: delete histogram, set mean value to 1.85 and sigma to 0.012"<<endl;
400 cout<<"Reset "<<fhistoInvMass<<endl;
402 //cout<<"esiste"<<endl;
403 delete fhistoInvMass;
405 cout<<fhistoInvMass<<endl;
407 else cout<<"histogram doesn't exist, do not delete"<<endl;
412 //_________________________________________________________________________
414 void AliHFMassFitter::InitNtuParam(char *ntuname) {
416 // Create ntuple to keep fit parameters
419 fntuParam=new TNtuple(ntuname,"Contains fit parameters","intbkg1:slope1:conc1:intGB:meanGB:sigmaGB:intbkg2:slope2:conc2:inttot:slope3:conc3:intsgn:meansgn:sigmasgn:intbkg1Err:slope1Err:conc1Err:intGBErr:meanGBErr:sigmaGBErr:intbkg2Err:slope2Err:conc2Err:inttotErr:slope3Err:conc3Err:intsgnErr:meansgnErr:sigmasgnErr");
423 //_________________________________________________________________________
425 void AliHFMassFitter::FillNtuParam() {
426 // Fill ntuple with fit parameters
430 if (ftypeOfFit4Bkg==2) {
431 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
432 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
433 fntuParam->SetBranchAddress("conc1",&fFitPars[2]);
434 fntuParam->SetBranchAddress("intGB",&fFitPars[3]);
435 fntuParam->SetBranchAddress("meanGB",&fFitPars[4]);
436 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]);
437 fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]);
438 fntuParam->SetBranchAddress("slope2",&fFitPars[7]);
439 fntuParam->SetBranchAddress("conc2",&fFitPars[8]);
440 fntuParam->SetBranchAddress("inttot",&fFitPars[9]);
441 fntuParam->SetBranchAddress("slope3",&fFitPars[10]);
442 fntuParam->SetBranchAddress("conc3",&fFitPars[11]);
443 fntuParam->SetBranchAddress("intsgn",&fFitPars[12]);
444 fntuParam->SetBranchAddress("meansgn",&fFitPars[13]);
445 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]);
447 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]);
448 fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]);
449 fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]);
450 fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]);
451 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]);
452 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]);
453 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]);
454 fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]);
455 fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]);
456 fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]);
457 fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]);
458 fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]);
459 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]);
460 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]);
461 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]);
465 if(ftypeOfFit4Bkg==3){
466 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
467 fntuParam->SetBranchAddress("slope1",¬hing);
468 fntuParam->SetBranchAddress("conc1",¬hing);
469 fntuParam->SetBranchAddress("intGB",&fFitPars[1]);
470 fntuParam->SetBranchAddress("meanGB",&fFitPars[2]);
471 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]);
472 fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]);
473 fntuParam->SetBranchAddress("slope2",¬hing);
474 fntuParam->SetBranchAddress("conc2",¬hing);
475 fntuParam->SetBranchAddress("inttot",&fFitPars[6]);
476 fntuParam->SetBranchAddress("slope3",¬hing);
477 fntuParam->SetBranchAddress("conc3",¬hing);
478 fntuParam->SetBranchAddress("intsgn",&fFitPars[6]);
479 fntuParam->SetBranchAddress("meansgn",&fFitPars[7]);
480 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]);
482 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]);
483 fntuParam->SetBranchAddress("slope1Err",¬hing);
484 fntuParam->SetBranchAddress("conc1Err",¬hing);
485 fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]);
486 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]);
487 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]);
488 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]);
489 fntuParam->SetBranchAddress("slope2Err",¬hing);
490 fntuParam->SetBranchAddress("conc2Err",¬hing);
491 fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]);
492 fntuParam->SetBranchAddress("slope3Err",¬hing);
493 fntuParam->SetBranchAddress("conc3Err",¬hing);
494 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]);
495 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]);
496 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]);
500 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
501 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
502 fntuParam->SetBranchAddress("conc1",¬hing);
503 fntuParam->SetBranchAddress("intGB",&fFitPars[2]);
504 fntuParam->SetBranchAddress("meanGB",&fFitPars[3]);
505 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]);
506 fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]);
507 fntuParam->SetBranchAddress("slope2",&fFitPars[6]);
508 fntuParam->SetBranchAddress("conc2",¬hing);
509 fntuParam->SetBranchAddress("inttot",&fFitPars[7]);
510 fntuParam->SetBranchAddress("slope3",&fFitPars[8]);
511 fntuParam->SetBranchAddress("conc3",¬hing);
512 fntuParam->SetBranchAddress("intsgn",&fFitPars[9]);
513 fntuParam->SetBranchAddress("meansgn",&fFitPars[10]);
514 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]);
516 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]);
517 fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]);
518 fntuParam->SetBranchAddress("conc1Err",¬hing);
519 fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]);
520 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]);
521 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]);
522 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]);
523 fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]);
524 fntuParam->SetBranchAddress("conc2Err",¬hing);
525 fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]);
526 fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]);
527 fntuParam->SetBranchAddress("conc3Err",¬hing);
528 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]);
529 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]);
530 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]);
534 fntuParam->TTree::Fill();
537 //_________________________________________________________________________
539 TNtuple* AliHFMassFitter::NtuParamOneShot(char *ntuname){
540 // Create, fill and return ntuple with fit parameters
542 InitNtuParam(ntuname);
546 //_________________________________________________________________________
548 void AliHFMassFitter::RebinMass(Int_t bingroup){
549 // Rebin invariant mass histogram
552 cout<<"Histogram not set"<<endl;
555 Int_t nbinshisto=fhistoInvMass->GetNbinsX();
557 cout<<"Error! Cannot group "<<bingroup<<" bins\n";
559 cout<<"Kept original number of bins: "<<fNbin<<endl;
561 fhistoInvMass->Rebin(bingroup);
562 if(nbinshisto%bingroup != 0) CheckRangeFit();
563 fNbin = fhistoInvMass->GetNbinsX();
564 cout<<"New number of bins: "<<fNbin<<endl;
571 //___________________________________________________________________________
573 Double_t AliHFMassFitter::FitFunction4MassDistr (Double_t *x, Double_t *par){
574 // Fit function for signal+background
577 //exponential or linear fit
579 // par[0] = tot integral
581 // par[2] = gaussian integral
582 // par[3] = gaussian mean
583 // par[4] = gaussian sigma
585 Double_t total,bkg=0,sgn=0;
587 if (ftypeOfFit4Bkg==0 || ftypeOfFit4Bkg==1) {
588 if(ftypeOfFit4Sgn == 0) {
590 Double_t parbkg[2] = {par[0]-par[2], par[1]};
591 bkg = FitFunction4Bkg(x,parbkg);
593 if(ftypeOfFit4Sgn == 1) {
594 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-2*par[2], par[1]};
595 bkg = FitFunction4Bkg(x,parbkg);
598 sgn = FitFunction4Sgn(x,&par[2]);
604 // par[0] = tot integral
607 // par[3] = gaussian integral
608 // par[4] = gaussian mean
609 // par[5] = gaussian sigma
611 if (ftypeOfFit4Bkg==2) {
613 if(ftypeOfFit4Sgn == 0) {
615 Double_t parbkg[3] = {par[0]-par[3], par[1], par[2]};
616 bkg = FitFunction4Bkg(x,parbkg);
618 if(ftypeOfFit4Sgn == 1) {
620 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-2*par[3], par[1], par[2]};
621 bkg = FitFunction4Bkg(x,parbkg);
624 sgn = FitFunction4Sgn(x,&par[3]);
627 if (ftypeOfFit4Bkg==3) {
629 if(ftypeOfFit4Sgn == 0) {
630 bkg=FitFunction4Bkg(x,par);
631 sgn=FitFunction4Sgn(x,&par[1]);
633 if(ftypeOfFit4Sgn == 1) {
634 Double_t parbkg[4]={par[1],par[2],ffactor*par[3],par[0]};
635 bkg=FitFunction4Bkg(x,parbkg);
636 sgn=FitFunction4Sgn(x,&par[1]);
645 //_________________________________________________________________________
646 Double_t AliHFMassFitter::FitFunction4Sgn (Double_t *x, Double_t *par){
647 // Fit function for the signal
649 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
651 // * [0] = integralSgn
654 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
656 return par[0]/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[2]/par[2]);
660 //__________________________________________________________________________
662 Double_t AliHFMassFitter::FitFunction4Bkg (Double_t *x, Double_t *par){
663 // Fit function for the background
665 Double_t maxDeltaM = 4.*fSigmaSgn;
666 if(fSideBands && TMath::Abs(x[0]-fMass) < maxDeltaM) {
671 Double_t gaus2=0,total=-1;
672 if(ftypeOfFit4Sgn == 1){
674 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
676 // * [0] = integralSgn
679 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
680 gaus2 = FitFunction4Sgn(x,par);
683 switch (ftypeOfFit4Bkg){
686 //exponential = A*exp(B*x) -> integral(exponential)=A/B*exp(B*x)](min,max)
687 //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written
688 //as integralTot- integralGaus (=par [2])
690 // * [0] = integralBkg;
692 //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x)
693 total = par[0+firstPar]*par[1+firstPar]/(TMath::Exp(par[1+firstPar]*fmaxMass)-TMath::Exp(par[1+firstPar]*fminMass))*TMath::Exp(par[1+firstPar]*x[0]);
697 //y=a+b*x -> integral = a(max-min)+1/2*b*(max^2-min^2) -> a = (integral-1/2*b*(max^2-min^2))/(max-min)=integral/(max-min)-1/2*b*(max+min)
698 // * [0] = integralBkg;
700 total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass));
704 //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) +
705 //+ 1/3*c*(max^3-min^3) ->
706 //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min)
707 // * [0] = integralBkg;
710 total = par[0+firstPar]/(fmaxMass-fminMass)+par[1]*(x[0]-0.5*(fmaxMass+fminMass))+par[2+firstPar]*(x[0]*x[0]-1/3.*(fmaxMass*fmaxMass*fmaxMass-fminMass*fminMass*fminMass)/(fmaxMass-fminMass));
713 total=par[0+firstPar];
716 // Types of Fit Functions for Background:
717 // * 0 = exponential;
719 // * 2 = polynomial 2nd order
720 // * 3 = no background"<<endl;
726 //__________________________________________________________________________
727 Bool_t AliHFMassFitter::SideBandsBounds(){
729 //determines the ranges of the side bands
731 Double_t width=fhistoInvMass->GetBinWidth(8);
732 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
733 Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
734 Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin)+width;
736 if(fMass-fminMass < 0 || fmaxMass-fMass <0) {
737 cout<<"Left limit of range > mean or right limit of range < mean: change left/right limit or initial mean value"<<endl;
741 if((TMath::Abs(fminMass-minHisto) < 10e6 || TMath::Abs(fmaxMass - maxHisto) < 10e6) && (fMass-4.*fSigmaSgn-fminMass) < 10e6){
742 Double_t coeff = (fMass-fminMass)/fSigmaSgn;
744 fSideBandl=(Int_t)((fMass-0.5*coeff*fSigmaSgn-fminMass)/width);
745 fSideBandr=(Int_t)((fMass+0.5*coeff*fSigmaSgn-fminMass)/width);
746 cout<<"Changed number of sigma from 4 to "<<0.5*coeff<<" for the estimation of the side bands"<<endl;
747 if (coeff<3) cout<<"Side bands inside 3 sigma, may be better use ftypeOfFit4Bkg = 3 (only signal)"<<endl;
750 cout<<"Side bands inside 2 sigma. Change mode: ftypeOfFit4Bkg = 3"<<endl;
752 //set binleft and right without considering SetRangeFit- anyway no bkg!
753 fSideBandl=(Int_t)((fMass-4.*fSigmaSgn-minHisto)/width);
754 fSideBandr=(Int_t)((fMass+4.*fSigmaSgn-minHisto)/width);
758 fSideBandl=(Int_t)((fMass-4.*fSigmaSgn-minHisto)/width);
759 fSideBandr=(Int_t)((fMass+4.*fSigmaSgn-minHisto)/width);
760 // cout<<"\tfMass = "<<fMass<<"\tfSigmaSgn = "<<fSigmaSgn<<"\tminHisto = "<<minHisto<<endl;
761 // cout<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
765 cout<<"Error! Range too little";
771 //__________________________________________________________________________
773 void AliHFMassFitter::GetSideBandsBounds(Int_t &left, Int_t &right) const{
775 // get the range of the side bands
777 if (fSideBandl==0 && fSideBandr==0){
778 cout<<"Use MassFitter method first"<<endl;
785 //__________________________________________________________________________
786 Bool_t AliHFMassFitter::CheckRangeFit(){
787 //check if the limit of the range correspond to the limit of bins. If not reset the limit to the nearer value which satisfy this condition
789 if (!fhistoInvMass) {
790 cout<<"No histogram to fit! SetHisto(TH1F* h) before! "<<endl;
793 Bool_t leftok=kFALSE, rightok=kFALSE;
794 Int_t nbins=fhistoInvMass->GetNbinsX();
795 Double_t width=fhistoInvMass->GetBinWidth(1);
796 Double_t minhisto=fhistoInvMass->GetBinLowEdge(1), maxhisto=fhistoInvMass->GetBinLowEdge(nbins)+width;
798 //check if limits are inside histogram range
799 if( fminMass-minhisto < 0. ) {
800 cout<<"Out of histogram left bound!"<<endl;
803 if( fmaxMass-maxhisto > 0. ) {
804 cout<<"Out of histogram right bound!"<<endl;
811 //calculate bin corresponding to fminMass
812 binl=fhistoInvMass->FindBin(fminMass);
813 if (fminMass > fhistoInvMass->GetBinCenter(binl)) binl++;
814 fminMass=fhistoInvMass->GetBinLowEdge(binl);
815 if(TMath::Abs(tmp-fminMass) > 1e-6){
816 cout<<"Left bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fminMass<<endl;
821 //calculate bin corresponding to fmaxMass
822 binr=fhistoInvMass->FindBin(fmaxMass);
823 if (fmaxMass < fhistoInvMass->GetBinCenter(binr)) binr--;
824 fmaxMass=fhistoInvMass->GetBinLowEdge(binr)+width;
825 if(TMath::Abs(tmp-fmaxMass) > 1e-6){
826 cout<<"Right bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fmaxMass<<endl;
830 return (leftok && rightok);
834 //__________________________________________________________________________
836 Bool_t AliHFMassFitter::MassFitter(Bool_t draw){
837 // Main method of the class: performs the fit of the histogram
839 //Set default fitter Minuit in order to use gMinuit in the contour plots
840 TVirtualFitter::SetDefaultFitter("Minuit");
842 Int_t nFitPars=0; //total function's number of parameters
843 switch (ftypeOfFit4Bkg){
858 Int_t bkgPar = nFitPars-3; //background function's number of parameters
860 cout<<"nFitPars = "<<nFitPars<<"\tbkgPar = "<<bkgPar<<endl;
863 TString listname="contourplot";
866 fContourGraph=new TList();
867 fContourGraph->SetOwner();
870 fContourGraph->SetName(listname);
874 TString bkgname="funcbkg";
875 TString bkg1name="funcbkg1";
876 TString massname="funcmass";
879 Double_t totInt = fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass), fhistoInvMass->FindBin(fmaxMass), "width");
882 Double_t width=fhistoInvMass->GetBinWidth(8);
883 cout<<"fNbin"<<fNbin<<endl;
884 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
885 //Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
886 //Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin)+width;
887 Bool_t ok=SideBandsBounds();
888 if(!ok) return kFALSE;
890 //sidebands integral - first approx (from histo)
891 Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,fSideBandl,"width") + (Double_t)fhistoInvMass->Integral(fSideBandr,fNbin,"width");
892 cout<<"------nbin = "<<fNbin<<"\twidth = "<<width<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
893 cout<<"------sideBandsInt - first approx = "<<sideBandsInt<<endl;
894 if (sideBandsInt<=0) {
895 cout<<"! sideBandsInt <=0. There's a problem, cannot start the fit"<<endl;
902 TF1 *funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
903 cout<<"Function name = "<<funcbkg->GetName()<<endl<<endl;
905 funcbkg->SetLineColor(2); //red
907 //first fit for bkg: approx bkgint
909 switch (ftypeOfFit4Bkg) {
911 funcbkg->SetParNames("BkgInt","Slope");
912 funcbkg->SetParameters(sideBandsInt,-2.);
915 funcbkg->SetParNames("BkgInt","Slope");
916 funcbkg->SetParameters(sideBandsInt,-100.);
919 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
920 funcbkg->SetParameters(sideBandsInt,-10.,5);
923 if(ftypeOfFit4Sgn==0){
924 funcbkg->SetParNames("Const");
925 funcbkg->SetParameter(0,0.);
926 funcbkg->FixParameter(0,0.);
930 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
934 cout<<"\nBACKGROUND FIT - only combinatorial"<<endl;
935 Int_t ftypeOfFit4SgnBkp=ftypeOfFit4Sgn;
937 Double_t intbkg1=0,slope1=0,conc1=0;
938 //if only signal and reflection: skip
939 if (!(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn==1)) {
941 fhistoInvMass->Fit(bkgname.Data(),"R,L,E,0");
943 for(Int_t i=0;i<bkgPar;i++){
944 fFitPars[i]=funcbkg->GetParameter(i);
945 //cout<<i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
946 fFitPars[nFitPars+2*bkgPar+3+i]= funcbkg->GetParError(i);
947 //cout<<nFitPars+2*bkgPar+3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
950 //intbkg1 = funcbkg->GetParameter(0);
951 funcbkg->SetRange(fminMass,fmaxMass);
952 intbkg1 = funcbkg->Integral(fminMass,fmaxMass);
953 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1);
954 if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2);
955 cout<<"First fit: \nintbkg1 = "<<intbkg1<<"\t(Compare with par0 = "<<funcbkg->GetParameter(0)<<")\nslope1= "<<slope1<<"\nconc1 = "<<conc1<<endl;
957 else cout<<"\t\t//"<<endl;
959 ftypeOfFit4Sgn=ftypeOfFit4SgnBkp;
961 if (ftypeOfFit4Sgn == 1) {
962 cout<<"\nBACKGROUND FIT WITH REFLECTION"<<endl;
965 cout<<"nFitPars = "<<nFitPars<<"\tbkgPar = "<<bkgPar<<endl;
967 funcbkg1 = new TF1(bkg1name.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
968 cout<<"Function name = "<<funcbkg1->GetName()<<endl;
970 funcbkg1->SetLineColor(2); //red
972 if(ftypeOfFit4Bkg==2){
973 cout<<"*** Polynomial Fit ***"<<endl;
974 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
975 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
977 //cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<<fMass<<"\t"<<ffactor*fSigmaSgn<<"\t"<<intbkg1<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<endl;
978 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<bkgPar<<"\tgsidebands = "<<fSideBands<<endl;
980 if(ftypeOfFit4Bkg==3) //no background: gaus sign+ gaus broadened
982 cout<<"*** No background Fit ***"<<endl;
983 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","Const");
984 funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.);
985 funcbkg1->FixParameter(3,0.);
986 } else{ //expo or linear
987 if(ftypeOfFit4Bkg==0) cout<<"*** Exponential Fit ***"<<endl;
988 if(ftypeOfFit4Bkg==1) cout<<"*** Linear Fit ***"<<endl;
989 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
990 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
993 Int_t status=fhistoInvMass->Fit(bkg1name.Data(),"R,L,E,+,0");
995 cout<<"Minuit returned "<<status<<endl;
999 for(Int_t i=0;i<bkgPar;i++){
1000 fFitPars[bkgPar-3+i]=funcbkg1->GetParameter(i);
1001 //cout<<bkgPar-3+i<<"\t"<<funcbkg1->GetParameter(i);
1002 fFitPars[nFitPars+3*bkgPar-6+i]= funcbkg1->GetParError(i);
1003 //cout<<"\t"<<nFitPars+3*bkgPar-6+i<<"\t"<<funcbkg1->GetParError(i)<<endl;
1006 intbkg1=funcbkg1->GetParameter(3);
1007 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4);
1008 if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5);
1013 for(Int_t i=0;i<3;i++){
1014 fFitPars[bkgPar-3+i]=0.;
1015 cout<<bkgPar-3+i<<"\t"<<0.<<"\t";
1016 fFitPars[nFitPars+3*bkgPar-6+i]= 0.;
1017 cout<<nFitPars+3*bkgPar-6+i<<"\t"<<0.<<endl;
1020 for(Int_t i=0;i<bkgPar-3;i++){
1021 fFitPars[bkgPar+i]=funcbkg->GetParameter(i);
1022 cout<<bkgPar+i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
1023 fFitPars[nFitPars+3*bkgPar-3+i]= funcbkg->GetParError(i);
1024 cout<<nFitPars+3*bkgPar-3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
1030 //sidebands integral - second approx (from fit)
1031 fSideBands = kFALSE;
1033 cout<<"Compare intbkg1 = "<<intbkg1<<" and integral = ";
1034 if(ftypeOfFit4Sgn == 1) bkgInt=funcbkg1->Integral(fminMass,fmaxMass);
1035 else bkgInt=funcbkg->Integral(fminMass,fmaxMass);
1036 cout<</*"------BkgInt(Fit) = "<<*/bkgInt<<endl;
1038 //Signal integral - first approx
1040 sgnInt = totInt-bkgInt;
1041 cout<<"------TotInt = "<<totInt<<"\tsgnInt = "<<sgnInt<<endl;
1043 cout<<"Setting sgnInt = - sgnInt"<<endl;
1046 /*Fit All Mass distribution with exponential + gaussian (+gaussiam braodened) */
1047 TF1 *funcmass = new TF1(massname.Data(),this,&AliHFMassFitter::FitFunction4MassDistr,fminMass,fmaxMass,nFitPars,"AliHFMassFitter","FitFunction4MassDistr");
1048 cout<<"Function name = "<<funcmass->GetName()<<endl<<endl;
1049 funcmass->SetLineColor(4); //blue
1052 cout<<"\nTOTAL FIT"<<endl;
1055 funcmass->SetParNames("TotInt","Slope","SgnInt","Mean","Sigma");
1056 funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn);
1058 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1059 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1062 funcmass->FixParameter(0,totInt);
1066 funcmass->FixParameter(1,slope1);
1070 funcmass->FixParameter(2,sgnInt);
1074 funcmass->FixParameter(3,fMass);
1078 funcmass->FixParameter(4,fSigmaSgn);
1082 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1083 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
1085 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1086 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1087 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1088 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1089 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1090 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1091 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1092 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1094 //funcmass->FixParameter(2,sgnInt);
1097 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
1098 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1099 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
1100 if(fFixPar[0]) funcmass->FixParameter(0,0.);
1101 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1102 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1105 //funcmass->FixParameter(nFitPars-2,fMass);
1106 //funcmass->SetParLimits(nFitPars-1,0.007,0.05);
1107 //funcmass->SetParLimits(nFitPars-2,fMass-0.01,fMass+0.01);
1110 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1112 cout<<"Minuit returned "<<status<<endl;
1116 cout<<"fit done"<<endl;
1117 //reset value of fMass and fSigmaSgn to those found from fit
1118 fMass=funcmass->GetParameter(nFitPars-2);
1119 fSigmaSgn=funcmass->GetParameter(nFitPars-1);
1121 for(Int_t i=0;i<nFitPars;i++){
1122 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
1123 fFitPars[nFitPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1124 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<nFitPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
1127 //check: cout parameters
1128 for(Int_t i=0;i<2*(nFitPars+2*bkgPar-3);i++){
1129 cout<<i<<"\t"<<fFitPars[i]<<endl;
1134 // TCanvas *canvas=new TCanvas(fhistoInvMass->GetName(),fhistoInvMass->GetName());
1135 // TH1F *fhistocopy=new TH1F(*fhistoInvMass);
1137 // fhistocopy->DrawClone();
1138 // if(ftypeOfFit4Sgn == 1) funcbkg1->DrawClone("sames");
1139 // else funcbkg->DrawClone("sames");
1140 // funcmass->DrawClone("sames");
1141 // cout<<"Drawn"<<endl;
1144 if(funcmass->GetParameter(nFitPars-1) <0 || funcmass->GetParameter(nFitPars-2) <0 || funcmass->GetParameter(nFitPars-3) <0 ) {
1145 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
1149 //increase counter of number of fits done
1155 for (Int_t kpar=1; kpar<nFitPars;kpar++){
1157 for(Int_t jpar=kpar+1;jpar<nFitPars;jpar++){
1158 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1160 // produce 2 contours per couple of parameters
1161 TGraph* cont[2] = {0x0, 0x0};
1162 const Double_t errDef[2] = {1., 4.};
1163 for (Int_t i=0; i<2; i++) {
1164 gMinuit->SetErrorDef(errDef[i]);
1165 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
1166 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
1169 if(!cont[0] || !cont[1]){
1170 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1174 // set graph titles and add them to the list
1175 TString title = "Contour plot";
1176 TString titleX = funcmass->GetParName(kpar);
1177 TString titleY = funcmass->GetParName(jpar);
1178 for (Int_t i=0; i<2; i++) {
1179 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1180 cont[i]->SetTitle(title);
1181 cont[i]->GetXaxis()->SetTitle(titleX);
1182 cont[i]->GetYaxis()->SetTitle(titleY);
1183 cont[i]->GetYaxis()->SetLabelSize(0.033);
1184 cont[i]->GetYaxis()->SetTitleSize(0.033);
1185 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1187 fContourGraph->Add(cont[i]);
1191 TString cvname = Form("c%d%d", kpar, jpar);
1192 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1194 cont[1]->SetFillColor(38);
1195 cont[1]->Draw("alf");
1196 cont[0]->SetFillColor(9);
1197 cont[0]->Draw("lf");
1205 if (ftypeOfFit4Sgn == 1 && funcbkg1) {
1218 AddFunctionsToHisto();
1219 if (draw) DrawFit();
1224 //_________________________________________________________________________
1225 Double_t AliHFMassFitter::GetChiSquare() const{
1226 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1227 return funcmass->GetChisquare();
1230 //_________________________________________________________________________
1231 Double_t AliHFMassFitter::GetReducedChiSquare() const{
1232 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1233 return funcmass->GetChisquare()/funcmass->GetNDF();
1238 //_________________________________________________________________________
1239 void AliHFMassFitter::GetFitPars(Float_t *vector) const {
1240 // Return fit parameters
1242 for(Int_t i=0;i<fParsSize;i++){
1243 vector[i]=fFitPars[i];
1248 //_________________________________________________________________________
1249 void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1251 //gives the integral of signal obtained from fit parameters
1252 if(!valuewitherror)valuewitherror=new Float_t[2];
1254 Int_t index=fParsSize/2 - 3;
1255 valuewitherror[0]=fFitPars[index];
1256 index=fParsSize - 3;
1257 valuewitherror[1]=fFitPars[index];
1261 //_________________________________________________________________________
1262 void AliHFMassFitter::AddFunctionsToHisto(){
1264 //Add the background function in the complete range to the list of functions attached to the histogram
1266 cout<<"AddFunctionsToHisto called"<<endl;
1267 TString bkgname = "funcbkg";
1269 switch (ftypeOfFit4Bkg){
1283 if (ftypeOfFit4Sgn == 1) {
1288 TString bkgnamesave=bkgname;
1289 TString testname=bkgname;
1290 testname += "FullRange";
1291 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1293 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1297 TList *hlist=fhistoInvMass->GetListOfFunctions();
1300 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1302 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1306 bkgname += "FullRange";
1307 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,np,"AliHFMassFitter","FitFunction4Bkg");
1308 //cout<<bfullrange->GetName()<<endl;
1309 for(Int_t i=0;i<np;i++){
1310 //cout<<i<<" di "<<np<<endl;
1311 bfullrange->SetParName(i,b->GetParName(i));
1312 bfullrange->SetParameter(i,b->GetParameter(i));
1313 bfullrange->SetParError(i,b->GetParError(i));
1315 bfullrange->SetLineStyle(4);
1316 bfullrange->SetLineColor(14);
1318 bkgnamesave += "Recalc";
1320 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,np,"AliHFMassFitter","FitFunction4Bkg");
1322 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
1325 cout<<"funcmass doesn't exist "<<endl;
1329 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(np));
1330 blastpar->SetParError(0,mass->GetParError(np));
1332 blastpar->SetParameter(1,mass->GetParameter(1));
1333 blastpar->SetParError(1,mass->GetParError(1));
1336 blastpar->SetParameter(2,mass->GetParameter(2));
1337 blastpar->SetParError(2,mass->GetParError(2));
1340 blastpar->SetLineStyle(1);
1341 blastpar->SetLineColor(2);
1343 hlist->Add((TF1*)bfullrange->Clone());
1344 hlist->Add((TF1*)blastpar->Clone());
1357 //_________________________________________________________________________
1359 TH1F* AliHFMassFitter::GetHistoClone() const{
1361 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1364 //_________________________________________________________________________
1366 void AliHFMassFitter::WriteHisto(TString path) const {
1368 //Write the histogram in the default file HFMassFitterOutput.root
1370 if (fcounter == 0) {
1371 cout<<"Use MassFitter method before WriteHisto"<<endl;
1374 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1376 path += "HFMassFitterOutput.root";
1379 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1380 else output = new TFile(path.Data(),"update");
1383 fContourGraph->Write();
1388 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
1397 //_________________________________________________________________________
1399 void AliHFMassFitter::WriteNtuple(TString path) const{
1400 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
1401 path += "HFMassFitterOutput.root";
1402 TFile *output = new TFile(path.Data(),"update");
1407 //cout<<nget->GetName()<<" written in "<<path<<endl;
1408 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1421 //_________________________________________________________________________
1422 void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1424 //write the canvas in a root file
1426 gStyle->SetOptStat(0);
1427 gStyle->SetCanvasColor(0);
1428 gStyle->SetFrameFillColor(0);
1432 switch (ftypeOfFit4Bkg){
1447 TString filename=Form("%sMassFit.root",type.Data());
1448 filename.Prepend(userIDstring);
1449 path.Append(filename);
1451 TFile* outputcv=new TFile(path.Data(),"update");
1453 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1454 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1455 if(draw)c->DrawClone();
1461 //_________________________________________________________________________
1463 TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
1464 //return a TVirtualPad with the fitted histograms and info
1466 TString cvtitle="fit of ";
1467 cvtitle+=fhistoInvMass->GetName();
1471 TCanvas *c=new TCanvas(cvname,cvtitle);
1472 PlotFit(c->cd(),nsigma,writeFitInfo);
1475 //_________________________________________________________________________
1477 void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1478 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
1479 gStyle->SetOptStat(0);
1480 gStyle->SetCanvasColor(0);
1481 gStyle->SetFrameFillColor(0);
1483 cout<<"nsigma = "<<nsigma<<endl;
1484 cout<<"Verbosity = "<<writeFitInfo<<endl;
1486 TH1F* hdraw=GetHistoClone();
1487 hdraw->SetMinimum(0);
1488 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1490 hdraw->SetMarkerStyle(20);
1491 hdraw->DrawClone("PE");
1492 hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1493 hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
1494 hdraw->GetFunction("funcmass")->DrawClone("same");
1496 if(writeFitInfo > 0){
1497 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1498 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1499 pinfob->SetBorderSize(0);
1500 pinfob->SetFillStyle(0);
1501 pinfom->SetBorderSize(0);
1502 pinfom->SetFillStyle(0);
1503 TF1* ff=fhistoInvMass->GetFunction("funcmass");
1505 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1506 pinfom->SetTextColor(kBlue);
1507 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1508 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
1511 pinfom->DrawClone();
1513 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1514 pinfo2->SetBorderSize(0);
1515 pinfo2->SetFillStyle(0);
1517 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1519 Significance(nsigma,signif,errsignif);
1520 Signal(nsigma,signal,errsignal);
1521 Background(nsigma,bkg, errbkg);
1523 Significance(1.828,1.892,signif,errsignif);
1524 Signal(1.828,1.892,signal,errsignal);
1525 Background(1.828,1.892,bkg, errbkg);
1527 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
1528 pinfo2->AddText(str);
1529 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
1530 pinfo2->AddText(str);
1531 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
1532 pinfo2->AddText(str);
1537 if(writeFitInfo > 1){
1538 for (Int_t i=0;i<fNFinalPars-3;i++){
1539 pinfob->SetTextColor(kRed);
1540 str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1541 pinfob->AddText(str);
1544 pinfob->DrawClone();
1552 //_________________________________________________________________________
1554 void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
1555 //draws histogram together with fit functions with default nice colors in user canvas
1556 PlotFit(pd,nsigma,writeFitInfo);
1561 //_________________________________________________________________________
1562 void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1564 //draws histogram together with fit functions with default nice colors
1565 gStyle->SetOptStat(0);
1566 gStyle->SetCanvasColor(0);
1567 gStyle->SetFrameFillColor(0);
1570 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
1576 //_________________________________________________________________________
1578 void AliHFMassFitter::PrintParTitles() const{
1580 //prints to screen the parameters names
1582 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1584 cout<<"Fit function not found"<<endl;
1589 switch (ftypeOfFit4Bkg){
1604 np+=3; //3 parameter for signal
1605 if (ftypeOfFit4Sgn == 1) np+=3;
1607 cout<<"Parameter Titles \n";
1608 for(Int_t i=0;i<np;i++){
1609 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1615 //************ significance
1617 //_________________________________________________________________________
1619 void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1620 // Return signal integral in mean+- n sigma
1623 cout<<"Use MassFitter method before Signal"<<endl;
1627 Double_t min=fMass-nOfSigma*fSigmaSgn;
1628 Double_t max=fMass+nOfSigma*fSigmaSgn;
1630 Signal(min,max,signal,errsignal);
1632 // //functions names
1633 // TString bkgname= "funcbkgRecalc";
1634 // TString bkg1name="funcbkg1Recalc";
1635 // TString massname="funcmass";
1639 // TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1641 // cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1645 // if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1646 // else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1649 // cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1654 // switch (ftypeOfFit4Bkg){
1669 // Float_t intS,intSerr;
1671 // //relative error evaluation
1673 // intS=funcmass->GetParameter(np);
1674 // intSerr=funcmass->GetParError(np);
1676 // cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1677 // Double_t background,errbackground;
1678 // Background(nOfSigma,background,errbackground);
1680 // //signal +/- error in nsigma
1681 // Double_t min=fMass-nOfSigma*fSigmaSgn;
1682 // Double_t max=fMass+nOfSigma*fSigmaSgn;
1684 // Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1685 // signal=mass - background;
1686 // errsignal=TMath::Sqrt((intSerr/intS*mass)*(intSerr/intS*mass)/*assume relative error is the same as for total integral*/ + errbackground*errbackground);
1691 //_________________________________________________________________________
1693 void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1695 // Return signal integral in a range
1698 cout<<"Use MassFitter method before Signal"<<endl;
1703 TString bkgname="funcbkgRecalc";
1704 TString bkg1name="funcbkg1Recalc";
1705 TString massname="funcmass";
1709 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1711 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1715 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1716 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1719 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1724 switch (ftypeOfFit4Bkg){
1739 Double_t intS,intSerr;
1741 //relative error evaluation
1742 intS=funcmass->GetParameter(np);
1743 intSerr=funcmass->GetParError(np);
1745 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1746 Double_t background,errbackground;
1747 Background(min,max,background,errbackground);
1749 //signal +/- error in the range
1751 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1752 signal=mass - background;
1753 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
1757 //_________________________________________________________________________
1759 void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1760 // Return background integral in mean+- n sigma
1763 cout<<"Use MassFitter method before Background"<<endl;
1766 Double_t min=fMass-nOfSigma*fSigmaSgn;
1767 Double_t max=fMass+nOfSigma*fSigmaSgn;
1769 Background(min,max,background,errbackground);
1771 // //functions names
1772 // TString bkgname="funcbkgRecalc";
1773 // TString bkg1name="funcbkg1Recalc";
1776 // if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1777 // else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1779 // cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1783 // Float_t intB,intBerr;//, intT,intTerr,intS,intSerr;
1785 // //relative error evaluation: from final parameters of the fit
1786 // if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1789 // intB=funcbkg->GetParameter(0);
1790 // intBerr=funcbkg->GetParError(0);
1792 // cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1795 // Double_t min=fMass-nOfSigma*fSigmaSgn;
1796 // Double_t max=fMass+nOfSigma*fSigmaSgn;
1798 // //relative error evaluation: from histo
1800 // intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1803 // for(Int_t i=1;i<=fSideBandl;i++){
1804 // sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1806 // for(Int_t i=fSideBandr;i<=fNbin;i++){
1807 // sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1810 // intBerr=TMath::Sqrt(sum2);
1811 // cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1813 // cout<<"Last estimation of bkg error is used"<<endl;
1815 // //backround +/- error in nsigma
1816 // if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1818 // errbackground = 0;
1821 // background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1822 // errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1823 // //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1828 //___________________________________________________________________________
1830 void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1831 // Return background integral in a range
1834 cout<<"Use MassFitter method before Background"<<endl;
1839 TString bkgname="funcbkgRecalc";
1840 TString bkg1name="funcbkg1Recalc";
1843 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1844 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1846 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1851 Double_t intB,intBerr;
1853 //relative error evaluation: from final parameters of the fit
1854 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1856 intB=funcbkg->GetParameter(0);
1857 intBerr=funcbkg->GetParError(0);
1858 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1861 //relative error evaluation: from histo
1863 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1865 for(Int_t i=1;i<=fSideBandl;i++){
1866 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1868 for(Int_t i=fSideBandr;i<=fNbin;i++){
1869 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1872 intBerr=TMath::Sqrt(sum2);
1873 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1875 cout<<"Last estimation of bkg error is used"<<endl;
1877 //backround +/- error in the range
1878 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1883 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1884 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1885 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1892 //__________________________________________________________________________
1894 void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
1895 // Return significance in mean+- n sigma
1897 Double_t signal,errsignal,background,errbackground;
1898 Signal(nOfSigma,signal,errsignal);
1899 Background(nOfSigma,background,errbackground);
1901 significance = signal/TMath::Sqrt(signal+background);
1903 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);
1908 //__________________________________________________________________________
1910 void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
1911 // Return significance integral in a range
1913 Double_t signal,errsignal,background,errbackground;
1914 Signal(min, max,signal,errsignal);
1915 Background(min, max,background,errbackground);
1917 significance = signal/TMath::Sqrt(signal+background);
1919 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);