Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
StandardFeldmanCousinsDemo.py
Go to the documentation of this file.
1# \file
2# \ingroup tutorial_roostats
3# \notebook -js
4# Standard demo of the Feldman-Cousins calculator
5# StandardFeldmanCousinsDemo
6#
7# This is a standard demo that can be used with any ROOT file
8# prepared in the standard way. You specify:
9# - name for input ROOT file
10# - name of workspace inside ROOT file that holds model and data
11# - name of ModelConfig that specifies details for calculator tools
12# - name of dataset
13#
14# With default parameters the macro will attempt to run the
15# standard hist2workspace example and read the ROOT file
16# that it produces.
17#
18# The actual heart of the demo is only about 10 lines long.
19#
20# The FeldmanCousins tools is a classical frequentist calculation
21# based on the Neyman Construction. The test statistic can be
22# generalized for nuisance parameters by using the profile likelihood ratio.
23# But unlike the ProfileLikelihoodCalculator, this tool explicitly
24# builds the sampling distribution of the test statistic via toy Monte Carlo.
25#
26# \macro_image
27# \macro_output
28# \macro_code
29#
30# \author Kyle Cranmer (C++ version), and P. P. (Python translation)
31
32
33import ROOT
34
35
36def StandardFeldmanCousinsDemo(infile="", workspaceName="combined", modelConfigName="ModelConfig", dataName="obsData"):
37
38 # -------------------------------------------------------
39 # First part is just to access a user-defined file
40 # or create the standard example file if it doesn't exist
41 filename = ""
42 if infile == "":
43 filename = "results/example_combined_GaussExample_model.root"
44 fileExist = not ROOT.gSystem.AccessPathName(filename) # note opposite return code
45 # if file does not exists generate with histfactory
46 if not fileExist:
47 # Normally this would be run on the command line
48 print(f"will run standard hist2workspace example")
49 ROOT.gROOT.ProcessLine(".! prepareHistFactory .")
50 ROOT.gROOT.ProcessLine(".! hist2workspace config/example.xml")
51 print(f"\n\n---------------------")
52 print(f"Done creating example input")
53 print(f"---------------------\n\n")
54
55 else:
56 filename = infile
57
58 # Try to open the file
59 file = ROOT.TFile.Open(filename)
60
61 # if input file was specified but not found, quit
62 if not file:
63 print(f"StandardRooStatsDemoMacro: Input file {filename} is not found")
64 return
65
66 # -------------------------------------------------------
67 # Tutorial starts here
68 # -------------------------------------------------------
69
70 # get the workspace out of the file
71 w = file.Get(workspaceName)
72 if not w:
73 print(f"workspace not found")
74 return
75
76 # get the modelConfig out of the file
77 mc = w.obj(modelConfigName)
78
79 # get the modelConfig out of the file
80 data = w.data(dataName)
81
82 # make sure ingredients are found
83 if not data or not mc:
84 w.Print()
85 print(f"data or ModelConfig was not found")
86 return
87
88 # -------------------------------------------------------
89 # create and use the FeldmanCousins tool
90 # to find and plot the 95% confidence interval
91 # on the parameter of interest as specified
92 # in the model config
93 fc = ROOT.RooStats.FeldmanCousins(data, mc)
94 fc.SetConfidenceLevel(0.95) # 95% interval
95 # fc.AdditionalNToysFactor(0.1); # to speed up the result
96 fc.UseAdaptiveSampling(True) # speed it up a bit
97 fc.SetNBins(10) # set how many points per parameter of interest to scan
98 fc.CreateConfBelt(True) # save the information in the belt for plotting
99
100 # Since this tool needs to throw toy MC the PDF needs to be
101 # extended or the tool needs to know how many entries in a dataset
102 # per pseudo experiment.
103 # In the 'number counting form' where the entries in the dataset
104 # are counts, and not values of discriminating variables, the
105 # datasets typically only have one entry and the PDF is not
106 # extended.
107 if not mc.GetPdf().canBeExtended():
108 if data.numEntries() == 1:
109 fc.FluctuateNumDataEntries(False)
110 else:
111 print(f"Not sure what to do about this model")
112
113 # Now get the interval
114 interval = fc.GetInterval()
115 belt = fc.GetConfidenceBelt()
116
117 # print out the interval on the first Parameter of Interest
118 firstPOI = mc.GetParametersOfInterest().first()
119 print(
120 f"\n95% interval on {firstPOI.GetName()} is : [{interval.LowerLimit(firstPOI)}, ",
121 interval.UpperLimit(firstPOI),
122 "] ",
123 )
124
125 # ---------------------------------------------
126 # No nice plots yet, so plot the belt by hand
127
128 # Ask the calculator which points were scanned
129 parameterScan = fc.GetPointsToScan()
130 tmpPoint = ROOT.RooArgSet()
131
132 # make a histogram of parameter vs. threshold
133 histOfThresholds = ROOT.TH1F(
134 "histOfThresholds", "", parameterScan.numEntries(), firstPOI.getMin(), firstPOI.getMax()
135 )
136
137 # loop through the points that were tested and ask confidence belt
138 # what the upper/lower thresholds were.
139 # For FeldmanCousins, the lower cut off is always 0
140 for i in range(parameterScan.numEntries()):
141 tmpPoint = parameterScan.get(i).clone("temp")
142 arMax = belt.GetAcceptanceRegionMax(tmpPoint)
143 arMin = belt.GetAcceptanceRegionMax(tmpPoint)
144 poiVal = tmpPoint.getRealValue(firstPOI.GetName())
145 histOfThresholds.Fill(poiVal, arMax)
146
147 histOfThresholds.SetMinimum(0)
148 c_belt = ROOT.TCanvas("c_belt", "c_belt")
149 histOfThresholds.Draw()
150 c_belt.Update()
151 c_belt.Draw()
152 c_belt.SaveAs("StandardFeldmanCousinsDemo.1.belt.png")
153
154
155StandardFeldmanCousinsDemo(infile="", workspaceName="combined", modelConfigName="ModelConfig", dataName="obsData")