Loading [MathJax]/extensions/tex2jax.js
Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
rf613_global_observables.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_roofit
3/// \notebook -js
4/// This tutorial explains the concept of global observables in RooFit, and
5/// showcases how their values can be stored either in the model or in the
6/// dataset.
7///
8/// ### Introduction
9///
10/// Note: in this tutorial, we are multiplying the likelihood with an additional
11/// likelihood to constrain the parameters with auxiliary measurements. This is
12/// different from the `rf604_constraints` tutorial, where the likelihood is
13/// multiplied with a Bayesian prior to constrain the parameters.
14///
15///
16/// With RooFit, you usually optimize some model parameters `p` to maximize the
17/// likelihood `L` given the per-event or per-bin ## observations `x`:
18///
19/// \f[ L( x | p ) \f]
20///
21/// Often, the parameters are constrained with some prior likelihood `C`, which
22/// doesn't depend on the observables `x`:
23///
24/// \f[ L'( x | p ) = L( x | p ) * C( p ) \f]
25///
26/// Usually, these constraint terms depend on some auxiliary measurements of
27/// other observables `g`. The constraint term is then the likelihood of the
28/// so-called global observables:
29///
30/// \f[ L'( x | p ) = L( x | p ) * C( g | p ) \f]
31///
32/// For example, think of a model where the true luminosity `lumi` is a
33/// nuisance parameter that is constrained by an auxiliary measurement
34/// `lumi_obs` with uncertainty `lumi_obs_sigma`:
35///
36/// \f[ L'(data | mu, lumi) = L(data | mu, lumi) * Gauss(lumi_obs | lumi, lumi_obs_sigma) \f]
37///
38/// As a Gaussian is symmetric under exchange of the observable and the mean
39/// parameter, you can also sometimes find this equivalent but less conventional
40/// formulation for Gaussian constraints:
41///
42/// \f[ L'(data | mu, lumi) = L(data | mu, lumi) * Gauss(lumi | lumi_obs, lumi_obs_sigma) \f]
43///
44/// If you wanted to constrain a parameter that represents event counts, you
45/// would use a Poissonian constraint, e.g.:
46///
47/// \f[ L'(data | mu, count) = L(data | mu, count) * Poisson(count_obs | count) \f]
48///
49/// Unlike a Guassian, a Poissonian is not symmetric under exchange of the
50/// observable and the parameter, so here you need to be more careful to follow
51/// the global observable prescription correctly.
52///
53///
54/// \macro_code
55///
56/// \date January 2022
57/// \author Jonas Rembser
58
59#include <RooArgSet.h>
60#include <RooConstVar.h>
61#include <RooDataSet.h>
62#include <RooFitResult.h>
63#include <RooGaussian.h>
64#include <RooProdPdf.h>
65#include <RooRealVar.h>
66
68{
69 using namespace RooFit;
70
71 // Setting up the model and creating toy dataset
72 // ---------------------------------------------
73
74 // l'(x | mu, sigma) = l(x | mu, sigma) * Gauss(mu_obs | mu, 0.2)
75
76 // event observables
77 RooRealVar x("x", "x", -10, 10);
78
79 // parameters
80 RooRealVar mu("mu", "mu", 0.0, -10, 10);
81 RooRealVar sigma("sigma", "sigma", 1.0, 0.1, 2.0);
82
83 // Gaussian model for event observables
84 RooGaussian gauss("gauss", "gauss", x, mu, sigma);
85
86 // global observables (which are not parameters so they are constant)
87 RooRealVar mu_obs("mu_obs", "mu_obs", 1.0, -10, 10);
88 mu_obs.setConstant();
89 // note: alternatively, one can create a constant with default limits using `RooRealVar("mu_obs", "mu_obs", 1.0)`
90
91 // constraint pdf
92 RooGaussian constraint("constraint", "constraint", mu_obs, mu, RooConst(0.2));
93
94 // full pdf including constraint pdf
95 RooProdPdf model("model", "model", {gauss, constraint});
96
97 // Generating toy data with randomized global observables
98 // ------------------------------------------------------
99
100 // For most toy-based statistical procedures, it is necessary to also
101 // randomize the global observable when generating toy datasets.
102 //
103 // To that end, let's generate a single event from the model and take the
104 // global observable value (the same is done in the RooStats:ToyMCSampler
105 // class):
106
107 std::unique_ptr<RooDataSet> dataGlob{model.generate({mu_obs}, 1)};
108
109 // Next, we temporarily set the value of `mu_obs` to the randomized value for
110 // generating our toy dataset:
111 double mu_obs_orig_val = mu_obs.getVal();
112
113 RooArgSet{mu_obs}.assign(*dataGlob->get(0));
114
115 // actually generate the toy dataset
116 std::unique_ptr<RooDataSet> data{model.generate({x}, 1000)};
117
118 // When fitting the toy dataset, it is important to set the global
119 // observables in the fit to the values that were used to generate the toy
120 // dataset. To facilitate the bookkeeping of global observable values, you
121 // can attach a snapshot with the current global observable values to the
122 // dataset like this (new feature introduced in ROOT 6.26):
123
124 data->setGlobalObservables({mu_obs});
125
126 // reset original mu_obs value
127 mu_obs.setVal(mu_obs_orig_val);
128
129 // Fitting a model with global observables
130 // ---------------------------------------
131
132 // Create snapshot of original parameters to reset parameters after fitting
133 RooArgSet modelParameters;
134 model.getParameters(data->get(), modelParameters);
135 RooArgSet origParameters;
136 modelParameters.snapshot(origParameters);
137
138 using FitRes = std::unique_ptr<RooFitResult>;
139
140 // When you fit a model that includes global observables, you need to
141 // specify them in the call to RooAbsPdf::fitTo with the
142 // RooFit::GlobalObservables command argument. By default, the global
143 // observable values attached to the dataset will be prioritized over the
144 // values in the model, so the following fit correctly uses the randomized
145 // global observable values from the toy dataset:
146 std::cout << "1. model.fitTo(*data, GlobalObservables(mu_obs))\n";
147 std::cout << "------------------------------------------------\n\n";
148 FitRes res1{model.fitTo(*data, GlobalObservables(mu_obs), PrintLevel(-1), Save())};
149 res1->Print();
150 modelParameters.assign(origParameters);
151
152 // In our example, the set of global observables is attached to the toy
153 // dataset. In this case, you can actually drop the GlobalObservables()
154 // command argument, because the global observables are automatically
155 // figured out from the data set (this fit result should be identical to the
156 // previous one).
157 std::cout << "2. model.fitTo(*data)\n";
158 std::cout << "---------------------\n\n";
159 FitRes res2{model.fitTo(*data, PrintLevel(-1), Save())};
160 res2->Print();
161 modelParameters.assign(origParameters);
162
163 // If you want to explicitly ignore the global observables in the dataset,
164 // you can do that by specifying GlobalObservablesSource("model"). Keep in
165 // mind that now it's also again your responsability to define the set of
166 // global observables.
167 std::cout << "3. model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource(\"model\"))\n";
168 std::cout << "------------------------------------------------\n\n";
169 FitRes res3{model.fitTo(*data, GlobalObservables(mu_obs), GlobalObservablesSource("model"), PrintLevel(-1), Save())};
170 res3->Print();
171 modelParameters.assign(origParameters);
172}
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
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:58
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:35
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:158
Plain Gaussian p.d.f.
Definition RooGaussian.h:24
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition RooProdPdf.h:33
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:39
RooConstVar & RooConst(Double_t val)
RooCmdArg GlobalObservables(Args_t &&... argsOrArgSet)
RooCmdArg GlobalObservablesSource(const char *sourceName)
RooCmdArg Save(Bool_t flag=kTRUE)
RooCmdArg PrintLevel(Int_t code)
const Double_t sigma
Double_t x[n]
Definition legend1.C:17
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18