Skip to content

Commit d252d43

Browse files
committed
HFInvMassFitter: Fix canvas division, add ratio histograms
1 parent 33a836d commit d252d43

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
@@ -359,6 +359,7 @@ void HFInvMassFitter::doFit()
359359
mTotalPdf->plotOn(mInvMassFrame, Name("Tot_c"), LineColor(kBlue));
360360
mSgnPdf->plotOn(mInvMassFrame, Normalization(1.0, RooAbsReal::RelativeExpected), DrawOption("F"), FillColor(TColor::GetColorTransparent(kBlue, 0.2)), VLines());
361361
mChiSquareOverNdfTotal = mInvMassFrame->chiSquare("Tot_c", "data_c"); // calculate reduced chi2 / DNF
362+
362363
// plot residual distribution
363364
mResidualFrame = mass->frame(Title("Residual Distribution"));
364365
RooHist* residualHistogram = mInvMassFrame->residHist("data_c", "Bkg_c");
@@ -375,6 +376,7 @@ void HFInvMassFitter::doFit()
375376
calculateSignal(mRawYield, mRawYieldErr);
376377
countSignal(mRawYieldCounted, mRawYieldCountedErr);
377378
calculateSignificance(mSignificance, mSignificanceErr);
379+
calculateFitToDataRatio();
378380
}
379381
}
380382

@@ -640,6 +642,37 @@ void HFInvMassFitter::drawResidual(TVirtualPad* pad)
640642
highlightPeakRegion(mResidualFrame);
641643
}
642644

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

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

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
@@ -346,6 +346,7 @@ int runMassFitter(const TString& configFileName)
346346
const Int_t nCanvases = std::ceil(static_cast<float>(nSliceVarBins) / nCanvasesMax);
347347
std::vector<TCanvas*> canvasMass(nCanvases);
348348
std::vector<TCanvas*> canvasResiduals(nCanvases);
349+
std::vector<TCanvas*> canvasRatio(nCanvases);
349350
std::vector<TCanvas*> canvasRefl(nCanvases);
350351
for (int iCanvas = 0; iCanvas < nCanvases; iCanvas++) {
351352
const int nPads = (nCanvases == 1) ? nSliceVarBins : nCanvasesMax;
@@ -356,9 +357,16 @@ int runMassFitter(const TString& configFileName)
356357
canvasResiduals[iCanvas] =
357358
new TCanvas(Form("canvasResiduals%d", iCanvas), Form("canvasResiduals%d", iCanvas), canvasSize[0], canvasSize[1]);
358359
divideCanvas(canvasResiduals[iCanvas], nPads);
359-
canvasRefl[iCanvas] = new TCanvas(Form("canvasRefl%d", iCanvas), Form("canvasRefl%d", iCanvas),
360-
canvasSize[0], canvasSize[1]);
361-
divideCanvas(canvasRefl[iCanvas], nPads);
360+
361+
canvasRatio[iCanvas] = new TCanvas(Form("canvasRatio%d", iCanvas), Form("canvasRatio%d", iCanvas),
362+
canvasSize[0], canvasSize[1]);
363+
divideCanvas(canvasRatio[iCanvas], nPads);
364+
365+
if (enableRefl) {
366+
canvasRefl[iCanvas] = new TCanvas(Form("canvasRefl%d", iCanvas), Form("canvasRefl%d", iCanvas),
367+
canvasSize[0], canvasSize[1]);
368+
divideCanvas(canvasRefl[iCanvas], nPads);
369+
}
362370
}
363371

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

538555
hFitConfig->SetBinContent(1, iSliceVar + 1, massMin[iSliceVar]);
@@ -555,7 +572,10 @@ int runMassFitter(const TString& configFileName)
555572
canvasMass[iCanvas]->Write();
556573
if (!isMc) {
557574
canvasResiduals[iCanvas]->Write();
558-
canvasRefl[iCanvas]->Write();
575+
canvasRatio[iCanvas]->Write();
576+
if (enableRefl) {
577+
canvasRefl[iCanvas]->Write();
578+
}
559579
}
560580
}
561581

@@ -614,13 +634,9 @@ void setHistoStyle(TH1* histo, Color_t color, Size_t markerSize)
614634

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

626642
int main(int argc, char* argv[])

0 commit comments

Comments
 (0)