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() :
71 // default constructor
73 cout<<"Default constructor:"<<endl;
74 cout<<"Remember to set the Histo, the Type, the FixPar"<<endl;
78 //___________________________________________________________________________
80 AliHFMassFitter::AliHFMassFitter (const TH1F *histoToFit, Double_t minvalue, Double_t maxvalue, Int_t rebin,Int_t fittypeb,Int_t fittypes):
105 // standard constructor
107 fhistoInvMass= (TH1F*)histoToFit->Clone("fhistoInvMass");
108 fhistoInvMass->SetDirectory(0);
111 if(rebin!=1) RebinMass(rebin);
112 else fNbin=(Int_t)fhistoInvMass->GetNbinsX();
114 ftypeOfFit4Bkg=fittypeb;
115 ftypeOfFit4Sgn=fittypes;
116 if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2) fWithBkg=kFALSE;
118 if (!fWithBkg) cout<<"Fit Histogram of Signal only"<<endl;
119 else cout<<"Type of fit For Background = "<<ftypeOfFit4Bkg<<endl;
122 fFitPars=new Float_t[fParsSize];
124 SetDefaultFixParam();
126 fContourGraph=new TList();
127 fContourGraph->SetOwner();
132 AliHFMassFitter::AliHFMassFitter(const AliHFMassFitter &mfit):
134 fhistoInvMass(mfit.fhistoInvMass),
135 fminMass(mfit.fminMass),
136 fmaxMass(mfit.fmaxMass),
137 fminBinMass(mfit.fminBinMass),
138 fmaxBinMass(mfit.fmaxBinMass),
140 fParsSize(mfit.fParsSize),
141 fNFinalPars(mfit.fNFinalPars),
143 fWithBkg(mfit.fWithBkg),
144 ftypeOfFit4Bkg(mfit.ftypeOfFit4Bkg),
145 ftypeOfFit4Sgn(mfit.ftypeOfFit4Sgn),
146 ffactor(mfit.ffactor),
147 fntuParam(mfit.fntuParam),
149 fSigmaSgn(mfit.fSigmaSgn),
150 fSideBands(mfit.fSideBands),
152 fSideBandl(mfit.fSideBandl),
153 fSideBandr(mfit.fSideBandr),
154 fcounter(mfit.fcounter),
155 fContourGraph(mfit.fContourGraph)
159 if(mfit.fParsSize > 0){
160 fFitPars=new Float_t[fParsSize];
161 fFixPar=new Bool_t[fNFinalPars];
162 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
163 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Bool_t));
168 //_________________________________________________________________________
170 AliHFMassFitter::~AliHFMassFitter() {
174 cout<<"AliHFMassFitter destructor called"<<endl;
176 cout<<"deleting histogram..."<<endl;
177 delete fhistoInvMass;
181 cout<<"deleting ntuple..."<<endl;
189 cout<<"deleting parameter array..."<<endl;
195 cout<<"deleting bool array..."<<endl;
202 //_________________________________________________________________________
204 AliHFMassFitter& AliHFMassFitter::operator=(const AliHFMassFitter &mfit){
206 //assignment operator
208 if(&mfit == this) return *this;
209 fhistoInvMass= mfit.fhistoInvMass;
210 fminMass= mfit.fminMass;
211 fmaxMass= mfit.fmaxMass;
213 fParsSize= mfit.fParsSize;
214 fWithBkg= mfit.fWithBkg;
215 ftypeOfFit4Bkg= mfit.ftypeOfFit4Bkg;
216 ftypeOfFit4Sgn= mfit.ftypeOfFit4Sgn;
217 ffactor= mfit.ffactor;
218 fntuParam= mfit.fntuParam;
220 fSigmaSgn= mfit.fSigmaSgn;
221 fSideBands= mfit.fSideBands;
222 fSideBandl= mfit.fSideBandl;
223 fSideBandr= mfit.fSideBandr;
224 fcounter= mfit.fcounter;
225 fContourGraph= mfit.fContourGraph;
227 if(mfit.fParsSize > 0){
232 fFitPars=new Float_t[fParsSize];
233 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
239 fFixPar=new Bool_t[fNFinalPars];
240 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Float_t));
246 //************ tools & settings
248 //__________________________________________________________________________
250 void AliHFMassFitter::ComputeNFinalPars() {
252 //compute the number of parameters of the total (signal+bgk) function
253 cout<<"Info:ComputeNFinalPars... ";
254 switch (ftypeOfFit4Bkg) {//npar background func
268 cout<<"Error in computing fNFinalPars: check ftypeOfFit4Bkg"<<endl;
272 fNFinalPars+=3; //gaussian signal
273 cout<<": "<<fNFinalPars<<endl;
275 //__________________________________________________________________________
277 void AliHFMassFitter::ComputeParSize() {
279 //compute the size of the parameter array and set the data member
281 switch (ftypeOfFit4Bkg) {//npar background func
295 cout<<"Error in computing fParsSize: check ftypeOfFit4Bkg"<<endl;
299 fParsSize += 3; // npar refl
300 fParsSize += 3; // npar signal gaus
302 fParsSize*=2; // add errors
303 cout<<"Parameters array size "<<fParsSize<<endl;
306 //___________________________________________________________________________
307 void AliHFMassFitter::SetDefaultFixParam(){
309 //Set default values for fFixPar (only total integral fixed)
312 fFixPar=new Bool_t[fNFinalPars];
314 fFixPar[0]=kTRUE; //default: IntTot fixed
315 cout<<"Parameter 0 is fixed"<<endl;
316 for(Int_t i=1;i<fNFinalPars;i++){
322 //___________________________________________________________________________
323 Bool_t AliHFMassFitter::SetFixThisParam(Int_t thispar,Bool_t fixpar){
325 //set the value (kFALSE or kTRUE) of one element of fFixPar
326 //return kFALSE if something wrong
328 if(thispar>=fNFinalPars) {
329 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
333 cout<<"Initializing fFixPar...";
334 SetDefaultFixParam();
335 cout<<" done."<<endl;
338 fFixPar[thispar]=fixpar;
339 if(fixpar)cout<<"Parameter "<<thispar<<" is now fixed"<<endl;
340 else cout<<"Parameter "<<thispar<<" is now free"<<endl;
344 //___________________________________________________________________________
345 Bool_t AliHFMassFitter::GetFixThisParam(Int_t thispar)const{
346 //return the value of fFixPar[thispar]
347 if(thispar>=fNFinalPars) {
348 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
352 cout<<"Error! Parameters to be fixed still not set"<<endl;
356 return fFixPar[thispar];
360 //___________________________________________________________________________
361 void AliHFMassFitter::SetHisto(const TH1F *histoToFit){
363 fhistoInvMass = new TH1F(*histoToFit);
364 fhistoInvMass->SetDirectory(0);
365 //cout<<"SetHisto pointer "<<fhistoInvMass<<endl;
368 //___________________________________________________________________________
370 void AliHFMassFitter::SetType(Int_t fittypeb, Int_t fittypes) {
372 //set the type of fit to perform for signal and background
374 ftypeOfFit4Bkg = fittypeb;
375 ftypeOfFit4Sgn = fittypes;
378 fFitPars = new Float_t[fParsSize];
380 SetDefaultFixParam();
383 //___________________________________________________________________________
385 void AliHFMassFitter::Reset() {
387 //delete the histogram and reset the mean and sigma to default
389 cout<<"Reset called: delete histogram, set mean value to 1.85 and sigma to 0.012"<<endl;
392 cout<<"Reset "<<fhistoInvMass<<endl;
394 delete fhistoInvMass;
396 cout<<fhistoInvMass<<endl;
398 else cout<<"histogram doesn't exist, do not delete"<<endl;
403 //_________________________________________________________________________
405 void AliHFMassFitter::InitNtuParam(char *ntuname) {
407 // Create ntuple to keep fit parameters
410 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");
414 //_________________________________________________________________________
416 void AliHFMassFitter::FillNtuParam() {
417 // Fill ntuple with fit parameters
421 if (ftypeOfFit4Bkg==2) {
422 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
423 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
424 fntuParam->SetBranchAddress("conc1",&fFitPars[2]);
425 fntuParam->SetBranchAddress("intGB",&fFitPars[3]);
426 fntuParam->SetBranchAddress("meanGB",&fFitPars[4]);
427 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]);
428 fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]);
429 fntuParam->SetBranchAddress("slope2",&fFitPars[7]);
430 fntuParam->SetBranchAddress("conc2",&fFitPars[8]);
431 fntuParam->SetBranchAddress("inttot",&fFitPars[9]);
432 fntuParam->SetBranchAddress("slope3",&fFitPars[10]);
433 fntuParam->SetBranchAddress("conc3",&fFitPars[11]);
434 fntuParam->SetBranchAddress("intsgn",&fFitPars[12]);
435 fntuParam->SetBranchAddress("meansgn",&fFitPars[13]);
436 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]);
438 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]);
439 fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]);
440 fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]);
441 fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]);
442 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]);
443 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]);
444 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]);
445 fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]);
446 fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]);
447 fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]);
448 fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]);
449 fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]);
450 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]);
451 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]);
452 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]);
456 if(ftypeOfFit4Bkg==3){
457 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
458 fntuParam->SetBranchAddress("slope1",¬hing);
459 fntuParam->SetBranchAddress("conc1",¬hing);
460 fntuParam->SetBranchAddress("intGB",&fFitPars[1]);
461 fntuParam->SetBranchAddress("meanGB",&fFitPars[2]);
462 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]);
463 fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]);
464 fntuParam->SetBranchAddress("slope2",¬hing);
465 fntuParam->SetBranchAddress("conc2",¬hing);
466 fntuParam->SetBranchAddress("inttot",&fFitPars[6]);
467 fntuParam->SetBranchAddress("slope3",¬hing);
468 fntuParam->SetBranchAddress("conc3",¬hing);
469 fntuParam->SetBranchAddress("intsgn",&fFitPars[6]);
470 fntuParam->SetBranchAddress("meansgn",&fFitPars[7]);
471 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]);
473 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]);
474 fntuParam->SetBranchAddress("slope1Err",¬hing);
475 fntuParam->SetBranchAddress("conc1Err",¬hing);
476 fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]);
477 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]);
478 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]);
479 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]);
480 fntuParam->SetBranchAddress("slope2Err",¬hing);
481 fntuParam->SetBranchAddress("conc2Err",¬hing);
482 fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]);
483 fntuParam->SetBranchAddress("slope3Err",¬hing);
484 fntuParam->SetBranchAddress("conc3Err",¬hing);
485 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]);
486 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]);
487 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]);
491 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
492 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
493 fntuParam->SetBranchAddress("conc1",¬hing);
494 fntuParam->SetBranchAddress("intGB",&fFitPars[2]);
495 fntuParam->SetBranchAddress("meanGB",&fFitPars[3]);
496 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]);
497 fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]);
498 fntuParam->SetBranchAddress("slope2",&fFitPars[6]);
499 fntuParam->SetBranchAddress("conc2",¬hing);
500 fntuParam->SetBranchAddress("inttot",&fFitPars[7]);
501 fntuParam->SetBranchAddress("slope3",&fFitPars[8]);
502 fntuParam->SetBranchAddress("conc3",¬hing);
503 fntuParam->SetBranchAddress("intsgn",&fFitPars[9]);
504 fntuParam->SetBranchAddress("meansgn",&fFitPars[10]);
505 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]);
507 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]);
508 fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]);
509 fntuParam->SetBranchAddress("conc1Err",¬hing);
510 fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]);
511 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]);
512 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]);
513 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]);
514 fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]);
515 fntuParam->SetBranchAddress("conc2Err",¬hing);
516 fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]);
517 fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]);
518 fntuParam->SetBranchAddress("conc3Err",¬hing);
519 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]);
520 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]);
521 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]);
525 fntuParam->TTree::Fill();
528 //_________________________________________________________________________
530 TNtuple* AliHFMassFitter::NtuParamOneShot(char *ntuname){
531 // Create, fill and return ntuple with fit parameters
533 InitNtuParam(ntuname);
537 //_________________________________________________________________________
539 void AliHFMassFitter::RebinMass(Int_t bingroup){
540 // Rebin invariant mass histogram
543 cout<<"Histogram not set"<<endl;
546 Int_t nbinshisto=fhistoInvMass->GetNbinsX();
548 cout<<"Error! Cannot group "<<bingroup<<" bins\n";
550 cout<<"Kept original number of bins: "<<fNbin<<endl;
553 while(nbinshisto%bingroup != 0) {
556 cout<<"Group "<<bingroup<<" bins"<<endl;
557 fhistoInvMass->Rebin(bingroup);
558 fNbin = fhistoInvMass->GetNbinsX();
559 cout<<"New number of bins: "<<fNbin<<endl;
566 //___________________________________________________________________________
568 Double_t AliHFMassFitter::FitFunction4MassDistr (Double_t *x, Double_t *par){
569 // Fit function for signal+background
572 //exponential or linear fit
574 // par[0] = tot integral
576 // par[2] = gaussian integral
577 // par[3] = gaussian mean
578 // par[4] = gaussian sigma
580 Double_t total,bkg=0,sgn=0;
582 if (ftypeOfFit4Bkg==0 || ftypeOfFit4Bkg==1) {
583 if(ftypeOfFit4Sgn == 0) {
585 Double_t parbkg[2] = {par[0]-par[2], par[1]};
586 bkg = FitFunction4Bkg(x,parbkg);
588 if(ftypeOfFit4Sgn == 1) {
589 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-2*par[2], par[1]};
590 bkg = FitFunction4Bkg(x,parbkg);
593 sgn = FitFunction4Sgn(x,&par[2]);
599 // par[0] = tot integral
602 // par[3] = gaussian integral
603 // par[4] = gaussian mean
604 // par[5] = gaussian sigma
606 if (ftypeOfFit4Bkg==2) {
608 if(ftypeOfFit4Sgn == 0) {
610 Double_t parbkg[3] = {par[0]-par[3], par[1], par[2]};
611 bkg = FitFunction4Bkg(x,parbkg);
613 if(ftypeOfFit4Sgn == 1) {
615 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-2*par[3], par[1], par[2]};
616 bkg = FitFunction4Bkg(x,parbkg);
619 sgn = FitFunction4Sgn(x,&par[3]);
622 if (ftypeOfFit4Bkg==3) {
624 if(ftypeOfFit4Sgn == 0) {
625 bkg=FitFunction4Bkg(x,par);
626 sgn=FitFunction4Sgn(x,&par[1]);
628 if(ftypeOfFit4Sgn == 1) {
629 Double_t parbkg[4]={par[1],par[2],ffactor*par[3],par[0]};
630 bkg=FitFunction4Bkg(x,parbkg);
631 sgn=FitFunction4Sgn(x,&par[1]);
640 //_________________________________________________________________________
641 Double_t AliHFMassFitter::FitFunction4Sgn (Double_t *x, Double_t *par){
642 // Fit function for the signal
644 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
646 // * [0] = integralSgn
649 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
651 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]);
655 //__________________________________________________________________________
657 Double_t AliHFMassFitter::FitFunction4Bkg (Double_t *x, Double_t *par){
658 // Fit function for the background
660 Double_t maxDeltaM = 4.*fSigmaSgn;
661 if(fSideBands && TMath::Abs(x[0]-fMass) < maxDeltaM) {
666 Double_t gaus2=0,total=-1;
667 if(ftypeOfFit4Sgn == 1){
669 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
671 // * [0] = integralSgn
674 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
675 gaus2 = FitFunction4Sgn(x,par);
678 switch (ftypeOfFit4Bkg){
681 //exponential = A*exp(B*x) -> integral(exponential)=A/B*exp(B*x)](min,max)
682 //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written
683 //as integralTot- integralGaus (=par [2])
685 // * [0] = integralBkg;
687 //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x)
688 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]);
692 //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)
693 // * [0] = integralBkg;
695 total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass));
699 //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) +
700 //+ 1/3*c*(max^3-min^3) ->
701 //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min)
702 // * [0] = integralBkg;
705 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));
708 total=par[0+firstPar];
711 // Types of Fit Functions for Background:
712 // * 0 = exponential;
714 // * 2 = polynomial 2nd order
715 // * 3 = no background"<<endl;
721 //__________________________________________________________________________
722 Bool_t AliHFMassFitter::SideBandsBounds(){
724 //determines the ranges of the side bands
726 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
727 Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
728 Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin+1);
730 Double_t sidebandldouble,sidebandrdouble;
731 Bool_t leftok=kFALSE, rightok=kFALSE;
733 if(fMass-fminMass < 0 || fmaxMass-fMass <0) {
734 cout<<"Left limit of range > mean or right limit of range < mean: change left/right limit or initial mean value"<<endl;
738 //histo limit = fit function limit
739 if((TMath::Abs(fminMass-minHisto) < 1e6 || TMath::Abs(fmaxMass - maxHisto) < 1e6) && (fMass-4.*fSigmaSgn-fminMass) < 1e6){
740 Double_t coeff = (fMass-fminMass)/fSigmaSgn;
741 sidebandldouble=(fMass-0.5*coeff*fSigmaSgn);
742 sidebandrdouble=(fMass+0.5*coeff*fSigmaSgn);
743 cout<<"Changed number of sigma from 4 to "<<0.5*coeff<<" for the estimation of the side bands"<<endl;
744 if (coeff<3) cout<<"Side bands inside 3 sigma, may be better use ftypeOfFit4Bkg = 3 (only signal)"<<endl;
746 cout<<"Side bands inside 2 sigma. Change mode: ftypeOfFit4Bkg = 3"<<endl;
748 //set binleft and right without considering SetRangeFit- anyway no bkg!
749 sidebandldouble=(fMass-4.*fSigmaSgn);
750 sidebandrdouble=(fMass+4.*fSigmaSgn);
754 sidebandldouble=(fMass-4.*fSigmaSgn);
755 sidebandrdouble=(fMass+4.*fSigmaSgn);
758 cout<<"Left side band ";
761 //calculate bin corresponding to fSideBandl
762 fSideBandl=fhistoInvMass->FindBin(sidebandldouble);
763 if (sidebandldouble >= fhistoInvMass->GetBinCenter(fSideBandl)) fSideBandl++;
764 sidebandldouble=fhistoInvMass->GetBinLowEdge(fSideBandl);
766 if(TMath::Abs(tmp-sidebandldouble) > 1e-6){
767 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
770 cout<<sidebandldouble<<" (bin "<<fSideBandl<<")"<<endl;
772 cout<<"Right side band ";
774 //calculate bin corresponding to fSideBandr
775 fSideBandr=fhistoInvMass->FindBin(sidebandrdouble);
776 if (sidebandrdouble < fhistoInvMass->GetBinCenter(fSideBandr)) fSideBandr--;
777 sidebandrdouble=fhistoInvMass->GetBinLowEdge(fSideBandr+1);
779 if(TMath::Abs(tmp-sidebandrdouble) > 1e-6){
780 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
783 cout<<sidebandrdouble<<" (bin "<<fSideBandr<<")"<<endl;
784 if (fSideBandl==0 || fSideBandr==fNbin) {
785 cout<<"Error! Range too little";
791 //__________________________________________________________________________
793 void AliHFMassFitter::GetSideBandsBounds(Int_t &left, Int_t &right) const{
795 // get the range of the side bands
797 if (fSideBandl==0 && fSideBandr==0){
798 cout<<"Use MassFitter method first"<<endl;
805 //__________________________________________________________________________
806 Bool_t AliHFMassFitter::CheckRangeFit(){
807 //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
809 if (!fhistoInvMass) {
810 cout<<"No histogram to fit! SetHisto(TH1F* h) before! "<<endl;
813 Bool_t leftok=kFALSE, rightok=kFALSE;
814 Int_t nbins=fhistoInvMass->GetNbinsX();
815 Double_t minhisto=fhistoInvMass->GetBinLowEdge(1), maxhisto=fhistoInvMass->GetBinLowEdge(nbins+1);
817 //check if limits are inside histogram range
819 if( fminMass-minhisto < 0. ) {
820 cout<<"Out of histogram left bound! Setting to "<<minhisto<<endl;
823 if( fmaxMass-maxhisto > 0. ) {
824 cout<<"Out of histogram right bound! Setting to"<<maxhisto<<endl;
830 //calculate bin corresponding to fminMass
831 fminBinMass=fhistoInvMass->FindBin(fminMass);
832 if (fminMass >= fhistoInvMass->GetBinCenter(fminBinMass)) fminBinMass++;
833 fminMass=fhistoInvMass->GetBinLowEdge(fminBinMass);
834 if(TMath::Abs(tmp-fminMass) > 1e-6){
835 cout<<"Left bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fminMass<<endl;
840 //calculate bin corresponding to fmaxMass
841 fmaxBinMass=fhistoInvMass->FindBin(fmaxMass);
842 if (fmaxMass < fhistoInvMass->GetBinCenter(fmaxBinMass)) fmaxBinMass--;
843 fmaxMass=fhistoInvMass->GetBinLowEdge(fmaxBinMass+1);
844 if(TMath::Abs(tmp-fmaxMass) > 1e-6){
845 cout<<"Right bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fmaxMass<<endl;
849 return (leftok && rightok);
853 //__________________________________________________________________________
855 Bool_t AliHFMassFitter::MassFitter(Bool_t draw){
856 // Main method of the class: performs the fit of the histogram
858 //Set default fitter Minuit in order to use gMinuit in the contour plots
859 TVirtualFitter::SetDefaultFitter("Minuit");
862 Bool_t isBkgOnly=kFALSE;
864 Int_t fit1status=RefitWithBkgOnly(kFALSE);
866 Int_t checkinnsigma=4;
867 Double_t range[2]={fMass-checkinnsigma*fSigmaSgn,fMass+checkinnsigma*fSigmaSgn};
868 TF1* func=GetHistoClone()->GetFunction("funcbkgonly");
869 Double_t intUnderFunc=func->Integral(range[0],range[1]);
870 Double_t intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(range[0]),fhistoInvMass->FindBin(range[1]),"width");
871 cout<<"Pick zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
872 Double_t diffUnderPick=(intUnderHisto-intUnderFunc);
873 intUnderFunc=func->Integral(fminMass,fminMass+checkinnsigma*fSigmaSgn);
874 intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fminMass+checkinnsigma*fSigmaSgn),"width");
875 cout<<"Band (l) zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
876 Double_t diffUnderBands=(intUnderHisto-intUnderFunc);
877 Double_t relDiff=diffUnderPick/diffUnderBands;
878 cout<<"Relative difference = "<<relDiff<<endl;
879 if(TMath::Abs(relDiff) < 1) isBkgOnly=kTRUE;
881 cout<<"Relative difference = "<<relDiff<<": I suppose there is some signal, continue with total fit!"<<endl;
885 cout<<"INFO!! The histogram contains only background"<<endl;
888 //increase counter of number of fits done
894 Int_t bkgPar = fNFinalPars-3; //background function's number of parameters
896 cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
899 TString listname="contourplot";
902 fContourGraph=new TList();
903 fContourGraph->SetOwner();
906 fContourGraph->SetName(listname);
910 TString bkgname="funcbkg";
911 TString bkg1name="funcbkg1";
912 TString massname="funcmass";
915 Double_t totInt = fhistoInvMass->Integral(fminBinMass,fmaxBinMass, "width");
916 //cout<<"Here tot integral is = "<<totInt<<"; integral in whole range is "<<fhistoInvMass->Integral("width")<<endl;
918 Double_t width=fhistoInvMass->GetBinWidth(8);
919 //cout<<"fNbin = "<<fNbin<<endl;
920 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
922 Bool_t ok=SideBandsBounds();
923 if(!ok) return kFALSE;
925 //sidebands integral - first approx (from histo)
926 Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,fSideBandl,"width") + (Double_t)fhistoInvMass->Integral(fSideBandr,fNbin,"width");
927 cout<<"------nbin = "<<fNbin<<"\twidth = "<<width<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
928 cout<<"------sideBandsInt - first approx = "<<sideBandsInt<<endl;
929 if (sideBandsInt<=0) {
930 cout<<"! sideBandsInt <=0. There's a problem, cannot start the fit"<<endl;
937 TF1 *funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
938 cout<<"Function name = "<<funcbkg->GetName()<<endl<<endl;
940 funcbkg->SetLineColor(2); //red
942 //first fit for bkg: approx bkgint
944 switch (ftypeOfFit4Bkg) {
946 funcbkg->SetParNames("BkgInt","Slope");
947 funcbkg->SetParameters(sideBandsInt,-2.);
950 funcbkg->SetParNames("BkgInt","Slope");
951 funcbkg->SetParameters(sideBandsInt,-100.);
954 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
955 funcbkg->SetParameters(sideBandsInt,-10.,5);
958 if(ftypeOfFit4Sgn==0){
959 funcbkg->SetParNames("Const");
960 funcbkg->SetParameter(0,0.);
961 funcbkg->FixParameter(0,0.);
965 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
969 cout<<"\nBACKGROUND FIT - only combinatorial"<<endl;
970 Int_t ftypeOfFit4SgnBkp=ftypeOfFit4Sgn;
972 Double_t intbkg1=0,slope1=0,conc1=0;
973 //if only signal and reflection: skip
974 if (!(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn==1)) {
976 fhistoInvMass->Fit(bkgname.Data(),"R,L,E,0");
978 for(Int_t i=0;i<bkgPar;i++){
979 fFitPars[i]=funcbkg->GetParameter(i);
980 //cout<<i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
981 fFitPars[fNFinalPars+2*bkgPar+3+i]= funcbkg->GetParError(i);
982 //cout<<fNFinalPars+2*bkgPar+3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
985 //intbkg1 = funcbkg->GetParameter(0);
987 intbkg1 = funcbkg->Integral(fminMass,fmaxMass);
988 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1);
989 if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2);
990 //cout<<"First fit: \nintbkg1 = "<<intbkg1<<"\t(Compare with par0 = "<<funcbkg->GetParameter(0)<<")\nslope1= "<<slope1<<"\nconc1 = "<<conc1<<endl;
992 else cout<<"\t\t//"<<endl;
994 ftypeOfFit4Sgn=ftypeOfFit4SgnBkp;
996 if (ftypeOfFit4Sgn == 1) {
997 cout<<"\nBACKGROUND FIT WITH REFLECTION"<<endl;
1000 //cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
1002 funcbkg1 = new TF1(bkg1name.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
1003 cout<<"Function name = "<<funcbkg1->GetName()<<endl;
1005 funcbkg1->SetLineColor(2); //red
1007 if(ftypeOfFit4Bkg==2){
1008 cout<<"*** Polynomial Fit ***"<<endl;
1009 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
1010 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
1012 //cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<<fMass<<"\t"<<ffactor*fSigmaSgn<<"\t"<<intbkg1<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<endl;
1013 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<bkgPar<<"\tgsidebands = "<<fSideBands<<endl;
1015 if(ftypeOfFit4Bkg==3) //no background: gaus sign+ gaus broadened
1017 cout<<"*** No background Fit ***"<<endl;
1018 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","Const");
1019 funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.);
1020 funcbkg1->FixParameter(3,0.);
1021 } else{ //expo or linear
1022 if(ftypeOfFit4Bkg==0) cout<<"*** Exponential Fit ***"<<endl;
1023 if(ftypeOfFit4Bkg==1) cout<<"*** Linear Fit ***"<<endl;
1024 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
1025 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
1028 Int_t status=fhistoInvMass->Fit(bkg1name.Data(),"R,L,E,+,0");
1030 cout<<"Minuit returned "<<status<<endl;
1034 for(Int_t i=0;i<bkgPar;i++){
1035 fFitPars[bkgPar-3+i]=funcbkg1->GetParameter(i);
1036 //cout<<bkgPar-3+i<<"\t"<<funcbkg1->GetParameter(i);
1037 fFitPars[fNFinalPars+3*bkgPar-6+i]= funcbkg1->GetParError(i);
1038 //cout<<"\t"<<fNFinalPars+3*bkgPar-6+i<<"\t"<<funcbkg1->GetParError(i)<<endl;
1041 intbkg1=funcbkg1->GetParameter(3);
1042 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4);
1043 if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5);
1048 for(Int_t i=0;i<3;i++){
1049 fFitPars[bkgPar-3+i]=0.;
1050 cout<<bkgPar-3+i<<"\t"<<0.<<"\t";
1051 fFitPars[fNFinalPars+3*bkgPar-6+i]= 0.;
1052 cout<<fNFinalPars+3*bkgPar-6+i<<"\t"<<0.<<endl;
1055 for(Int_t i=0;i<bkgPar-3;i++){
1056 fFitPars[bkgPar+i]=funcbkg->GetParameter(i);
1057 cout<<bkgPar+i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
1058 fFitPars[fNFinalPars+3*bkgPar-3+i]= funcbkg->GetParError(i);
1059 cout<<fNFinalPars+3*bkgPar-3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
1065 //sidebands integral - second approx (from fit)
1066 fSideBands = kFALSE;
1068 //cout<<"Compare intbkg1 = "<<intbkg1<<" and integral = ";
1069 if(ftypeOfFit4Sgn == 1) bkgInt=funcbkg1->Integral(fminMass,fmaxMass);
1070 else bkgInt=funcbkg->Integral(fminMass,fmaxMass);
1071 //cout<</*"------BkgInt(Fit) = "<<*/bkgInt<<endl;
1073 //Signal integral - first approx
1075 sgnInt = totInt-bkgInt;
1076 //cout<<"------TotInt = "<<totInt<<"\tsgnInt = "<<sgnInt<<endl;
1078 cout<<"Setting sgnInt = - sgnInt"<<endl;
1081 /*Fit All Mass distribution with exponential + gaussian (+gaussian braodened) */
1082 TF1 *funcmass = new TF1(massname.Data(),this,&AliHFMassFitter::FitFunction4MassDistr,fminMass,fmaxMass,fNFinalPars,"AliHFMassFitter","FitFunction4MassDistr");
1083 cout<<"Function name = "<<funcmass->GetName()<<endl<<endl;
1084 funcmass->SetLineColor(4); //blue
1087 cout<<"\nTOTAL FIT"<<endl;
1090 funcmass->SetParNames("TotInt","Slope","SgnInt","Mean","Sigma");
1091 funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn);
1093 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1094 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1096 funcmass->FixParameter(0,totInt);
1099 funcmass->FixParameter(1,slope1);
1102 funcmass->FixParameter(2,sgnInt);
1105 funcmass->FixParameter(3,fMass);
1108 funcmass->FixParameter(4,fSigmaSgn);
1111 if (fNFinalPars==6){
1112 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1113 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
1115 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1116 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1117 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1118 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1119 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1120 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1121 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1122 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1124 //funcmass->FixParameter(2,sgnInt);
1127 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
1128 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1129 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
1130 if(fFixPar[0]) funcmass->FixParameter(0,0.);
1131 if(fFixPar[1])funcmass->FixParameter(1,sgnInt);
1132 if(fFixPar[2])funcmass->FixParameter(2,fMass);
1133 if(fFixPar[3])funcmass->FixParameter(3,fSigmaSgn);
1134 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1135 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1141 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1143 cout<<"Minuit returned "<<status<<endl;
1147 cout<<"fit done"<<endl;
1148 //reset value of fMass and fSigmaSgn to those found from fit
1149 fMass=funcmass->GetParameter(fNFinalPars-2);
1150 fSigmaSgn=funcmass->GetParameter(fNFinalPars-1);
1152 for(Int_t i=0;i<fNFinalPars;i++){
1153 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
1154 fFitPars[fNFinalPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1155 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<fNFinalPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
1158 //check: cout parameters
1159 for(Int_t i=0;i<2*(fNFinalPars+2*bkgPar-3);i++){
1160 cout<<i<<"\t"<<fFitPars[i]<<endl;
1164 if(funcmass->GetParameter(fNFinalPars-1) <0 || funcmass->GetParameter(fNFinalPars-2) <0 || funcmass->GetParameter(fNFinalPars-3) <0 ) {
1165 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
1169 //increase counter of number of fits done
1175 for (Int_t kpar=1; kpar<fNFinalPars;kpar++){
1177 for(Int_t jpar=kpar+1;jpar<fNFinalPars;jpar++){
1178 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1180 // produce 2 contours per couple of parameters
1181 TGraph* cont[2] = {0x0, 0x0};
1182 const Double_t errDef[2] = {1., 4.};
1183 for (Int_t i=0; i<2; i++) {
1184 gMinuit->SetErrorDef(errDef[i]);
1185 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
1186 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
1189 if(!cont[0] || !cont[1]){
1190 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1194 // set graph titles and add them to the list
1195 TString title = "Contour plot";
1196 TString titleX = funcmass->GetParName(kpar);
1197 TString titleY = funcmass->GetParName(jpar);
1198 for (Int_t i=0; i<2; i++) {
1199 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1200 cont[i]->SetTitle(title);
1201 cont[i]->GetXaxis()->SetTitle(titleX);
1202 cont[i]->GetYaxis()->SetTitle(titleY);
1203 cont[i]->GetYaxis()->SetLabelSize(0.033);
1204 cont[i]->GetYaxis()->SetTitleSize(0.033);
1205 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1207 fContourGraph->Add(cont[i]);
1211 TString cvname = Form("c%d%d", kpar, jpar);
1212 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1214 cont[1]->SetFillColor(38);
1215 cont[1]->Draw("alf");
1216 cont[0]->SetFillColor(9);
1217 cont[0]->Draw("lf");
1225 if (ftypeOfFit4Sgn == 1 && funcbkg1) {
1238 AddFunctionsToHisto();
1239 if (draw) DrawFit();
1245 //______________________________________________________________________________
1247 Bool_t AliHFMassFitter::RefitWithBkgOnly(Bool_t draw){
1249 //perform a fit with background function only. Can be useful to try when fit fails to understand if it is because there's no signal
1250 //If you want to change the backgroud function or range use SetType or SetRangeFit before
1252 TString bkgname="funcbkgonly";
1253 fSideBands = kFALSE;
1255 TF1* funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1257 funcbkg->SetLineColor(kBlue+3); //dark blue
1259 Double_t integral=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fmaxMass),"width");
1261 switch (ftypeOfFit4Bkg) {
1263 funcbkg->SetParNames("BkgInt","Slope");
1264 funcbkg->SetParameters(integral,-2.);
1267 funcbkg->SetParNames("BkgInt","Slope");
1268 funcbkg->SetParameters(integral,-100.);
1271 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1272 funcbkg->SetParameters(integral,-10.,5);
1275 cout<<"Warning! This choice does not have a lot of sense..."<<endl;
1276 if(ftypeOfFit4Sgn==0){
1277 funcbkg->SetParNames("Const");
1278 funcbkg->SetParameter(0,0.);
1279 funcbkg->FixParameter(0,0.);
1283 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1289 Int_t status=fhistoInvMass->Fit(bkgname.Data(),"R,L,E,+,0");
1291 cout<<"Minuit returned "<<status<<endl;
1294 AddFunctionsToHisto();
1301 //_________________________________________________________________________
1302 Double_t AliHFMassFitter::GetChiSquare() const{
1303 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1305 cout<<"funcmass not found"<<endl;
1308 return funcmass->GetChisquare();
1311 //_________________________________________________________________________
1312 Double_t AliHFMassFitter::GetReducedChiSquare() const{
1313 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1315 cout<<"funcmass not found"<<endl;
1318 return funcmass->GetChisquare()/funcmass->GetNDF();
1323 //_________________________________________________________________________
1324 void AliHFMassFitter::GetFitPars(Float_t *vector) const {
1325 // Return fit parameters
1327 for(Int_t i=0;i<fParsSize;i++){
1328 vector[i]=fFitPars[i];
1333 //_________________________________________________________________________
1334 void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1336 //gives the integral of signal obtained from fit parameters
1337 if(!valuewitherror)valuewitherror=new Float_t[2];
1339 Int_t index=fParsSize/2 - 3;
1340 valuewitherror[0]=fFitPars[index];
1341 index=fParsSize - 3;
1342 valuewitherror[1]=fFitPars[index];
1346 //_________________________________________________________________________
1347 void AliHFMassFitter::AddFunctionsToHisto(){
1349 //Add the background function in the complete range to the list of functions attached to the histogram
1351 //cout<<"AddFunctionsToHisto called"<<endl;
1352 TString bkgname = "funcbkg";
1354 Bool_t done1=kFALSE,done2=kFALSE;
1356 TString bkgnamesave=bkgname;
1357 TString testname=bkgname;
1358 testname += "FullRange";
1359 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1364 testname="funcbkgonly";
1365 testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1372 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1376 TList *hlist=fhistoInvMass->GetListOfFunctions();
1380 TF1 *bonly=(TF1*)hlist->FindObject(testname.Data());
1382 cout<<testname.Data()<<" not found looking for complete fit"<<endl;
1384 bonly->SetLineColor(kBlue+3);
1385 hlist->Add((TF1*)bonly->Clone());
1395 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1397 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1401 bkgname += "FullRange";
1402 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1403 //cout<<bfullrange->GetName()<<endl;
1404 for(Int_t i=0;i<fNFinalPars-3;i++){
1405 bfullrange->SetParName(i,b->GetParName(i));
1406 bfullrange->SetParameter(i,b->GetParameter(i));
1407 bfullrange->SetParError(i,b->GetParError(i));
1409 bfullrange->SetLineStyle(4);
1410 bfullrange->SetLineColor(14);
1412 bkgnamesave += "Recalc";
1414 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1416 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
1419 cout<<"funcmass doesn't exist "<<endl;
1423 //intBkg=intTot-intS
1424 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(fNFinalPars-3));
1425 blastpar->SetParError(0,mass->GetParError(fNFinalPars-3));
1426 if (fNFinalPars>=5) {
1427 blastpar->SetParameter(1,mass->GetParameter(1));
1428 blastpar->SetParError(1,mass->GetParError(1));
1430 if (fNFinalPars==6) {
1431 blastpar->SetParameter(2,mass->GetParameter(2));
1432 blastpar->SetParError(2,mass->GetParError(2));
1435 blastpar->SetLineStyle(1);
1436 blastpar->SetLineColor(2);
1438 hlist->Add((TF1*)bfullrange->Clone());
1439 hlist->Add((TF1*)blastpar->Clone());
1455 //_________________________________________________________________________
1457 TH1F* AliHFMassFitter::GetHistoClone() const{
1459 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1462 //_________________________________________________________________________
1464 void AliHFMassFitter::WriteHisto(TString path) const {
1466 //Write the histogram in the default file HFMassFitterOutput.root
1468 if (fcounter == 0) {
1469 cout<<"Use MassFitter method before WriteHisto"<<endl;
1472 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1474 path += "HFMassFitterOutput.root";
1477 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1478 else output = new TFile(path.Data(),"update");
1481 fContourGraph->Write();
1486 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
1495 //_________________________________________________________________________
1497 void AliHFMassFitter::WriteNtuple(TString path) const{
1498 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
1499 path += "HFMassFitterOutput.root";
1500 TFile *output = new TFile(path.Data(),"update");
1505 //cout<<nget->GetName()<<" written in "<<path<<endl;
1506 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1519 //_________________________________________________________________________
1520 void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1522 //write the canvas in a root file
1524 gStyle->SetOptStat(0);
1525 gStyle->SetCanvasColor(0);
1526 gStyle->SetFrameFillColor(0);
1530 switch (ftypeOfFit4Bkg){
1545 TString filename=Form("%sMassFit.root",type.Data());
1546 filename.Prepend(userIDstring);
1547 path.Append(filename);
1549 TFile* outputcv=new TFile(path.Data(),"update");
1551 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1552 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1553 if(draw)c->DrawClone();
1559 //_________________________________________________________________________
1561 TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
1562 //return a TVirtualPad with the fitted histograms and info
1564 TString cvtitle="fit of ";
1565 cvtitle+=fhistoInvMass->GetName();
1569 TCanvas *c=new TCanvas(cvname,cvtitle);
1570 PlotFit(c->cd(),nsigma,writeFitInfo);
1573 //_________________________________________________________________________
1575 void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1576 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
1577 gStyle->SetOptStat(0);
1578 gStyle->SetCanvasColor(0);
1579 gStyle->SetFrameFillColor(0);
1581 cout<<"nsigma = "<<nsigma<<endl;
1582 cout<<"Verbosity = "<<writeFitInfo<<endl;
1584 TH1F* hdraw=GetHistoClone();
1586 if(!hdraw->GetFunction("funcmass") && !hdraw->GetFunction("funcbkgFullRange") && !hdraw->GetFunction("funcbkgRecalc")&& !hdraw->GetFunction("funcbkgonly")){
1587 cout<<"Probably fit failed and you didn't try to refit with background only, there's no function to be drawn"<<endl;
1591 if(hdraw->GetFunction("funcbkgonly")){ //Warning! if this function is present, no chance to draw the other!
1592 cout<<"Drawing background fit only"<<endl;
1593 hdraw->SetMinimum(0);
1594 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1596 hdraw->SetMarkerStyle(20);
1597 hdraw->DrawClone("PE");
1598 hdraw->GetFunction("funcbkgonly")->DrawClone("sames");
1600 if(writeFitInfo > 0){
1601 TPaveText *pinfo=new TPaveText(0.6,0.86,1.,1.,"NDC");
1602 pinfo->SetBorderSize(0);
1603 pinfo->SetFillStyle(0);
1604 TF1* f=hdraw->GetFunction("funcbkgonly");
1605 for (Int_t i=0;i<fNFinalPars-3;i++){
1606 pinfo->SetTextColor(kBlue+3);
1607 TString str=Form("%s = %f #pm %f",f->GetParName(i),f->GetParameter(i),f->GetParError(i));
1608 pinfo->AddText(str);
1611 pinfo->AddText(Form("Reduced #chi^{2} = %.3f",f->GetChisquare()/f->GetNDF()));
1621 hdraw->SetMinimum(0);
1622 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1624 hdraw->SetMarkerStyle(20);
1625 hdraw->DrawClone("PE");
1626 // if(hdraw->GetFunction("funcbkgFullRange")) hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1627 // if(hdraw->GetFunction("funcbkgRecalc")) hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
1628 if(hdraw->GetFunction("funcmass")) hdraw->GetFunction("funcmass")->DrawClone("same");
1630 if(writeFitInfo > 0){
1631 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1632 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1633 pinfob->SetBorderSize(0);
1634 pinfob->SetFillStyle(0);
1635 pinfom->SetBorderSize(0);
1636 pinfom->SetFillStyle(0);
1637 TF1* ff=fhistoInvMass->GetFunction("funcmass");
1639 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1640 pinfom->SetTextColor(kBlue);
1641 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1642 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
1645 pinfom->DrawClone();
1647 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1648 pinfo2->SetBorderSize(0);
1649 pinfo2->SetFillStyle(0);
1651 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1653 Significance(nsigma,signif,errsignif);
1654 Signal(nsigma,signal,errsignal);
1655 Background(nsigma,bkg, errbkg);
1657 Significance(1.828,1.892,signif,errsignif);
1658 Signal(1.828,1.892,signal,errsignal);
1659 Background(1.828,1.892,bkg, errbkg);
1661 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
1662 pinfo2->AddText(str);
1663 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
1664 pinfo2->AddText(str);
1665 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
1666 pinfo2->AddText(str);
1671 if(writeFitInfo > 1){
1672 for (Int_t i=0;i<fNFinalPars-3;i++){
1673 pinfob->SetTextColor(kRed);
1674 str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1675 pinfob->AddText(str);
1678 pinfob->DrawClone();
1686 //_________________________________________________________________________
1688 void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
1689 //draws histogram together with fit functions with default nice colors in user canvas
1690 PlotFit(pd,nsigma,writeFitInfo);
1695 //_________________________________________________________________________
1696 void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1698 //draws histogram together with fit functions with default nice colors
1699 gStyle->SetOptStat(0);
1700 gStyle->SetCanvasColor(0);
1701 gStyle->SetFrameFillColor(0);
1704 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
1710 //_________________________________________________________________________
1712 void AliHFMassFitter::PrintParTitles() const{
1714 //prints to screen the parameters names
1716 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1718 cout<<"Fit function not found"<<endl;
1722 cout<<"Parameter Titles \n";
1723 for(Int_t i=0;i<fNFinalPars;i++){
1724 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1730 //************ significance
1732 //_________________________________________________________________________
1734 void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1735 // Return signal integral in mean+- n sigma
1738 cout<<"Use MassFitter method before Signal"<<endl;
1742 Double_t min=fMass-nOfSigma*fSigmaSgn;
1743 Double_t max=fMass+nOfSigma*fSigmaSgn;
1745 Signal(min,max,signal,errsignal);
1752 //_________________________________________________________________________
1754 void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1756 // Return signal integral in a range
1759 cout<<"Use MassFitter method before Signal"<<endl;
1764 TString bkgname="funcbkgRecalc";
1765 TString bkg1name="funcbkg1Recalc";
1766 TString massname="funcmass";
1770 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1772 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1776 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1777 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1780 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1784 Int_t np=fNFinalPars-3;
1786 Double_t intS,intSerr;
1788 //relative error evaluation
1789 intS=funcmass->GetParameter(np);
1790 intSerr=funcmass->GetParError(np);
1792 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1793 Double_t background,errbackground;
1794 Background(min,max,background,errbackground);
1796 //signal +/- error in the range
1798 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1799 signal=mass - background;
1800 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
1804 //_________________________________________________________________________
1806 void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1807 // Return background integral in mean+- n sigma
1810 cout<<"Use MassFitter method before Background"<<endl;
1813 Double_t min=fMass-nOfSigma*fSigmaSgn;
1814 Double_t max=fMass+nOfSigma*fSigmaSgn;
1816 Background(min,max,background,errbackground);
1821 //___________________________________________________________________________
1823 void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1824 // Return background integral in a range
1827 cout<<"Use MassFitter method before Background"<<endl;
1832 TString bkgname="funcbkgRecalc";
1833 TString bkg1name="funcbkg1Recalc";
1836 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1837 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1839 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1844 Double_t intB,intBerr;
1846 //relative error evaluation: from final parameters of the fit
1847 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1849 intB=funcbkg->GetParameter(0);
1850 intBerr=funcbkg->GetParError(0);
1851 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1854 //relative error evaluation: from histo
1856 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1858 for(Int_t i=1;i<=fSideBandl;i++){
1859 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1861 for(Int_t i=fSideBandr;i<=fNbin;i++){
1862 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1865 intBerr=TMath::Sqrt(sum2);
1866 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1868 cout<<"Last estimation of bkg error is used"<<endl;
1870 //backround +/- error in the range
1871 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1876 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1877 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1878 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1885 //__________________________________________________________________________
1887 void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
1888 // Return significance in mean+- n sigma
1890 Double_t min=fMass-nOfSigma*fSigmaSgn;
1891 Double_t max=fMass+nOfSigma*fSigmaSgn;
1892 Significance(min, max, significance, errsignificance);
1897 //__________________________________________________________________________
1899 void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
1900 // Return significance integral in a range
1902 Double_t signal,errsignal,background,errbackground;
1903 Signal(min, max,signal,errsignal);
1904 Background(min, max,background,errbackground);
1906 if (signal+background <= 0.){
1907 cout<<"Cannot calculate significance because of div by 0!"<<endl;
1913 significance = signal/TMath::Sqrt(signal+background);
1915 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);