Rf 5 0 1_Simultaneouspdf

Organization and simultaneous fits: using simultaneous pdfs to describe simultaneous fits to multiple datasets

Author: Clemens Lange, Wouter Verkerke (C++ version)
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Wednesday, January 19, 2022 at 10:23 AM.

In [ ]:
import ROOT

Create model for physics sample

Create observables

In [ ]:
x = ROOT.RooRealVar("x", "x", -8, 8)

Construct signal pdf

In [ ]:
mean = ROOT.RooRealVar("mean", "mean", 0, -8, 8)
sigma = ROOT.RooRealVar("sigma", "sigma", 0.3, 0.1, 10)
gx = ROOT.RooGaussian("gx", "gx", x, mean, sigma)

Construct background pdf

In [ ]:
a0 = ROOT.RooRealVar("a0", "a0", -0.1, -1, 1)
a1 = ROOT.RooRealVar("a1", "a1", 0.004, -1, 1)
px = ROOT.RooChebychev("px", "px", x, [a0, a1])

Construct composite pdf

In [ ]:
f = ROOT.RooRealVar("f", "f", 0.2, 0.0, 1.0)
model = ROOT.RooAddPdf("model", "model", [gx, px], [f])

Create model for control sample

Construct signal pdf. NOTE that sigma is shared with the signal sample model

In [ ]:
mean_ctl = ROOT.RooRealVar("mean_ctl", "mean_ctl", -3, -8, 8)
gx_ctl = ROOT.RooGaussian("gx_ctl", "gx_ctl", x, mean_ctl, sigma)

Construct the background pdf

In [ ]:
a0_ctl = ROOT.RooRealVar("a0_ctl", "a0_ctl", -0.1, -1, 1)
a1_ctl = ROOT.RooRealVar("a1_ctl", "a1_ctl", 0.5, -0.1, 1)
px_ctl = ROOT.RooChebychev("px_ctl", "px_ctl", x, [a0_ctl, a1_ctl])

Construct the composite model

In [ ]:
f_ctl = ROOT.RooRealVar("f_ctl", "f_ctl", 0.5, 0.0, 1.0)
model_ctl = ROOT.RooAddPdf("model_ctl", "model_ctl", [gx_ctl, px_ctl], [f_ctl])

Generate events for both samples

Generate 1000 events in x and y from model

In [ ]:
data = model.generate({x}, 100)
data_ctl = model_ctl.generate({x}, 2000)

Create index category and join samples

Define category to distinguish physics and control samples events

In [ ]:
sample = ROOT.RooCategory("sample", "sample")

Construct combined dataset in (x,sample)

In [ ]:
combData = ROOT.RooDataSet(
    "combined data",
    ROOT.RooFit.Import("physics", data),
    ROOT.RooFit.Import("control", data_ctl),

Construct a simultaneous pdf in (x, sample)

Construct a simultaneous pdf using category sample as index

In [ ]:
simPdf = ROOT.RooSimultaneous("simPdf", "simultaneous pdf", sample)

Associate model with the physics state and model_ctl with the control state

In [ ]:
simPdf.addPdf(model, "physics")
simPdf.addPdf(model_ctl, "control")

Perform a simultaneous fit

Perform simultaneous fit of model to data and model_ctl to data_ctl

In [ ]:

Plot model slices on data slices

Make a frame for the physics sample

In [ ]:
frame1 = x.frame(Bins=30, Title="Physics sample")

Plot all data tagged as physics sample

In [ ]:
combData.plotOn(frame1, Cut="sample==sample::physics")

Plot "physics" slice of simultaneous pdf. NB: You must project the sample index category with data using ProjWData as a RooSimultaneous makes no prediction on the shape in the index category and can thus not be integrated NB2: The sampleSet must be named. It will not work to pass this as a temporary because python will delete it. The same holds for fitTo() and plotOn() below.

In [ ]:
sampleSet = {sample}
simPdf.plotOn(frame1, Slice=(sample, "physics"), Components="px", ProjWData=(sampleSet, combData), LineStyle="--")

The same plot for the control sample slice

In [ ]:
frame2 = x.frame(Bins=30, Title="Control sample")
combData.plotOn(frame2, Cut="sample==sample::control")
simPdf.plotOn(frame2, Slice=(sample, "control"), ProjWData=(sampleSet, combData))
simPdf.plotOn(frame2, Slice=(sample, "control"), Components="px_ctl", ProjWData=(sampleSet, combData), LineStyle="--")

c = ROOT.TCanvas("rf501_simultaneouspdf", "rf501_simultaneouspdf", 800, 400)


Draw all canvases

In [ ]:
from ROOT import gROOT