Skip to content

[RF] Don't double-scale pdfs plotted by RooSimultaneous::plotOn()#20618

Merged
guitargeek merged 6 commits intoroot-project:masterfrom
guitargeek:rf501
Dec 21, 2025
Merged

[RF] Don't double-scale pdfs plotted by RooSimultaneous::plotOn()#20618
guitargeek merged 6 commits intoroot-project:masterfrom
guitargeek:rf501

Conversation

@guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Dec 2, 2025

After a8ef8b0, when plotting an extended pdf it automatically scales
itself to the number of expected events.

However, when plotting slices of a RooSimultaneous, the normalization is
already precomputed in RooSimultanous::plotOn() and should not be
overridden again. To prevent this, flag the calculated normatization as
the final number of events, and not some relative factor, which it is by
default.

Closes #20383.

The tutorials are also updated to use less confusing statements to plot slices of the RooSimultaneous.

@VanyaBelyaev, is that okay for you now?

Some unrelated RooFit code modernization commits were added to this PR to keep the net number of added lines of code negative.

@guitargeek guitargeek self-assigned this Dec 2, 2025
@guitargeek guitargeek requested a review from couet as a code owner December 2, 2025 20:56
@guitargeek guitargeek added the bug label Dec 2, 2025
@guitargeek guitargeek requested a review from lmoneta as a code owner December 2, 2025 20:57
@github-actions
Copy link

github-actions bot commented Dec 3, 2025

Test Results

    22 files      22 suites   3d 20h 31m 11s ⏱️
 3 791 tests  3 791 ✅ 0 💤 0 ❌
80 280 runs  80 280 ✅ 0 💤 0 ❌

Results for commit 1d1b9d8.

♻️ This comment has been updated with latest results.

@VanyaBelyaev
Copy link

Dear @guitargeek
Thank you for the fix!
As soon as it propagates to the LCG-de3 nightly slot, I'll be happy to test it in my working environment and to report the results.

And I like a lot significantly simplified "interface" without Slice&ProjWData.
It always was rather non-intuitive and partly confusing
It is nice to know better alternative exists. It will take some time to
update all my code for new model, but definitely it is a step in right direction.

@ferdymercury
Copy link
Collaborator

@guitargeek does this PR also clarify/close https://its.cern.ch/jira/browse/ROOT-7499 ?

@guitargeek
Copy link
Contributor Author

@guitargeek does this PR also clarify/close https://its.cern.ch/jira/browse/ROOT-7499 ?

No. But I have created another PR for that:

@guitargeek
Copy link
Contributor Author

And I like a lot significantly simplified "interface" without Slice&ProjWData.

Just to be clear: the simplified interface is not new. Plotting the slices as I suggest now has always worked in RooFit, and I'm just changing the tutorials to use simpler patterns 🙂 Why the plot command in the tutorial was so convoluted is not clear to me.

Copy link
Member

@dpiparo dpiparo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks!

It greatly helps debugging if the error message tells you which objects
are actually existing.
In the documentation of the RooSimultaneous, it says about the
`ProjWData()` argument:

> For observables present in given dataset projection of PDF is achieved
  by constructing an average over all observable values in given set.

And about `Slice()`, it says:

> Override default projection behaviour by omitting the specified
  category observable from the projection, i.e., by not integrating over
  all states of this category.

Starting from this explanation, it is highly unintuitive that one should
do things like `simPdf.plotOn(Slice(sample, "state"), ProjWData(same))` when
plotting the pdf of state `"state"` from a RooSimultaneous.

I think that instead, we should promote easy patterns in the tutorials.

That is, if you want to plot a slice pdf from a RooSimultaneous, you are
retreiving it with `getPdf()` and then plot it. The result is the same.
After a8ef8b0, when plotting an extended pdf it automatically scales
itself to the number of expected events.

However, when plotting slices of a RooSimultaneous, the normalization is
already precomputed in `RooSimultanous::plotOn()` and should not be
overridden again. To prevent this, flag the calculated normatization as
the final number of events, and not some relative factor, which it is by
default.

A unit test that covers this case was also implemented.

Closes root-project#20383.
  * smart pointers for transient members

  * more `std::string` instead of TString
  * delete commented-out obsolete code

  * use more range-based loops

  * inline definitions where appropriate

  * initialize `Measurement` data member in class declaration
@guitargeek guitargeek merged commit 49ebb8a into root-project:master Dec 21, 2025
30 checks passed
@guitargeek guitargeek deleted the rf501 branch December 21, 2025 15:28
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.

[RF] Broken rf501_simultaneouspdf.py in dev3/nighlies

4 participants