Skip to content

Commit 4224d9a

Browse files
committed
[RF] Fix RooLognormal analytical integral for xMin < zero
Just like for other pdfs that are strictly zero for negative observable values, the integral for xMin < zero should still evaluate correctly (compare for example with the RooLandau). Addresses this forum report: https://root-forum.cern.ch/t/roofit-pdfs-with-different-domain-in-the-same-model-e-g-gauss-lognormal/64505/3 Little demo that it works now: ```c++ RooRealVar x("x", "x", 0.0, 10.0); RooRealVar mu("mu", "mu", 1.0); RooRealVar sigma("sigma", "sigma", 0.5); RooLognormal logn("logn", "lognormal pdf", x, mu, sigma); double a = -1.0; double b = 5.0; x.setRange("intRange", -1.0, 5.0); RooAbsReal* integral = logn.createIntegral(x, RooFit::NormSet(x), RooFit::Range("intRange")); double result = integral->getVal(); std::cout << "Integral of Lognormal from " << a << " to " << b << " = " << result << std::endl; ``` (cherry picked from commit 7ffaf51)
1 parent 87dd853 commit 4224d9a

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

roofit/roofit/src/RooLognormal.cxx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ The parameterization here is physics driven and differs from the ROOT::Math::log
2727

2828
#include "RooLognormal.h"
2929
#include "RooRandom.h"
30-
#include "RooMath.h"
3130
#include "RooHelpers.h"
3231
#include "RooBatchCompute.h"
3332

@@ -104,9 +103,11 @@ double RooLognormal::analyticalIntegral(Int_t /*code*/, const char *rangeName) c
104103
static const double root2 = std::sqrt(2.);
105104

106105
double ln_k = std::abs(_useStandardParametrization ? k : std::log(k));
107-
double scaledMin = _useStandardParametrization ? std::log(x.min(rangeName)) - m0 : std::log(x.min(rangeName) / m0);
108-
double scaledMax = _useStandardParametrization ? std::log(x.max(rangeName)) - m0 : std::log(x.max(rangeName) / m0);
109-
return 0.5 * (RooMath::erf(scaledMax / (root2 * ln_k)) - RooMath::erf(scaledMin / (root2 * ln_k)));
106+
const double xMin = std::max(x.min(rangeName), 0.);
107+
const double xMax = x.max(rangeName);
108+
double scaledMax = _useStandardParametrization ? std::log(xMax) - m0 : std::log(xMax / m0);
109+
double scaledMin = _useStandardParametrization ? std::log(xMin) - m0 : std::log(xMin / m0);
110+
return 0.5 * (std::erf(scaledMax / (root2 * ln_k)) - std::erf(scaledMin / (root2 * ln_k)));
110111
}
111112

112113
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)