Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
rf104_classfactory.py
Go to the documentation of this file.
1 ## \file
2 ## \ingroup tutorial_roofit
3 ## \notebook
4 ## Basic functionality: the class factory for functions and p.d.f.s
5 ##
6 ## NOTE: This demo uses code that is generated by the macro,
7 ## which can be compiled on the fly (set to MyPdfV3 below).
8 ## To use MyPdfV1 or MyPdfV2, adjust lines below accordingly.
9 ##
10 ## \macro_code
11 ##
12 ## \date February 2018
13 ## \author Clemens Lange, Wouter Verkerke (C++ version)
14 
15 import ROOT
16 
17 # Write class skeleton code
18 # --------------------------------------------------
19 
20 # Write skeleton p.d.f class with variable x,a,b
21 # To use this class,
22 # - Edit the file MyPdfV1.cxx and implement the evaluate() method in terms of x,a and b
23 # - Compile and link class with '.x MyPdfV1.cxx+'
24 #
25 ROOT.RooClassFactory.makePdf("MyPdfV1", "x,A,B")
26 
27 # With added initial value expression
28 # ---------------------------------------------------------------------
29 
30 # Write skeleton p.d.f class with variable x,a,b and given formula expression
31 # To use this class,
32 # - Compile and link class with '.x MyPdfV2.cxx+'
33 #
34 ROOT.RooClassFactory.makePdf(
35  "MyPdfV2", "x,A,B", "", "A*fabs(x)+pow(x-B,2)")
36 
37 # With added analytical integral expression
38 # ---------------------------------------------------------------------------------
39 
40 # Write skeleton p.d.f class with variable x,a,b, given formula expression _and_
41 # given expression for analytical integral over x
42 # To use this class,
43 # - Compile and link class with '.x MyPdfV3.cxx+'
44 #
45 ROOT.RooClassFactory.makePdf(
46  "MyPdfV3",
47  "x,A,B",
48  "",
49  "A*fabs(x)+pow(x-B,2)",
50  ROOT.kTRUE,
51  ROOT.kFALSE,
52  "x:(A/2)*(pow(x.max(rangeName),2)+pow(x.min(rangeName),2))+(1./3)*(pow(x.max(rangeName)-B,3)-pow(x.min(rangeName)-B,3))")
53 
54 # Use instance of created class
55 # ---------------------------------------------------------
56 
57 # Compile MyPdfV3 class
58 ROOT.gROOT.ProcessLineSync(".x MyPdfV3.cxx+")
59 
60 # Creat instance of MyPdfV3 class
61 a = ROOT.RooRealVar("a", "a", 1)
62 b = ROOT.RooRealVar("b", "b", 2, -10, 10)
63 y = ROOT.RooRealVar("y", "y", -10, 10)
64 pdf = ROOT.MyPdfV3("pdf", "pdf", y, a, b)
65 
66 # Generate toy data from pdf and plot data and p.d.f on frame
67 frame1 = y.frame(ROOT.RooFit.Title("Compiled class MyPdfV3"))
68 data = pdf.generate(ROOT.RooArgSet(y), 1000)
69 pdf.fitTo(data)
70 data.plotOn(frame1)
71 pdf.plotOn(frame1)
72 
73 # /
74 # C o m p i l e d v e r s i o n o f e x a m p l e r f 1 0 3 #
75 # /
76 
77 # Declare observable x
78 x = ROOT.RooRealVar("x", "x", -20, 20)
79 
80 # The ROOT.RooClassFactory.makePdfInstance() function performs code writing, compiling, linking
81 # and object instantiation in one go and can serve as a straight
82 # replacement of ROOT.RooGenericPdf
83 
84 alpha = ROOT.RooRealVar("alpha", "alpha", 5, 0.1, 10)
85 genpdf = ROOT.RooClassFactory.makePdfInstance(
86  "GenPdf",
87  "(1+0.1*fabs(x)+sin(sqrt(fabs(x*alpha+0.1))))",
88  ROOT.RooArgList(
89  x,
90  alpha))
91 
92 # Generate a toy dataset from the interpreted p.d.f
93 data2 = genpdf.generate(ROOT.RooArgSet(x), 50000)
94 
95 # Fit the interpreted p.d.f to the generated data
96 genpdf.fitTo(data2)
97 
98 # Make a plot of the data and the p.d.f overlaid
99 frame2 = x.frame(ROOT.RooFit.Title("Compiled version of pdf of rf103"))
100 data2.plotOn(frame2)
101 genpdf.plotOn(frame2)
102 
103 # Draw all frames on a canvas
104 c = ROOT.TCanvas("rf104_classfactory", "rf104_classfactory", 800, 400)
105 c.Divide(2)
106 c.cd(1)
107 ROOT.gPad.SetLeftMargin(0.15)
108 frame1.GetYaxis().SetTitleOffset(1.4)
109 frame1.Draw()
110 c.cd(2)
111 ROOT.gPad.SetLeftMargin(0.15)
112 frame2.GetYaxis().SetTitleOffset(1.4)
113 frame2.Draw()
114 
115 c.SaveAs("rf104_classfactory.png")