Basic functionality: binding ROOT math functions as RooFit functions and pdfs
Author: Wouter Verkerke
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Wednesday, April 17, 2024 at 11:16 AM.
%%cpp -d
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "RooPlot.h"
#include "TMath.h"
#include "TF1.h"
#include "Math/DistFunc.h"
#include "RooTFnBinding.h"
using namespace RooFit;
Bind one-dimensional TMath::Erf function as RooAbsReal function
RooRealVar x("x", "x", -3, 3);
RooAbsReal *errorFunc = bindFunction("erf", TMath::Erf, x);
Print erf definition
errorFunc->Print();
RooCFunction1Binding<double,double>::erf[ function=TMath::Erf x=x ] = 0
Plot erf on frame
RooPlot *frame1 = x.frame(Title("TMath::Erf bound as RooFit function"));
errorFunc->plotOn(frame1);
Bind pdf ROOT::Math::Beta with three variables as RooAbsPdf function
RooRealVar x2("x2", "x2", 0, 0.999);
RooRealVar a("a", "a", 5, 0, 10);
RooRealVar b("b", "b", 2, 0, 10);
RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b);
input_line_51:5:1: warning: 'beta' shadows a declaration with the same name in the 'std' namespace; use '::beta' to reference this declaration RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b); ^
Perf beta definition
beta->Print();
input_line_52:2:2: error: reference to 'beta' is ambiguous beta->Print(); ^ input_line_51:5:12: note: candidate found by name lookup is 'beta' RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b); ^ /usr/include/c++/9/bits/specfun.h:343:5: note: candidate found by name lookup is 'std::beta' beta(_Tpa __a, _Tpb __b) ^
Generate some events and fit
std::unique_ptr<RooDataSet> data{beta->generate(x2, 10000)};
beta->fitTo(*data, PrintLevel(-1));
input_line_53:2:35: error: reference to 'beta' is ambiguous std::unique_ptr<RooDataSet> data{beta->generate(x2, 10000)}; ^ input_line_51:5:12: note: candidate found by name lookup is 'beta' RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b); ^ /usr/include/c++/9/bits/specfun.h:343:5: note: candidate found by name lookup is 'std::beta' beta(_Tpa __a, _Tpb __b) ^ input_line_53:3:1: error: reference to 'beta' is ambiguous beta->fitTo(*data, PrintLevel(-1)); ^ input_line_51:5:12: note: candidate found by name lookup is 'beta' RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b); ^ /usr/include/c++/9/bits/specfun.h:343:5: note: candidate found by name lookup is 'std::beta' beta(_Tpa __a, _Tpb __b) ^ input_line_53:2:2: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration std::unique_ptr<RooDataSet> data{beta->generate(x2, 10000)}; ^
Plot data and pdf on frame
RooPlot *frame2 = x2.frame(Title("ROOT::Math::Beta bound as RooFit pdf"));
data->plotOn(frame2);
beta->plotOn(frame2);
input_line_54:3:1: error: reference to overloaded function could not be resolved; did you mean to call it? data->plotOn(frame2); ^~~~ /usr/include/c++/9/bits/range_access.h:289:5: note: possible target for call data(_Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:299:5: note: possible target for call data(const _Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:309:5: note: possible target for call data(_Tp (&__array)[_Nm]) noexcept ^ /usr/include/c++/9/bits/range_access.h:318:5: note: possible target for call data(initializer_list<_Tp> __il) noexcept ^ input_line_54:4:1: error: reference to 'beta' is ambiguous beta->plotOn(frame2); ^ input_line_51:5:12: note: candidate found by name lookup is 'beta' RooAbsPdf *beta = bindPdf("beta", ROOT::Math::beta_pdf, x2, a, b); ^ /usr/include/c++/9/bits/specfun.h:343:5: note: candidate found by name lookup is 'std::beta' beta(_Tpa __a, _Tpb __b) ^
Create a ROOT TF1 function
TF1 *fa1 = new TF1("fa1", "sin(x)/x", 0, 10);
Create an observable
RooRealVar x3("x3", "x3", 0.01, 20);
Create binding of TF1 object to above observable
RooAbsReal *rfa1 = bindFunction(fa1, x3);
Print rfa1 definition
rfa1->Print();
RooTFnBinding::fa1[ TFn={fa1=sin(x)/x} obs=(x3) ] = -0.0547936
Make plot frame in observable, plot TF1 binding function
RooPlot *frame3 = x3.frame(Title("TF1 bound as RooFit function"));
rfa1->plotOn(frame3);
TCanvas *c = new TCanvas("rf105_funcbinding", "rf105_funcbinding", 1200, 400);
c->Divide(3);
c->cd(1);
gPad->SetLeftMargin(0.15);
frame1->GetYaxis()->SetTitleOffset(1.6);
frame1->Draw();
c->cd(2);
gPad->SetLeftMargin(0.15);
frame2->GetYaxis()->SetTitleOffset(1.6);
frame2->Draw();
c->cd(3);
gPad->SetLeftMargin(0.15);
frame3->GetYaxis()->SetTitleOffset(1.6);
frame3->Draw();
input_line_63:2:3: error: use of undeclared identifier 'frame2' (frame2->GetYaxis()->SetTitleOffset(1.6000000000000001)) ^ Error in <HandleInterpreterException>: Error evaluating expression (frame2->GetYaxis()->SetTitleOffset(1.6000000000000001)) Execution of your code was aborted.
Draw all canvases
%jsroot on
gROOT->GetListOfCanvases()->Draw()