Logo ROOT   6.14/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
45 using namespace RooFit;
46 using namespace RooStats;
47 
48 
49 // see below for implementation
50 void AddModel(RooWorkspace*);
51 void AddData(RooWorkspace*);
52 void DoSPlot(RooWorkspace*);
53 void MakePlots(RooWorkspace*);
54 
55 void 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 //____________________________________
86 void 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 //____________________________________
179 void 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 //____________________________________
200 void 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 
266 void 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 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
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
Plot dataset on specified frame.
Definition: RooAbsData.cxx:568
RooCmdArg LineColor(Color_t color)
void ws()
Definition: ws.C:62
Definition: Rtypes.h:59
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:688
int Int_t
Definition: RtypesCore.h:41
void SetTitle(const char *name)
Set the title of the RooPlot to &#39;title&#39;.
Definition: RooPlot.cxx:1098
Definition: Rtypes.h:59
static RooMsgService & instance()
Return reference to singleton instance.
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
Plot (project) PDF on specified frame.
Definition: RooAbsPdf.h:105
RooCmdArg Extended(Bool_t flag=kTRUE)
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
RooCmdArg DataError(Int_t)
RooCmdArg LineStyle(Style_t style)
Plain Gaussian p.d.f.
Definition: RooGaussian.h:25
Double_t GetSWeight(Int_t numEvent, const char *sVariable) const
Definition: SPlot.cxx:185
RooConstVar represent a constant real-valued object.
Definition: RooConstVar.h:25
Exponential p.d.f.
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
RooAbsData * data(const char *name) const
Retrieve dataset (binned or unbinned) with given name. A null pointer is returned if not found...
RooCmdArg Rename(const char *suffix)
void setSilentMode(Bool_t flag)
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:29
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event &#39;index&#39;.
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
A RooPlot is a plot frame and a container for graphics objects within that frame. ...
Definition: RooPlot.h:41
The Canvas class.
Definition: TCanvas.h:31
Namespace for the RooStats classes.
Definition: Asimov.h:20
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
double Double_t
Definition: RtypesCore.h:55
RooCmdArg Components(const RooArgSet &compSet)
RooRealVar * var(const char *name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found...
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
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
Bool_t import(const RooAbsArg &arg, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg())
Import a RooAbsArg object, e.g.
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())
Generate a new dataset containing the specified variables with events sampled from our distribution...
Definition: RooAbsPdf.cxx:1725
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:1079
Double_t GetSumOfEventSWeight(Int_t numEvent) const
Sum the SWeights for a particular event.
Definition: SPlot.cxx:234
This class calculates sWeights used to create an sPlot.
Definition: SPlot.h:32
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43
virtual void Draw(Option_t *options=0)
Draw this plot and all of the elements it contains.
Definition: RooPlot.cxx:558
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48