Logo ROOT   6.16/01
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
49// see below for implementation
50void AddModel(RooWorkspace*);
51void AddData(RooWorkspace*);
52void DoSPlot(RooWorkspace*);
53void MakePlots(RooWorkspace*);
54
55void rs301_splot()
56{
57
58 // Create a new workspace to manage the project.
59 RooWorkspace* wspace = new RooWorkspace("myWS");
60
61 // add the signal and background models to the workspace.
62 // Inside this function you will find a description our model.
63 AddModel(wspace);
64
65 // add some toy data to the workspace
66 AddData(wspace);
67
68 // inspect the workspace if you wish
69 // wspace->Print();
70
71 // do sPlot.
72 //This wil make a new dataset with sWeights added for every event.
73 DoSPlot(wspace);
74
75 // Make some plots showing the discriminating variable and
76 // the control variable after unfolding.
77 MakePlots(wspace);
78
79 // cleanup
80 delete wspace;
81
82}
83
84
85//____________________________________
86void AddModel(RooWorkspace* ws){
87
88 // Make models for signal (Higgs) and background (Z+jets and QCD)
89 // In real life, this part requires an intelligent modeling
90 // of signal and background -- this is only an example.
91
92 // set range of observable
93 Double_t lowRange = 00, highRange = 200;
94
95 // make a RooRealVar for the observables
96 RooRealVar invMass("invMass", "M_{inv}", lowRange, highRange,"GeV");
97 RooRealVar isolation("isolation", "isolation", 0., 20., "GeV");
98
99
100 // --------------------------------------
101 // make 2-d model for Z including the invariant mass
102 // distribution and an isolation distribution which we want to
103 // unfold from QCD.
104 std::cout << "make z model" << std::endl;
105 // mass model for Z
106 RooRealVar mZ("mZ", "Z Mass", 91.2, lowRange, highRange);
107 RooRealVar sigmaZ("sigmaZ", "Width of Gaussian", 2,0,10,"GeV");
108 RooGaussian mZModel("mZModel", "Z+jets Model", invMass, mZ, sigmaZ);
109 // we know Z mass
110 mZ.setConstant();
111 // we leave the width of the Z free during the fit in this example.
112
113 // isolation model for Z. Only used to generate toy MC.
114 // the exponential is of the form exp(c*x). If we want
115 // the isolation to decay an e-fold every R GeV, we use
116 // c = -1/R.
117 RooConstVar zIsolDecayConst("zIsolDecayConst",
118 "z isolation decay constant", -1);
119 RooExponential zIsolationModel("zIsolationModel", "z isolation model",
120 isolation, zIsolDecayConst);
121
122 // make the combined Z model
123 RooProdPdf zModel("zModel", "4-d model for Z",
124 RooArgSet(mZModel, zIsolationModel));
125
126 // --------------------------------------
127 // make QCD model
128
129 std::cout << "make qcd model" << std::endl;
130 // mass model for QCD.
131 // the exponential is of the form exp(c*x). If we want
132 // the mass to decay an e-fold every R GeV, we use
133 // c = -1/R.
134 // We can leave this parameter free during the fit.
135 RooRealVar qcdMassDecayConst("qcdMassDecayConst",
136 "Decay const for QCD mass spectrum",
137 -0.01, -100, 100,"1/GeV");
138 RooExponential qcdMassModel("qcdMassModel", "qcd Mass Model",
139 invMass, qcdMassDecayConst);
140
141
142 // isolation model for QCD. Only used to generate toy MC
143 // the exponential is of the form exp(c*x). If we want
144 // the isolation to decay an e-fold every R GeV, we use
145 // c = -1/R.
146 RooConstVar qcdIsolDecayConst("qcdIsolDecayConst",
147 "Et resolution constant", -.1);
148 RooExponential qcdIsolationModel("qcdIsolationModel", "QCD isolation model",
149 isolation, qcdIsolDecayConst);
150
151 // make the 2-d model
152 RooProdPdf qcdModel("qcdModel", "2-d model for QCD",
153 RooArgSet(qcdMassModel, qcdIsolationModel));
154
155 // --------------------------------------
156 // combined model
157
158 // These variables represent the number of Z or QCD events
159 // They will be fitted.
160 RooRealVar zYield("zYield","fitted yield for Z",50 ,0.,1000) ;
161 RooRealVar qcdYield("qcdYield","fitted yield for QCD", 100 ,0.,1000) ;
162
163 // now make the combined model
164 std::cout << "make full model" << std::endl;
165 RooAddPdf model("model","z+qcd background models",
166 RooArgList(zModel, qcdModel),
167 RooArgList(zYield,qcdYield));
168
169
170 // interesting for debugging and visualizing the model
171 model.graphVizTree("fullModel.dot");
172
173 std::cout << "import model" << std::endl;
174
175 ws->import(model);
176}
177
178//____________________________________
179void AddData(RooWorkspace* ws){
180 // Add a toy dataset
181
182 // how many events do we want?
183 Int_t nEvents = 1000;
184
185 // get what we need out of the workspace to make toy data
186 RooAbsPdf* model = ws->pdf("model");
187 RooRealVar* invMass = ws->var("invMass");
188 RooRealVar* isolation = ws->var("isolation");
189
190 // make the toy data
191 std::cout << "make data set and import to workspace" << std::endl;
192 RooDataSet* data = model->generate(RooArgSet(*invMass, *isolation),nEvents);
193
194 // import data into workspace
195 ws->import(*data, Rename("data"));
196
197}
198
199//____________________________________
200void DoSPlot(RooWorkspace* ws){
201 std::cout << "Calculate sWeights" << std::endl;
202
203 // get what we need out of the workspace to do the fit
204 RooAbsPdf* model = ws->pdf("model");
205 RooRealVar* zYield = ws->var("zYield");
206 RooRealVar* qcdYield = ws->var("qcdYield");
207 RooDataSet* data = (RooDataSet*) ws->data("data");
208
209 // fit the model to the data.
210 model->fitTo(*data, Extended() );
211
212 // The sPlot technique requires that we fix the parameters
213 // of the model that are not yields after doing the fit.
214 //
215 // This *could* be done with the lines below, however this is taken care of
216 // by the RooStats::SPlot constructor (or more precisely the AddSWeight
217 // method).
218 //
219 //RooRealVar* sigmaZ = ws->var("sigmaZ");
220 //RooRealVar* qcdMassDecayConst = ws->var("qcdMassDecayConst");
221 //sigmaZ->setConstant();
222 //qcdMassDecayConst->setConstant();
223
224
226
227
228 // Now we use the SPlot class to add SWeights to our data set
229 // based on our model and our yield variables
230 RooStats::SPlot* sData = new RooStats::SPlot("sData","An SPlot",
231 *data, model, RooArgList(*zYield,*qcdYield) );
232
233
234 // Check that our weights have the desired properties
235
236 std::cout << "Check SWeights:" << std::endl;
237
238
239 std::cout << std::endl << "Yield of Z is "
240 << zYield->getVal() << ". From sWeights it is "
241 << sData->GetYieldFromSWeight("zYield") << std::endl;
242
243
244 std::cout << "Yield of QCD is "
245 << qcdYield->getVal() << ". From sWeights it is "
246 << sData->GetYieldFromSWeight("qcdYield") << std::endl
247 << std::endl;
248
249 for(Int_t i=0; i < 10; i++)
250 {
251 std::cout << "z Weight " << sData->GetSWeight(i,"zYield")
252 << " qcd Weight " << sData->GetSWeight(i,"qcdYield")
253 << " Total Weight " << sData->GetSumOfEventSWeight(i)
254 << std::endl;
255 }
256
257 std::cout << std::endl;
258
259 // import this new dataset with sWeights
260 std::cout << "import new dataset with sWeights" << std::endl;
261 ws->import(*data, Rename("dataWithSWeights"));
262
263
264}
265
266void MakePlots(RooWorkspace* ws){
267
268 // Here we make plots of the discriminating variable (invMass) after the fit
269 // and of the control variable (isolation) after unfolding with sPlot.
270 std::cout << "make plots" << std::endl;
271
272 // make our canvas
273 TCanvas* cdata = new TCanvas("sPlot","sPlot demo", 400, 600);
274 cdata->Divide(1,3);
275
276 // get what we need out of the workspace
277 RooAbsPdf* model = ws->pdf("model");
278 RooAbsPdf* zModel = ws->pdf("zModel");
279 RooAbsPdf* qcdModel = ws->pdf("qcdModel");
280
281 RooRealVar* isolation = ws->var("isolation");
282 RooRealVar* invMass = ws->var("invMass");
283
284 // note, we get the dataset with sWeights
285 RooDataSet* data = (RooDataSet*) ws->data("dataWithSWeights");
286
287 // this shouldn't be necessary, need to fix something with workspace
288 // do this to set parameters back to their fitted values.
289 model->fitTo(*data, Extended() );
290
291 //plot invMass for data with full model and individual components overlaid
292 // TCanvas* cdata = new TCanvas();
293 cdata->cd(1);
294 RooPlot* frame = invMass->frame() ;
295 data->plotOn(frame ) ;
296 model->plotOn(frame) ;
297 model->plotOn(frame,Components(*zModel),LineStyle(kDashed), LineColor(kRed)) ;
298 model->plotOn(frame,Components(*qcdModel),LineStyle(kDashed),LineColor(kGreen)) ;
299
300 frame->SetTitle("Fit of model to discriminating variable");
301 frame->Draw() ;
302
303
304 // Now use the sWeights to show isolation distribution for Z and QCD.
305 // The SPlot class can make this easier, but here we demonstrate in more
306 // detail how the sWeights are used. The SPlot class should make this
307 // very easy and needs some more development.
308
309 // Plot isolation for Z component.
310 // Do this by plotting all events weighted by the sWeight for the Z component.
311 // The SPlot class adds a new variable that has the name of the corresponding
312 // yield + "_sw".
313 cdata->cd(2);
314
315 // create weighted data set
316 RooDataSet * dataw_z = new RooDataSet(data->GetName(),data->GetTitle(),data,*data->get(),0,"zYield_sw") ;
317
318 RooPlot* frame2 = isolation->frame() ;
319 dataw_z->plotOn(frame2, DataError(RooAbsData::SumW2) ) ;
320
321 frame2->SetTitle("isolation distribution for Z");
322 frame2->Draw() ;
323
324 // Plot isolation for QCD component.
325 // Eg. plot all events weighted by the sWeight for the QCD component.
326 // The SPlot class adds a new variable that has the name of the corresponding
327 // yield + "_sw".
328 cdata->cd(3);
329 RooDataSet * dataw_qcd = new RooDataSet(data->GetName(),data->GetTitle(),data,*data->get(),0,"qcdYield_sw") ;
330 RooPlot* frame3 = isolation->frame() ;
331 dataw_qcd->plotOn(frame3,DataError(RooAbsData::SumW2) ) ;
332
333 frame3->SetTitle("isolation distribution for QCD");
334 frame3->Draw() ;
335
336 // cdata->SaveAs("SPlot.gif");
337
338}
int Int_t
Definition: RtypesCore.h:41
double Double_t
Definition: RtypesCore.h:55
@ kRed
Definition: Rtypes.h:63
@ kGreen
Definition: Rtypes.h:63
@ 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:531
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
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 *set=0) const
Evaluate object. Returns either cached value or triggers a recalculation.
Definition: RooAbsReal.h:64
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
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
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 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:1162
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)
@(#)root/roostats:$Id$ Author: George Lewis, Kyle Cranmer
Definition: Asimov.h:20
void ws()
Definition: ws.C:63