Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
rf104_classfactory.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_roofit
3 /// \notebook -js
4 /// Basic functionality: The class factory for functions and p.d.f.s
5 ///
6 ///
7 /// NOTE: This demo uses code that is generated by the macro,
8 /// therefore it cannot be compiled in one step by ACliC.
9 /// To run this macro compiled with ACliC do
10 ///
11 /// ~~~ {.cpp}
12 /// root>.x rf104_classfactory.C // run interpreted to generate code
13 /// root>.L MyPdfV3.cxx+ // Compile and load created class
14 /// root>.x rf104_classfactory.C+ // run compiled code
15 /// ~~~
16 ///
17 /// \macro_image
18 /// \macro_output
19 /// \macro_code
20 /// \author 07/2008 - Wouter Verkerke
21 
22 #include "RooRealVar.h"
23 #include "RooDataSet.h"
24 #include "RooGaussian.h"
25 #include "TCanvas.h"
26 #include "TAxis.h"
27 #include "RooPlot.h"
28 #include "RooClassFactory.h"
29 #include "TROOT.h"
30 
31 using namespace RooFit;
32 
33 void rf104_classfactory()
34 {
35  // W r i t e c l a s s s k e l e t o n c o d e
36  // --------------------------------------------------
37 
38  // Write skeleton p.d.f class with variable x,a,b
39  // To use this class,
40  // - Edit the file MyPdfV1.cxx and implement the evaluate() method in terms of x,a and b
41  // - Compile and link class with '.x MyPdfV1.cxx+'
42  //
43  RooClassFactory::makePdf("MyPdfV1", "x,A,B");
44 
45  // W i t h a d d e d i n i t i a l v a l u e e x p r e s s i o n
46  // ---------------------------------------------------------------------
47 
48  // Write skeleton p.d.f class with variable x,a,b and given formula expression
49  // To use this class,
50  // - Compile and link class with '.x MyPdfV2.cxx+'
51  //
52  RooClassFactory::makePdf("MyPdfV2", "x,A,B", "", "A*fabs(x)+pow(x-B,2)");
53 
54  // W i t h a d d e d a n a l y t i c a l i n t e g r a l e x p r e s s i o n
55  // ---------------------------------------------------------------------------------
56 
57  // Write skeleton p.d.f class with variable x,a,b, given formula expression _and_
58  // given expression for analytical integral over x
59  // To use this class,
60  // - Compile and link class with '.x MyPdfV3.cxx+'
61  //
62  RooClassFactory::makePdf("MyPdfV3", "x,A,B", "", "A*fabs(x)+pow(x-B,2)", kTRUE, kFALSE,
63  "x:(A/2)*(pow(x.max(rangeName),2)+pow(x.min(rangeName),2))+(1./"
64  "3)*(pow(x.max(rangeName)-B,3)-pow(x.min(rangeName)-B,3))");
65 
66  // U s e i n s t a n c e o f c r e a t e d c l a s s
67  // ---------------------------------------------------------
68 
69  // Compile MyPdfV3 class
70  gROOT->ProcessLineSync(".x MyPdfV3.cxx+");
71 
72  // Create instance of MyPdfV3 class
73  RooRealVar a("a", "a", 1);
74  RooRealVar b("b", "b", 2, -10, 10);
75  RooRealVar y("y", "y", -10, 10);
76 
77  // We need to hide the type to run in a ROOT macro
78  RooWorkspace w("w");
79  w.factory("MyPdfV3::pdf(y[-10,10], a[1], b[2,-10,10])");
80  auto pdf = w.pdf("pdf");
81 
82  // Generate toy data from pdf and plot data and p.d.f on frame
83  RooPlot *frame1 = y.frame(Title("Compiled class MyPdfV3"));
84  RooDataSet *data = pdf->generate(y, 1000);
85  pdf->fitTo(*data);
86  data->plotOn(frame1);
87  pdf->plotOn(frame1);
88 
89  // -----------------------------------------------------------------
90  // 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
91  // =================================================================
92 
93  // Declare observable x
94  RooRealVar x("x", "x", -20, 20);
95 
96  // The RooClassFactory::makePdfInstance() function performs code writing, compiling, linking
97  // and object instantiation in one go and can serve as a straight replacement of RooGenericPdf
98 
99  RooRealVar alpha("alpha", "alpha", 5, 0.1, 10);
100  RooAbsPdf *genpdf =
101  RooClassFactory::makePdfInstance("GenPdf", "(1+0.1*fabs(x)+sin(sqrt(fabs(x*alpha+0.1))))", RooArgSet(x, alpha));
102 
103  // Generate a toy dataset from the interpreted p.d.f
104  RooDataSet *data2 = genpdf->generate(x, 50000);
105 
106  // Fit the interpreted p.d.f to the generated data
107  genpdf->fitTo(*data2);
108 
109  // Make a plot of the data and the p.d.f overlaid
110  RooPlot *frame2 = x.frame(Title("Compiled version of pdf of rf103"));
111  data2->plotOn(frame2);
112  genpdf->plotOn(frame2);
113 
114  // Draw all frames on a canvas
115  TCanvas *c = new TCanvas("rf104_classfactory", "rf104_classfactory", 800, 400);
116  c->Divide(2);
117  c->cd(1);
118  gPad->SetLeftMargin(0.15);
119  frame1->GetYaxis()->SetTitleOffset(1.4);
120  frame1->Draw();
121  c->cd(2);
122  gPad->SetLeftMargin(0.15);
123  frame2->GetYaxis()->SetTitleOffset(1.4);
124  frame2->Draw();
125 }