Skip to content

Commit 1f0efbe

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.
1 parent 87df588 commit 1f0efbe

File tree

3 files changed

+42
-44
lines changed

3 files changed

+42
-44
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 & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,28 +96,28 @@
9696
frame1 = x.frame(Title="Physics sample")
9797

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

101102
# 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="--")
103+
simPdf.getPdf("physics").plotOn(frame1)
104+
simPdf.getPdf("physics").plotOn(frame1, Components="px", LineStyle="--")
109105

110106
# 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.
107+
# approach, using the data slice for the projection. This approach is more
108+
# general, because you can plot sums of slices by using logical or in the
109+
# Cut() command.
110+
# NBL You _must_ project the sample index category with data using ProjWData
111+
# as a RooSimultaneous makes no prediction on the shape in the index category
112+
# and can thus not be integrated.
113+
# In other words: Since the PDF doesn't know the number of events in the different
114+
# category states, it doesn't know how much of each component it has to project out.
115+
# This information is read from the data.
116116
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="--")
117+
slicedData2 = combData.reduce(Cut="sample==sample::control")
118+
slicedData2.plotOn(frame2)
119+
simPdf.plotOn(frame2, ProjWData=(sample, slicedData2))
120+
simPdf.plotOn(frame2, Components="px_ctl", ProjWData=(sample, slicedData2), LineStyle="--")
121121

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

0 commit comments

Comments
 (0)