Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
StandardFrequentistDiscovery.py
Go to the documentation of this file.
1# \file
2# \ingroup tutorial_roostats
3# \notebook
4# StandardFrequentistDiscovery
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# \macro_image
18# \macro_output
19# \macro_code
20#
21# \authors Sven Kreiss, Kyle Cranmer (C++ version), and P. P. (Python translation)
22
23
24import ROOT
25
26
28 infile="",
29 workspaceName="channel1",
30 modelConfigNameSB="ModelConfig",
31 dataName="obsData",
32 toys=1000,
33 poiValueForBackground=0.0,
34 poiValueForSignal=1.0,
35):
36
37 # The workspace contains the model for s+b. The b model is "autogenerated"
38 # by copying s+b and setting the one parameter of interest to zero.
39 # To keep the script simple, multiple parameters of interest or different
40 # functional forms of the b model are not supported.
41
42 # for now, assume there is only one parameter of interest, and these are
43 # its values:
44
45 # -------------------------------------------------------
46 # First part is just to access a user-defined file
47 # or create the standard example file if it doesn't exist
48 filename = ""
49 if infile == "":
50 filename = "results/example_channel1_GammaExample_model.root"
51 fileExist = not ROOT.gSystem.AccessPathName(filename) # note opposite return code
52 # if file does not exists generate with histfactory
53 if not fileExist:
54 # Normally this would be run on the command line
55 print(f"will run standard hist2workspace example")
56 ROOT.gROOT.ProcessLine(".! prepareHistFactory .")
57 ROOT.gROOT.ProcessLine(".! hist2workspace config/example.xml")
58 print(f"\n\n---------------------")
59 print(f"Done creating example input")
60 print(f"---------------------\n\n")
61
62 else:
63 filename = infile
64
65 # Try to open the file
66 file = ROOT.TFile.Open(filename)
67
68 # if input file was specified but not found, quit
69 if not file:
70 print(f"StandardRooStatsDemoMacro: Input file {filename} is not found")
71 return -1
72
73 # -------------------------------------------------------
74 # Tutorial starts here
75 # -------------------------------------------------------
76
77 mn_t = ROOT.TStopwatch()
79
80 # get the workspace out of the file
81 w = file.Get(workspaceName)
82 if not w:
83 print(f"workspace not found")
84 return -1.0
85
86 # get the modelConfig out of the file
87 mc = w[modelConfigNameSB]
88
89 # get the data out of the file
90 data = w[dataName]
91
92 # make sure ingredients are found
93 if not data or not mc:
94 w.Print()
95 print(f"data or ModelConfig was not found")
96 return -1.0
97
98 firstPOI = mc.GetParametersOfInterest().first()
99 firstPOI.setVal(poiValueForSignal)
101 # create null model
102 mcNull = mc.Clone("ModelConfigNull")
103 firstPOI.setVal(poiValueForBackground)
105
106 # ----------------------------------------------------
107 # Configure a ProfileLikelihoodTestStat and a SimpleLikelihoodRatioTestStat
108 # to use simultaneously with ToyMCSampler
111 plts.SetVarName("q_0/2")
112
113 # ----------------------------------------------------
114 # configure the ToyMCImportanceSampler with two test statistics
115 toymcs = ROOT.RooStats.ToyMCSampler(plts, 50)
116
117 # Since this tool needs to throw toy MC the PDF needs to be
118 # extended or the tool needs to know how many entries in a dataset
119 # per pseudo experiment.
120 # In the 'number counting form' where the entries in the dataset
121 # are counts, and not values of discriminating variables, the
122 # datasets typically only have one entry and the PDF is not
123 # extended.
124 if not mc.GetPdf().canBeExtended():
125 if data.numEntries() == 1:
127 else:
128 print(f"Not sure what to do about this model")
129
130 # instantiate the calculator
131 freqCalc = ROOT.RooStats.FrequentistCalculator(data, mc, mcNull, toymcs)
132 freqCalc.SetToys(toys, toys) # null toys, alt toys
133
134 # Run the calculator and print result
135 freqCalcResult = freqCalc.GetHypoTest()
136 freqCalcResult.GetNullDistribution().SetTitle("b only")
137 freqCalcResult.GetAltDistribution().SetTitle("s+b")
140
141 # stop timing
142 mn_t.Stop()
143 print(f"total CPU time: ", mn_t.CpuTime())
144 print(f"total real time: ", mn_t.RealTime())
145
146 # plot
147 c1 = ROOT.TCanvas()
148 plot = ROOT.RooStats.HypoTestPlot(freqCalcResult, 100, -0.49, 9.51)
149 plot.SetLogYaxis(True)
150 plot.Draw()
151 c1.Update()
152 c1.Draw()
153 c1.SaveAs("StandardFrequentistDiscovery.1.png")
154
155 # adding chi2 to plot a different plot.
156 # plot 1 and plot 2 have problems at HypoTestPlot.AddTF1
157 c2 = ROOT.TCanvas("myc2", "myc2")
158 nPOI = 1
159 # g = TF1("g", TString.Format("1*ROOT::Math::chisquared_pdf(2*x,{},0)".format( nPOI)), 0, 9) # doesn´t work properly
160 scale_ctte = 0.2
162 f"""TF1 *g = new TF1("g", TString::Format("{scale_ctte}*ROOT::Math::chisquared_pdf(2*x,%d,0)", {nPOI}), 0, 9);"""
163 )
164 g = ROOT.g
167 plot2 = ROOT.RooStats.HypoTestPlot(freqCalcResult, 100, -0.49, 9.51)
168 tmptitle = f"#chi^{{2}}(2x,{nPOI})"
169 plot2.AddTF1(g, tmptitle, "SAME")
171 plot2.Draw()
172
173 c2.Update()
174 c2.Draw()
175 c2.SaveAs("StandardFrequentistDiscovery.2.png")
176
177 return pvalue
178
179
181 infile="",
182 workspaceName="channel1",
183 modelConfigNameSB="ModelConfig",
184 dataName="obsData",
185 toys=1000,
186 poiValueForBackground=0.0,
187 poiValueForSignal=1.0,
188)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.