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;
1097 funcmass->FixParameter(0,totInt);
1101 funcmass->FixParameter(1,slope1);
1105 funcmass->FixParameter(2,sgnInt);
1109 funcmass->FixParameter(3,fMass);
1113 funcmass->FixParameter(4,fSigmaSgn);
1116 if (fNFinalPars==6){
1117 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1118 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
1120 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1121 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1122 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1123 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1124 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1125 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1126 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1127 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1129 //funcmass->FixParameter(2,sgnInt);
1132 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
1133 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1134 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
1135 if(fFixPar[0]) funcmass->FixParameter(0,0.);
1136 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1137 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1143 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1145 cout<<"Minuit returned "<<status<<endl;
1149 cout<<"fit done"<<endl;
1150 //reset value of fMass and fSigmaSgn to those found from fit
1151 fMass=funcmass->GetParameter(fNFinalPars-2);
1152 fSigmaSgn=funcmass->GetParameter(fNFinalPars-1);
1154 for(Int_t i=0;i<fNFinalPars;i++){
1155 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
1156 fFitPars[fNFinalPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1157 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<fNFinalPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
1160 //check: cout parameters
1161 for(Int_t i=0;i<2*(fNFinalPars+2*bkgPar-3);i++){
1162 cout<<i<<"\t"<<fFitPars[i]<<endl;
1166 if(funcmass->GetParameter(fNFinalPars-1) <0 || funcmass->GetParameter(fNFinalPars-2) <0 || funcmass->GetParameter(fNFinalPars-3) <0 ) {
1167 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
1171 //increase counter of number of fits done
1177 for (Int_t kpar=1; kpar<fNFinalPars;kpar++){
1179 for(Int_t jpar=kpar+1;jpar<fNFinalPars;jpar++){
1180 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1182 // produce 2 contours per couple of parameters
1183 TGraph* cont[2] = {0x0, 0x0};
1184 const Double_t errDef[2] = {1., 4.};
1185 for (Int_t i=0; i<2; i++) {
1186 gMinuit->SetErrorDef(errDef[i]);
1187 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
1188 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
1191 if(!cont[0] || !cont[1]){
1192 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1196 // set graph titles and add them to the list
1197 TString title = "Contour plot";
1198 TString titleX = funcmass->GetParName(kpar);
1199 TString titleY = funcmass->GetParName(jpar);
1200 for (Int_t i=0; i<2; i++) {
1201 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1202 cont[i]->SetTitle(title);
1203 cont[i]->GetXaxis()->SetTitle(titleX);
1204 cont[i]->GetYaxis()->SetTitle(titleY);
1205 cont[i]->GetYaxis()->SetLabelSize(0.033);
1206 cont[i]->GetYaxis()->SetTitleSize(0.033);
1207 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1209 fContourGraph->Add(cont[i]);
1213 TString cvname = Form("c%d%d", kpar, jpar);
1214 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1216 cont[1]->SetFillColor(38);
1217 cont[1]->Draw("alf");
1218 cont[0]->SetFillColor(9);
1219 cont[0]->Draw("lf");
1227 if (ftypeOfFit4Sgn == 1 && funcbkg1) {
1240 AddFunctionsToHisto();
1241 if (draw) DrawFit();
1247 //______________________________________________________________________________
1249 Bool_t AliHFMassFitter::RefitWithBkgOnly(Bool_t draw){
1251 //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
1252 //If you want to change the backgroud function or range use SetType or SetRangeFit before
1254 TString bkgname="funcbkgonly";
1255 fSideBands = kFALSE;
1257 TF1* funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1259 funcbkg->SetLineColor(kBlue+3); //dark blue
1261 Double_t integral=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fmaxMass),"width");
1263 switch (ftypeOfFit4Bkg) {
1265 funcbkg->SetParNames("BkgInt","Slope");
1266 funcbkg->SetParameters(integral,-2.);
1269 funcbkg->SetParNames("BkgInt","Slope");
1270 funcbkg->SetParameters(integral,-100.);
1273 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1274 funcbkg->SetParameters(integral,-10.,5);
1277 cout<<"Warning! This choice does not have a lot of sense..."<<endl;
1278 if(ftypeOfFit4Sgn==0){
1279 funcbkg->SetParNames("Const");
1280 funcbkg->SetParameter(0,0.);
1281 funcbkg->FixParameter(0,0.);
1285 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1291 Int_t status=fhistoInvMass->Fit(bkgname.Data(),"R,L,E,+,0");
1293 cout<<"Minuit returned "<<status<<endl;
1296 AddFunctionsToHisto();
1303 //_________________________________________________________________________
1304 Double_t AliHFMassFitter::GetChiSquare() const{
1305 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1307 cout<<"funcmass not found"<<endl;
1310 return funcmass->GetChisquare();
1313 //_________________________________________________________________________
1314 Double_t AliHFMassFitter::GetReducedChiSquare() const{
1315 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1317 cout<<"funcmass not found"<<endl;
1320 return funcmass->GetChisquare()/funcmass->GetNDF();
1325 //_________________________________________________________________________
1326 void AliHFMassFitter::GetFitPars(Float_t *vector) const {
1327 // Return fit parameters
1329 for(Int_t i=0;i<fParsSize;i++){
1330 vector[i]=fFitPars[i];
1335 //_________________________________________________________________________
1336 void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1338 //gives the integral of signal obtained from fit parameters
1339 if(!valuewitherror)valuewitherror=new Float_t[2];
1341 Int_t index=fParsSize/2 - 3;
1342 valuewitherror[0]=fFitPars[index];
1343 index=fParsSize - 3;
1344 valuewitherror[1]=fFitPars[index];
1348 //_________________________________________________________________________
1349 void AliHFMassFitter::AddFunctionsToHisto(){
1351 //Add the background function in the complete range to the list of functions attached to the histogram
1353 cout<<"AddFunctionsToHisto called"<<endl;
1354 TString bkgname = "funcbkg";
1356 Bool_t done1=kFALSE,done2=kFALSE;
1358 TString bkgnamesave=bkgname;
1359 TString testname=bkgname;
1360 testname += "FullRange";
1361 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1366 testname="funcbkgonly";
1367 testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1374 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1378 TList *hlist=fhistoInvMass->GetListOfFunctions();
1382 TF1 *bonly=(TF1*)hlist->FindObject(testname.Data());
1384 cout<<testname.Data()<<" not found looking for complete fit"<<endl;
1386 bonly->SetLineColor(kBlue+3);
1387 hlist->Add((TF1*)bonly->Clone());
1397 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1399 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1403 bkgname += "FullRange";
1404 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars,"AliHFMassFitter","FitFunction4Bkg");
1405 //cout<<bfullrange->GetName()<<endl;
1406 for(Int_t i=0;i<fNFinalPars;i++){
1407 //cout<<i<<" di "<<fNFinalPars<<endl;
1408 bfullrange->SetParName(i,b->GetParName(i));
1409 bfullrange->SetParameter(i,b->GetParameter(i));
1410 bfullrange->SetParError(i,b->GetParError(i));
1412 bfullrange->SetLineStyle(4);
1413 bfullrange->SetLineColor(14);
1415 bkgnamesave += "Recalc";
1417 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars,"AliHFMassFitter","FitFunction4Bkg");
1419 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
1422 cout<<"funcmass doesn't exist "<<endl;
1426 //intBkg=intTot-intS
1427 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(fNFinalPars-3));
1428 blastpar->SetParError(0,mass->GetParError(fNFinalPars-3));
1429 if (fNFinalPars>=2) {
1430 blastpar->SetParameter(1,mass->GetParameter(1));
1431 blastpar->SetParError(1,mass->GetParError(1));
1433 if (fNFinalPars==3) {
1434 blastpar->SetParameter(2,mass->GetParameter(2));
1435 blastpar->SetParError(2,mass->GetParError(2));
1438 blastpar->SetLineStyle(1);
1439 blastpar->SetLineColor(2);
1441 hlist->Add((TF1*)bfullrange->Clone());
1442 hlist->Add((TF1*)blastpar->Clone());
1458 //_________________________________________________________________________
1460 TH1F* AliHFMassFitter::GetHistoClone() const{
1462 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1465 //_________________________________________________________________________
1467 void AliHFMassFitter::WriteHisto(TString path) const {
1469 //Write the histogram in the default file HFMassFitterOutput.root
1471 if (fcounter == 0) {
1472 cout<<"Use MassFitter method before WriteHisto"<<endl;
1475 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1477 path += "HFMassFitterOutput.root";
1480 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1481 else output = new TFile(path.Data(),"update");
1484 fContourGraph->Write();
1489 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
1498 //_________________________________________________________________________
1500 void AliHFMassFitter::WriteNtuple(TString path) const{
1501 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
1502 path += "HFMassFitterOutput.root";
1503 TFile *output = new TFile(path.Data(),"update");
1508 //cout<<nget->GetName()<<" written in "<<path<<endl;
1509 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1522 //_________________________________________________________________________
1523 void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1525 //write the canvas in a root file
1527 gStyle->SetOptStat(0);
1528 gStyle->SetCanvasColor(0);
1529 gStyle->SetFrameFillColor(0);
1533 switch (ftypeOfFit4Bkg){
1548 TString filename=Form("%sMassFit.root",type.Data());
1549 filename.Prepend(userIDstring);
1550 path.Append(filename);
1552 TFile* outputcv=new TFile(path.Data(),"update");
1554 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1555 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1556 if(draw)c->DrawClone();
1562 //_________________________________________________________________________
1564 TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
1565 //return a TVirtualPad with the fitted histograms and info
1567 TString cvtitle="fit of ";
1568 cvtitle+=fhistoInvMass->GetName();
1572 TCanvas *c=new TCanvas(cvname,cvtitle);
1573 PlotFit(c->cd(),nsigma,writeFitInfo);
1576 //_________________________________________________________________________
1578 void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1579 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
1580 gStyle->SetOptStat(0);
1581 gStyle->SetCanvasColor(0);
1582 gStyle->SetFrameFillColor(0);
1584 cout<<"nsigma = "<<nsigma<<endl;
1585 cout<<"Verbosity = "<<writeFitInfo<<endl;
1587 TH1F* hdraw=GetHistoClone();
1589 if(!hdraw->GetFunction("funcmass") && !hdraw->GetFunction("funcbkgFullRange") && !hdraw->GetFunction("funcbkgRecalc")&& !hdraw->GetFunction("funcbkgonly")){
1590 cout<<"Probably fit failed and you didn't try to refit with background only, there's no function to be drawn"<<endl;
1594 if(hdraw->GetFunction("funcbkgonly")){ //Warning! if this function is present, no chance to draw the other!
1595 cout<<"Drawing background fit only"<<endl;
1596 hdraw->SetMinimum(0);
1597 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1599 hdraw->SetMarkerStyle(20);
1600 hdraw->DrawClone("PE");
1601 hdraw->GetFunction("funcbkgonly")->DrawClone("sames");
1603 if(writeFitInfo > 0){
1604 TPaveText *pinfo=new TPaveText(0.6,0.86,1.,1.,"NDC");
1605 pinfo->SetBorderSize(0);
1606 pinfo->SetFillStyle(0);
1607 TF1* f=hdraw->GetFunction("funcbkgonly");
1608 for (Int_t i=0;i<fNFinalPars-3;i++){
1609 pinfo->SetTextColor(kBlue+3);
1610 TString str=Form("%s = %f #pm %f",f->GetParName(i),f->GetParameter(i),f->GetParError(i));
1611 pinfo->AddText(str);
1614 pinfo->AddText(Form("Reduced #chi^{2} = %.3f",f->GetChisquare()/f->GetNDF()));
1624 hdraw->SetMinimum(0);
1625 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1627 hdraw->SetMarkerStyle(20);
1628 hdraw->DrawClone("PE");
1629 if(hdraw->GetFunction("funcbkgFullRange")) hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1630 if(hdraw->GetFunction("funcbkgRecalc")) hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
1631 if(hdraw->GetFunction("funcmass")) hdraw->GetFunction("funcmass")->DrawClone("same");
1633 if(writeFitInfo > 0){
1634 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1635 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1636 pinfob->SetBorderSize(0);
1637 pinfob->SetFillStyle(0);
1638 pinfom->SetBorderSize(0);
1639 pinfom->SetFillStyle(0);
1640 TF1* ff=fhistoInvMass->GetFunction("funcmass");
1642 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1643 pinfom->SetTextColor(kBlue);
1644 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1645 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
1648 pinfom->DrawClone();
1650 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1651 pinfo2->SetBorderSize(0);
1652 pinfo2->SetFillStyle(0);
1654 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1656 Significance(nsigma,signif,errsignif);
1657 Signal(nsigma,signal,errsignal);
1658 Background(nsigma,bkg, errbkg);
1660 Significance(1.828,1.892,signif,errsignif);
1661 Signal(1.828,1.892,signal,errsignal);
1662 Background(1.828,1.892,bkg, errbkg);
1664 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
1665 pinfo2->AddText(str);
1666 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
1667 pinfo2->AddText(str);
1668 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
1669 pinfo2->AddText(str);
1674 if(writeFitInfo > 1){
1675 for (Int_t i=0;i<fNFinalPars-3;i++){
1676 pinfob->SetTextColor(kRed);
1677 str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1678 pinfob->AddText(str);
1681 pinfob->DrawClone();
1689 //_________________________________________________________________________
1691 void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
1692 //draws histogram together with fit functions with default nice colors in user canvas
1693 PlotFit(pd,nsigma,writeFitInfo);
1698 //_________________________________________________________________________
1699 void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1701 //draws histogram together with fit functions with default nice colors
1702 gStyle->SetOptStat(0);
1703 gStyle->SetCanvasColor(0);
1704 gStyle->SetFrameFillColor(0);
1707 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
1713 //_________________________________________________________________________
1715 void AliHFMassFitter::PrintParTitles() const{
1717 //prints to screen the parameters names
1719 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1721 cout<<"Fit function not found"<<endl;
1725 cout<<"Parameter Titles \n";
1726 for(Int_t i=0;i<fNFinalPars;i++){
1727 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1733 //************ significance
1735 //_________________________________________________________________________
1737 void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1738 // Return signal integral in mean+- n sigma
1741 cout<<"Use MassFitter method before Signal"<<endl;
1745 Double_t min=fMass-nOfSigma*fSigmaSgn;
1746 Double_t max=fMass+nOfSigma*fSigmaSgn;
1748 Signal(min,max,signal,errsignal);
1755 //_________________________________________________________________________
1757 void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1759 // Return signal integral in a range
1762 cout<<"Use MassFitter method before Signal"<<endl;
1767 TString bkgname="funcbkgRecalc";
1768 TString bkg1name="funcbkg1Recalc";
1769 TString massname="funcmass";
1773 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1775 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1779 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1780 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1783 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1787 Int_t np=fNFinalPars-3;
1789 Double_t intS,intSerr;
1791 //relative error evaluation
1792 intS=funcmass->GetParameter(np);
1793 intSerr=funcmass->GetParError(np);
1795 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1796 Double_t background,errbackground;
1797 Background(min,max,background,errbackground);
1799 //signal +/- error in the range
1801 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1802 signal=mass - background;
1803 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
1807 //_________________________________________________________________________
1809 void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1810 // Return background integral in mean+- n sigma
1813 cout<<"Use MassFitter method before Background"<<endl;
1816 Double_t min=fMass-nOfSigma*fSigmaSgn;
1817 Double_t max=fMass+nOfSigma*fSigmaSgn;
1819 Background(min,max,background,errbackground);
1824 //___________________________________________________________________________
1826 void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1827 // Return background integral in a range
1830 cout<<"Use MassFitter method before Background"<<endl;
1835 TString bkgname="funcbkgRecalc";
1836 TString bkg1name="funcbkg1Recalc";
1839 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1840 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1842 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1847 Double_t intB,intBerr;
1849 //relative error evaluation: from final parameters of the fit
1850 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1852 intB=funcbkg->GetParameter(0);
1853 intBerr=funcbkg->GetParError(0);
1854 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1857 //relative error evaluation: from histo
1859 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1861 for(Int_t i=1;i<=fSideBandl;i++){
1862 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1864 for(Int_t i=fSideBandr;i<=fNbin;i++){
1865 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1868 intBerr=TMath::Sqrt(sum2);
1869 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1871 cout<<"Last estimation of bkg error is used"<<endl;
1873 //backround +/- error in the range
1874 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1879 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1880 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1881 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1888 //__________________________________________________________________________
1890 void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
1891 // Return significance in mean+- n sigma
1893 Double_t min=fMass-nOfSigma*fSigmaSgn;
1894 Double_t max=fMass+nOfSigma*fSigmaSgn;
1895 Significance(min, max, significance, errsignificance);
1900 //__________________________________________________________________________
1902 void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
1903 // Return significance integral in a range
1905 Double_t signal,errsignal,background,errbackground;
1906 Signal(min, max,signal,errsignal);
1907 Background(min, max,background,errbackground);
1909 if (signal+background <= 0.){
1910 cout<<"Cannot calculate significance because of div by 0!"<<endl;
1915 significance = signal/TMath::Sqrt(signal+background);
1917 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);