Logo ROOT   6.12/07
Reference Guide
StandardBayesianNumericalDemo.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_roostats
3 /// \notebook -js
4 /// Standard demo of the numerical Bayesian calculator
5 ///
6 /// This is a standard demo that can be used with any ROOT file
7 /// prepared in the standard way. You specify:
8 /// - name for input ROOT file
9 /// - name of workspace inside ROOT file that holds model and data
10 /// - name of ModelConfig that specifies details for calculator tools
11 /// - name of dataset
12 ///
13 /// With default parameters the macro will attempt to run the
14 /// standard hist2workspace example and read the ROOT file
15 /// that it produces.
16 ///
17 /// The actual heart of the demo is only about 10 lines long.
18 ///
19 /// The BayesianCalculator is based on Bayes's theorem
20 /// and performs the integration using ROOT's numeric integration utilities
21 ///
22 /// \macro_image
23 /// \macro_output
24 /// \macro_code
25 ///
26 /// \author Kyle Cranmer
27 
28 #include "TFile.h"
29 #include "TROOT.h"
30 #include "RooWorkspace.h"
31 #include "RooAbsData.h"
32 #include "RooRealVar.h"
33 
34 #include "RooUniform.h"
35 #include "RooStats/ModelConfig.h"
38 #include "RooStats/RooStatsUtils.h"
39 #include "RooPlot.h"
40 #include "TSystem.h"
41 
42 #include <cassert>
43 
44 using namespace RooFit;
45 using namespace RooStats;
46 
47 
48 struct BayesianNumericalOptions {
49 
50  double confLevel = 0.95 ; // interval CL
51  TString integrationType = ""; // integration Type (default is adaptive (numerical integration)
52  // possible values are "TOYMC" (toy MC integration, work when nuisances have a constraints pdf)
53  // "VEGAS" , "MISER", or "PLAIN" (these are all possible MC integration)
54  int nToys = 10000; // number of toys used for the MC integrations - for Vegas should be probably set to an higher value
55  bool scanPosterior = false; // flag to compute interval by scanning posterior (it is more robust but maybe less precise)
56  int nScanPoints = 20; // number of points for scanning the posterior (if scanPosterior = false it is used only for plotting). Use by default a low value to speed-up tutorial
57  int intervalType = 1; // type of interval (0 is shortest, 1 central, 2 upper limit)
58  double maxPOI = -999; // force a different value of POI for doing the scan (default is given value)
59  double nSigmaNuisance = -1; // force integration of nuisance parameters to be within nSigma of their error (do first a model fit to find nuisance error)
60 
61 };
62 
63 BayesianNumericalOptions optBayes;
64 
65 void StandardBayesianNumericalDemo(const char* infile = "",
66  const char* workspaceName = "combined",
67  const char* modelConfigName = "ModelConfig",
68  const char* dataName = "obsData") {
69 
70  // option definitions
71  double confLevel = optBayes.confLevel;
72  TString integrationType = optBayes.integrationType;
73  int nToys = optBayes.nToys;
74  bool scanPosterior = optBayes.scanPosterior;
75  int nScanPoints = optBayes.nScanPoints;
76  int intervalType = optBayes.intervalType;
77  int maxPOI = optBayes.maxPOI;
78  double nSigmaNuisance = optBayes.nSigmaNuisance;
79 
80 
81 
82  // -------------------------------------------------------
83  // First part is just to access a user-defined file
84  // or create the standard example file if it doesn't exist
85 
86  const char* filename = "";
87  if (!strcmp(infile,"")) {
88  filename = "results/example_combined_GaussExample_model.root";
89  bool fileExist = !gSystem->AccessPathName(filename); // note opposite return code
90  // if file does not exists generate with histfactory
91  if (!fileExist) {
92 #ifdef _WIN32
93  cout << "HistFactory file cannot be generated on Windows - exit" << endl;
94  return;
95 #endif
96  // Normally this would be run on the command line
97  cout <<"will run standard hist2workspace example"<<endl;
98  gROOT->ProcessLine(".! prepareHistFactory .");
99  gROOT->ProcessLine(".! hist2workspace config/example.xml");
100  cout <<"\n\n---------------------"<<endl;
101  cout <<"Done creating example input"<<endl;
102  cout <<"---------------------\n\n"<<endl;
103  }
104 
105  }
106  else
107  filename = infile;
108 
109  // Try to open the file
110  TFile *file = TFile::Open(filename);
111 
112  // if input file was specified byt not found, quit
113  if(!file ){
114  cout <<"StandardRooStatsDemoMacro: Input file " << filename << " is not found" << endl;
115  return;
116  }
117 
118 
119  // -------------------------------------------------------
120  // Tutorial starts here
121  // -------------------------------------------------------
122 
123  // get the workspace out of the file
124  RooWorkspace* w = (RooWorkspace*) file->Get(workspaceName);
125  if(!w){
126  cout <<"workspace not found" << endl;
127  return;
128  }
129 
130  // get the modelConfig out of the file
131  ModelConfig* mc = (ModelConfig*) w->obj(modelConfigName);
132 
133  // get the modelConfig out of the file
134  RooAbsData* data = w->data(dataName);
135 
136  // make sure ingredients are found
137  if(!data || !mc){
138  w->Print();
139  cout << "data or ModelConfig was not found" <<endl;
140  return;
141  }
142 
143  // ------------------------------------------
144  // create and use the BayesianCalculator
145  // to find and plot the 95% credible interval
146  // on the parameter of interest as specified
147  // in the model config
148 
149  // before we do that, we must specify our prior
150  // it belongs in the model config, but it may not have
151  // been specified
152  RooUniform prior("prior","",*mc->GetParametersOfInterest());
153  w->import(prior);
154  mc->SetPriorPdf(*w->pdf("prior"));
155 
156  // do without systematics
157  //mc->SetNuisanceParameters(RooArgSet() );
158  if (nSigmaNuisance > 0) {
159  RooAbsPdf * pdf = mc->GetPdf();
160  assert(pdf);
161  RooFitResult * res = pdf->fitTo(*data, Save(true), Minimizer(ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str()), Hesse(true),
163 
164  res->Print();
165  RooArgList nuisPar(*mc->GetNuisanceParameters());
166  for (int i = 0; i < nuisPar.getSize(); ++i) {
167  RooRealVar * v = dynamic_cast<RooRealVar*> (&nuisPar[i] );
168  assert( v);
169  v->setMin( TMath::Max( v->getMin(), v->getVal() - nSigmaNuisance * v->getError() ) );
170  v->setMax( TMath::Min( v->getMax(), v->getVal() + nSigmaNuisance * v->getError() ) );
171  std::cout << "setting interval for nuisance " << v->GetName() << " : [ " << v->getMin() << " , " << v->getMax() << " ]" << std::endl;
172  }
173  }
174 
175 
176  BayesianCalculator bayesianCalc(*data,*mc);
177  bayesianCalc.SetConfidenceLevel(confLevel); // 95% interval
178 
179  // default of the calculator is central interval. here use shortest , central or upper limit depending on input
180  // doing a shortest interval might require a longer time since it requires a scan of the posterior function
181  if (intervalType == 0) bayesianCalc.SetShortestInterval(); // for shortest interval
182  if (intervalType == 1) bayesianCalc.SetLeftSideTailFraction(0.5); // for central interval
183  if (intervalType == 2) bayesianCalc.SetLeftSideTailFraction(0.); // for upper limit
184 
185  if (!integrationType.IsNull() ) {
186  bayesianCalc.SetIntegrationType(integrationType); // set integrationType
187  bayesianCalc.SetNumIters(nToys); // set number of iterations (i.e. number of toys for MC integrations)
188  }
189 
190  // in case of toyMC make a nuisance pdf
191  if (integrationType.Contains("TOYMC") ) {
192  RooAbsPdf * nuisPdf = RooStats::MakeNuisancePdf(*mc, "nuisance_pdf");
193  cout << "using TOYMC integration: make nuisance pdf from the model " << std::endl;
194  nuisPdf->Print();
195  bayesianCalc.ForceNuisancePdf(*nuisPdf);
196  scanPosterior = true; // for ToyMC the posterior is scanned anyway so used given points
197  }
198 
199  // compute interval by scanning the posterior function
200  if (scanPosterior)
201  bayesianCalc.SetScanOfPosterior(nScanPoints);
202 
204  if (maxPOI != -999 && maxPOI > poi->getMin())
205  poi->setMax(maxPOI);
206 
207 
208  SimpleInterval* interval = bayesianCalc.GetInterval();
209 
210  // print out the interval on the first Parameter of Interest
211  cout << "\n>>>> RESULT : " << confLevel*100 << "% interval on " << poi->GetName()<<" is : ["<<
212  interval->LowerLimit() << ", "<<
213  interval->UpperLimit() <<"] "<<endl;
214 
215 
216  // make a plot
217  // since plotting may take a long time (it requires evaluating
218  // the posterior in many points) this command will speed up
219  // by reducing the number of points to plot - do 50
220 
221  // ignore errors of PDF if is zero
223 
224 
225  cout << "\nDrawing plot of posterior function....." << endl;
226 
227  // always plot using numer of scan points
228  bayesianCalc.SetScanOfPosterior(nScanPoints);
229 
230  RooPlot * plot = bayesianCalc.GetPosteriorPlot();
231  plot->Draw();
232 
233 }
virtual Double_t getMin(const char *name=0) const
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1276
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
Definition: ModelConfig.h:30
virtual Double_t getMax(const char *name=0) const
RooAbsPdf * MakeNuisancePdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name)
RooCmdArg PrintLevel(Int_t code)
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
#define gROOT
Definition: TROOT.h:402
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
void setMax(const char *name, Double_t value)
Set maximum of name range to given value.
Definition: RooRealVar.cxx:418
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooFitResult.h:66
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3950
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
virtual Double_t LowerLimit()
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...
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
static const std::string & DefaultMinimizerType()
SVector< double, 2 > v
Definition: Dict.h:5
RooAbsArg * first() const
RooCmdArg Minimizer(const char *type, const char *alg=0)
void setMin(const char *name, Double_t value)
Set minimum of name range to given value.
Definition: RooRealVar.cxx:388
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
Flat p.d.f.
Definition: RooUniform.h:24
TObject * obj(const char *name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name) ...
A RooPlot is a plot frame and a container for graphics objects within that frame. ...
Definition: RooPlot.h:41
Namespace for the RooStats classes.
Definition: Asimov.h:20
RooAbsPdf * GetPdf() const
get model PDF (return NULL if pdf has not been specified or does not exist)
Definition: ModelConfig.h:222
const RooArgSet * GetParametersOfInterest() const
get RooArgSet containing the parameter of interest (return NULL if not existing)
Definition: ModelConfig.h:225
RooCmdArg Hesse(Bool_t flag=kTRUE)
RooAbsPdf * pdf(const char *name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
virtual void SetPriorPdf(const RooAbsPdf &pdf)
Set the Prior Pdf, add to the the workspace if not already there.
Definition: ModelConfig.h:81
RooCmdArg Save(Bool_t flag=kTRUE)
virtual Double_t UpperLimit()
SimpleInterval is a concrete implementation of the ConfInterval interface.
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
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.
Definition: file.py:1
const RooArgSet * GetNuisanceParameters() const
get RooArgSet containing the nuisance parameters (return NULL if not existing)
Definition: ModelConfig.h:228
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
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 getError() const
Definition: RooRealVar.h:53
void Print(Option_t *opts=0) const
Print contents of the workspace.
BayesianCalculator is a concrete implementation of IntervalCalculator, providing the computation of a...
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:42
virtual void Draw(Option_t *options=0)
Draw this plot and all of the elements it contains.
Definition: RooPlot.cxx:559