Skip to content

Commit 80d3896

Browse files
committed
[RF] Don't override integral normalization set in RooNormalizedPdf
We should not override the normalization set for integrals of a RooNormalizedPdf, because sometimes, the requested normalization set is explicitly different from the internal normalization set of the normalized pdf. Closes #18718.
1 parent baee12d commit 80d3896

File tree

3 files changed

+56
-15
lines changed

3 files changed

+56
-15
lines changed

roofit/roofitcore/inc/RooFit/Detail/RooNormalizedPdf.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
#include <RooAbsPdf.h>
1717
#include <RooRealProxy.h>
1818

19-
namespace RooFit {
20-
namespace Detail {
19+
namespace RooFit::Detail {
2120

2221
class RooNormalizedPdf : public RooAbsPdf {
2322
public:
@@ -51,16 +50,15 @@ class RooNormalizedPdf : public RooAbsPdf {
5150

5251
bool forceAnalyticalInt(const RooAbsArg & /*dep*/) const override { return true; }
5352
/// Forward determination of analytical integration capabilities to input p.d.f
54-
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet * /*normSet*/,
53+
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet,
5554
const char *rangeName = nullptr) const override
5655
{
57-
return _pdf->getAnalyticalIntegralWN(allVars, analVars, &_normSet, rangeName);
56+
return _pdf->getAnalyticalIntegralWN(allVars, analVars, normSet ? normSet : &_normSet, rangeName);
5857
}
5958
/// Forward calculation of analytical integrals to input p.d.f
60-
double
61-
analyticalIntegralWN(Int_t code, const RooArgSet * /*normSet*/, const char *rangeName = nullptr) const override
59+
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName = nullptr) const override
6260
{
63-
return _pdf->analyticalIntegralWN(code, &_normSet, rangeName);
61+
return _pdf->analyticalIntegralWN(code, normSet ? normSet : &_normSet, rangeName);
6462
}
6563

6664
ExtendMode extendMode() const override { return static_cast<RooAbsPdf &>(*_pdf).extendMode(); }
@@ -97,7 +95,6 @@ class RooNormalizedPdf : public RooAbsPdf {
9795
ClassDefOverride(RooFit::Detail::RooNormalizedPdf, 0);
9896
};
9997

100-
} // namespace Detail
101-
} // namespace RooFit
98+
} // namespace RooFit::Detail
10299

103100
#endif

roofit/roofitcore/src/RooNormalizedPdf.cxx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@
1616

1717
#include <array>
1818

19-
2019
/**
2120
* \class RooNormalizedPdf
2221
*
2322
* A RooNormalizedPdf wraps a pdf divided by its integral for a given
2423
* normalization set into a new self-normalized pdf.
2524
*/
2625

27-
namespace RooFit {
28-
namespace Detail {
26+
namespace RooFit::Detail {
2927

3028
void RooNormalizedPdf::doEval(RooFit::EvalContext &ctx) const
3129
{
@@ -53,5 +51,4 @@ void RooNormalizedPdf::doEval(RooFit::EvalContext &ctx) const
5351
}
5452
}
5553

56-
} // namespace Detail
57-
} // namespace RooFit
54+
} // namespace RooFit::Detail

roofit/roofitcore/test/testRooSimultaneous.cxx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// Tests for the RooSimultaneous
22
// Authors: Jonas Rembser, CERN 06/2021
33

4+
#include <RooAddPdf.h>
45
#include <RooAddition.h>
56
#include <RooCategory.h>
67
#include <RooConstVar.h>
78
#include <RooDataSet.h>
9+
#include <RooExponential.h>
810
#include <RooFitResult.h>
911
#include <RooGenericPdf.h>
1012
#include <RooHelpers.h>
@@ -24,7 +26,7 @@
2426

2527
/// Forum issue
2628
/// https://root-forum.cern.ch/t/roofit-failed-to-create-nll-for-simultaneous-pdfs-with-multiple-range-names/49363.
27-
/// Multi-range likelihoods should also work with RooSimultaneous, where one
29+
/// Multi-range likelihoods should also work with RooSimultaneous, wheitionre one
2830
/// of the observables is a category.
2931
TEST(RooSimultaneous, MultiRangeNLL)
3032
{
@@ -510,6 +512,51 @@ TEST_P(TestStatisticTest, RooSimultaneousSingleChannelCrossCheckWithCondVar)
510512
<< "Inconsistency in RooSimultaneous wrapping with ConditionalObservables";
511513
}
512514

515+
/// GitHub issue #18718.
516+
/// Make sure that we can do a ranged fit on an extended RooAddPdf in a
517+
/// RooSimultaneous with the new CPU backend.
518+
TEST(RooSimultaneous, RangedExtendedRooAddPdf)
519+
{
520+
521+
const double nBkgA_nom = 9000;
522+
const double nBkgB_nom = 10000;
523+
524+
RooRealVar x("x", "Observable", 100, 150);
525+
x.setRange("fitRange", 100, 130);
526+
527+
RooRealVar nBkgA("nBkgA", "", nBkgA_nom, 0.8 * nBkgA_nom, 1.2 * nBkgA_nom);
528+
RooRealVar nBkgB("nBkgB", "", nBkgB_nom, 0.8 * nBkgB_nom, 1.2 * nBkgB_nom);
529+
530+
RooExponential expA("expA", "", x, RooFit::RooConst(-0.06));
531+
RooAddPdf modelA("modelA", "", {expA}, {nBkgA});
532+
533+
RooExponential expB("expB", "", x, RooFit::RooConst(-0.09));
534+
RooAddPdf modelB("modelB", "", {expB}, {nBkgB});
535+
536+
RooCategory runCat("runCat", "", {{"RunA", 0}, {"RunB", 1}});
537+
538+
RooSimultaneous simPdf("simPdf", "", {{"RunA", &modelA}, {"RunB", &modelB}}, runCat);
539+
540+
using namespace RooFit;
541+
542+
std::unique_ptr<RooDataSet> combData{simPdf.generate(RooArgSet(x, runCat), Extended())};
543+
544+
using Res = std::unique_ptr<RooFitResult>;
545+
546+
RooArgSet params;
547+
RooArgSet paramsSnap;
548+
simPdf.getParameters(combData->get(), params);
549+
params.snapshot(paramsSnap);
550+
551+
Res fitResult{simPdf.fitTo(*combData, Save(), Range("fitRange"), EvalBackend(RooFit::EvalBackend::Cpu()))};
552+
553+
params.assign(paramsSnap);
554+
555+
Res fitResultRef{simPdf.fitTo(*combData, Save(), Range("fitRange"), EvalBackend(RooFit::EvalBackend::Legacy()))};
556+
557+
EXPECT_TRUE(fitResult->isIdentical(*fitResultRef));
558+
}
559+
513560
/// GitHub issue #20383.
514561
/// Check that the the simultaneous pdf is normalized correctly when plotting
515562
/// with a projection dataset.

0 commit comments

Comments
 (0)