Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ModelInspector.py
Go to the documentation of this file.
1# \file
2# \ingroup tutorial_roostats
3# RooStats Model Inspector
4#
5# Usage:
6# The usage is the same as the StandardXxxDemo.py Python Scripts.
7# The macro expects a root file containing a workspace with a ModelConfig and a dataset
8#
9# ~~~{.py}
10# $ ipython3
11# %run ModelInspector.py
12# #ModelInspector(fileName, workspaceName, modelConfigName, dataSetName)
13# ~~~
14# Fails with normal python.
15# Drag the sliders to adjust the parameters of the model.
16# the min and max range of the sliders are used to define the upper & lower variation
17# the pointer position of the slider is the central blue curve.
18#
19# Click the FIT button to
20#
21# To Do:
22# - Check a better way to exit without crashing.
23# - check boxes to specify which nuisance parameters used in making variation
24# - a button to make the profile inspector plots
25# - a check button to use MINOS errors
26# - have fit button show the covariance matrix from the fit
27# - a button to make the log likelihood plots
28# - a dialog to open the desired file
29# - ability to see the signal and background contributions?
30#
31# \macro_code
32#
33# - Version 1, October 2011
34# - based on tutorial macro by Bertrand Bellenot, Ilka Antcheva
35# - Version 2, November 2011
36# - fixes from Bertrand Bellenot for scrolling window for many parameters
37# - Version 3, April 2024
38# - translation from C++ macros to python3
39#
40# \author Kyle Cranmer (C++ version), and P. P. (Python translation)
41
42import sys
43import ROOT
44
45from enum import Enum
46
47
48class ETestCommandIdentifiers(Enum):
49 HId1 = 1
50 HId2 = 2
51 HId3 = 3
52 HCId1 = 4
53 HCId2 = 5
54 HSId1 = 6
55
56
57ETestCmdId = ETestCommandIdentifiers
58
59
60class ModelInspectorGUI(ROOT.TGMainFrame):
61 # private:
62 # -fCanvas = TRootEmbeddedCanvas()
63 # -fLcan = TGLayoutHints()
64 # -fFitFcn = TF1()
65 # -fPlot = RooPlot()
66 # -fWS = RooWorkspace()
67 # -fFile = TFile()
68 # -fMC = ModelConfig()
69 # -fData = super(RooAbsData)
70 # -fFitRes = RooFitResult()
71 # -
72 # -fSliderList = TList()
73 # -fFrameList = TList()
74 # -fPlotList = vector("RooPlot *")()
75 # -fSliderMap = ROOT.map("TGTripleHSlider *", " TString " )() # it is an instance
76 # -
77 # -TSliderMap = ROOT.map(TGTripleHSlider , char ) # it is a type
78 # -fLabelMap = ROOT.map("TGTripleHSlider*" , "TGLabel *" )()
79 # -
80 # -fFitButton = TGButton()
81 # -fExitButton = TGTextButton()
82 # -
83 # -# BB: a TGCanvas and a vertical frame are needed for using scrollbars
84 # -fCan = TGCanvas()
85 # -fVFrame = TGVerticalFrame()
86 # -
87 # -fHframe0 = fHframe1 = fHframe2 = TGHorizontalFrame()
88 # -fBly = fBfly1 = fBfly2 = fBfly3 = TGLayoutHints()
89 # -fHslider1 = TGTripleHSlider()
90 # -fTbh1 = fTbh2 = fTbh3 = TGTextBuffer()
91 # -fCheck1 = fCheck2 = TGCheckButton()
92
93 # public:
94 # def __init__(RooWorkspace, ModelConfig, RooAbsData): pass
95 # def __del__() : pass
96
97 # def CloseWindow() : pass
98 # def DoText( str ): pass
99 # def DoSlider(): pass
100 # def DoSlider( str ): pass
101 # def DoFit(): pass
102 # def DoExit(): pass
103 # def HandleButtons(): pass
104
105 # ______________________________________________________________________________
106 def __del__(self):
107 # Clean up
108
109 self.Cleanup()
110
111 # ______________________________________________________________________________
112 def CloseWindow(self):
113 # Called when window is closed via the window manager.
114
115 del self
116 pass
117
118 # ______________________________________________________________________________
119 def DoText(self):
120 # Handle text entry widgets.
121
122 te = ROOT.BindObject(self.gTQSender, ROOT.TGTextEntry)
123 Id = te.WidgetId()
124 if Id == ETestCmdId.HId1.value:
125 fHslider1.SetPosition(atof(self.fTbh1.GetString()), self.fHslider1.GetMaxPosition())
126 elif Id == ETestCmdId.HId2.value:
127 fHslider1.SetPointerPosition(atof(self.fTbh2.GetString()))
128 elif Id == ETestCmdId.HId3.value:
129 fHslider1.SetPosition(self.fHslider1.GetMinPosition(), atof(self.fTbh1.GetString()))
130
131 self.DoSlider()
132
133 # ______________________________________________________________________________
134 def DoFit(self):
135 self.fFitRes = self.fMC.GetPdf().fitTo(self.fData, Save=True)
136
137 for it in self.fSliderMap:
138 param = self.fWS.var(it.second)
139 param = self.fFitRes.floatParsFinal().find(it.second.Data())
140 it.first.SetPosition(param.getVal() - param.getError(), param.getVal() + param.getError())
141 it.first.SetPointerPosition(param.getVal())
142
143 self.DoSlider()
144
145 # ______________________________________________________________________________
146 # def DoSlider(text = ""):
147
148 # print(f".", text)
149 #
150
151 # ______________________________________________________________________________
152 def DoSlider(self):
153 # Handle slider widgets.
154
155 # char buf[32];
156
157 simPdf = ROOT.nullptr
158 numCats = 0
159 if str(self.fMC.GetPdf().ClassName()) == "RooSimultaneous":
160 simPdf = self.fMC.GetPdf()
161 channelCat = simPdf.indexCat()
162 numCats = channelCat.numTypes()
163 else:
164 pass
165
166 ###############
167 if not simPdf:
168 ###############
169 # if not SimPdf
170 ###############
171
172 # pre loop
173 # map<TGTripleHSlider , const char >.iterator it
174 it = ROOT.map(TGTripleHSlider, char).iterator # it # unnecessary
175
176 # try :
177 # del self.fPlot
178 # except :
179 # pass
180 # self.fPlot = (self.fMC.GetObservables().first()).frame()
181 self.fPlot = (self.fMC.GetObservables().first()).frame()
182 self.fData.plotOn(self.fPlot)
183 normCount = Double_t()
184
185 # high loop
186 # it0 = self.fSliderMap.begin()
187 for it in self.fSliderMap:
188 name = it.second
189 self.fWS.var(name).setVal(it.first.GetMaxPosition())
190 param = self.fWS.var(name)
191 self.fLabelMap[it.first].SetText(
192 ROOT.Form(
193 "{:s} = {:.3}f [{:.3}f,{:.3}f]".format(
194 param.GetName(),
195 it.first.GetPointerPosition(),
196 it.first.GetMinPosition(),
197 it.first.GetMaxPosition(),
198 )
199 )
200 )
201
202 normCount = self.fMC.GetPdf().expectedEvents(self.fMC.GetObservables())
203 self.fMC.GetPdf().plotOn(
204 self.fPlot, ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent), LineColor="r"
205 )
206
207 # low loop
208 # it0 = self.fSliderMap.begin()
209 for it in self.fSliderMap:
210 name = it.second
211 self.fWS.var(name).setVal(it.first.GetMinPosition())
212
213 normCount = self.fMC.GetPdf().expectedEvents(self.fMC.GetObservables())
214 self.fMC.GetPdf().plotOn(
215 self.fPlot, ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent), LineColor="g"
216 )
217
218 # central loop
219 # it0 = self.fSliderMap.begin()
220 for it in self.fSliderMap:
221 name = it.second
222 self.fWS.var(name).setVal(it.first.GetPointerPosition())
223
224 normCount = self.fMC.GetPdf().expectedEvents(self.fMC.GetObservables())
225 self.fMC.GetPdf().plotOn(
226 self.fPlot, ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent), LineColor="b"
227 )
228 self.fPlot.Draw()
229
230 self.fCanvas.GetCanvas().Modified()
231 self.fCanvas.GetCanvas().Update()
232 #########################/
233 else:
234 #########################/
235 # else ( indentation belongs to "if simpdf")
236 #########################/
237 channelCat = simPdf.indexCat()
238 # TIterator* iter = simPdf->indexCat().typeIterator() ;
239 frameIndex = 0
240 global gchannelCat
241 gchannelCat = channelCat
242 for tt in channelCat:
243 catName = tt.first
244
245 frameIndex += 1
246 self.fCanvas.GetCanvas().cd(frameIndex)
247
248 # pre loop
249 pdftmp = simPdf.getPdf(str(catName))
250 obstmp = pdftmp.getObservables(self.fMC.GetObservables())
251 global ggpdftmp, gobstmp
252 ggpdftmp = pdftmp
253 gobstmp = obstmp
254 # return
255 obs = obstmp.first()
256 # fplotlist is a template, plotlist is the actual vector<RooPlot> with dim numCats
257 global gframeIndex
258 gframeIndex = frameIndex
259 global gfPlotList
260 gfPlotList = self.fPlotList
261 self.fPlot = self.fPlotList[frameIndex - 1]
262 if self.fPlot:
263 del self.fPlot
264 self.fPlot = obs.frame()
265
266 self.fPlotList[frameIndex - 1] = self.fPlot
267 # plotlist[(frameIndex - 1)] = fPlot
268
269 msglevel = ROOT.RooMsgService.instance().globalKillBelow()
270 ROOT.RooMsgService.instance().setGlobalKillBelow(ROOT.RooFit.WARNING)
271 # """
272 self.fData.plotOn(
273 self.fPlot,
274 MarkerSize=1,
275 Cut=ROOT.Form("{:s}=={:s}::{:s}".format(channelCat.GetName(), channelCat.GetName(), str(catName))),
276 DataError="None",
277 )
278 # """
279
280 # self.fData.plotOn(self.fPlot)
281
282 ROOT.RooMsgService.instance().setGlobalKillBelow(msglevel)
283
284 # normCount = Double_t()
285
286 # high loop
287 # it0 = self.fSliderMap.begin()
288 for it in self.fSliderMap:
289 name = it.second
290 self.fWS.var(name).setVal(it.first.GetMaxPosition())
291 param = self.fWS.var(name) # RooRealVar
292 self.fLabelMap[it.first].SetText(
293 ROOT.Form(
294 "{:s} = {:.3f} [{:.3f},{:.3f}]".format(
295 param.GetName(),
296 it.first.GetPointerPosition(),
297 it.first.GetMinPosition(),
298 it.first.GetMaxPosition(),
299 )
300 )
301 )
302 # normCount = pdftmp.expectedEvents(obs)
303 normCount = pdftmp.expectedEvents(obstmp)
304 # normCount = pdftmp.expectedEvents(RooArgSet(obs))
305 pdftmp.plotOn(
306 self.fPlot,
307 ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent),
308 LineColor="r",
309 LineWidth=2,
310 )
311
312 # low loop
313 # it0 = self.fSliderMap.begin()
314 for it in self.fSliderMap:
315 name = it.second
316 self.fWS.var(name).setVal(it.first.GetMinPosition())
317 param = self.fWS.var(name)
318 self.fLabelMap[it.first].SetText(
319 ROOT.Form(
320 "{:s} = {:.3f} [{:.3f},{:.3f}]".format(
321 param.GetName(),
322 it.first.GetPointerPosition(),
323 it.first.GetMinPosition(),
324 it.first.GetMaxPosition(),
325 )
326 )
327 )
328
329 # normCount = pdftmp.expectedEvents(RooArgSet(obs))
330 normCount = pdftmp.expectedEvents(obstmp)
331 pdftmp.plotOn(
332 self.fPlot,
333 ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent),
334 LineColor="g",
335 LineWidth=2,
336 )
337
338 # central loop
339 # it0 = self.fSliderMap.begin()
340 for it in self.fSliderMap:
341 name = it.second
342 self.fWS.var(name).setVal(it.first.GetPointerPosition())
343 param = self.fWS.var(name)
344 self.fLabelMap[it.first].SetText(
345 ROOT.Form(
346 "{:s} = {:.3f} [{:.3f},{:.3f}]".format(
347 param.GetName(),
348 it.first.GetPointerPosition(),
349 it.first.GetMinPosition(),
350 it.first.GetMaxPosition(),
351 )
352 )
353 )
354
355 # normCount = pdftmp.expectedEvents(RooArgSet(obs))
356 normCount = pdftmp.expectedEvents(obstmp)
357 if not self.fFitRes:
358 pass
359 global gnormCount
360 gnormCount = normCount
361 global gpdftmp
362 gpdftmp = pdftmp
363 pdftmp.plotOn(
364 self.fPlot,
365 ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent),
366 LineColor="b",
367 LineWidth=2,
368 )
369 # pdftmp.plotOn(self.fPlot)
370 else:
371 pdftmp.plotOn(
372 self.fPlot,
373 ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent),
374 ROOT.RooFit.VisualizeError(self.fFitRes, self.fMC.GetNuisanceParameters()),
375 FillColor="y",
376 )
377 pdftmp.plotOn(
378 self.fPlot,
379 ROOT.RooFit.Normalization(normCount, ROOT.RooAbsReal.NumEvent),
380 LineColor="b",
381 LineWidth=2,
382 )
383 msglevel = ROOT.RooMsgService.instance().globalKillBelow()
384 ROOT.RooMsgService.instance().setGlobalKillBelow(ROOT.RooFit.WARNING)
385 self.fData.plotOn(
386 self.fPlot,
387 MarkerSize=1,
388 Cut=ROOT.Form(
389 "{:s}=={:s}::{:s}".format(channelCat.GetName(), channelCat.GetName(), str(catName))
390 ),
391 DataError="None",
392 )
393
394 ROOT.RooMsgService.instance().setGlobalKillBelow(msglevel)
395
396 self.fPlot.Draw()
397
398 self.fCanvas.GetCanvas().Modified()
399 self.fCanvas.GetCanvas().Update()
400 ##############/
401 # end if(simPdf)
402 # return
403
404 # ______________________________________________________________________________
405 def HandleButtons(self):
406
407 # Handle different buttons.
408
409 # btn = ROOT.BindObject( ROOT.gTQSender, ROOT.TGTextButton )
410 # doesnt' work properly; since we are inside a function a new instance of ROOT is created.
411 # then, the ROOT.gTQSender doesn't have any information.
412 # self.gTQSender is a stored variable saved after super().__init__(ROOT.gClient.GetRoot(), ...)
413
414 btn = ROOT.BindObject(self.gTQSender, ROOT.TGTextButton)
415 Id = btn.WidgetId()
416 match (Id):
417 case ETestCmdId.HCId1.value:
418 self.fHslider1.SetConstrained(self.fCheck1.GetState())
419 pass
420 case ETestCmdId.HCId2.value:
421 self.fHslider1.SetRelative(self.fCheck2.GetState())
422 pass
423 case _:
424 pass
425
426 def DoExit(self):
427
428 print("Exit application...")
429 self.gApplication.Terminate(0)
430 del self
431 sys.exit()
432
433 # ______________________________________________________________________________
434 def __init__(self, w, mc, data):
435 # ----------------------------------members---------------------
436 # --- Principal Members ---
437 self.fWS = w
438 self.fMC = mc
439 self.fData = data
440 # --- Principal Members ---
441 self.fCanvas = ROOT.TRootEmbeddedCanvas()
442 self.fLcan = ROOT.TGLayoutHints()
443 self.fFitFcn = ROOT.TF1()
444 self.fPlot = ROOT.RooPlot()
445 self.fFile = ROOT.TFile()
446 self.fFitRes = ROOT.RooFitResult()
447 # -
448 self.fSliderList = ROOT.TList()
449 self.fFrameList = ROOT.TList()
450 self.fPlotList = ROOT.std.vector("RooPlot *")()
451 self.fSliderMap = ROOT.std.map("TGTripleHSlider *", " TString ")() # it is an instance
452 # -
453 # -TSliderMap = ROOT.map(TGTripleHSlider , char ) # it is a type
454 self.fLabelMap = ROOT.std.map("TGTripleHSlider*", "TGLabel *")()
455 # -
456 self.fFitButton = ROOT.TGButton()
457 self.fExitButton = ROOT.TGTextButton()
458 # -
459 # -# BB: a TGCanvas and a vertical frame are needed for using scrollbars
460 self.fCan = ROOT.TGCanvas()
461 self.fVFrame = ROOT.TGVerticalFrame()
462 # -
463 self.fHframe0 = self.fHframe1 = self.fHframe2 = ROOT.TGHorizontalFrame()
464 self.fBly = self.fBfly1 = self.fBfly2 = self.fBfly3 = ROOT.TGLayoutHints()
465 self.fHslider1 = ROOT.TGTripleHSlider()
466 self.fTbh1 = self.fTbh2 = self.fTbh3 = ROOT.TGTextBuffer()
467 self.fCheck1 = self.fCheck2 = ROOT.TGCheckButton()
468 # -------------------------------------------end of members---------------------
469 # debugging
470 # global gself
471 # gself = self
472 #
473 # super(TGMainFrame, self).__init__(gClient.GetRoot(), 500, 500)
474 # Initialize TGMainFrame and saving its pointers
475 super().__init__(ROOT.gClient.GetRoot(), 500, 500)
476 self.gTQSender = ROOT.gTQSender
477 self.gApplication = ROOT.gApplication
478
479 ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.NumIntegration)
480
481 simPdf = ROOT.nullptr
482 numCats = 1
483 # if (strcmp(fMC.GetPdf().ClassName(), "RooSimultaneous") == 0) : non-pythonic syntax
484 if self.fMC.GetPdf().ClassName() == "RooSimultaneous": # simple, pythonic syntax
485 print(f"Is a simultaneous PDF")
486 simPdf = self.fMC.GetPdf()
487 channelCat = simPdf.indexCat()
488 print(f" with {channelCat.numTypes()} categories")
489 numCats = channelCat.numTypes()
490 else:
491 print(f"Is not a simultaneous PDF")
492
493 self.fFitRes = ROOT.nullptr
494 self.SetCleanup(ROOT.kDeepCleanup)
495
496 # Create an embedded canvas and add it to the main frame with center at x and y
497 # and with 30 pixel margin all around
498 self.fCanvas = ROOT.TRootEmbeddedCanvas("Canvas", self, 600, 400)
499 self.fLcan = ROOT.TGLayoutHints(ROOT.kLHintsExpandX | ROOT.kLHintsExpandY, 10, 10, 10, 10)
500 self.AddFrame(self.fCanvas, self.fLcan)
501 self.fPlotList.resize(numCats)
502 # plotlist = self.fPlotList(numCats) # instead we create an instance of the template
503 if numCats > 1:
504 self.fCanvas.GetCanvas().Divide(numCats)
505 for i in range(numCats):
506 self.fCanvas.GetCanvas().cd(i + 1).SetBorderMode(0)
507 self.fCanvas.GetCanvas().cd(i + 1).SetGrid()
508
509 # return
510 self.fHframe0 = ROOT.TGHorizontalFrame(self, 0, 0, 0)
511
512 self.fCheck1 = ROOT.TGCheckButton(self.fHframe0, "&Constrained", ETestCmdId.HCId1.value)
513 self.fCheck2 = ROOT.TGCheckButton(self.fHframe0, "&Relative", ETestCmdId.HCId2.value)
514 self.fCheck1.SetState(ROOT.kButtonUp)
515 self.fCheck2.SetState(ROOT.kButtonUp)
516 self.fCheck1.SetToolTipText("Pointer position constrained to slider sides")
517 self.fCheck2.SetToolTipText("Pointer position relative to slider position")
518
519 self.fHframe0.Resize(200, 50)
520
521 self.fHframe2 = ROOT.TGHorizontalFrame(self, 0, 0, 0)
522
523 dp_DoFit = ROOT.TPyDispatcher(self.DoFit)
524 self.fFitButton = ROOT.TGTextButton(self.fHframe2, "&Fit")
525 self.fFitButton.SetFont("Helvetica")
526 self.fFitButton.Connect("Clicked()", "TPyDispatcher", dp_DoFit, "Dispatch()")
527
528 dp_DoExit = ROOT.TPyDispatcher(self.DoExit)
529 self.fExitButton = ROOT.TGTextButton(self.fHframe2, "&Exit")
530 self.fExitButton.SetFont("Helvetica")
531 # self.fExitButton.Connect( "Clicked()", "TPyDispatcher", dp_DoExit , "Dispatch()")
532 # doesn't work properly. Break segmentation violation. Full crash.
533 self.fExitButton.SetCommand('TPython::Exec( "raise SystemExit" )')
534
535 # dp_CloseWindow = TPyDispatcher( self.CloseWindow)
536 # self.Connect("CloseWindow()", "TPyDispatcher", dp_CloseWindow, "Dispatch()")
537 self.DontCallClose()
538
539 dp_HandleButtons = ROOT.TPyDispatcher(self.HandleButtons)
540 self.fCheck1.Connect("Clicked()", "TPyDispatcher", dp_HandleButtons, "Dispatch()")
541 self.fCheck2.Connect("Clicked()", "TPyDispatcher", dp_HandleButtons, "Dispatch()")
542
543 self.fHframe2.Resize(100, 25)
544
545 # --- layout for buttons: top align, equally expand horizontally
546 self.fBly = ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsExpandX, 5, 5, 5, 5)
547
548 # --- layout for the frame: place at bottom, right aligned
549 self.fBfly1 = ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsCenterX, 5, 5, 5, 5)
550 self.fBfly2 = ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsLeft, 5, 5, 5, 5)
551 self.fBfly3 = ROOT.TGLayoutHints(ROOT.kLHintsTop | ROOT.kLHintsRight, 5, 5, 5, 5)
552
553 self.fHframe2.AddFrame(self.fFitButton, self.fBfly2)
554 self.fHframe2.AddFrame(self.fExitButton, self.fBfly3)
555
556 self.AddFrame(self.fHframe0, self.fBly)
557 self.AddFrame(self.fHframe2, self.fBly)
558
559 # Loop over POI & NP, create slider
560 # need maps of NP->slider? or just slider->NP
561 parameters = ROOT.RooArgSet()
562 parameters.add(self.fMC.GetParametersOfInterest())
563 parameters.add(self.fMC.GetNuisanceParameters())
564 # it = parameters.createIterator() # unnecessary
565 param = ROOT.nullptr
566 # BB: This is the part needed in order to have scrollbars
567 self.fCan = ROOT.TGCanvas(self, 100, 100, ROOT.kFixedSize)
568 self.AddFrame(self.fCan, ROOT.TGLayoutHints(ROOT.kLHintsExpandY | ROOT.kLHintsExpandX))
569 self.fVFrame = ROOT.TGVerticalFrame(self.fCan.GetViewPort(), 10, 10)
570 self.fCan.SetContainer(self.fVFrame)
571 # And that's it!
572 # Obviously, the parent of other subframes is now fVFrame instead of "self"...
573
574 # while (param := it.Next()): #unnecessary
575 for param in parameters:
576 print(f"Adding Slider for ", param.GetName())
577 hframek = ROOT.TGHorizontalFrame(self.fVFrame, 0, 0, 0)
578
579 hlabel = ROOT.TGLabel(
580 hframek, ROOT.Form("{:s} = {:.3f} +{:.3f}".format(param.GetName(), param.getVal(), param.getError()))
581 )
582
583 hsliderk = ROOT.TGTripleHSlider(
584 hframek,
585 0,
586 ROOT.kDoubleScaleBoth,
587 ETestCmdId.HSId1.value,
588 ROOT.kHorizontalFrame,
589 ROOT.TGFrame.GetDefaultFrameBackground(),
590 False,
591 False,
592 False,
593 False,
594 )
595
596 dp_DoSlider = ROOT.TPyDispatcher(self.DoSlider)
597 hsliderk.Connect("PointerPositionChanged()", "TPyDispatcher", dp_DoSlider, "Dispatch()")
598 hsliderk.Connect("PositionChanged()", "TPyDispatcher", dp_DoSlider, "Dispatch()")
599 hsliderk.SetRange(param.getMin(), param.getMax())
600
601 hframek.Resize(200, 25)
602 self.fSliderList.Add(hsliderk)
603 self.fFrameList.Add(hframek)
604
605 hsliderk.SetPosition(param.getVal() - param.getError(), param.getVal() + param.getError())
606 hsliderk.SetPointerPosition(param.getVal())
607
608 hframek.AddFrame(hlabel, self.fBly) #
609 hframek.AddFrame(hsliderk, self.fBly) #
610 self.fVFrame.AddFrame(hframek, self.fBly)
611 self.fSliderMap[hsliderk] = param.GetName()
612 self.fLabelMap[hsliderk] = hlabel
613
614 # Set main frame name, map sub windows (buttons), initialize layout
615 # algorithm via Resize() and map main frame
616 self.SetWindowName("RooFit/RooStats Model Inspector")
617 self.MapSubwindows()
618 self.Resize(self.GetDefaultSize())
619 self.MapWindow()
620
621 self.DoSlider()
622
623
624# ----------------------------------------------------------------------------------------------------
625def ModelInspector(infile="", workspaceName="combined", modelConfigName="ModelConfig", dataName="obsData"):
626
627 # -------------------------------------------------------
628 # First part is just to access a user-defined file
629 # or create the standard example file if it doesn't exist
630
631 filename = ""
632 if infile == "":
633 filename = "results/example_combined_GaussExample_model.root"
634 fileExist = not ROOT.gSystem.AccessPathName(filename) # note opposite return code
635 # if file does not exists generate with histfactory
636 if not fileExist:
637 # Normally this would be run on the command line
638 print(f"will run standard hist2workspace example")
639 ROOT.gROOT.ProcessLine(".! prepareHistFactory .")
640 ROOT.gROOT.ProcessLine(".! hist2workspace config/example.xml")
641 print(f"\n\n---------------------")
642 print(f"Done creating example input")
643 print(f"---------------------\n\n")
644
645 else:
646 filename = infile
647
648 # Bad behaviour of variable, workspace, modelconfig. They get unset after its first call(being whatever)
649 # if we declare pointer to the file, workspace, modelconfig, so everything seems to work-out fine.
650 Declare = ROOT.gInterpreter.Declare
651 Declare(
652 """using namespace std;
653 using namespace RooFit;
654 using namespace RooStats;
655 """
656 )
657 ##################################################
658 # Try to open the file:
659 # Not to use: file = TFile.Open(filename, "READ" )
660 Declare(f'TFile *file = TFile::Open("{filename}");')
661 file = ROOT.file
662
663 # if input file was specified but not found, quit
664 try:
665 file.GetName()
666 except ReferenceError:
667 print("file wasn't load properly and is a nullptr")
668 print(f"\nInput file {filename} was not found")
669 return
670
671 # -------------------------------------------------------
672 # Tutorial starts here
673 # -------------------------------------------------------
674 # get the workspace out of the file
675 # Not to use :w = file.Get(workspaceName) # RooWorkspace
676 ProcessLine = ROOT.gInterpreter.ProcessLine
677 ProcessLine(f'RooWorkspace *w = (RooWorkspace *)file->Get("{workspaceName}");')
678 w = ROOT.w
679 try:
680 w.GetName()
681 except ReferenceError:
682 print(f"Workspace:{workspaceName} wasn't load properly and is a nullptr")
683 return
684
685 # get the modelConfig out of the file
686 # Not to use: mc = w.obj(modelConfigName) # ModelConfig
687 ProcessLine(f'ModelConfig *mc = (ModelConfig *)w->obj("{modelConfigName}");')
688 mc = ROOT.mc
689
690 # get the data out of the workspace
691 # Not to use: data = w.data(dataName) # RooAbsData
692 ProcessLine(f'RooAbsData *DATA = w->data("{dataName}");')
693 data = ROOT.DATA
694
695 # make sure ingredients are found
696 try:
697 mc.GetName()
698 print("name", mc.GetPdf())
699 mc.GetPdf()
700 data.GetName()
701 except ReferenceError:
702 print(f"ModelConfig:{modelConfigName} wasn't load properly and is a nullptr")
703 return
704 try:
705 data.GetName()
706 except ReferenceError:
707 print(f"data:{dataName} wasn't load properly and is a nullptr")
708 return
709
710 print("running ModelInspectorGUI...")
711 ModelInspectorGUI(w, mc, data)
712
713
714ModelInspector(infile="", workspaceName="combined", modelConfigName="ModelConfig", dataName="obsData")
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
TMatrixT< Element > & Add(TMatrixT< Element > &target, Element scalar, const TMatrixT< Element > &source)
Modify addition: target += scalar * source.
th1 Draw()