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");
225 TVirtualFitter::SetDefaultFitter(
"Minuit");
232 printf(
"\n--- First fit with only background on the side bands - Exclusion region = %.2f sigma ---\n",
fNSigma4SideBands);
243 printf(
" ---> Failed first fit with only background, minuit status = %d\n",status);
254 printf(
"\n--- Estimate signal counts in the peak region ---\n");
271 printf(
" ---> Final fit includes a second inv. mass peak\n");
276 printf(
" ---> Final fit includes reflections\n");
283 printf(
"\n--- Final fit with signal+background on the full range ---\n");
286 printf(
" ---> Failed fit with signal+background, minuit status = %d\n",status);
301 fSecFunc->SetParameter(ipar,
fTotFunc->GetParameter(ipar+fNParsBkg+fNParsSig));
302 fSecFunc->SetParError(ipar,
fTotFunc->GetParError(ipar+fNParsBkg+fNParsSig));
331 if(doFinalFit)
return 1;
339 TCanvas* c0=
new TCanvas(
"c0");
347 gStyle->SetOptStat(0);
348 gStyle->SetCanvasColor(0);
349 gStyle->SetFrameFillColor(0);
362 if(writeFitInfo > 0){
363 TPaveText *pinfos=
new TPaveText(0.12,0.65,0.47,0.89,
"NDC");
364 TPaveText *pinfom=
new TPaveText(0.6,0.7,1.,.87,
"NDC");
365 pinfos->SetBorderSize(0);
366 pinfos->SetFillStyle(0);
367 pinfom->SetBorderSize(0);
368 pinfom->SetFillStyle(0);
370 pinfom->SetTextColor(kBlue);
382 pinfos->AddText(Form(
"B (%.0f#sigma) = %.0f #pm %.0f",nsigma,bkg,errbkg));
383 pinfos->AddText(Form(
"S/B = (%.0f#sigma) %.4f ",nsigma,
fRawYield/bkg));
385 pinfos->AddText(Form(
"Signif (%.0f#sigma) = %.1f #pm %.1f ",nsigma,signif,errsignif));
404 for(
Int_t ibin=binForMinSig; ibin<=binForMaxSig; ibin++){
408 Double_t diffUnderPeak=(sum-sumback);
409 printf(
" ---> IntegralUnderFitFunc=%f IntegralUnderHisto=%f EstimatedSignal=%f\n",sum,sumback,diffUnderPeak);
410 if(diffUnderPeak/TMath::Sqrt(sum)<1.){
411 printf(
" ---> (Tot-Bkg)/sqrt(Tot)=%f ---> Likely no signal/\n",diffUnderPeak/TMath::Sqrt(sum));
426 funcbkg->SetParNames(
"BkgInt",
"Slope");
427 funcbkg->SetParameters(integral,-2.);
430 funcbkg->SetParNames(
"BkgInt",
"Slope");
431 funcbkg->SetParameters(integral,-100.);
434 funcbkg->SetParNames(
"BkgInt",
"Coef1",
"Coef2");
435 funcbkg->SetParameters(integral,-10.,5);
438 funcbkg->SetParNames(
"Const");
439 funcbkg->SetParameter(0,0.);
440 funcbkg->FixParameter(0,0.);
443 funcbkg->SetParNames(
"BkgInt",
"Coef1");
444 funcbkg->SetParameters(integral,0.5);
447 funcbkg->SetParNames(
"BkgInt",
"Coef1",
"Coef2");
448 funcbkg->SetParameters(integral,-10.,5.);
452 funcbkg->SetParName(j,Form(
"Coef%d",j));
453 funcbkg->SetParameter(j,0);
455 funcbkg->SetParameter(0,integral);
458 AliError(Form(
"Wrong choice of fTypeOfFit4Bkg (%d)",
fTypeOfFit4Bkg));
463 funcbkg->SetLineColor(kBlue+3);
472 funcsec->SetParameter(0,integsig);
477 funcsec->SetParNames(
"SecPeakInt",
"SecMean",
"SecSigma");
486 funcrfl->SetParLimits(0,0.,1.);
488 funcrfl->SetParNames(
"ReflOverS");
499 fbr->SetParameter(ipar,
fBkgFunc->GetParameter(ipar));
500 fbr->SetParName(ipar,
fBkgFunc->GetParName(ipar));
503 fbr->SetParameter(ipar+fNParsBkg,
fRflFunc->GetParameter(ipar));
504 fbr->SetParName(ipar+fNParsBkg,
fRflFunc->GetParName(ipar));
517 funcsig->SetParameter(0,integsig);
519 funcsig->SetParameter(1,
fMass);
523 funcsig->SetParNames(
"SgnInt",
"Mean",
"Sigma");
526 funcsig->SetParameter(0,integsig);
528 funcsig->SetParameter(1,
fMass);
531 funcsig->SetParLimits(2,0.004,0.05);
533 funcsig->SetParameter(3,0.2);
534 funcsig->SetParLimits(3,0.,1.);
536 funcsig->SetParLimits(4,0.004,0.05);
537 funcsig->SetParNames(
"SgnInt",
"Mean",
"Sigma1",
"Frac",
"Sigma2");
551 ftot->SetParameter(ipar,
fBkgFunc->GetParameter(ipar));
552 ftot->SetParName(ipar,
fBkgFunc->GetParName(ipar));
555 ftot->SetParameter(ipar+fNParsBkg,
fSigFunc->GetParameter(ipar));
556 ftot->SetParName(ipar+fNParsBkg,
fSigFunc->GetParName(ipar));
558 fSigFunc->GetParLimits(ipar,parmin,parmax);
559 ftot->SetParLimits(ipar+fNParsBkg,parmin,parmax);
563 ftot->SetParameter(ipar+fNParsBkg+fNParsSig,
fSecFunc->GetParameter(ipar));
564 ftot->SetParName(ipar+fNParsBkg+fNParsSig,
fSecFunc->GetParName(ipar));
566 fSecFunc->GetParLimits(ipar,parmin,parmax);
567 ftot->SetParLimits(ipar+fNParsBkg+fNParsSig,parmin,parmax);
572 ftot->SetParameter(ipar+fNParsBkg+fNParsSig+
fNParsSec,
fRflFunc->GetParameter(ipar));
575 fRflFunc->GetParLimits(ipar,parmin,parmax);
576 ftot->SetParLimits(ipar+fNParsBkg+fNParsSig+
fNParsSec,parmin,parmax);
607 total = par[0]*par[1]/(TMath::Exp(par[1]*
fMaxMass)-TMath::Exp(par[1]*
fMinMass))*TMath::Exp(par[1]*x[0]);
615 total= par[0]/(fMaxMass-
fMinMass)+par[1]*(x[0]-0.5*(fMaxMass+fMinMass));
626 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));
641 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
643 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]);
651 Double_t mpi = TDatabasePDG::Instance()->GetParticle(211)->Mass();
653 total = par[1]*TMath::Sqrt(x[0] - mpi)*TMath::Exp(-1.*par[2]*(x[0]-mpi));
670 total+=par[it]*TMath::Power(x[0]-
fMassParticle,it)/TMath::Factorial(it);
692 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]);
703 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]);
704 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]);
705 sigval=par[0]*(g1+g2);
747 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]);
761 return bkg+sig+sec+refl;
771 Signal(minMass,maxMass,signal,errsignal);
792 Background(minMass,maxMass,background,errbackground);
805 AliError(
"Bkg function not found!");
809 Double_t intB=funcbkg->GetParameter(0);
810 Double_t intBerr=funcbkg->GetParError(0);
818 for(
Int_t i=1;i<=leftBand;i++){
825 intBerr=TMath::Sqrt(sum2);
828 errbackground=intBerr/intB*background;
841 Significance(minMass, maxMass, significance, errsignificance);
875 TF1 *funcbkg,*funcPrev=0x0;
880 funcbkg->SetParameter(j,funcPrev->GetParameter(j));
885 funcbkg->SetParameter(0,estimatecent);
886 funcbkg->SetParameter(1,estimateslope);
888 printf(
" ---> Pre-fit of background with pol degree %d ---\n",
fCurPolDegreeBkg);
889 hCp->Fit(funcbkg,
"REMN",
"");
890 funcPrev=(TF1*)funcbkg->Clone(
"ftemp");
896 fback->SetParameter(j,funcPrev->GetParameter(j));
897 fback->SetParError(j,funcPrev->GetParError(j));
899 printf(
" ---> Final background fit with pol degree %d ---\n",
fPolDegreeBkg);
900 hCp->Fit(fback,
"REMN",
"");
928 back+=par[it]*TMath::Power(x[0]-
fMassParticle,it)/TMath::Factorial(it);
949 printf(
"\n--- Reflection templates from simulation ---\n");
950 if(opt.Contains(
"templ")){
951 printf(
" ---> Reflection contribution using directly the histogram from simulation\n");
957 Double_t xMinForFit=h->GetBinLowEdge(1);
958 Double_t xMaxForFit=h->GetXaxis()->GetBinUpEdge(h->GetNbinsX());
959 if(minRange>=0 && maxRange>=0){
960 xMinForFit=TMath::Max(minRange,h->GetBinLowEdge(1));
961 xMaxForFit=TMath::Min(maxRange,h->GetXaxis()->GetBinUpEdge(h->GetNbinsX()));
963 if(opt.EqualTo(
"1gaus") || opt.EqualTo(
"singlegaus")){
964 printf(
" ---> Reflection contribution from single-Gaussian fit to histogram from simulation\n");
965 f=
new TF1(
"mygaus",
"gaus",xMinForFit,xMaxForFit);
966 f->SetParameter(0,h->GetMaximum());
968 f->SetParameter(1,1.865);
969 f->SetParameter(2,0.050);
972 else if(opt.EqualTo(
"2gaus") || opt.EqualTo(
"doublegaus")){
973 printf(
" ---> Reflection contribution from double-Gaussian fit to histogram from simulation\n");
974 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);
975 f->SetParameter(0,h->GetMaximum());
977 f->SetParLimits(3,0.,1.);
978 f->SetParameter(3,0.5);
979 f->SetParameter(1,1.84);
980 f->SetParameter(2,0.050);
981 f->SetParameter(4,1.88);
982 f->SetParameter(5,0.050);
985 else if(opt.EqualTo(
"pol3")){
986 printf(
" ---> Reflection contribution from pol3 fit to histogram from simulation\n");
987 f=
new TF1(
"mypol3",
"pol3",xMinForFit,xMaxForFit);
988 f->SetParameter(0,h->GetMaximum());
994 else if(opt.EqualTo(
"pol6")){
995 printf(
" ---> Reflection contribution from pol6 fit to histogram from simulation\n");
996 f=
new TF1(
"mypol6",
"pol6",xMinForFit,xMaxForFit);
997 f->SetParameter(0,h->GetMaximum());
1004 printf(
" ---> Bad option for reflection configuration -> reflections will not be included in the fit\n");
1015 if(
fHistoTemplRfl->GetBinContent(j)>=0.&&TMath::Abs(h->GetBinError(j)*h->GetBinError(j)-h->GetBinContent(j))>0.1*h->GetBinContent(j))isPoissErr=kFALSE;
1026 printf(
" ---> Fit to MC template for reflection failed -> reflections will not be included in the fit\n");
1047 massVal=TDatabasePDG::Instance()->GetParticle(pdgCode)->Mass();
1050 massVal=TDatabasePDG::Instance()->GetParticle(pdgCode)->Mass();
1051 massVal-=TDatabasePDG::Instance()->GetParticle(421)->Mass();
1072 printf(
"Left range for bin counting smaller than allowed by histogram axis, setting it to the lower edge of the first histo bin\n");
1076 printf(
"Right range for bin counting larger than allowed by histogram axis, setting it to the upper edge of the last histo bin\n");
1084 if(!fbackground)
return 0.;
1086 for(
Int_t jb=minBinSum; jb<=maxBinSum; jb++){
1092 cntSig+=(cntTot-cntBkg-cntRefl);
1095 errRyBC=TMath::Sqrt(cntErr);
1107 if(maxrange>minrange){
1114 hResidualTrend->SetName(Form(
"%s_residualTrend",
fHistoInvMass->GetName()));
1115 hResidualTrend->SetTitle(Form(
"%s (Residuals)",
fHistoInvMass->GetTitle()));
1116 hResidualTrend->SetMarkerStyle(20);
1117 hResidualTrend->SetMarkerSize(1.0);
1118 hResidualTrend->Reset();
1122 hPullsTrend->Reset();
1123 hPullsTrend->SetName(Form(
"%s_pullTrend",
fHistoInvMass->GetName()));
1124 hPullsTrend->SetTitle(Form(
"%s (Pulls)",
fHistoInvMass->GetTitle()));
1125 hPullsTrend->SetMarkerStyle(20);
1126 hPullsTrend->SetMarkerSize(1.0);
1130 hPulls->SetTitle(Form(
"%s ; Pulls",
fHistoInvMass->GetTitle()));
1131 hPulls->SetBins(40,-10,10);
1135 Double_t res=-1.e-6,min=1.e+12,max=-1.e+12;
1140 if(jst>=binmi&&jst<=binma){
1141 arval->AddAt(res,jst-binmi);
1147 hResidualTrend->SetBinContent(jst,res);
1148 hResidualTrend->SetBinError(jst,
fHistoInvMass->GetBinError(jst));
1151 if(jst>=binmi&&jst<=binma)hPulls->Fill(res/
fHistoInvMass->GetBinError(jst));
1154 hPullsTrend->SetBinContent(jst,res/
fHistoInvMass->GetBinError(jst));
1155 hPullsTrend->SetBinError(jst,0.0001);
1158 if(hResidualTrend)hResidualTrend->GetXaxis()->SetRange(binmi,binma);
1160 hPullsTrend->GetXaxis()->SetRange(binmi,binma);
1161 hPullsTrend->SetMinimum(-7);
1162 hPullsTrend->SetMaximum(+7);
1164 if(TMath::Abs(min)>TMath::Abs(max))max=min;
1166 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);
1167 for(
Int_t j=0;j<binma-binmi+1;j++){
1168 hout->Fill(arval->At(j));
1171 hout->Fit(
"gaus",
"LEM",
"",-TMath::Abs(max)*1.2,TMath::Abs(max)*1.2);
1175 hPulls->Fit(
"gaus",
"LEM",
"",-3,3);
1185 printf(
"--- Background function in 1st step fit to side bands ---\n");
1189 printf(
"--- Total fit function from 2nd step fit ---\n");
1193 printf(
"--- Background function in 2nd step fit ---\n");
1197 printf(
"--- Reflections ---\n");
1201 printf(
"--- Background + reflections ---\n");
1205 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 MassFitter(Bool_t draw=kTRUE)
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)
Double_t GetRawYieldBinCounting(Double_t &errRyBC, Double_t nSigma=3., Int_t option=0, Int_t pdgCode=0) const
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
ClassImp(AliAnalysisTaskDeltaPt) AliAnalysisTaskDeltaPt
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)
Double_t fMaxMass
lower mass limit
TF1 * CreateBackgroundFitFunction(TString fname, Double_t integral)
TF1 * fRflFunc
internal variable for fit with reflections
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
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