19 #include <TVirtualFitter.h>
20 #include <TDatabasePDG.h>
23 #include <TPaveText.h>
54 fTypeOfFit4Bkg(
kExpo),
58 fTypeOfFit4Sgn(
kGaus),
68 fOnlySideBands(kFALSE),
69 fNSigma4SideBands(4.),
80 fFixRflOverSig(kFALSE),
104 fTypeOfFit4Bkg(fittypeb),
106 fCurPolDegreeBkg(-1),
107 fMassParticle(1.864),
108 fTypeOfFit4Sgn(fittypes),
118 fOnlySideBands(kFALSE),
119 fNSigma4SideBands(4.),
127 fReflections(kFALSE),
130 fFixRflOverSig(kFALSE),
141 fFixSecWidth(kFALSE),
195 AliError(
"Error in computing fNParsBkg: check fTypeOfFit4Bkg");
207 AliError(
"Error in computing fNParsSig: check fTypeOfFit4Sgn");
223 TVirtualFitter::SetDefaultFitter(
"Minuit");
230 printf(
"\n--- First fit with only background on the side bands - Exclusion region = %.2f sigma ---\n",
fNSigma4SideBands);
241 printf(
" ---> Failed first fit with only background, minuit status = %d\n",status);
252 printf(
"\n--- Estimate signal counts in the peak region ---\n");
259 printf(
"\n--- Final fit with signal+background on the full range ---\n");
268 printf(
" ---> Final fit includes a second inv. mass peak\n");
273 printf(
" ---> Final fit includes reflections\n");
280 printf(
" ---> Failed fit with signal+background, minuit status = %d\n",status);
293 fSecFunc->SetParameter(ipar,
fTotFunc->GetParameter(ipar+fNParsBkg+fNParsSig));
294 fSecFunc->SetParError(ipar,
fTotFunc->GetParError(ipar+fNParsBkg+fNParsSig));
330 TCanvas* c0=
new TCanvas(
"c0");
338 gStyle->SetOptStat(0);
339 gStyle->SetCanvasColor(0);
340 gStyle->SetFrameFillColor(0);
353 if(writeFitInfo > 0){
354 TPaveText *pinfos=
new TPaveText(0.12,0.65,0.47,0.89,
"NDC");
355 TPaveText *pinfom=
new TPaveText(0.6,0.7,1.,.87,
"NDC");
356 pinfos->SetBorderSize(0);
357 pinfos->SetFillStyle(0);
358 pinfom->SetBorderSize(0);
359 pinfom->SetFillStyle(0);
361 pinfom->SetTextColor(kBlue);
373 pinfos->AddText(Form(
"B (%.0f#sigma) = %.0f #pm %.0f",nsigma,bkg,errbkg));
374 pinfos->AddText(Form(
"S/B = (%.0f#sigma) %.4f ",nsigma,
fRawYield/bkg));
376 pinfos->AddText(Form(
"Signif (%.0f#sigma) = %.1f #pm %.1f ",nsigma,signif,errsignif));
395 for(
Int_t ibin=binForMinSig; ibin<=binForMaxSig; ibin++){
399 Double_t diffUnderPeak=(sum-sumback);
400 printf(
" ---> IntegralUnderFitFunc=%f IntegralUnderHisto=%f EstimatedSignal=%f\n",sum,sumback,diffUnderPeak);
401 if(diffUnderPeak/TMath::Sqrt(sum)<1.){
402 printf(
" ---> (Tot-Bkg)/sqrt(Tot)=%f ---> Likely no signal/\n",diffUnderPeak/TMath::Sqrt(sum));
417 funcbkg->SetParNames(
"BkgInt",
"Slope");
418 funcbkg->SetParameters(integral,-2.);
421 funcbkg->SetParNames(
"BkgInt",
"Slope");
422 funcbkg->SetParameters(integral,-100.);
425 funcbkg->SetParNames(
"BkgInt",
"Coef1",
"Coef2");
426 funcbkg->SetParameters(integral,-10.,5);
429 funcbkg->SetParNames(
"Const");
430 funcbkg->SetParameter(0,0.);
431 funcbkg->FixParameter(0,0.);
434 funcbkg->SetParNames(
"BkgInt",
"Coef1");
435 funcbkg->SetParameters(integral,0.5);
438 funcbkg->SetParNames(
"BkgInt",
"Coef1",
"Coef2");
439 funcbkg->SetParameters(integral,-10.,5.);
443 funcbkg->SetParName(j,Form(
"Coef%d",j));
444 funcbkg->SetParameter(j,0);
446 funcbkg->SetParameter(0,integral);
449 AliError(Form(
"Wrong choice of fTypeOfFit4Bkg (%d)",
fTypeOfFit4Bkg));
454 funcbkg->SetLineColor(kBlue+3);
463 funcsec->SetParameter(0,integsig);
468 funcsec->SetParNames(
"SecPeakInt",
"SecMean",
"SecSigma");
477 funcrfl->SetParLimits(0,0.,1.);
479 funcrfl->SetParNames(
"ReflOverS");
490 fbr->SetParameter(ipar,
fBkgFunc->GetParameter(ipar));
491 fbr->SetParName(ipar,
fBkgFunc->GetParName(ipar));
494 fbr->SetParameter(ipar+fNParsBkg,
fRflFunc->GetParameter(ipar));
495 fbr->SetParName(ipar+fNParsBkg,
fRflFunc->GetParName(ipar));
508 funcsig->SetParameter(0,integsig);
510 funcsig->SetParameter(1,
fMass);
514 funcsig->SetParNames(
"SgnInt",
"Mean",
"Sigma");
517 funcsig->SetParameter(0,integsig);
519 funcsig->SetParameter(1,
fMass);
522 funcsig->SetParLimits(2,0.004,0.05);
524 funcsig->SetParameter(3,0.2);
525 funcsig->SetParLimits(3,0.,1.);
527 funcsig->SetParLimits(4,0.004,0.05);
528 funcsig->SetParNames(
"SgnInt",
"Mean",
"Sigma1",
"Frac",
"Sigma2");
542 ftot->SetParameter(ipar,
fBkgFunc->GetParameter(ipar));
543 ftot->SetParName(ipar,
fBkgFunc->GetParName(ipar));
546 ftot->SetParameter(ipar+fNParsBkg,
fSigFunc->GetParameter(ipar));
547 ftot->SetParName(ipar+fNParsBkg,
fSigFunc->GetParName(ipar));
549 fSigFunc->GetParLimits(ipar,parmin,parmax);
550 ftot->SetParLimits(ipar+fNParsBkg,parmin,parmax);
554 ftot->SetParameter(ipar+fNParsBkg+fNParsSig,
fSecFunc->GetParameter(ipar));
555 ftot->SetParName(ipar+fNParsBkg+fNParsSig,
fSecFunc->GetParName(ipar));
557 fSecFunc->GetParLimits(ipar,parmin,parmax);
558 ftot->SetParLimits(ipar+fNParsBkg+fNParsSig,parmin,parmax);
563 ftot->SetParameter(ipar+fNParsBkg+fNParsSig+
fNParsSec,
fRflFunc->GetParameter(ipar));
566 fRflFunc->GetParLimits(ipar,parmin,parmax);
567 ftot->SetParLimits(ipar+fNParsBkg+fNParsSig+
fNParsSec,parmin,parmax);
598 total = par[0]*par[1]/(TMath::Exp(par[1]*
fMaxMass)-TMath::Exp(par[1]*
fMinMass))*TMath::Exp(par[1]*x[0]);
606 total= par[0]/(fMaxMass-
fMinMass)+par[1]*(x[0]-0.5*(fMaxMass+fMinMass));
617 total = par[0]/(fMaxMass-
fMinMass)+par[1]*(x[0]-0.5*(fMaxMass+fMinMass))+par[2]*(x[0]*x[0]-1/3.*(fMaxMass*fMaxMass*fMaxMass-fMinMass*fMinMass*fMinMass)/(fMaxMass-
fMinMass));
632 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
634 total = par[0]*(par[1]+1.)/(TMath::Power(fMaxMass-mpi,par[1]+1.)-TMath::Power(fMinMass-mpi,par[1]+1.))*TMath::Power(x[0]-mpi,par[1]);
642 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
644 total = par[1]*TMath::Sqrt(x[0] - mpi)*TMath::Exp(-1.*par[2]*(x[0]-mpi));
661 total+=par[it]*TMath::Power(x[0]-
fMassParticle,it)/TMath::Factorial(it);
683 sigval=par[0]/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[2]/par[2]);
694 Double_t g1=(1.-par[3])/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[2]/par[2]);
695 Double_t g2=par[3]/TMath::Sqrt(2.*TMath::Pi())/par[4]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[4]/par[4]);
696 sigval=par[0]*(g1+g2);
738 Double_t secgaval=par[0]/TMath::Sqrt(2.*TMath::Pi())/par[2]*TMath::Exp(-(x[0]-par[1])*(x[0]-par[1])/2./par[2]/par[2]);
752 return bkg+sig+sec+refl;
762 Signal(minMass,maxMass,signal,errsignal);
783 Background(minMass,maxMass,background,errbackground);
796 AliError(
"Bkg function not found!");
800 Double_t intB=funcbkg->GetParameter(0);
801 Double_t intBerr=funcbkg->GetParError(0);
809 for(
Int_t i=1;i<=leftBand;i++){
816 intBerr=TMath::Sqrt(sum2);
819 errbackground=intBerr/intB*background;
832 Significance(minMass, maxMass, significance, errsignificance);
866 TF1 *funcbkg,*funcPrev=0x0;
871 funcbkg->SetParameter(j,funcPrev->GetParameter(j));
876 funcbkg->SetParameter(0,estimatecent);
877 funcbkg->SetParameter(1,estimateslope);
879 printf(
" ---> Pre-fit of background with pol degree %d ---\n",
fCurPolDegreeBkg);
880 hCp->Fit(funcbkg,
"REMN",
"");
881 funcPrev=(TF1*)funcbkg->Clone(
"ftemp");
887 fback->SetParameter(j,funcPrev->GetParameter(j));
888 fback->SetParError(j,funcPrev->GetParError(j));
890 printf(
" ---> Final background fit with pol degree %d ---\n",
fPolDegreeBkg);
891 hCp->Fit(fback,
"REMN",
"");
919 back+=par[it]*TMath::Power(x[0]-
fMassParticle,it)/TMath::Factorial(it);
940 printf(
"\n--- Reflection templates from simulation ---\n");
941 if(opt.Contains(
"templ")){
942 printf(
" ---> Reflection contribution using directly the histogram from simulation\n");
948 Double_t xMinForFit=h->GetBinLowEdge(1);
949 Double_t xMaxForFit=h->GetXaxis()->GetBinUpEdge(h->GetNbinsX());
950 if(minRange>=0 && maxRange>=0){
951 xMinForFit=TMath::Max(minRange,h->GetBinLowEdge(1));
952 xMaxForFit=TMath::Min(maxRange,h->GetXaxis()->GetBinUpEdge(h->GetNbinsX()));
954 if(opt.EqualTo(
"1gaus") || opt.EqualTo(
"singlegaus")){
955 printf(
" ---> Reflection contribution from single-Gaussian fit to histogram from simulation\n");
956 f=
new TF1(
"mygaus",
"gaus",xMinForFit,xMaxForFit);
957 f->SetParameter(0,h->GetMaximum());
959 f->SetParameter(1,1.865);
960 f->SetParameter(2,0.050);
963 else if(opt.EqualTo(
"2gaus") || opt.EqualTo(
"doublegaus")){
964 printf(
" ---> Reflection contribution from double-Gaussian fit to histogram from simulation\n");
965 f=
new TF1(
"my2gaus",
"[0]*([3]/( TMath::Sqrt(2.*TMath::Pi())*[2])*TMath::Exp(-(x-[1])*(x-[1])/(2.*[2]*[2]))+(1.-[3])/( TMath::Sqrt(2.*TMath::Pi())*[5])*TMath::Exp(-(x-[4])*(x-[4])/(2.*[5]*[5])))",xMinForFit,xMaxForFit);
966 f->SetParameter(0,h->GetMaximum());
968 f->SetParLimits(3,0.,1.);
969 f->SetParameter(3,0.5);
970 f->SetParameter(1,1.84);
971 f->SetParameter(2,0.050);
972 f->SetParameter(4,1.88);
973 f->SetParameter(5,0.050);
976 else if(opt.EqualTo(
"pol3")){
977 printf(
" ---> Reflection contribution from pol3 fit to histogram from simulation\n");
978 f=
new TF1(
"mypol3",
"pol3",xMinForFit,xMaxForFit);
979 f->SetParameter(0,h->GetMaximum());
985 else if(opt.EqualTo(
"pol6")){
986 printf(
" ---> Reflection contribution from pol6 fit to histogram from simulation\n");
987 f=
new TF1(
"mypol6",
"pol6",xMinForFit,xMaxForFit);
988 f->SetParameter(0,h->GetMaximum());
995 printf(
" ---> Bad option for reflection configuration -> reflections will not be included in the fit\n");
1006 if(
fHistoTemplRfl->GetBinContent(j)>=0.&&TMath::Abs(h->GetBinError(j)*h->GetBinError(j)-h->GetBinContent(j))>0.1*h->GetBinContent(j))isPoissErr=kFALSE;
1017 printf(
" ---> Fit to MC template for reflection failed -> reflections will not be included in the fit\n");
1043 printf(
"Left range for bin counting smaller than allowed by histogram axis, setting it to the lower edge of the first histo bin\n");
1047 printf(
"Right range for bin counting larger than allowed by histogram axis, setting it to the upper edge of the last histo bin\n");
1055 if(!fbackground)
return 0.;
1057 for(
Int_t jb=minBinSum; jb<=maxBinSum; jb++){
1061 cntSig+=(cntTot-cntBkg);
1064 errRyBC=TMath::Sqrt(cntErr);
1076 if(maxrange>minrange){
1083 hResidualTrend->SetName(Form(
"%s_residualTrend",
fHistoInvMass->GetName()));
1084 hResidualTrend->SetTitle(Form(
"%s (Residuals)",
fHistoInvMass->GetTitle()));
1085 hResidualTrend->SetMarkerStyle(20);
1086 hResidualTrend->SetMarkerSize(1.0);
1087 hResidualTrend->Reset();
1091 hPullsTrend->Reset();
1092 hPullsTrend->SetName(Form(
"%s_pullTrend",
fHistoInvMass->GetName()));
1093 hPullsTrend->SetTitle(Form(
"%s (Pulls)",
fHistoInvMass->GetTitle()));
1094 hPullsTrend->SetMarkerStyle(20);
1095 hPullsTrend->SetMarkerSize(1.0);
1099 hPulls->SetTitle(Form(
"%s ; Pulls",
fHistoInvMass->GetTitle()));
1100 hPulls->SetBins(40,-10,10);
1104 Double_t res=-1.e-6,min=1.e+12,max=-1.e+12;
1109 if(jst>=binmi&&jst<=binma){
1110 arval->AddAt(res,jst-binmi);
1116 hResidualTrend->SetBinContent(jst,res);
1117 hResidualTrend->SetBinError(jst,
fHistoInvMass->GetBinError(jst));
1120 if(jst>=binmi&&jst<=binma)hPulls->Fill(res/
fHistoInvMass->GetBinError(jst));
1123 hPullsTrend->SetBinContent(jst,res/
fHistoInvMass->GetBinError(jst));
1124 hPullsTrend->SetBinError(jst,0.0001);
1127 if(hResidualTrend)hResidualTrend->GetXaxis()->SetRange(binmi,binma);
1129 hPullsTrend->GetXaxis()->SetRange(binmi,binma);
1130 hPullsTrend->SetMinimum(-7);
1131 hPullsTrend->SetMaximum(+7);
1133 if(TMath::Abs(min)>TMath::Abs(max))max=min;
1135 TH1F *hout=
new TH1F(Form(
"%s_residuals",
fHistoInvMass->GetName()),Form(
"%s ; residuals",
fHistoInvMass->GetTitle()),25,-TMath::Abs(max)*1.5,TMath::Abs(max)*1.5);
1136 for(
Int_t j=0;j<binma-binmi+1;j++){
1137 hout->Fill(arval->At(j));
1140 hout->Fit(
"gaus",
"LEM",
"",-TMath::Abs(max)*1.2,TMath::Abs(max)*1.2);
1144 hPulls->Fit(
"gaus",
"LEM",
"",-3,3);
1154 printf(
"--- Background function in 1st step fit to side bands ---\n");
1158 printf(
"--- Total fit function from 2nd step fit ---\n");
1162 printf(
"--- Background function in 2nd step fit ---\n");
1166 printf(
"--- Reflections ---\n");
1170 printf(
"--- Background + reflections ---\n");
1174 printf(
"--- Additional Gaussian peak ---\n");
Int_t fTypeOfFit4Sgn
pdg value of particle mass
Double_t fSigmaSgnErr
signal gaussian sigma
Bool_t fFixSecWidth
flag to fix the position of the 2nd peak
Double_t fRawYieldHelp
switch for smoothing of reflection template
Double_t fRawYield
L, LW or Chi2.
void DrawHere(TVirtualPad *c, Double_t nsigma=3, Int_t writeFitInfo=1)
TF1 * CreateReflectionFunction(TString fname)
Int_t fCurPolDegreeBkg
degree of polynomial expansion for back fit (option 6 for back)
Bool_t PrepareHighPolFit(TF1 *fback)
Bool_t fOnlySideBands
fit parameters in background fit function
virtual void Signal(Double_t nOfSigma, Double_t &signal, Double_t &errsignal) const
Double_t FitFunction4SecPeak(Double_t *x, Double_t *par)
Double_t fMass
signal fit func
TF1 * CreateTotalFitFunction(TString fname)
Double_t fRawYieldErr
signal gaussian integral
Int_t fNParsBkg
fit parameters in signal fit function
AliHFInvMassFitter class for the fit of invariant mass distribution of charm hadrons.
Int_t fNParsRfl
flag use/not use reflections
TF1 * CreateSecondPeakFunction(TString fname, Double_t integral)
TF1 * fTotFunc
fit function for second peak
Double_t fFixedRawYield
switch for fix Sigma of gaussian
Double_t FitFunction4Bkg(Double_t *x, Double_t *par)
Double_t fSigmaSgn
unc on signal gaussian mean value
Double_t fSecMass
fit parameters in 2nd peak fit function
Bool_t fFixSecMass
width of the 2nd peak
TF1 * fSecFunc
flag to fix the width of the 2nd peak
TH1F * GetResidualsAndPulls(TH1 *hPulls=0x0, TH1 *hResidualTrend=0x0, TH1 *hPullsTrend=0x0, Double_t minrange=0, Double_t maxrange=-1)
Double_t fSecWidth
position of the 2nd peak
TString fFitOption
number of sigmas to veto the signal peak
TF1 * fBkRFunc
fit function for reflections
Int_t fNParsSec
switch off/on second peak (for D+->KKpi in Ds)
TF1 * CreateSignalFitFunction(TString fname, Double_t integral)
Bool_t fFixedMean
unc on signal gaussian sigma
Double_t fMassParticle
help variable
Double_t FitFunction4Refl(Double_t *x, Double_t *par)
TH1F * SetTemplateReflections(const TH1 *h, TString opt, Double_t minRange, Double_t maxRange)
Int_t fTypeOfFit4Bkg
upper mass limit
TH1F * fHistoTemplRfl
switch for fix refl/signal
TF1 * fBkgFunc
background fit function (1st step, side bands only)
Double_t fMassErr
signal gaussian mean value
Double_t fRflOverSig
fit parameters in reflection fit function
Double_t fMinMass
histogram to fit
Bool_t fFixRflOverSig
reflection/signal
static void ComputeSignificance(Double_t signal, Double_t errsignal, Double_t background, Double_t errbackground, Double_t &significance, Double_t &errsignificance)
Significance calculator.
Double_t FitFunction4Mass(Double_t *x, Double_t *par)
void Significance(Double_t nOfSigma, Double_t &significance, Double_t &errsignificance) const
Double_t BackFitFuncPolHelper(Double_t *x, Double_t *par)
Bool_t MassFitter(Bool_t draw=kTRUE)
Double_t fMaxMass
lower mass limit
TF1 * CreateBackgroundFitFunction(TString fname, Double_t integral)
TF1 * fRflFunc
internal variable for fit with reflections
ClassImp(AliAnalysisTaskCRC) AliAnalysisTaskCRC
Double_t fNSigma4SideBands
kTRUE = only side bands considered
void Background(Double_t nOfSigma, Double_t &background, Double_t &errbackground) const
Double_t FitFunction4Sgn(Double_t *x, Double_t *par)
Int_t fPolDegreeBkg
background fit func
TF1 * fBkgFuncRefit
background fit function (1st step, extended in peak region)
Double_t CheckForSignal(Double_t mean, Double_t sigma)
TF1 * fSigFunc
err on signal gaussian integral
TF1 * fBkgFuncSb
Signal fit function.
Bool_t fSecondPeak
fit function for reflections
Bool_t fSmoothRfl
histogram with reflection template
Double_t GetRawYieldBinCounting(Double_t &errRyBC, Double_t nSigma=3., Int_t option=0) const
TF1 * CreateBackgroundPlusReflectionFunction(TString fname)
Double_t FitFunction4BkgAndRefl(Double_t *x, Double_t *par)
Int_t fNParsSig
initialization for wa yield
Bool_t fReflections
background fit function (2nd step)
Bool_t fFixedSigma
switch for fix mean of gaussian