Skip to content

Conversation

@guitargeek
Copy link
Contributor

Good testing is imporant, so it's also important to follow predictable
conventions in unit tests. In RooFit, we have established that the name
of all test files should match the `test*.cxx` patters.

In this commit, all the files that don't match this pattern are renamed,
and code-formatted on this occasion.

Also, all the files in `roofit/roofitcore/test/TestStatistics` are
reformatted because they almost followed the style anyway.
So far, most of the `RooNLLVar` test in `testTestStatistics` were
hardcoded to only cover the BatchMode, but it's good if they also cover
the legacy RooFit. Hence, all these tests were converted to
parameterized tests that cover the BatchMode `"off"` and `"cpu"`.

In the same go, all the unit tests in the same file are updated to
silence unnecessary info printout.
* The ERROR printouts in the `createNLLModularLAndOffset` test are
  actually expected, so we now silence them using the "hijack" mechanism
  and check if they are inside the string

* The `fitTo` test uses the multiprocess parallelization and can be
  turned on if roofit was built with `multiprocess`

* Some memory leaks were fixed too
It's better to use Asimov datasets in the bin integration tests, because
like this there is no randomness and it's much easier to separate bias
from variance (as there is no variance).

Also, this commit avoids some code duplication in `testTestStatistics`
The different overloads of `RooAbsRealLValue::inRange()` implemented
different tolerances when checking if a value `x` falls inside a
specific range. Some overloads checked if the interval
`[x - 1e-6, x + 1e6]` is overlapping with the range, an other overload
checked if the interval `[x - 1e-8*x, x + 1e8*x]` is overlapping.

It's better is this is done consistently and predictably so this commit
suggests to leave out these epsilon margins that were never documented.
For backwards compatibility, one can set a custom relative or absolute
epsilon via the `RooNumber` interface.
In order to merge the `RooMomentMorphND` and the `RooMomentMorphFuncND`,
it is better to rename things first such that the code becomes
comparable. Like this, it will be easier to spot the residual
differences.
Since the change to Asimov datasets in `testTestStatistics`, there are
warnings that tell you to explicitly set `SumW2Error()` because you are
fitting to weighted data. That's what is done in this commit.

This means the message level threshold can we changed also to not
silence warnings anymore.
In `RooAbsArg::redirectServers()`, we don't need to do anything if there
are no new servers or if the only new server is this RooAbsArg itself.
And by returning early, we avoid potentially annoying side effects of
the redirectServersHook.
The idea of the RooGenProdProj is that we divide two integral objects
each created with this makeIntgral() function to get the normalized
integral of a product. Therefore, we don't need to normalize the
numerater and denominator integrals themselves. Doing the normalization
would be expensive and it would cancel out anyway. However, if we don't
specify an explicit normalization integral in createIntegral(), the
last-used normalization set might be used to normalize the pdf,
resulting in redundant computations.

For this reason, the normalization set of the integrated pdfs is fixed
to an empty set in this case. Note that in RooFit, a nullptr
normalization set and an empty normalization set is not equivalent. The
former implies taking the last-used normalization set, and the latter
means explicitly no normalization.

This fixes the performance regression reported in root-project#11814, and a new unit
test is implemented to make sure no new numeric integrals pop up in the
reproducer code to that issue.

Unfortunately, this change means that there will be again warnings about
missing `RooAddPdf` normalization sets, but this is not a regression
because these warnings only got fixed in the 6.28 development cycle in
290b478.
The `RooRealIntegral` class is smart enough to figure out which
variables the function the integrated function doesn't depend on and
trivially integrates them itself by multiplying with the variable
definition range.

However, if the integration range is a subrange of the variable range,
this was not considered. This resulted in wrong results. for integrals
like `pdf.createIntegral(x, "subrange")`, where the pdf doesn't depend
on x. These kind of integrals can occur in the projections that the
RooAddPdf does, so it's important that they work, and fixing this
partially addresses root-project#11486.

This change also fixes a so-far unknown bug in the `RooXYChi2Var`, which
also used these kind of integrals. Without this fix, the `Integrate()`
feature for `chi2FitTo()` was completely broken, which can be seen in
the output of the `rf609` tutorial with any previous ROOT version. The
tutorial looks okay by chance, because the function is dominted by the
quadratic term in `x` that is constant in the fit. But if one makes this
a floating parameter, the problem gets obvious.

Probably that was the reason why the main model parameter was set
constant to begin with, to sweep the bug under the rug. Now, the
tutorials are updated to have the quadratic coefficient floating too.
And also `stressRooFit`, since the reference file has to be updated
anyway.

To demonstrate that things work correctly now, a new unit test was
implemented that does the closure check of the `integrate()` feature of
the `RooXYChi2Var` with a linear fit function.
@phsft-bot
Copy link

Starting build on ROOT-debian10-i386/soversion, ROOT-performance-centos8-multicore/cxx17, ROOT-ubuntu18.04/nortcxxmod, ROOT-ubuntu2004/python3, mac12/noimt, mac11/cxx14, windows10/cxx14
How to customize builds

@phsft-bot
Copy link

Build failed on mac12/noimt.
Running on macphsft17.dyndns.cern.ch:/Users/sftnight/build/jenkins/workspace/root-pullrequests-build
See console output.

Warnings:

  • [2023-01-12T09:56:46.024Z] /Users/sftnight/build/jenkins/workspace/root-pullrequests-build/root/core/base/src/TDirectory.cxx:1245:7: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]

Failing tests:

And 63 more

@guitargeek guitargeek merged commit b249caa into root-project:v6-28-00-patches Jan 12, 2023
@guitargeek guitargeek deleted the v6-28-00-patches_roofit_backports_4 branch January 12, 2023 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants