Skip to content

Commit 9b634c0

Browse files
committed
[RF] Avoid confusing plotOn(Slice(sample), ProjWData(same)) pattern
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. (cherry picked from commit 4dd0bb6)
1 parent c675a35 commit 9b634c0

File tree

3 files changed

+42
-45
lines changed

3 files changed

+42
-45
lines changed

roofit/roofitcore/test/stressRooFit_tests.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,22 +2972,21 @@ class TestBasic501 : public RooUnitTest {
29722972
RooPlot *frame1 = x.frame(Bins(30), Title("Physics sample"));
29732973

29742974
// Plot all data tagged as physics sample
2975-
combData.plotOn(frame1, Cut("sample==sample::physics"));
2975+
std::unique_ptr<RooAbsData> slicedData1{combData.reduce(Cut("sample==sample::physics"))};
2976+
slicedData1->SetName("combData_Cut[sample==sample::physics]"); // to be consistent with reference file
2977+
slicedData1->plotOn(frame1);
29762978

29772979
// Plot "physics" slice of simultaneous pdf.
2978-
// NBL You _must_ project the sample index category with data using ProjWData
2979-
// as a RooSimultaneous makes no prediction on the shape in the index category
2980-
// and can thus not be integrated
2981-
simPdf.plotOn(frame1, Slice(sample, "physics"), ProjWData(sample, combData));
2982-
simPdf.plotOn(frame1, Slice(sample, "physics"), Components("px"), ProjWData(sample, combData),
2983-
LineStyle(kDashed));
2984-
2985-
// The same plot for the control sample slice
2980+
simPdf.getPdf("physics")->plotOn(frame1);
2981+
simPdf.getPdf("physics")->plotOn(frame1, Components("px"), LineStyle(kDashed));
2982+
2983+
// The same plot for the control sample slice.
29862984
RooPlot *frame2 = x.frame(Bins(30), Title("Control sample"));
2987-
combData.plotOn(frame2, Cut("sample==sample::control"));
2988-
simPdf.plotOn(frame2, Slice(sample, "control"), ProjWData(sample, combData));
2989-
simPdf.plotOn(frame2, Slice(sample, "control"), Components("px_ctl"), ProjWData(sample, combData),
2990-
LineStyle(kDashed));
2985+
std::unique_ptr<RooAbsData> slicedData2{combData.reduce(Cut("sample==sample::control"))};
2986+
slicedData2->SetName("combData_Cut[sample==sample::control]"); // to be consistent with reference file
2987+
slicedData2->plotOn(frame2);
2988+
simPdf.getPdf("control")->plotOn(frame2);
2989+
simPdf.getPdf("control")->plotOn(frame2, Components("px_ctl"), LineStyle(kDashed));
29912990

29922991
regPlot(frame1, "rf501_plot1");
29932992
regPlot(frame2, "rf501_plot2");

tutorials/roofit/roofit/rf501_simultaneouspdf.C

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,29 +102,28 @@ void rf501_simultaneouspdf()
102102
RooPlot *frame1 = x.frame(Title("Physics sample"));
103103

104104
// Plot all data tagged as physics sample
105-
combData.plotOn(frame1, Cut("sample==sample::physics"));
105+
std::unique_ptr<RooAbsData> slicedData1{combData.reduce(Cut("sample==sample::physics"))};
106+
slicedData1->plotOn(frame1);
106107

107108
// Plot "physics" slice of simultaneous pdf.
109+
simPdf.getPdf("physics")->plotOn(frame1);
110+
simPdf.getPdf("physics")->plotOn(frame1, Components("px"), LineStyle(kDashed));
111+
112+
// The same plot for the control sample slice. We do this with a different
113+
// approach, using the data slice for the projection. This approach is more
114+
// general, because you can plot sums of slices by using logical or in the
115+
// Cut() command.
108116
// NBL You _must_ project the sample index category with data using ProjWData
109117
// as a RooSimultaneous makes no prediction on the shape in the index category
110118
// and can thus not be integrated.
111119
// In other words: Since the PDF doesn't know the number of events in the different
112120
// category states, it doesn't know how much of each component it has to project out.
113121
// This information is read from the data.
114-
simPdf.plotOn(frame1, Slice(sample, "physics"), ProjWData(sample, combData));
115-
simPdf.plotOn(frame1, Slice(sample, "physics"), Components("px"), ProjWData(sample, combData), LineStyle(kDashed));
116-
117-
// The same plot for the control sample slice. We do this with a different
118-
// approach this time, for illustration purposes. Here, we are slicing the
119-
// dataset and then use the data slice for the projection, because then the
120-
// RooFit::Slice() becomes unnecessary. This approach is more general,
121-
// because you can plot sums of slices by using logical or in the Cut()
122-
// command.
123122
RooPlot *frame2 = x.frame(Bins(30), Title("Control sample"));
124-
std::unique_ptr<RooAbsData> slicedData{combData.reduce(Cut("sample==sample::control"))};
125-
slicedData->plotOn(frame2);
126-
simPdf.plotOn(frame2, ProjWData(sample, *slicedData));
127-
simPdf.plotOn(frame2, Components("px_ctl"), ProjWData(sample, *slicedData), LineStyle(kDashed));
123+
std::unique_ptr<RooAbsData> slicedData2{combData.reduce(Cut("sample==sample::control"))};
124+
slicedData2->plotOn(frame2);
125+
simPdf.plotOn(frame2, ProjWData(sample, *slicedData2));
126+
simPdf.plotOn(frame2, Components("px_ctl"), ProjWData(sample, *slicedData2), LineStyle(kDashed));
128127

129128
// The same plot for all the phase space. Here, we can just use the original
130129
// combined dataset.

tutorials/roofit/roofit/rf501_simultaneouspdf.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
import ROOT
1515

16-
1716
# Create model for physics sample
1817
# -------------------------------------------------------------
1918

@@ -96,28 +95,28 @@
9695
frame1 = x.frame(Title="Physics sample")
9796

9897
# Plot all data tagged as physics sample
99-
combData.plotOn(frame1, Cut="sample==sample::physics")
98+
slicedData1 = combData.reduce(Cut="sample==sample::physics")
99+
slicedData1.plotOn(frame1)
100100

101101
# Plot "physics" slice of simultaneous pdf.
102-
# NB: You *must* project the sample index category with data using ProjWData as
103-
# a RooSimultaneous makes no prediction on the shape in the index category and
104-
# can thus not be integrated. In other words: Since the PDF doesn't know the
105-
# number of events in the different category states, it doesn't know how much
106-
# of each component it has to project out. This info is read from the data.
107-
simPdf.plotOn(frame1, Slice=(sample, "physics"), ProjWData=(sample, combData))
108-
simPdf.plotOn(frame1, Slice=(sample, "physics"), Components="px", ProjWData=(sample, combData), LineStyle="--")
102+
simPdf.getPdf("physics").plotOn(frame1)
103+
simPdf.getPdf("physics").plotOn(frame1, Components="px", LineStyle="--")
109104

110105
# The same plot for the control sample slice. We do this with a different
111-
# approach this time, for illustration purposes. Here, we are slicing the
112-
# dataset and then use the data slice for the projection, because then the
113-
# RooFit::Slice() becomes unnecessary. This approach is more general,
114-
# because you can plot sums of slices by using logical or in the Cut()
115-
# command.
106+
# approach, using the data slice for the projection. This approach is more
107+
# general, because you can plot sums of slices by using logical or in the
108+
# Cut() command.
109+
# NBL You _must_ project the sample index category with data using ProjWData
110+
# as a RooSimultaneous makes no prediction on the shape in the index category
111+
# and can thus not be integrated.
112+
# In other words: Since the PDF doesn't know the number of events in the different
113+
# category states, it doesn't know how much of each component it has to project out.
114+
# This information is read from the data.
116115
frame2 = x.frame(Title="Control sample")
117-
slicedData = combData.reduce(Cut="sample==sample::control")
118-
slicedData.plotOn(frame2)
119-
simPdf.plotOn(frame2, ProjWData=(sample, slicedData))
120-
simPdf.plotOn(frame2, Components="px_ctl", ProjWData=(sample, slicedData), LineStyle="--")
116+
slicedData2 = combData.reduce(Cut="sample==sample::control")
117+
slicedData2.plotOn(frame2)
118+
simPdf.plotOn(frame2, ProjWData=(sample, slicedData2))
119+
simPdf.plotOn(frame2, Components="px_ctl", ProjWData=(sample, slicedData2), LineStyle="--")
121120

122121
# The same plot for all the phase space. Here, we can just use the original
123122
# combined dataset.

0 commit comments

Comments
 (0)