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 **************************************************************************/
18 /////////////////////////////////////////////////////////////
20 // AliHFMassFitter for the fit of invariant mass distribution
23 // Author: C.Bianchin, chiara.bianchin@pd.infn.it
24 /////////////////////////////////////////////////////////////
26 #include <Riostream.h>
34 #include <TVirtualPad.h>
36 #include <TVirtualFitter.h>
39 #include <TPaveText.h>
40 #include <TDatabasePDG.h>
42 #include "AliHFMassFitter.h"
43 #include "AliVertexingHFUtils.h"
49 ClassImp(AliHFMassFitter)
51 //************** constructors
52 AliHFMassFitter::AliHFMassFitter() :
77 // default constructor
79 cout<<"Default constructor:"<<endl;
80 cout<<"Remember to set the Histo, the Type, the FixPar"<<endl;
84 //___________________________________________________________________________
86 AliHFMassFitter::AliHFMassFitter (const TH1F *histoToFit, Double_t minvalue, Double_t maxvalue, Int_t rebin,Int_t fittypeb,Int_t fittypes):
111 // standard constructor
113 fhistoInvMass= (TH1F*)histoToFit->Clone("fhistoInvMass");
114 fhistoInvMass->SetDirectory(0);
117 if(rebin!=1) RebinMass(rebin);
118 else fNbin=(Int_t)fhistoInvMass->GetNbinsX();
120 ftypeOfFit4Bkg=fittypeb;
121 ftypeOfFit4Sgn=fittypes;
122 if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2 && ftypeOfFit4Bkg!=4 && ftypeOfFit4Bkg!=5) fWithBkg=kFALSE;
124 if (!fWithBkg) cout<<"Fit Histogram of Signal only"<<endl;
125 else cout<<"Type of fit For Background = "<<ftypeOfFit4Bkg<<endl;
128 fFitPars=new Float_t[fParsSize];
130 SetDefaultFixParam();
132 fContourGraph=new TList();
133 fContourGraph->SetOwner();
138 AliHFMassFitter::AliHFMassFitter(const AliHFMassFitter &mfit):
140 fhistoInvMass(mfit.fhistoInvMass),
141 fminMass(mfit.fminMass),
142 fmaxMass(mfit.fmaxMass),
143 fminBinMass(mfit.fminBinMass),
144 fmaxBinMass(mfit.fmaxBinMass),
146 fParsSize(mfit.fParsSize),
147 fNFinalPars(mfit.fNFinalPars),
149 fWithBkg(mfit.fWithBkg),
150 ftypeOfFit4Bkg(mfit.ftypeOfFit4Bkg),
151 ftypeOfFit4Sgn(mfit.ftypeOfFit4Sgn),
152 ffactor(mfit.ffactor),
153 fntuParam(mfit.fntuParam),
155 fSigmaSgn(mfit.fSigmaSgn),
156 fSideBands(mfit.fSideBands),
158 fSideBandl(mfit.fSideBandl),
159 fSideBandr(mfit.fSideBandr),
160 fcounter(mfit.fcounter),
161 fContourGraph(mfit.fContourGraph)
165 if(mfit.fParsSize > 0){
166 fFitPars=new Float_t[fParsSize];
167 fFixPar=new Bool_t[fNFinalPars];
168 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
169 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Bool_t));
174 //_________________________________________________________________________
176 AliHFMassFitter::~AliHFMassFitter() {
180 cout<<"AliHFMassFitter destructor called"<<endl;
182 delete fhistoInvMass;
193 //_________________________________________________________________________
195 AliHFMassFitter& AliHFMassFitter::operator=(const AliHFMassFitter &mfit){
197 //assignment operator
199 if(&mfit == this) return *this;
200 fhistoInvMass= mfit.fhistoInvMass;
201 fminMass= mfit.fminMass;
202 fmaxMass= mfit.fmaxMass;
204 fParsSize= mfit.fParsSize;
205 fWithBkg= mfit.fWithBkg;
206 ftypeOfFit4Bkg= mfit.ftypeOfFit4Bkg;
207 ftypeOfFit4Sgn= mfit.ftypeOfFit4Sgn;
208 ffactor= mfit.ffactor;
209 fntuParam= mfit.fntuParam;
211 fSigmaSgn= mfit.fSigmaSgn;
212 fSideBands= mfit.fSideBands;
213 fSideBandl= mfit.fSideBandl;
214 fSideBandr= mfit.fSideBandr;
215 fcounter= mfit.fcounter;
216 fContourGraph= mfit.fContourGraph;
218 if(mfit.fParsSize > 0){
221 fFitPars=new Float_t[fParsSize];
222 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
226 fFixPar=new Bool_t[fNFinalPars];
227 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Float_t));
233 //************ tools & settings
235 //__________________________________________________________________________
237 void AliHFMassFitter::ComputeNFinalPars() {
239 //compute the number of parameters of the total (signal+bgk) function
240 cout<<"Info:ComputeNFinalPars... ";
241 switch (ftypeOfFit4Bkg) {//npar background func
261 cout<<"Error in computing fNFinalPars: check ftypeOfFit4Bkg"<<endl;
265 fNFinalPars+=3; //gaussian signal
266 cout<<": "<<fNFinalPars<<endl;
268 //__________________________________________________________________________
270 void AliHFMassFitter::ComputeParSize() {
272 //compute the size of the parameter array and set the data member
274 switch (ftypeOfFit4Bkg) {//npar background func
294 cout<<"Error in computing fParsSize: check ftypeOfFit4Bkg"<<endl;
298 fParsSize += 3; // npar refl
299 fParsSize += 3; // npar signal gaus
301 fParsSize*=2; // add errors
302 cout<<"Parameters array size "<<fParsSize<<endl;
305 //___________________________________________________________________________
306 void AliHFMassFitter::SetDefaultFixParam(){
308 //Set default values for fFixPar (only total integral fixed)
311 fFixPar=new Bool_t[fNFinalPars];
313 fFixPar[0]=kTRUE; //default: IntTot fixed
314 cout<<"Parameter 0 is fixed"<<endl;
315 for(Int_t i=1;i<fNFinalPars;i++){
321 //___________________________________________________________________________
322 Bool_t AliHFMassFitter::SetFixThisParam(Int_t thispar,Bool_t fixpar){
324 //set the value (kFALSE or kTRUE) of one element of fFixPar
325 //return kFALSE if something wrong
327 if(thispar>=fNFinalPars) {
328 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
332 cout<<"Initializing fFixPar...";
333 SetDefaultFixParam();
334 cout<<" done."<<endl;
337 fFixPar[thispar]=fixpar;
338 if(fixpar)cout<<"Parameter "<<thispar<<" is now fixed"<<endl;
339 else cout<<"Parameter "<<thispar<<" is now free"<<endl;
343 //___________________________________________________________________________
344 Bool_t AliHFMassFitter::GetFixThisParam(Int_t thispar)const{
345 //return the value of fFixPar[thispar]
346 if(thispar>=fNFinalPars) {
347 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
351 cout<<"Error! Parameters to be fixed still not set"<<endl;
355 return fFixPar[thispar];
359 //___________________________________________________________________________
360 void AliHFMassFitter::SetHisto(const TH1F *histoToFit){
362 fhistoInvMass = new TH1F(*histoToFit);
363 fhistoInvMass->SetDirectory(0);
364 //cout<<"SetHisto pointer "<<fhistoInvMass<<endl;
367 //___________________________________________________________________________
369 void AliHFMassFitter::SetType(Int_t fittypeb, Int_t fittypes) {
371 //set the type of fit to perform for signal and background
373 ftypeOfFit4Bkg = fittypeb;
374 ftypeOfFit4Sgn = fittypes;
377 fFitPars = new Float_t[fParsSize];
379 SetDefaultFixParam();
382 //___________________________________________________________________________
384 void AliHFMassFitter::Reset() {
386 //delete the histogram and reset the mean and sigma to default
388 cout<<"Reset called: delete histogram, set mean value to 1.85 and sigma to 0.012"<<endl;
391 cout<<"Reset "<<fhistoInvMass<<endl;
392 delete fhistoInvMass;
395 //_________________________________________________________________________
397 void AliHFMassFitter::InitNtuParam(TString ntuname) {
399 // Create ntuple to keep fit parameters
402 fntuParam=new TNtuple(ntuname.Data(),"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");
406 //_________________________________________________________________________
408 void AliHFMassFitter::FillNtuParam() {
409 // Fill ntuple with fit parameters
413 if (ftypeOfFit4Bkg==2) {
414 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
415 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
416 fntuParam->SetBranchAddress("conc1",&fFitPars[2]);
417 fntuParam->SetBranchAddress("intGB",&fFitPars[3]);
418 fntuParam->SetBranchAddress("meanGB",&fFitPars[4]);
419 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]);
420 fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]);
421 fntuParam->SetBranchAddress("slope2",&fFitPars[7]);
422 fntuParam->SetBranchAddress("conc2",&fFitPars[8]);
423 fntuParam->SetBranchAddress("inttot",&fFitPars[9]);
424 fntuParam->SetBranchAddress("slope3",&fFitPars[10]);
425 fntuParam->SetBranchAddress("conc3",&fFitPars[11]);
426 fntuParam->SetBranchAddress("intsgn",&fFitPars[12]);
427 fntuParam->SetBranchAddress("meansgn",&fFitPars[13]);
428 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]);
430 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]);
431 fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]);
432 fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]);
433 fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]);
434 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]);
435 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]);
436 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]);
437 fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]);
438 fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]);
439 fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]);
440 fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]);
441 fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]);
442 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]);
443 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]);
444 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]);
448 if(ftypeOfFit4Bkg==3){
449 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
450 fntuParam->SetBranchAddress("slope1",¬hing);
451 fntuParam->SetBranchAddress("conc1",¬hing);
452 fntuParam->SetBranchAddress("intGB",&fFitPars[1]);
453 fntuParam->SetBranchAddress("meanGB",&fFitPars[2]);
454 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]);
455 fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]);
456 fntuParam->SetBranchAddress("slope2",¬hing);
457 fntuParam->SetBranchAddress("conc2",¬hing);
458 fntuParam->SetBranchAddress("inttot",&fFitPars[6]);
459 fntuParam->SetBranchAddress("slope3",¬hing);
460 fntuParam->SetBranchAddress("conc3",¬hing);
461 fntuParam->SetBranchAddress("intsgn",&fFitPars[6]);
462 fntuParam->SetBranchAddress("meansgn",&fFitPars[7]);
463 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]);
465 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]);
466 fntuParam->SetBranchAddress("slope1Err",¬hing);
467 fntuParam->SetBranchAddress("conc1Err",¬hing);
468 fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]);
469 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]);
470 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]);
471 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]);
472 fntuParam->SetBranchAddress("slope2Err",¬hing);
473 fntuParam->SetBranchAddress("conc2Err",¬hing);
474 fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]);
475 fntuParam->SetBranchAddress("slope3Err",¬hing);
476 fntuParam->SetBranchAddress("conc3Err",¬hing);
477 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]);
478 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]);
479 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]);
483 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
484 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
485 fntuParam->SetBranchAddress("conc1",¬hing);
486 fntuParam->SetBranchAddress("intGB",&fFitPars[2]);
487 fntuParam->SetBranchAddress("meanGB",&fFitPars[3]);
488 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]);
489 fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]);
490 fntuParam->SetBranchAddress("slope2",&fFitPars[6]);
491 fntuParam->SetBranchAddress("conc2",¬hing);
492 fntuParam->SetBranchAddress("inttot",&fFitPars[7]);
493 fntuParam->SetBranchAddress("slope3",&fFitPars[8]);
494 fntuParam->SetBranchAddress("conc3",¬hing);
495 fntuParam->SetBranchAddress("intsgn",&fFitPars[9]);
496 fntuParam->SetBranchAddress("meansgn",&fFitPars[10]);
497 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]);
499 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]);
500 fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]);
501 fntuParam->SetBranchAddress("conc1Err",¬hing);
502 fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]);
503 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]);
504 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]);
505 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]);
506 fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]);
507 fntuParam->SetBranchAddress("conc2Err",¬hing);
508 fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]);
509 fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]);
510 fntuParam->SetBranchAddress("conc3Err",¬hing);
511 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]);
512 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]);
513 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]);
517 fntuParam->TTree::Fill();
520 //_________________________________________________________________________
522 TNtuple* AliHFMassFitter::NtuParamOneShot(TString ntuname){
523 // Create, fill and return ntuple with fit parameters
525 InitNtuParam(ntuname.Data());
529 //_________________________________________________________________________
531 void AliHFMassFitter::RebinMass(Int_t bingroup){
532 // Rebin invariant mass histogram
535 cout<<"Histogram not set"<<endl;
538 Int_t nbinshisto=fhistoInvMass->GetNbinsX();
540 cout<<"Error! Cannot group "<<bingroup<<" bins\n";
542 cout<<"Kept original number of bins: "<<fNbin<<endl;
545 while(nbinshisto%bingroup != 0) {
548 cout<<"Group "<<bingroup<<" bins"<<endl;
549 fhistoInvMass->Rebin(bingroup);
550 fNbin = fhistoInvMass->GetNbinsX();
551 cout<<"New number of bins: "<<fNbin<<endl;
558 //___________________________________________________________________________
560 Double_t AliHFMassFitter::FitFunction4MassDistr (Double_t *x, Double_t *par){
561 // Fit function for signal+background
564 //exponential or linear fit
566 // par[0] = tot integral
568 // par[2] = gaussian integral
569 // par[3] = gaussian mean
570 // par[4] = gaussian sigma
572 Double_t total,bkg=0,sgn=0;
574 if (ftypeOfFit4Bkg==0 || ftypeOfFit4Bkg==1) {
575 if(ftypeOfFit4Sgn == 0) {
577 Double_t parbkg[2] = {par[0]-par[2], par[1]};
578 bkg = FitFunction4Bkg(x,parbkg);
580 if(ftypeOfFit4Sgn == 1) {
581 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-2*par[2], par[1]};
582 bkg = FitFunction4Bkg(x,parbkg);
585 sgn = FitFunction4Sgn(x,&par[2]);
591 // par[0] = tot integral
594 // par[3] = gaussian integral
595 // par[4] = gaussian mean
596 // par[5] = gaussian sigma
598 if (ftypeOfFit4Bkg==2) {
600 if(ftypeOfFit4Sgn == 0) {
602 Double_t parbkg[3] = {par[0]-par[3], par[1], par[2]};
603 bkg = FitFunction4Bkg(x,parbkg);
605 if(ftypeOfFit4Sgn == 1) {
607 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-2*par[3], par[1], par[2]};
608 bkg = FitFunction4Bkg(x,parbkg);
611 sgn = FitFunction4Sgn(x,&par[3]);
614 if (ftypeOfFit4Bkg==3) {
616 if(ftypeOfFit4Sgn == 0) {
617 bkg=FitFunction4Bkg(x,par);
618 sgn=FitFunction4Sgn(x,&par[1]);
620 if(ftypeOfFit4Sgn == 1) {
621 Double_t parbkg[4]={par[1],par[2],ffactor*par[3],par[0]};
622 bkg=FitFunction4Bkg(x,parbkg);
623 sgn=FitFunction4Sgn(x,&par[1]);
629 // par[0] = tot integral
631 // par[2] = gaussian integral
632 // par[3] = gaussian mean
633 // par[4] = gaussian sigma
635 if (ftypeOfFit4Bkg==4) {
637 if(ftypeOfFit4Sgn == 0) {
639 Double_t parbkg[2] = {par[0]-par[2], par[1]};
640 bkg = FitFunction4Bkg(x,parbkg);
642 if(ftypeOfFit4Sgn == 1) {
644 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-par[2], par[1]};
645 bkg = FitFunction4Bkg(x,parbkg);
647 sgn = FitFunction4Sgn(x,&par[2]);
651 //Power and exponential fit
653 // par[0] = tot integral
656 // par[3] = gaussian integral
657 // par[4] = gaussian mean
658 // par[5] = gaussian sigma
660 if (ftypeOfFit4Bkg==5) {
662 if(ftypeOfFit4Sgn == 0) {
663 Double_t parbkg[3] = {par[0]-par[3],par[1],par[2]};
664 bkg = FitFunction4Bkg(x,parbkg);
666 if(ftypeOfFit4Sgn == 1) {
667 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-par[3], par[1], par[2]};
668 bkg = FitFunction4Bkg(x,parbkg);
670 sgn = FitFunction4Sgn(x,&par[3]);
678 //_________________________________________________________________________
679 Double_t AliHFMassFitter::FitFunction4Sgn (Double_t *x, Double_t *par){
680 // Fit function for the signal
682 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
684 // * [0] = integralSgn
687 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
689 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]);
693 //__________________________________________________________________________
695 Double_t AliHFMassFitter::FitFunction4Bkg (Double_t *x, Double_t *par){
696 // Fit function for the background
698 Double_t maxDeltaM = 4.*fSigmaSgn;
699 if(fSideBands && TMath::Abs(x[0]-fMass) < maxDeltaM) {
704 Double_t gaus2=0,total=-1;
705 if(ftypeOfFit4Sgn == 1){
707 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
709 // * [0] = integralSgn
712 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
713 gaus2 = FitFunction4Sgn(x,par);
716 switch (ftypeOfFit4Bkg){
719 //exponential = A*exp(B*x) -> integral(exponential)=A/B*exp(B*x)](min,max)
720 //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written
721 //as integralTot- integralGaus (=par [2])
723 // * [0] = integralBkg;
725 //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x)
726 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]);
730 //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)
731 // * [0] = integralBkg;
733 total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass));
737 //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) +
738 //+ 1/3*c*(max^3-min^3) ->
739 //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min)
740 // * [0] = integralBkg;
743 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));
746 total=par[0+firstPar];
750 //y=a(x-m_pi)^b -> integral = a/(b+1)*((max-m_pi)^(b+1)-(min-m_pi)^(b+1))
752 //a = integral*(b+1)/((max-m_pi)^(b+1)-(min-m_pi)^(b+1))
753 // * [0] = integralBkg;
755 // a(power function) = [0]*([1]+1)/((max-m_pi)^([1]+1)-(min-m_pi)^([1]+1))*(x-m_pi)^[1]
757 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
759 total = par[0+firstPar]*(par[1+firstPar]+1.)/(TMath::Power(fmaxMass-mpi,par[1+firstPar]+1.)-TMath::Power(fminMass-mpi,par[1+firstPar]+1.))*TMath::Power(x[0]-mpi,par[1+firstPar]);
763 //power function wit exponential
764 //y=a*Sqrt(x-m_pi)*exp(-b*(x-m_pi))
766 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
768 total = par[1+firstPar]*TMath::Sqrt(x[0] - mpi)*TMath::Exp(-1.*par[2+firstPar]*(x[0]-mpi));
772 // Types of Fit Functions for Background:
773 // * 0 = exponential;
775 // * 2 = polynomial 2nd order
776 // * 3 = no background"<<endl;
777 // * 4 = Power function
778 // * 5 = Power function with exponential
784 //__________________________________________________________________________
785 Bool_t AliHFMassFitter::SideBandsBounds(){
787 //determines the ranges of the side bands
789 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
790 Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
791 Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin+1);
793 Double_t sidebandldouble,sidebandrdouble;
794 Bool_t leftok=kFALSE, rightok=kFALSE;
796 if(fMass-fminMass < 0 || fmaxMass-fMass <0) {
797 cout<<"Left limit of range > mean or right limit of range < mean: change left/right limit or initial mean value"<<endl;
801 //histo limit = fit function limit
802 if((TMath::Abs(fminMass-minHisto) < 1e6 || TMath::Abs(fmaxMass - maxHisto) < 1e6) && (fMass-4.*fSigmaSgn-fminMass) < 1e6){
803 Double_t coeff = (fMass-fminMass)/fSigmaSgn;
804 sidebandldouble=(fMass-0.5*coeff*fSigmaSgn);
805 sidebandrdouble=(fMass+0.5*coeff*fSigmaSgn);
806 cout<<"Changed number of sigma from 4 to "<<0.5*coeff<<" for the estimation of the side bands"<<endl;
807 if (coeff<3) cout<<"Side bands inside 3 sigma, may be better use ftypeOfFit4Bkg = 3 (only signal)"<<endl;
809 cout<<"Side bands inside 2 sigma. Change mode: ftypeOfFit4Bkg = 3"<<endl;
811 //set binleft and right without considering SetRangeFit- anyway no bkg!
812 sidebandldouble=(fMass-4.*fSigmaSgn);
813 sidebandrdouble=(fMass+4.*fSigmaSgn);
817 sidebandldouble=(fMass-4.*fSigmaSgn);
818 sidebandrdouble=(fMass+4.*fSigmaSgn);
821 cout<<"Left side band ";
824 //calculate bin corresponding to fSideBandl
825 fSideBandl=fhistoInvMass->FindBin(sidebandldouble);
826 if (sidebandldouble >= fhistoInvMass->GetBinCenter(fSideBandl)) fSideBandl++;
827 sidebandldouble=fhistoInvMass->GetBinLowEdge(fSideBandl);
829 if(TMath::Abs(tmp-sidebandldouble) > 1e-6){
830 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
833 cout<<sidebandldouble<<" (bin "<<fSideBandl<<")"<<endl;
835 cout<<"Right side band ";
837 //calculate bin corresponding to fSideBandr
838 fSideBandr=fhistoInvMass->FindBin(sidebandrdouble);
839 if (sidebandrdouble < fhistoInvMass->GetBinCenter(fSideBandr)) fSideBandr--;
840 sidebandrdouble=fhistoInvMass->GetBinLowEdge(fSideBandr+1);
842 if(TMath::Abs(tmp-sidebandrdouble) > 1e-6){
843 cout<<tmp<<" is not allowed, changing it to the nearest value allowed: ";
846 cout<<sidebandrdouble<<" (bin "<<fSideBandr<<")"<<endl;
847 if (fSideBandl==0 || fSideBandr==fNbin) {
848 cout<<"Error! Range too little";
854 //__________________________________________________________________________
856 void AliHFMassFitter::GetSideBandsBounds(Int_t &left, Int_t &right) const{
858 // get the range of the side bands
860 if (fSideBandl==0 && fSideBandr==0){
861 cout<<"Use MassFitter method first"<<endl;
868 //__________________________________________________________________________
869 Bool_t AliHFMassFitter::CheckRangeFit(){
870 //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
872 if (!fhistoInvMass) {
873 cout<<"No histogram to fit! SetHisto(TH1F* h) before! "<<endl;
876 Bool_t leftok=kFALSE, rightok=kFALSE;
877 Int_t nbins=fhistoInvMass->GetNbinsX();
878 Double_t minhisto=fhistoInvMass->GetBinLowEdge(1), maxhisto=fhistoInvMass->GetBinLowEdge(nbins+1);
880 //check if limits are inside histogram range
882 if( fminMass-minhisto < 0. ) {
883 cout<<"Out of histogram left bound! Setting to "<<minhisto<<endl;
886 if( fmaxMass-maxhisto > 0. ) {
887 cout<<"Out of histogram right bound! Setting to"<<maxhisto<<endl;
893 //calculate bin corresponding to fminMass
894 fminBinMass=fhistoInvMass->FindBin(fminMass);
895 if (fminMass >= fhistoInvMass->GetBinCenter(fminBinMass)) fminBinMass++;
896 fminMass=fhistoInvMass->GetBinLowEdge(fminBinMass);
897 if(TMath::Abs(tmp-fminMass) > 1e-6){
898 cout<<"Left bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fminMass<<endl;
903 //calculate bin corresponding to fmaxMass
904 fmaxBinMass=fhistoInvMass->FindBin(fmaxMass);
905 if (fmaxMass < fhistoInvMass->GetBinCenter(fmaxBinMass)) fmaxBinMass--;
906 fmaxMass=fhistoInvMass->GetBinLowEdge(fmaxBinMass+1);
907 if(TMath::Abs(tmp-fmaxMass) > 1e-6){
908 cout<<"Right bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fmaxMass<<endl;
912 return (leftok && rightok);
916 //__________________________________________________________________________
918 Bool_t AliHFMassFitter::MassFitter(Bool_t draw){
919 // Main method of the class: performs the fit of the histogram
921 //Set default fitter Minuit in order to use gMinuit in the contour plots
922 TVirtualFitter::SetDefaultFitter("Minuit");
925 Bool_t isBkgOnly=kFALSE;
927 Int_t fit1status=RefitWithBkgOnly(kFALSE);
929 Int_t checkinnsigma=4;
930 Double_t range[2]={fMass-checkinnsigma*fSigmaSgn,fMass+checkinnsigma*fSigmaSgn};
931 TF1* func=GetHistoClone()->GetFunction("funcbkgonly");
932 Double_t intUnderFunc=func->Integral(range[0],range[1]);
933 Double_t intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(range[0]),fhistoInvMass->FindBin(range[1]),"width");
934 cout<<"Pick zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
935 Double_t diffUnderPick=(intUnderHisto-intUnderFunc);
936 intUnderFunc=func->Integral(fminMass,fminMass+checkinnsigma*fSigmaSgn);
937 intUnderHisto=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fminMass+checkinnsigma*fSigmaSgn),"width");
938 cout<<"Band (l) zone: IntFunc = "<<intUnderFunc<<"; IntHist = "<<intUnderHisto<<"\tDiff = "<<intUnderHisto-intUnderFunc<<"\tRelDiff = "<<(intUnderHisto-intUnderFunc)/intUnderFunc<<endl;
939 Double_t diffUnderBands=(intUnderHisto-intUnderFunc);
940 Double_t relDiff=diffUnderPick/diffUnderBands;
941 cout<<"Relative difference = "<<relDiff<<endl;
942 if(TMath::Abs(relDiff) < 1) isBkgOnly=kTRUE;
944 cout<<"Relative difference = "<<relDiff<<": I suppose there is some signal, continue with total fit!"<<endl;
948 cout<<"INFO!! The histogram contains only background"<<endl;
951 //increase counter of number of fits done
957 Int_t bkgPar = fNFinalPars-3; //background function's number of parameters
959 cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
962 TString listname="contourplot";
965 fContourGraph=new TList();
966 fContourGraph->SetOwner();
969 fContourGraph->SetName(listname);
973 TString bkgname="funcbkg";
974 TString bkg1name="funcbkg1";
975 TString massname="funcmass";
978 Double_t totInt = fhistoInvMass->Integral(fminBinMass,fmaxBinMass, "width");
979 //cout<<"Here tot integral is = "<<totInt<<"; integral in whole range is "<<fhistoInvMass->Integral("width")<<endl;
981 Double_t width=fhistoInvMass->GetBinWidth(8);
982 //cout<<"fNbin = "<<fNbin<<endl;
983 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
985 Bool_t ok=SideBandsBounds();
986 if(!ok) return kFALSE;
988 //sidebands integral - first approx (from histo)
989 Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,fSideBandl,"width") + (Double_t)fhistoInvMass->Integral(fSideBandr,fNbin,"width");
990 cout<<"------nbin = "<<fNbin<<"\twidth = "<<width<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
991 cout<<"------sideBandsInt - first approx = "<<sideBandsInt<<endl;
992 if (sideBandsInt<=0) {
993 cout<<"! sideBandsInt <=0. There's a problem, cannot start the fit"<<endl;
1000 TF1 *funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
1001 cout<<"Function name = "<<funcbkg->GetName()<<endl<<endl;
1003 funcbkg->SetLineColor(2); //red
1005 //first fit for bkg: approx bkgint
1007 switch (ftypeOfFit4Bkg) {
1009 funcbkg->SetParNames("BkgInt","Slope");
1010 funcbkg->SetParameters(sideBandsInt,-2.);
1013 funcbkg->SetParNames("BkgInt","Slope");
1014 funcbkg->SetParameters(sideBandsInt,-100.);
1017 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1018 funcbkg->SetParameters(sideBandsInt,-10.,5);
1021 if(ftypeOfFit4Sgn==0){
1022 funcbkg->SetParNames("Const");
1023 funcbkg->SetParameter(0,0.);
1024 funcbkg->FixParameter(0,0.);
1028 funcbkg->SetParNames("BkgInt","Coef2");
1029 funcbkg->SetParameters(sideBandsInt,0.5);
1032 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1033 funcbkg->SetParameters(sideBandsInt, -10., 5.);
1036 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1040 cout<<"\nBACKGROUND FIT - only combinatorial"<<endl;
1041 Int_t ftypeOfFit4SgnBkp=ftypeOfFit4Sgn;
1043 Double_t intbkg1=0,slope1=0,conc1=0;
1044 //if only signal and reflection: skip
1045 if (!(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn==1)) {
1047 fhistoInvMass->Fit(bkgname.Data(),"R,L,E,0");
1049 for(Int_t i=0;i<bkgPar;i++){
1050 fFitPars[i]=funcbkg->GetParameter(i);
1051 //cout<<i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
1052 fFitPars[fNFinalPars+2*bkgPar+3+i]= funcbkg->GetParError(i);
1053 //cout<<fNFinalPars+2*bkgPar+3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
1055 fSideBands = kFALSE;
1056 //intbkg1 = funcbkg->GetParameter(0);
1058 intbkg1 = funcbkg->Integral(fminMass,fmaxMass);
1059 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1);
1060 if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2);
1061 if(ftypeOfFit4Bkg==5) conc1 = funcbkg->GetParameter(2);
1064 //cout<<"First fit: \nintbkg1 = "<<intbkg1<<"\t(Compare with par0 = "<<funcbkg->GetParameter(0)<<")\nslope1= "<<slope1<<"\nconc1 = "<<conc1<<endl;
1066 else cout<<"\t\t//"<<endl;
1068 ftypeOfFit4Sgn=ftypeOfFit4SgnBkp;
1070 if (ftypeOfFit4Sgn == 1) {
1071 cout<<"\nBACKGROUND FIT WITH REFLECTION"<<endl;
1074 //cout<<"fNFinalPars = "<<fNFinalPars<<"\tbkgPar = "<<bkgPar<<endl;
1076 funcbkg1 = new TF1(bkg1name.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
1077 cout<<"Function name = "<<funcbkg1->GetName()<<endl;
1079 funcbkg1->SetLineColor(2); //red
1081 switch (ftypeOfFit4Bkg) {
1084 cout<<"*** Exponential Fit ***"<<endl;
1085 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
1086 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
1091 cout<<"*** Linear Fit ***"<<endl;
1092 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
1093 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
1098 cout<<"*** Polynomial Fit ***"<<endl;
1099 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
1100 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
1104 //no background: gaus sign+ gaus broadened
1106 cout<<"*** No background Fit ***"<<endl;
1107 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","Const");
1108 funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.);
1109 funcbkg1->FixParameter(3,0.);
1114 cout<<"*** Power function Fit ***"<<endl;
1115 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef2");
1116 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
1121 cout<<"*** Power function conv. with exponential Fit ***"<<endl;
1122 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
1123 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
1127 //cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<<fMass<<"\t"<<ffactor*fSigmaSgn<<"\t"<<intbkg1<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<endl;
1128 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<bkgPar<<"\tgsidebands = "<<fSideBands<<endl;
1130 Int_t status=fhistoInvMass->Fit(bkg1name.Data(),"R,L,E,+,0");
1132 cout<<"Minuit returned "<<status<<endl;
1136 for(Int_t i=0;i<bkgPar;i++){
1137 fFitPars[bkgPar-3+i]=funcbkg1->GetParameter(i);
1138 //cout<<bkgPar-3+i<<"\t"<<funcbkg1->GetParameter(i);
1139 fFitPars[fNFinalPars+3*bkgPar-6+i]= funcbkg1->GetParError(i);
1140 //cout<<"\t"<<fNFinalPars+3*bkgPar-6+i<<"\t"<<funcbkg1->GetParError(i)<<endl;
1143 intbkg1=funcbkg1->GetParameter(3);
1144 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4);
1145 if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5);
1146 if(ftypeOfFit4Bkg==5) conc1 = funcbkg1->GetParameter(5);
1152 for(Int_t i=0;i<3;i++){
1153 fFitPars[bkgPar-3+i]=0.;
1154 cout<<bkgPar-3+i<<"\t"<<0.<<"\t";
1155 fFitPars[fNFinalPars+3*bkgPar-6+i]= 0.;
1156 cout<<fNFinalPars+3*bkgPar-6+i<<"\t"<<0.<<endl;
1159 for(Int_t i=0;i<bkgPar-3;i++){
1160 fFitPars[bkgPar+i]=funcbkg->GetParameter(i);
1161 cout<<bkgPar+i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
1162 fFitPars[fNFinalPars+3*bkgPar-3+i]= funcbkg->GetParError(i);
1163 cout<<fNFinalPars+3*bkgPar-3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
1169 //sidebands integral - second approx (from fit)
1170 fSideBands = kFALSE;
1172 //cout<<"Compare intbkg1 = "<<intbkg1<<" and integral = ";
1173 if(ftypeOfFit4Sgn == 1) bkgInt=funcbkg1->Integral(fminMass,fmaxMass);
1174 else bkgInt=funcbkg->Integral(fminMass,fmaxMass);
1175 //cout<</*"------BkgInt(Fit) = "<<*/bkgInt<<endl;
1177 //Signal integral - first approx
1179 sgnInt = totInt-bkgInt;
1180 //cout<<"------TotInt = "<<totInt<<"\tsgnInt = "<<sgnInt<<endl;
1182 cout<<"Setting sgnInt = - sgnInt"<<endl;
1185 /*Fit All Mass distribution with exponential + gaussian (+gaussian braodened) */
1186 TF1 *funcmass = new TF1(massname.Data(),this,&AliHFMassFitter::FitFunction4MassDistr,fminMass,fmaxMass,fNFinalPars,"AliHFMassFitter","FitFunction4MassDistr");
1187 cout<<"Function name = "<<funcmass->GetName()<<endl<<endl;
1188 funcmass->SetLineColor(4); //blue
1191 cout<<"\nTOTAL FIT"<<endl;
1194 funcmass->SetParNames("TotInt","Slope","SgnInt","Mean","Sigma");
1195 funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn);
1197 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1198 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1200 funcmass->FixParameter(0,totInt);
1203 funcmass->FixParameter(1,slope1);
1206 funcmass->FixParameter(2,sgnInt);
1209 funcmass->FixParameter(3,fMass);
1212 funcmass->FixParameter(4,fSigmaSgn);
1215 if (fNFinalPars==6){
1216 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1217 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
1219 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1220 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1221 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1222 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1223 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1224 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1225 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1226 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1228 //funcmass->FixParameter(2,sgnInt);
1231 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
1232 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1233 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
1234 if(fFixPar[0]) funcmass->FixParameter(0,0.);
1235 if(fFixPar[1])funcmass->FixParameter(1,sgnInt);
1236 if(fFixPar[2])funcmass->FixParameter(2,fMass);
1237 if(fFixPar[3])funcmass->FixParameter(3,fSigmaSgn);
1238 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1239 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<fNFinalPars<<"\tgsidebands = "<<fSideBands<<endl;
1245 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1247 cout<<"Minuit returned "<<status<<endl;
1251 cout<<"fit done"<<endl;
1252 //reset value of fMass and fSigmaSgn to those found from fit
1253 fMass=funcmass->GetParameter(fNFinalPars-2);
1254 fSigmaSgn=funcmass->GetParameter(fNFinalPars-1);
1256 for(Int_t i=0;i<fNFinalPars;i++){
1257 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
1258 fFitPars[fNFinalPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1259 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<fNFinalPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
1262 //check: cout parameters
1263 for(Int_t i=0;i<2*(fNFinalPars+2*bkgPar-3);i++){
1264 cout<<i<<"\t"<<fFitPars[i]<<endl;
1268 if(funcmass->GetParameter(fNFinalPars-1) <0 || funcmass->GetParameter(fNFinalPars-2) <0 || funcmass->GetParameter(fNFinalPars-3) <0 ) {
1269 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
1273 //increase counter of number of fits done
1279 for (Int_t kpar=1; kpar<fNFinalPars;kpar++){
1281 for(Int_t jpar=kpar+1;jpar<fNFinalPars;jpar++){
1282 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1284 // produce 2 contours per couple of parameters
1285 TGraph* cont[2] = {0x0, 0x0};
1286 const Double_t errDef[2] = {1., 4.};
1287 for (Int_t i=0; i<2; i++) {
1288 gMinuit->SetErrorDef(errDef[i]);
1289 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
1290 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
1293 if(!cont[0] || !cont[1]){
1294 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1298 // set graph titles and add them to the list
1299 TString title = "Contour plot";
1300 TString titleX = funcmass->GetParName(kpar);
1301 TString titleY = funcmass->GetParName(jpar);
1302 for (Int_t i=0; i<2; i++) {
1303 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1304 cont[i]->SetTitle(title);
1305 cont[i]->GetXaxis()->SetTitle(titleX);
1306 cont[i]->GetYaxis()->SetTitle(titleY);
1307 cont[i]->GetYaxis()->SetLabelSize(0.033);
1308 cont[i]->GetYaxis()->SetTitleSize(0.033);
1309 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1311 fContourGraph->Add(cont[i]);
1315 TString cvname = Form("c%d%d", kpar, jpar);
1316 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1318 cont[1]->SetFillColor(38);
1319 cont[1]->Draw("alf");
1320 cont[0]->SetFillColor(9);
1321 cont[0]->Draw("lf");
1329 if (ftypeOfFit4Sgn == 1) {
1335 AddFunctionsToHisto();
1336 if (draw) DrawFit();
1342 //______________________________________________________________________________
1344 Bool_t AliHFMassFitter::RefitWithBkgOnly(Bool_t draw){
1346 //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
1347 //If you want to change the backgroud function or range use SetType or SetRangeFit before
1349 TString bkgname="funcbkgonly";
1350 fSideBands = kFALSE;
1352 TF1* funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1354 funcbkg->SetLineColor(kBlue+3); //dark blue
1356 Double_t integral=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fmaxMass),"width");
1358 switch (ftypeOfFit4Bkg) {
1360 funcbkg->SetParNames("BkgInt","Slope");
1361 funcbkg->SetParameters(integral,-2.);
1364 funcbkg->SetParNames("BkgInt","Slope");
1365 funcbkg->SetParameters(integral,-100.);
1368 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1369 funcbkg->SetParameters(integral,-10.,5);
1372 cout<<"Warning! This choice does not make a lot of sense..."<<endl;
1373 if(ftypeOfFit4Sgn==0){
1374 funcbkg->SetParNames("Const");
1375 funcbkg->SetParameter(0,0.);
1376 funcbkg->FixParameter(0,0.);
1380 funcbkg->SetParNames("BkgInt","Coef1");
1381 funcbkg->SetParameters(integral,0.5);
1384 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1385 funcbkg->SetParameters(integral,-10.,5.);
1388 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1394 Int_t status=fhistoInvMass->Fit(bkgname.Data(),"R,L,E,+,0");
1396 cout<<"Minuit returned "<<status<<endl;
1399 AddFunctionsToHisto();
1406 //_________________________________________________________________________
1407 Double_t AliHFMassFitter::GetChiSquare() const{
1409 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1411 cout<<"funcmass not found"<<endl;
1414 return funcmass->GetChisquare();
1417 //_________________________________________________________________________
1418 Double_t AliHFMassFitter::GetReducedChiSquare() const{
1419 //Get reduced Chi^2 method
1420 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1422 cout<<"funcmass not found"<<endl;
1425 return funcmass->GetChisquare()/funcmass->GetNDF();
1430 //_________________________________________________________________________
1431 void AliHFMassFitter::GetFitPars(Float_t *vector) const {
1432 // Return fit parameters
1434 for(Int_t i=0;i<fParsSize;i++){
1435 vector[i]=fFitPars[i];
1440 //_________________________________________________________________________
1441 void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1443 //gives the integral of signal obtained from fit parameters
1444 if(!valuewitherror) {
1445 printf("AliHFMassFitter::IntS: got a null pointer\n");
1449 Int_t index=fParsSize/2 - 3;
1450 valuewitherror[0]=fFitPars[index];
1451 index=fParsSize - 3;
1452 valuewitherror[1]=fFitPars[index];
1456 //_________________________________________________________________________
1457 void AliHFMassFitter::AddFunctionsToHisto(){
1459 //Add the background function in the complete range to the list of functions attached to the histogram
1461 //cout<<"AddFunctionsToHisto called"<<endl;
1462 TString bkgname = "funcbkg";
1464 Bool_t done1=kFALSE,done2=kFALSE;
1466 TString bkgnamesave=bkgname;
1467 TString testname=bkgname;
1468 testname += "FullRange";
1469 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1474 testname="funcbkgonly";
1475 testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1482 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1486 TList *hlist=fhistoInvMass->GetListOfFunctions();
1490 TF1 *bonly=(TF1*)hlist->FindObject(testname.Data());
1492 cout<<testname.Data()<<" not found looking for complete fit"<<endl;
1494 bonly->SetLineColor(kBlue+3);
1495 hlist->Add((TF1*)bonly->Clone());
1502 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1504 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1508 bkgname += "FullRange";
1509 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1510 //cout<<bfullrange->GetName()<<endl;
1511 for(Int_t i=0;i<fNFinalPars-3;i++){
1512 bfullrange->SetParName(i,b->GetParName(i));
1513 bfullrange->SetParameter(i,b->GetParameter(i));
1514 bfullrange->SetParError(i,b->GetParError(i));
1516 bfullrange->SetLineStyle(4);
1517 bfullrange->SetLineColor(14);
1519 bkgnamesave += "Recalc";
1521 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1523 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
1526 cout<<"funcmass doesn't exist "<<endl;
1530 //intBkg=intTot-intS
1531 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(fNFinalPars-3));
1532 blastpar->SetParError(0,mass->GetParError(fNFinalPars-3));
1533 if (fNFinalPars>=5) {
1534 blastpar->SetParameter(1,mass->GetParameter(1));
1535 blastpar->SetParError(1,mass->GetParError(1));
1537 if (fNFinalPars==6) {
1538 blastpar->SetParameter(2,mass->GetParameter(2));
1539 blastpar->SetParError(2,mass->GetParError(2));
1542 blastpar->SetLineStyle(1);
1543 blastpar->SetLineColor(2);
1545 hlist->Add((TF1*)bfullrange->Clone());
1546 hlist->Add((TF1*)blastpar->Clone());
1557 //_________________________________________________________________________
1559 TH1F* AliHFMassFitter::GetHistoClone() const{
1561 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1564 //_________________________________________________________________________
1566 void AliHFMassFitter::WriteHisto(TString path) const {
1568 //Write the histogram in the default file HFMassFitterOutput.root
1570 if (fcounter == 0) {
1571 cout<<"Use MassFitter method before WriteHisto"<<endl;
1574 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1576 path += "HFMassFitterOutput.root";
1579 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1580 else output = new TFile(path.Data(),"update");
1583 fContourGraph->Write();
1588 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
1594 //_________________________________________________________________________
1596 void AliHFMassFitter::WriteNtuple(TString path) const{
1597 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
1598 path += "HFMassFitterOutput.root";
1599 TFile *output = new TFile(path.Data(),"update");
1604 //cout<<nget->GetName()<<" written in "<<path<<endl;
1605 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1616 //_________________________________________________________________________
1617 void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1619 //write the canvas in a root file
1621 gStyle->SetOptStat(0);
1622 gStyle->SetCanvasColor(0);
1623 gStyle->SetFrameFillColor(0);
1627 switch (ftypeOfFit4Bkg){
1644 type="PowExp"; //3+3
1648 TString filename=Form("%sMassFit.root",type.Data());
1649 filename.Prepend(userIDstring);
1650 path.Append(filename);
1652 TFile* outputcv=new TFile(path.Data(),"update");
1654 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1655 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1656 if(draw)c->DrawClone();
1662 //_________________________________________________________________________
1664 TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
1665 //return a TVirtualPad with the fitted histograms and info
1667 TString cvtitle="fit of ";
1668 cvtitle+=fhistoInvMass->GetName();
1672 TCanvas *c=new TCanvas(cvname,cvtitle);
1673 PlotFit(c->cd(),nsigma,writeFitInfo);
1676 //_________________________________________________________________________
1678 void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1679 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
1680 gStyle->SetOptStat(0);
1681 gStyle->SetCanvasColor(0);
1682 gStyle->SetFrameFillColor(0);
1684 cout<<"nsigma = "<<nsigma<<endl;
1685 cout<<"Verbosity = "<<writeFitInfo<<endl;
1687 TH1F* hdraw=GetHistoClone();
1689 if(!hdraw->GetFunction("funcmass") && !hdraw->GetFunction("funcbkgFullRange") && !hdraw->GetFunction("funcbkgRecalc")&& !hdraw->GetFunction("funcbkgonly")){
1690 cout<<"Probably fit failed and you didn't try to refit with background only, there's no function to be drawn"<<endl;
1694 if(hdraw->GetFunction("funcbkgonly")){ //Warning! if this function is present, no chance to draw the other!
1695 cout<<"Drawing background fit only"<<endl;
1696 hdraw->SetMinimum(0);
1697 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1699 hdraw->SetMarkerStyle(20);
1700 hdraw->DrawClone("PE");
1701 hdraw->GetFunction("funcbkgonly")->DrawClone("sames");
1703 if(writeFitInfo > 0){
1704 TPaveText *pinfo=new TPaveText(0.6,0.86,1.,1.,"NDC");
1705 pinfo->SetBorderSize(0);
1706 pinfo->SetFillStyle(0);
1707 TF1* f=hdraw->GetFunction("funcbkgonly");
1708 for (Int_t i=0;i<fNFinalPars-3;i++){
1709 pinfo->SetTextColor(kBlue+3);
1710 TString str=Form("%s = %.3f #pm %.3f",f->GetParName(i),f->GetParameter(i),f->GetParError(i));
1711 pinfo->AddText(str);
1714 pinfo->AddText(Form("Reduced #chi^{2} = %.3f",f->GetChisquare()/f->GetNDF()));
1724 hdraw->SetMinimum(0);
1725 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1727 hdraw->SetMarkerStyle(20);
1728 hdraw->DrawClone("PE");
1729 // if(hdraw->GetFunction("funcbkgFullRange")) hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1730 // if(hdraw->GetFunction("funcbkgRecalc")) hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
1731 if(hdraw->GetFunction("funcmass")) hdraw->GetFunction("funcmass")->DrawClone("same");
1733 if(writeFitInfo > 0){
1734 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1735 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1736 pinfob->SetBorderSize(0);
1737 pinfob->SetFillStyle(0);
1738 pinfom->SetBorderSize(0);
1739 pinfom->SetFillStyle(0);
1740 TF1* ff=fhistoInvMass->GetFunction("funcmass");
1742 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1743 pinfom->SetTextColor(kBlue);
1744 TString str=Form("%s = %.3f #pm %.3f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1745 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
1748 pinfom->DrawClone();
1750 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1751 pinfo2->SetBorderSize(0);
1752 pinfo2->SetFillStyle(0);
1754 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1756 Significance(nsigma,signif,errsignif);
1757 Signal(nsigma,signal,errsignal);
1758 Background(nsigma,bkg, errbkg);
1760 Significance(1.828,1.892,signif,errsignif);
1761 Signal(1.828,1.892,signal,errsignal);
1762 Background(1.828,1.892,bkg, errbkg);
1764 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
1765 pinfo2->AddText(str);
1766 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
1767 pinfo2->AddText(str);
1768 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
1769 pinfo2->AddText(str);
1770 if(bkg>0) str=Form("S/B (%.0f#sigma) %.4f ",nsigma,signal/bkg);
1771 pinfo2->AddText(str);
1776 if(writeFitInfo > 1){
1777 for (Int_t i=0;i<fNFinalPars-3;i++){
1778 pinfob->SetTextColor(kRed);
1779 str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1780 pinfob->AddText(str);
1783 pinfob->DrawClone();
1791 //_________________________________________________________________________
1793 void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
1794 //draws histogram together with fit functions with default nice colors in user canvas
1795 PlotFit(pd,nsigma,writeFitInfo);
1800 //_________________________________________________________________________
1801 void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1803 //draws histogram together with fit functions with default nice colors
1804 gStyle->SetOptStat(0);
1805 gStyle->SetCanvasColor(0);
1806 gStyle->SetFrameFillColor(0);
1809 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
1815 //_________________________________________________________________________
1817 void AliHFMassFitter::PrintParTitles() const{
1819 //prints to screen the parameters names
1821 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1823 cout<<"Fit function not found"<<endl;
1827 cout<<"Parameter Titles \n";
1828 for(Int_t i=0;i<fNFinalPars;i++){
1829 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1835 //************ significance
1837 //_________________________________________________________________________
1839 void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1840 // Return signal integral in mean+- n sigma
1843 cout<<"Use MassFitter method before Signal"<<endl;
1847 Double_t min=fMass-nOfSigma*fSigmaSgn;
1848 Double_t max=fMass+nOfSigma*fSigmaSgn;
1850 Signal(min,max,signal,errsignal);
1857 //_________________________________________________________________________
1859 void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1861 // Return signal integral in a range
1864 cout<<"Use MassFitter method before Signal"<<endl;
1869 TString bkgname="funcbkgRecalc";
1870 TString bkg1name="funcbkg1Recalc";
1871 TString massname="funcmass";
1875 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1877 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1881 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1882 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1885 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1889 Int_t np=fNFinalPars-3;
1891 Double_t intS,intSerr;
1893 //relative error evaluation
1894 intS=funcmass->GetParameter(np);
1895 intSerr=funcmass->GetParError(np);
1897 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1898 Double_t background,errbackground;
1899 Background(min,max,background,errbackground);
1901 //signal +/- error in the range
1903 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1904 signal=mass - background;
1905 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
1909 //_________________________________________________________________________
1911 void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1912 // Return background integral in mean+- n sigma
1915 cout<<"Use MassFitter method before Background"<<endl;
1918 Double_t min=fMass-nOfSigma*fSigmaSgn;
1919 Double_t max=fMass+nOfSigma*fSigmaSgn;
1921 Background(min,max,background,errbackground);
1926 //___________________________________________________________________________
1928 void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1929 // Return background integral in a range
1932 cout<<"Use MassFitter method before Background"<<endl;
1937 TString bkgname="funcbkgRecalc";
1938 TString bkg1name="funcbkg1Recalc";
1941 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1942 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1944 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1949 Double_t intB,intBerr;
1951 //relative error evaluation: from final parameters of the fit
1952 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1954 intB=funcbkg->GetParameter(0);
1955 intBerr=funcbkg->GetParError(0);
1956 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1959 //relative error evaluation: from histo
1961 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1963 for(Int_t i=1;i<=fSideBandl;i++){
1964 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1966 for(Int_t i=fSideBandr;i<=fNbin;i++){
1967 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1970 intBerr=TMath::Sqrt(sum2);
1971 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1973 cout<<"Last estimation of bkg error is used"<<endl;
1975 //backround +/- error in the range
1976 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1981 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1982 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1983 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1990 //__________________________________________________________________________
1992 void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
1993 // Return significance in mean+- n sigma
1995 Double_t min=fMass-nOfSigma*fSigmaSgn;
1996 Double_t max=fMass+nOfSigma*fSigmaSgn;
1997 Significance(min, max, significance, errsignificance);
2002 //__________________________________________________________________________
2004 void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
2005 // Return significance integral in a range
2007 Double_t signal,errsignal,background,errbackground;
2008 Signal(min, max,signal,errsignal);
2009 Background(min, max,background,errbackground);
2011 if (signal+background <= 0.){
2012 cout<<"Cannot calculate significance because of div by 0!"<<endl;
2018 AliVertexingHFUtils::ComputeSignificance(signal,errsignal,background,errbackground,significance,errsignificance);