1 /**************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /////////////////////////////////////////////////////////////
18 // AliHFMassFitter for the fit of invariant mass distribution
21 // Author: C.Bianchin, chiara.bianchin@pd.infn.it
22 /////////////////////////////////////////////////////////////
24 #include <Riostream.h>
32 #include <TVirtualPad.h>
34 #include <TVirtualFitter.h>
37 #include <TPaveText.h>
39 #include "AliHFMassFitter.h"
43 ClassImp(AliHFMassFitter)
45 //************** constructors
46 AliHFMassFitter::AliHFMassFitter() :
69 // default constructor
71 cout<<"Default constructor:"<<endl;
72 cout<<"Remember to set the Histo, the Type, the FixPar"<<endl;
76 //___________________________________________________________________________
78 AliHFMassFitter::AliHFMassFitter (const TH1F *histoToFit, Double_t minvalue, Double_t maxvalue, Int_t rebin,Int_t fittypeb,Int_t fittypes):
101 // standard constructor
103 fhistoInvMass= (TH1F*)histoToFit->Clone("fhistoInvMass");
104 fhistoInvMass->SetDirectory(0);
107 if(rebin!=1) RebinMass(rebin);
108 else fNbin=(Int_t)fhistoInvMass->GetNbinsX();
110 ftypeOfFit4Bkg=fittypeb;
111 ftypeOfFit4Sgn=fittypes;
112 if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2) fWithBkg=kFALSE;
114 if (!fWithBkg) cout<<"Fit Histogram of Signal only"<<endl;
115 else cout<<"Type of fit For Background = "<<ftypeOfFit4Bkg<<endl;
118 fFitPars=new Float_t[fParsSize];
120 SetDefaultFixParam();
122 fContourGraph=new TList();
123 fContourGraph->SetOwner();
128 AliHFMassFitter::AliHFMassFitter(const AliHFMassFitter &mfit):
130 fhistoInvMass(mfit.fhistoInvMass),
131 fminMass(mfit.fminMass),
132 fmaxMass(mfit.fmaxMass),
134 fParsSize(mfit.fParsSize),
135 fNFinalPars(mfit.fNFinalPars),
137 fWithBkg(mfit.fWithBkg),
138 ftypeOfFit4Bkg(mfit.ftypeOfFit4Bkg),
139 ftypeOfFit4Sgn(mfit.ftypeOfFit4Sgn),
140 ffactor(mfit.ffactor),
141 fntuParam(mfit.fntuParam),
143 fSigmaSgn(mfit.fSigmaSgn),
144 fSideBands(mfit.fSideBands),
146 fSideBandl(mfit.fSideBandl),
147 fSideBandr(mfit.fSideBandr),
148 fcounter(mfit.fcounter),
149 fContourGraph(mfit.fContourGraph)
153 if(mfit.fParsSize > 0){
154 fFitPars=new Float_t[fParsSize];
155 fFixPar=new Bool_t[fNFinalPars];
156 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
157 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Bool_t));
159 //for(Int_t i=0;i<fParsSize;i++) fFitPars[i]=mfit.fFitPars[i];
162 //_________________________________________________________________________
164 AliHFMassFitter::~AliHFMassFitter() {
168 cout<<"AliHFMassFitter destructor called"<<endl;
170 cout<<"deleting histogram..."<<endl;
171 delete fhistoInvMass;
175 cout<<"deleting ntuple..."<<endl;
183 cout<<"deleting parameter array..."<<endl;
189 cout<<"deleting bool array..."<<endl;
196 //_________________________________________________________________________
198 AliHFMassFitter& AliHFMassFitter::operator=(const AliHFMassFitter &mfit){
200 //assignment operator
202 if(&mfit == this) return *this;
203 fhistoInvMass= mfit.fhistoInvMass;
204 fminMass= mfit.fminMass;
205 fmaxMass= mfit.fmaxMass;
207 fParsSize= mfit.fParsSize;
208 fWithBkg= mfit.fWithBkg;
209 ftypeOfFit4Bkg= mfit.ftypeOfFit4Bkg;
210 ftypeOfFit4Sgn= mfit.ftypeOfFit4Sgn;
211 ffactor= mfit.ffactor;
212 fntuParam= mfit.fntuParam;
214 fSigmaSgn= mfit.fSigmaSgn;
215 fSideBands= mfit.fSideBands;
216 fSideBandl= mfit.fSideBandl;
217 fSideBandr= mfit.fSideBandr;
218 fcounter= mfit.fcounter;
219 fContourGraph= mfit.fContourGraph;
221 if(mfit.fParsSize > 0){
226 fFitPars=new Float_t[fParsSize];
227 memcpy(fFitPars,mfit.fFitPars,mfit.fParsSize*sizeof(Float_t));
233 fFixPar=new Bool_t[fNFinalPars];
234 memcpy(fFixPar,mfit.fFixPar,mfit.fNFinalPars*sizeof(Float_t));
236 // fFitPars=new Float_t[fParsSize];
237 // for(Int_t i=0;i<fParsSize;i++) fFitPars[i]=mfit.fFitPars[i];
242 //************ tools & settings
244 //__________________________________________________________________________
246 void AliHFMassFitter::ComputeNFinalPars() {
248 //compute the number of parameters of the total (signal+bgk) function
249 cout<<"Info:ComputeNFinalPars... ";
250 switch (ftypeOfFit4Bkg) {//npar background func
264 cout<<"Error in computing fNFinalPars: check ftypeOfFit4Bkg"<<endl;
268 fNFinalPars+=3; //gaussian signal
269 cout<<": "<<fNFinalPars<<endl;
271 //__________________________________________________________________________
273 void AliHFMassFitter::ComputeParSize() {
275 //compute the size of the parameter array and set the data member
277 switch (ftypeOfFit4Bkg) {//npar background func
291 cout<<"Error in computing fParsSize: check ftypeOfFit4Bkg"<<endl;
295 fParsSize += 3; // npar refl
296 fParsSize += 3; // npar signal gaus
298 fParsSize*=2; // add errors
299 cout<<"Parameters array size "<<fParsSize<<endl;
302 //___________________________________________________________________________
303 void AliHFMassFitter::SetDefaultFixParam(){
305 //Set default values for fFixPar (only total integral fixed)
308 fFixPar=new Bool_t[fNFinalPars];
310 fFixPar[0]=kTRUE; //default: IntTot fixed
311 cout<<"Parameter 0 is fixed"<<endl;
312 for(Int_t i=1;i<fNFinalPars;i++){
318 //___________________________________________________________________________
319 Bool_t AliHFMassFitter::SetFixThisParam(Int_t thispar,Bool_t fixpar){
321 //set the value (kFALSE or kTRUE) of one element of fFixPar
322 //return kFALSE if something wrong
324 if(thispar>=fNFinalPars) {
325 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
329 cout<<"Initializing fFixPar...";
330 SetDefaultFixParam();
331 cout<<" done."<<endl;
334 fFixPar[thispar]=fixpar;
335 if(fixpar)cout<<"Parameter "<<thispar<<" is now fixed"<<endl;
336 else cout<<"Parameter "<<thispar<<" is now free"<<endl;
340 //___________________________________________________________________________
341 Bool_t AliHFMassFitter::GetFixThisParam(Int_t thispar)const{
342 //return the value of fFixPar[thispar]
343 if(thispar>=fNFinalPars) {
344 cout<<"Error! Parameter out of bounds! Max is "<<fNFinalPars-1<<endl;
348 cout<<"Error! Parameters to be fixed still not set"<<endl;
352 return fFixPar[thispar];
356 //___________________________________________________________________________
357 void AliHFMassFitter::SetHisto(const TH1F *histoToFit){
358 //fhistoInvMass = (TH1F*)histoToFit->Clone();
359 fhistoInvMass = new TH1F(*histoToFit);
360 fhistoInvMass->SetDirectory(0);
361 cout<<"SetHisto pointer "<<fhistoInvMass<<endl;
364 //___________________________________________________________________________
366 void AliHFMassFitter::SetType(Int_t fittypeb, Int_t fittypes) {
368 //set the type of fit to perform for signal and background
370 ftypeOfFit4Bkg = fittypeb;
371 ftypeOfFit4Sgn = fittypes;
380 fFitPars = new Float_t[fParsSize];
387 SetDefaultFixParam();
392 //___________________________________________________________________________
394 void AliHFMassFitter::Reset() {
396 //delete the histogram and reset the mean and sigma to default
398 cout<<"Reset called: delete histogram, set mean value to 1.85 and sigma to 0.012"<<endl;
401 cout<<"Reset "<<fhistoInvMass<<endl;
403 //cout<<"esiste"<<endl;
404 delete fhistoInvMass;
406 cout<<fhistoInvMass<<endl;
408 else cout<<"histogram doesn't exist, do not delete"<<endl;
413 //_________________________________________________________________________
415 void AliHFMassFitter::InitNtuParam(char *ntuname) {
417 // Create ntuple to keep fit parameters
420 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");
424 //_________________________________________________________________________
426 void AliHFMassFitter::FillNtuParam() {
427 // Fill ntuple with fit parameters
431 if (ftypeOfFit4Bkg==2) {
432 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
433 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
434 fntuParam->SetBranchAddress("conc1",&fFitPars[2]);
435 fntuParam->SetBranchAddress("intGB",&fFitPars[3]);
436 fntuParam->SetBranchAddress("meanGB",&fFitPars[4]);
437 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]);
438 fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]);
439 fntuParam->SetBranchAddress("slope2",&fFitPars[7]);
440 fntuParam->SetBranchAddress("conc2",&fFitPars[8]);
441 fntuParam->SetBranchAddress("inttot",&fFitPars[9]);
442 fntuParam->SetBranchAddress("slope3",&fFitPars[10]);
443 fntuParam->SetBranchAddress("conc3",&fFitPars[11]);
444 fntuParam->SetBranchAddress("intsgn",&fFitPars[12]);
445 fntuParam->SetBranchAddress("meansgn",&fFitPars[13]);
446 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]);
448 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]);
449 fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]);
450 fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]);
451 fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]);
452 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]);
453 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]);
454 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]);
455 fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]);
456 fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]);
457 fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]);
458 fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]);
459 fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]);
460 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]);
461 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]);
462 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]);
466 if(ftypeOfFit4Bkg==3){
467 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
468 fntuParam->SetBranchAddress("slope1",¬hing);
469 fntuParam->SetBranchAddress("conc1",¬hing);
470 fntuParam->SetBranchAddress("intGB",&fFitPars[1]);
471 fntuParam->SetBranchAddress("meanGB",&fFitPars[2]);
472 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]);
473 fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]);
474 fntuParam->SetBranchAddress("slope2",¬hing);
475 fntuParam->SetBranchAddress("conc2",¬hing);
476 fntuParam->SetBranchAddress("inttot",&fFitPars[6]);
477 fntuParam->SetBranchAddress("slope3",¬hing);
478 fntuParam->SetBranchAddress("conc3",¬hing);
479 fntuParam->SetBranchAddress("intsgn",&fFitPars[6]);
480 fntuParam->SetBranchAddress("meansgn",&fFitPars[7]);
481 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]);
483 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]);
484 fntuParam->SetBranchAddress("slope1Err",¬hing);
485 fntuParam->SetBranchAddress("conc1Err",¬hing);
486 fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]);
487 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]);
488 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]);
489 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]);
490 fntuParam->SetBranchAddress("slope2Err",¬hing);
491 fntuParam->SetBranchAddress("conc2Err",¬hing);
492 fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]);
493 fntuParam->SetBranchAddress("slope3Err",¬hing);
494 fntuParam->SetBranchAddress("conc3Err",¬hing);
495 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]);
496 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]);
497 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]);
501 fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]);
502 fntuParam->SetBranchAddress("slope1",&fFitPars[1]);
503 fntuParam->SetBranchAddress("conc1",¬hing);
504 fntuParam->SetBranchAddress("intGB",&fFitPars[2]);
505 fntuParam->SetBranchAddress("meanGB",&fFitPars[3]);
506 fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]);
507 fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]);
508 fntuParam->SetBranchAddress("slope2",&fFitPars[6]);
509 fntuParam->SetBranchAddress("conc2",¬hing);
510 fntuParam->SetBranchAddress("inttot",&fFitPars[7]);
511 fntuParam->SetBranchAddress("slope3",&fFitPars[8]);
512 fntuParam->SetBranchAddress("conc3",¬hing);
513 fntuParam->SetBranchAddress("intsgn",&fFitPars[9]);
514 fntuParam->SetBranchAddress("meansgn",&fFitPars[10]);
515 fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]);
517 fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]);
518 fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]);
519 fntuParam->SetBranchAddress("conc1Err",¬hing);
520 fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]);
521 fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]);
522 fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]);
523 fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]);
524 fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]);
525 fntuParam->SetBranchAddress("conc2Err",¬hing);
526 fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]);
527 fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]);
528 fntuParam->SetBranchAddress("conc3Err",¬hing);
529 fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]);
530 fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]);
531 fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]);
535 fntuParam->TTree::Fill();
538 //_________________________________________________________________________
540 TNtuple* AliHFMassFitter::NtuParamOneShot(char *ntuname){
541 // Create, fill and return ntuple with fit parameters
543 InitNtuParam(ntuname);
547 //_________________________________________________________________________
549 void AliHFMassFitter::RebinMass(Int_t bingroup){
550 // Rebin invariant mass histogram
553 cout<<"Histogram not set"<<endl;
556 Int_t nbinshisto=fhistoInvMass->GetNbinsX();
558 cout<<"Error! Cannot group "<<bingroup<<" bins\n";
560 cout<<"Kept original number of bins: "<<fNbin<<endl;
563 while(nbinshisto%bingroup != 0) {
566 cout<<"Group "<<bingroup<<" bins"<<endl;
567 fhistoInvMass->Rebin(bingroup);
568 fNbin = fhistoInvMass->GetNbinsX();
569 cout<<"New number of bins: "<<fNbin<<endl;
576 //___________________________________________________________________________
578 Double_t AliHFMassFitter::FitFunction4MassDistr (Double_t *x, Double_t *par){
579 // Fit function for signal+background
582 //exponential or linear fit
584 // par[0] = tot integral
586 // par[2] = gaussian integral
587 // par[3] = gaussian mean
588 // par[4] = gaussian sigma
590 Double_t total,bkg=0,sgn=0;
592 if (ftypeOfFit4Bkg==0 || ftypeOfFit4Bkg==1) {
593 if(ftypeOfFit4Sgn == 0) {
595 Double_t parbkg[2] = {par[0]-par[2], par[1]};
596 bkg = FitFunction4Bkg(x,parbkg);
598 if(ftypeOfFit4Sgn == 1) {
599 Double_t parbkg[5] = {par[2],par[3],ffactor*par[4],par[0]-2*par[2], par[1]};
600 bkg = FitFunction4Bkg(x,parbkg);
603 sgn = FitFunction4Sgn(x,&par[2]);
609 // par[0] = tot integral
612 // par[3] = gaussian integral
613 // par[4] = gaussian mean
614 // par[5] = gaussian sigma
616 if (ftypeOfFit4Bkg==2) {
618 if(ftypeOfFit4Sgn == 0) {
620 Double_t parbkg[3] = {par[0]-par[3], par[1], par[2]};
621 bkg = FitFunction4Bkg(x,parbkg);
623 if(ftypeOfFit4Sgn == 1) {
625 Double_t parbkg[6] = {par[3],par[4],ffactor*par[5],par[0]-2*par[3], par[1], par[2]};
626 bkg = FitFunction4Bkg(x,parbkg);
629 sgn = FitFunction4Sgn(x,&par[3]);
632 if (ftypeOfFit4Bkg==3) {
634 if(ftypeOfFit4Sgn == 0) {
635 bkg=FitFunction4Bkg(x,par);
636 sgn=FitFunction4Sgn(x,&par[1]);
638 if(ftypeOfFit4Sgn == 1) {
639 Double_t parbkg[4]={par[1],par[2],ffactor*par[3],par[0]};
640 bkg=FitFunction4Bkg(x,parbkg);
641 sgn=FitFunction4Sgn(x,&par[1]);
650 //_________________________________________________________________________
651 Double_t AliHFMassFitter::FitFunction4Sgn (Double_t *x, Double_t *par){
652 // Fit function for the signal
654 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
656 // * [0] = integralSgn
659 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
661 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]);
665 //__________________________________________________________________________
667 Double_t AliHFMassFitter::FitFunction4Bkg (Double_t *x, Double_t *par){
668 // Fit function for the background
670 Double_t maxDeltaM = 4.*fSigmaSgn;
671 if(fSideBands && TMath::Abs(x[0]-fMass) < maxDeltaM) {
676 Double_t gaus2=0,total=-1;
677 if(ftypeOfFit4Sgn == 1){
679 //gaussian = A/(sigma*sqrt(2*pi))*exp(-(x-mean)^2/2/sigma^2)
681 // * [0] = integralSgn
684 //gaussian = [0]/TMath::Sqrt(2.*TMath::Pi())/[2]*exp[-(x-[1])*(x-[1])/(2*[2]*[2])]
685 gaus2 = FitFunction4Sgn(x,par);
688 switch (ftypeOfFit4Bkg){
691 //exponential = A*exp(B*x) -> integral(exponential)=A/B*exp(B*x)](min,max)
692 //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written
693 //as integralTot- integralGaus (=par [2])
695 // * [0] = integralBkg;
697 //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x)
698 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]);
702 //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)
703 // * [0] = integralBkg;
705 total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass));
709 //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) +
710 //+ 1/3*c*(max^3-min^3) ->
711 //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min)
712 // * [0] = integralBkg;
715 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));
718 total=par[0+firstPar];
721 // Types of Fit Functions for Background:
722 // * 0 = exponential;
724 // * 2 = polynomial 2nd order
725 // * 3 = no background"<<endl;
731 //__________________________________________________________________________
732 Bool_t AliHFMassFitter::SideBandsBounds(){
734 //determines the ranges of the side bands
736 Double_t width=fhistoInvMass->GetBinWidth(8);
737 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
738 Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
739 Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin)+width;
741 if(fMass-fminMass < 0 || fmaxMass-fMass <0) {
742 cout<<"Left limit of range > mean or right limit of range < mean: change left/right limit or initial mean value"<<endl;
746 if((TMath::Abs(fminMass-minHisto) < 10e6 || TMath::Abs(fmaxMass - maxHisto) < 10e6) && (fMass-4.*fSigmaSgn-fminMass) < 10e6){
747 Double_t coeff = (fMass-fminMass)/fSigmaSgn;
749 fSideBandl=(Int_t)((fMass-0.5*coeff*fSigmaSgn-fminMass)/width);
750 fSideBandr=(Int_t)((fMass+0.5*coeff*fSigmaSgn-fminMass)/width);
751 cout<<"Changed number of sigma from 4 to "<<0.5*coeff<<" for the estimation of the side bands"<<endl;
752 if (coeff<3) cout<<"Side bands inside 3 sigma, may be better use ftypeOfFit4Bkg = 3 (only signal)"<<endl;
754 cout<<"Side bands inside 2 sigma. Change mode: ftypeOfFit4Bkg = 3"<<endl;
756 //set binleft and right without considering SetRangeFit- anyway no bkg!
757 fSideBandl=(Int_t)((fMass-4.*fSigmaSgn-minHisto)/width);
758 fSideBandr=(Int_t)((fMass+4.*fSigmaSgn-minHisto)/width);
762 fSideBandl=(Int_t)((fMass-4.*fSigmaSgn-minHisto)/width);
763 fSideBandr=(Int_t)((fMass+4.*fSigmaSgn-minHisto)/width);
764 // cout<<"\tfMass = "<<fMass<<"\tfSigmaSgn = "<<fSigmaSgn<<"\tminHisto = "<<minHisto<<endl;
765 // cout<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
769 cout<<"Error! Range too little";
775 //__________________________________________________________________________
777 void AliHFMassFitter::GetSideBandsBounds(Int_t &left, Int_t &right) const{
779 // get the range of the side bands
781 if (fSideBandl==0 && fSideBandr==0){
782 cout<<"Use MassFitter method first"<<endl;
789 //__________________________________________________________________________
790 Bool_t AliHFMassFitter::CheckRangeFit(){
791 //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
793 if (!fhistoInvMass) {
794 cout<<"No histogram to fit! SetHisto(TH1F* h) before! "<<endl;
797 Bool_t leftok=kFALSE, rightok=kFALSE;
798 Int_t nbins=fhistoInvMass->GetNbinsX();
799 Double_t width=fhistoInvMass->GetBinWidth(1);
800 Double_t minhisto=fhistoInvMass->GetBinLowEdge(1), maxhisto=fhistoInvMass->GetBinLowEdge(nbins)+width;
802 //check if limits are inside histogram range
804 if( fminMass-minhisto < 0. ) {
805 cout<<"Out of histogram left bound! Setting to "<<minhisto<<endl;
808 if( fmaxMass-maxhisto > 0. ) {
809 cout<<"Out of histogram right bound! Setting to"<<maxhisto<<endl;
816 //calculate bin corresponding to fminMass
817 binl=fhistoInvMass->FindBin(fminMass);
818 if (fminMass > fhistoInvMass->GetBinCenter(binl)) binl++;
819 fminMass=fhistoInvMass->GetBinLowEdge(binl);
820 if(TMath::Abs(tmp-fminMass) > 1e-6){
821 cout<<"Left bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fminMass<<endl;
826 //calculate bin corresponding to fmaxMass
827 binr=fhistoInvMass->FindBin(fmaxMass);
828 if (fmaxMass < fhistoInvMass->GetBinCenter(binr)) binr--;
829 fmaxMass=fhistoInvMass->GetBinLowEdge(binr)+width;
830 if(TMath::Abs(tmp-fmaxMass) > 1e-6){
831 cout<<"Right bound "<<tmp<<" is not allowed, changing it to the nearest value allowed: "<<fmaxMass<<endl;
835 return (leftok && rightok);
839 //__________________________________________________________________________
841 Bool_t AliHFMassFitter::MassFitter(Bool_t draw){
842 // Main method of the class: performs the fit of the histogram
844 //Set default fitter Minuit in order to use gMinuit in the contour plots
845 TVirtualFitter::SetDefaultFitter("Minuit");
847 Int_t nFitPars=0; //total function's number of parameters
848 switch (ftypeOfFit4Bkg){
863 Int_t bkgPar = nFitPars-3; //background function's number of parameters
865 cout<<"nFitPars = "<<nFitPars<<"\tbkgPar = "<<bkgPar<<endl;
868 TString listname="contourplot";
871 fContourGraph=new TList();
872 fContourGraph->SetOwner();
875 fContourGraph->SetName(listname);
879 TString bkgname="funcbkg";
880 TString bkg1name="funcbkg1";
881 TString massname="funcmass";
884 Double_t totInt = fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass), fhistoInvMass->FindBin(fmaxMass), "width");
887 Double_t width=fhistoInvMass->GetBinWidth(8);
888 cout<<"fNbin"<<fNbin<<endl;
889 if (fNbin==0) fNbin=fhistoInvMass->GetNbinsX();
890 //Double_t minHisto=fhistoInvMass->GetBinLowEdge(1);
891 //Double_t maxHisto=fhistoInvMass->GetBinLowEdge(fNbin)+width;
892 Bool_t ok=SideBandsBounds();
893 if(!ok) return kFALSE;
895 //sidebands integral - first approx (from histo)
896 Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,fSideBandl,"width") + (Double_t)fhistoInvMass->Integral(fSideBandr,fNbin,"width");
897 cout<<"------nbin = "<<fNbin<<"\twidth = "<<width<<"\tbinleft = "<<fSideBandl<<"\tbinright = "<<fSideBandr<<endl;
898 cout<<"------sideBandsInt - first approx = "<<sideBandsInt<<endl;
899 if (sideBandsInt<=0) {
900 cout<<"! sideBandsInt <=0. There's a problem, cannot start the fit"<<endl;
907 TF1 *funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
908 cout<<"Function name = "<<funcbkg->GetName()<<endl<<endl;
910 funcbkg->SetLineColor(2); //red
912 //first fit for bkg: approx bkgint
914 switch (ftypeOfFit4Bkg) {
916 funcbkg->SetParNames("BkgInt","Slope");
917 funcbkg->SetParameters(sideBandsInt,-2.);
920 funcbkg->SetParNames("BkgInt","Slope");
921 funcbkg->SetParameters(sideBandsInt,-100.);
924 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
925 funcbkg->SetParameters(sideBandsInt,-10.,5);
928 if(ftypeOfFit4Sgn==0){
929 funcbkg->SetParNames("Const");
930 funcbkg->SetParameter(0,0.);
931 funcbkg->FixParameter(0,0.);
935 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
939 cout<<"\nBACKGROUND FIT - only combinatorial"<<endl;
940 Int_t ftypeOfFit4SgnBkp=ftypeOfFit4Sgn;
942 Double_t intbkg1=0,slope1=0,conc1=0;
943 //if only signal and reflection: skip
944 if (!(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn==1)) {
946 fhistoInvMass->Fit(bkgname.Data(),"R,L,E,0");
948 for(Int_t i=0;i<bkgPar;i++){
949 fFitPars[i]=funcbkg->GetParameter(i);
950 //cout<<i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
951 fFitPars[nFitPars+2*bkgPar+3+i]= funcbkg->GetParError(i);
952 //cout<<nFitPars+2*bkgPar+3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
955 //intbkg1 = funcbkg->GetParameter(0);
956 funcbkg->SetRange(fminMass,fmaxMass);
957 intbkg1 = funcbkg->Integral(fminMass,fmaxMass);
958 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1);
959 if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2);
960 cout<<"First fit: \nintbkg1 = "<<intbkg1<<"\t(Compare with par0 = "<<funcbkg->GetParameter(0)<<")\nslope1= "<<slope1<<"\nconc1 = "<<conc1<<endl;
962 else cout<<"\t\t//"<<endl;
964 ftypeOfFit4Sgn=ftypeOfFit4SgnBkp;
966 if (ftypeOfFit4Sgn == 1) {
967 cout<<"\nBACKGROUND FIT WITH REFLECTION"<<endl;
970 cout<<"nFitPars = "<<nFitPars<<"\tbkgPar = "<<bkgPar<<endl;
972 funcbkg1 = new TF1(bkg1name.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,bkgPar,"AliHFMassFitter","FitFunction4Bkg");
973 cout<<"Function name = "<<funcbkg1->GetName()<<endl;
975 funcbkg1->SetLineColor(2); //red
977 if(ftypeOfFit4Bkg==2){
978 cout<<"*** Polynomial Fit ***"<<endl;
979 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2");
980 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1);
982 //cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<<fMass<<"\t"<<ffactor*fSigmaSgn<<"\t"<<intbkg1<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<endl;
983 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<bkgPar<<"\tgsidebands = "<<fSideBands<<endl;
985 if(ftypeOfFit4Bkg==3) //no background: gaus sign+ gaus broadened
987 cout<<"*** No background Fit ***"<<endl;
988 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","Const");
989 funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.);
990 funcbkg1->FixParameter(3,0.);
991 } else{ //expo or linear
992 if(ftypeOfFit4Bkg==0) cout<<"*** Exponential Fit ***"<<endl;
993 if(ftypeOfFit4Bkg==1) cout<<"*** Linear Fit ***"<<endl;
994 funcbkg1->SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope");
995 funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1);
998 Int_t status=fhistoInvMass->Fit(bkg1name.Data(),"R,L,E,+,0");
1000 cout<<"Minuit returned "<<status<<endl;
1004 for(Int_t i=0;i<bkgPar;i++){
1005 fFitPars[bkgPar-3+i]=funcbkg1->GetParameter(i);
1006 //cout<<bkgPar-3+i<<"\t"<<funcbkg1->GetParameter(i);
1007 fFitPars[nFitPars+3*bkgPar-6+i]= funcbkg1->GetParError(i);
1008 //cout<<"\t"<<nFitPars+3*bkgPar-6+i<<"\t"<<funcbkg1->GetParError(i)<<endl;
1011 intbkg1=funcbkg1->GetParameter(3);
1012 if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4);
1013 if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5);
1018 for(Int_t i=0;i<3;i++){
1019 fFitPars[bkgPar-3+i]=0.;
1020 cout<<bkgPar-3+i<<"\t"<<0.<<"\t";
1021 fFitPars[nFitPars+3*bkgPar-6+i]= 0.;
1022 cout<<nFitPars+3*bkgPar-6+i<<"\t"<<0.<<endl;
1025 for(Int_t i=0;i<bkgPar-3;i++){
1026 fFitPars[bkgPar+i]=funcbkg->GetParameter(i);
1027 cout<<bkgPar+i<<"\t"<<funcbkg->GetParameter(i)<<"\t";
1028 fFitPars[nFitPars+3*bkgPar-3+i]= funcbkg->GetParError(i);
1029 cout<<nFitPars+3*bkgPar-3+i<<"\t"<< funcbkg->GetParError(i)<<endl;
1035 //sidebands integral - second approx (from fit)
1036 fSideBands = kFALSE;
1038 cout<<"Compare intbkg1 = "<<intbkg1<<" and integral = ";
1039 if(ftypeOfFit4Sgn == 1) bkgInt=funcbkg1->Integral(fminMass,fmaxMass);
1040 else bkgInt=funcbkg->Integral(fminMass,fmaxMass);
1041 cout<</*"------BkgInt(Fit) = "<<*/bkgInt<<endl;
1043 //Signal integral - first approx
1045 sgnInt = totInt-bkgInt;
1046 cout<<"------TotInt = "<<totInt<<"\tsgnInt = "<<sgnInt<<endl;
1048 cout<<"Setting sgnInt = - sgnInt"<<endl;
1051 /*Fit All Mass distribution with exponential + gaussian (+gaussiam braodened) */
1052 TF1 *funcmass = new TF1(massname.Data(),this,&AliHFMassFitter::FitFunction4MassDistr,fminMass,fmaxMass,nFitPars,"AliHFMassFitter","FitFunction4MassDistr");
1053 cout<<"Function name = "<<funcmass->GetName()<<endl<<endl;
1054 funcmass->SetLineColor(4); //blue
1057 cout<<"\nTOTAL FIT"<<endl;
1060 funcmass->SetParNames("TotInt","Slope","SgnInt","Mean","Sigma");
1061 funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn);
1063 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1064 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1067 funcmass->FixParameter(0,totInt);
1071 funcmass->FixParameter(1,slope1);
1075 funcmass->FixParameter(2,sgnInt);
1079 funcmass->FixParameter(3,fMass);
1083 funcmass->FixParameter(4,fSigmaSgn);
1087 funcmass->SetParNames("TotInt","Coef1","Coef2","SgnInt","Mean","Sigma");
1088 funcmass->SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn);
1090 //cout<<"Parameters set to: "<<totInt<<"\t"<<slope1<<"\t"<<conc1<<"\t"<<sgnInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1091 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1092 if(fFixPar[0])funcmass->FixParameter(0,totInt);
1093 if(fFixPar[1])funcmass->FixParameter(1,slope1);
1094 if(fFixPar[2])funcmass->FixParameter(2,conc1);
1095 if(fFixPar[3])funcmass->FixParameter(3,sgnInt);
1096 if(fFixPar[4])funcmass->FixParameter(4,fMass);
1097 if(fFixPar[5])funcmass->FixParameter(5,fSigmaSgn);
1099 //funcmass->FixParameter(2,sgnInt);
1102 funcmass->SetParNames("Const","SgnInt","Mean","Sigma");
1103 if(ftypeOfFit4Sgn == 1) funcmass->SetParameters(0.,0.5*totInt,fMass,fSigmaSgn);
1104 else funcmass->SetParameters(0.,totInt,fMass,fSigmaSgn);
1105 if(fFixPar[0]) funcmass->FixParameter(0,0.);
1106 //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<<fMass<<"\t"<<fSigmaSgn<<"\t"<<endl;
1107 //cout<<"Limits: ("<<fminMass<<","<<fmaxMass<<")\tnPar = "<<nFitPars<<"\tgsidebands = "<<fSideBands<<endl;
1110 //funcmass->FixParameter(nFitPars-2,fMass);
1111 //funcmass->SetParLimits(nFitPars-1,0.007,0.05);
1112 //funcmass->SetParLimits(nFitPars-2,fMass-0.01,fMass+0.01);
1115 status = fhistoInvMass->Fit(massname.Data(),"R,L,E,+,0");
1117 cout<<"Minuit returned "<<status<<endl;
1121 cout<<"fit done"<<endl;
1122 //reset value of fMass and fSigmaSgn to those found from fit
1123 fMass=funcmass->GetParameter(nFitPars-2);
1124 fSigmaSgn=funcmass->GetParameter(nFitPars-1);
1126 for(Int_t i=0;i<nFitPars;i++){
1127 fFitPars[i+2*bkgPar-3]=funcmass->GetParameter(i);
1128 fFitPars[nFitPars+4*bkgPar-6+i]= funcmass->GetParError(i);
1129 //cout<<i+2*bkgPar-3<<"\t"<<funcmass->GetParameter(i)<<"\t\t"<<nFitPars+4*bkgPar-6+i<<"\t"<<funcmass->GetParError(i)<<endl;
1132 //check: cout parameters
1133 for(Int_t i=0;i<2*(nFitPars+2*bkgPar-3);i++){
1134 cout<<i<<"\t"<<fFitPars[i]<<endl;
1139 // TCanvas *canvas=new TCanvas(fhistoInvMass->GetName(),fhistoInvMass->GetName());
1140 // TH1F *fhistocopy=new TH1F(*fhistoInvMass);
1142 // fhistocopy->DrawClone();
1143 // if(ftypeOfFit4Sgn == 1) funcbkg1->DrawClone("sames");
1144 // else funcbkg->DrawClone("sames");
1145 // funcmass->DrawClone("sames");
1146 // cout<<"Drawn"<<endl;
1149 if(funcmass->GetParameter(nFitPars-1) <0 || funcmass->GetParameter(nFitPars-2) <0 || funcmass->GetParameter(nFitPars-3) <0 ) {
1150 cout<<"IntS or mean or sigma negative. You may tray to SetInitialGaussianSigma(..) and SetInitialGaussianMean(..)"<<endl;
1154 //increase counter of number of fits done
1160 for (Int_t kpar=1; kpar<nFitPars;kpar++){
1162 for(Int_t jpar=kpar+1;jpar<nFitPars;jpar++){
1163 cout<<"Par "<<kpar<<" and "<<jpar<<endl;
1165 // produce 2 contours per couple of parameters
1166 TGraph* cont[2] = {0x0, 0x0};
1167 const Double_t errDef[2] = {1., 4.};
1168 for (Int_t i=0; i<2; i++) {
1169 gMinuit->SetErrorDef(errDef[i]);
1170 cont[i] = (TGraph*)gMinuit->Contour(80,kpar,jpar);
1171 cout<<"Minuit Status = "<<gMinuit->GetStatus()<<endl;
1174 if(!cont[0] || !cont[1]){
1175 cout<<"Skipping par "<<kpar<<" vs par "<<jpar<<endl;
1179 // set graph titles and add them to the list
1180 TString title = "Contour plot";
1181 TString titleX = funcmass->GetParName(kpar);
1182 TString titleY = funcmass->GetParName(jpar);
1183 for (Int_t i=0; i<2; i++) {
1184 cont[i]->SetName( Form("cperr%d_%d%d", i, kpar, jpar) );
1185 cont[i]->SetTitle(title);
1186 cont[i]->GetXaxis()->SetTitle(titleX);
1187 cont[i]->GetYaxis()->SetTitle(titleY);
1188 cont[i]->GetYaxis()->SetLabelSize(0.033);
1189 cont[i]->GetYaxis()->SetTitleSize(0.033);
1190 cont[i]->GetYaxis()->SetTitleOffset(1.67);
1192 fContourGraph->Add(cont[i]);
1196 TString cvname = Form("c%d%d", kpar, jpar);
1197 TCanvas *c4=new TCanvas(cvname,cvname,600,600);
1199 cont[1]->SetFillColor(38);
1200 cont[1]->Draw("alf");
1201 cont[0]->SetFillColor(9);
1202 cont[0]->Draw("lf");
1210 if (ftypeOfFit4Sgn == 1 && funcbkg1) {
1223 AddFunctionsToHisto();
1224 if (draw) DrawFit();
1230 //______________________________________________________________________________
1232 Bool_t AliHFMassFitter::RefitWithBkgOnly(Bool_t draw){
1234 //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
1235 //If you want to change the backgroud function or range use SetType or SetRangeFit before
1237 TString bkgname="funcbkgonly";
1238 fSideBands = kFALSE;
1240 TF1* funcbkg = new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,fNFinalPars-3,"AliHFMassFitter","FitFunction4Bkg");
1242 funcbkg->SetLineColor(kBlue+3); //dark blue
1244 Double_t integral=fhistoInvMass->Integral(fhistoInvMass->FindBin(fminMass),fhistoInvMass->FindBin(fmaxMass),"width");
1246 switch (ftypeOfFit4Bkg) {
1248 funcbkg->SetParNames("BkgInt","Slope");
1249 funcbkg->SetParameters(integral,-2.);
1252 funcbkg->SetParNames("BkgInt","Slope");
1253 funcbkg->SetParameters(integral,-100.);
1256 funcbkg->SetParNames("BkgInt","Coef1","Coef2");
1257 funcbkg->SetParameters(integral,-10.,5);
1260 cout<<"Warning! This choice does not have a lot of sense..."<<endl;
1261 if(ftypeOfFit4Sgn==0){
1262 funcbkg->SetParNames("Const");
1263 funcbkg->SetParameter(0,0.);
1264 funcbkg->FixParameter(0,0.);
1268 cout<<"Wrong choise of ftypeOfFit4Bkg ("<<ftypeOfFit4Bkg<<")"<<endl;
1274 Int_t status=fhistoInvMass->Fit(bkgname.Data(),"R,L,E,+,0");
1276 cout<<"Minuit returned "<<status<<endl;
1279 AddFunctionsToHisto();
1286 //_________________________________________________________________________
1287 Double_t AliHFMassFitter::GetChiSquare() const{
1288 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1289 return funcmass->GetChisquare();
1292 //_________________________________________________________________________
1293 Double_t AliHFMassFitter::GetReducedChiSquare() const{
1294 TF1 *funcmass=(TF1*)fhistoInvMass->GetFunction("funcmass");
1296 cout<<"funcmass not found"<<endl;
1299 return funcmass->GetChisquare()/funcmass->GetNDF();
1304 //_________________________________________________________________________
1305 void AliHFMassFitter::GetFitPars(Float_t *vector) const {
1306 // Return fit parameters
1308 for(Int_t i=0;i<fParsSize;i++){
1309 vector[i]=fFitPars[i];
1314 //_________________________________________________________________________
1315 void AliHFMassFitter::IntS(Float_t *valuewitherror) const {
1317 //gives the integral of signal obtained from fit parameters
1318 if(!valuewitherror)valuewitherror=new Float_t[2];
1320 Int_t index=fParsSize/2 - 3;
1321 valuewitherror[0]=fFitPars[index];
1322 index=fParsSize - 3;
1323 valuewitherror[1]=fFitPars[index];
1327 //_________________________________________________________________________
1328 void AliHFMassFitter::AddFunctionsToHisto(){
1330 //Add the background function in the complete range to the list of functions attached to the histogram
1332 cout<<"AddFunctionsToHisto called"<<endl;
1333 TString bkgname = "funcbkg";
1335 switch (ftypeOfFit4Bkg){
1349 if (ftypeOfFit4Sgn == 1) {
1354 Bool_t done1=kFALSE,done2=kFALSE;
1356 TString bkgnamesave=bkgname;
1357 TString testname=bkgname;
1358 testname += "FullRange";
1359 TF1 *testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1364 testname="funcbkgonly";
1365 testfunc=(TF1*)fhistoInvMass->FindObject(testname.Data());
1372 cout<<"AddFunctionsToHisto already used: exiting...."<<endl;
1376 TList *hlist=fhistoInvMass->GetListOfFunctions();
1380 TF1 *bonly=(TF1*)hlist->FindObject(testname.Data());
1382 cout<<testname.Data()<<" not found looking for complete fit"<<endl;
1384 bonly->SetLineColor(kBlue+3);
1385 hlist->Add((TF1*)bonly->Clone());
1395 TF1 *b=(TF1*)hlist->FindObject(bkgname.Data());
1397 cout<<bkgname<<" not found, cannot produce "<<bkgname<<"FullRange and "<<bkgname<<"Recalc"<<endl;
1401 bkgname += "FullRange";
1402 TF1 *bfullrange=new TF1(bkgname.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,np,"AliHFMassFitter","FitFunction4Bkg");
1403 //cout<<bfullrange->GetName()<<endl;
1404 for(Int_t i=0;i<np;i++){
1405 //cout<<i<<" di "<<np<<endl;
1406 bfullrange->SetParName(i,b->GetParName(i));
1407 bfullrange->SetParameter(i,b->GetParameter(i));
1408 bfullrange->SetParError(i,b->GetParError(i));
1410 bfullrange->SetLineStyle(4);
1411 bfullrange->SetLineColor(14);
1413 bkgnamesave += "Recalc";
1415 TF1 *blastpar=new TF1(bkgnamesave.Data(),this,&AliHFMassFitter::FitFunction4Bkg,fminMass,fmaxMass,np,"AliHFMassFitter","FitFunction4Bkg");
1417 TF1 *mass=fhistoInvMass->GetFunction("funcmass");
1420 cout<<"funcmass doesn't exist "<<endl;
1424 blastpar->SetParameter(0,mass->GetParameter(0)-mass->GetParameter(np));
1425 blastpar->SetParError(0,mass->GetParError(np));
1427 blastpar->SetParameter(1,mass->GetParameter(1));
1428 blastpar->SetParError(1,mass->GetParError(1));
1431 blastpar->SetParameter(2,mass->GetParameter(2));
1432 blastpar->SetParError(2,mass->GetParError(2));
1435 blastpar->SetLineStyle(1);
1436 blastpar->SetLineColor(2);
1438 hlist->Add((TF1*)bfullrange->Clone());
1439 hlist->Add((TF1*)blastpar->Clone());
1455 //_________________________________________________________________________
1457 TH1F* AliHFMassFitter::GetHistoClone() const{
1459 TH1F* hout=(TH1F*)fhistoInvMass->Clone(fhistoInvMass->GetName());
1462 //_________________________________________________________________________
1464 void AliHFMassFitter::WriteHisto(TString path) const {
1466 //Write the histogram in the default file HFMassFitterOutput.root
1468 if (fcounter == 0) {
1469 cout<<"Use MassFitter method before WriteHisto"<<endl;
1472 TH1F* hget=(TH1F*)fhistoInvMass->Clone();
1474 path += "HFMassFitterOutput.root";
1477 if (fcounter == 1) output = new TFile(path.Data(),"recreate");
1478 else output = new TFile(path.Data(),"update");
1481 fContourGraph->Write();
1486 cout<<fcounter<<" "<<hget->GetName()<<" written in "<<path<<endl;
1495 //_________________________________________________________________________
1497 void AliHFMassFitter::WriteNtuple(TString path) const{
1498 //TNtuple* nget=(TNtuple*)fntuParam->Clone();
1499 path += "HFMassFitterOutput.root";
1500 TFile *output = new TFile(path.Data(),"update");
1505 //cout<<nget->GetName()<<" written in "<<path<<endl;
1506 cout<<fntuParam->GetName()<<" written in "<<path<<endl;
1519 //_________________________________________________________________________
1520 void AliHFMassFitter::WriteCanvas(TString userIDstring,TString path,Double_t nsigma,Int_t writeFitInfo,Bool_t draw) const{
1522 //write the canvas in a root file
1524 gStyle->SetOptStat(0);
1525 gStyle->SetCanvasColor(0);
1526 gStyle->SetFrameFillColor(0);
1530 switch (ftypeOfFit4Bkg){
1545 TString filename=Form("%sMassFit.root",type.Data());
1546 filename.Prepend(userIDstring);
1547 path.Append(filename);
1549 TFile* outputcv=new TFile(path.Data(),"update");
1551 TCanvas* c=(TCanvas*)GetPad(nsigma,writeFitInfo);
1552 c->SetName(Form("%s%s%s",c->GetName(),userIDstring.Data(),type.Data()));
1553 if(draw)c->DrawClone();
1559 //_________________________________________________________________________
1561 TVirtualPad* AliHFMassFitter::GetPad(Double_t nsigma,Int_t writeFitInfo)const{
1562 //return a TVirtualPad with the fitted histograms and info
1564 TString cvtitle="fit of ";
1565 cvtitle+=fhistoInvMass->GetName();
1569 TCanvas *c=new TCanvas(cvname,cvtitle);
1570 PlotFit(c->cd(),nsigma,writeFitInfo);
1573 //_________________________________________________________________________
1575 void AliHFMassFitter::PlotFit(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo)const{
1576 //plot histogram, fit functions and write parameters according to verbosity level (0,1,>1)
1577 gStyle->SetOptStat(0);
1578 gStyle->SetCanvasColor(0);
1579 gStyle->SetFrameFillColor(0);
1581 cout<<"nsigma = "<<nsigma<<endl;
1582 cout<<"Verbosity = "<<writeFitInfo<<endl;
1584 TH1F* hdraw=GetHistoClone();
1586 if(!hdraw->GetFunction("funcmass") && !hdraw->GetFunction("funcbkgFullRange") && !hdraw->GetFunction("funcbkgRecalc")&& !hdraw->GetFunction("funcbkgonly")){
1587 cout<<"Probably fit failed and you didn't try to refit with background only, there's no function to be drawn"<<endl;
1591 if(hdraw->GetFunction("funcbkgonly")){ //Warning! if this function is present, no chance to draw the other!
1592 cout<<"Drawing background fit only"<<endl;
1593 hdraw->SetMinimum(0);
1594 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1596 hdraw->SetMarkerStyle(20);
1597 hdraw->DrawClone("PE");
1598 hdraw->GetFunction("funcbkgonly")->DrawClone("sames");
1600 if(writeFitInfo > 0){
1601 TPaveText *pinfo=new TPaveText(0.6,0.86,1.,1.,"NDC");
1602 pinfo->SetBorderSize(0);
1603 pinfo->SetFillStyle(0);
1604 TF1* f=hdraw->GetFunction("funcbkgonly");
1605 for (Int_t i=0;i<fNFinalPars-3;i++){
1606 pinfo->SetTextColor(kBlue+3);
1607 TString str=Form("%s = %f #pm %f",f->GetParName(i),f->GetParameter(i),f->GetParError(i));
1608 pinfo->AddText(str);
1611 pinfo->AddText(Form("Reduced #chi^{2} = %.3f",f->GetChisquare()/f->GetNDF()));
1621 hdraw->SetMinimum(0);
1622 hdraw->GetXaxis()->SetRangeUser(fminMass,fmaxMass);
1624 hdraw->SetMarkerStyle(20);
1625 hdraw->DrawClone("PE");
1626 hdraw->GetFunction("funcbkgFullRange")->DrawClone("same");
1627 hdraw->GetFunction("funcbkgRecalc")->DrawClone("same");
1628 hdraw->GetFunction("funcmass")->DrawClone("same");
1630 if(writeFitInfo > 0){
1631 TPaveText *pinfob=new TPaveText(0.6,0.86,1.,1.,"NDC");
1632 TPaveText *pinfom=new TPaveText(0.6,0.7,1.,.87,"NDC");
1633 pinfob->SetBorderSize(0);
1634 pinfob->SetFillStyle(0);
1635 pinfom->SetBorderSize(0);
1636 pinfom->SetFillStyle(0);
1637 TF1* ff=fhistoInvMass->GetFunction("funcmass");
1639 for (Int_t i=fNFinalPars-3;i<fNFinalPars;i++){
1640 pinfom->SetTextColor(kBlue);
1641 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1642 if(!(writeFitInfo==1 && i==fNFinalPars-3)) pinfom->AddText(str);
1645 pinfom->DrawClone();
1647 TPaveText *pinfo2=new TPaveText(0.1,0.1,0.6,0.4,"NDC");
1648 pinfo2->SetBorderSize(0);
1649 pinfo2->SetFillStyle(0);
1651 Double_t signif, signal, bkg, errsignif, errsignal, errbkg;
1653 Significance(nsigma,signif,errsignif);
1654 Signal(nsigma,signal,errsignal);
1655 Background(nsigma,bkg, errbkg);
1657 Significance(1.828,1.892,signif,errsignif);
1658 Signal(1.828,1.892,signal,errsignal);
1659 Background(1.828,1.892,bkg, errbkg);
1661 TString str=Form("Significance (%.0f#sigma) %.1f #pm %.1f ",nsigma,signif,errsignif);
1662 pinfo2->AddText(str);
1663 str=Form("S (%.0f#sigma) %.0f #pm %.0f ",nsigma,signal,errsignal);
1664 pinfo2->AddText(str);
1665 str=Form("B (%.0f#sigma) %.0f #pm %.0f",nsigma,bkg,errbkg);
1666 pinfo2->AddText(str);
1671 if(writeFitInfo > 1){
1672 for (Int_t i=0;i<fNFinalPars-3;i++){
1673 pinfob->SetTextColor(kRed);
1674 TString str=Form("%s = %f #pm %f",ff->GetParName(i),ff->GetParameter(i),ff->GetParError(i));
1675 pinfob->AddText(str);
1678 pinfob->DrawClone();
1686 //_________________________________________________________________________
1688 void AliHFMassFitter::DrawHere(TVirtualPad* pd,Double_t nsigma,Int_t writeFitInfo) const {
1689 //draws histogram together with fit functions with default nice colors in user canvas
1690 PlotFit(pd,nsigma,writeFitInfo);
1695 //_________________________________________________________________________
1696 void AliHFMassFitter::DrawFit(Double_t nsigma) const{
1698 //draws histogram together with fit functions with default nice colors
1699 gStyle->SetOptStat(0);
1700 gStyle->SetCanvasColor(0);
1701 gStyle->SetFrameFillColor(0);
1704 TCanvas* c=(TCanvas*)GetPad(nsigma,1);
1710 //_________________________________________________________________________
1712 void AliHFMassFitter::PrintParTitles() const{
1714 //prints to screen the parameters names
1716 TF1 *f=fhistoInvMass->GetFunction("funcmass");
1718 cout<<"Fit function not found"<<endl;
1723 switch (ftypeOfFit4Bkg){
1738 np+=3; //3 parameter for signal
1739 if (ftypeOfFit4Sgn == 1) np+=3;
1741 cout<<"Parameter Titles \n";
1742 for(Int_t i=0;i<np;i++){
1743 cout<<"Par "<<i<<": "<<f->GetParName(i)<<endl;
1749 //************ significance
1751 //_________________________________________________________________________
1753 void AliHFMassFitter::Signal(Double_t nOfSigma,Double_t &signal,Double_t &errsignal) const {
1754 // Return signal integral in mean+- n sigma
1757 cout<<"Use MassFitter method before Signal"<<endl;
1761 Double_t min=fMass-nOfSigma*fSigmaSgn;
1762 Double_t max=fMass+nOfSigma*fSigmaSgn;
1764 Signal(min,max,signal,errsignal);
1766 // //functions names
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;
1788 // switch (ftypeOfFit4Bkg){
1803 // Float_t intS,intSerr;
1805 // //relative error evaluation
1807 // intS=funcmass->GetParameter(np);
1808 // intSerr=funcmass->GetParError(np);
1810 // cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1811 // Double_t background,errbackground;
1812 // Background(nOfSigma,background,errbackground);
1814 // //signal +/- error in nsigma
1815 // Double_t min=fMass-nOfSigma*fSigmaSgn;
1816 // Double_t max=fMass+nOfSigma*fSigmaSgn;
1818 // Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1819 // signal=mass - background;
1820 // errsignal=TMath::Sqrt((intSerr/intS*mass)*(intSerr/intS*mass)/*assume relative error is the same as for total integral*/ + errbackground*errbackground);
1825 //_________________________________________________________________________
1827 void AliHFMassFitter::Signal(Double_t min, Double_t max, Double_t &signal,Double_t &errsignal) const {
1829 // Return signal integral in a range
1832 cout<<"Use MassFitter method before Signal"<<endl;
1837 TString bkgname="funcbkgRecalc";
1838 TString bkg1name="funcbkg1Recalc";
1839 TString massname="funcmass";
1843 TF1 *funcmass=fhistoInvMass->GetFunction(massname.Data());
1845 cout<<"AliHFMassFitter::Signal() ERROR -> Mass distr function not found!"<<endl;
1849 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1850 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1853 cout<<"AliHFMassFitter::Signal() ERROR -> Bkg function not found!"<<endl;
1858 switch (ftypeOfFit4Bkg){
1873 Double_t intS,intSerr;
1875 //relative error evaluation
1876 intS=funcmass->GetParameter(np);
1877 intSerr=funcmass->GetParError(np);
1879 cout<<"Sgn relative error evaluation from fit: "<<intSerr/intS<<endl;
1880 Double_t background,errbackground;
1881 Background(min,max,background,errbackground);
1883 //signal +/- error in the range
1885 Double_t mass=funcmass->Integral(min, max)/fhistoInvMass->GetBinWidth(4);
1886 signal=mass - background;
1887 errsignal=(intSerr/intS)*signal;/*assume relative error is the same as for total integral*/
1891 //_________________________________________________________________________
1893 void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const {
1894 // Return background integral in mean+- n sigma
1897 cout<<"Use MassFitter method before Background"<<endl;
1900 Double_t min=fMass-nOfSigma*fSigmaSgn;
1901 Double_t max=fMass+nOfSigma*fSigmaSgn;
1903 Background(min,max,background,errbackground);
1905 // //functions names
1906 // TString bkgname="funcbkgRecalc";
1907 // TString bkg1name="funcbkg1Recalc";
1910 // if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1911 // else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1913 // cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1917 // Float_t intB,intBerr;//, intT,intTerr,intS,intSerr;
1919 // //relative error evaluation: from final parameters of the fit
1920 // if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1923 // intB=funcbkg->GetParameter(0);
1924 // intBerr=funcbkg->GetParError(0);
1926 // cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1929 // Double_t min=fMass-nOfSigma*fSigmaSgn;
1930 // Double_t max=fMass+nOfSigma*fSigmaSgn;
1932 // //relative error evaluation: from histo
1934 // intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1937 // for(Int_t i=1;i<=fSideBandl;i++){
1938 // sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1940 // for(Int_t i=fSideBandr;i<=fNbin;i++){
1941 // sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
1944 // intBerr=TMath::Sqrt(sum2);
1945 // cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
1947 // cout<<"Last estimation of bkg error is used"<<endl;
1949 // //backround +/- error in nsigma
1950 // if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
1952 // errbackground = 0;
1955 // background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
1956 // errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
1957 // //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
1962 //___________________________________________________________________________
1964 void AliHFMassFitter::Background(Double_t min, Double_t max, Double_t &background,Double_t &errbackground) const {
1965 // Return background integral in a range
1968 cout<<"Use MassFitter method before Background"<<endl;
1973 TString bkgname="funcbkgRecalc";
1974 TString bkg1name="funcbkg1Recalc";
1977 if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction(bkgname.Data());
1978 else funcbkg=fhistoInvMass->GetFunction(bkg1name.Data());
1980 cout<<"AliHFMassFitter::Background() ERROR -> Bkg function not found!"<<endl;
1985 Double_t intB,intBerr;
1987 //relative error evaluation: from final parameters of the fit
1988 if(ftypeOfFit4Bkg==3 && ftypeOfFit4Sgn == 0) cout<<"No background fit: Bkg relative error evaluation put to zero"<<endl;
1990 intB=funcbkg->GetParameter(0);
1991 intBerr=funcbkg->GetParError(0);
1992 cout<<"Bkg relative error evaluation: from final parameters of the fit: "<<intBerr/intB<<endl;
1995 //relative error evaluation: from histo
1997 intB=fhistoInvMass->Integral(1,fSideBandl)+fhistoInvMass->Integral(fSideBandr,fNbin);
1999 for(Int_t i=1;i<=fSideBandl;i++){
2000 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
2002 for(Int_t i=fSideBandr;i<=fNbin;i++){
2003 sum2+=fhistoInvMass->GetBinError(i)*fhistoInvMass->GetBinError(i);
2006 intBerr=TMath::Sqrt(sum2);
2007 cout<<"Bkg relative error evaluation: from histo: "<<intBerr/intB<<endl;
2009 cout<<"Last estimation of bkg error is used"<<endl;
2011 //backround +/- error in the range
2012 if (ftypeOfFit4Bkg == 3 && ftypeOfFit4Sgn == 0) {
2017 background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2);
2018 errbackground=intBerr/intB*background; // assume relative error is the same as for total integral
2019 //cout<<"integral = "<<funcbkg->Integral(min, max)<<"\tbinW = "<<fhistoInvMass->GetBinWidth(2)<<endl;
2026 //__________________________________________________________________________
2028 void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const {
2029 // Return significance in mean+- n sigma
2031 Double_t min=fMass-nOfSigma*fSigmaSgn;
2032 Double_t max=fMass+nOfSigma*fSigmaSgn;
2033 Significance(min, max, significance, errsignificance);
2035 Double_t signal,errsignal,background,errbackground;
2036 Signal(nOfSigma,signal,errsignal);
2037 Background(nOfSigma,background,errbackground);
2039 significance = signal/TMath::Sqrt(signal+background);
2041 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);
2046 //__________________________________________________________________________
2048 void AliHFMassFitter::Significance(Double_t min, Double_t max, Double_t &significance,Double_t &errsignificance) const {
2049 // Return significance integral in a range
2051 Double_t signal,errsignal,background,errbackground;
2052 Signal(min, max,signal,errsignal);
2053 Background(min, max,background,errbackground);
2055 if (signal+background <= 0.){
2056 cout<<"Cannot calculate significance because of div by 0!"<<endl;
2061 significance = signal/TMath::Sqrt(signal+background);
2063 errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal);