Logo ROOT   6.18/05
Reference Guide
rs301_splot.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_roostats
3/// \notebook -js
4/// SPlot tutorial
5///
6/// This tutorial shows an example of using SPlot to unfold two distributions.
7/// The physics context for the example is that we want to know
8/// the isolation distribution for real electrons from Z events
9/// and fake electrons from QCD. Isolation is our 'control' variable
10/// To unfold them, we need a model for an uncorrelated variable that
11/// discriminates between Z and QCD. To do this, we use the invariant
12/// mass of two electrons. We model the Z with a Gaussian and the QCD
13/// with a falling exponential.
14///
15/// Note, since we don't have real data in this tutorial, we need to generate
16/// toy data. To do that we need a model for the isolation variable for
17/// both Z and QCD. This is only used to generate the toy data, and would
18/// not be needed if we had real data.
19///
20/// \macro_image
21/// \macro_output
22/// \macro_code
23///
24/// \author Kyle Cranmer
25
26#include "RooRealVar.h"
27#include "RooStats/SPlot.h"
28#include "RooDataSet.h"
29#include "RooRealVar.h"
30#include "RooGaussian.h"
31#include "RooExponential.h"
32#include "RooChebychev.h"
33#include "RooAddPdf.h"
34#include "RooProdPdf.h"
35#include "RooAddition.h"
36#include "RooProduct.h"
37#include "TCanvas.h"
38#include "RooAbsPdf.h"
39#include "RooFit.h"
40#include "RooFitResult.h"
41#include "RooWorkspace.h"
42#include "RooConstVar.h"
43
44// use this order for safety on library loading
45using namespace RooFit;
46using namespace RooStats;
47
48// see below for implementation
49void AddModel(RooWorkspace *);
50void AddData(RooWorkspace *);
51void DoSPlot(RooWorkspace *);
52void MakePlots(RooWorkspace *);
53
54void rs301_splot()
55{
56
57 // Create a new workspace to manage the project.
58 RooWorkspace *wspace = new RooWorkspace("myWS");
59
60 // add the signal and background models to the workspace.
61 // Inside this function you will find a description our model.
62 AddModel(wspace);
63
64 // add some toy data to the workspace
65 AddData(wspace);
66
67 // inspect the workspace if you wish
68 // wspace->Print();
69
70 // do sPlot.
71 // This wil make a new dataset with sWeights added for every event.
72 DoSPlot(wspace);
73
74 // Make some plots showing the discriminating variable and
75 // the control variable after unfolding.
76 MakePlots(wspace);
77
78 // cleanup
79 delete wspace;
80}
81
82//____________________________________
83void AddModel(RooWorkspace *ws)
84{
85
86 // Make models for signal (Higgs) and background (Z+jets and QCD)
87 // In real life, this part requires an intelligent modeling
88 // of signal and background -- this is only an example.
89
90 // set range of observable
91 Double_t lowRange = 00, highRange = 200;
92
93 // make a RooRealVar for the observables
94 RooRealVar invMass("invMass", "M_{inv}", lowRange, highRange, "GeV");
95 RooRealVar isolation("isolation", "isolation", 0., 20., "GeV");
96
97 // --------------------------------------
98 // make 2-d model for Z including the invariant mass
99 // distribution and an isolation distribution which we want to
100 // unfold from QCD.
101 std::cout << "make z model" << std::endl;
102 // mass model for Z
103 RooRealVar mZ("mZ", "Z Mass", 91.2, lowRange, highRange);
104 RooRealVar sigmaZ("sigmaZ", "Width of Gaussian", 2, 0, 10, "GeV");
105 RooGaussian mZModel("mZModel", "Z+jets Model", invMass, mZ, sigmaZ);
106 // we know Z mass
107 mZ.setConstant();
108 // we leave the width of the Z free during the fit in this example.
109
110 // isolation model for Z. Only used to generate toy MC.
111 // the exponential is of the form exp(c*x). If we want
112 // the isolation to decay an e-fold every R GeV, we use
113 // c = -1/R.
114 RooConstVar zIsolDecayConst("zIsolDecayConst", "z isolation decay constant", -1);
115 RooExponential zIsolationModel("zIsolationModel", "z isolation model", isolation, zIsolDecayConst);
116
117 // make the combined Z model
118 RooProdPdf zModel("zModel", "4-d model for Z", RooArgSet(mZModel, zIsolationModel));
119
120 // --------------------------------------
121 // make QCD model
122
123 std::cout << "make qcd model" << std::endl;
124 // mass model for QCD.
125 // the exponential is of the form exp(c*x). If we want
126 // the mass to decay an e-fold every R GeV, we use
127 // c = -1/R.
128 // We can leave this parameter free during the fit.
129 RooRealVar qcdMassDecayConst("qcdMassDecayConst", "Decay const for QCD mass spectrum", -0.01, -100, 100, "1/GeV");
130 RooExponential qcdMassModel("qcdMassModel", "qcd Mass Model", invMass, qcdMassDecayConst);
131
132 // isolation model for QCD. Only used to generate toy MC
133 // the exponential is of the form exp(c*x). If we want
134 // the isolation to decay an e-fold every R GeV, we use
135 // c = -1/R.
136 RooConstVar qcdIsolDecayConst("qcdIsolDecayConst", "Et resolution constant", -.1);
137 RooExponential qcdIsolationModel("qcdIsolationModel", "QCD isolation model", isolation, qcdIsolDecayConst);
138
139 // make the 2-d model
140 RooProdPdf qcdModel("qcdModel", "2-d model for QCD", RooArgSet(qcdMassModel, qcdIsolationModel));
141
142 // --------------------------------------
143 // combined model
144
145 // These variables represent the number of Z or QCD events
146 // They will be fitted.
147 RooRealVar zYield("zYield", "fitted yield for Z", 50, 0., 1000);
148 RooRealVar qcdYield("qcdYield", "fitted yield for QCD", 100, 0., 1000);
149
150 // now make the combined model
151 std::cout << "make full model" << std::endl;
152 RooAddPdf model("model", "z+qcd background models", RooArgList(zModel, qcdModel), RooArgList(zYield, qcdYield));
153
154 // interesting for debugging and visualizing the model
155 model.graphVizTree("fullModel.dot");
156
157 std::cout << "import model" << std::endl;
158
159 ws->import(model);
160}
161
162//____________________________________
163void AddData(RooWorkspace *ws)
164{
165 // Add a toy dataset
166
167 // how many events do we want?
168 Int_t nEvents = 1000;
169
170 // get what we need out of the workspace to make toy data
171 RooAbsPdf *model = ws->pdf("model");
172 RooRealVar *invMass = ws->var("invMass");
173 RooRealVar *isolation = ws->var("isolation");
174
175 // make the toy data
176 std::cout << "make data set and import to workspace" << std::endl;
177 RooDataSet *data = model->generate(RooArgSet(*invMass, *isolation), nEvents);
178
179 // import data into workspace
180 ws->import(*data, Rename("data"));
181}
182
183//____________________________________
184void DoSPlot(RooWorkspace *ws)
185{
186 std::cout << "Calculate sWeights" << std::endl;
187
188 // get what we need out of the workspace to do the fit
189 RooAbsPdf *model = ws->pdf("model");
190 RooRealVar *zYield = ws->var("zYield");
191 RooRealVar *qcdYield = ws->var("qcdYield");
192 RooDataSet *data = (RooDataSet *)ws->data("data");
193
194 // fit the model to the data.
195 model->fitTo(*data, Extended());
196
197 // The sPlot technique requires that we fix the parameters
198 // of the model that are not yields after doing the fit.
199 //
200 // This *could* be done with the lines below, however this is taken care of
201 // by the RooStats::SPlot constructor (or more precisely the AddSWeight
202 // method).
203 //
204 // RooRealVar* sigmaZ = ws->var("sigmaZ");
205 // RooRealVar* qcdMassDecayConst = ws->var("qcdMassDecayConst");
206 // sigmaZ->setConstant();
207 // qcdMassDecayConst->setConstant();
208
210
211 // Now we use the SPlot class to add SWeights to our data set
212 // based on our model and our yield variables
213 RooStats::SPlot *sData = new RooStats::SPlot("sData", "An SPlot", *data, model, RooArgList(*zYield, *qcdYield));
214
215 // Check that our weights have the desired properties
216
217 std::cout << "Check SWeights:" << std::endl;
218
219 std::cout << std::endl
220 << "Yield of Z is " << zYield->getVal() << ". From sWeights it is "
221 << sData->GetYieldFromSWeight("zYield") << std::endl;
222
223 std::cout << "Yield of QCD is " << qcdYield->getVal() << ". From sWeights it is "
224 << sData->GetYieldFromSWeight("qcdYield") << std::endl
225 << std::endl;
226
227 for (Int_t i = 0; i < 10; i++) {
228 std::cout << "z Weight " << sData->GetSWeight(i, "zYield") << " qcd Weight "
229 << sData->GetSWeight(i, "qcdYield") << " Total Weight " << sData->GetSumOfEventSWeight(i)
230 << std::endl;
231 }
232
233 std::cout << std::endl;
234
235 // import this new dataset with sWeights
236 std::cout << "import new dataset with sWeights" << std::endl;
237 ws->import(*data, Rename("dataWithSWeights"));
238}
239
240void MakePlots(RooWorkspace *ws)
241{
242
243 // Here we make plots of the discriminating variable (invMass) after the fit
244 // and of the control variable (isolation) after unfolding with sPlot.
245 std::cout << "make plots" << std::endl;
246
247 // make our canvas
248 TCanvas *cdata = new TCanvas("sPlot", "sPlot demo", 400, 600);
249 cdata->Divide(1, 3);
250
251 // get what we need out of the workspace
252 RooAbsPdf *model = ws->pdf("model");
253 RooAbsPdf *zModel = ws->pdf("zModel");
254 RooAbsPdf *qcdModel = ws->pdf("qcdModel");
255
256 RooRealVar *isolation = ws->var("isolation");
257 RooRealVar *invMass = ws->var("invMass");
258
259 // note, we get the dataset with sWeights
260 RooDataSet *data = (RooDataSet *)ws->data("dataWithSWeights");
261
262 // this shouldn't be necessary, need to fix something with workspace
263 // do this to set parameters back to their fitted values.
264 model->fitTo(*data, Extended());
265
266 // plot invMass for data with full model and individual components overlaid
267 // TCanvas* cdata = new TCanvas();
268 cdata->cd(1);
269 RooPlot *frame = invMass->frame();
270 data->plotOn(frame);
271 model->plotOn(frame);
272 model->plotOn(frame, Components(*zModel), LineStyle(kDashed), LineColor(kRed));
273 model->plotOn(frame, Components(*qcdModel), LineStyle(kDashed), LineColor(kGreen));
274
275 frame->SetTitle("Fit of model to discriminating variable");
276 frame->Draw();
277
278 // Now use the sWeights to show isolation distribution for Z and QCD.
279 // The SPlot class can make this easier, but here we demonstrate in more
280 // detail how the sWeights are used. The SPlot class should make this
281 // very easy and needs some more development.
282
283 // Plot isolation for Z component.
284 // Do this by plotting all events weighted by the sWeight for the Z component.
285 // The SPlot class adds a new variable that has the name of the corresponding
286 // yield + "_sw".
287 cdata->cd(2);
288
289 // create weighted data set
290 RooDataSet *dataw_z = new RooDataSet(data->GetName(), data->GetTitle(), data, *data->get(), 0, "zYield_sw");
291
292 RooPlot *frame2 = isolation->frame();
293 dataw_z->plotOn(frame2, DataError(RooAbsData::SumW2));
294
295 frame2->SetTitle("isolation distribution for Z");
296 frame2->Draw();
297
298 // Plot isolation for QCD component.
299 // Eg. plot all events weighted by the sWeight for the QCD component.
300 // The SPlot class adds a new variable that has the name of the corresponding
301 // yield + "_sw".
302 cdata->cd(3);
303 RooDataSet *dataw_qcd = new RooDataSet(data->GetName(), data->GetTitle(), data, *data->get(), 0, "qcdYield_sw");
304 RooPlot *frame3 = isolation->frame();
305 dataw_qcd->plotOn(frame3, DataError(RooAbsData::SumW2));
306
307 frame3->SetTitle("isolation distribution for QCD");
308 frame3->Draw();
309
310 // cdata->SaveAs("SPlot.gif");
311}
int Int_t
Definition: RtypesCore.h:41
double Double_t
Definition: RtypesCore.h:55
@ kRed
Definition: Rtypes.h:64
@ kGreen
Definition: Rtypes.h:64
@ kDashed
Definition: TAttLine.h:48
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Calls RooPlot* plotOn(RooPlot* frame, const RooLinkedList& cmdList) const ;.
Definition: RooAbsData.cxx:552
RooDataSet * generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none())
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition: RooAbsPdf.h:56
virtual RooFitResult * fitTo(RooAbsData &data, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none())
Fit PDF to given dataset.
Definition: RooAbsPdf.cxx:1119
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none(), const RooCmdArg &arg9=RooCmdArg::none(), const RooCmdArg &arg10=RooCmdArg::none()) const
Helper calling plotOn(RooPlot*, RooLinkedList&) const.
Definition: RooAbsPdf.h:119
RooPlot * frame(const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Create a new RooPlot on the heap with a drawing frame initialized for this object,...
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:81
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooConstVar represent a constant real-valued object.
Definition: RooConstVar.h:25
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event 'index'.
Exponential p.d.f.
Plain Gaussian p.d.f.
Definition: RooGaussian.h:25
static RooMsgService & instance()
Return reference to singleton instance.
void setSilentMode(Bool_t flag)
A RooPlot is a plot frame and a container for graphics objects within that frame.
Definition: RooPlot.h:41
void SetTitle(const char *name)
Set the title of the RooPlot to 'title'.
Definition: RooPlot.cxx:1104
virtual void Draw(Option_t *options=0)
Draw this plot and all of the elements it contains.
Definition: RooPlot.cxx:558
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
This class calculates sWeights used to create an sPlot.
Definition: SPlot.h:32
Double_t GetYieldFromSWeight(const char *sVariable) const
Sum the SWeights for a particular specie over all events This should equal the total (weighted) yield...
Definition: SPlot.cxx:265
Double_t GetSWeight(Int_t numEvent, const char *sVariable) const
Definition: SPlot.cxx:185
Double_t GetSumOfEventSWeight(Int_t numEvent) const
Sum the SWeights for a particular event.
Definition: SPlot.cxx:234
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43
The Canvas class.
Definition: TCanvas.h:31
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:693
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1166
Template specialisation used in RooAbsArg:
RooCmdArg Extended(Bool_t flag=kTRUE)
RooCmdArg Rename(const char *suffix)
RooCmdArg Components(const RooArgSet &compSet)
RooCmdArg DataError(Int_t)
RooCmdArg LineColor(Color_t color)
RooCmdArg LineStyle(Style_t style)
Namespace for the RooStats classes.
Definition: Asimov.h:20
void ws()
Definition: ws.C:66