Skip to content

Commit 19475fa

Browse files
committed
HFInvMassFitter: Fix canvas division, add ratio histograms
1 parent 405f868 commit 19475fa

File tree

3 files changed

+99
-11
lines changed

3 files changed

+99
-11
lines changed

PWGHF/D2H/Macros/HFInvMassFitter.cxx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ void HFInvMassFitter::doFit()
356356
mTotalPdf->plotOn(mInvMassFrame, Name("Tot_c"), LineColor(kBlue));
357357
mSgnPdf->plotOn(mInvMassFrame, Normalization(1.0, RooAbsReal::RelativeExpected), DrawOption("F"), FillColor(TColor::GetColorTransparent(kBlue, 0.2)), VLines());
358358
mChiSquareOverNdfTotal = mInvMassFrame->chiSquare("Tot_c", "data_c"); // calculate reduced chi2 / DNF
359+
359360
// plot residual distribution
360361
mResidualFrame = mass->frame(Title("Residual Distribution"));
361362
RooHist* residualHistogram = mInvMassFrame->residHist("data_c", "Bkg_c");
@@ -372,6 +373,7 @@ void HFInvMassFitter::doFit()
372373
calculateSignal(mRawYield, mRawYieldErr);
373374
countSignal(mRawYieldCounted, mRawYieldCountedErr);
374375
calculateSignificance(mSignificance, mSignificanceErr);
376+
calculateFitToDataRatio();
375377
}
376378
}
377379

@@ -637,6 +639,37 @@ void HFInvMassFitter::drawResidual(TVirtualPad* pad)
637639
highlightPeakRegion(mResidualFrame);
638640
}
639641

642+
// draw ratio on canvas
643+
void HFInvMassFitter::drawRatio(TVirtualPad* pad)
644+
{
645+
pad->cd();
646+
mRatioFrame->GetYaxis()->SetTitle("");
647+
TPaveText* textInfo = new TPaveText(0.12, 0.65, 0.47, .89, "NDC");
648+
textInfo->SetBorderSize(0);
649+
textInfo->SetFillStyle(0);
650+
textInfo->SetTextColor(kBlue);
651+
textInfo->AddText(Form("S = %.0f #pm %.0f ", mRawYield, mRawYieldErr));
652+
textInfo->AddText(Form("S_{count} = %.0f #pm %.0f ", mRawYieldCounted, mRawYieldCountedErr));
653+
textInfo->AddText(Form("mean = %.3f #pm %.3f", mRooMeanSgn->getVal(), mRooMeanSgn->getError()));
654+
if (mTypeOfSgnPdf == DoubleGaus) {
655+
auto const& baseSigmaSgn = mWorkspace->var("sigma");
656+
textInfo->AddText(Form("sigma = %.3f #pm %.3f", baseSigmaSgn->getVal(), baseSigmaSgn->getError()));
657+
textInfo->AddText(Form("sigma 2 = %.3f #pm %.3f", mRooSigmaSgn->getVal(), mRooSigmaSgn->getError()));
658+
} else {
659+
textInfo->AddText(Form("sigma = %.3f #pm %.3f", mRooSigmaSgn->getVal(), mRooSigmaSgn->getError()));
660+
}
661+
mRatioFrame->addObject(textInfo);
662+
double xMin = mRatioFrame->GetXaxis()->GetXmin();
663+
double xMax = mRatioFrame->GetXaxis()->GetXmax();
664+
TLine* line = new TLine(xMin, 1.0, xMax, 1.0);
665+
line->SetLineColor(kGray);
666+
line->SetLineStyle(2);
667+
line->SetLineWidth(2);
668+
mRatioFrame->addObject(line);
669+
mRatioFrame->Draw();
670+
highlightPeakRegion(mRatioFrame);
671+
}
672+
640673
// draw peak region with vertical lines
641674
void HFInvMassFitter::highlightPeakRegion(const RooPlot* plot, Color_t color, Width_t width, Style_t style) const
642675
{
@@ -818,6 +851,42 @@ void HFInvMassFitter::plotRefl(RooAbsPdf* pdf)
818851
pdf->plotOn(mInvMassFrame, Components(namesOfReflPdf.at(mTypeOfReflPdf).c_str()), Name("Refl_c"), LineColor(kGreen));
819852
}
820853

854+
// Calculate fit to data ratio
855+
void HFInvMassFitter::calculateFitToDataRatio()
856+
{
857+
if (!mInvMassFrame)
858+
return;
859+
// Create a new RooPlot for the ratio
860+
mRatioFrame = mWorkspace->var("mass")->frame(Title("Fit/Data Ratio"));
861+
862+
// Get the data and fit curves from the frame
863+
auto* dataHist = dynamic_cast<RooHist*>(mInvMassFrame->findObject("data_c"));
864+
auto* fitCurve = dynamic_cast<RooCurve*>(mInvMassFrame->findObject("Tot_c")); // or the relevant fit curve
865+
866+
if (!dataHist || !fitCurve)
867+
return;
868+
869+
RooHist* ratioHist = new RooHist();
870+
871+
for (int i = 0; i < dataHist->GetN(); ++i) {
872+
double x, dataY, dataErr;
873+
dataHist->GetPoint(i, x, dataY);
874+
dataErr = dataHist->GetErrorY(i);
875+
876+
double fitY = fitCurve->Eval(x);
877+
878+
double ratio = dataY != 0 ? fitY / dataY : 0;
879+
double err = dataY != 0 ? ratio * dataErr / dataY : 0;
880+
881+
ratioHist->SetPoint(i, x, ratio);
882+
ratioHist->SetPointError(i, 0, 0, err, err);
883+
}
884+
885+
mRatioFrame->SetMinimum(0.0);
886+
mRatioFrame->SetMaximum(2.0);
887+
mRatioFrame->addPlotable(ratioHist, "P");
888+
}
889+
821890
// Fix reflection pdf
822891
void HFInvMassFitter::setReflFuncFixed()
823892
{

PWGHF/D2H/Macros/HFInvMassFitter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,10 @@ class HFInvMassFitter : public TNamed
224224
void calculateBackground(Double_t& bkg, Double_t& bkgErr) const;
225225
void calculateSignificance(Double_t& significance, Double_t& significanceErr) const;
226226
void checkForSignal(Double_t& estimatedSignal);
227+
void calculateFitToDataRatio();
227228
void drawFit(TVirtualPad* c, Int_t writeFitInfo = 2);
228229
void drawResidual(TVirtualPad* c);
230+
void drawRatio(TVirtualPad* c);
229231
void drawReflection(TVirtualPad* c);
230232

231233
private:
@@ -293,6 +295,7 @@ class HFInvMassFitter : public TNamed
293295
RooPlot* mReflFrame; /// reflection frame
294296
RooPlot* mReflOnlyFrame; /// reflection frame plot on reflection only
295297
RooPlot* mResidualFrame; /// residual frame
298+
RooPlot* mRatioFrame; /// fit/data ratio frame
296299
RooPlot* mResidualFrameForCalculation;
297300
RooWorkspace* mWorkspace; /// workspace
298301
Double_t mIntegralHisto; /// integral of histogram to fit

PWGHF/D2H/Macros/runMassFitter.C

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ int runMassFitter(const TString& configFileName)
353353
const Int_t nCanvases = std::ceil(static_cast<float>(nSliceVarBins) / nCanvasesMax);
354354
std::vector<TCanvas*> canvasMass(nCanvases);
355355
std::vector<TCanvas*> canvasResiduals(nCanvases);
356+
std::vector<TCanvas*> canvasRatio(nCanvases);
356357
std::vector<TCanvas*> canvasRefl(nCanvases);
357358
for (int iCanvas = 0; iCanvas < nCanvases; iCanvas++) {
358359
const int nPads = (nCanvases == 1) ? nSliceVarBins : nCanvasesMax;
@@ -363,9 +364,16 @@ int runMassFitter(const TString& configFileName)
363364
canvasResiduals[iCanvas] =
364365
new TCanvas(Form("canvasResiduals%d", iCanvas), Form("canvasResiduals%d", iCanvas), canvasSize[0], canvasSize[1]);
365366
divideCanvas(canvasResiduals[iCanvas], nPads);
366-
canvasRefl[iCanvas] = new TCanvas(Form("canvasRefl%d", iCanvas), Form("canvasRefl%d", iCanvas),
367-
canvasSize[0], canvasSize[1]);
368-
divideCanvas(canvasRefl[iCanvas], nPads);
367+
368+
canvasRatio[iCanvas] = new TCanvas(Form("canvasRatio%d", iCanvas), Form("canvasRatio%d", iCanvas),
369+
canvasSize[0], canvasSize[1]);
370+
divideCanvas(canvasRatio[iCanvas], nPads);
371+
372+
if (enableRefl) {
373+
canvasRefl[iCanvas] = new TCanvas(Form("canvasRefl%d", iCanvas), Form("canvasRefl%d", iCanvas),
374+
canvasSize[0], canvasSize[1]);
375+
divideCanvas(canvasRefl[iCanvas], nPads);
376+
}
369377
}
370378

371379
for (unsigned int iSliceVar = 0; iSliceVar < nSliceVarBins; iSliceVar++) {
@@ -532,6 +540,15 @@ int runMassFitter(const TString& configFileName)
532540
massFitter->drawResidual(gPad);
533541
canvasResiduals[iCanvas]->Modified();
534542
canvasResiduals[iCanvas]->Update();
543+
544+
if (nSliceVarBins > 1) {
545+
canvasRatio[iCanvas]->cd(iSliceVar - nCanvasesMax * iCanvas + 1);
546+
} else {
547+
canvasRatio[iCanvas]->cd();
548+
}
549+
massFitter->drawRatio(gPad);
550+
canvasRatio[iCanvas]->Modified();
551+
canvasRatio[iCanvas]->Update();
535552
}
536553

537554
hFitConfig->SetBinContent(1, iSliceVar + 1, massMin[iSliceVar]);
@@ -554,7 +571,10 @@ int runMassFitter(const TString& configFileName)
554571
canvasMass[iCanvas]->Write();
555572
if (!isMc) {
556573
canvasResiduals[iCanvas]->Write();
557-
canvasRefl[iCanvas]->Write();
574+
canvasRatio[iCanvas]->Write();
575+
if (enableRefl) {
576+
canvasRefl[iCanvas]->Write();
577+
}
558578
}
559579
}
560580

@@ -613,13 +633,9 @@ void setHistoStyle(TH1* histo, Color_t color, Size_t markerSize)
613633

614634
void divideCanvas(TCanvas* canvas, int nSliceVarBins)
615635
{
616-
const int rectangularSideMin = std::floor(std::sqrt(nSliceVarBins));
617-
constexpr int RectangularSidesDiffMax = 2;
618-
for (int rectangularSidesDiff = 0; rectangularSidesDiff < RectangularSidesDiffMax; ++rectangularSidesDiff) {
619-
if (rectangularSideMin * (rectangularSideMin + rectangularSidesDiff) >= nSliceVarBins) {
620-
canvas->Divide(rectangularSideMin + rectangularSidesDiff, rectangularSideMin);
621-
}
622-
}
636+
int nCols = std::ceil(std::sqrt(nSliceVarBins));
637+
int nRows = std::ceil(double(nSliceVarBins) / nCols);
638+
canvas->Divide(nCols, nRows);
623639
}
624640

625641
int main(int argc, const char* argv[])

0 commit comments

Comments
 (0)