Skip to content

Commit e54bf52

Browse files
committed
[RF] Test RooFit Hessians with Clad
1 parent 3dcd9c7 commit e54bf52

5 files changed

Lines changed: 39 additions & 17 deletions

File tree

interpreter/cling/tools/plugins/clad/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ if (DEFINED CLAD_SOURCE_DIR)
7474
list(APPEND _clad_extra_settings SOURCE_DIR ${CLAD_SOURCE_DIR})
7575
else()
7676
list(APPEND _clad_extra_settings GIT_REPOSITORY https://github.com/vgvassilev/clad.git)
77-
list(APPEND _clad_extra_settings GIT_TAG v2.2)
77+
list(APPEND _clad_extra_settings GIT_TAG master)
7878
endif()
7979

8080
## list(APPEND _clad_patches_list "patch1.patch" "patch2.patch")

roofit/histfactory/test/testHistFactory.cxx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@
99
#include <RooFitHS3/JSONIO.h>
1010
#include <RooFitHS3/RooJSONFactoryWSTool.h>
1111

12-
#include <RooFit/Detail/NormalizationHelpers.h>
13-
#include <RooDataHist.h>
14-
#include <RooWorkspace.h>
1512
#include <RooArgSet.h>
16-
#include <RooSimultaneous.h>
17-
#include <RooRealSumPdf.h>
18-
#include <RooRealVar.h>
19-
#include <RooHelpers.h>
13+
#include <RooDataHist.h>
14+
#include <RooEvaluatorWrapper.h>
15+
#include <RooFit/Detail/NormalizationHelpers.h>
16+
#include <RooFit/Evaluator.h>
2017
#include <RooFitResult.h>
18+
#include <RooHelpers.h>
19+
#include <RooMinimizer.h>
2120
#include <RooPlot.h>
22-
#include <RooFit/Evaluator.h>
21+
#include <RooRealSumPdf.h>
22+
#include <RooRealVar.h>
23+
#include <RooSimultaneous.h>
24+
#include <RooWorkspace.h>
2325

2426
#include <TROOT.h>
2527
#include <TFile.h>
@@ -618,9 +620,21 @@ TEST_P(HFFixtureFit, Fit)
618620
}
619621

620622
using namespace RooFit;
621-
std::unique_ptr<RooFitResult> fitResult{simPdf->fitTo(*data, evalBackend, Optimize(constTermOptimization),
622-
GlobalObservables(*mc->GetGlobalObservables()), Save(),
623-
PrintLevel(verbose ? 1 : -1))};
623+
std::unique_ptr<RooAbsReal> nll{simPdf->createNLL(*data, evalBackend, Optimize(constTermOptimization),
624+
GlobalObservables(*mc->GetGlobalObservables()))};
625+
RooMinimizer::Config cfg;
626+
if (evalBackend == RooFit::EvalBackend::Codegen()) {
627+
// Make sure we use both analytical gradient and Hessian
628+
static_cast<RooFit::Experimental::RooEvaluatorWrapper &>(*nll).generateGradient();
629+
static_cast<RooFit::Experimental::RooEvaluatorWrapper &>(*nll).generateHessian();
630+
cfg.useGradient = true;
631+
cfg.useHessian = true;
632+
}
633+
RooMinimizer minim{*nll, cfg};
634+
minim.setPrintLevel(verbose ? 1 : -1);
635+
minim.minimize("Minuit2", "Migrad");
636+
minim.hesse();
637+
std::unique_ptr<RooFitResult> fitResult{minim.save()};
624638
ASSERT_NE(fitResult, nullptr);
625639
if (verbose)
626640
fitResult->Print("v");

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ double constraintSum(DoubleArray comp, unsigned int compSize)
180180
{
181181
double sum = 0;
182182
#if defined(__CLING__) && defined(R__HAS_CLAD)
183-
#pragma clad checkpoint loop
183+
//#pragma clad checkpoint loop
184184
#endif
185185
for (unsigned int i = 0; i < compSize; i++) {
186186
sum -= std::log(comp[i]);
@@ -370,7 +370,7 @@ double flexibleInterp(unsigned int code, ParamsArray params, unsigned int n, Dou
370370
{
371371
double total = nominal;
372372
#if defined(__CLING__) && defined(R__HAS_CLAD)
373-
#pragma clad checkpoint loop
373+
//#pragma clad checkpoint loop
374374
#endif
375375
for (std::size_t i = 0; i < n; ++i) {
376376
total += flexibleInterpSingle(code, low[i], high[i], boundary, nominal, params[i], total);

roofit/roofitcore/src/RooFit/CodegenContext.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ std::unique_ptr<CodegenContext::LoopScope> CodegenContext::beginLoop(RooAbsArg c
186186
}
187187

188188
// Make sure that the name of this variable doesn't clash with other stuff
189-
addToCodeBody(in, "#pragma clad checkpoint loop\n");
189+
//addToCodeBody(in, "#pragma clad checkpoint loop\n");
190190
addToCodeBody(in, "for(int " + idx + " = 0; " + idx + " < obs[" + std::to_string(2 * firstObsIdx + 1) + "]; " + idx +
191191
"++) {\n");
192192

roofit/roofitcore/test/testRooFuncWrapper.cxx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,16 @@ class FactoryTest : public testing::TestWithParam<FactoryTestParams> {
129129
std::unique_ptr<RooHelpers::LocalChangeMsgLevel> _changeMsgLvl;
130130
};
131131

132-
std::unique_ptr<RooFitResult> runMinimizer(RooAbsReal &absReal, bool useGradient = true)
132+
std::unique_ptr<RooFitResult> runMinimizer(RooAbsReal &absReal, bool useAD = true)
133133
{
134134
RooMinimizer::Config cfg;
135-
cfg.useGradient = useGradient;
135+
cfg.useGradient = useAD;
136+
cfg.useHessian = useAD;
136137
RooMinimizer m{absReal, cfg};
137138
m.setPrintLevel(-1);
138139
m.setStrategy(0);
139140
m.minimize("Minuit2");
141+
m.hesse(); // to use the analytical Hessian for error estimation
140142
return std::unique_ptr<RooFitResult>{m.save()};
141143
}
142144

@@ -164,6 +166,9 @@ TEST_P(FactoryTest, NLLFit)
164166
// We want to use the generated code also for the nominal likelihood. Like
165167
// this, we make sure to validate also the NLL values of the generated code.
166168
static_cast<RooFit::Experimental::RooEvaluatorWrapper &>(*nllFunc).setUseGeneratedFunctionCode(true);
169+
// Let's also validate the Hessian
170+
static_cast<RooFit::Experimental::RooEvaluatorWrapper&>(*nllFunc).generateHessian();
171+
static_cast<RooFit::Experimental::RooEvaluatorWrapper&>(*nllFunc).writeDebugMacro(_params._name);
167172

168173
double tol = _params._fitResultTolerance;
169174

@@ -214,6 +219,9 @@ TEST_P(FactoryTest, NLLFit)
214219
// because for very small correlations it's usually not the same within the
215220
// relative tolerance because you would compare two small values that are
216221
// only different from zero because of noise.
222+
// The error tolerance is also quite large, because the analytical Hessian
223+
// gives numerically quite different results.
224+
double errorTol = 0.1;
217225
EXPECT_TRUE(result->isIdenticalNoCov(*resultRef, tol, tol));
218226
EXPECT_TRUE(resultAd->isIdenticalNoCov(*resultRef, tol, tol));
219227
}

0 commit comments

Comments
 (0)