/************************************************************************** * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ ///////////////////////////////////////////////////////////// // // AliHFMassFitter for the fit of invariant mass distribution // of charmed mesons // // Author: C.Bianchin, chiara.bianchin@pd.infn.it ///////////////////////////////////////////////////////////// #include #include "AliHFMassFitter.h" ClassImp(AliHFMassFitter) //constructors AliHFMassFitter::AliHFMassFitter() : TNamed(), fhistoInvMass(0), fminMass(0), fmaxMass(0), fNbin(1), fParsSize(1), fFitPars(0), fWithBkg(0), ftypeOfFit4Bkg(0), ftypeOfFit4Sgn(0), ffactor(1), fntuParam(0), fMass(1.85), fSigmaSgn(0.012), fSideBands(0) { // default constructor cout<<"Default constructor"<GetNbinsX(); ftypeOfFit4Bkg=fittypeb; ftypeOfFit4Sgn=fittypes; if(ftypeOfFit4Bkg!=0 && ftypeOfFit4Bkg!=1 && ftypeOfFit4Bkg!=2) fWithBkg=kFALSE; else fWithBkg=kTRUE; if (!fWithBkg) cout<<"Fit Histogram of Signal only"< integral(exponential)=A/B*exp(B*x)](min,max) //-> A = B*integral/(exp(B*max)-exp(B*min)) where integral can be written //as integralTot- integralGaus (=par [2]) //Par: // * [0] = integralBkg; // * [1] = B; //exponential = [1]*[0]/(exp([1]*max)-exp([1]*min))*exp([1]*x) 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]); break; case 1: //linear //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) // * [0] = integralBkg; // * [1] = b; total= par[0+firstPar]/(fmaxMass-fminMass)+par[1+firstPar]*(x[0]-0.5*(fmaxMass+fminMass)); break; case 2: //polynomial //y=a+b*x+c*x**2 -> integral = a(max-min) + 1/2*b*(max^2-min^2) + //+ 1/3*c*(max^3-min^3) -> //a = (integral-1/2*b*(max^2-min^2)-1/3*c*(max^3-min^3))/(max-min) // * [0] = integralBkg; // * [1] = b; // * [2] = c; 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)); break; case 3: total=par[0+firstPar]; break; // default: // Types of Fit Functions for Background: // * 0 = exponential; // * 1 = linear; // * 2 = polynomial 2nd order // * 3 = no background"<GetNbinsX(); width=fhistoInvMass->GetBinWidth(8); //width=(fmaxMass-fminMass)/(Double_t)fNbin; binleft=(Int_t)((fMass-4.*fSigmaSgn-fminMass)/width); binright=(Int_t)((fMass+4.*fSigmaSgn-fminMass)/width); //sidebands integral - first approx (from histo) Double_t sideBandsInt=(Double_t)fhistoInvMass->Integral(1,binleft,"width") + (Double_t)fhistoInvMass->Integral(binright,fNbin,"width"); cout<<"------nbin = "<SetLineColor(2); //red //first fit for bkg: approx bkgint switch (ftypeOfFit4Bkg) { case 0: //gaus+expo funcbkg->SetParNames("BkgInt","Slope"); funcbkg->SetParameters(sideBandsInt,-2.); break; case 1: funcbkg->SetParNames("BkgInt","Slope"); funcbkg->SetParameters(sideBandsInt,-100.); break; case 2: funcbkg->SetParNames("BkgInt","Coef1","Coef2"); funcbkg->SetParameters(sideBandsInt,-10.,5); break; case 3: if(ftypeOfFit4Sgn==0){ //in principle it doesn't have effects funcbkg->SetParNames("Const"); funcbkg->SetParameter(0,0.); funcbkg->FixParameter(0,0.); } break; default: cout<<"Wrong choise of ftypeOfFit4Bkg ("<Fit("funcbkg","R,L,E,0"); for(Int_t i=0;iGetParameter(i); //cout<GetParameter(i)<<"\t"; fFitPars[nFitPars+2*bkgPar+3+i]= funcbkg->GetParError(i); //cout<GetParError(i)<GetParameter(0); if(ftypeOfFit4Bkg!=3) slope1 = funcbkg->GetParameter(1); if(ftypeOfFit4Bkg==2) conc1 = funcbkg->GetParameter(2); cout<<"Primo fit: \nintbkg1 = "<SetLineColor(2); //red if(ftypeOfFit4Bkg==2){ cout<<"*** Polynomial Fit ***"<SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Coef1","Coef2"); funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1,conc1); // cout<<"Parameters set to: "<<0.5*(totInt-intbkg1)<<"\t"<SetParNames("IntGB","MeanGB","SigmaGB","Const"); funcbkg1->SetParameters(0.5*totInt,fMass,ffactor*fSigmaSgn,0.); funcbkg1->FixParameter(3,0.); } else{ //expo or linear if(ftypeOfFit4Bkg==0) cout<<"*** Exponential Fit ***"<SetParNames("IntGB","MeanGB","SigmaGB","BkgInt","Slope"); funcbkg1->SetParameters(0.5*(totInt-intbkg1),fMass,ffactor*fSigmaSgn,intbkg1,slope1); } } fhistoInvMass->Fit("funcbkg1","R,L,E,+,0"); for(Int_t i=0;iGetParameter(i); //cout<GetParameter(i); fFitPars[nFitPars+3*bkgPar-6+i]= funcbkg1->GetParError(i); //cout<<"\t"<GetParError(i)<GetParameter(3); if(ftypeOfFit4Bkg!=3) slope1 = funcbkg1->GetParameter(4); if(ftypeOfFit4Bkg==2) conc1 = funcbkg1->GetParameter(5); } else { bkgPar+=3; for(Int_t i=0;i<3;i++){ fFitPars[bkgPar-3+i]=0.; //cout<GetParameter(i); //cout<GetParameter(i)<<"\t"; fFitPars[nFitPars+3*bkgPar-3+i]= funcbkg->GetParError(i); //cout<GetParError(i)<Integral(fminMass,fmaxMass); else bkgInt=funcbkg->Integral(fminMass,fmaxMass); cout<<"------BkgInt(Fit) = "<SetLineColor(4); //blue //Set parameters cout<<"\nTOTAL FIT"<SetParNames("TotInt","Slope","SgnInt","Mean","Sigma"); funcmass->SetParameters(totInt,slope1,sgnInt,fMass,fSigmaSgn); // cout<<"Parameters set to: "<SetParameters(totInt,slope1,conc1,sgnInt,fMass,fSigmaSgn); // cout<<"Parameters set to: "<SetParameters(0.,0.5*totInt,fMass,fSigmaSgn); funcmass->FixParameter(0,0.); //cout<<"Parameters set to: "<<0.5*totInt<<"\t"<GetParameter(i); fFitPars[nFitPars+4*bkgPar-6+i]= funcmass->GetParError(i); cout<GetParameter(i)<<"\t\t"<GetParError(i)<GetName()); TH1F *fhistocopy=new TH1F(*fhistoInvMass); canvas->cd(); fhistocopy->Draw(); if(ftypeOfFit4Sgn == 1) { cout<<"funcbkg1 "<Draw("sames"); } else { cout<<"funcbkg "<Draw("sames"); } cout<<"funcmass "<Draw("sames"); cout<<"Drawn"<SetBranchAddress("intbkg1",&fFitPars[0]); fntuParam->SetBranchAddress("slope1",&fFitPars[1]); fntuParam->SetBranchAddress("conc1",&fFitPars[2]); fntuParam->SetBranchAddress("intGB",&fFitPars[3]); fntuParam->SetBranchAddress("meanGB",&fFitPars[4]); fntuParam->SetBranchAddress("sigmaGB",&fFitPars[5]); fntuParam->SetBranchAddress("intbkg2",&fFitPars[6]); fntuParam->SetBranchAddress("slope2",&fFitPars[7]); fntuParam->SetBranchAddress("conc2",&fFitPars[8]); fntuParam->SetBranchAddress("inttot",&fFitPars[9]); fntuParam->SetBranchAddress("slope3",&fFitPars[10]); fntuParam->SetBranchAddress("conc3",&fFitPars[11]); fntuParam->SetBranchAddress("intsgn",&fFitPars[12]); fntuParam->SetBranchAddress("meansgn",&fFitPars[13]); fntuParam->SetBranchAddress("sigmasgn",&fFitPars[14]); fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[15]); fntuParam->SetBranchAddress("slope1Err",&fFitPars[16]); fntuParam->SetBranchAddress("conc1Err",&fFitPars[17]); fntuParam->SetBranchAddress("intGBErr",&fFitPars[18]); fntuParam->SetBranchAddress("meanGBErr",&fFitPars[19]); fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[20]); fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[21]); fntuParam->SetBranchAddress("slope2Err",&fFitPars[22]); fntuParam->SetBranchAddress("conc2Err",&fFitPars[23]); fntuParam->SetBranchAddress("inttotErr",&fFitPars[24]); fntuParam->SetBranchAddress("slope3Err",&fFitPars[25]); fntuParam->SetBranchAddress("conc3Err",&fFitPars[26]); fntuParam->SetBranchAddress("intsgnErr",&fFitPars[27]); fntuParam->SetBranchAddress("meansgnErr",&fFitPars[28]); fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[29]); } else { if(ftypeOfFit4Bkg==3){ fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]); fntuParam->SetBranchAddress("slope1",¬hing); fntuParam->SetBranchAddress("conc1",¬hing); fntuParam->SetBranchAddress("intGB",&fFitPars[1]); fntuParam->SetBranchAddress("meanGB",&fFitPars[2]); fntuParam->SetBranchAddress("sigmaGB",&fFitPars[3]); fntuParam->SetBranchAddress("intbkg2",&fFitPars[4]); fntuParam->SetBranchAddress("slope2",¬hing); fntuParam->SetBranchAddress("conc2",¬hing); fntuParam->SetBranchAddress("inttot",&fFitPars[6]); fntuParam->SetBranchAddress("slope3",¬hing); fntuParam->SetBranchAddress("conc3",¬hing); fntuParam->SetBranchAddress("intsgn",&fFitPars[6]); fntuParam->SetBranchAddress("meansgn",&fFitPars[7]); fntuParam->SetBranchAddress("sigmasgn",&fFitPars[8]); fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[9]); fntuParam->SetBranchAddress("slope1Err",¬hing); fntuParam->SetBranchAddress("conc1Err",¬hing); fntuParam->SetBranchAddress("intGBErr",&fFitPars[10]); fntuParam->SetBranchAddress("meanGBErr",&fFitPars[11]); fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[12]); fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[13]); fntuParam->SetBranchAddress("slope2Err",¬hing); fntuParam->SetBranchAddress("conc2Err",¬hing); fntuParam->SetBranchAddress("inttotErr",&fFitPars[15]); fntuParam->SetBranchAddress("slope3Err",¬hing); fntuParam->SetBranchAddress("conc3Err",¬hing); fntuParam->SetBranchAddress("intsgnErr",&fFitPars[15]); fntuParam->SetBranchAddress("meansgnErr",&fFitPars[16]); fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[17]); } else{ fntuParam->SetBranchAddress("intbkg1",&fFitPars[0]); fntuParam->SetBranchAddress("slope1",&fFitPars[1]); fntuParam->SetBranchAddress("conc1",¬hing); fntuParam->SetBranchAddress("intGB",&fFitPars[2]); fntuParam->SetBranchAddress("meanGB",&fFitPars[3]); fntuParam->SetBranchAddress("sigmaGB",&fFitPars[4]); fntuParam->SetBranchAddress("intbkg2",&fFitPars[5]); fntuParam->SetBranchAddress("slope2",&fFitPars[6]); fntuParam->SetBranchAddress("conc2",¬hing); fntuParam->SetBranchAddress("inttot",&fFitPars[7]); fntuParam->SetBranchAddress("slope3",&fFitPars[8]); fntuParam->SetBranchAddress("conc3",¬hing); fntuParam->SetBranchAddress("intsgn",&fFitPars[9]); fntuParam->SetBranchAddress("meansgn",&fFitPars[10]); fntuParam->SetBranchAddress("sigmasgn",&fFitPars[11]); fntuParam->SetBranchAddress("intbkg1Err",&fFitPars[12]); fntuParam->SetBranchAddress("slope1Err",&fFitPars[13]); fntuParam->SetBranchAddress("conc1Err",¬hing); fntuParam->SetBranchAddress("intGBErr",&fFitPars[14]); fntuParam->SetBranchAddress("meanGBErr",&fFitPars[15]); fntuParam->SetBranchAddress("sigmaGBErr",&fFitPars[16]); fntuParam->SetBranchAddress("intbkg2Err",&fFitPars[17]); fntuParam->SetBranchAddress("slope2Err",&fFitPars[18]); fntuParam->SetBranchAddress("conc2Err",¬hing); fntuParam->SetBranchAddress("inttotErr",&fFitPars[19]); fntuParam->SetBranchAddress("slope3Err",&fFitPars[20]); fntuParam->SetBranchAddress("conc3Err",¬hing); fntuParam->SetBranchAddress("intsgnErr",&fFitPars[21]); fntuParam->SetBranchAddress("meansgnErr",&fFitPars[22]); fntuParam->SetBranchAddress("sigmasgnErr",&fFitPars[23]); } } fntuParam->TTree::Fill(); } //_________________________________________________________________________ TNtuple* AliHFMassFitter::NtuParamOneShot(char *ntuname){ // Create, fill and return ntuple with fit parameters InitNtuParam(ntuname); FillNtuParam(); return fntuParam; } //_________________________________________________________________________ void AliHFMassFitter::RebinMass(Int_t bingroup){ // Rebin invariant mass histogram if(bingroup<1){ cout<<"Error! Cannot group "<GetNbinsX(); cout<<"Kept original number of bins: "<Rebin(bingroup); fNbin = fhistoInvMass->GetNbinsX(); cout<<"New number of bins: "<GetFunction("funcmass"); Double_t mean=0,sigma=1; Double_t intS,intSerr; if(ftypeOfFit4Bkg == 2) { //polynomial mean=funcmass->GetParameter(4); //mean sigma=funcmass->GetParameter(5); //sigma intS=fFitPars[12]; intSerr=fFitPars[27]; } else if(ftypeOfFit4Bkg == 3){ //no background mean=funcmass->GetParameter(2); //mean sigma=funcmass->GetParameter(3); //sigma intS=fFitPars[6]; intSerr=fFitPars[15]; } else { //expo or linear mean=funcmass->GetParameter(3); //mean sigma=funcmass->GetParameter(4); //sigma intS=fFitPars[9]; intSerr=fFitPars[21]; } TF1 *funcbkg=0; if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction("funcbkg"); else funcbkg=fhistoInvMass->GetFunction("funcbkg1"); Double_t min=mean-nOfSigma*sigma; Double_t max=mean+nOfSigma*sigma; signal=(funcmass->Integral(min,max)-funcbkg->Integral(min,max))/(Double_t)fhistoInvMass->GetBinWidth(2); errsignal=intSerr/intS*signal; // assume relative error is the same as for total integral return; } //_________________________________________________________________________ void AliHFMassFitter::Background(Double_t nOfSigma,Double_t &background,Double_t &errbackground) const { // Return background integral in mean+- n sigma TF1 *funcmass=fhistoInvMass->GetFunction("funcmass"); Double_t mean=0,sigma=1; Double_t intB,intBerr,err; if(ftypeOfFit4Bkg == 2) { //polynomial mean=funcmass->GetParameter(4); //mean sigma=funcmass->GetParameter(5); //sigma intB=fFitPars[9]-fFitPars[12]; intBerr=fFitPars[27]; } else if(ftypeOfFit4Bkg == 3){ //no background mean=funcmass->GetParameter(2); //mean sigma=funcmass->GetParameter(3); //sigma if (ftypeOfFit4Sgn == 1){ //reflection intB=fFitPars[1]; intBerr=fFitPars[9]; } else { intB=-1;intBerr=-1; err=0; } } else { //expo or linear mean=funcmass->GetParameter(3); //mean sigma=funcmass->GetParameter(4); //sigma intB=fFitPars[7]-fFitPars[9]; intBerr=fFitPars[21]; } TF1 *funcbkg=0; if(ftypeOfFit4Sgn == 0) funcbkg=fhistoInvMass->GetFunction("funcbkg"); else funcbkg=fhistoInvMass->GetFunction("funcbkg1"); Double_t min=mean-nOfSigma*sigma; Double_t max=mean+nOfSigma*sigma; background=funcbkg->Integral(min,max)/(Double_t)fhistoInvMass->GetBinWidth(2); errbackground=intBerr/intB*background; return; } //__________________________________________________________________________ void AliHFMassFitter::Significance(Double_t nOfSigma,Double_t &significance,Double_t &errsignificance) const { // Return significance in mean+- n sigma Double_t signal,errsignal,background,errbackground; Signal(nOfSigma,signal,errsignal); Background(nOfSigma,background,errbackground); significance = signal/TMath::Sqrt(signal+background); errsignificance = TMath::Sqrt(significance*significance/(signal+background)/(signal+background)*(1/4.*errsignal*errsignal+errbackground*errbackground)+significance*significance/signal/signal*errsignal*errsignal); return; } //__________________________________________________________________________