/// \file /// \ingroup tutorial_roofit /// \notebook -js /// /// Basic functionality: The class factory for functions and p.d.f.s /// /// NOTE: This demo uses code that is generated by the macro, /// therefore it cannot be compiled in one step by ACliC. /// To run this macro compiled with ACliC do /// /// ~~~ {.cpp} /// root>.x rf104_classfactory.C // run interpreted to generate code /// root>.L MyPdfV3.cxx+ // Compile and load created class /// root>.x rf104_classfactory.C+ // run compiled code /// ~~~ /// /// \macro_image /// \macro_output /// \macro_code /// /// \date 07/2008 /// \author Wouter Verkerke #include "RooRealVar.h" #include "RooDataSet.h" #include "RooGaussian.h" #include "TCanvas.h" #include "TAxis.h" #include "RooPlot.h" #include "RooClassFactory.h" #include "TROOT.h" using namespace RooFit; void rf104_classfactory() { // W r i t e c l a s s s k e l e t o n c o d e // -------------------------------------------------- // Write skeleton p.d.f class with variable x,a,b // To use this class, // - Edit the file MyPdfV1.cxx and implement the evaluate() method in terms of x,a and b // - Compile and link class with '.x MyPdfV1.cxx+' // RooClassFactory::makePdf("MyPdfV1", "x,A,B"); // 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 // --------------------------------------------------------------------- // Write skeleton p.d.f class with variable x,a,b and given formula expression // To use this class, // - Compile and link class with '.x MyPdfV2.cxx+' // RooClassFactory::makePdf("MyPdfV2", "x,A,B", "", "A*fabs(x)+pow(x-B,2)"); // 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 // --------------------------------------------------------------------------------- // Write skeleton p.d.f class with variable x,a,b, given formula expression _and_ // given expression for analytical integral over x // To use this class, // - Compile and link class with '.x MyPdfV3.cxx+' // RooClassFactory::makePdf("MyPdfV3", "x,A,B", "", "A*fabs(x)+pow(x-B,2)", kTRUE, kFALSE, "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))"); // 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 // --------------------------------------------------------- // Compile MyPdfV3 class gROOT->ProcessLineSync(".x MyPdfV3.cxx+"); // Create instance of MyPdfV3 class RooRealVar a("a", "a", 1); RooRealVar b("b", "b", 2, -10, 10); RooRealVar y("y", "y", -10, 10); // We need to hide the type to run in a ROOT macro RooWorkspace w("w"); w.factory("MyPdfV3::pdf(y[-10,10], a[1], b[2,-10,10])"); auto pdf = w.pdf("pdf"); // Generate toy data from pdf and plot data and p.d.f on frame RooPlot *frame1 = y.frame(Title("Compiled class MyPdfV3")); RooDataSet *data = pdf->generate(y, 1000); pdf->fitTo(*data); data->plotOn(frame1); pdf->plotOn(frame1); // ----------------------------------------------------------------- // 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 // ================================================================= // Declare observable x RooRealVar x("x", "x", -20, 20); // The RooClassFactory::makePdfInstance() function performs code writing, compiling, linking // and object instantiation in one go and can serve as a straight replacement of RooGenericPdf RooRealVar alpha("alpha", "alpha", 5, 0.1, 10); RooAbsPdf *genpdf = RooClassFactory::makePdfInstance("GenPdf", "(1+0.1*fabs(x)+sin(sqrt(fabs(x*alpha+0.1))))", RooArgSet(x, alpha)); // Generate a toy dataset from the interpreted p.d.f RooDataSet *data2 = genpdf->generate(x, 50000); // Fit the interpreted p.d.f to the generated data genpdf->fitTo(*data2); // Make a plot of the data and the p.d.f overlaid RooPlot *frame2 = x.frame(Title("Compiled version of pdf of rf103")); data2->plotOn(frame2); genpdf->plotOn(frame2); // Draw all frames on a canvas TCanvas *c = new TCanvas("rf104_classfactory", "rf104_classfactory", 800, 400); c->Divide(2); c->cd(1); gPad->SetLeftMargin(0.15); frame1->GetYaxis()->SetTitleOffset(1.4); frame1->Draw(); c->cd(2); gPad->SetLeftMargin(0.15); frame2->GetYaxis()->SetTitleOffset(1.4); frame2->Draw(); }