ROOT
Version v6.32
master
v6.34
v6.30
v6.28
v6.26
v6.24
v6.22
v6.20
v6.18
v6.16
v6.14
v6.12
v6.10
v6.08
v6.06
Reference Guide
►
ROOT
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Modules
Pages
Loading...
Searching...
No Matches
rs_bernsteinCorrection.py
Go to the documentation of this file.
1
## \file
2
## \ingroup tutorial_roostats
3
## \notebook -js
4
## Example of the BernsteinCorrection utility in RooStats.
5
##
6
## The idea is that one has a distribution coming either from data or Monte Carlo
7
## (called "reality" in the macro) and a nominal model that is not sufficiently
8
## flexible to take into account the real distribution. One wants to take into
9
## account the systematic associated with this imperfect modeling by augmenting
10
## the nominal model with some correction term (in this case a polynomial).
11
## The BernsteinCorrection utility will import into your workspace a corrected model
12
## given by nominal(x) * poly_N(x), where poly_N is an n-th order polynomial in
13
## the Bernstein basis. The degree N of the polynomial is chosen by specifying the tolerance
14
## one has in adding an extra term to the polynomial.
15
## The Bernstein basis is nice because it only has positive-definite terms
16
## and works well with PDFs.
17
## Finally, the macro makes a plot of:
18
## - the data (drawn from 'reality'),
19
## - the best fit of the nominal model (blue)
20
## - and the best fit corrected model.
21
##
22
## \macro_image
23
## \macro_output
24
## \macro_code
25
##
26
## \date June 2022
27
## \authors Artem Busorgin, Kyle Cranmer (C++ version)
28
29
import
sys
30
import
ROOT
31
32
# set range of observable
33
lowRange = -1
34
highRange = 5
35
36
# make a RooRealVar for the observable
37
x =
ROOT.RooRealVar
(
"x"
,
"x"
, lowRange, highRange)
38
39
# true model
40
narrow =
ROOT.RooGaussian
(
"narrow"
,
""
, x,
ROOT.RooFit.RooConst
(0.0),
ROOT.RooFit.RooConst
(0.8))
41
wide =
ROOT.RooGaussian
(
"wide"
,
""
, x,
ROOT.RooFit.RooConst
(0.0),
ROOT.RooFit.RooConst
(2.0))
42
reality =
ROOT.RooAddPdf
(
"reality"
,
""
, [narrow, wide],
ROOT.RooFit.RooConst
(0.8))
43
44
data =
reality.generate
(x, 1000)
45
46
# nominal model
47
sigma =
ROOT.RooRealVar
(
"sigma"
,
""
, 1.0, 0, 10)
48
nominal =
ROOT.RooGaussian
(
"nominal"
,
""
, x,
ROOT.RooFit.RooConst
(0.0), sigma)
49
50
wks =
ROOT.RooWorkspace
(
"myWorksspace"
)
51
52
wks.Import
(data, Rename=
"data"
)
53
wks.Import
(nominal)
54
55
if
ROOT.TClass.GetClass
(
"ROOT::Minuit2::Minuit2Minimizer"
):
56
# use Minuit2 if ROOT was built with support for it:
57
ROOT.Math.MinimizerOptions.SetDefaultMinimizer
(
"Minuit2"
)
58
59
# The tolerance sets the probability to add an unnecessary term.
60
# lower tolerance will add fewer terms, while higher tolerance
61
# will add more terms and provide a more flexible function.
62
tolerance = 0.05
63
bernsteinCorrection =
ROOT.RooStats.BernsteinCorrection
(tolerance)
64
degree =
bernsteinCorrection.ImportCorrectedPdf
(wks,
"nominal"
,
"x"
,
"data"
)
65
66
if
degree < 0:
67
ROOT.Error
(
"rs_bernsteinCorrection"
,
"Bernstein correction failed !"
)
68
sys.exit
()
69
70
print(
"Correction based on Bernstein Poly of degree "
, degree)
71
72
frame =
x.frame
()
73
data.plotOn
(frame)
74
# plot the best fit nominal model in blue
75
nominal.fitTo
(data, PrintLevel=0)
76
nominal.plotOn
(frame)
77
78
# plot the best fit corrected model in red
79
corrected = wks[
"corrected"
]
80
if
not
corrected:
81
sys.exit
()
82
83
# fit corrected model
84
corrected.fitTo
(data, PrintLevel=0)
85
corrected.plotOn
(frame, LineColor=
"r"
)
86
87
# plot the correction term (* norm constant) in dashed green
88
# should make norm constant just be 1, not depend on binning of data
89
poly = wks[
"poly"
]
90
if
poly:
91
poly.plotOn
(frame, LineColor=
"g"
, LineStyle=
"--"
)
92
93
# this is a switch to check the sampling distribution
94
# of -2 log LR for two comparisons:
95
# the first is for n-1 vs. n degree polynomial corrections
96
# the second is for n vs. n+1 degree polynomial corrections
97
# Here we choose n to be the one chosen by the tolerance
98
# criterion above, eg. n = "degree" in the code.
99
# Setting this to true is takes about 10 min.
100
checkSamplingDist =
True
101
numToyMC = 20
# increase this value for sensible results
102
103
c1 =
ROOT.TCanvas
()
104
if
checkSamplingDist:
105
c1.Divide
(1, 2)
106
c1.cd
(1)
107
108
frame.Draw
()
109
ROOT.gPad.Update
()
110
111
if
checkSamplingDist:
112
# check sampling dist
113
ROOT.Math.MinimizerOptions.SetDefaultPrintLevel
(-1)
114
samplingDist =
ROOT.TH1F
(
"samplingDist"
,
""
, 20, 0, 10)
115
samplingDistExtra =
ROOT.TH1F
(
"samplingDistExtra"
,
""
, 20, 0, 10)
116
bernsteinCorrection.CreateQSamplingDist
(
117
wks,
"nominal"
,
"x"
,
"data"
, samplingDist, samplingDistExtra, degree, numToyMC
118
)
119
120
c1.cd
(2)
121
samplingDistExtra.SetLineColor
(
ROOT.kRed
)
122
samplingDistExtra.Draw
()
123
samplingDist.Draw
(
"same"
)
124
125
c1.SaveAs
(
"rs_bernsteinCorrection.png"
)
TRangeDynCast
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Definition
TCollection.h:358
tutorials
roostats
rs_bernsteinCorrection.py
ROOT v6-32 - Reference Guide Generated on Thu Mar 27 2025 04:51:55 (GVA Time) using Doxygen 1.10.0