diff --git a/README.md b/README.md index 0114b15..833c519 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # roofit pyROOT version of RooFit tutorials -Original C-version can be found at https://root.cern.ch/root/html/tutorials/roofit/ +Original C-version can be found in [cpp](cpp) (taken from https://root.cern.ch/root/html/tutorials/roofit/) Currently available: diff --git a/cpp/rf101_basics.C b/cpp/rf101_basics.C new file mode 100644 index 0000000..8aa156e --- /dev/null +++ b/cpp/rf101_basics.C @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #101 +// +// Fitting, plotting, toy data generation on one-dimensional p.d.f +// +// pdf = gauss(x,m,s) +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "RooPlot.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf101_basics() +{ + // S e t u p m o d e l + // --------------------- + + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + RooRealVar x("x","x",-10,10) ; + RooRealVar mean("mean","mean of gaussian",1,-10,10) ; + RooRealVar sigma("sigma","width of gaussian",1,0.1,10) ; + + // Build gaussian p.d.f in terms of x,mean and sigma + RooGaussian gauss("gauss","gaussian PDF",x,mean,sigma) ; + + // Construct plot frame in 'x' + RooPlot* xframe = x.frame(Title("Gaussian p.d.f.")) ; + + + // P l o t m o d e l a n d c h a n g e p a r a m e t e r v a l u e s + // --------------------------------------------------------------------------- + + // Plot gauss in frame (i.e. in x) + gauss.plotOn(xframe) ; + + // Change the value of sigma to 3 + sigma.setVal(3) ; + + // Plot gauss in frame (i.e. in x) and draw frame on canvas + gauss.plotOn(xframe,LineColor(kRed)) ; + + + // G e n e r a t e e v e n t s + // ----------------------------- + + // Generate a dataset of 1000 events in x from gauss + RooDataSet* data = gauss.generate(x,10000) ; + + // Make a second plot frame in x and draw both the + // data and the p.d.f in the frame + RooPlot* xframe2 = x.frame(Title("Gaussian p.d.f. with data")) ; + data->plotOn(xframe2) ; + gauss.plotOn(xframe2) ; + + + // F i t m o d e l t o d a t a + // ----------------------------- + + // Fit pdf to data + gauss.fitTo(*data) ; + + // Print values of mean and sigma (that now reflect fitted values and errors) + mean.Print() ; + sigma.Print() ; + + // Draw all frames on a canvas + TCanvas* c = new TCanvas("rf101_basics","rf101_basics",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.6) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; xframe2->GetYaxis()->SetTitleOffset(1.6) ; xframe2->Draw() ; + + +} diff --git a/cpp/rf102_dataimport.C b/cpp/rf102_dataimport.C new file mode 100644 index 0000000..a76ac63 --- /dev/null +++ b/cpp/rf102_dataimport.C @@ -0,0 +1,161 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #102 +// +// Importing data from ROOT TTrees and THx histograms +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "RooPlot.h" +#include "TTree.h" +#include "TH1D.h" +#include "TRandom.h" +using namespace RooFit ; + +TH1* makeTH1() ; +TTree* makeTTree() ; + + +void rf102_dataimport() +{ + //////////////////////////////////////////////////////// + // I m p o r t i n g R O O T h i s t o g r a m s // + //////////////////////////////////////////////////////// + + // I m p o r t T H 1 i n t o a R o o D a t a H i s t + // --------------------------------------------------------- + + // Create a ROOT TH1 histogram + TH1* hh = makeTH1() ; + + // Declare observable x + RooRealVar x("x","x",-10,10) ; + + // Create a binned dataset that imports contents of TH1 and associates its contents to observable 'x' + RooDataHist dh("dh","dh",x,Import(*hh)) ; + + + // P l o t a n d f i t a R o o D a t a H i s t + // --------------------------------------------------- + + // Make plot of binned dataset showing Poisson error bars (RooFit default) + RooPlot* frame = x.frame(Title("Imported TH1 with Poisson error bars")) ; + dh.plotOn(frame) ; + + // Fit a Gaussian p.d.f to the data + RooRealVar mean("mean","mean",0,-10,10) ; + RooRealVar sigma("sigma","sigma",3,0.1,10) ; + RooGaussian gauss("gauss","gauss",x,mean,sigma) ; + gauss.fitTo(dh) ; + gauss.plotOn(frame) ; + + // P l o t a n d f i t a R o o D a t a H i s t w i t h i n t e r n a l e r r o r s + // --------------------------------------------------------------------------------------------- + + // If histogram has custom error (i.e. its contents is does not originate from a Poisson process + // but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead + // (same error bars as shown by ROOT) + RooPlot* frame2 = x.frame(Title("Imported TH1 with internal errors")) ; + dh.plotOn(frame2,DataError(RooAbsData::SumW2)) ; + gauss.plotOn(frame2) ; + + // Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used + // in a maximum likelihood fit + // + // A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition + // of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly + // fitted with a chi^2 fit (see rf602_chi2fit.C) + + + //////////////////////////////////////////////// + // I m p o r t i n g R O O T T T r e e s // + //////////////////////////////////////////////// + + + // I m p o r t T T r e e i n t o a R o o D a t a S e t + // ----------------------------------------------------------- + + TTree* tree = makeTTree() ; + + // Define 2nd observable y + RooRealVar y("y","y",-10,10) ; + + // Construct unbinned dataset importing tree branches x and y matching between branches and RooRealVars + // is done by name of the branch/RRV + // + // Note that ONLY entries for which x,y have values within their allowed ranges as defined in + // RooRealVar x and y are imported. Since the y values in the import tree are in the range [-15,15] + // and RRV y defines a range [-10,10] this means that the RooDataSet below will have less entries than the TTree 'tree' + + RooDataSet ds("ds","ds",RooArgSet(x,y),Import(*tree)) ; + + + // P l o t d a t a s e t w i t h m u l t i p l e b i n n i n g c h o i c e s + // ------------------------------------------------------------------------------------ + + // Print number of events in dataset + ds.Print() ; + + // Print unbinned dataset with default frame binning (100 bins) + RooPlot* frame3 = y.frame(Title("Unbinned data shown in default frame binning")) ; + ds.plotOn(frame3) ; + + // Print unbinned dataset with custom binning choice (20 bins) + RooPlot* frame4 = y.frame(Title("Unbinned data shown with custom binning")) ; + ds.plotOn(frame4,Binning(20)) ; + + // Draw all frames on a canvas + TCanvas* c = new TCanvas("rf102_dataimport","rf102_dataimport",800,800) ; + c->Divide(2,2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.4) ; frame3->Draw() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.4) ; frame4->Draw() ; + +} + + + + +TH1* makeTH1() +{ + // Create ROOT TH1 filled with a Gaussian distribution + + TH1D* hh = new TH1D("hh","hh",25,-10,10) ; + for (int i=0 ; i<100 ; i++) { + hh->Fill(gRandom->Gaus(0,3)) ; + } + return hh ; +} + + +TTree* makeTTree() +{ + // Create ROOT TTree filled with a Gaussian distribution in x and a uniform distribution in y + + TTree* tree = new TTree("tree","tree") ; + Double_t* px = new Double_t ; + Double_t* py = new Double_t ; + tree->Branch("x",px,"x/D") ; + tree->Branch("y",py,"y/D") ; + for (int i=0 ; i<100 ; i++) { + *px = gRandom->Gaus(0,3) ; + *py = gRandom->Uniform()*30 - 15 ; + tree->Fill() ; + } + return tree ; +} + + diff --git a/cpp/rf103_interprfuncs.C b/cpp/rf103_interprfuncs.C new file mode 100644 index 0000000..8d34cc0 --- /dev/null +++ b/cpp/rf103_interprfuncs.C @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #103 +// +// Interpreted functions and p.d.f.s +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooFitResult.h" +#include "RooGenericPdf.h" +#include "RooConstVar.h" + +using namespace RooFit ; + + +void rf103_interprfuncs() +{ + ///////////////////////////////////////////////////////// + // G e n e r i c i n t e r p r e t e d p . d . f . // + ///////////////////////////////////////////////////////// + + // Declare observable x + RooRealVar x("x","x",-20,20) ; + + // C o n s t r u c t g e n e r i c p d f f r o m i n t e r p r e t e d e x p r e s s i o n + // ------------------------------------------------------------------------------------------------- + + // To construct a proper p.d.f, the formula expression is explicitly normalized internally by dividing + // it by a numeric integral of the expresssion over x in the range [-20,20] + // + RooRealVar alpha("alpha","alpha",5,0.1,10) ; + RooGenericPdf genpdf("genpdf","genpdf","(1+0.1*abs(x)+sin(sqrt(abs(x*alpha+0.1))))",RooArgSet(x,alpha)) ; + + + // S a m p l e , f i t a n d p l o t g e n e r i c p d f + // --------------------------------------------------------------- + + // Generate a toy dataset from the interpreted p.d.f + RooDataSet* data = genpdf.generate(x,10000) ; + + // Fit the interpreted p.d.f to the generated data + genpdf.fitTo(*data) ; + + // Make a plot of the data and the p.d.f overlaid + RooPlot* xframe = x.frame(Title("Interpreted expression pdf")) ; + data->plotOn(xframe) ; + genpdf.plotOn(xframe) ; + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // S t a n d a r d p . d . f a d j u s t w i t h i n t e r p r e t e d h e l p e r f u n c t i o n // + // // + // Make a gauss(x,sqrt(mean2),sigma) from a standard RooGaussian // + // // + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + // C o n s t r u c t s t a n d a r d p d f w i t h f o r m u l a r e p l a c i n g p a r a m e t e r + // ------------------------------------------------------------------------------------------------------------ + + // Construct parameter mean2 and sigma + RooRealVar mean2("mean2","mean^2",10,0,200) ; + RooRealVar sigma("sigma","sigma",3,0.1,10) ; + + // Construct interpreted function mean = sqrt(mean^2) + RooFormulaVar mean("mean","mean","sqrt(mean2)",mean2) ; + + // Construct a gaussian g2(x,sqrt(mean2),sigma) ; + RooGaussian g2("g2","h2",x,mean,sigma) ; + + + // G e n e r a t e t o y d a t a + // --------------------------------- + + // Construct a separate gaussian g1(x,10,3) to generate a toy Gaussian dataset with mean 10 and width 3 + RooGaussian g1("g1","g1",x,RooConst(10),RooConst(3)) ; + RooDataSet* data2 = g1.generate(x,1000) ; + + + // F i t a n d p l o t t a i l o r e d s t a n d a r d p d f + // ------------------------------------------------------------------- + + // Fit g2 to data from g1 + RooFitResult* r = g2.fitTo(*data2,Save()) ; + r->Print() ; + + // Plot data on frame and overlay projection of g2 + RooPlot* xframe2 = x.frame(Title("Tailored Gaussian pdf")) ; + data2->plotOn(xframe2) ; + g2.plotOn(xframe2) ; + + + // Draw all frames on a canvas + TCanvas* c = new TCanvas("rf103_interprfuncs","rf103_interprfuncs",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; xframe2->GetYaxis()->SetTitleOffset(1.4) ; xframe2->Draw() ; + + +} diff --git a/cpp/rf104_classfactory.C b/cpp/rf104_classfactory.C new file mode 100644 index 0000000..1cea526 --- /dev/null +++ b/cpp/rf104_classfactory.C @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #104 +// +// 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 +// +// root>.x rf104_classfactory.C // run interpreted to generate code +// root>.L MyPdfV3.cxx+ // Compile and load created classs +// root>.x rf104_classfactory.C+ // run compiled code +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooClassFactory.h" +#include "TROOT.h" + +#ifndef __CINT__ +#include "MyPdfV3.h" +#endif + + +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 (only when running in CINT) +#ifdef __CINT__ + gROOT->ProcessLineSync(".x MyPdfV3.cxx+") ; +#endif + + // Creat instance of MyPdfV3 class + RooRealVar a("a","a",1) ; + RooRealVar b("b","b",2,-10,10) ; + RooRealVar y("y","y",-10,10); + MyPdfV3 pdf("pdf","pdf",y,a,b) ; + + // 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() ; + +} diff --git a/cpp/rf105_funcbinding.C b/cpp/rf105_funcbinding.C new file mode 100644 index 0000000..8ae61b0 --- /dev/null +++ b/cpp/rf105_funcbinding.C @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #105 +// +// Demonstration of binding ROOT Math functions as RooFit functions +// and pdfs +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#else +// Refer to a class implemented in libRooFit to force its loading +// via the autoloader. +class Roo2DKeysPdf; +#endif +#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" +#ifndef __CINT__ +#include "RooCFunction1Binding.h" +#include "RooCFunction3Binding.h" +#endif +#include "RooTFnBinding.h" + +using namespace RooFit; + + +void rf105_funcbinding() +{ + + // B i n d T M a t h : : E r f C f u n c t i o n + // --------------------------------------------------- + + // Bind one-dimensional TMath::Erf function as RooAbsReal function + RooRealVar x("x","x",-3,3) ; + RooAbsReal* erf = bindFunction("erf",TMath::Erf,x) ; + + // Print erf definition + erf->Print() ; + + // Plot erf on frame + RooPlot* frame1 = x.frame(Title("TMath::Erf bound as RooFit function")) ; + erf->plotOn(frame1) ; + + + // B i n d R O O T : : M a t h : : b e t a _ p d f C f u n c t i o n + // ----------------------------------------------------------------------- + + // 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) ; + + // Perf beta definition + beta->Print() ; + + // Generate some events and fit + RooDataSet* data = beta->generate(x2,10000) ; + beta->fitTo(*data) ; + + // Plot data and pdf on frame + RooPlot* frame2 = x2.frame(Title("ROOT::Math::Beta bound as RooFit pdf")) ; + data->plotOn(frame2) ; + beta->plotOn(frame2) ; + + + + // B i n d R O O T T F 1 a s R o o F i t f u n c t i o n + // --------------------------------------------------------------- + + // 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() ; + + // 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() ; + +} diff --git a/cpp/rf106_plotdecoration.C b/cpp/rf106_plotdecoration.C new file mode 100644 index 0000000..4bbdd39 --- /dev/null +++ b/cpp/rf106_plotdecoration.C @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #106 +// +// Adding boxes with parameters, statistics to RooPlots. +// Decorating RooPlots with arrows, text etc... +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TText.h" +#include "TArrow.h" +#include "TFile.h" +using namespace RooFit ; + + +void rf106_plotdecoration() +{ + + // S e t u p m o d e l + // --------------------- + + // Create observables + RooRealVar x("x","x",-10,10) ; + + // Create Gaussian + RooRealVar sigma("sigma","sigma",1,0.1,10) ; + RooRealVar mean("mean","mean",-3,-10,10) ; + RooGaussian gauss("gauss","gauss",x,mean,sigma) ; + + // Generate a sample of 1000 events with sigma=3 + RooDataSet* data = gauss.generate(x,1000) ; + + // Fit pdf to data + gauss.fitTo(*data) ; + + + // P l o t p . d . f a n d d a t a + // ------------------------------------- + + // Overlay projection of gauss on data + RooPlot* frame = x.frame(Name("xframe"),Title("RooPlot with decorations"),Bins(40)) ; + data->plotOn(frame) ; + gauss.plotOn(frame) ; + + + // A d d b o x w i t h p d f p a r a m e t e r s + // ----------------------------------------------------- + + // Left edge of box starts at 55% of Xaxis) + gauss.paramOn(frame,Layout(0.55)) ; + + + // A d d b o x w i t h d a t a s t a t i s t i c s + // ------------------------------------------------------- + + // X size of box is from 55% to 99% of Xaxis range, top of box is at 80% of Yaxis range) + data->statOn(frame,Layout(0.55,0.99,0.8)) ; + + + // A d d t e x t a n d a r r o w + // ----------------------------------- + + // Add text to frame + TText* txt = new TText(2,100,"Signal") ; + txt->SetTextSize(0.04) ; + txt->SetTextColor(kRed) ; + frame->addObject(txt) ; + + // Add arrow to frame + TArrow* arrow = new TArrow(2,100,-1,50,0.01,"|>") ; + arrow->SetLineColor(kRed) ; + arrow->SetFillColor(kRed) ; + arrow->SetLineWidth(3) ; + frame->addObject(arrow) ; + + + // P e r s i s t f r a m e w i t h a l l d e c o r a t i o n s i n R O O T f i l e + // --------------------------------------------------------------------------------------------- + + TFile f("rf106_plotdecoration.root","RECREATE") ; + frame->Write() ; + f.Close() ; + + // To read back and plot frame with all decorations in clean root session do + // root> TFile f("rf106_plotdecoration.root") ; + // root> xframe->Draw() ; + + new TCanvas("rf106_plotdecoration","rf106_plotdecoration",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + +} diff --git a/cpp/rf107_plotstyles.C b/cpp/rf107_plotstyles.C new file mode 100644 index 0000000..08525f4 --- /dev/null +++ b/cpp/rf107_plotstyles.C @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #107 +// +// Demonstration of various plotting styles of data, functions +// in a RooPlot +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf107_plotstyles() +{ + + // S e t u p m o d e l + // --------------------- + + // Create observables + RooRealVar x("x","x",-10,10) ; + + // Create Gaussian + RooRealVar sigma("sigma","sigma",3,0.1,10) ; + RooRealVar mean("mean","mean",-3,-10,10) ; + RooGaussian gauss("gauss","gauss",x,mean,sigma) ; + + // Generate a sample of 100 events with sigma=3 + RooDataSet* data = gauss.generate(x,100) ; + + // Fit pdf to data + gauss.fitTo(*data) ; + + + + // M a k e p l o t f r a m e s + // ------------------------------- + + // Make four plot frames to demonstrate various plotting features + RooPlot* frame1 = x.frame(Name("xframe"),Title("Red Curve / SumW2 Histo errors"),Bins(20)) ; + RooPlot* frame2 = x.frame(Name("xframe"),Title("Dashed Curve / No XError bars"),Bins(20)) ; + RooPlot* frame3 = x.frame(Name("xframe"),Title("Filled Curve / Blue Histo"),Bins(20)) ; + RooPlot* frame4 = x.frame(Name("xframe"),Title("Partial Range / Filled Bar chart"),Bins(20)) ; + + + + // D a t a p l o t t i n g s t y l e s + // --------------------------------------- + + // Use sqrt(sum(weights^2)) error instead of Poisson errors + data->plotOn(frame1,DataError(RooAbsData::SumW2)) ; + + // Remove horizontal error bars + data->plotOn(frame2,XErrorSize(0)) ; + + // Blue markers and error bors + data->plotOn(frame3,MarkerColor(kBlue),LineColor(kBlue)) ; + + // Filled bar chart + data->plotOn(frame4,DrawOption("B"),DataError(RooAbsData::None),XErrorSize(0),FillColor(kGray)) ; + + + + // F u n c t i o n p l o t t i n g s t y l e s + // ----------------------------------------------- + + // Change line color to red + gauss.plotOn(frame1,LineColor(kRed)) ; + + // Change line style to dashed + gauss.plotOn(frame2,LineStyle(kDashed)) ; + + // Filled shapes in green color + gauss.plotOn(frame3,DrawOption("F"),FillColor(kOrange),MoveToBack()) ; + + // + gauss.plotOn(frame4,Range(-8,3),LineColor(kMagenta)) ; + + + + TCanvas* c = new TCanvas("rf107_plotstyles","rf107_plotstyles",800,800) ; + c->Divide(2,2) ; + 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() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.6) ; frame4->Draw() ; + + +} diff --git a/cpp/rf108_plotbinning.C b/cpp/rf108_plotbinning.C new file mode 100644 index 0000000..339a59d --- /dev/null +++ b/cpp/rf108_plotbinning.C @@ -0,0 +1,128 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #108 +// +// Plotting unbinned data with alternate and variable binnings +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussModel.h" +#include "RooDecay.h" +#include "RooBMixDecay.h" +#include "RooCategory.h" +#include "RooBinning.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf108_plotbinning() +{ + + // S e t u p m o d e l + // --------------------- + + // Build a B decay p.d.f with mixing + RooRealVar dt("dt","dt",-20,20) ; + RooRealVar dm("dm","dm",0.472) ; + RooRealVar tau("tau","tau",1.547) ; + RooRealVar w("w","mistag rate",0.1) ; + RooRealVar dw("dw","delta mistag rate",0.) ; + + RooCategory mixState("mixState","B0/B0bar mixing state") ; + mixState.defineType("mixed",-1) ; + mixState.defineType("unmixed",1) ; + RooCategory tagFlav("tagFlav","Flavour of the tagged B0") ; + tagFlav.defineType("B0",1) ; + tagFlav.defineType("B0bar",-1) ; + + // Build a gaussian resolution model + RooRealVar dterr("dterr","dterr",0.1,1.0) ; + RooRealVar bias1("bias1","bias1",0) ; + RooRealVar sigma1("sigma1","sigma1",0.1) ; + RooGaussModel gm1("gm1","gauss model 1",dt,bias1,sigma1) ; + + // Construct Bdecay (x) gauss + RooBMixDecay bmix("bmix","decay",dt,mixState,tagFlav,tau,dm,w,dw,gm1,RooBMixDecay::DoubleSided) ; + + + // S a m p l e d a t a f r o m m o d e l + // -------------------------------------------- + + // Sample 2000 events in (dt,mixState,tagFlav) from bmix + RooDataSet *data = bmix.generate(RooArgSet(dt,mixState,tagFlav),2000) ; + + + + // S h o w d t d i s t r i b u t i o n w i t h c u s t o m b i n n i n g + // ------------------------------------------------------------------------------- + + // Make plot of dt distribution of data in range (-15,15) with fine binning for dt>0 and coarse binning for dt<0 + + // Create binning object with range (-15,15) + RooBinning tbins(-15,15) ; + + // Add 60 bins with uniform spacing in range (-15,0) + tbins.addUniform(60,-15,0) ; + + // Add 15 bins with uniform spacing in range (0,15) + tbins.addUniform(15,0,15) ; + + // Make plot with specified binning + RooPlot* dtframe = dt.frame(Range(-15,15),Title("dt distribution with custom binning")) ; + data->plotOn(dtframe,Binning(tbins)) ; + bmix.plotOn(dtframe) ; + + // NB: Note that bin density for each bin is adjusted to that of default frame binning as shown + // in Y axis label (100 bins --> Events/0.4*Xaxis-dim) so that all bins represent a consistent density distribution + + + // S h o w m i x s t a t e a s y m m e t r y w i t h c u s t o m b i n n i n g + // ------------------------------------------------------------------------------------ + + // Make plot of dt distribution of data asymmetry in 'mixState' with variable binning + + // Create binning object with range (-10,10) + RooBinning abins(-10,10) ; + + // Add boundaries at 0, (-1,1), (-2,2), (-3,3), (-4,4) and (-6,6) + abins.addBoundary(0) ; + abins.addBoundaryPair(1) ; + abins.addBoundaryPair(2) ; + abins.addBoundaryPair(3) ; + abins.addBoundaryPair(4) ; + abins.addBoundaryPair(6) ; + + // Create plot frame in dt + RooPlot* aframe = dt.frame(Range(-10,10),Title("mixState asymmetry distribution with custom binning")) ; + + // Plot mixState asymmetry of data with specified customg binning + data->plotOn(aframe,Asymmetry(mixState),Binning(abins)) ; + + // Plot corresponding property of p.d.f + bmix.plotOn(aframe,Asymmetry(mixState)) ; + + // Adjust vertical range of plot to sensible values for an asymmetry + aframe->SetMinimum(-1.1) ; + aframe->SetMaximum(1.1) ; + + // NB: For asymmetry distributions no density corrects are needed (and are thus not applied) + + + // Draw plots on canvas + TCanvas* c = new TCanvas("rf108_plotbinning","rf108_plotbinning",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; dtframe->GetYaxis()->SetTitleOffset(1.6) ; dtframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; aframe->GetYaxis()->SetTitleOffset(1.6) ; aframe->Draw() ; + +} diff --git a/cpp/rf109_chi2residpull.C b/cpp/rf109_chi2residpull.C new file mode 100644 index 0000000..ec4c93c --- /dev/null +++ b/cpp/rf109_chi2residpull.C @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #109 +// +// Calculating chi^2 from histograms and curves in RooPlots, +// making histogram of residual and pull distributions +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooHist.h" +using namespace RooFit ; + + +void rf109_chi2residpull() +{ + + // S e t u p m o d e l + // --------------------- + + // Create observables + RooRealVar x("x","x",-10,10) ; + + // Create Gaussian + RooRealVar sigma("sigma","sigma",3,0.1,10) ; + RooRealVar mean("mean","mean",0,-10,10) ; + RooGaussian gauss("gauss","gauss",x,RooConst(0),sigma) ; + + // Generate a sample of 1000 events with sigma=3 + RooDataSet* data = gauss.generate(x,10000) ; + + // Change sigma to 3.15 + sigma=3.15 ; + + + // P l o t d a t a a n d s l i g h t l y d i s t o r t e d m o d e l + // --------------------------------------------------------------------------- + + // Overlay projection of gauss with sigma=3.15 on data with sigma=3.0 + RooPlot* frame1 = x.frame(Title("Data with distorted Gaussian pdf"),Bins(40)) ; + data->plotOn(frame1,DataError(RooAbsData::SumW2)) ; + gauss.plotOn(frame1) ; + + + // C a l c u l a t e c h i ^ 2 + // ------------------------------ + + // Show the chi^2 of the curve w.r.t. the histogram + // If multiple curves or datasets live in the frame you can specify + // the name of the relevant curve and/or dataset in chiSquare() + cout << "chi^2 = " << frame1->chiSquare() << endl ; + + + // S h o w r e s i d u a l a n d p u l l d i s t s + // ------------------------------------------------------- + + // Construct a histogram with the residuals of the data w.r.t. the curve + RooHist* hresid = frame1->residHist() ; + + // Construct a histogram with the pulls of the data w.r.t the curve + RooHist* hpull = frame1->pullHist() ; + + // Create a new frame to draw the residual distribution and add the distribution to the frame + RooPlot* frame2 = x.frame(Title("Residual Distribution")) ; + frame2->addPlotable(hresid,"P") ; + + // Create a new frame to draw the pull distribution and add the distribution to the frame + RooPlot* frame3 = x.frame(Title("Pull Distribution")) ; + frame3->addPlotable(hpull,"P") ; + + + + TCanvas* c = new TCanvas("rf109_chi2residpull","rf109_chi2residpull",900,300) ; + 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() ; + +} diff --git a/cpp/rf110_normintegration.C b/cpp/rf110_normintegration.C new file mode 100644 index 0000000..bb8b65a --- /dev/null +++ b/cpp/rf110_normintegration.C @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #110 +// +// Examples on normalization of p.d.f.s, +// integration of p.d.fs, construction +// of cumulative distribution functions from p.d.f.s +// in one dimension +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooAbsReal.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf110_normintegration() +{ + // S e t u p m o d e l + // --------------------- + + // Create observables x,y + RooRealVar x("x","x",-10,10) ; + + // Create p.d.f. gaussx(x,-2,3) + RooGaussian gx("gx","gx",x,RooConst(-2),RooConst(3)) ; + + + // R e t r i e v e r a w & n o r m a l i z e d v a l u e s o f R o o F i t p . d . f . s + // -------------------------------------------------------------------------------------------------- + + // Return 'raw' unnormalized value of gx + cout << "gx = " << gx.getVal() << endl ; + + // Return value of gx normalized over x in range [-10,10] + RooArgSet nset(x) ; + cout << "gx_Norm[x] = " << gx.getVal(&nset) << endl ; + + // Create object representing integral over gx + // which is used to calculate gx_Norm[x] == gx / gx_Int[x] + RooAbsReal* igx = gx.createIntegral(x) ; + cout << "gx_Int[x] = " << igx->getVal() << endl ; + + + // I n t e g r a t e n o r m a l i z e d p d f o v e r s u b r a n g e + // ---------------------------------------------------------------------------- + + // Define a range named "signal" in x from -5,5 + x.setRange("signal",-5,5) ; + + // Create an integral of gx_Norm[x] over x in range "signal" + // This is the fraction of of p.d.f. gx_Norm[x] which is in the + // range named "signal" + RooAbsReal* igx_sig = gx.createIntegral(x,NormSet(x),Range("signal")) ; + cout << "gx_Int[x|signal]_Norm[x] = " << igx_sig->getVal() << endl ; + + + + // C o n s t r u c t c u m u l a t i v e d i s t r i b u t i o n f u n c t i o n f r o m p d f + // ----------------------------------------------------------------------------------------------------- + + // Create the cumulative distribution function of gx + // i.e. calculate Int[-10,x] gx(x') dx' + RooAbsReal* gx_cdf = gx.createCdf(x) ; + + // Plot cdf of gx versus x + RooPlot* frame = x.frame(Title("c.d.f of Gaussian p.d.f")) ; + gx_cdf->plotOn(frame) ; + + + + // Draw plot on canvas + new TCanvas("rf110_normintegration","rf110_normintegration",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; + frame->Draw() ; + + +} diff --git a/cpp/rf111_derivatives.C b/cpp/rf111_derivatives.C new file mode 100644 index 0000000..22bd47a --- /dev/null +++ b/cpp/rf111_derivatives.C @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'BASIC FUNCTIONALITY' RooFit tutorial macro #111 +// +// Numerical 1st,2nd and 3rd order derivatives w.r.t. observables and parameters +// +// pdf = gauss(x,m,s) +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf111_derivatives() +{ + // S e t u p m o d e l + // --------------------- + + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + RooRealVar x("x","x",-10,10) ; + RooRealVar mean("mean","mean of gaussian",1,-10,10) ; + RooRealVar sigma("sigma","width of gaussian",1,0.1,10) ; + + // Build gaussian p.d.f in terms of x,mean and sigma + RooGaussian gauss("gauss","gaussian PDF",x,mean,sigma) ; + + + // C r e a t e a n d p l o t d e r i v a t i v e s w . r . t . x + // ---------------------------------------------------------------------- + + // Derivative of normalized gauss(x) w.r.t. observable x + RooAbsReal* dgdx = gauss.derivative(x,1) ; + + // Second and third derivative of normalized gauss(x) w.r.t. observable x + RooAbsReal* d2gdx2 = gauss.derivative(x,2) ; + RooAbsReal* d3gdx3 = gauss.derivative(x,3) ; + + // Construct plot frame in 'x' + RooPlot* xframe = x.frame(Title("d(Gauss)/dx")) ; + + // Plot gauss in frame (i.e. in x) + gauss.plotOn(xframe) ; + + // Plot derivatives in same frame + dgdx->plotOn(xframe,LineColor(kMagenta)) ; + d2gdx2->plotOn(xframe,LineColor(kRed)) ; + d3gdx3->plotOn(xframe,LineColor(kOrange)) ; + + + // C r e a t e a n d p l o t d e r i v a t i v e s w . r . t . s i g m a + // ------------------------------------------------------------------------------ + + // Derivative of normalized gauss(x) w.r.t. parameter sigma + RooAbsReal* dgds = gauss.derivative(sigma,1) ; + + // Second and third derivative of normalized gauss(x) w.r.t. parameter sigma + RooAbsReal* d2gds2 = gauss.derivative(sigma,2) ; + RooAbsReal* d3gds3 = gauss.derivative(sigma,3) ; + + // Construct plot frame in 'sigma' + RooPlot* sframe = sigma.frame(Title("d(Gauss)/d(sigma)"),Range(0.,2.)) ; + + // Plot gauss in frame (i.e. in x) + gauss.plotOn(sframe) ; + + // Plot derivatives in same frame + dgds->plotOn(sframe,LineColor(kMagenta)) ; + d2gds2->plotOn(sframe,LineColor(kRed)) ; + d3gds3->plotOn(sframe,LineColor(kOrange)) ; + + + + // Draw all frames on a canvas + TCanvas* c = new TCanvas("rf111_derivatives","rf111_derivatives",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.6) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; sframe->GetYaxis()->SetTitleOffset(1.6) ; sframe->Draw() ; + + +} diff --git a/cpp/rf201_composite.C b/cpp/rf201_composite.C new file mode 100644 index 0000000..34021ba --- /dev/null +++ b/cpp/rf201_composite.C @@ -0,0 +1,126 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #201 +// +// Composite p.d.f with signal and background component +// +// pdf = f_bkg * bkg(x,a0,a1) + (1-fbkg) * (f_sig1 * sig1(x,m,s1 + (1-f_sig1) * sig2(x,m,s2))) +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf201_composite() +{ + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + + //////////////////////////////////////////////////// + // M E T H O D 1 - T w o R o o A d d P d f s // + //////////////////////////////////////////////////// + + + // A d d s i g n a l c o m p o n e n t s + // ------------------------------------------ + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + + // A d d s i g n a l a n d b a c k g r o u n d + // ------------------------------------------------ + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + // S a m p l e , f i t a n d p l o t m o d e l + // --------------------------------------------------- + + // Generate a data sample of 1000 events in x from model + RooDataSet *data = model.generate(x,1000) ; + + // Fit model to data + model.fitTo(*data) ; + + // Plot data and PDF overlaid + RooPlot* xframe = x.frame(Title("Example of composite pdf=(sig1+sig2)+bkg")) ; + data->plotOn(xframe) ; + model.plotOn(xframe) ; + + // Overlay the background component of model with a dashed line + model.plotOn(xframe,Components(bkg),LineStyle(kDashed)) ; + + // Overlay the background+sig2 components of model with a dotted line + model.plotOn(xframe,Components(RooArgSet(bkg,sig2)),LineStyle(kDotted)) ; + + // Print structure of composite p.d.f. + model.Print("t") ; + + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // M E T H O D 2 - O n e R o o A d d P d f w i t h r e c u r s i v e f r a c t i o n s // + //////////////////////////////////////////////////////////////////////////////////////////////////// + + // Construct sum of models on one go using recursive fraction interpretations + // + // model2 = bkg + (sig1 + sig2) + // + RooAddPdf model2("model","g1+g2+a",RooArgList(bkg,sig1,sig2),RooArgList(bkgfrac,sig1frac),kTRUE) ; + + // NB: Each coefficient is interpreted as the fraction of the + // left-hand component of the i-th recursive sum, i.e. + // + // sum4 = A + ( B + ( C + D) with fraction fA, fB and fC expands to + // + // sum4 = fA*A + (1-fA)*(fB*B + (1-fB)*(fC*C + (1-fC)*D)) + + + // P l o t r e c u r s i v e a d d i t i o n m o d e l + // --------------------------------------------------------- + model2.plotOn(xframe,LineColor(kRed),LineStyle(kDashed)) ; + model2.plotOn(xframe,Components(RooArgSet(bkg,sig2)),LineColor(kRed),LineStyle(kDashed)) ; + model2.Print("t") ; + + + // Draw the frame on the canvas + new TCanvas("rf201_composite","rf201_composite",600,600) ; + gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + + +} + diff --git a/cpp/rf202_extendedmlfit.C b/cpp/rf202_extendedmlfit.C new file mode 100644 index 0000000..7e999a3 --- /dev/null +++ b/cpp/rf202_extendedmlfit.C @@ -0,0 +1,120 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #202 +// +// Setting up an extended maximum likelihood fit +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooExtendPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf202_extendedmlfit() +{ + + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + ///////////////////// + // M E T H O D 1 // + ///////////////////// + + + // C o n s t r u c t e x t e n d e d c o m p o s i t e m o d e l + // ------------------------------------------------------------------- + + // Sum the composite signal and background into an extended pdf nsig*sig+nbkg*bkg + RooRealVar nsig("nsig","number of signal events",500,0.,10000) ; + RooRealVar nbkg("nbkg","number of background events",500,0,10000) ; + RooAddPdf model("model","(g1+g2)+a",RooArgList(bkg,sig),RooArgList(nbkg,nsig)) ; + + + + // S a m p l e , f i t a n d p l o t e x t e n d e d m o d e l + // --------------------------------------------------------------------- + + // Generate a data sample of expected number events in x from model + // = model.expectedEvents() = nsig+nbkg + RooDataSet *data = model.generate(x) ; + + // Fit model to data, extended ML term automatically included + model.fitTo(*data) ; + + // Plot data and PDF overlaid, use expected number of events for p.d.f projection normalization + // rather than observed number of events (==data->numEntries()) + RooPlot* xframe = x.frame(Title("extended ML fit example")) ; + data->plotOn(xframe) ; + model.plotOn(xframe,Normalization(1.0,RooAbsReal::RelativeExpected)) ; + + // Overlay the background component of model with a dashed line + model.plotOn(xframe,Components(bkg),LineStyle(kDashed),Normalization(1.0,RooAbsReal::RelativeExpected)) ; + + // Overlay the background+sig2 components of model with a dotted line + model.plotOn(xframe,Components(RooArgSet(bkg,sig2)),LineStyle(kDotted),Normalization(1.0,RooAbsReal::RelativeExpected)) ; + + // Print structure of composite p.d.f. + model.Print("t") ; + + + ///////////////////// + // M E T H O D 2 // + ///////////////////// + + // C o n s t r u c t e x t e n d e d c o m p o n e n t s f i r s t + // --------------------------------------------------------------------- + + // Associated nsig/nbkg as expected number of events with sig/bkg + RooExtendPdf esig("esig","extended signal p.d.f",sig,nsig) ; + RooExtendPdf ebkg("ebkg","extended background p.d.f",bkg,nbkg) ; + + + // S u m e x t e n d e d c o m p o n e n t s w i t h o u t c o e f s + // ------------------------------------------------------------------------- + + // Construct sum of two extended p.d.f. (no coefficients required) + RooAddPdf model2("model2","(g1+g2)+a",RooArgList(ebkg,esig)) ; + + + + // Draw the frame on the canvas + new TCanvas("rf202_composite","rf202_composite",600,600) ; + gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + + +} diff --git a/cpp/rf203_ranges.C b/cpp/rf203_ranges.C new file mode 100644 index 0000000..ff13524 --- /dev/null +++ b/cpp/rf203_ranges.C @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #203 +// +// Fitting and plotting in sub ranges +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "RooFitResult.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf203_ranges() +{ + // S e t u p m o d e l + // --------------------- + + // Construct observables x + RooRealVar x("x","x",-10,10) ; + + // Construct gaussx(x,mx,1) + RooRealVar mx("mx","mx",0,-10,10) ; + RooGaussian gx("gx","gx",x,mx,RooConst(1)) ; + + // Construct px = 1 (flat in x) + RooPolynomial px("px","px",x) ; + + // Construct model = f*gx + (1-f)px + RooRealVar f("f","f",0.,1.) ; + RooAddPdf model("model","model",RooArgList(gx,px),f) ; + + // Generated 10000 events in (x,y) from p.d.f. model + RooDataSet* modelData = model.generate(x,10000) ; + + // F i t f u l l r a n g e + // --------------------------- + + // Fit p.d.f to all data + RooFitResult* r_full = model.fitTo(*modelData,Save(kTRUE)) ; + + + // F i t p a r t i a l r a n g e + // ---------------------------------- + + // Define "signal" range in x as [-3,3] + x.setRange("signal",-3,3) ; + + // Fit p.d.f only to data in "signal" range + RooFitResult* r_sig = model.fitTo(*modelData,Save(kTRUE),Range("signal")) ; + + + // P l o t / p r i n t r e s u l t s + // --------------------------------------- + + // Make plot frame in x and add data and fitted model + RooPlot* frame = x.frame(Title("Fitting a sub range")) ; + modelData->plotOn(frame) ; + model.plotOn(frame,Range("Full"),LineStyle(kDashed),LineColor(kRed)) ; // Add shape in full ranged dashed + model.plotOn(frame) ; // By default only fitted range is shown + + // Print fit results + cout << "result of fit on all data " << endl ; + r_full->Print() ; + cout << "result of fit in in signal region (note increased error on signal fraction)" << endl ; + r_sig->Print() ; + + // Draw frame on canvas + new TCanvas("rf203_ranges","rf203_ranges",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + + return ; + +} diff --git a/cpp/rf204_extrangefit.C b/cpp/rf204_extrangefit.C new file mode 100644 index 0000000..1e58266 --- /dev/null +++ b/cpp/rf204_extrangefit.C @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #204 +// +// Extended maximum likelihood fit with alternate range definition +// for observed number of events. +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooExtendPdf.h" +#include "RooFitResult.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf204_extrangefit() +{ + + + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + + // C o n s t r u c t e x t e n d e d c o m p s wi t h r a n g e s p e c + // ------------------------------------------------------------------------------ + + // Define signal range in which events counts are to be defined + x.setRange("signalRange",4,6) ; + + // Associated nsig/nbkg as expected number of events with sig/bkg _in_the_range_ "signalRange" + RooRealVar nsig("nsig","number of signal events in signalRange",500,0.,10000) ; + RooRealVar nbkg("nbkg","number of background events in signalRange",500,0,10000) ; + RooExtendPdf esig("esig","extended signal p.d.f",sig,nsig,"signalRange") ; + RooExtendPdf ebkg("ebkg","extended background p.d.f",bkg,nbkg,"signalRange") ; + + + // S u m e x t e n d e d c o m p o n e n t s + // --------------------------------------------- + + // Construct sum of two extended p.d.f. (no coefficients required) + RooAddPdf model("model","(g1+g2)+a",RooArgList(ebkg,esig)) ; + + + // S a m p l e d a t a , f i t m o d e l + // ------------------------------------------- + + // Generate 1000 events from model so that nsig,nbkg come out to numbers <<500 in fit + RooDataSet *data = model.generate(x,1000) ; + + + // Perform unbinned extended ML fit to data + RooFitResult* r = model.fitTo(*data,Extended(kTRUE),Save()) ; + r->Print() ; + +} diff --git a/cpp/rf205_compplot.C b/cpp/rf205_compplot.C new file mode 100644 index 0000000..53fd122 --- /dev/null +++ b/cpp/rf205_compplot.C @@ -0,0 +1,120 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #205 +// +// Options for plotting components of composite p.d.f.s. +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooAddPdf.h" +#include "RooChebychev.h" +#include "RooExponential.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf205_compplot() +{ + // S e t u p c o m p o s i t e p d f + // -------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg1("bkg1","Background 1",x,RooArgSet(a0,a1)) ; + + // Build expontential pdf + RooRealVar alpha("alpha","alpha",-1) ; + RooExponential bkg2("bkg2","Background 2",x,alpha) ; + + // Sum the background components into a composite background p.d.f. + RooRealVar bkg1frac("sig1frac","fraction of component 1 in background",0.2,0.,1.) ; + RooAddPdf bkg("bkg","Signal",RooArgList(bkg1,bkg2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + + // S e t u p b a s i c p l o t w i t h d a t a a n d f u l l p d f + // ------------------------------------------------------------------------------ + + // Generate a data sample of 1000 events in x from model + RooDataSet *data = model.generate(x,1000) ; + + // Plot data and complete PDF overlaid + RooPlot* xframe = x.frame(Title("Component plotting of pdf=(sig1+sig2)+(bkg1+bkg2)")) ; + data->plotOn(xframe) ; + model.plotOn(xframe) ; + + // Clone xframe for use below + RooPlot* xframe2 = (RooPlot*) xframe->Clone("xframe2") ; + + + // M a k e c o m p o n e n t b y o b j e c t r e f e r e n c e + // -------------------------------------------------------------------- + + // Plot single background component specified by object reference + model.plotOn(xframe,Components(bkg),LineColor(kRed)) ; + + // Plot single background component specified by object reference + model.plotOn(xframe,Components(bkg2),LineStyle(kDashed),LineColor(kRed)) ; + + // Plot multiple background components specified by object reference + // Note that specified components may occur at any level in object tree + // (e.g bkg is component of 'model' and 'sig2' is component 'sig') + model.plotOn(xframe,Components(RooArgSet(bkg,sig2)),LineStyle(kDotted)) ; + + + + // M a k e c o m p o n e n t b y n a m e / r e g e x p + // ------------------------------------------------------------ + + // Plot single background component specified by name + model.plotOn(xframe2,Components("bkg"),LineColor(kCyan)) ; + + // Plot multiple background components specified by name + model.plotOn(xframe2,Components("bkg1,sig2"),LineStyle(kDotted),LineColor(kCyan)) ; + + // Plot multiple background components specified by regular expression on name + model.plotOn(xframe2,Components("sig*"),LineStyle(kDashed),LineColor(kCyan)) ; + + // Plot multiple background components specified by multiple regular expressions on name + model.plotOn(xframe2,Components("bkg1,sig*"),LineStyle(kDashed),LineColor(kYellow),Invisible()) ; + + + // Draw the frame on the canvas + TCanvas* c = new TCanvas("rf205_compplot","rf205_compplot",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; xframe2->GetYaxis()->SetTitleOffset(1.4) ; xframe2->Draw() ; + + +} diff --git a/cpp/rf206_treevistools.C b/cpp/rf206_treevistools.C new file mode 100644 index 0000000..38159ea --- /dev/null +++ b/cpp/rf206_treevistools.C @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #206 +// +// Tools for visualization of RooAbsArg expression trees +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooExponential.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf206_treevistools() +{ + // S e t u p c o m p o s i t e p d f + // -------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg1("bkg1","Background 1",x,RooArgSet(a0,a1)) ; + + // Build expontential pdf + RooRealVar alpha("alpha","alpha",-1) ; + RooExponential bkg2("bkg2","Background 2",x,alpha) ; + + // Sum the background components into a composite background p.d.f. + RooRealVar bkg1frac("bkg1frac","fraction of component 1 in background",0.2,0.,1.) ; + RooAddPdf bkg("bkg","Signal",RooArgList(bkg1,bkg2),bkg1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + // P r i n t c o m p o s i t e t r e e i n A S C I I + // ----------------------------------------------------------- + + // Print tree to stdout + model.Print("t") ; + + // Print tree to file + model.printCompactTree("","rf206_asciitree.txt") ; + + + // D r a w c o m p o s i t e t r e e g r a p h i c a l l y + // ------------------------------------------------------------- + + // Print GraphViz DOT file with representation of tree + model.graphVizTree("rf206_model.dot") ; + + // Make graphic output file with one of the GraphViz tools + // (freely available from www.graphviz.org) + // + // 'Top-to-bottom graph' + // unix> dot -Tgif -o rf207_model_dot.gif rf207_model.dot + // + // 'Spring-model graph' + // unix> fdp -Tgif -o rf207_model_fdp.gif rf207_model.dot + +} diff --git a/cpp/rf207_comptools.C b/cpp/rf207_comptools.C new file mode 100644 index 0000000..ba6e177 --- /dev/null +++ b/cpp/rf207_comptools.C @@ -0,0 +1,144 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #207 +// +// Tools and utilities for manipulation of composite objects +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooChebychev.h" +#include "RooExponential.h" +#include "RooAddPdf.h" +#include "RooPlot.h" +#include "RooCustomizer.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf207_comptools() +{ + + // S e t u p c o m p o s i t e p d f, d a t a s e t + // -------------------------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma("sigma","width of gaussians",0.5) ; + RooGaussian sig("sig","Signal component 1",x,mean,sigma) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg1("bkg1","Background 1",x,RooArgSet(a0,a1)) ; + + // Build expontential pdf + RooRealVar alpha("alpha","alpha",-1) ; + RooExponential bkg2("bkg2","Background 2",x,alpha) ; + + // Sum the background components into a composite background p.d.f. + RooRealVar bkg1frac("bkg1frac","fraction of component 1 in background",0.2,0.,1.) ; + RooAddPdf bkg("bkg","Signal",RooArgList(bkg1,bkg2),bkg1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + + // Create dummy dataset that has more observables than the above pdf + RooRealVar y("y","y",-10,10) ; + RooDataSet data("data","data",RooArgSet(x,y)) ; + + + + + ////////////////////////////////////////////////////////// + // B a s i c i n f o r m a t i o n r e q u e s t s // + ////////////////////////////////////////////////////////// + + + // G e t l i s t o f o b s e r v a b l e s + // --------------------------------------------- + + // Get list of observables of pdf in context of a dataset + // + // Observables are define each context as the variables + // shared between a model and a dataset. In this case + // that is the variable 'x' + + RooArgSet* model_obs = model.getObservables(data) ; + model_obs->Print("v") ; + + + // G e t l i s t o f p a r a m e t e r s + // ------------------------------------------- + + // Get list of parameters, given list of observables + RooArgSet* model_params = model.getParameters(x) ; + model_params->Print("v") ; + + // Get list of parameters, given a dataset + // (Gives identical results to operation above) + RooArgSet* model_params2 = model.getParameters(data) ; + model_params2->Print() ; + + + // G e t l i s t o f c o m p o n e n t s + // ------------------------------------------- + + // Get list of component objects, including top-level node + RooArgSet* model_comps = model.getComponents() ; + model_comps->Print("v") ; + + + ///////////////////////////////////////////////////////////////////////////////////// + // M o d i f i c a t i o n s t o s t r u c t u r e o f c o m p o s i t e s // + ///////////////////////////////////////////////////////////////////////////////////// + + + // Create a second Gaussian + RooRealVar sigma2("sigma2","width of gaussians",1) ; + RooGaussian sig2("sig2","Signal component 1",x,mean,sigma2) ; + + // Create a sum of the original Gaussian plus the new second Gaussian + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sigsum("sigsum","sig+sig2",RooArgList(sig,sig2),sig1frac) ; + + // Construct a customizer utility to customize model + RooCustomizer cust(model,"cust") ; + + // Instruct the customizer to replace node 'sig' with node 'sigsum' + cust.replaceArg(sig,sigsum) ; + + // Build a clone of the input pdf according to the above customization + // instructions. Each node that requires modified is clone so that the + // original pdf remained untouched. The name of each cloned node is that + // of the original node suffixed by the name of the customizer object + // + // The returned head node own all nodes that were cloned as part of + // the build process so when cust_clone is deleted so will all other + // nodes that were created in the process. + RooAbsPdf* cust_clone = (RooAbsPdf*) cust.build(kTRUE) ; + + // Print structure of clone of model with sig->sigsum replacement. + cust_clone->Print("t") ; + + + delete cust_clone ; + +} diff --git a/cpp/rf208_convolution.C b/cpp/rf208_convolution.C new file mode 100644 index 0000000..c13edc9 --- /dev/null +++ b/cpp/rf208_convolution.C @@ -0,0 +1,84 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #208 +// +// One-dimensional numeric convolution +// (require ROOT to be compiled with --enable-fftw3) +// +// pdf = landau(t) (x) gauss(t) +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooLandau.h" +#include "RooFFTConvPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf208_convolution() +{ + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Construct observable + RooRealVar t("t","t",-10,30) ; + + // Construct landau(t,ml,sl) ; + RooRealVar ml("ml","mean landau",5.,-20,20) ; + RooRealVar sl("sl","sigma landau",1,0.1,10) ; + RooLandau landau("lx","lx",t,ml,sl) ; + + // Construct gauss(t,mg,sg) + RooRealVar mg("mg","mg",0) ; + RooRealVar sg("sg","sg",2,0.1,10) ; + RooGaussian gauss("gauss","gauss",t,mg,sg) ; + + + // C o n s t r u c t c o n v o l u t i o n p d f + // --------------------------------------- + + // Set #bins to be used for FFT sampling to 10000 + t.setBins(10000,"cache") ; + + // Construct landau (x) gauss + RooFFTConvPdf lxg("lxg","landau (X) gauss",t,landau,gauss) ; + + + + // S a m p l e , f i t a n d p l o t c o n v o l u t e d p d f + // ---------------------------------------------------------------------- + + // Sample 1000 events in x from gxlx + RooDataSet* data = lxg.generate(t,10000) ; + + // Fit gxlx to data + lxg.fitTo(*data) ; + + // Plot data, landau pdf, landau (X) gauss pdf + RooPlot* frame = t.frame(Title("landau (x) gauss convolution")) ; + data->plotOn(frame) ; + lxg.plotOn(frame) ; + landau.plotOn(frame,LineStyle(kDashed)) ; + + + // Draw frame on canvas + new TCanvas("rf208_convolution","rf208_convolution",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + +} + + + diff --git a/cpp/rf209_anaconv.C b/cpp/rf209_anaconv.C new file mode 100644 index 0000000..9e7c65c --- /dev/null +++ b/cpp/rf209_anaconv.C @@ -0,0 +1,93 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #209 +// +// Decay function p.d.fs with optional B physics +// effects (mixing and CP violation) that can be +// analytically convolved with e.g. Gaussian resolution +// functions +// +// pdf1 = decay(t,tau) (x) delta(t) +// pdf2 = decay(t,tau) (x) gauss(t,m,s) +// pdf3 = decay(t,tau) (x) (f*gauss1(t,m1,s1) + (1-f)*gauss2(t,m1,s1)) +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussModel.h" +#include "RooAddModel.h" +#include "RooTruthModel.h" +#include "RooDecay.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf209_anaconv() +{ + // B - p h y s i c s p d f w i t h t r u t h r e s o l u t i o n + // --------------------------------------------------------------------- + + // Variables of decay p.d.f. + RooRealVar dt("dt","dt",-10,10) ; + RooRealVar tau("tau","tau",1.548) ; + + // Build a truth resolution model (delta function) + RooTruthModel tm("tm","truth model",dt) ; + + // Construct decay(t) (x) delta(t) + RooDecay decay_tm("decay_tm","decay",dt,tau,tm,RooDecay::DoubleSided) ; + + // Plot p.d.f. (dashed) + RooPlot* frame = dt.frame(Title("Bdecay (x) resolution")) ; + decay_tm.plotOn(frame,LineStyle(kDashed)) ; + + + // B - p h y s i c s p d f w i t h G a u s s i a n r e s o l u t i o n + // ---------------------------------------------------------------------------- + + // Build a gaussian resolution model + RooRealVar bias1("bias1","bias1",0) ; + RooRealVar sigma1("sigma1","sigma1",1) ; + RooGaussModel gm1("gm1","gauss model 1",dt,bias1,sigma1) ; + + // Construct decay(t) (x) gauss1(t) + RooDecay decay_gm1("decay_gm1","decay",dt,tau,gm1,RooDecay::DoubleSided) ; + + // Plot p.d.f. + decay_gm1.plotOn(frame) ; + + + // B - p h y s i c s p d f w i t h d o u b l e G a u s s i a n r e s o l u t i o n + // ------------------------------------------------------------------------------------------ + + // Build another gaussian resolution model + RooRealVar bias2("bias2","bias2",0) ; + RooRealVar sigma2("sigma2","sigma2",5) ; + RooGaussModel gm2("gm2","gauss model 2",dt,bias2,sigma2) ; + + // Build a composite resolution model f*gm1+(1-f)*gm2 + RooRealVar gm1frac("gm1frac","fraction of gm1",0.5) ; + RooAddModel gmsum("gmsum","sum of gm1 and gm2",RooArgList(gm1,gm2),gm1frac) ; + + // Construct decay(t) (x) (f*gm1 + (1-f)*gm2) + RooDecay decay_gmsum("decay_gmsum","decay",dt,tau,gmsum,RooDecay::DoubleSided) ; + + // Plot p.d.f. (red) + decay_gmsum.plotOn(frame,LineColor(kRed)) ; + + + // Draw all frames on canvas + new TCanvas("rf209_anaconv","rf209_anaconv",600, 600); + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + +} diff --git a/cpp/rf210_angularconv.C b/cpp/rf210_angularconv.C new file mode 100644 index 0000000..4bfbfcf --- /dev/null +++ b/cpp/rf210_angularconv.C @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #210 +// +// Convolution in cyclical angular observables theta, and +// construction of p.d.f in terms of trasnformed angular +// coordinates, e.g. cos(theta), where the convolution +// is performed in theta rather than cos(theta) +// +// (require ROOT to be compiled with --enable-fftw3) +// +// pdf(theta) = T(theta) (x) gauss(theta) +// pdf(cosTheta) = T(acos(cosTheta)) (x) gauss(acos(cosTheta)) +// +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooGenericPdf.h" +#include "RooFormulaVar.h" +#include "RooFFTConvPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf210_angularconv() +{ + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Define angle psi + RooRealVar psi("psi","psi",0,3.14159268) ; + + // Define physics p.d.f T(psi) + RooGenericPdf Tpsi("Tpsi","1+sin(2*@0)",psi) ; + + // Define resolution R(psi) + RooRealVar gbias("gbias","gbias",0.2,0.,1) ; + RooRealVar greso("greso","greso",0.3,0.1,1.0) ; + RooGaussian Rpsi("Rpsi","Rpsi",psi,gbias,greso) ; + + // Define cos(psi) and function psif that calculates psi from cos(psi) + RooRealVar cpsi("cpsi","cos(psi)",-1,1) ; + RooFormulaVar psif("psif","acos(cpsi)",cpsi) ; + + // Define physics p.d.f. also as function of cos(psi): T(psif(cpsi)) = T(cpsi) ; + RooGenericPdf Tcpsi("T","1+sin(2*@0)",psif) ; + + + + // C o n s t r u c t c o n v o l u t i o n p d f i n p s i + // -------------------------------------------------------------- + + // Define convoluted p.d.f. as function of psi: M=[T(x)R](psi) = M(psi) + RooFFTConvPdf Mpsi("Mf","Mf",psi,Tpsi,Rpsi) ; + + // Set the buffer fraction to zero to obtain a true cyclical convolution + Mpsi.setBufferFraction(0) ; + + + + // S a m p l e , f i t a n d p l o t c o n v o l u t e d p d f ( p s i ) + // -------------------------------------------------------------------------------- + + // Generate some events in observable psi + RooDataSet* data_psi = Mpsi.generate(psi,10000) ; + + // Fit convoluted model as function of angle psi + Mpsi.fitTo(*data_psi) ; + + // Plot cos(psi) frame with Mf(cpsi) + RooPlot* frame1 = psi.frame(Title("Cyclical convolution in angle psi")) ; + data_psi->plotOn(frame1) ; + Mpsi.plotOn(frame1) ; + + // Overlay comparison to unsmeared physics p.d.f T(psi) + Tpsi.plotOn(frame1,LineColor(kRed)) ; + + + + // C o n s t r u c t c o n v o l u t i o n p d f i n c o s ( p s i ) + // -------------------------------------------------------------------------- + + + // Define convoluted p.d.f. as function of cos(psi): M=[T(x)R](psif(cpsi)) = M(cpsi) + // + // Need to give both observable psi here (for definition of convolution) + // and function psif here (for definition of observables, ultimately in cpsi) + RooFFTConvPdf Mcpsi("Mf","Mf",psif,psi,Tpsi,Rpsi) ; + + // Set the buffer fraction to zero to obtain a true cyclical convolution + Mcpsi.setBufferFraction(0) ; + + + // S a m p l e , f i t a n d p l o t c o n v o l u t e d p d f ( c o s p s i ) + // -------------------------------------------------------------------------------- + + // Generate some events + RooDataSet* data_cpsi = Mcpsi.generate(cpsi,10000) ; + + // set psi constant to exclude to be a parameter of the fit + psi.setConstant(true); + + // Fit convoluted model as function of cos(psi) + Mcpsi.fitTo(*data_cpsi) ; + + // Plot cos(psi) frame with Mf(cpsi) + RooPlot* frame2 = cpsi.frame(Title("Same convolution in psi, expressed in cos(psi)")) ; + data_cpsi->plotOn(frame2) ; + Mcpsi.plotOn(frame2) ; + + // Overlay comparison to unsmeared physics p.d.f Tf(cpsi) + Tcpsi.plotOn(frame2,LineColor(kRed)) ; + + + + // Draw frame on canvas + TCanvas* c = new TCanvas("rf210_angularconv","rf210_angularconv",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() ; + +} diff --git a/cpp/rf211_paramconv.C b/cpp/rf211_paramconv.C new file mode 100644 index 0000000..d29a5df --- /dev/null +++ b/cpp/rf211_paramconv.C @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ADDITION AND CONVOLUTION' RooFit tutorial macro #211 +// +// Working a with a p.d.f. with a convolution operator in terms +// of a parameter +// +// (require ROOT to be compiled with --enable-fftw3) +// +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooGenericPdf.h" +#include "RooFormulaVar.h" +#include "RooFFTConvPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH2.h" +using namespace RooFit ; + + +void rf211_paramconv() +{ + // S e t u p c o m p o n e n t p d f s + // --------------------------------------- + + // Gaussian g(x ; mean,sigma) + RooRealVar x("x","x",-10,10) ; + RooRealVar mean("mean","mean",-3,3) ; + RooRealVar sigma("sigma","sigma",0.5,0.1,10) ; + RooGaussian modelx("gx","gx",x,mean,sigma) ; + + // Block function in mean + RooRealVar a("a","a",2,1,10) ; + RooGenericPdf model_mean("model_mean","abs(mean)generateBinned(x,1000) ; + + // Fit p.d.f. to toy data + projModel->fitTo(*d,Verbose()) ; + + // Plot data and fitted p.d.f. + RooPlot* frame = x.frame(Bins(25)) ; + d->plotOn(frame) ; + projModel->plotOn(frame) ; + + // Make 2d histogram of model(x;mean) + TH1* hh = model.createHistogram("hh",x,Binning(50),YVar(mean,Binning(50)),ConditionalObservables(mean)) ; + hh->SetTitle("histogram of model(x|mean)") ; + hh->SetLineColor(kBlue) ; + + // Draw frame on canvas + TCanvas* c = new TCanvas("rf211_paramconv","rf211_paramconv",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.20) ; hh->GetZaxis()->SetTitleOffset(2.5) ; hh->Draw("surf") ; + +} diff --git a/cpp/rf301_composition.C b/cpp/rf301_composition.C new file mode 100644 index 0000000..00f1b08 --- /dev/null +++ b/cpp/rf301_composition.C @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #301 +// +// Multi-dimensional p.d.f.s through composition, e.g. substituting a +// p.d.f parameter with a function that depends on other observables +// +// pdf = gauss(x,f(y),s) with f(y) = a0 + a1*y +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooPolyVar.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf301_composition() +{ + // S e t u p c o m p o s e d m o d e l g a u s s ( x , m ( y ) , s ) + // ----------------------------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + + // Create function f(y) = a0 + a1*y + RooRealVar a0("a0","a0",-0.5,-5,5) ; + RooRealVar a1("a1","a1",-0.5,-1,1) ; + RooPolyVar fy("fy","fy",y,RooArgSet(a0,a1)) ; + + // Creat gauss(x,f(y),s) + RooRealVar sigma("sigma","width of gaussian",0.5) ; + RooGaussian model("model","Gaussian with shifting mean",x,fy,sigma) ; + + + // S a m p l e d a t a , p l o t d a t a a n d p d f o n x a n d y + // --------------------------------------------------------------------------------- + + // Generate 10000 events in x and y from model + RooDataSet *data = model.generate(RooArgSet(x,y),10000) ; + + // Plot x distribution of data and projection of model on x = Int(dy) model(x,y) + RooPlot* xframe = x.frame() ; + data->plotOn(xframe) ; + model.plotOn(xframe) ; + + // Plot x distribution of data and projection of model on y = Int(dx) model(x,y) + RooPlot* yframe = y.frame() ; + data->plotOn(yframe) ; + model.plotOn(yframe) ; + + // Make two-dimensional plot in x vs y + TH1* hh_model = model.createHistogram("hh_model",x,Binning(50),YVar(y,Binning(50))) ; + hh_model->SetLineColor(kBlue) ; + + + + // Make canvas and draw RooPlots + TCanvas *c = new TCanvas("rf301_composition","rf301_composition",1200, 400); + c->Divide(3); + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; yframe->GetYaxis()->SetTitleOffset(1.4) ; yframe->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.20) ; hh_model->GetZaxis()->SetTitleOffset(2.5) ; hh_model->Draw("surf") ; + +} + + + diff --git a/cpp/rf302_utilfuncs.C b/cpp/rf302_utilfuncs.C new file mode 100644 index 0000000..175dbb8 --- /dev/null +++ b/cpp/rf302_utilfuncs.C @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #302 +// +// Utility functions classes available for use in tailoring +// of composite (multidimensional) pdfs +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooFormulaVar.h" +#include "RooAddition.h" +#include "RooProduct.h" +#include "RooPolyVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" + +using namespace RooFit ; + + +void rf302_utilfuncs() +{ + // C r e a t e o b s e r v a b l e s , p a r a m e t e r s + // ----------------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + + // Create parameters + RooRealVar a0("a0","a0",-1.5,-5,5) ; + RooRealVar a1("a1","a1",-0.5,-1,1) ; + RooRealVar sigma("sigma","width of gaussian",0.5) ; + + + // U s i n g R o o F o r m u l a V a r t o t a i l o r p d f + // ----------------------------------------------------------------------- + + // Create interpreted function f(y) = a0 - a1*sqrt(10*abs(y)) + RooFormulaVar fy_1("fy_1","a0-a1*sqrt(10*abs(y))",RooArgSet(y,a0,a1)) ; + + // Create gauss(x,f(y),s) + RooGaussian model_1("model_1","Gaussian with shifting mean",x,fy_1,sigma) ; + + + + // U s i n g R o o P o l y V a r t o t a i l o r p d f + // ----------------------------------------------------------------------- + + // Create polynomial function f(y) = a0 + a1*y + RooPolyVar fy_2("fy_2","fy_2",y,RooArgSet(a0,a1)) ; + + // Create gauss(x,f(y),s) + RooGaussian model_2("model_2","Gaussian with shifting mean",x,fy_2,sigma) ; + + + + // U s i n g R o o A d d i t i o n t o t a i l o r p d f + // ----------------------------------------------------------------------- + + // Create sum function f(y) = a0 + y + RooAddition fy_3("fy_3","a0+y",RooArgSet(a0,y)) ; + + // Create gauss(x,f(y),s) + RooGaussian model_3("model_3","Gaussian with shifting mean",x,fy_3,sigma) ; + + + + // U s i n g R o o P r o d u c t t o t a i l o r p d f + // ----------------------------------------------------------------------- + + // Create product function f(y) = a1*y + RooProduct fy_4("fy_4","a1*y",RooArgSet(a1,y)) ; + + // Create gauss(x,f(y),s) + RooGaussian model_4("model_4","Gaussian with shifting mean",x,fy_4,sigma) ; + + + + // P l o t a l l p d f s + // ---------------------------- + + // Make two-dimensional plots in x vs y + TH1* hh_model_1 = model_1.createHistogram("hh_model_1",x,Binning(50),YVar(y,Binning(50))) ; + TH1* hh_model_2 = model_2.createHistogram("hh_model_2",x,Binning(50),YVar(y,Binning(50))) ; + TH1* hh_model_3 = model_3.createHistogram("hh_model_3",x,Binning(50),YVar(y,Binning(50))) ; + TH1* hh_model_4 = model_4.createHistogram("hh_model_4",x,Binning(50),YVar(y,Binning(50))) ; + hh_model_1->SetLineColor(kBlue) ; + hh_model_2->SetLineColor(kBlue) ; + hh_model_3->SetLineColor(kBlue) ; + hh_model_4->SetLineColor(kBlue) ; + + // Make canvas and draw RooPlots + TCanvas *c = new TCanvas("rf302_utilfuncs","rf302_utilfuncs",800, 800); + c->Divide(2,2); + c->cd(1) ; gPad->SetLeftMargin(0.20) ; hh_model_1->GetZaxis()->SetTitleOffset(2.5) ; hh_model_1->Draw("surf") ; + c->cd(2) ; gPad->SetLeftMargin(0.20) ; hh_model_2->GetZaxis()->SetTitleOffset(2.5) ; hh_model_2->Draw("surf") ; + c->cd(3) ; gPad->SetLeftMargin(0.20) ; hh_model_3->GetZaxis()->SetTitleOffset(2.5) ; hh_model_3->Draw("surf") ; + c->cd(4) ; gPad->SetLeftMargin(0.20) ; hh_model_4->GetZaxis()->SetTitleOffset(2.5) ; hh_model_4->Draw("surf") ; + +} diff --git a/cpp/rf303_conditional.C b/cpp/rf303_conditional.C new file mode 100644 index 0000000..9c0c448 --- /dev/null +++ b/cpp/rf303_conditional.C @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #303 +// +// Use of tailored p.d.f as conditional p.d.fs.s +// +// pdf = gauss(x,f(y),sx | y ) with f(y) = a0 + a1*y +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooPolyVar.h" +#include "RooProdPdf.h" +#include "RooPlot.h" +#include "TRandom.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +RooDataSet* makeFakeDataXY() ; + +void rf303_conditional() +{ + // S e t u p c o m p o s e d m o d e l g a u s s ( x , m ( y ) , s ) + // ----------------------------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y",-10,10) ; + + // Create function f(y) = a0 + a1*y + RooRealVar a0("a0","a0",-0.5,-5,5) ; + RooRealVar a1("a1","a1",-0.5,-1,1) ; + RooPolyVar fy("fy","fy",y,RooArgSet(a0,a1)) ; + + // Creat gauss(x,f(y),s) + RooRealVar sigma("sigma","width of gaussian",0.5,0.1,2.0) ; + RooGaussian model("model","Gaussian with shifting mean",x,fy,sigma) ; + + + // Obtain fake external experimental dataset with values for x and y + RooDataSet* expDataXY = makeFakeDataXY() ; + + + + // G e n e r a t e d a t a f r o m c o n d i t i o n a l p . d . f m o d e l ( x | y ) + // --------------------------------------------------------------------------------------------- + + // Make subset of experimental data with only y values + RooDataSet* expDataY= (RooDataSet*) expDataXY->reduce(y) ; + + // Generate 10000 events in x obtained from _conditional_ model(x|y) with y values taken from experimental data + RooDataSet *data = model.generate(x,ProtoData(*expDataY)) ; + data->Print() ; + + + + // F i t c o n d i t i o n a l p . d . f m o d e l ( x | y ) t o d a t a + // --------------------------------------------------------------------------------------------- + + model.fitTo(*expDataXY,ConditionalObservables(y)) ; + + + + // P r o j e c t c o n d i t i o n a l p . d . f o n x a n d y d i m e n s i o n s + // --------------------------------------------------------------------------------------------- + + // Plot x distribution of data and projection of model on x = 1/Ndata sum(data(y_i)) model(x;y_i) + RooPlot* xframe = x.frame() ; + expDataXY->plotOn(xframe) ; + model.plotOn(xframe,ProjWData(*expDataY)) ; + + + // Speed up (and approximate) projection by using binned clone of data for projection + RooAbsData* binnedDataY = expDataY->binnedClone() ; + model.plotOn(xframe,ProjWData(*binnedDataY),LineColor(kCyan),LineStyle(kDotted)) ; + + + // Show effect of projection with too coarse binning + ((RooRealVar*)expDataY->get()->find("y"))->setBins(5) ; + RooAbsData* binnedDataY2 = expDataY->binnedClone() ; + model.plotOn(xframe,ProjWData(*binnedDataY2),LineColor(kRed)) ; + + + // Make canvas and draw RooPlots + new TCanvas("rf303_conditional","rf303_conditional",600, 460); + gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.2) ; xframe->Draw() ; +} + + + + +RooDataSet* makeFakeDataXY() +{ + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y",-10,10) ; + RooArgSet coord(x,y) ; + + RooDataSet* d = new RooDataSet("d","d",RooArgSet(x,y)) ; + + for (int i=0 ; i<10000 ; i++) { + Double_t tmpy = gRandom->Gaus(0,10) ; + Double_t tmpx = gRandom->Gaus(0.5*tmpy,1) ; + if (fabs(tmpy)<10 && fabs(tmpx)<10) { + x = tmpx ; + y = tmpy ; + d->add(coord) ; + } + + } + + return d ; +} + diff --git a/cpp/rf304_uncorrprod.C b/cpp/rf304_uncorrprod.C new file mode 100644 index 0000000..b6b9a63 --- /dev/null +++ b/cpp/rf304_uncorrprod.C @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #304 +// +// Simple uncorrelated multi-dimensional p.d.f.s +// +// pdf = gauss(x,mx,sx) * gauss(y,my,sy) +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + + +void rf304_uncorrprod() +{ + + // C r e a t e c o m p o n e n t p d f s i n x a n d y + // ---------------------------------------------------------------- + + // Create two p.d.f.s gaussx(x,meanx,sigmax) gaussy(y,meany,sigmay) and its variables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + + RooRealVar meanx("mean1","mean of gaussian x",2) ; + RooRealVar meany("mean2","mean of gaussian y",-2) ; + RooRealVar sigmax("sigmax","width of gaussian x",1) ; + RooRealVar sigmay("sigmay","width of gaussian y",5) ; + + RooGaussian gaussx("gaussx","gaussian PDF",x,meanx,sigmax) ; + RooGaussian gaussy("gaussy","gaussian PDF",y,meany,sigmay) ; + + + + // C o n s t r u c t u n c o r r e l a t e d p r o d u c t p d f + // ------------------------------------------------------------------- + + // Multiply gaussx and gaussy into a two-dimensional p.d.f. gaussxy + RooProdPdf gaussxy("gaussxy","gaussx*gaussy",RooArgList(gaussx,gaussy)) ; + + + + // S a m p l e p d f , p l o t p r o j e c t i o n o n x a n d y + // --------------------------------------------------------------------------- + + // Generate 10000 events in x and y from gaussxy + RooDataSet *data = gaussxy.generate(RooArgSet(x,y),10000) ; + + // Plot x distribution of data and projection of gaussxy on x = Int(dy) gaussxy(x,y) + RooPlot* xframe = x.frame(Title("X projection of gauss(x)*gauss(y)")) ; + data->plotOn(xframe) ; + gaussxy.plotOn(xframe) ; + + // Plot x distribution of data and projection of gaussxy on y = Int(dx) gaussxy(x,y) + RooPlot* yframe = y.frame(Title("Y projection of gauss(x)*gauss(y)")) ; + data->plotOn(yframe) ; + gaussxy.plotOn(yframe) ; + + + + // Make canvas and draw RooPlots + TCanvas *c = new TCanvas("rf304_uncorrprod","rf304_uncorrprod",800, 400); + c->Divide(2); + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; yframe->GetYaxis()->SetTitleOffset(1.4) ; yframe->Draw() ; + +} + + + diff --git a/cpp/rf305_condcorrprod.C b/cpp/rf305_condcorrprod.C new file mode 100644 index 0000000..4fb8bb5 --- /dev/null +++ b/cpp/rf305_condcorrprod.C @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #305 +// +// Multi-dimensional p.d.f.s with conditional p.d.fs in product +// +// pdf = gauss(x,f(y),sx | y ) * gauss(y,ms,sx) with f(y) = a0 + a1*y +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolyVar.h" +#include "RooProdPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf305_condcorrprod() +{ + // C r e a t e c o n d i t i o n a l p d f g x ( x | y ) + // ----------------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + + // Create function f(y) = a0 + a1*y + RooRealVar a0("a0","a0",-0.5,-5,5) ; + RooRealVar a1("a1","a1",-0.5,-1,1) ; + RooPolyVar fy("fy","fy",y,RooArgSet(a0,a1)) ; + + // Create gaussx(x,f(y),sx) + RooRealVar sigmax("sigma","width of gaussian",0.5) ; + RooGaussian gaussx("gaussx","Gaussian in x with shifting mean in y",x,fy,sigmax) ; + + + + // C r e a t e p d f g y ( y ) + // ----------------------------------------------------------- + + // Create gaussy(y,0,5) + RooGaussian gaussy("gaussy","Gaussian in y",y,RooConst(0),RooConst(3)) ; + + + + // C r e a t e p r o d u c t g x ( x | y ) * g y ( y ) + // ------------------------------------------------------- + + // Create gaussx(x,sx|y) * gaussy(y) + RooProdPdf model("model","gaussx(x|y)*gaussy(y)",gaussy,Conditional(gaussx,x)) ; + + + + // S a m p l e , f i t a n d p l o t p r o d u c t p d f + // --------------------------------------------------------------- + + // Generate 1000 events in x and y from model + RooDataSet *data = model.generate(RooArgSet(x,y),10000) ; + + // Plot x distribution of data and projection of model on x = Int(dy) model(x,y) + RooPlot* xframe = x.frame() ; + data->plotOn(xframe) ; + model.plotOn(xframe) ; + + // Plot x distribution of data and projection of model on y = Int(dx) model(x,y) + RooPlot* yframe = y.frame() ; + data->plotOn(yframe) ; + model.plotOn(yframe) ; + + // Make two-dimensional plot in x vs y + TH1* hh_model = model.createHistogram("hh_model",x,Binning(50),YVar(y,Binning(50))) ; + hh_model->SetLineColor(kBlue) ; + + + + // Make canvas and draw RooPlots + TCanvas *c = new TCanvas("rf305_condcorrprod","rf05_condcorrprod",1200, 400); + c->Divide(3); + c->cd(1) ; gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.6) ; xframe->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; yframe->GetYaxis()->SetTitleOffset(1.6) ; yframe->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.20) ; hh_model->GetZaxis()->SetTitleOffset(2.5) ; hh_model->Draw("surf") ; + +} + + + diff --git a/cpp/rf306_condpereventerrors.C b/cpp/rf306_condpereventerrors.C new file mode 100644 index 0000000..d016126 --- /dev/null +++ b/cpp/rf306_condpereventerrors.C @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #306 +// +// Complete example with use of conditional p.d.f. with per-event errors +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooGaussModel.h" +#include "RooDecay.h" +#include "RooLandau.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH2D.h" +using namespace RooFit ; + + + +void rf306_condpereventerrors() +{ + // B - p h y s i c s p d f w i t h p e r - e v e n t G a u s s i a n r e s o l u t i o n + // ---------------------------------------------------------------------------------------------- + + // Observables + RooRealVar dt("dt","dt",-10,10) ; + RooRealVar dterr("dterr","per-event error on dt",0.01,10) ; + + // Build a gaussian resolution model scaled by the per-event error = gauss(dt,bias,sigma*dterr) + RooRealVar bias("bias","bias",0,-10,10) ; + RooRealVar sigma("sigma","per-event error scale factor",1,0.1,10) ; + RooGaussModel gm("gm1","gauss model scaled bt per-event error",dt,bias,sigma,dterr) ; + + // Construct decay(dt) (x) gauss1(dt|dterr) + RooRealVar tau("tau","tau",1.548) ; + RooDecay decay_gm("decay_gm","decay",dt,tau,gm,RooDecay::DoubleSided) ; + + + + // C o n s t r u c t f a k e ' e x t e r n a l ' d a t a w i t h p e r - e v e n t e r r o r + // ------------------------------------------------------------------------------------------------------ + + // Use landau p.d.f to get somewhat realistic distribution with long tail + RooLandau pdfDtErr("pdfDtErr","pdfDtErr",dterr,RooConst(1),RooConst(0.25)) ; + RooDataSet* expDataDterr = pdfDtErr.generate(dterr,10000) ; + + + + // S a m p l e d a t a f r o m c o n d i t i o n a l d e c a y _ g m ( d t | d t e r r ) + // --------------------------------------------------------------------------------------------- + + // Specify external dataset with dterr values to use decay_dm as conditional p.d.f. + RooDataSet* data = decay_gm.generate(dt,ProtoData(*expDataDterr)) ; + + + + // F i t c o n d i t i o n a l d e c a y _ d m ( d t | d t e r r ) + // --------------------------------------------------------------------- + + // Specify dterr as conditional observable + decay_gm.fitTo(*data,ConditionalObservables(dterr)) ; + + + + // P l o t c o n d i t i o n a l d e c a y _ d m ( d t | d t e r r ) + // --------------------------------------------------------------------- + + + // Make two-dimensional plot of conditional p.d.f in (dt,dterr) + TH1* hh_decay = decay_gm.createHistogram("hh_decay",dt,Binning(50),YVar(dterr,Binning(50))) ; + hh_decay->SetLineColor(kBlue) ; + + + // Plot decay_gm(dt|dterr) at various values of dterr + RooPlot* frame = dt.frame(Title("Slices of decay(dt|dterr) at various dterr")) ; + for (Int_t ibin=0 ; ibin<100 ; ibin+=20) { + dterr.setBin(ibin) ; + decay_gm.plotOn(frame,Normalization(5.)) ; + } + + + // Make projection of data an dt + RooPlot* frame2 = dt.frame(Title("Projection of decay(dt|dterr) on dt")) ; + data->plotOn(frame2) ; + + // Make projection of decay(dt|dterr) on dt. + // + // Instead of integrating out dterr, make a weighted average of curves + // at values dterr_i as given in the external dataset. + // (The kTRUE argument bins the data before projection to speed up the process) + decay_gm.plotOn(frame2,ProjWData(*expDataDterr,kTRUE)) ; + + + + // Draw all frames on canvas + TCanvas* c = new TCanvas("rf306_condpereventerrors","rf306_condperventerrors",1200, 400); + c->Divide(3) ; + c->cd(1) ; gPad->SetLeftMargin(0.20) ; hh_decay->GetZaxis()->SetTitleOffset(2.5) ; hh_decay->Draw("surf") ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.6) ; frame2->Draw() ; + + +} + diff --git a/cpp/rf307_fullpereventerrors.C b/cpp/rf307_fullpereventerrors.C new file mode 100644 index 0000000..d3d68cc --- /dev/null +++ b/cpp/rf307_fullpereventerrors.C @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #307 +// +// Complete example with use of full p.d.f. with per-event errors +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooGaussModel.h" +#include "RooConstVar.h" +#include "RooDecay.h" +#include "RooLandau.h" +#include "RooProdPdf.h" +#include "RooHistPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf307_fullpereventerrors() +{ + // B - p h y s i c s p d f w i t h p e r - e v e n t G a u s s i a n r e s o l u t i o n + // ---------------------------------------------------------------------------------------------- + + // Observables + RooRealVar dt("dt","dt",-10,10) ; + RooRealVar dterr("dterr","per-event error on dt",0.01,10) ; + + // Build a gaussian resolution model scaled by the per-event error = gauss(dt,bias,sigma*dterr) + RooRealVar bias("bias","bias",0,-10,10) ; + RooRealVar sigma("sigma","per-event error scale factor",1,0.1,10) ; + RooGaussModel gm("gm1","gauss model scaled bt per-event error",dt,bias,sigma,dterr) ; + + // Construct decay(dt) (x) gauss1(dt|dterr) + RooRealVar tau("tau","tau",1.548) ; + RooDecay decay_gm("decay_gm","decay",dt,tau,gm,RooDecay::DoubleSided) ; + + + + // C o n s t r u c t e m p i r i c a l p d f f o r p e r - e v e n t e r r o r + // ----------------------------------------------------------------- + + // Use landau p.d.f to get empirical distribution with long tail + RooLandau pdfDtErr("pdfDtErr","pdfDtErr",dterr,RooConst(1),RooConst(0.25)) ; + RooDataSet* expDataDterr = pdfDtErr.generate(dterr,10000) ; + + // Construct a histogram pdf to describe the shape of the dtErr distribution + RooDataHist* expHistDterr = expDataDterr->binnedClone() ; + RooHistPdf pdfErr("pdfErr","pdfErr",dterr,*expHistDterr) ; + + + // C o n s t r u c t c o n d i t i o n a l p r o d u c t d e c a y _ d m ( d t | d t e r r ) * p d f ( d t e r r ) + // ---------------------------------------------------------------------------------------------------------------------- + + // Construct production of conditional decay_dm(dt|dterr) with empirical pdfErr(dterr) + RooProdPdf model("model","model",pdfErr,Conditional(decay_gm,dt)) ; + + // (Alternatively you could also use the landau shape pdfDtErr) + //RooProdPdf model("model","model",pdfDtErr,Conditional(decay_gm,dt)) ; + + + + // S a m p l e, f i t a n d p l o t p r o d u c t m o d e l + // ------------------------------------------------------------------ + + // Specify external dataset with dterr values to use model_dm as conditional p.d.f. + RooDataSet* data = model.generate(RooArgSet(dt,dterr),10000) ; + + + + // F i t c o n d i t i o n a l d e c a y _ d m ( d t | d t e r r ) + // --------------------------------------------------------------------- + + // Specify dterr as conditional observable + model.fitTo(*data) ; + + + + // P l o t c o n d i t i o n a l d e c a y _ d m ( d t | d t e r r ) + // --------------------------------------------------------------------- + + + // Make two-dimensional plot of conditional p.d.f in (dt,dterr) + TH1* hh_model = model.createHistogram("hh_model",dt,Binning(50),YVar(dterr,Binning(50))) ; + hh_model->SetLineColor(kBlue) ; + + + // Make projection of data an dt + RooPlot* frame = dt.frame(Title("Projection of model(dt|dterr) on dt")) ; + data->plotOn(frame) ; + model.plotOn(frame) ; + + + // Draw all frames on canvas + TCanvas* c = new TCanvas("rf307_fullpereventerrors","rf307_fullperventerrors",800, 400); + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.20) ; hh_model->GetZaxis()->SetTitleOffset(2.5) ; hh_model->Draw("surf") ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + + + +} diff --git a/cpp/rf308_normintegration2d.C b/cpp/rf308_normintegration2d.C new file mode 100644 index 0000000..34c6c53 --- /dev/null +++ b/cpp/rf308_normintegration2d.C @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #308 +// +// Examples on normalization of p.d.f.s, +// integration of p.d.fs, construction +// of cumulative distribution functions from p.d.f.s +// in two dimensions +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooProdPdf.h" +#include "RooAbsReal.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf308_normintegration2d() +{ + // S e t u p m o d e l + // --------------------- + + // Create observables x,y + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y",-10,10) ; + + // Create p.d.f. gaussx(x,-2,3), gaussy(y,2,2) + RooGaussian gx("gx","gx",x,RooConst(-2),RooConst(3)) ; + RooGaussian gy("gy","gy",y,RooConst(+2),RooConst(2)) ; + + // Create gxy = gx(x)*gy(y) + RooProdPdf gxy("gxy","gxy",RooArgSet(gx,gy)) ; + + + + // R e t r i e v e r a w & n o r m a l i z e d v a l u e s o f R o o F i t p . d . f . s + // -------------------------------------------------------------------------------------------------- + + // Return 'raw' unnormalized value of gx + cout << "gxy = " << gxy.getVal() << endl ; + + // Return value of gxy normalized over x _and_ y in range [-10,10] + RooArgSet nset_xy(x,y) ; + cout << "gx_Norm[x,y] = " << gxy.getVal(&nset_xy) << endl ; + + // Create object representing integral over gx + // which is used to calculate gx_Norm[x,y] == gx / gx_Int[x,y] + RooAbsReal* igxy = gxy.createIntegral(RooArgSet(x,y)) ; + cout << "gx_Int[x,y] = " << igxy->getVal() << endl ; + + // NB: it is also possible to do the following + + // Return value of gxy normalized over x in range [-10,10] (i.e. treating y as parameter) + RooArgSet nset_x(x) ; + cout << "gx_Norm[x] = " << gxy.getVal(&nset_x) << endl ; + + // Return value of gxy normalized over y in range [-10,10] (i.e. treating x as parameter) + RooArgSet nset_y(y) ; + cout << "gx_Norm[y] = " << gxy.getVal(&nset_y) << endl ; + + + + // I n t e g r a t e n o r m a l i z e d p d f o v e r s u b r a n g e + // ---------------------------------------------------------------------------- + + // Define a range named "signal" in x from -5,5 + x.setRange("signal",-5,5) ; + y.setRange("signal",-3,3) ; + + // Create an integral of gxy_Norm[x,y] over x and y in range "signal" + // This is the fraction of of p.d.f. gxy_Norm[x,y] which is in the + // range named "signal" + RooAbsReal* igxy_sig = gxy.createIntegral(RooArgSet(x,y),NormSet(RooArgSet(x,y)),Range("signal")) ; + cout << "gx_Int[x,y|signal]_Norm[x,y] = " << igxy_sig->getVal() << endl ; + + + + + // C o n s t r u c t c u m u l a t i v e d i s t r i b u t i o n f u n c t i o n f r o m p d f + // ----------------------------------------------------------------------------------------------------- + + // Create the cumulative distribution function of gx + // i.e. calculate Int[-10,x] gx(x') dx' + RooAbsReal* gxy_cdf = gxy.createCdf(RooArgSet(x,y)) ; + + // Plot cdf of gx versus x + TH1* hh_cdf = gxy_cdf->createHistogram("hh_cdf",x,Binning(40),YVar(y,Binning(40))) ; + hh_cdf->SetLineColor(kBlue) ; + + new TCanvas("rf308_normintegration2d","rf308_normintegration2d",600,600) ; + gPad->SetLeftMargin(0.15) ; hh_cdf->GetZaxis()->SetTitleOffset(1.8) ; + hh_cdf->Draw("surf") ; + +} diff --git a/cpp/rf309_ndimplot.C b/cpp/rf309_ndimplot.C new file mode 100644 index 0000000..6780989 --- /dev/null +++ b/cpp/rf309_ndimplot.C @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #308 +// +// Making 2/3 dimensional plots of p.d.f.s and datasets +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooConstVar.h" +#include "RooGaussian.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf309_ndimplot() +{ + + // C r e a t e 2 D m o d e l a n d d a t a s e t + // ----------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + + // Create parameters + RooRealVar a0("a0","a0",-3.5,-5,5) ; + RooRealVar a1("a1","a1",-1.5,-1,1) ; + RooRealVar sigma("sigma","width of gaussian",1.5) ; + + // Create interpreted function f(y) = a0 - a1*sqrt(10*abs(y)) + RooFormulaVar fy("fy","a0-a1*sqrt(10*abs(y))",RooArgSet(y,a0,a1)) ; + + // Create gauss(x,f(y),s) + RooGaussian model("model","Gaussian with shifting mean",x,fy,sigma) ; + + // Sample dataset from gauss(x,y) + RooDataSet* data = model.generate(RooArgSet(x,y),10000) ; + + + // M a k e 2 D p l o t s o f d a t a a n d m o d e l + // ------------------------------------------------------------- + + // Create and fill ROOT 2D histogram (20x20 bins) with contents of dataset + //TH2D* hh_data = data->createHistogram("hh_data",x,Binning(20),YVar(y,Binning(20))) ; + TH1* hh_data = data->createHistogram("x,y",20,20) ; + + // Create and fill ROOT 2D histogram (50x50 bins) with sampling of pdf + //TH2D* hh_pdf = model.createHistogram("hh_model",x,Binning(50),YVar(y,Binning(50))) ; + TH1* hh_pdf = model.createHistogram("x,y",50,50) ; + hh_pdf->SetLineColor(kBlue) ; + + + // C r e a t e 3 D m o d e l a n d d a t a s e t + // ----------------------------------------------------- + + // Create observables + RooRealVar z("z","z",-5,5) ; + + RooGaussian gz("gz","gz",z,RooConst(0),RooConst(2)) ; + RooProdPdf model3("model3","model3",RooArgSet(model,gz)) ; + + RooDataSet* data3 = model3.generate(RooArgSet(x,y,z),10000) ; + + + // M a k e 3 D p l o t s o f d a t a a n d m o d e l + // ------------------------------------------------------------- + + // Create and fill ROOT 2D histogram (8x8x8 bins) with contents of dataset + TH1* hh_data3 = data3->createHistogram("hh_data3",x,Binning(8),YVar(y,Binning(8)),ZVar(z,Binning(8))) ; + + // Create and fill ROOT 2D histogram (20x20x20 bins) with sampling of pdf + TH1* hh_pdf3 = model3.createHistogram("hh_model3",x,Binning(20),YVar(y,Binning(20)),ZVar(z,Binning(20))) ; + hh_pdf3->SetFillColor(kBlue) ; + + + + TCanvas* c1 = new TCanvas("rf309_2dimplot","rf309_2dimplot",800,800) ; + c1->Divide(2,2) ; + c1->cd(1) ; gPad->SetLeftMargin(0.15) ; hh_data->GetZaxis()->SetTitleOffset(1.4) ; hh_data->Draw("lego") ; + c1->cd(2) ; gPad->SetLeftMargin(0.20) ; hh_pdf->GetZaxis()->SetTitleOffset(2.5) ; hh_pdf->Draw("surf") ; + c1->cd(3) ; gPad->SetLeftMargin(0.15) ; hh_data->GetZaxis()->SetTitleOffset(1.4) ; hh_data->Draw("box") ; + c1->cd(4) ; gPad->SetLeftMargin(0.15) ; hh_pdf->GetZaxis()->SetTitleOffset(2.5) ; hh_pdf->Draw("cont3") ; + + TCanvas* c2 = new TCanvas("rf309_3dimplot","rf309_3dimplot",800,400) ; + c2->Divide(2) ; + c2->cd(1) ; gPad->SetLeftMargin(0.15) ; hh_data3->GetZaxis()->SetTitleOffset(1.4) ; hh_data3->Draw("lego") ; + c2->cd(2) ; gPad->SetLeftMargin(0.15) ; hh_pdf3->GetZaxis()->SetTitleOffset(1.4) ; hh_pdf3->Draw("iso") ; + +} diff --git a/cpp/rf310_sliceplot.C b/cpp/rf310_sliceplot.C new file mode 100644 index 0000000..f26772e --- /dev/null +++ b/cpp/rf310_sliceplot.C @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #309 +// +// Projecting p.d.f and data slices in discrete observables +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussModel.h" +#include "RooDecay.h" +#include "RooBMixDecay.h" +#include "RooCategory.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf310_sliceplot() +{ + + + // C r e a t e B d e c a y p d f w it h m i x i n g + // ---------------------------------------------------------- + + // Decay time observables + RooRealVar dt("dt","dt",-20,20) ; + + // Discrete observables mixState (B0tag==B0reco?) and tagFlav (B0tag==B0(bar)?) + RooCategory mixState("mixState","B0/B0bar mixing state") ; + RooCategory tagFlav("tagFlav","Flavour of the tagged B0") ; + + // Define state labels of discrete observables + mixState.defineType("mixed",-1) ; + mixState.defineType("unmixed",1) ; + tagFlav.defineType("B0",1) ; + tagFlav.defineType("B0bar",-1) ; + + // Model parameters + RooRealVar dm("dm","delta m(B)",0.472,0.,1.0) ; + RooRealVar tau("tau","B0 decay time",1.547,1.0,2.0) ; + RooRealVar w("w","Flavor Mistag rate",0.03,0.0,1.0) ; + RooRealVar dw("dw","Flavor Mistag rate difference between B0 and B0bar",0.01) ; + + // Build a gaussian resolution model + RooRealVar bias1("bias1","bias1",0) ; + RooRealVar sigma1("sigma1","sigma1",0.01) ; + RooGaussModel gm1("gm1","gauss model 1",dt,bias1,sigma1) ; + + // Construct a decay pdf, smeared with single gaussian resolution model + RooBMixDecay bmix_gm1("bmix","decay",dt,mixState,tagFlav,tau,dm,w,dw,gm1,RooBMixDecay::DoubleSided) ; + + // Generate BMixing data with above set of event errors + RooDataSet *data = bmix_gm1.generate(RooArgSet(dt,tagFlav,mixState),20000) ; + + + + // P l o t f u l l d e c a y d i s t r i b u t i o n + // ---------------------------------------------------------- + + // Create frame, plot data and pdf projection (integrated over tagFlav and mixState) + RooPlot* frame = dt.frame(Title("Inclusive decay distribution")) ; + data->plotOn(frame) ; + bmix_gm1.plotOn(frame) ; + + + + // P l o t d e c a y d i s t r . f o r m i x e d a n d u n m i x e d s l i c e o f m i x S t a t e + // ------------------------------------------------------------------------------------------------------------------ + + // Create frame, plot data (mixed only) + RooPlot* frame2 = dt.frame(Title("Decay distribution of mixed events")) ; + data->plotOn(frame2,Cut("mixState==mixState::mixed")) ; + + // Position slice in mixState at "mixed" and plot slice of pdf in mixstate over data (integrated over tagFlav) + bmix_gm1.plotOn(frame2,Slice(mixState,"mixed")) ; + + // Create frame, plot data (unmixed only) + RooPlot* frame3 = dt.frame(Title("Decay distribution of unmixed events")) ; + data->plotOn(frame3,Cut("mixState==mixState::unmixed")) ; + + // Position slice in mixState at "unmixed" and plot slice of pdf in mixstate over data (integrated over tagFlav) + bmix_gm1.plotOn(frame3,Slice(mixState,"unmixed")) ; + + + + TCanvas* c = new TCanvas("rf310_sliceplot","rf310_sliceplot",1200,400) ; + c->Divide(3) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; gPad->SetLogy() ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; gPad->SetLogy() ; frame2->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.4) ; gPad->SetLogy() ; frame3->Draw() ; + + +} diff --git a/cpp/rf311_rangeplot.C b/cpp/rf311_rangeplot.C new file mode 100644 index 0000000..d3225b8 --- /dev/null +++ b/cpp/rf311_rangeplot.C @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #310 +// +// Projecting p.d.f and data ranges in continuous observables +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooProdPdf.h" +#include "RooAddPdf.h" +#include "RooPolynomial.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf311_rangeplot() +{ + + // C r e a t e 3 D p d f a n d d a t a + // ------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + RooRealVar z("z","z",-5,5) ; + + // Create signal pdf gauss(x)*gauss(y)*gauss(z) + RooGaussian gx("gx","gx",x,RooConst(0),RooConst(1)) ; + RooGaussian gy("gy","gy",y,RooConst(0),RooConst(1)) ; + RooGaussian gz("gz","gz",z,RooConst(0),RooConst(1)) ; + RooProdPdf sig("sig","sig",RooArgSet(gx,gy,gz)) ; + + // Create background pdf poly(x)*poly(y)*poly(z) + RooPolynomial px("px","px",x,RooArgSet(RooConst(-0.1),RooConst(0.004))) ; + RooPolynomial py("py","py",y,RooArgSet(RooConst(0.1),RooConst(-0.004))) ; + RooPolynomial pz("pz","pz",z) ; + RooProdPdf bkg("bkg","bkg",RooArgSet(px,py,pz)) ; + + // Create composite pdf sig+bkg + RooRealVar fsig("fsig","signal fraction",0.1,0.,1.) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),fsig) ; + + RooDataSet* data = model.generate(RooArgSet(x,y,z),20000) ; + + + + // P r o j e c t p d f a n d d a t a o n x + // ------------------------------------------------- + + // Make plain projection of data and pdf on x observable + RooPlot* frame = x.frame(Title("Projection of 3D data and pdf on X"),Bins(40)) ; + data->plotOn(frame) ; + model.plotOn(frame) ; + + + + // P r o j e c t p d f a n d d a t a o n x i n s i g n a l r a n g e + // ---------------------------------------------------------------------------------- + + // Define signal region in y and z observables + y.setRange("sigRegion",-1,1) ; + z.setRange("sigRegion",-1,1) ; + + // Make plot frame + RooPlot* frame2 = x.frame(Title("Same projection on X in signal range of (Y,Z)"),Bins(40)) ; + + // Plot subset of data in which all observables are inside "sigRegion" + // For observables that do not have an explicit "sigRegion" range defined (e.g. observable) + // an implicit definition is used that is identical to the full range (i.e. [-5,5] for x) + data->plotOn(frame2,CutRange("sigRegion")) ; + + // Project model on x, integrating projected observables (y,z) only in "sigRegion" + model.plotOn(frame2,ProjectionRange("sigRegion")) ; + + + + TCanvas* c = new TCanvas("rf311_rangeplot","rf310_rangeplot",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + + +} diff --git a/cpp/rf312_multirangefit.C b/cpp/rf312_multirangefit.C new file mode 100644 index 0000000..a646abc --- /dev/null +++ b/cpp/rf312_multirangefit.C @@ -0,0 +1,120 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #312 +// +// Performing fits in multiple (disjoint) ranges in one or more dimensions +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooProdPdf.h" +#include "RooAddPdf.h" +#include "RooPolynomial.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooFitResult.h" +using namespace RooFit ; + + +void rf312_multirangefit() +{ + + // C r e a t e 2 D p d f a n d d a t a + // ------------------------------------------- + + // Define observables x,y + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y",-10,10) ; + + // Construct the signal pdf gauss(x)*gauss(y) + RooRealVar mx("mx","mx",1,-10,10) ; + RooRealVar my("my","my",1,-10,10) ; + + RooGaussian gx("gx","gx",x,mx,RooConst(1)) ; + RooGaussian gy("gy","gy",y,my,RooConst(1)) ; + + RooProdPdf sig("sig","sig",gx,gy) ; + + // Construct the background pdf (flat in x,y) + RooPolynomial px("px","px",x) ; + RooPolynomial py("py","py",y) ; + RooProdPdf bkg("bkg","bkg",px,py) ; + + // Construct the composite model sig+bkg + RooRealVar f("f","f",0.,1.) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),f) ; + + // Sample 10000 events in (x,y) from the model + RooDataSet* modelData = model.generate(RooArgSet(x,y),10000) ; + + + + // D e f i n e s i g n a l a n d s i d e b a n d r e g i o n s + // ------------------------------------------------------------------- + + // Construct the SideBand1,SideBand2,Signal regions + // + // | + // +-------------+-----------+ + // | | | + // | Side | Sig | + // | Band1 | nal | + // | | | + // --+-------------+-----------+-- + // | | + // | Side | + // | Band2 | + // | | + // +-------------+-----------+ + // | + + x.setRange("SB1",-10,+10) ; + y.setRange("SB1",-10,0) ; + + x.setRange("SB2",-10,0) ; + y.setRange("SB2",0,+10) ; + + x.setRange("SIG",0,+10) ; + y.setRange("SIG",0,+10) ; + + x.setRange("FULL",-10,+10) ; + y.setRange("FULL",-10,+10) ; + + + // P e r f o r m f i t s i n i n d i v i d u a l s i d e b a n d r e g i o n s + // ------------------------------------------------------------------------------------- + + // Perform fit in SideBand1 region (RooAddPdf coefficients will be interpreted in full range) + RooFitResult* r_sb1 = model.fitTo(*modelData,Range("SB1"),Save()) ; + + // Perform fit in SideBand2 region (RooAddPdf coefficients will be interpreted in full range) + RooFitResult* r_sb2 = model.fitTo(*modelData,Range("SB2"),Save()) ; + + + + // P e r f o r m f i t s i n j o i n t s i d e b a n d r e g i o n s + // ----------------------------------------------------------------------------- + + // Now perform fit to joint 'L-shaped' sideband region 'SB1|SB2' + // (RooAddPdf coefficients will be interpreted in full range) + RooFitResult* r_sb12 = model.fitTo(*modelData,Range("SB1,SB2"),Save()) ; + + + // Print results for comparison + r_sb1->Print() ; + r_sb2->Print() ; + r_sb12->Print() ; + + +} diff --git a/cpp/rf313_paramranges.C b/cpp/rf313_paramranges.C new file mode 100644 index 0000000..dab2fb1 --- /dev/null +++ b/cpp/rf313_paramranges.C @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #313 +// +// Working with parameterized ranges to define non-rectangular regions +// for fitting and integration +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf313_paramranges() +{ + + // C r e a t e 3 D p d f + // ------------------------- + + // Define observable (x,y,z) + RooRealVar x("x","x",0,10) ; + RooRealVar y("y","y",0,10) ; + RooRealVar z("z","z",0,10) ; + + // Define 3 dimensional pdf + RooRealVar z0("z0","z0",-0.1,1) ; + RooPolynomial px("px","px",x,RooConst(0)) ; + RooPolynomial py("py","py",y,RooConst(0)) ; + RooPolynomial pz("pz","pz",z,z0) ; + RooProdPdf pxyz("pxyz","pxyz",RooArgSet(px,py,pz)) ; + + + + // D e f i n e d n o n - r e c t a n g u l a r r e g i o n R i n ( x , y , z ) + // ------------------------------------------------------------------------------------- + + // + // R = Z[0 - 0.1*Y^2] * Y[0.1*X - 0.9*X] * X[0 - 10] + // + + // Construct range parameterized in "R" in y [ 0.1*x, 0.9*x ] + RooFormulaVar ylo("ylo","0.1*x",x) ; + RooFormulaVar yhi("yhi","0.9*x",x) ; + y.setRange("R",ylo,yhi) ; + + // Construct parameterized ranged "R" in z [ 0, 0.1*y^2 ] + RooFormulaVar zlo("zlo","0.0*y",y) ; + RooFormulaVar zhi("zhi","0.1*y*y",y) ; + z.setRange("R",zlo,zhi) ; + + + + // C a l c u l a t e i n t e g r a l o f n o r m a l i z e d p d f i n R + // ---------------------------------------------------------------------------------- + + // Create integral over normalized pdf model over x,y,z in "R" region + RooAbsReal* intPdf = pxyz.createIntegral(RooArgSet(x,y,z),RooArgSet(x,y,z),"R") ; + + // Plot value of integral as function of pdf parameter z0 + RooPlot* frame = z0.frame(Title("Integral of pxyz over x,y,z in region R")) ; + intPdf->plotOn(frame) ; + + + + new TCanvas("rf313_paramranges","rf313_paramranges",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + + return ; +} diff --git a/cpp/rf314_paramfitrange.C b/cpp/rf314_paramfitrange.C new file mode 100644 index 0000000..5e729ea --- /dev/null +++ b/cpp/rf314_paramfitrange.C @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #314 +// +// Working with parameterized ranges in a fit. This an example of a +// fit with an acceptance that changes per-event +// +// pdf = exp(-t/tau) with t[tmin,5] +// +// where t and tmin are both observables in the dataset +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooExponential.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooFitResult.h" + +using namespace RooFit ; + + +void rf314_paramfitrange() +{ + + // D e f i n e o b s e r v a b l e s a n d d e c a y p d f + // --------------------------------------------------------------- + + // Declare observables + RooRealVar t("t","t",0,5) ; + RooRealVar tmin("tmin","tmin",0,0,5) ; + + // Make parameterized range in t : [tmin,5] + t.setRange(tmin,RooConst(t.getMax())) ; + + // Make pdf + RooRealVar tau("tau","tau",-1.54,-10,-0.1) ; + RooExponential model("model","model",t,tau) ; + + + + // C r e a t e i n p u t d a t a + // ------------------------------------ + + // Generate complete dataset without acceptance cuts (for reference) + RooDataSet* dall = model.generate(t,10000) ; + + // Generate a (fake) prototype dataset for acceptance limit values + RooDataSet* tmp = RooGaussian("gmin","gmin",tmin,RooConst(0),RooConst(0.5)).generate(tmin,5000) ; + + // Generate dataset with t values that observe (t>tmin) + RooDataSet* dacc = model.generate(t,ProtoData(*tmp)) ; + + + + // F i t p d f t o d a t a i n a c c e p t a n c e r e g i o n + // ----------------------------------------------------------------------- + + RooFitResult* r = model.fitTo(*dacc,Save()) ; + + + + // P l o t f i t t e d p d f o n f u l l a n d a c c e p t e d d a t a + // --------------------------------------------------------------------------------- + + // Make plot frame, add datasets and overlay model + RooPlot* frame = t.frame(Title("Fit to data with per-event acceptance")) ; + dall->plotOn(frame,MarkerColor(kRed),LineColor(kRed)) ; + model.plotOn(frame) ; + dacc->plotOn(frame) ; + + // Print fit results to demonstrate absence of bias + r->Print("v") ; + + + new TCanvas("rf314_paramranges","rf314_paramranges",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + + return ; +} diff --git a/cpp/rf315_projectpdf.C b/cpp/rf315_projectpdf.C new file mode 100644 index 0000000..1f7b3fd --- /dev/null +++ b/cpp/rf315_projectpdf.C @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #315 +// +// Marginizalization of multi-dimensional p.d.f.s through integration +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooProdPdf.h" +#include "RooPolyVar.h" +#include "TH1.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooNumIntConfig.h" +#include "RooConstVar.h" +using namespace RooFit ; + + +void rf315_projectpdf() +{ + // C r e a t e p d f m ( x , y ) = g x ( x | y ) * g ( y ) + // -------------------------------------------------------------- + + // Increase default precision of numeric integration + // as this exercise has high sensitivity to numeric integration precision + RooAbsPdf::defaultIntegratorConfig()->setEpsRel(1e-8) ; + RooAbsPdf::defaultIntegratorConfig()->setEpsAbs(1e-8) ; + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-2,2) ; + + // Create function f(y) = a0 + a1*y + RooRealVar a0("a0","a0",0) ; + RooRealVar a1("a1","a1",-1.5,-3,1) ; + RooPolyVar fy("fy","fy",y,RooArgSet(a0,a1)) ; + + // Create gaussx(x,f(y),sx) + RooRealVar sigmax("sigmax","width of gaussian",0.5) ; + RooGaussian gaussx("gaussx","Gaussian in x with shifting mean in y",x,fy,sigmax) ; + + // Create gaussy(y,0,2) + RooGaussian gaussy("gaussy","Gaussian in y",y,RooConst(0),RooConst(2)) ; + + // Create gaussx(x,sx|y) * gaussy(y) + RooProdPdf model("model","gaussx(x|y)*gaussy(y)",gaussy,Conditional(gaussx,x)) ; + + + + // M a r g i n a l i z e m ( x , y ) t o m ( x ) + // ---------------------------------------------------- + + // modelx(x) = Int model(x,y) dy + RooAbsPdf* modelx = model.createProjection(y) ; + + + + // U s e m a r g i n a l i z e d p . d . f . a s r e g u l a r 1 - D p . d . f . + // ------------------------------------------------------------------------------------------ + + // Sample 1000 events from modelx + RooAbsData* data = modelx->generateBinned(x,1000) ; + + // Fit modelx to toy data + modelx->fitTo(*data,Verbose()) ; + + // Plot modelx over data + RooPlot* frame = x.frame(40) ; + data->plotOn(frame) ; + modelx->plotOn(frame) ; + + // Make 2D histogram of model(x,y) + TH1* hh = model.createHistogram("x,y") ; + hh->SetLineColor(kBlue) ; + + + TCanvas* c = new TCanvas("rf315_projectpdf","rf315_projectpdf",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.20) ; hh->GetZaxis()->SetTitleOffset(2.5) ; hh->Draw("surf") ; + +} diff --git a/cpp/rf316_llratioplot.C b/cpp/rf316_llratioplot.C new file mode 100644 index 0000000..eaf254a --- /dev/null +++ b/cpp/rf316_llratioplot.C @@ -0,0 +1,124 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'MULTIDIMENSIONAL MODELS' RooFit tutorial macro #316 +// +// Using the likelihood ratio techique to construct a signal enhanced +// one-dimensional projection of a multi-dimensional p.d.f. +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf316_llratioplot() +{ + + // C r e a t e 3 D p d f a n d d a t a + // ------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + RooRealVar z("z","z",-5,5) ; + + // Create signal pdf gauss(x)*gauss(y)*gauss(z) + RooGaussian gx("gx","gx",x,RooConst(0),RooConst(1)) ; + RooGaussian gy("gy","gy",y,RooConst(0),RooConst(1)) ; + RooGaussian gz("gz","gz",z,RooConst(0),RooConst(1)) ; + RooProdPdf sig("sig","sig",RooArgSet(gx,gy,gz)) ; + + // Create background pdf poly(x)*poly(y)*poly(z) + RooPolynomial px("px","px",x,RooArgSet(RooConst(-0.1),RooConst(0.004))) ; + RooPolynomial py("py","py",y,RooArgSet(RooConst(0.1),RooConst(-0.004))) ; + RooPolynomial pz("pz","pz",z) ; + RooProdPdf bkg("bkg","bkg",RooArgSet(px,py,pz)) ; + + // Create composite pdf sig+bkg + RooRealVar fsig("fsig","signal fraction",0.1,0.,1.) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),fsig) ; + + RooDataSet* data = model.generate(RooArgSet(x,y,z),20000) ; + + + + // P r o j e c t p d f a n d d a t a o n x + // ------------------------------------------------- + + // Make plain projection of data and pdf on x observable + RooPlot* frame = x.frame(Title("Projection of 3D data and pdf on X"),Bins(40)) ; + data->plotOn(frame) ; + model.plotOn(frame) ; + + + + // D e f i n e p r o j e c t e d s i g n a l l i k e l i h o o d r a t i o + // ---------------------------------------------------------------------------------- + + // Calculate projection of signal and total likelihood on (y,z) observables + // i.e. integrate signal and composite model over x + RooAbsPdf* sigyz = sig.createProjection(x) ; + RooAbsPdf* totyz = model.createProjection(x) ; + + // Construct the log of the signal / signal+background probability + RooFormulaVar llratio_func("llratio","log10(@0)-log10(@1)",RooArgList(*sigyz,*totyz)) ; + + + + // P l o t d a t a w i t h a L L r a t i o c u t + // ------------------------------------------------------- + + // Calculate the llratio value for each event in the dataset + data->addColumn(llratio_func) ; + + // Extract the subset of data with large signal likelihood + RooDataSet* dataSel = (RooDataSet*) data->reduce(Cut("llratio>0.7")) ; + + // Make plot frame + RooPlot* frame2 = x.frame(Title("Same projection on X with LLratio(y,z)>0.7"),Bins(40)) ; + + // Plot select data on frame + dataSel->plotOn(frame2) ; + + + + // M a k e M C p r o j e c t i o n o f p d f w i t h s a m e L L r a t i o c u t + // --------------------------------------------------------------------------------------------- + + // Generate large number of events for MC integration of pdf projection + RooDataSet* mcprojData = model.generate(RooArgSet(x,y,z),10000) ; + + // Calculate LL ratio for each generated event and select MC events with llratio)0.7 + mcprojData->addColumn(llratio_func) ; + RooDataSet* mcprojDataSel = (RooDataSet*) mcprojData->reduce(Cut("llratio>0.7")) ; + + // Project model on x, integrating projected observables (y,z) with Monte Carlo technique + // on set of events with the same llratio cut as was applied to data + model.plotOn(frame2,ProjWData(*mcprojDataSel)) ; + + + + TCanvas* c = new TCanvas("rf316_llratioplot","rf316_llratioplot",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + + + +} diff --git a/cpp/rf401_importttreethx.C b/cpp/rf401_importttreethx.C new file mode 100644 index 0000000..cfd7eaf --- /dev/null +++ b/cpp/rf401_importttreethx.C @@ -0,0 +1,164 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #401 +// +// Overview of advanced option for importing data from ROOT TTree and THx histograms +// Basic import options are demonstrated in rf102_dataimport.C +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooCategory.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TH1.h" +#include "TTree.h" +#include "TRandom.h" +#include + +using namespace RooFit ; + + + +TH1* makeTH1(const char* name, Double_t mean, Double_t sigma) ; +TTree* makeTTree() ; + + +void rf401_importttreethx() +{ + // I m p o r t m u l t i p l e T H 1 i n t o a R o o D a t a H i s t + // -------------------------------------------------------------------------- + + // Create thee ROOT TH1 histograms + TH1* hh_1 = makeTH1("hh1",0,3) ; + TH1* hh_2 = makeTH1("hh2",-3,1) ; + TH1* hh_3 = makeTH1("hh3",+3,4) ; + + // Declare observable x + RooRealVar x("x","x",-10,10) ; + + // Create category observable c that serves as index for the ROOT histograms + RooCategory c("c","c") ; + c.defineType("SampleA") ; + c.defineType("SampleB") ; + c.defineType("SampleC") ; + + // Create a binned dataset that imports contents of all TH1 mapped by index category c + RooDataHist* dh = new RooDataHist("dh","dh",x,Index(c),Import("SampleA",*hh_1),Import("SampleB",*hh_2),Import("SampleC",*hh_3)) ; + dh->Print() ; + + // Alternative constructor form for importing multiple histograms + map hmap ; + hmap["SampleA"] = hh_1 ; + hmap["SampleB"] = hh_2 ; + hmap["SampleC"] = hh_3 ; + RooDataHist* dh2 = new RooDataHist("dh","dh",x,c,hmap) ; + dh2->Print() ; + + + + // I m p o r t i n g a T T r e e i n t o a R o o D a t a S e t w i t h c u t s + // ----------------------------------------------------------------------------------------- + + TTree* tree = makeTTree() ; + + // Define observables y,z + RooRealVar y("y","y",-10,10) ; + RooRealVar z("z","z",-10,10) ; + + // Import only observables (y,z) + RooDataSet ds("ds","ds",RooArgSet(x,y),Import(*tree)) ; + ds.Print() ; + + // Import observables (x,y,z) but only event for which (y+z<0) is true + RooDataSet ds2("ds2","ds2",RooArgSet(x,y,z),Import(*tree),Cut("y+z<0")) ; + ds2.Print() ; + + + + // I m p o r t i n g i n t e g e r T T r e e b r a n c h e s + // --------------------------------------------------------------- + + // Import integer tree branch as RooRealVar + RooRealVar i("i","i",0,5) ; + RooDataSet ds3("ds3","ds3",RooArgSet(i,x),Import(*tree)) ; + ds3.Print() ; + + // Define category i + RooCategory icat("i","i") ; + icat.defineType("State0",0) ; + icat.defineType("State1",1) ; + + // Import integer tree branch as RooCategory (only events with i==0 and i==1 + // will be imported as those are the only defined states) + RooDataSet ds4("ds4","ds4",RooArgSet(icat,x),Import(*tree)) ; + ds4.Print() ; + + + + // I m p o r t m u l t i p l e R o o D a t a S e t s i n t o a R o o D a t a S e t + // ---------------------------------------------------------------------------------------- + + // Create three RooDataSets in (y,z) + RooDataSet* dsA = (RooDataSet*) ds2.reduce(RooArgSet(x,y),"z<-5") ; + RooDataSet* dsB = (RooDataSet*) ds2.reduce(RooArgSet(x,y),"abs(z)<5") ; + RooDataSet* dsC = (RooDataSet*) ds2.reduce(RooArgSet(x,y),"z>5") ; + + // Create a dataset that imports contents of all the above datasets mapped by index category c + RooDataSet* dsABC = new RooDataSet("dsABC","dsABC",RooArgSet(x,y),Index(c),Import("SampleA",*dsA),Import("SampleB",*dsB),Import("SampleC",*dsC)) ; + + dsABC->Print() ; + +} + + + +TH1* makeTH1(const char* name, Double_t mean, Double_t sigma) +{ + // Create ROOT TH1 filled with a Gaussian distribution + + TH1D* hh = new TH1D(name,name,100,-10,10) ; + for (int i=0 ; i<1000 ; i++) { + hh->Fill(gRandom->Gaus(mean,sigma)) ; + } + return hh ; +} + + + +TTree* makeTTree() +{ + // Create ROOT TTree filled with a Gaussian distribution in x and a uniform distribution in y + + TTree* tree = new TTree("tree","tree") ; + Double_t* px = new Double_t ; + Double_t* py = new Double_t ; + Double_t* pz = new Double_t ; + Int_t* pi = new Int_t ; + tree->Branch("x",px,"x/D") ; + tree->Branch("y",py,"y/D") ; + tree->Branch("z",pz,"z/D") ; + tree->Branch("i",pi,"i/I") ; + for (int i=0 ; i<100 ; i++) { + *px = gRandom->Gaus(0,3) ; + *py = gRandom->Uniform()*30 - 15 ; + *pz = gRandom->Gaus(0,5) ; + *pi = i % 3 ; + tree->Fill() ; + } + return tree ; +} + + + diff --git a/cpp/rf402_datahandling.C b/cpp/rf402_datahandling.C new file mode 100644 index 0000000..d3dc84b --- /dev/null +++ b/cpp/rf402_datahandling.C @@ -0,0 +1,180 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #402 +// +// Tools for manipulation of (un)binned datasets +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooCategory.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TFile.h" +using namespace RooFit ; + +// WVE Add reduction by range + + +void rf402_datahandling() +{ + + // Binned (RooDataHist) and unbinned datasets (RooDataSet) share + // many properties and inherit from a common abstract base class + // (RooAbsData), that provides an interface for all operations + // that can be performed regardless of the data format + + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y", 0, 40) ; + RooCategory c("c","c") ; + c.defineType("Plus",+1) ; + c.defineType("Minus",-1) ; + + + + // B a s i c O p e r a t i o n s o n u n b i n n e d d a t a s e t s + // -------------------------------------------------------------- + + // RooDataSet is an unbinned dataset (a collection of points in N-dimensional space) + RooDataSet d("d","d",RooArgSet(x,y,c)) ; + + // Unlike RooAbsArgs (RooAbsPdf,RooFormulaVar,....) datasets are not attached to + // the variables they are constructed from. Instead they are attached to an internal + // clone of the supplied set of arguments + + // Fill d with dummy values + Int_t i ; + for (i=0 ; i<1000 ; i++) { + x = i/50 - 10 ; + y = sqrt(1.0*i) ; + c.setLabel((i%2)?"Plus":"Minus") ; + + // We must explicitly refer to x,y,c here to pass the values because + // d is not linked to them (as explained above) + d.add(RooArgSet(x,y,c)) ; + } + d.Print("v") ; + cout << endl ; + + // The get() function returns a pointer to the internal copy of the RooArgSet(x,y,c) + // supplied in the constructor + const RooArgSet* row = d.get() ; + row->Print("v") ; + cout << endl ; + + // Get with an argument loads a specific data point in row and returns + // a pointer to row argset. get() always returns the same pointer, unless + // an invalid row number is specified. In that case a null ptr is returned + d.get(900)->Print("v") ; + cout << endl ; + + + + // R e d u c i n g , A p p e n d i n g a n d M e r g i n g + // ------------------------------------------------------------- + + // The reduce() function returns a new dataset which is a subset of the original + cout << endl << ">> d1 has only columns x,c" << endl ; + RooDataSet* d1 = (RooDataSet*) d.reduce(RooArgSet(x,c)) ; + d1->Print("v") ; + + cout << endl << ">> d2 has only column y" << endl ; + RooDataSet* d2 = (RooDataSet*) d.reduce(RooArgSet(y)) ; + d2->Print("v") ; + + cout << endl << ">> d3 has only the points with y>5.17" << endl ; + RooDataSet* d3 = (RooDataSet*) d.reduce("y>5.17") ; + d3->Print("v") ; + + cout << endl << ">> d4 has only columns x,c for data points with y>5.17" << endl ; + RooDataSet* d4 = (RooDataSet*) d.reduce(RooArgSet(x,c),"y>5.17") ; + d4->Print("v") ; + + // The merge() function adds two data set column-wise + cout << endl << ">> merge d2(y) with d1(x,c) to form d1(x,c,y)" << endl ; + d1->merge(d2) ; + d1->Print("v") ; + + // The append() function addes two datasets row-wise + cout << endl << ">> append data points of d3 to d1" << endl ; + d1->append(*d3) ; + d1->Print("v") ; + + + + // O p e r a t i o n s o n b i n n e d d a t a s e t s + // --------------------------------------------------------- + + // A binned dataset can be constructed empty, from an unbinned dataset, or + // from a ROOT native histogram (TH1,2,3) + + cout << ">> construct dh (binned) from d(unbinned) but only take the x and y dimensions," << endl + << ">> the category 'c' will be projected in the filling process" << endl ; + + // The binning of real variables (like x,y) is done using their fit range + // 'get/setRange()' and number of specified fit bins 'get/setBins()'. + // Category dimensions of binned datasets get one bin per defined category state + x.setBins(10) ; + y.setBins(10) ; + RooDataHist dh("dh","binned version of d",RooArgSet(x,y),d) ; + dh.Print("v") ; + + RooPlot* yframe = y.frame(Bins(10),Title("Operations on binned datasets")) ; + dh.plotOn(yframe) ; // plot projection of 2D binned data on y + + // Examine the statistics of a binned dataset + cout << ">> number of bins in dh : " << dh.numEntries() << endl ; + cout << ">> sum of weights in dh : " << dh.sum(kFALSE) << endl ; + cout << ">> integral over histogram: " << dh.sum(kTRUE) << endl ; // accounts for bin volume + + // Locate a bin from a set of coordinates and retrieve its properties + x = 0.3 ; y = 20.5 ; + cout << ">> retrieving the properties of the bin enclosing coordinate (x,y) = (0.3,20.5) " << endl ; + cout << " bin center:" << endl ; + dh.get(RooArgSet(x,y))->Print("v") ; // load bin center coordinates in internal buffer + cout << " weight = " << dh.weight() << endl ; // return weight of last loaded coordinates + + // Reduce the 2-dimensional binned dataset to a 1-dimensional binned dataset + // + // All reduce() methods are interfaced in RooAbsData. All reduction techniques + // demonstrated on unbinned datasets can be applied to binned datasets as well. + cout << ">> Creating 1-dimensional projection on y of dh for bins with x>0" << endl ; + RooDataHist* dh2 = (RooDataHist*) dh.reduce(y,"x>0") ; + dh2->Print("v") ; + + // Add dh2 to yframe and redraw + dh2->plotOn(yframe,LineColor(kRed),MarkerColor(kRed)) ; + + + + // S a v i n g a n d l o a d i n g f r o m f i l e + // ------------------------------------------------------- + + // Datasets can be persisted with ROOT I/O + cout << endl << ">> Persisting d via ROOT I/O" << endl ; + TFile f("rf402_datahandling.root","RECREATE") ; + d.Write() ; + f.ls() ; + + // To read back in future session: + // > TFile f("rf402_datahandling.root") ; + // > RooDataSet* d = (RooDataSet*) f.FindObject("d") ; + + + + new TCanvas("rf402_datahandling","rf402_datahandling",600,600) ; + gPad->SetLeftMargin(0.15) ; yframe->GetYaxis()->SetTitleOffset(1.4) ; yframe->Draw() ; + +} diff --git a/cpp/rf403_weightedevts.C b/cpp/rf403_weightedevts.C new file mode 100644 index 0000000..8d517c1 --- /dev/null +++ b/cpp/rf403_weightedevts.C @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #403 +// +// Using weights in unbinned datasets +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooFormulaVar.h" +#include "RooGenericPdf.h" +#include "RooPolynomial.h" +#include "RooChi2Var.h" +#include "RooMinuit.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooFitResult.h" +using namespace RooFit ; + + +void rf403_weightedevts() +{ + // C r e a t e o b s e r v a b l e a n d u n w e i g h t e d d a t a s e t + // ------------------------------------------------------------------------------- + + // Declare observable + RooRealVar x("x","x",-10,10) ; + x.setBins(40) ; + + // Construction a uniform pdf + RooPolynomial p0("px","px",x) ; + + // Sample 1000 events from pdf + RooDataSet* data = p0.generate(x,1000) ; + + + + // C a l c u l a t e w e i g h t a n d m a k e d a t a s e t w e i g h t e d + // ----------------------------------------------------------------------------------- + + // Construct formula to calculate (fake) weight for events + RooFormulaVar wFunc("w","event weight","(x*x+10)",x) ; + + // Add column with variable w to previously generated dataset + RooRealVar* w = (RooRealVar*) data->addColumn(wFunc) ; + + // Dataset d is now a dataset with two observable (x,w) with 1000 entries + data->Print() ; + + // Instruct dataset wdata in interpret w as event weight rather than as observable + RooDataSet wdata(data->GetName(),data->GetTitle(),data,*data->get(),0,w->GetName()) ; + + // Dataset d is now a dataset with one observable (x) with 1000 entries and a sum of weights of ~430K + wdata.Print() ; + + + + // U n b i n n e d M L f i t t o w e i g h t e d d a t a + // --------------------------------------------------------------- + + // Construction quadratic polynomial pdf for fitting + RooRealVar a0("a0","a0",1) ; + RooRealVar a1("a1","a1",0,-1,1) ; + RooRealVar a2("a2","a2",1,0,10) ; + RooPolynomial p2("p2","p2",x,RooArgList(a0,a1,a2),0) ; + + // Fit quadratic polynomial to weighted data + + // NOTE: A plain Maximum likelihood fit to weighted data does in general + // NOT result in correct error estimates, unless individual + // event weights represent Poisson statistics themselves. + // + // Fit with 'wrong' errors + RooFitResult* r_ml_wgt = p2.fitTo(wdata,Save()) ; + + // A first order correction to estimated parameter errors in an + // (unbinned) ML fit can be obtained by calculating the + // covariance matrix as + // + // V' = V C-1 V + // + // where V is the covariance matrix calculated from a fit + // to -logL = - sum [ w_i log f(x_i) ] and C is the covariance + // matrix calculated from -logL' = -sum [ w_i^2 log f(x_i) ] + // (i.e. the weights are applied squared) + // + // A fit in this mode can be performed as follows: + + RooFitResult* r_ml_wgt_corr = p2.fitTo(wdata,Save(),SumW2Error(kTRUE)) ; + + + + // P l o t w e i g h e d d a t a a n d f i t r e s u l t + // --------------------------------------------------------------- + + // Construct plot frame + RooPlot* frame = x.frame(Title("Unbinned ML fit, binned chi^2 fit to weighted data")) ; + + // Plot data using sum-of-weights-squared error rather than Poisson errors + wdata.plotOn(frame,DataError(RooAbsData::SumW2)) ; + + // Overlay result of 2nd order polynomial fit to weighted data + p2.plotOn(frame) ; + + + + // M L F i t o f p d f t o e q u i v a l e n t u n w e i g h t e d d a t a s e t + // ----------------------------------------------------------------------------------------- + + // Construct a pdf with the same shape as p0 after weighting + RooGenericPdf genPdf("genPdf","x*x+10",x) ; + + // Sample a dataset with the same number of events as data + RooDataSet* data2 = genPdf.generate(x,1000) ; + + // Sample a dataset with the same number of weights as data + RooDataSet* data3 = genPdf.generate(x,43000) ; + + // Fit the 2nd order polynomial to both unweighted datasets and save the results for comparison + RooFitResult* r_ml_unw10 = p2.fitTo(*data2,Save()) ; + RooFitResult* r_ml_unw43 = p2.fitTo(*data3,Save()) ; + + + // C h i 2 f i t o f p d f t o b i n n e d w e i g h t e d d a t a s e t + // ------------------------------------------------------------------------------------ + + // Construct binned clone of unbinned weighted dataset + RooDataHist* binnedData = wdata.binnedClone() ; + binnedData->Print("v") ; + + // Perform chi2 fit to binned weighted dataset using sum-of-weights errors + // + // NB: Within the usual approximations of a chi2 fit, a chi2 fit to weighted + // data using sum-of-weights-squared errors does give correct error + // estimates + RooChi2Var chi2("chi2","chi2",p2,*binnedData,DataError(RooAbsData::SumW2)) ; + RooMinuit m(chi2) ; + m.migrad() ; + m.hesse() ; + + // Plot chi^2 fit result on frame as well + RooFitResult* r_chi2_wgt = m.save() ; + p2.plotOn(frame,LineStyle(kDashed),LineColor(kRed)) ; + + + + // C o m p a r e f i t r e s u l t s o f c h i 2 , M L f i t s t o ( u n ) w e i g h t e d d a t a + // --------------------------------------------------------------------------------------------------------------- + + // Note that ML fit on 1Kevt of weighted data is closer to result of ML fit on 43Kevt of unweighted data + // than to 1Kevt of unweighted data, whereas the reference chi^2 fit with SumW2 error gives a result closer to + // that of an unbinned ML fit to 1Kevt of unweighted data. + + cout << "==> ML Fit results on 1K unweighted events" << endl ; + r_ml_unw10->Print() ; + cout << "==> ML Fit results on 43K unweighted events" << endl ; + r_ml_unw43->Print() ; + cout << "==> ML Fit results on 1K weighted events with a summed weight of 43K" << endl ; + r_ml_wgt->Print() ; + cout << "==> Corrected ML Fit results on 1K weighted events with a summed weight of 43K" << endl ; + r_ml_wgt_corr->Print() ; + cout << "==> Chi2 Fit results on 1K weighted events with a summed weight of 43K" << endl ; + r_chi2_wgt->Print() ; + + + new TCanvas("rf403_weightedevts","rf403_weightedevts",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.8) ; frame->Draw() ; + + +} diff --git a/cpp/rf404_categories.C b/cpp/rf404_categories.C new file mode 100644 index 0000000..f40a82d --- /dev/null +++ b/cpp/rf404_categories.C @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #404 +// +// Working with RooCategory objects to describe discrete variables +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooPolynomial.h" +#include "RooCategory.h" +#include "Roo1DTable.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf404_categories() +{ + + // C o n s t r u c t a c a t e g o r y w i t h l a b e l s + // ---------------------------------------------------------------- + + // Define a category with labels only + RooCategory tagCat("tagCat","Tagging category") ; + tagCat.defineType("Lepton") ; + tagCat.defineType("Kaon") ; + tagCat.defineType("NetTagger-1") ; + tagCat.defineType("NetTagger-2") ; + tagCat.Print() ; + + + + // C o n s t r u c t a c a t e g o r y w i t h l a b e l s a n d i n d e c e s + // ---------------------------------------------------------------------------------------- + + // Define a category with explicitly numbered states + RooCategory b0flav("b0flav","B0 flavour eigenstate") ; + b0flav.defineType("B0",-1) ; + b0flav.defineType("B0bar",1) ; + b0flav.Print() ; + + + + // G e n e r a t e d u m m y d a t a f o r t a b u l a t i o n d e m o + // ---------------------------------------------------------------------------- + + // Generate a dummy dataset + RooRealVar x("x","x",0,10) ; + RooDataSet *data = RooPolynomial("p","p",x).generate(RooArgSet(x,b0flav,tagCat),10000) ; + + + + // P r i n t t a b l e s o f c a t e g o r y c o n t e n t s o f d a t a s e t s + // ------------------------------------------------------------------------------------------ + + // Tables are equivalent of plots for categories + Roo1DTable* btable = data->table(b0flav) ; + btable->Print() ; + btable->Print("v") ; + + // Create table for subset of events matching cut expression + Roo1DTable* ttable = data->table(tagCat,"x>8.23") ; + ttable->Print() ; + ttable->Print("v") ; + + // Create table for all (tagCat x b0flav) state combinations + Roo1DTable* bttable = data->table(RooArgSet(tagCat,b0flav)) ; + bttable->Print("v") ; + + // Retrieve number of events from table + // Number can be non-integer if source dataset has weighed events + Double_t nb0 = btable->get("B0") ; + cout << "Number of events with B0 flavor is " << nb0 << endl ; + + // Retrieve fraction of events with "Lepton" tag + Double_t fracLep = ttable->getFrac("Lepton") ; + cout << "Fraction of events tagged with Lepton tag is " << fracLep << endl ; + + + + // D e f i n i n g r a n g e s f o r p l o t t i n g , f i t t i n g o n c a t e g o r i e s + // ------------------------------------------------------------------------------------------------------ + + // Define named range as comma separated list of labels + tagCat.setRange("good","Lepton,Kaon") ; + + // Or add state names one by one + tagCat.addToRange("soso","NetTagger-1") ; + tagCat.addToRange("soso","NetTagger-2") ; + + // Use category range in dataset reduction specification + RooDataSet* goodData = (RooDataSet*) data->reduce(CutRange("good")) ; + goodData->table(tagCat)->Print("v") ; + + +} diff --git a/cpp/rf405_realtocatfuncs.C b/cpp/rf405_realtocatfuncs.C new file mode 100644 index 0000000..81a7740 --- /dev/null +++ b/cpp/rf405_realtocatfuncs.C @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #405 +// +// Demonstration of real-->discrete mapping functions +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooCategory.h" +#include "RooThresholdCategory.h" +#include "RooBinningCategory.h" +#include "Roo1DTable.h" +#include "RooArgusBG.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf405_realtocatfuncs() +{ + + // D e f i n e p d f i n x , s a m p l e d a t a s e t i n x + // ------------------------------------------------------------------------ + + + // Define a dummy PDF in x + RooRealVar x("x","x",0,10) ; + RooArgusBG a("a","argus(x)",x,RooConst(10),RooConst(-1)) ; + + // Generate a dummy dataset + RooDataSet *data = a.generate(x,10000) ; + + + + // C r e a t e a t h r e s h o l d r e a l - > c a t f u n c t i o n + // -------------------------------------------------------------------------- + + // A RooThresholdCategory is a category function that maps regions in a real-valued + // input observable observables to state names. At construction time a 'default' + // state name must be specified to which all values of x are mapped that are not + // otherwise assigned + RooThresholdCategory xRegion("xRegion","region of x",x,"Background") ; + + // Specify thresholds and state assignments one-by-one. + // Each statement specifies that all values _below_ the given value + // (and above any lower specified threshold) are mapped to the + // category state with the given name + // + // Background | SideBand | Signal | SideBand | Background + // 4.23 5.23 8.23 9.23 + xRegion.addThreshold(4.23,"Background") ; + xRegion.addThreshold(5.23,"SideBand") ; + xRegion.addThreshold(8.23,"Signal") ; + xRegion.addThreshold(9.23,"SideBand") ; + + + + // U s e t h r e s h o l d f u n c t i o n t o p l o t d a t a r e g i o n s + // ------------------------------------------------------------------------------------- + + // Add values of threshold function to dataset so that it can be used as observable + data->addColumn(xRegion) ; + + // Make plot of data in x + RooPlot* xframe = x.frame(Title("Demo of threshold and binning mapping functions")) ; + data->plotOn(xframe) ; + + // Use calculated category to select sideband data + data->plotOn(xframe,Cut("xRegion==xRegion::SideBand"),MarkerColor(kRed),LineColor(kRed)) ; + + + + // C r e a t e a b i n n i n g r e a l - > c a t f u n c t i o n + // ---------------------------------------------------------------------- + + // A RooBinningCategory is a category function that maps bins of a (named) binning definition + // in a real-valued input observable observables to state names. The state names are automatically + // constructed from the variable name, the binning name and the bin number. If no binning name + // is specified the default binning is mapped + + x.setBins(10,"coarse") ; + RooBinningCategory xBins("xBins","coarse bins in x",x,"coarse") ; + + + + // U s e b i n n i n g f u n c t i o n f o r t a b u l a t i o n a n d p l o t t i n g + // ----------------------------------------------------------------------------------------------- + + // Print table of xBins state multiplicity. Note that xBins does not need to be an observable in data + // it can be a function of observables in data as well + Roo1DTable* xbtable = data->table(xBins) ; + xbtable->Print("v") ; + + // Add values of xBins function to dataset so that it can be used as observable + RooCategory* xb = (RooCategory*) data->addColumn(xBins) ; + + // Define range "alt" as including bins 1,3,5,7,9 + xb->setRange("alt","x_coarse_bin1,x_coarse_bin3,x_coarse_bin5,x_coarse_bin7,x_coarse_bin9") ; + + // Construct subset of data matching range "alt" but only for the first 5000 events and plot it on the frame + RooDataSet* dataSel = (RooDataSet*) data->reduce(CutRange("alt"),EventRange(0,5000)) ; + dataSel->plotOn(xframe,MarkerColor(kGreen),LineColor(kGreen)) ; + + + + new TCanvas("rf405_realtocatfuncs","rf405_realtocatfuncs",600,600) ; + xframe->SetMinimum(0.01) ; + gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + + +} diff --git a/cpp/rf406_cattocatfuncs.C b/cpp/rf406_cattocatfuncs.C new file mode 100644 index 0000000..ac58e1b --- /dev/null +++ b/cpp/rf406_cattocatfuncs.C @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #406 +// +// Demonstration of discrete-->discrete (invertable) functions +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooPolynomial.h" +#include "RooCategory.h" +#include "RooMappedCategory.h" +#include "RooMultiCategory.h" +#include "RooSuperCategory.h" +#include "Roo1DTable.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf406_cattocatfuncs() +{ + // C o n s t r u c t t w o c a t e g o r i e s + // ---------------------------------------------- + + // Define a category with labels only + RooCategory tagCat("tagCat","Tagging category") ; + tagCat.defineType("Lepton") ; + tagCat.defineType("Kaon") ; + tagCat.defineType("NetTagger-1") ; + tagCat.defineType("NetTagger-2") ; + tagCat.Print() ; + + // Define a category with explicitly numbered states + RooCategory b0flav("b0flav","B0 flavour eigenstate") ; + b0flav.defineType("B0",-1) ; + b0flav.defineType("B0bar",1) ; + b0flav.Print() ; + + // Construct a dummy dataset with random values of tagCat and b0flav + RooRealVar x("x","x",0,10) ; + RooPolynomial p("p","p",x) ; + RooDataSet* data = p.generate(RooArgSet(x,b0flav,tagCat),10000) ; + + + + // C r e a t e a c a t - > c a t m a p p i n g c a t e g o r y + // --------------------------------------------------------------------- + + // A RooMappedCategory is category->category mapping function based on string expression + // The constructor takes an input category an a default state name to which unassigned + // states are mapped + RooMappedCategory tcatType("tcatType","tagCat type",tagCat,"Cut based") ; + + // Enter fully specified state mappings + tcatType.map("Lepton","Cut based") ; + tcatType.map("Kaon","Cut based") ; + + // Enter a wilcard expression mapping + tcatType.map("NetTagger*","Neural Network") ; + + // Make a table of the mapped category state multiplicit in data + Roo1DTable* mtable = data->table(tcatType) ; + mtable->Print("v") ; + + + + // C r e a t e a c a t X c a t p r o d u c t c a t e g o r y + // ---------------------------------------------------------------------- + + // A SUPER-category is 'product' of _lvalue_ categories. The state names of a super + // category is a composite of the state labels of the input categories + RooSuperCategory b0Xtcat("b0Xtcat","b0flav X tagCat",RooArgSet(b0flav,tagCat)) ; + + // Make a table of the product category state multiplicity in data + Roo1DTable* stable = data->table(b0Xtcat) ; + stable->Print("v") ; + + // Since the super category is an lvalue, assignment is explicitly possible + b0Xtcat.setLabel("{B0bar;Lepton}") ; + + + + // A MULTI-category is a 'product' of any category (function). The state names of a super + // category is a composite of the state labels of the input categories + RooMultiCategory b0Xttype("b0Xttype","b0flav X tagType",RooArgSet(b0flav,tcatType)) ; + + // Make a table of the product category state multiplicity in data + Roo1DTable* xtable = data->table(b0Xttype) ; + xtable->Print("v") ; + + +} diff --git a/cpp/rf407_latextables.C b/cpp/rf407_latextables.C new file mode 100644 index 0000000..0bf5c49 --- /dev/null +++ b/cpp/rf407_latextables.C @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'DATA AND CATEGORIES' RooFit tutorial macro #407 +// +// Latex printing of lists and sets of RooArgSets +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooExponential.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf407_latextables() +{ + // S e t u p c o m p o s i t e p d f + // -------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg1("bkg1","Background 1",x,RooArgSet(a0,a1)) ; + + // Build expontential pdf + RooRealVar alpha("alpha","alpha",-1) ; + RooExponential bkg2("bkg2","Background 2",x,alpha) ; + + // Sum the background components into a composite background p.d.f. + RooRealVar bkg1frac("sig1frac","fraction of component 1 in background",0.2,0.,1.) ; + RooAddPdf bkg("bkg","Signal",RooArgList(bkg1,bkg2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + + // M a k e l i s t o f p a r a m e t e r s b e f o r e a n d a f t e r f i t + // ---------------------------------------------------------------------------------------- + + // Make list of model parameters + RooArgSet* params = model.getParameters(x) ; + + // Save snapshot of prefit parameters + RooArgSet* initParams = (RooArgSet*) params->snapshot() ; + + // Do fit to data, to obtain error estimates on parameters + RooDataSet* data = model.generate(x,1000) ; + model.fitTo(*data) ; + + + + // P r i n t l a t ex t a b l e o f p a r a m e t e r s o f p d f + // -------------------------------------------------------------------------- + + + // Print parameter list in LaTeX for (one column with names, one column with values) + params->printLatex() ; + + // Print parameter list in LaTeX for (names values|names values) + params->printLatex(Columns(2)) ; + + // Print two parameter lists side by side (name values initvalues) + params->printLatex(Sibling(*initParams)) ; + + // Print two parameter lists side by side (name values initvalues|name values initvalues) + params->printLatex(Sibling(*initParams),Columns(2)) ; + + // Write LaTex table to file + params->printLatex(Sibling(*initParams),OutputFile("rf407_latextables.tex")) ; + + +} + + diff --git a/cpp/rf501_simultaneouspdf.C b/cpp/rf501_simultaneouspdf.C new file mode 100644 index 0000000..76f52ac --- /dev/null +++ b/cpp/rf501_simultaneouspdf.C @@ -0,0 +1,146 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #501 +// +// Using simultaneous p.d.f.s to describe simultaneous fits to multiple +// datasets +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooSimultaneous.h" +#include "RooCategory.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf501_simultaneouspdf() +{ + // C r e a t e m o d e l f o r p h y s i c s s a m p l e + // ------------------------------------------------------------- + + // Create observables + RooRealVar x("x","x",-8,8) ; + + // Construct signal pdf + RooRealVar mean("mean","mean",0,-8,8) ; + RooRealVar sigma("sigma","sigma",0.3,0.1,10) ; + RooGaussian gx("gx","gx",x,mean,sigma) ; + + // Construct background pdf + RooRealVar a0("a0","a0",-0.1,-1,1) ; + RooRealVar a1("a1","a1",0.004,-1,1) ; + RooChebychev px("px","px",x,RooArgSet(a0,a1)) ; + + // Construct composite pdf + RooRealVar f("f","f",0.2,0.,1.) ; + RooAddPdf model("model","model",RooArgList(gx,px),f) ; + + + + // C r e a t e m o d e l f o r c o n t r o l s a m p l e + // -------------------------------------------------------------- + + // Construct signal pdf. + // NOTE that sigma is shared with the signal sample model + RooRealVar mean_ctl("mean_ctl","mean_ctl",-3,-8,8) ; + RooGaussian gx_ctl("gx_ctl","gx_ctl",x,mean_ctl,sigma) ; + + // Construct the background pdf + RooRealVar a0_ctl("a0_ctl","a0_ctl",-0.1,-1,1) ; + RooRealVar a1_ctl("a1_ctl","a1_ctl",0.5,-0.1,1) ; + RooChebychev px_ctl("px_ctl","px_ctl",x,RooArgSet(a0_ctl,a1_ctl)) ; + + // Construct the composite model + RooRealVar f_ctl("f_ctl","f_ctl",0.5,0.,1.) ; + RooAddPdf model_ctl("model_ctl","model_ctl",RooArgList(gx_ctl,px_ctl),f_ctl) ; + + + + // G e n e r a t e e v e n t s f o r b o t h s a m p l e s + // --------------------------------------------------------------- + + // Generate 1000 events in x and y from model + RooDataSet *data = model.generate(RooArgSet(x),100) ; + RooDataSet *data_ctl = model_ctl.generate(RooArgSet(x),2000) ; + + + + // C r e a t e i n d e x c a t e g o r y a n d j o i n s a m p l e s + // --------------------------------------------------------------------------- + + // Define category to distinguish physics and control samples events + RooCategory sample("sample","sample") ; + sample.defineType("physics") ; + sample.defineType("control") ; + + // Construct combined dataset in (x,sample) + RooDataSet combData("combData","combined data",x,Index(sample),Import("physics",*data),Import("control",*data_ctl)) ; + + + + // C o n s t r u c t a s i m u l t a n e o u s p d f i n ( x , s a m p l e ) + // ----------------------------------------------------------------------------------- + + // Construct a simultaneous pdf using category sample as index + RooSimultaneous simPdf("simPdf","simultaneous pdf",sample) ; + + // Associate model with the physics state and model_ctl with the control state + simPdf.addPdf(model,"physics") ; + simPdf.addPdf(model_ctl,"control") ; + + + + // P e r f o r m a s i m u l t a n e o u s f i t + // --------------------------------------------------- + + // Perform simultaneous fit of model to data and model_ctl to data_ctl + simPdf.fitTo(combData) ; + + + + // P l o t m o d e l s l i c e s o n d a t a s l i c e s + // ---------------------------------------------------------------- + + // Make a frame for the physics sample + RooPlot* frame1 = x.frame(Bins(30),Title("Physics sample")) ; + + // Plot all data tagged as physics sample + combData.plotOn(frame1,Cut("sample==sample::physics")) ; + + // Plot "physics" slice of simultaneous pdf. + // NBL You _must_ project the sample index category with data using ProjWData + // as a RooSimultaneous makes no prediction on the shape in the index category + // and can thus not be integrated + simPdf.plotOn(frame1,Slice(sample,"physics"),ProjWData(sample,combData)) ; + simPdf.plotOn(frame1,Slice(sample,"physics"),Components("px"),ProjWData(sample,combData),LineStyle(kDashed)) ; + + // The same plot for the control sample slice + RooPlot* frame2 = x.frame(Bins(30),Title("Control sample")) ; + combData.plotOn(frame2,Cut("sample==sample::control")) ; + simPdf.plotOn(frame2,Slice(sample,"control"),ProjWData(sample,combData)) ; + simPdf.plotOn(frame2,Slice(sample,"control"),Components("px_ctl"),ProjWData(sample,combData),LineStyle(kDashed)) ; + + + + TCanvas* c = new TCanvas("rf501_simultaneouspdf","rf403_simultaneouspdf",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() ; + + +} diff --git a/cpp/rf502_wspacewrite.C b/cpp/rf502_wspacewrite.C new file mode 100644 index 0000000..86dceb3 --- /dev/null +++ b/cpp/rf502_wspacewrite.C @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #502 +// +// Creating and writing a workspace +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TFile.h" +#include "TH1.h" +using namespace RooFit ; + + + +void rf502_wspacewrite() +{ + // C r e a t e m o d e l a n d d a t a s e t + // ----------------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5,0,10) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + // Generate a data sample of 1000 events in x from model + RooDataSet *data = model.generate(x,1000) ; + + + + // C r e a t e w o r k s p a c e , i m p o r t d a t a a n d m o d e l + // ----------------------------------------------------------------------------- + + // Create a new empty workspace + RooWorkspace *w = new RooWorkspace("w","workspace") ; + + // Import model and all its components into the workspace + w->import(model) ; + + // Import data into the workspace + w->import(*data) ; + + // Print workspace contents + w->Print() ; + + + + // S a v e w o r k s p a c e i n f i l e + // ------------------------------------------- + + // Save the workspace into a ROOT file + w->writeToFile("rf502_workspace.root") ; + + + // Workspace will remain in memory after macro finishes + gDirectory->Add(w) ; + +} diff --git a/cpp/rf503_wspaceread.C b/cpp/rf503_wspaceread.C new file mode 100644 index 0000000..bfbd609 --- /dev/null +++ b/cpp/rf503_wspaceread.C @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #503 +// +// Reading and using a workspace +// +// --> The input file for this macro is generated by rf502_wspaceread.C +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TFile.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf503_wspaceread() +{ + // R e a d w o r k s p a c e f r o m f i l e + // ----------------------------------------------- + + // Open input file with workspace (generated by rf14_wspacewrite) + TFile *f = new TFile("rf502_workspace.root") ; + + // Retrieve workspace from file + RooWorkspace* w = (RooWorkspace*) f->Get("w") ; + + + + // R e t r i e v e p d f , d a t a f r o m w o r k s p a c e + // ----------------------------------------------------------------- + + // Retrieve x,model and data from workspace + RooRealVar* x = w->var("x") ; + RooAbsPdf* model = w->pdf("model") ; + RooAbsData* data = w->data("modelData") ; + + // Print structure of composite p.d.f. + model->Print("t") ; + + + // F i t m o d e l t o d a t a , p l o t m o d e l + // --------------------------------------------------------- + + // Fit model to data + model->fitTo(*data) ; + + // Plot data and PDF overlaid + RooPlot* xframe = x->frame(Title("Model and data read from workspace")) ; + data->plotOn(xframe) ; + model->plotOn(xframe) ; + + // Overlay the background component of model with a dashed line + model->plotOn(xframe,Components("bkg"),LineStyle(kDashed)) ; + + // Overlay the background+sig2 components of model with a dotted line + model->plotOn(xframe,Components("bkg,sig2"),LineStyle(kDotted)) ; + + + + // Draw the frame on the canvas + new TCanvas("rf503_wspaceread","rf503_wspaceread",600,600) ; + gPad->SetLeftMargin(0.15) ; xframe->GetYaxis()->SetTitleOffset(1.4) ; xframe->Draw() ; + + +} diff --git a/cpp/rf504_simwstool.C b/cpp/rf504_simwstool.C new file mode 100644 index 0000000..c03657f --- /dev/null +++ b/cpp/rf504_simwstool.C @@ -0,0 +1,114 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #504 +// +// Using RooSimWSTool to construct a simultaneous p.d.f that is built +// of variations of an input p.d.f +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooCategory.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooSimultaneous.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooSimWSTool.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TFile.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf504_simwstool() +{ + // C r e a t e m a s t e r p d f + // --------------------------------- + + // Construct gauss(x,m,s) + RooRealVar x("x","x",-10,10) ; + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",1,-10,10) ; + RooGaussian gauss("g","g",x,m,s) ; + + // Construct poly(x,p0) + RooRealVar p0("p0","p0",0.01,0.,1.) ; + RooPolynomial poly("p","p",x,p0) ; + + // Construct model = f*gauss(x) + (1-f)*poly(x) + RooRealVar f("f","f",0.5,0.,1.) ; + RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ; + + + + // C r e a t e c a t e g o r y o b s e r v a b l e s f o r s p l i t t i n g + // ---------------------------------------------------------------------------------- + + // Define two categories that can be used for splitting + RooCategory c("c","c") ; + c.defineType("run1") ; + c.defineType("run2") ; + + RooCategory d("d","d") ; + d.defineType("foo") ; + d.defineType("bar") ; + + + + // S e t u p S i m W S T o o l + // ----------------------------- + + // Import ingredients in a workspace + RooWorkspace w("w","w") ; + w.import(RooArgSet(model,c,d)) ; + + // Make Sim builder tool + RooSimWSTool sct(w) ; + + + // B u i l d a s i m u l t a n e o u s m o d e l w i t h o n e s p l i t + // --------------------------------------------------------------------------------- + + // Construct a simultaneous p.d.f with the following form + // + // model_run1(x) = f*gauss_run1(x,m_run1,s) + (1-f)*poly + // model_run2(x) = f*gauss_run2(x,m_run2,s) + (1-f)*poly + // simpdf(x,c) = model_run1(x) if c=="run1" + // = model_run2(x) if c=="run2" + // + // Returned p.d.f is owned by the workspace + RooSimultaneous* model_sim = sct.build("model_sim","model",SplitParam("m","c")) ; + + // Print tree structure of model + model_sim->Print("t") ; + + // Adjust model_sim parameters in workspace + w.var("m_run1")->setVal(-3) ; + w.var("m_run2")->setVal(+3) ; + + // Print contents of workspace + w.Print("v") ; + + + + // B u i l d a s i m u l t a n e o u s m o d e l w i t h p r o d u c t s p l i t + // ----------------------------------------------------------------------------------------- + + // Build another simultaneous p.d.f using a composite split in states c X d + RooSimultaneous* model_sim2 = sct.build("model_sim2","model",SplitParam("p0","c,d")) ; + + // Print tree structure of this model + model_sim2->Print("t") ; + +} diff --git a/cpp/rf505_asciicfg.C b/cpp/rf505_asciicfg.C new file mode 100644 index 0000000..0612e89 --- /dev/null +++ b/cpp/rf505_asciicfg.C @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #505 +// +// Reading and writing ASCII configuration files +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf505_asciicfg() +{ + // C r e a t e p d f + // ------------------ + + // Construct gauss(x,m,s) + RooRealVar x("x","x",-10,10) ; + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",1,-10,10) ; + RooGaussian gauss("g","g",x,m,s) ; + + // Construct poly(x,p0) + RooRealVar p0("p0","p0",0.01,0.,1.) ; + RooPolynomial poly("p","p",x,p0) ; + + // Construct model = f*gauss(x) + (1-f)*poly(x) + RooRealVar f("f","f",0.5,0.,1.) ; + RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ; + + + + // F i t m o d e l t o t o y d a t a + // ----------------------------------------- + + RooDataSet* d = model.generate(x,1000) ; + model.fitTo(*d) ; + + + // W r i t e p a r a m e t e r s t o a s c i i f i l e + // ----------------------------------------------------------- + + // Obtain set of parameters + RooArgSet* params = model.getParameters(x) ; + + // Write parameters to file + params->writeToFile("rf505_asciicfg_example.txt") ; + + + + // R e a d p a r a m e t e r s f r o m a s c i i f i l e + // ---------------------------------------------------------------- + + // Read parameters from file + params->readFromFile("rf505_asciicfg_example.txt") ; + params->Print("v") ; + + // Read parameters from section 'Section2' of file + params->readFromFile("rf505_asciicfg.txt",0,"Section2") ; + params->Print("v") ; + + // Read parameters from section 'Section3' of file. Mark all + // variables that were processed with the "READ" attribute + params->readFromFile("rf505_asciicfg.txt","READ","Section3") ; + + // Print the list of parameters that were not read from Section3 + cout << "The following parameters of the were _not_ read from Section3: " + << (*params->selectByAttrib("READ",kFALSE)) << endl ; + + + // Read parameters from section 'Section4' of file, which contains + // 'include file' statement of rf505_asciicfg_example.txt + // so that we effective read the same + params->readFromFile("rf505_asciicfg.txt",0,"Section4") ; + params->Print("v") ; + + + +} diff --git a/cpp/rf505_asciicfg.txt b/cpp/rf505_asciicfg.txt new file mode 100644 index 0000000..455cdef --- /dev/null +++ b/cpp/rf505_asciicfg.txt @@ -0,0 +1,25 @@ +[Section1] +# Comments lines start with a hash +f = 0.52727 +/- 0.021516 L(0 - 1) +m = 0.033901 +/- 0.054520 L(-10 - 10) +p0 = 0.0069868 +/- 0.0082025 L(0 - 1) +s = 0.99523 +/- 0.053043 L(-10 - 10) + +[Section2] +# Here we provide different values for the same parameters +f = 0.45 +/- 0.03 L(0 - 1) +m = 0.025 +/- 0.02 L(-10 - 10) +p0 = 0.0022 +/- 0.0001 L(0 - 1) +s = 0.98 +/- 0.03 L(-10 - 10) + +[Section3] +# It is also OK to supply a partial list +# Here we declare f and m as constant as well +f = 0.372 C +m = 0.195 C + +[Section 4] +# You can include other files as well +include rf505_asciicfg_example.txt + + diff --git a/cpp/rf506_msgservice.C b/cpp/rf506_msgservice.C new file mode 100644 index 0000000..54d226a --- /dev/null +++ b/cpp/rf506_msgservice.C @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #506 +// +// Tuning and customizing the RooFit message logging facility +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooMsgService.h" + +using namespace RooFit ; + + +void rf506_msgservice() +{ + // C r e a t e p d f + // -------------------- + + // Construct gauss(x,m,s) + RooRealVar x("x","x",-10,10) ; + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",1,-10,10) ; + RooGaussian gauss("g","g",x,m,s) ; + + // Construct poly(x,p0) + RooRealVar p0("p0","p0",0.01,0.,1.) ; + RooPolynomial poly("p","p",x,p0) ; + + // Construct model = f*gauss(x) + (1-f)*poly(x) + RooRealVar f("f","f",0.5,0.,1.) ; + RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ; + + RooDataSet* data = model.generate(x,10) ; + + + + // P r i n t c o n f i g u r a t i o n o f m e s s a g e s e r v i c e + // --------------------------------------------------------------------------- + + // Print streams configuration + RooMsgService::instance().Print() ; + cout << endl ; + + + + // A d d i n g I n t e g r a t i o n t o p i c t o e x i s t i n g I N F O s t r e a m + // ----------------------------------------------------------------------------------------------- + + // Print streams configuration + RooMsgService::instance().Print() ; + cout << endl ; + + // Add Integration topic to existing INFO stream + RooMsgService::instance().getStream(1).addTopic(Integration) ; + + // Construct integral over gauss to demonstrate new message stream + RooAbsReal* igauss = gauss.createIntegral(x) ; + igauss->Print() ; + + // Print streams configuration in verbose, which also shows inactive streams + cout << endl ; + RooMsgService::instance().Print() ; + cout << endl ; + + // Remove stream + RooMsgService::instance().getStream(1).removeTopic(Integration) ; + + + + // E x a m p l e s o f p d f v a l u e t r a c i n g s t r e a m + // ----------------------------------------------------------------------- + + // Show DEBUG level message on function tracing, trace RooGaussian only + RooMsgService::instance().addStream(DEBUG,Topic(Tracing),ClassName("RooGaussian")) ; + + // Perform a fit to generate some tracing messages + model.fitTo(*data,Verbose(kTRUE)) ; + + // Reset message service to default stream configuration + RooMsgService::instance().reset() ; + + + + // Show DEBUG level message on function tracing on all objects, redirect output to file + RooMsgService::instance().addStream(DEBUG,Topic(Tracing),OutputFile("rf506_debug.log")) ; + + // Perform a fit to generate some tracing messages + model.fitTo(*data,Verbose(kTRUE)) ; + + // Reset message service to default stream configuration + RooMsgService::instance().reset() ; + + + + // E x a m p l e o f a n o t h e r d e b u g g i n g s t r e a m + // --------------------------------------------------------------------- + + // Show DEBUG level messages on client/server link state management + RooMsgService::instance().addStream(DEBUG,Topic(LinkStateMgmt)) ; + RooMsgService::instance().Print("v") ; + + // Clone composite pdf g to trigger some link state management activity + RooAbsArg* gprime = gauss.cloneTree() ; + gprime->Print() ; + + // Reset message service to default stream configuration + RooMsgService::instance().reset() ; + + + +} diff --git a/cpp/rf507_debugtools.C b/cpp/rf507_debugtools.C new file mode 100644 index 0000000..5bad673 --- /dev/null +++ b/cpp/rf507_debugtools.C @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #507 +// +// RooFit memory tracing debug tool +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooTrace.h" +using namespace RooFit ; + + +void rf507_debugtools() +{ + // Activate RooFit memory tracing + RooTrace::active(kTRUE) ; + + // Construct gauss(x,m,s) + RooRealVar x("x","x",-10,10) ; + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",1,-10,10) ; + RooGaussian gauss("g","g",x,m,s) ; + + // Show dump of all RooFit object in memory + RooTrace::dump() ; + + // Activate verbose mode + RooTrace::verbose(kTRUE) ; + + // Construct poly(x,p0) + RooRealVar p0("p0","p0",0.01,0.,1.) ; + RooPolynomial poly("p","p",x,p0) ; + + // Put marker in trace list for future reference + RooTrace::mark() ; + + // Construct model = f*gauss(x) + (1-f)*poly(x) + RooRealVar f("f","f",0.5,0.,1.) ; + RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ; + + // Show object added to memory since marker + RooTrace::printObjectCounts() ; + + // Since verbose mode is still on, you will see messages + // pertaining to destructor calls of all RooFit objects + // made in this macro + // + // A call to RooTrace::dump() at the end of this macro + // should show that there a no RooFit object left in memory +} diff --git a/cpp/rf508_listsetmanip.C b/cpp/rf508_listsetmanip.C new file mode 100644 index 0000000..91ced63 --- /dev/null +++ b/cpp/rf508_listsetmanip.C @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #508 +// +// RooArgSet and RooArgList tools and tricks +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooArgSet.h" +#include "RooArgList.h" +#include "RooCategory.h" +using namespace RooFit ; + + +void rf508_listsetmanip() +{ + + // C r e a t e d u m m y o b j e c t s + // --------------------------------------- + + // Create some variables + RooRealVar a("a","a",1,-10,10) ; + RooRealVar b("b","b",2,-10,10) ; + RooRealVar c("c","c",3,-10,10) ; + RooRealVar d("d","d",4,-10,10) ; + RooRealVar x("x","x",0,-10,10) ; + c.setError(0.5) ; + a.setConstant() ; + b.setConstant() ; + + // Create a category + RooCategory e("e","e") ; + e.defineType("sig") ; + e.defineType("bkg") ; + + // Create a pdf + RooGaussian g("g","g",x,a,b) ; + + + + // C r e a t i n g , f i l l i n g R o o A r g S e t s + // ------------------------------------------------------- + + // A RooArgSet is a set of RooAbsArg objects. Each object in the set must have + // a unique name + + // Set constructors exists with up to 9 initial arguments + RooArgSet s(a,b) ; + + // At any time objects can be added with add() + s.add(e) ; + + // Add up to 9 additional arguments in one call + s.add(RooArgSet(c,d)) ; + + // Sets can contain any type of RooAbsArg, also pdf and functions + s.add(g) ; + + // Remove element d + s.remove(d) ; + + + + // A c c e s s i n g R o o A r g S e t c o n t e n t s + // ------------------------------------------------------- + + // You can look up objects by name + RooAbsArg* aptr = s.find("a") ; + + // Construct a subset by name + RooArgSet* subset1 = (RooArgSet*) s.selectByName("a,b,c") ; + + // Construct asubset by attribute + RooArgSet* subset2 = (RooArgSet*) s.selectByAttrib("Constant",kTRUE) ; + + // Construct the subset of overlapping contents with another set + RooArgSet s1(a,b,c) ; + RooArgSet s2(c,d,e) ; + RooArgSet* subset3 = (RooArgSet*) s1.selectCommon(s2) ; + + + + // O w n i n g R o o A r g S e t s + // --------------------------------- + + // Create a RooArgSet that owns its components + // A set either owns all of its components or none, + // so once addOwned() is used, add() can no longer be + // used and will result in an error message + + RooRealVar* ac = (RooRealVar*) a.clone("a") ; + RooRealVar* bc = (RooRealVar*) b.clone("b") ; + RooRealVar* cc = (RooRealVar*) c.clone("c") ; + + RooArgSet s3 ; + s3.addOwned(RooArgSet(*ac,*bc,*cc)) ; + + // Another possibility is to add an owned clone + // of an object instead of the original + s3.addClone(RooArgSet(d,e,g)) ; + + // A clone of a owning set is non-owning and its + // contents is owned by the originating owning set + RooArgSet* sclone = (RooArgSet*) s3.Clone("sclone") ; + + // To make a clone of a set and its contents use + // the snapshot method + RooArgSet* sclone2 = (RooArgSet*) s3.snapshot() ; + + // If a set contains function objects, only the head node + // is cloned in a snapshot. To make a snapshot of all + // servers of a function object do as follows. The result + // of a RooArgSet snapshot with deepCloning option is a set + // of cloned objects, and all their clone (recursive) server + // dependencies, that together form a self-consistent + // set that is free of external dependencies + + RooArgSet* sclone3 = (RooArgSet*) s3.snapshot(kTRUE) ; + + + + // S e t p r i n t i n g + // ------------------------ + + // Inline printing only show list of names of contained objects + cout << "sclone = " << (*sclone) << endl ; + + // Plain print shows the same, prefixed by name of the set + sclone->Print() ; + + // Standard printing shows one line for each item with the items name, class name and value + sclone->Print("s") ; + + // Verbose printing adds each items arguments, address and 'extras' as defined by the object + sclone->Print("v") ; + + + + // U s i n g R o o A r g L i s t s + // --------------------------------- + + // List constructors exists with up to 9 initial arguments + RooArgList l(a,b,c,d) ; + + // Lists have an explicit order and allow multiple arguments with the same name + l.add(RooArgList(a,b,c,d)) ; + + // Access by index is provided + RooAbsArg* arg4 = l.at(4) ; + + +} diff --git a/cpp/rf509_wsinteractive.C b/cpp/rf509_wsinteractive.C new file mode 100644 index 0000000..826bc99 --- /dev/null +++ b/cpp/rf509_wsinteractive.C @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #509 +// +// Easy CINT interactive access to workspace contents through a +// 'C++' namespace in CINT that maps the workspace contents in a typesafe way +// +// ********************************************************************************* +// *** NB: This macro exploits a feature native to CINT and _cannot_ be compiled *** +// ********************************************************************************* +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TFile.h" +#include "TH1.h" +using namespace RooFit ; + + +void fillWorkspace(RooWorkspace& w) ; + +void rf509_wsinteractive() +{ + // C r e a t e a n d f i l l w o r k s p a c e + // ------------------------------------------------ + + // Create a workspace named 'w' + // With CINT w could exports its contents to + // a same-name C++ namespace in CINT 'namespace w'. + // but this does not work anymore in CLING. + // so this tutorial is an example on how to + // change the code + RooWorkspace* w = new RooWorkspace("w",kTRUE) ; + + // Fill workspace with p.d.f. and data in a separate function + fillWorkspace(*w) ; + + // Print workspace contents + w->Print() ; + + // this does not work anymore with CLING + // use normal workspace functionality + + + // U s e w o r k s p a c e c o n t e n t s + // ---------------------------------------------- + + + // Old syntax to use the name space prefix operator to access the workspace contents + // + //RooDataSet* d = w::model.generate(w::x,1000) ; + //RooFitResult* r = w::model.fitTo(*d) ; + + // use normal workspace methods + RooAbsPdf * model = w->pdf("model"); + RooRealVar * x = w->var("x"); + + RooDataSet* d = model->generate(*x,1000) ; + RooFitResult* r = model->fitTo(*d) ; + + // old syntax to access the variable x + // RooPlot* frame = w::x.frame() ; + + RooPlot* frame = x->frame() ; + d->plotOn(frame) ; + + // OLD syntax to ommit x:: + // NB: The 'w::' prefix can be omitted if namespace w is imported in local namespace + // in the usual C++ way + // + // using namespace w; + // model.plotOn(frame) ; + // model.plotOn(frame,Components(bkg),LineStyle(kDashed)) ; + + // new correct syntax + RooAbsPdf *bkg = w->pdf("bkg"); + model->plotOn(frame); + model->plotOn(frame,Components(*bkg),LineStyle(kDashed)) ; + + // Draw the frame on the canvas + new TCanvas("rf509_wsinteractive","rf509_wsinteractive",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + + +} + + + + +void fillWorkspace(RooWorkspace& w) +{ + // C r e a t e p d f a n d f i l l w o r k s p a c e + // -------------------------------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5,0,10) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + w.import(model) ; + +} diff --git a/cpp/rf510_wsnamedsets.C b/cpp/rf510_wsnamedsets.C new file mode 100644 index 0000000..2379981 --- /dev/null +++ b/cpp/rf510_wsnamedsets.C @@ -0,0 +1,159 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #510 +// +// Working with named parameter sets and parameter snapshots in +// workspaces +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TFile.h" +#include "TH1.h" +using namespace RooFit ; + + +void fillWorkspace(RooWorkspace& w) ; + +void rf510_wsnamedsets() +{ + // C r e a t e m o d e l a n d d a t a s e t + // ----------------------------------------------- + + RooWorkspace* w = new RooWorkspace("w") ; + fillWorkspace(*w) ; + + // Exploit convention encoded in named set "parameters" and "observables" + // to use workspace contents w/o need for introspected + RooAbsPdf* model = w->pdf("model") ; + + // Generate data from p.d.f. in given observables + RooDataSet* data = model->generate(*w->set("observables"),1000) ; + + // Fit model to data + model->fitTo(*data) ; + + // Plot fitted model and data on frame of first (only) observable + RooPlot* frame = ((RooRealVar*)w->set("observables")->first())->frame() ; + data->plotOn(frame) ; + model->plotOn(frame) ; + + // Overlay plot with model with reference parameters as stored in snapshots + w->loadSnapshot("reference_fit") ; + model->plotOn(frame,LineColor(kRed)) ; + w->loadSnapshot("reference_fit_bkgonly") ; + model->plotOn(frame,LineColor(kRed),LineStyle(kDashed)) ; + + + // Draw the frame on the canvas + new TCanvas("rf510_wsnamedsets","rf503_wsnamedsets",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + + + // Print workspace contents + w->Print() ; + + + // Workspace will remain in memory after macro finishes + gDirectory->Add(w) ; + +} + + + +void fillWorkspace(RooWorkspace& w) +{ + // C r e a t e m o d e l + // ----------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5,0,10) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + // Import model into p.d.f. + w.import(model) ; + + + // E n c o d e d e f i n i t i o n o f p a r a m e t e r s i n w o r k s p a c e + // --------------------------------------------------------------------------------------- + + + // Define named sets "parameters" and "observables", which list which variables should be considered + // parameters and observables by the users convention + // + // Variables appearing in sets _must_ live in the workspace already, or the autoImport flag + // of defineSet must be set to import them on the fly. Named sets contain only references + // to the original variables, therefore the value of observables in named sets already + // reflect their 'current' value + RooArgSet* params = (RooArgSet*) model.getParameters(x) ; + w.defineSet("parameters",*params) ; + w.defineSet("observables",x) ; + + + // E n c o d e r e f e r e n c e v a l u e f o r p a r a m e t e r s i n w o r k s p a c e + // --------------------------------------------------------------------------------------------------- + + + // Define a parameter 'snapshot' in the p.d.f. + // Unlike a named set, a parameter snapshot stores an independent set of values for + // a given set of variables in the workspace. The values can be stored and reloaded + // into the workspace variable objects using the loadSnapshot() and saveSnapshot() + // methods. A snapshot saves the value of each variable, any errors that are stored + // with it as well as the 'Constant' flag that is used in fits to determine if a + // parameter is kept fixed or not. + + // Do a dummy fit to a (supposedly) reference dataset here and store the results + // of that fit into a snapshot + RooDataSet* refData = model.generate(x,10000) ; + model.fitTo(*refData,PrintLevel(-1)) ; + + // The kTRUE flag imports the values of the objects in (*params) into the workspace + // If not set, the present values of the workspace parameters objects are stored + w.saveSnapshot("reference_fit",*params,kTRUE) ; + + // Make another fit with the signal componentforced to zero + // and save those parameters too + + bkgfrac.setVal(1) ; + bkgfrac.setConstant(kTRUE) ; + bkgfrac.removeError() ; + model.fitTo(*refData,PrintLevel(-1)) ; + + w.saveSnapshot("reference_fit_bkgonly",*params,kTRUE) ; + + +} diff --git a/cpp/rf511_wsfactory_basic.C b/cpp/rf511_wsfactory_basic.C new file mode 100644 index 0000000..299478e --- /dev/null +++ b/cpp/rf511_wsfactory_basic.C @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #511 +// +// Basic use of the 'object factory' associated with a workspace +// to rapidly build p.d.f.s functions and their parameter components +// +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf511_wsfactory_basic(Bool_t compact=kFALSE) +{ + RooWorkspace* w = new RooWorkspace("w") ; + + // C r e a t i n g a n d a d d i n g b a s i c p . d . f . s + // ---------------------------------------------------------------- + + + // Remake example p.d.f. of tutorial rs502_wspacewrite.C: + // + // Basic p.d.f. construction: ClassName::ObjectName(constructor arguments) + // Variable construction : VarName[x,xlo,xhi], VarName[xlo,xhi], VarName[x] + // P.d.f. addition : SUM::ObjectName(coef1*pdf1,...coefM*pdfM,pdfN) + // + + if (!compact) { + + // Use object factory to build p.d.f. of tutorial rs502_wspacewrite + w->factory("Gaussian::sig1(x[-10,10],mean[5,0,10],0.5)") ; + w->factory("Gaussian::sig2(x,mean,1)") ; + w->factory("Chebychev::bkg(x,{a0[0.5,0.,1],a1[-0.2,0.,1.]})") ; + w->factory("SUM::sig(sig1frac[0.8,0.,1.]*sig1,sig2)") ; + w->factory("SUM::model(bkgfrac[0.5,0.,1.]*bkg,sig)") ; + + } else { + + // Use object factory to build p.d.f. of tutorial rs502_wspacewrite but + // - Contracted to a single line recursive expression, + // - Omitting explicit names for components that are not referred to explicitly later + + w->factory("SUM::model(bkgfrac[0.5,0.,1.]*Chebychev::bkg(x[-10,10],{a0[0.5,0.,1],a1[-0.2,0.,1.]})," + "SUM(sig1frac[0.8,0.,1.]*Gaussian(x,mean[5,0,10],0.5), Gaussian(x,mean,1)))") ; + } + + + // A d v a n c e d p . d . f . c o n s t r u c t o r a r g u m e n t s + // ---------------------------------------------------------------- + // + // P.d.f. constructor arguments may by any type of RooAbsArg, but also + // + // Double_t --> converted to RooConst(...) + // {a,b,c} --> converted to RooArgSet() or RooArgList() depending on required ctor arg + // dataset name --> convered to RooAbsData reference for any dataset residing in the workspace + // enum --> Any enum label that belongs to an enum defined in the (base) class + + + // Make a dummy dataset p.d.f. 'model' and import it in the workspace + RooDataSet* data = w->pdf("model")->generate(*w->var("x"),1000) ; + w->import(*data,Rename("data")) ; + + // Construct a KEYS p.d.f. passing a dataset name and an enum type defining the + // mirroring strategy + w->factory("KeysPdf::k(x,data,NoMirror,0.2)") ; + + + // Print workspace contents + w->Print() ; + + // Make workspace visible on command line + gDirectory->Add(w) ; + +} + + diff --git a/cpp/rf512_wsfactory_oper.C b/cpp/rf512_wsfactory_oper.C new file mode 100644 index 0000000..3debc96 --- /dev/null +++ b/cpp/rf512_wsfactory_oper.C @@ -0,0 +1,100 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #512 +// +// Illustration of operator expressions and expression-based +// basic p.d.f.s in the workspace factory syntax +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf512_wsfactory_oper() +{ + RooWorkspace* w = new RooWorkspace("w") ; + + // You can define typedefs for even shorter construction semantics + w->factory("$Typedef(Gaussian,Gaus)") ; + w->factory("$Typedef(Chebychev,Cheby)") ; + + + // O p e r a t o r p . d . f . e x a m p l e s + // ------------------------------------------------ + + // PDF addition is done with SUM (coef1*pdf1,pdf2) + w->factory("SUM::summodel( f[0,1]*Gaussian::gx(x[-10,10],m[0],1.0), Chebychev::ch(x,{0.1,0.2,-0.3}) )") ; + + + // Extended PDF addition is done with SUM (yield1*pdf1,yield2*pdf2) + w->factory("SUM::extsummodel( Nsig[0,1000]*gx, Nbkg[0,1000]*ch )") ; + + + // PDF multiplication is done with PROD ( pdf1, pdf2 ) + w->factory("PROD::gxz( gx, Gaussian::gz(z[-10,10],0,1) )") ; + + + // Conditional p.d.f multiplication is done with PROD ( pdf1|obs, pdf2 ) + w->factory("Gaussian::gy( y[-10,10], x, 1.0 )") ; + w->factory("PROD::gxycond( gy|x, gx )") ; + + + // Convolution (numeric/ fft) is done with NCONV/FCONV (obs,pdf1,pdf2) + w->factory("FCONV::lxg( x, Gaussian::g(x,mg[0],1), Landau::lc(x,0,1) )") ; + + + // Simultaneous p.d.f.s are constructed with SIMUL( index, state1=pdf1, state2=pdf2,...) + w->factory("SIMUL::smodel( c[A=0,B=1], A=Gaussian::gs(x,m,s[1]), B=Landau::ls(x,0,1) )") ; + + + + + // O p e r a t o r f u n c t i o n e x a m p l e s + // --------------------------------------------------- + + // Function multiplication is done with prod (func1, func2,...) + w->factory("prod::uv(u[10],v[10])") ; + + + // Function addition is done with sum(func1,func2) + w->factory("sum::uv2(u,v)") ; + + + + // I n t e r p r e t e d a n d c o m p i l e d e x p r e s s i o n b a s e d p . d . f . s . + // --------------------------------------------------------------------------------------------------- + + // Create a RooGenericPdf interpreted p.d.f. You can use single quotes to pass the expression string argument + w->factory("EXPR::G('x*x+1',x)") ; + + // Create a custom compiled p.d.f similar to the above interpreted p.d.f. + // The code required to make this p.d.f. is automatically embedded in the workspace + w->factory("CEXPR::GC('x*x+a',{x,a[1]})") ; + + + // Compiled and interpreted functions (rather than p.d.f.s) can be made with the lower case + // 'expr' and 'cexpr' types + + // Print workspace contents + w->Print() ; + + // Make workspace visible on command line + gDirectory->Add(w) ; +} + + diff --git a/cpp/rf513_wsfactory_tools.C b/cpp/rf513_wsfactory_tools.C new file mode 100644 index 0000000..d8c0ff7 --- /dev/null +++ b/cpp/rf513_wsfactory_tools.C @@ -0,0 +1,94 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'ORGANIZATION AND SIMULTANEOUS FITS' RooFit tutorial macro #513 +// +// Illustration use of RooCustomizer and RooSimWSTool interface +// in factory workspace tool in a complex standalone B physics example +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooWorkspace.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf513_wsfactory_tools() +{ + RooWorkspace* w = new RooWorkspace("w") ; + + + // B u i l d a c o m p l e x e x a m p l e p . d . f . + // ----------------------------------------------------------- + + // Make signal model for CPV: A bmixing decay function in t (convoluted with a triple Gaussian resolution model) + // times a Gaussian function the reconstructed mass + w->factory("PROD::sig( BMixDecay::sig_t( dt[-20,20], mixState[mixed=1,unmix=-1], tagFlav[B0=1,B0bar=-1], " + "tau[1.54], dm[0.472], w[0.05], dw[0]," + "AddModel::gm({GaussModel(dt,biasC[-10,10],sigmaC[0.1,3],dterr[0.01,0.2])," + "GaussModel(dt,0,sigmaT[3,10])," + "GaussModel(dt,0,20)},{fracC[0,1],fracT[0,1]})," + "DoubleSided )," + "Gaussian::sig_m( mes[5.20,5.30], mB0[5.20,5.30], sigmB0[0.01,0.05] ))") ; + + // Make background component: A plain decay function in t times an Argus function in the reconstructed mass + w->factory("PROD::bkg( Decay::bkg_t( dt, tau, gm, DoubleSided)," + "ArgusBG::bkg_m( mes, 5.291, k[-100,-10]))") ; + + // Make composite model from the signal and background component + w->factory("SUM::model( Nsig[5000,0,10000]*sig, NBkg[500,0,10000]*bkg )") ; + + + // E x a m p l e o f R o o S i m W S T o o l i n t e r f a c e + // ------------------------------------------------------------------ + + // Introduce a flavour tagging category tagCat as observable with 4 states corresponding + // to 4 flavour tagging techniques with different performance that require different + // parameterizations of the fit model + // + // RooSimWSTool operation: + // - Make 4 clones of model (for each tagCat) state, that will gain an individual + // copy of parameters w,dw and biasC. The other parameters remain common + // - Make a simultaneous p.d.f. of the 4 clones assigning each to the appropriate + // state of the tagCat index category + + // RooSimWSTool is interfaced as meta-type SIMCLONE in the factory. The $SplitParam() + // argument maps to the SplitParam() named argument in the RooSimWSTool constructor + w->factory("SIMCLONE::model_sim( model, $SplitParam({w,dw,biasC},tagCat[Lep,Kao,NT1,NT2]))") ; + + + // E x a m p l e o f R o o C u s t o m i z e r i n t e r f a c e + // ------------------------------------------------------------------- + // + // Class RooCustomizer makes clones of existing p.d.f.s with certain prescribed + // modifications (branch of leaf node replacements) + // + // Here we take our model (the original before RooSimWSTool modifications) + // and request that the parameter w (the mistag rate) is replaced with + // an expression-based function that calculates w in terms of the Dilution + // parameter D that is defined as D = 1-2*w + + // Make a clone model_D of original 'model' replacing 'w' with 'expr('0.5-D/2',D[0,1])' + w->factory("EDIT::model_D(model, w=expr('0.5-D/2',D[0,1]) )") ; + + + // Print workspace contents + w->Print() ; + + // Make workspace visible on command line + gDirectory->Add(w) ; +} + + diff --git a/cpp/rf601_intminuit.C b/cpp/rf601_intminuit.C new file mode 100644 index 0000000..ee093f3 --- /dev/null +++ b/cpp/rf601_intminuit.C @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #601 +// +// Interactive minimization with MINUIT +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooProdPdf.h" +#include "RooAddPdf.h" +#include "RooMinuit.h" +#include "RooFitResult.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf601_intminuit() +{ + // S e t u p p d f a n d l i k e l i h o o d + // ----------------------------------------------- + + // Observable + RooRealVar x("x","x",-20,20) ; + + // Model (intentional strong correlations) + RooRealVar mean("mean","mean of g1 and g2",0) ; + RooRealVar sigma_g1("sigma_g1","width of g1",3) ; + RooGaussian g1("g1","g1",x,mean,sigma_g1) ; + + RooRealVar sigma_g2("sigma_g2","width of g2",4,3.0,6.0) ; + RooGaussian g2("g2","g2",x,mean,sigma_g2) ; + + RooRealVar frac("frac","frac",0.5,0.0,1.0) ; + RooAddPdf model("model","model",RooArgList(g1,g2),frac) ; + + // Generate 1000 events + RooDataSet* data = model.generate(x,1000) ; + + // Construct unbinned likelihood of model w.r.t. data + RooAbsReal* nll = model.createNLL(*data) ; + + // I n t e r a c t i v e m i n i m i z a t i o n , e r r o r a n a l y s i s + // ------------------------------------------------------------------------------- + + // Create MINUIT interface object + RooMinuit m(*nll) ; + + // Activate verbose logging of MINUIT parameter space stepping + m.setVerbose(kTRUE) ; + + // Call MIGRAD to minimize the likelihood + m.migrad() ; + + // Print values of all parameters, that reflect values (and error estimates) + // that are back propagated from MINUIT + model.getParameters(x)->Print("s") ; + + // Disable verbose logging + m.setVerbose(kFALSE) ; + + // Run HESSE to calculate errors from d2L/dp2 + m.hesse() ; + + // Print value (and error) of sigma_g2 parameter, that reflects + // value and error back propagated from MINUIT + sigma_g2.Print() ; + + // Run MINOS on sigma_g2 parameter only + m.minos(sigma_g2) ; + + // Print value (and error) of sigma_g2 parameter, that reflects + // value and error back propagated from MINUIT + sigma_g2.Print() ; + + + + // S a v i n g r e s u l t s , c o n t o u r p l o t s + // --------------------------------------------------------- + + // Save a snapshot of the fit result. This object contains the initial + // fit parameters, the final fit parameters, the complete correlation + // matrix, the EDM, the minimized FCN , the last MINUIT status code and + // the number of times the RooFit function object has indicated evaluation + // problems (e.g. zero probabilities during likelihood evaluation) + RooFitResult* r = m.save() ; + + // Make contour plot of mx vs sx at 1,2,3 sigma + RooPlot* frame = m.contour(frac,sigma_g2,1,2,3) ; + frame->SetTitle("RooMinuit contour plot") ; + + // Print the fit result snapshot + r->Print("v") ; + + + + // C h a n g e p a r a m e t e r v a l u e s , f l o a t i n g + // ----------------------------------------------------------------- + + // At any moment you can manually change the value of a (constant) + // parameter + mean = 0.3 ; + + // Rerun MIGRAD,HESSE + m.migrad() ; + m.hesse() ; + frac.Print() ; + + // Now fix sigma_g2 + sigma_g2.setConstant(kTRUE) ; + + // Rerun MIGRAD,HESSE + m.migrad() ; + m.hesse() ; + frac.Print() ; + + + + new TCanvas("rf601_intminuit","rf601_intminuit",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + +} diff --git a/cpp/rf602_chi2fit.C b/cpp/rf602_chi2fit.C new file mode 100644 index 0000000..4852eb1 --- /dev/null +++ b/cpp/rf602_chi2fit.C @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #602 +// +// Setting up a chi^2 fit to a binned dataset +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooChi2Var.h" +#include "RooMinuit.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf602_chi2fit() +{ + + // S e t u p m o d e l + // --------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,0.,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + + // C r e a t e b i n n e d d a t a s e t + // ----------------------------------------- + + RooDataSet* d = model.generate(x,10000) ; + RooDataHist* dh = d->binnedClone() ; + + // Construct a chi^2 of the data and the model. + // When a p.d.f. is used in a chi^2 fit, the probability density scaled + // by the number of events in the dataset to obtain the fit function + // If model is an extended p.d.f, the expected number events is used + // instead of the observed number of events. + model.chi2FitTo(*dh) ; + + // NB: It is also possible to fit a RooAbsReal function to a RooDataHist + // using chi2FitTo(). + + // Note that entries with zero bins are _not_ allowed + // for a proper chi^2 calculation and will give error + // messages + RooDataSet* dsmall = (RooDataSet*) d->reduce(EventRange(1,100)) ; + RooDataHist* dhsmall = dsmall->binnedClone() ; + RooChi2Var chi2_lowstat("chi2_lowstat","chi2",model,*dhsmall) ; + cout << chi2_lowstat.getVal() << endl ; + + +} diff --git a/cpp/rf603_multicpu.C b/cpp/rf603_multicpu.C new file mode 100644 index 0000000..d576386 --- /dev/null +++ b/cpp/rf603_multicpu.C @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #603 +// +// Setting up a multi-core parallelized unbinned maximum likelihood fit +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf603_multicpu() +{ + + // C r e a t e 3 D p d f a n d d a t a + // ------------------------------------------- + + // Create observables + RooRealVar x("x","x",-5,5) ; + RooRealVar y("y","y",-5,5) ; + RooRealVar z("z","z",-5,5) ; + + // Create signal pdf gauss(x)*gauss(y)*gauss(z) + RooGaussian gx("gx","gx",x,RooConst(0),RooConst(1)) ; + RooGaussian gy("gy","gy",y,RooConst(0),RooConst(1)) ; + RooGaussian gz("gz","gz",z,RooConst(0),RooConst(1)) ; + RooProdPdf sig("sig","sig",RooArgSet(gx,gy,gz)) ; + + // Create background pdf poly(x)*poly(y)*poly(z) + RooPolynomial px("px","px",x,RooArgSet(RooConst(-0.1),RooConst(0.004))) ; + RooPolynomial py("py","py",y,RooArgSet(RooConst(0.1),RooConst(-0.004))) ; + RooPolynomial pz("pz","pz",z) ; + RooProdPdf bkg("bkg","bkg",RooArgSet(px,py,pz)) ; + + // Create composite pdf sig+bkg + RooRealVar fsig("fsig","signal fraction",0.1,0.,1.) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),fsig) ; + + // Generate large dataset + RooDataSet* data = model.generate(RooArgSet(x,y,z),200000) ; + + + + // P a r a l l e l f i t t i n g + // ------------------------------- + + // In parallel mode the likelihood calculation is split in N pieces, + // that are calculated in parallel and added a posteriori before passing + // it back to MINUIT. + + // Use four processes and time results both in wall time and CPU time + model.fitTo(*data,NumCPU(4),Timer(kTRUE)) ; + + + + // P a r a l l e l M C p r o j e c t i o n s + // ---------------------------------------------- + + // Construct signal, total likelihood projection on (y,z) observables and likelihood ratio + RooAbsPdf* sigyz = sig.createProjection(x) ; + RooAbsPdf* totyz = model.createProjection(x) ; + RooFormulaVar llratio_func("llratio","log10(@0)-log10(@1)",RooArgList(*sigyz,*totyz)) ; + + // Calculate likelihood ratio for each event, define subset of events with high signal likelihood + data->addColumn(llratio_func) ; + RooDataSet* dataSel = (RooDataSet*) data->reduce(Cut("llratio>0.7")) ; + + // Make plot frame and plot data + RooPlot* frame = x.frame(Title("Projection on X with LLratio(y,z)>0.7"),Bins(40)) ; + dataSel->plotOn(frame) ; + + // Perform parallel projection using MC integration of pdf using given input dataSet. + // In this mode the data-weighted average of the pdf is calculated by splitting the + // input dataset in N equal pieces and calculating in parallel the weighted average + // one each subset. The N results of those calculations are then weighted into the + // final result + + // Use four processes + model.plotOn(frame,ProjWData(*dataSel),NumCPU(4)) ; + + + new TCanvas("rf603_multicpu","rf603_multicpu",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + +} diff --git a/cpp/rf604_constraints.C b/cpp/rf604_constraints.C new file mode 100644 index 0000000..7ebc925 --- /dev/null +++ b/cpp/rf604_constraints.C @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #604 +// +// Fitting with constraints +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "RooProdPdf.h" +#include "RooFitResult.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf604_constraints() +{ + + // C r e a t e m o d e l a n d d a t a s e t + // ---------------------------------------------- + + // Construct a Gaussian p.d.f + RooRealVar x("x","x",-10,10) ; + + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",2,0.1,10) ; + RooGaussian gauss("gauss","gauss(x,m,s)",x,m,s) ; + + // Construct a flat p.d.f (polynomial of 0th order) + RooPolynomial poly("poly","poly(x)",x) ; + + // Construct model = f*gauss + (1-f)*poly + RooRealVar f("f","f",0.5,0.,1.) ; + RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ; + + // Generate small dataset for use in fitting below + RooDataSet* d = model.generate(x,50) ; + + + + // C r e a t e c o n s t r a i n t p d f + // ----------------------------------------- + + // Construct Gaussian constraint p.d.f on parameter f at 0.8 with resolution of 0.1 + RooGaussian fconstraint("fconstraint","fconstraint",f,RooConst(0.8),RooConst(0.1)) ; + + + + // M E T H O D 1 - A d d i n t e r n a l c o n s t r a i n t t o m o d e l + // ------------------------------------------------------------------------------------- + + // Multiply constraint term with regular p.d.f using RooProdPdf + // Specify in fitTo() that internal constraints on parameter f should be used + + // Multiply constraint with p.d.f + RooProdPdf modelc("modelc","model with constraint",RooArgSet(model,fconstraint)) ; + + // Fit model (without use of constraint term) + RooFitResult* r1 = model.fitTo(*d,Save()) ; + + // Fit modelc with constraint term on parameter f + RooFitResult* r2 = modelc.fitTo(*d,Constrain(f),Save()) ; + + + + // M E T H O D 2 - S p e c i f y e x t e r n a l c o n s t r a i n t w h e n f i t t i n g + // ------------------------------------------------------------------------------------------------------- + + // Construct another Gaussian constraint p.d.f on parameter f at 0.8 with resolution of 0.1 + RooGaussian fconstext("fconstext","fconstext",f,RooConst(0.2),RooConst(0.1)) ; + + // Fit with external constraint + RooFitResult* r3 = model.fitTo(*d,ExternalConstraints(fconstext),Save()) ; + + + + // Print the fit results + cout << "fit result without constraint (data generated at f=0.5)" << endl ; + r1->Print("v") ; + cout << "fit result with internal constraint (data generated at f=0.5, constraint is f=0.8+/-0.2)" << endl ; + r2->Print("v") ; + cout << "fit result with (another) external constraint (data generated at f=0.5, constraint is f=0.2+/-0.1)" << endl ; + r3->Print("v") ; + +} diff --git a/cpp/rf605_profilell.C b/cpp/rf605_profilell.C new file mode 100644 index 0000000..61ca935 --- /dev/null +++ b/cpp/rf605_profilell.C @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #605 +// +// Working with the profile likelihood estimator +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooAddPdf.h" +#include "RooMinuit.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf605_profilell() +{ + // C r e a t e m o d e l a n d d a t a s e t + // ----------------------------------------------- + + // Observable + RooRealVar x("x","x",-20,20) ; + + // Model (intentional strong correlations) + RooRealVar mean("mean","mean of g1 and g2",0,-10,10) ; + RooRealVar sigma_g1("sigma_g1","width of g1",3) ; + RooGaussian g1("g1","g1",x,mean,sigma_g1) ; + + RooRealVar sigma_g2("sigma_g2","width of g2",4,3.0,6.0) ; + RooGaussian g2("g2","g2",x,mean,sigma_g2) ; + + RooRealVar frac("frac","frac",0.5,0.0,1.0) ; + RooAddPdf model("model","model",RooArgList(g1,g2),frac) ; + + // Generate 1000 events + RooDataSet* data = model.generate(x,1000) ; + + + + // C o n s t r u c t p l a i n l i k e l i h o o d + // --------------------------------------------------- + + // Construct unbinned likelihood + RooAbsReal* nll = model.createNLL(*data,NumCPU(2)) ; + + // Minimize likelihood w.r.t all parameters before making plots + RooMinuit(*nll).migrad() ; + + // Plot likelihood scan frac + RooPlot* frame1 = frac.frame(Bins(10),Range(0.01,0.95),Title("LL and profileLL in frac")) ; + nll->plotOn(frame1,ShiftToZero()) ; + + // Plot likelihood scan in sigma_g2 + RooPlot* frame2 = sigma_g2.frame(Bins(10),Range(3.3,5.0),Title("LL and profileLL in sigma_g2")) ; + nll->plotOn(frame2,ShiftToZero()) ; + + + + // C o n s t r u c t p r o f i l e l i k e l i h o o d i n f r a c + // ----------------------------------------------------------------------- + + // The profile likelihood estimator on nll for frac will minimize nll w.r.t + // all floating parameters except frac for each evaluation + + RooAbsReal* pll_frac = nll->createProfile(frac) ; + + // Plot the profile likelihood in frac + pll_frac->plotOn(frame1,LineColor(kRed)) ; + + // Adjust frame maximum for visual clarity + frame1->SetMinimum(0) ; + frame1->SetMaximum(3) ; + + + + // C o n s t r u c t p r o f i l e l i k e l i h o o d i n s i g m a _ g 2 + // ------------------------------------------------------------------------------- + + // The profile likelihood estimator on nll for sigma_g2 will minimize nll + // w.r.t all floating parameters except sigma_g2 for each evaluation + RooAbsReal* pll_sigmag2 = nll->createProfile(sigma_g2) ; + + // Plot the profile likelihood in sigma_g2 + pll_sigmag2->plotOn(frame2,LineColor(kRed)) ; + + // Adjust frame maximum for visual clarity + frame2->SetMinimum(0) ; + frame2->SetMaximum(3) ; + + + + // Make canvas and draw RooPlots + TCanvas *c = new TCanvas("rf605_profilell","rf605_profilell",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() ; + + delete pll_frac ; + delete pll_sigmag2 ; + delete nll ; +} + diff --git a/cpp/rf606_nllerrorhandling.C b/cpp/rf606_nllerrorhandling.C new file mode 100644 index 0000000..7f88046 --- /dev/null +++ b/cpp/rf606_nllerrorhandling.C @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #606 +// +// Understanding and customizing error handling in likelihood evaluations +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooArgusBG.h" +#include "RooNLLVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf606_nllerrorhandling() +{ + // C r e a t e m o d e l a n d d a t a s e t + // ---------------------------------------------- + + // Observable + RooRealVar m("m","m",5.20,5.30) ; + + // Parameters + RooRealVar m0("m0","m0",5.291,5.20,5.30) ; + RooRealVar k("k","k",-30,-50,-10) ; + + // Pdf + RooArgusBG argus("argus","argus",m,m0,k) ; + + // Sample 1000 events in m from argus + RooDataSet* data = argus.generate(m,1000) ; + + + + // P l o t m o d e l a n d d a t a + // -------------------------------------- + + RooPlot* frame1 = m.frame(Bins(40),Title("Argus model and data")) ; + data->plotOn(frame1) ; + argus.plotOn(frame1) ; + + + + // F i t m o d e l t o d a t a + // --------------------------------- + + // The ARGUS background shape has a sharp kinematic cutoff at m=m0 + // and is prone to evaluation errors if the cutoff parameter m0 + // is floated: when the pdf cutoff value is lower than that in data + // events with m>m0 will have zero probability + + // Perform unbinned ML fit. Print detailed error messages for up to + // 10 events per likelihood evaluation. The default error handling strategy + // is to return a very high value of the likelihood to MINUIT if errors occur, + // which will force MINUIT to retreat from the problematic area + + argus.fitTo(*data,PrintEvalErrors(10)) ; + + // Peform another fit. In this configuration only the number of errors per + // likelihood evaluation is shown, if it is greater than zero. The + // EvalErrorWall(kFALSE) arguments disables the default error handling strategy + // and will cause the actual (problematic) value of the likelihood to be passed + // to MINUIT. + // + // NB: Use of this option is NOT recommended as default strategt as broken -log(L) values + // can often be lower than 'good' ones because offending events are removed. + // This may effectively create a false minimum in problem areas. This is clearly + // illustrated in the second plot + + m0.setError(0.1) ; + argus.fitTo(*data,PrintEvalErrors(0),EvalErrorWall(kFALSE)) ; + + + + // P l o t l i k e l i h o o d a s f u n c t i o n o f m 0 + // ------------------------------------------------------------------ + + // Construct likelihood function of model and data + RooNLLVar nll("nll","nll",argus,*data) ; + + // Plot likelihood in m0 in range that includes problematic values + // In this configuration no messages are printed for likelihood evaluation errors, + // but if an likelihood value evaluates with error, the corresponding value + // on the curve will be set to the value given in EvalErrorValue(). + + RooPlot* frame2 = m0.frame(Range(5.288,5.293),Title("-log(L) scan vs m0, problematic regions masked")) ; + nll.plotOn(frame2,PrintEvalErrors(-1),ShiftToZero(),EvalErrorValue(nll.getVal()+10),LineColor(kRed)) ; + frame2->SetMaximum(15) ; + frame2->SetMinimum(0) ; + + + TCanvas* c = new TCanvas("rf606_nllerrorhandling","rf606_nllerrorhandling",1200,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() ; + +} diff --git a/cpp/rf607_fitresult.C b/cpp/rf607_fitresult.C new file mode 100644 index 0000000..7471c0d --- /dev/null +++ b/cpp/rf607_fitresult.C @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #607 +// +// Demonstration of options of the RooFitResult class +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooAddPdf.h" +#include "RooChebychev.h" +#include "RooFitResult.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TFile.h" +#include "TStyle.h" +#include "TH2.h" +#include "TMatrixDSym.h" + +using namespace RooFit ; + + +void rf607_fitresult() +{ + // C r e a t e p d f , d a t a + // -------------------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5,-10,10) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5,0.1,10) ; + RooRealVar sigma2("sigma2","width of gaussians",1,0.1,10) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar bkgfrac("bkgfrac","fraction of background",0.5,0.,1.) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),bkgfrac) ; + + // Generate 1000 events + RooDataSet* data = model.generate(x,1000) ; + + + + // F i t p d f t o d a t a , s a v e f i t r e s u l t + // ------------------------------------------------------------- + + // Perform fit and save result + RooFitResult* r = model.fitTo(*data,Save()) ; + + + + // P r i n t f i t r e s u l t s + // --------------------------------- + + // Summary printing: Basic info plus final values of floating fit parameters + r->Print() ; + + // Verbose printing: Basic info, values of constant parameters, initial and + // final values of floating parameters, global correlations + r->Print("v") ; + + + + // V i s u a l i z e c o r r e l a t i o n m a t r i x + // ------------------------------------------------------- + + // Construct 2D color plot of correlation matrix + gStyle->SetOptStat(0) ; + gStyle->SetPalette(1) ; + TH2* hcorr = r->correlationHist() ; + + + // Visualize ellipse corresponding to single correlation matrix element + RooPlot* frame = new RooPlot(sigma1,sig1frac,0.45,0.60,0.65,0.90) ; + frame->SetTitle("Covariance between sigma1 and sig1frac") ; + r->plotOn(frame,sigma1,sig1frac,"ME12ABHV") ; + + + + // A c c e s s f i t r e s u l t i n f o r m a t i o n + // --------------------------------------------------------- + + // Access basic information + cout << "EDM = " << r->edm() << endl ; + cout << "-log(L) at minimum = " << r->minNll() << endl ; + + // Access list of final fit parameter values + cout << "final value of floating parameters" << endl ; + r->floatParsFinal().Print("s") ; + + // Access correlation matrix elements + cout << "correlation between sig1frac and a0 is " << r->correlation(sig1frac,a0) << endl ; + cout << "correlation between bkgfrac and mean is " << r->correlation("bkgfrac","mean") << endl ; + + // Extract covariance and correlation matrix as TMatrixDSym + const TMatrixDSym& cor = r->correlationMatrix() ; + const TMatrixDSym& cov = r->covarianceMatrix() ; + + // Print correlation, covariance matrix + cout << "correlation matrix" << endl ; + cor.Print() ; + cout << "covariance matrix" << endl ; + cov.Print() ; + + + // P e r s i s t f i t r e s u l t i n r o o t f i l e + // ------------------------------------------------------------- + + // Open new ROOT file save save result + TFile f("rf607_fitresult.root","RECREATE") ; + r->Write("rf607") ; + f.Close() ; + + // In a clean ROOT session retrieve the persisted fit result as follows: + // RooFitResult* r = gDirectory->Get("rf607") ; + + + TCanvas* c = new TCanvas("rf607_fitresult","rf607_fitresult",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; hcorr->GetYaxis()->SetTitleOffset(1.4) ; hcorr->Draw("colz") ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.6) ; frame->Draw() ; + +} diff --git a/cpp/rf608_fitresultaspdf.C b/cpp/rf608_fitresultaspdf.C new file mode 100644 index 0000000..bbd6d23 --- /dev/null +++ b/cpp/rf608_fitresultaspdf.C @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #608 +// +// Representing the parabolic approximation of the fit as +// a multi-variate Gaussian on the parameters of the fitted p.d.f. +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooAddPdf.h" +#include "RooChebychev.h" +#include "RooFitResult.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TFile.h" +#include "TStyle.h" +#include "TH2.h" +#include "TH3.h" + +using namespace RooFit ; + + +void rf608_fitresultaspdf() +{ + // C r e a t e m o d e l a n d d a t a s e t + // ----------------------------------------------- + + // Observable + RooRealVar x("x","x",-20,20) ; + + // Model (intentional strong correlations) + RooRealVar mean("mean","mean of g1 and g2",0,-1,1) ; + RooRealVar sigma_g1("sigma_g1","width of g1",2) ; + RooGaussian g1("g1","g1",x,mean,sigma_g1) ; + + RooRealVar sigma_g2("sigma_g2","width of g2",4,3.0,5.0) ; + RooGaussian g2("g2","g2",x,mean,sigma_g2) ; + + RooRealVar frac("frac","frac",0.5,0.0,1.0) ; + RooAddPdf model("model","model",RooArgList(g1,g2),frac) ; + + // Generate 1000 events + RooDataSet* data = model.generate(x,1000) ; + + + // F i t m o d e l t o d a t a + // ---------------------------------- + + RooFitResult* r = model.fitTo(*data,Save()) ; + + + // C r e a t e M V G a u s s i a n p d f o f f i t t e d p a r a m e t e r s + // ------------------------------------------------------------------------------------ + + RooAbsPdf* parabPdf = r->createHessePdf(RooArgSet(frac,mean,sigma_g2)) ; + + + // S o m e e x e c e r c i s e s w i t h t h e p a r a m e t e r p d f + // ----------------------------------------------------------------------------- + + // Generate 100K points in the parameter space, sampled from the MVGaussian p.d.f. + RooDataSet* d = parabPdf->generate(RooArgSet(mean,sigma_g2,frac),100000) ; + + + // Sample a 3-D histogram of the p.d.f. to be visualized as an error ellipsoid using the GLISO draw option + TH3* hh_3d = (TH3*) parabPdf->createHistogram("mean,sigma_g2,frac",25,25,25) ; + hh_3d->SetFillColor(kBlue) ; + + + // Project 3D parameter p.d.f. down to 3 permutations of two-dimensional p.d.f.s + // The integrations corresponding to these projections are performed analytically + // by the MV Gaussian p.d.f. + RooAbsPdf* pdf_sigmag2_frac = parabPdf->createProjection(mean) ; + RooAbsPdf* pdf_mean_frac = parabPdf->createProjection(sigma_g2) ; + RooAbsPdf* pdf_mean_sigmag2 = parabPdf->createProjection(frac) ; + + + // Make 2D plots of the 3 two-dimensional p.d.f. projections + TH2* hh_sigmag2_frac = (TH2*) pdf_sigmag2_frac->createHistogram("sigma_g2,frac",50,50) ; + TH2* hh_mean_frac = (TH2*) pdf_mean_frac->createHistogram("mean,frac",50,50) ; + TH2* hh_mean_sigmag2 = (TH2*) pdf_mean_sigmag2->createHistogram("mean,sigma_g2",50,50) ; + hh_mean_frac->SetLineColor(kBlue) ; + hh_sigmag2_frac->SetLineColor(kBlue) ; + hh_mean_sigmag2->SetLineColor(kBlue) ; + + + // Draw the 'sigar' + gStyle->SetCanvasPreferGL(true); + gStyle->SetPalette(1) ; + new TCanvas("rf608_fitresultaspdf_1","rf608_fitresultaspdf_1",600,600) ; + hh_3d->Draw("gliso") ; + + // Draw the 2D projections of the 3D p.d.f. + TCanvas* c2 = new TCanvas("rf608_fitresultaspdf_2","rf608_fitresultaspdf_2",900,600) ; + c2->Divide(3,2) ; + c2->cd(1) ; gPad->SetLeftMargin(0.15) ; hh_mean_sigmag2->GetZaxis()->SetTitleOffset(1.4) ; hh_mean_sigmag2->Draw("surf3") ; + c2->cd(2) ; gPad->SetLeftMargin(0.15) ; hh_sigmag2_frac->GetZaxis()->SetTitleOffset(1.4) ; hh_sigmag2_frac->Draw("surf3") ; + c2->cd(3) ; gPad->SetLeftMargin(0.15) ; hh_mean_frac->GetZaxis()->SetTitleOffset(1.4) ; hh_mean_frac->Draw("surf3") ; + + // Draw the distributions of parameter points sampled from the p.d.f. + TH1* tmp1 = d->createHistogram("mean,sigma_g2",50,50) ; + TH1* tmp2 = d->createHistogram("sigma_g2,frac",50,50) ; + TH1* tmp3 = d->createHistogram("mean,frac",50,50) ; + + c2->cd(4) ; gPad->SetLeftMargin(0.15) ; tmp1->GetZaxis()->SetTitleOffset(1.4) ; tmp1->Draw("lego3") ; + c2->cd(5) ; gPad->SetLeftMargin(0.15) ; tmp2->GetZaxis()->SetTitleOffset(1.4) ; tmp2->Draw("lego3") ; + c2->cd(6) ; gPad->SetLeftMargin(0.15) ; tmp3->GetZaxis()->SetTitleOffset(1.4) ; tmp3->Draw("lego3") ; + +} + diff --git a/cpp/rf609_xychi2fit.C b/cpp/rf609_xychi2fit.C new file mode 100644 index 0000000..adb0b83 --- /dev/null +++ b/cpp/rf609_xychi2fit.C @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #609 +// +// Setting up a chi^2 fit to an unbinned dataset with X,Y,err(Y) +// values (and optionally err(X) values) +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooPolyVar.h" +#include "RooConstVar.h" +#include "RooChi2Var.h" +#include "RooMinuit.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TRandom.h" + +using namespace RooFit ; + + +void rf609_xychi2fit() +{ + // C r e a t e d a t a s e t w i t h X a n d Y v a l u e s + // ------------------------------------------------------------------- + + // Make weighted XY dataset with asymmetric errors stored + // The StoreError() argument is essential as it makes + // the dataset store the error in addition to the values + // of the observables. If errors on one or more observables + // are asymmetric, one can store the asymmetric error + // using the StoreAsymError() argument + + RooRealVar x("x","x",-11,11) ; + RooRealVar y("y","y",-10,200) ; + RooDataSet dxy("dxy","dxy",RooArgSet(x,y),StoreError(RooArgSet(x,y))) ; + + // Fill an example dataset with X,err(X),Y,err(Y) values + for (int i=0 ; i<=10 ; i++) { + + // Set X value and error + x = -10 + 2*i; + x.setError( i<5 ? 0.5/1. : 1.0/1. ) ; + + // Set Y value and error + y = x.getVal() * x.getVal() + 4*fabs(gRandom->Gaus()) ; + y.setError(sqrt(y.getVal())) ; + + dxy.add(RooArgSet(x,y)) ; + } + + + + // P e r f o r m c h i 2 f i t t o X + / - d x a n d Y + / - d Y v a l u e s + // --------------------------------------------------------------------------------------- + + // Make fit function + RooRealVar a("a","a",0.0,-10,10) ; + RooRealVar b("b","b",0.0,-100,100) ; + RooPolyVar f("f","f",x,RooArgList(b,a,RooConst(1))) ; + + // Plot dataset in X-Y interpretation + RooPlot* frame = x.frame(Title("Chi^2 fit of function set of (X#pmdX,Y#pmdY) values")) ; + dxy.plotOnXY(frame,YVar(y)) ; + + // Fit chi^2 using X and Y errors + f.chi2FitTo(dxy,YVar(y)) ; + + // Overlay fitted function + f.plotOn(frame) ; + + // Alternative: fit chi^2 integrating f(x) over ranges defined by X errors, rather + // than taking point at center of bin + f.chi2FitTo(dxy,YVar(y),Integrate(kTRUE)) ; + + // Overlay alternate fit result + f.plotOn(frame,LineStyle(kDashed),LineColor(kRed)) ; + + + // Draw the plot on a canvas + new TCanvas("rf609_xychi2fit","rf609_xychi2fit",600,600) ; + gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + + +} diff --git a/cpp/rf610_visualerror.C b/cpp/rf610_visualerror.C new file mode 100644 index 0000000..5ea313e --- /dev/null +++ b/cpp/rf610_visualerror.C @@ -0,0 +1,161 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #610 +// +// Visualization of errors from a covariance matrix +// +// +// +// 04/2009 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooAddPdf.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TAxis.h" +using namespace RooFit ; + + +void rf610_visualerror() +{ + // S e t u p e x a m p l e f i t + // --------------------------------------- + + // Create sum of two Gaussians p.d.f. with factory + RooRealVar x("x","x",-10,10) ; + + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",2,1,50) ; + RooGaussian sig("sig","sig",x,m,s) ; + + RooRealVar m2("m2","m2",-1,-10,10) ; + RooRealVar s2("s2","s2",6,1,50) ; + RooGaussian bkg("bkg","bkg",x,m2,s2) ; + + RooRealVar fsig("fsig","fsig",0.33,0,1) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),fsig) ; + + // Create binned dataset + x.setBins(25) ; + RooAbsData* d = model.generateBinned(x,1000) ; + + // Perform fit and save fit result + RooFitResult* r = model.fitTo(*d,Save()) ; + + + // V i s u a l i z e f i t e r r o r + // ------------------------------------- + + // Make plot frame + RooPlot* frame = x.frame(Bins(40),Title("P.d.f with visualized 1-sigma error band")) ; + d->plotOn(frame) ; + + // Visualize 1-sigma error encoded in fit result 'r' as orange band using linear error propagation + // This results in an error band that is by construction symmetric + // + // The linear error is calculated as + // error(x) = Z* F_a(x) * Corr(a,a') F_a'(x) + // + // where F_a(x) = [ f(x,a+da) - f(x,a-da) ] / 2, + // + // with f(x) = the plotted curve + // 'da' = error taken from the fit result + // Corr(a,a') = the correlation matrix from the fit result + // Z = requested significance 'Z sigma band' + // + // The linear method is fast (required 2*N evaluations of the curve, where N is the number of parameters), + // but may not be accurate in the presence of strong correlations (~>0.9) and at Z>2 due to linear and + // Gaussian approximations made + // + model.plotOn(frame,VisualizeError(*r,1),FillColor(kOrange)) ; + + + // Calculate error using sampling method and visualize as dashed red line. + // + // In this method a number of curves is calculated with variations of the parameter values, as sampled + // from a multi-variate Gaussian p.d.f. that is constructed from the fit results covariance matrix. + // The error(x) is determined by calculating a central interval that capture N% of the variations + // for each valye of x, where N% is controlled by Z (i.e. Z=1 gives N=68%). The number of sampling curves + // is chosen to be such that at least 100 curves are expected to be outside the N% interval, and is minimally + // 100 (e.g. Z=1->Ncurve=356, Z=2->Ncurve=2156)) Intervals from the sampling method can be asymmetric, + // and may perform better in the presence of strong correlations, but may take (much) longer to calculate + model.plotOn(frame,VisualizeError(*r,1,kFALSE),DrawOption("L"),LineWidth(2),LineColor(kRed)) ; + + // Perform the same type of error visualization on the background component only. + // The VisualizeError() option can generally applied to _any_ kind of plot (components, asymmetries, efficiencies etc..) + model.plotOn(frame,VisualizeError(*r,1),FillColor(kOrange),Components("bkg")) ; + model.plotOn(frame,VisualizeError(*r,1,kFALSE),DrawOption("L"),LineWidth(2),LineColor(kRed),Components("bkg"),LineStyle(kDashed)) ; + + // Overlay central value + model.plotOn(frame) ; + model.plotOn(frame,Components("bkg"),LineStyle(kDashed)) ; + d->plotOn(frame) ; + frame->SetMinimum(0) ; + + + // V i s u a l i z e p a r t i a l f i t e r r o r + // ------------------------------------------------------ + + // Make plot frame + RooPlot* frame2 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from (m,m2)")) ; + + // Visualize partial error. For partial error visualization the covariance matrix is first reduced as follows + // ___ -1 + // Vred = V22 = V11 - V12 * V22 * V21 + // + // Where V11,V12,V21,V22 represent a block decomposition of the covariance matrix into observables that + // are propagated (labeled by index '1') and that are not propagated (labeled by index '2'), and V22bar + // is the Shur complement of V22, calculated as shown above + // + // (Note that Vred is _not_ a simple sub-matrix of V) + + // Propagate partial error due to shape parameters (m,m2) using linear and sampling method + model.plotOn(frame2,VisualizeError(*r,RooArgSet(m,m2),2),FillColor(kCyan)) ; + model.plotOn(frame2,Components("bkg"),VisualizeError(*r,RooArgSet(m,m2),2),FillColor(kCyan)) ; + + model.plotOn(frame2) ; + model.plotOn(frame2,Components("bkg"),LineStyle(kDashed)) ; + frame2->SetMinimum(0) ; + + + // Make plot frame + RooPlot* frame3 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from (s,s2)")) ; + + // Propagate partial error due to yield parameter using linear and sampling method + model.plotOn(frame3,VisualizeError(*r,RooArgSet(s,s2),2),FillColor(kGreen)) ; + model.plotOn(frame3,Components("bkg"),VisualizeError(*r,RooArgSet(s,s2),2),FillColor(kGreen)) ; + + model.plotOn(frame3) ; + model.plotOn(frame3,Components("bkg"),LineStyle(kDashed)) ; + frame3->SetMinimum(0) ; + + + // Make plot frame + RooPlot* frame4 = x.frame(Bins(40),Title("Visualization of 2-sigma partial error from fsig")) ; + + // Propagate partial error due to yield parameter using linear and sampling method + model.plotOn(frame4,VisualizeError(*r,RooArgSet(fsig),2),FillColor(kMagenta)) ; + model.plotOn(frame4,Components("bkg"),VisualizeError(*r,RooArgSet(fsig),2),FillColor(kMagenta)) ; + + model.plotOn(frame4) ; + model.plotOn(frame4,Components("bkg"),LineStyle(kDashed)) ; + frame4->SetMinimum(0) ; + + + + TCanvas* c = new TCanvas("rf610_visualerror","rf610_visualerror",800,800) ; + c->Divide(2,2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->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() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.6) ; frame4->Draw() ; +} diff --git a/cpp/rf701_efficiencyfit.C b/cpp/rf701_efficiencyfit.C new file mode 100644 index 0000000..1271f45 --- /dev/null +++ b/cpp/rf701_efficiencyfit.C @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #701 +// +// Unbinned maximum likelihood fit of an efficiency eff(x) function to +// a dataset D(x,cut), where cut is a category encoding a selection, of which +// the efficiency as function of x should be described by eff(x) +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooFormulaVar.h" +#include "RooProdPdf.h" +#include "RooEfficiency.h" +#include "RooPolynomial.h" +#include "RooCategory.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf701_efficiencyfit() +{ + // C o n s t r u c t e f f i c i e n c y f u n c t i o n e ( x ) + // ------------------------------------------------------------------- + + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + RooRealVar x("x","x",-10,10) ; + + // Efficiency function eff(x;a,b) + RooRealVar a("a","a",0.4,0,1) ; + RooRealVar b("b","b",5) ; + RooRealVar c("c","c",-1,-10,10) ; + RooFormulaVar effFunc("effFunc","(1-a)+a*cos((x-c)/b)",RooArgList(a,b,c,x)) ; + + + + // C o n s t r u c t c o n d i t i o n a l e f f i c i e n c y p d f E ( c u t | x ) + // ------------------------------------------------------------------------------------------ + + // Acceptance state cut (1 or 0) + RooCategory cut("cut","cutr") ; + cut.defineType("accept",1) ; + cut.defineType("reject",0) ; + + // Construct efficiency p.d.f eff(cut|x) + RooEfficiency effPdf("effPdf","effPdf",effFunc,cut,"accept") ; + + + + // G e n e r a t e d a t a ( x , c u t ) f r o m a t o y m o d e l + // ----------------------------------------------------------------------------- + + // Construct global shape p.d.f shape(x) and product model(x,cut) = eff(cut|x)*shape(x) + // (These are _only_ needed to generate some toy MC here to be used later) + RooPolynomial shapePdf("shapePdf","shapePdf",x,RooConst(-0.095)) ; + RooProdPdf model("model","model",shapePdf,Conditional(effPdf,cut)) ; + + // Generate some toy data from model + RooDataSet* data = model.generate(RooArgSet(x,cut),10000) ; + + + + // F i t c o n d i t i o n a l e f f i c i e n c y p d f t o d a t a + // -------------------------------------------------------------------------- + + // Fit conditional efficiency p.d.f to data + effPdf.fitTo(*data,ConditionalObservables(x)) ; + + + + // P l o t f i t t e d , d a t a e f f i c i e n c y + // -------------------------------------------------------- + + // Plot distribution of all events and accepted fraction of events on frame + RooPlot* frame1 = x.frame(Bins(20),Title("Data (all, accepted)")) ; + data->plotOn(frame1) ; + data->plotOn(frame1,Cut("cut==cut::accept"),MarkerColor(kRed),LineColor(kRed)) ; + + // Plot accept/reject efficiency on data overlay fitted efficiency curve + RooPlot* frame2 = x.frame(Bins(20),Title("Fitted efficiency")) ; + data->plotOn(frame2,Efficiency(cut)) ; // needs ROOT version >= 5.21 + effFunc.plotOn(frame2,LineColor(kRed)) ; + + + + // Draw all frames on a canvas + TCanvas* ca = new TCanvas("rf701_efficiency","rf701_efficiency",800,400) ; + ca->Divide(2) ; + ca->cd(1) ; gPad->SetLeftMargin(0.15) ; frame1->GetYaxis()->SetTitleOffset(1.6) ; frame1->Draw() ; + ca->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + + +} diff --git a/cpp/rf702_efficiencyfit_2D.C b/cpp/rf702_efficiencyfit_2D.C new file mode 100644 index 0000000..99c1794 --- /dev/null +++ b/cpp/rf702_efficiencyfit_2D.C @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #702 +// +// Unbinned maximum likelihood fit of an efficiency eff(x) function to +// a dataset D(x,cut), where cut is a category encoding a selection whose +// efficiency as function of x should be described by eff(x) +// +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooCategory.h" +#include "RooEfficiency.h" +#include "RooPolynomial.h" +#include "RooProdPdf.h" +#include "RooFormulaVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf702_efficiencyfit_2D(Bool_t flat=kFALSE) +{ + // C o n s t r u c t e f f i c i e n c y f u n c t i o n e ( x , y ) + // ----------------------------------------------------------------------- + + // Declare variables x,mean,sigma with associated name, title, initial value and allowed range + RooRealVar x("x","x",-10,10) ; + RooRealVar y("y","y",-10,10) ; + + // Efficiency function eff(x;a,b) + RooRealVar ax("ax","ay",0.6,0,1) ; + RooRealVar bx("bx","by",5) ; + RooRealVar cx("cx","cy",-1,-10,10) ; + + RooRealVar ay("ay","ay",0.2,0,1) ; + RooRealVar by("by","by",5) ; + RooRealVar cy("cy","cy",-1,-10,10) ; + + RooFormulaVar effFunc("effFunc","((1-ax)+ax*cos((x-cx)/bx))*((1-ay)+ay*cos((y-cy)/by))",RooArgList(ax,bx,cx,x,ay,by,cy,y)) ; + + // Acceptance state cut (1 or 0) + RooCategory cut("cut","cutr") ; + cut.defineType("accept",1) ; + cut.defineType("reject",0) ; + + + + // C o n s t r u c t c o n d i t i o n a l e f f i c i e n c y p d f E ( c u t | x , y ) + // --------------------------------------------------------------------------------------------- + + // Construct efficiency p.d.f eff(cut|x) + RooEfficiency effPdf("effPdf","effPdf",effFunc,cut,"accept") ; + + + + // G e n e r a t e d a t a ( x , y , c u t ) f r o m a t o y m o d e l + // ------------------------------------------------------------------------------- + + // Construct global shape p.d.f shape(x) and product model(x,cut) = eff(cut|x)*shape(x) + // (These are _only_ needed to generate some toy MC here to be used later) + RooPolynomial shapePdfX("shapePdfX","shapePdfX",x,RooConst(flat?0:-0.095)) ; + RooPolynomial shapePdfY("shapePdfY","shapePdfY",y,RooConst(flat?0:+0.095)) ; + RooProdPdf shapePdf("shapePdf","shapePdf",RooArgSet(shapePdfX,shapePdfY)) ; + RooProdPdf model("model","model",shapePdf,Conditional(effPdf,cut)) ; + + // Generate some toy data from model + RooDataSet* data = model.generate(RooArgSet(x,y,cut),10000) ; + + + + // F i t c o n d i t i o n a l e f f i c i e n c y p d f t o d a t a + // -------------------------------------------------------------------------- + + // Fit conditional efficiency p.d.f to data + effPdf.fitTo(*data,ConditionalObservables(RooArgSet(x,y))) ; + + + + // P l o t f i t t e d , d a t a e f f i c i e n c y + // -------------------------------------------------------- + + // Make 2D histograms of all data, selected data and efficiency function + TH1* hh_data_all = data->createHistogram("hh_data_all",x,Binning(8),YVar(y,Binning(8))) ; + TH1* hh_data_sel = data->createHistogram("hh_data_sel",x,Binning(8),YVar(y,Binning(8)),Cut("cut==cut::accept")) ; + TH1* hh_eff = effFunc.createHistogram("hh_eff",x,Binning(50),YVar(y,Binning(50))) ; + + // Some adjustsment for good visualization + hh_data_all->SetMinimum(0) ; + hh_data_sel->SetMinimum(0) ; + hh_eff->SetMinimum(0) ; + hh_eff->SetLineColor(kBlue) ; + + + + // Draw all frames on a canvas + TCanvas* ca = new TCanvas("rf702_efficiency_2D","rf702_efficiency_2D",1200,400) ; + ca->Divide(3) ; + ca->cd(1) ; gPad->SetLeftMargin(0.15) ; hh_data_all->GetZaxis()->SetTitleOffset(1.8) ; hh_data_all->Draw("lego") ; + ca->cd(2) ; gPad->SetLeftMargin(0.15) ; hh_data_sel->GetZaxis()->SetTitleOffset(1.8) ; hh_data_sel->Draw("lego") ; + ca->cd(3) ; gPad->SetLeftMargin(0.15) ; hh_eff->GetZaxis()->SetTitleOffset(1.8) ; hh_eff->Draw("surf") ; + + return ; + + +} diff --git a/cpp/rf703_effpdfprod.C b/cpp/rf703_effpdfprod.C new file mode 100644 index 0000000..b94915f --- /dev/null +++ b/cpp/rf703_effpdfprod.C @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #703 +// +// Using a product of an (acceptance) efficiency and a p.d.f as p.d.f. +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooExponential.h" +#include "RooEffProd.h" +#include "RooFormulaVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf703_effpdfprod() +{ + // D e f i n e o b s e r v a b l e s a n d d e c a y p d f + // --------------------------------------------------------------- + + // Declare observables + RooRealVar t("t","t",0,5) ; + + // Make pdf + RooRealVar tau("tau","tau",-1.54,-4,-0.1) ; + RooExponential model("model","model",t,tau) ; + + + + // D e f i n e e f f i c i e n c y f u n c t i o n + // --------------------------------------------------- + + // Use error function to simulate turn-on slope + RooFormulaVar eff("eff","0.5*(TMath::Erf((t-1)/0.5)+1)",t) ; + + + + // D e f i n e d e c a y p d f w i t h e f f i c i e n c y + // --------------------------------------------------------------- + + // Multiply pdf(t) with efficiency in t + RooEffProd modelEff("modelEff","model with efficiency",model,eff) ; + + + + // P l o t e f f i c i e n c y , p d f + // ---------------------------------------- + + RooPlot* frame1 = t.frame(Title("Efficiency")) ; + eff.plotOn(frame1,LineColor(kRed)) ; + + RooPlot* frame2 = t.frame(Title("Pdf with and without efficiency")) ; + + model.plotOn(frame2,LineStyle(kDashed)) ; + modelEff.plotOn(frame2) ; + + + + // G e n e r a t e t o y d a t a , f i t m o d e l E f f t o d a t a + // ------------------------------------------------------------------------------ + + // Generate events. If the input pdf has an internal generator, the internal generator + // is used and an accept/reject sampling on the efficiency is applied. + RooDataSet* data = modelEff.generate(t,10000) ; + + // Fit pdf. The normalization integral is calculated numerically. + modelEff.fitTo(*data) ; + + // Plot generated data and overlay fitted pdf + RooPlot* frame3 = t.frame(Title("Fitted pdf with efficiency")) ; + data->plotOn(frame3) ; + modelEff.plotOn(frame3) ; + + + TCanvas* c = new TCanvas("rf703_effpdfprod","rf703_effpdfprod",1200,400) ; + c->Divide(3) ; + 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.6) ; frame2->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.6) ; frame3->Draw() ; + +} diff --git a/cpp/rf704_amplitudefit.C b/cpp/rf704_amplitudefit.C new file mode 100644 index 0000000..00a7c2e --- /dev/null +++ b/cpp/rf704_amplitudefit.C @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #704 +// +// Using a p.d.f defined by a sum of real-valued amplitude components +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooTruthModel.h" +#include "RooFormulaVar.h" +#include "RooRealSumPdf.h" +#include "RooPolyVar.h" +#include "RooProduct.h" +#include "TH1.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf704_amplitudefit() +{ + // S e t u p 2 D a m p l i t u d e f u n c t i o n s + // ------------------------------------------------------- + + // Observables + RooRealVar t("t","time",-1.,15.); + RooRealVar cosa("cosa","cos(alpha)",-1.,1.); + + // Use RooTruthModel to obtain compiled implementation of sinh/cosh modulated decay functions + RooRealVar tau("tau","#tau",1.5); + RooRealVar deltaGamma("deltaGamma","deltaGamma", 0.3); + RooTruthModel tm("tm","tm",t) ; + RooFormulaVar coshGBasis("coshGBasis","exp(-@0/ @1)*cosh(@0*@2/2)",RooArgList(t,tau,deltaGamma)); + RooFormulaVar sinhGBasis("sinhGBasis","exp(-@0/ @1)*sinh(@0*@2/2)",RooArgList(t,tau,deltaGamma)); + RooAbsReal* coshGConv = tm.convolution(&coshGBasis,&t); + RooAbsReal* sinhGConv = tm.convolution(&sinhGBasis,&t); + + // Construct polynomial amplitudes in cos(a) + RooPolyVar poly1("poly1","poly1",cosa,RooArgList(RooConst(0.5),RooConst(0.2),RooConst(0.2)),0); + RooPolyVar poly2("poly2","poly2",cosa,RooArgList(RooConst(1),RooConst(-0.2),RooConst(3)),0); + + // Construct 2D amplitude as uncorrelated product of amp(t)*amp(cosa) + RooProduct ampl1("ampl1","amplitude 1",RooArgSet(poly1,*coshGConv)); + RooProduct ampl2("ampl2","amplitude 2",RooArgSet(poly2,*sinhGConv)); + + + + // C o n s t r u c t a m p l i t u d e s u m p d f + // ----------------------------------------------------- + + // Amplitude strengths + RooRealVar f1("f1","f1",1,0,2) ; + RooRealVar f2("f2","f2",0.5,0,2) ; + + // Construct pdf + RooRealSumPdf pdf("pdf","pdf",RooArgList(ampl1,ampl2),RooArgList(f1,f2)) ; + + // Generate some toy data from pdf + RooDataSet* data = pdf.generate(RooArgSet(t,cosa),10000); + + // Fit pdf to toy data with only amplitude strength floating + pdf.fitTo(*data) ; + + + + // P l o t a m p l i t u d e s u m p d f + // ------------------------------------------- + + // Make 2D plots of amplitudes + TH1* hh_cos = ampl1.createHistogram("hh_cos",t,Binning(50),YVar(cosa,Binning(50))) ; + TH1* hh_sin = ampl2.createHistogram("hh_sin",t,Binning(50),YVar(cosa,Binning(50))) ; + hh_cos->SetLineColor(kBlue) ; + hh_sin->SetLineColor(kRed) ; + + + // Make projection on t, plot data, pdf and its components + // Note component projections may be larger than sum because amplitudes can be negative + RooPlot* frame1 = t.frame(); + data->plotOn(frame1); + pdf.plotOn(frame1); + pdf.plotOn(frame1,Components(ampl1),LineStyle(kDashed)); + pdf.plotOn(frame1,Components(ampl2),LineStyle(kDashed),LineColor(kRed)); + + // Make projection on cosa, plot data, pdf and its components + // Note that components projection may be larger than sum because amplitudes can be negative + RooPlot* frame2 = cosa.frame(); + data->plotOn(frame2); + pdf.plotOn(frame2); + pdf.plotOn(frame2,Components(ampl1),LineStyle(kDashed)); + pdf.plotOn(frame2,Components(ampl2),LineStyle(kDashed),LineColor(kRed)); + + + + TCanvas* c = new TCanvas("rf704_amplitudefit","rf704_amplitudefit",800,800) ; + c->Divide(2,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(); + c->cd(3) ; gPad->SetLeftMargin(0.20) ; hh_cos->GetZaxis()->SetTitleOffset(2.3) ; hh_cos->Draw("surf") ; + c->cd(4) ; gPad->SetLeftMargin(0.20) ; hh_sin->GetZaxis()->SetTitleOffset(2.3) ; hh_sin->Draw("surf") ; + + +} diff --git a/cpp/rf705_linearmorph.C b/cpp/rf705_linearmorph.C new file mode 100644 index 0000000..b48a842 --- /dev/null +++ b/cpp/rf705_linearmorph.C @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #705 +// +// Linear interpolation between p.d.f shapes using the 'Alex Read' algorithm +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooIntegralMorph.h" +#include "RooNLLVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf705_linearmorph() +{ + // C r e a t e e n d p o i n t p d f s h a p e s + // ------------------------------------------------------ + + // Observable + RooRealVar x("x","x",-20,20) ; + + // Lower end point shape: a Gaussian + RooRealVar g1mean("g1mean","g1mean",-10) ; + RooGaussian g1("g1","g1",x,g1mean,RooConst(2)) ; + + // Upper end point shape: a Polynomial + RooPolynomial g2("g2","g2",x,RooArgSet(RooConst(-0.03),RooConst(-0.001))) ; + + + + // C r e a t e i n t e r p o l a t i n g p d f + // ----------------------------------------------- + + // Create interpolation variable + RooRealVar alpha("alpha","alpha",0,1.0) ; + + // Specify sampling density on observable and interpolation variable + x.setBins(1000,"cache") ; + alpha.setBins(50,"cache") ; + + // Construct interpolating pdf in (x,a) represent g1(x) at a=a_min + // and g2(x) at a=a_max + RooIntegralMorph lmorph("lmorph","lmorph",g1,g2,x,alpha) ; + + + + // P l o t i n t e r p o l a t i n g p d f a t v a r i o u s a l p h a + // ----------------------------------------------------------------------------- + + // Show end points as blue curves + RooPlot* frame1 = x.frame() ; + g1.plotOn(frame1) ; + g2.plotOn(frame1) ; + + // Show interpolated shapes in red + alpha.setVal(0.125) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.25) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.375) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.50) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.625) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.75) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.875) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + alpha.setVal(0.95) ; + lmorph.plotOn(frame1,LineColor(kRed)) ; + + + + // S h o w 2 D d i s t r i b u t i o n o f p d f ( x , a l p h a ) + // ----------------------------------------------------------------------- + + // Create 2D histogram + TH1* hh = lmorph.createHistogram("hh",x,Binning(40),YVar(alpha,Binning(40))) ; + hh->SetLineColor(kBlue) ; + + + // F i t p d f t o d a t a s e t w i t h a l p h a = 0 . 8 + // ----------------------------------------------------------------- + + // Generate a toy dataset at alpha = 0.8 + alpha=0.8 ; + RooDataSet* data = lmorph.generate(x,1000) ; + + // Fit pdf to toy data + lmorph.setCacheAlpha(kTRUE) ; + lmorph.fitTo(*data,Verbose(kTRUE)) ; + + // Plot fitted pdf and data overlaid + RooPlot* frame2 = x.frame(Bins(100)) ; + data->plotOn(frame2) ; + lmorph.plotOn(frame2) ; + + + // S c a n - l o g ( L ) v s a l p h a + // ----------------------------------------- + + // Show scan -log(L) of dataset w.r.t alpha + RooPlot* frame3 = alpha.frame(Bins(100),Range(0.1,0.9)) ; + + // Make 2D pdf of histogram + RooNLLVar nll("nll","nll",lmorph,*data) ; + nll.plotOn(frame3,ShiftToZero()) ; + + lmorph.setCacheAlpha(kFALSE) ; + + + + TCanvas* c = new TCanvas("rf705_linearmorph","rf705_linearmorph",800,800) ; + c->Divide(2,2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame1->GetYaxis()->SetTitleOffset(1.6) ; frame1->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.20) ; hh->GetZaxis()->SetTitleOffset(2.5) ; hh->Draw("surf") ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.4) ; frame3->Draw() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + + + return ; + +} diff --git a/cpp/rf706_histpdf.C b/cpp/rf706_histpdf.C new file mode 100644 index 0000000..4ed8f6b --- /dev/null +++ b/cpp/rf706_histpdf.C @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #706 +// +// Histogram based p.d.f.s and functions +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooHistPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf706_histpdf() +{ + // C r e a t e p d f f o r s a m p l i n g + // --------------------------------------------- + + RooRealVar x("x","x",0,20) ; + RooPolynomial p("p","p",x,RooArgList(RooConst(0.01),RooConst(-0.01),RooConst(0.0004))) ; + + + + // C r e a t e l o w s t a t s h i s t o g r a m + // --------------------------------------------------- + + // Sample 500 events from p + x.setBins(20) ; + RooDataSet* data1 = p.generate(x,500) ; + + // Create a binned dataset with 20 bins and 500 events + RooDataHist* hist1 = data1->binnedClone() ; + + // Represent data in dh as pdf in x + RooHistPdf histpdf1("histpdf1","histpdf1",x,*hist1,0) ; + + // Plot unbinned data and histogram pdf overlaid + RooPlot* frame1 = x.frame(Title("Low statistics histogram pdf"),Bins(100)) ; + data1->plotOn(frame1) ; + histpdf1.plotOn(frame1) ; + + + // C r e a t e h i g h s t a t s h i s t o g r a m + // ----------------------------------------------------- + + // Sample 100000 events from p + x.setBins(10) ; + RooDataSet* data2 = p.generate(x,100000) ; + + // Create a binned dataset with 10 bins and 100K events + RooDataHist* hist2 = data2->binnedClone() ; + + // Represent data in dh as pdf in x, apply 2nd order interpolation + RooHistPdf histpdf2("histpdf2","histpdf2",x,*hist2,2) ; + + // Plot unbinned data and histogram pdf overlaid + RooPlot* frame2 = x.frame(Title("High stats histogram pdf with interpolation"),Bins(100)) ; + data2->plotOn(frame2) ; + histpdf2.plotOn(frame2) ; + + + TCanvas* c = new TCanvas("rf706_histpdf","rf706_histpdf",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.8) ; frame2->Draw() ; + + +} diff --git a/cpp/rf707_kernelestimation.C b/cpp/rf707_kernelestimation.C new file mode 100644 index 0000000..abf5593 --- /dev/null +++ b/cpp/rf707_kernelestimation.C @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #707 +// +// Using non-parametric (multi-dimensional) kernel estimation p.d.f.s +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooKeysPdf.h" +#include "RooNDKeysPdf.h" +#include "RooProdPdf.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +#include "RooPlot.h" +using namespace RooFit ; + + +void rf707_kernelestimation() +{ + // C r e a t e l o w s t a t s 1 - D d a t a s e t + // ------------------------------------------------------- + + // Create a toy pdf for sampling + RooRealVar x("x","x",0,20) ; + RooPolynomial p("p","p",x,RooArgList(RooConst(0.01),RooConst(-0.01),RooConst(0.0004))) ; + + // Sample 500 events from p + RooDataSet* data1 = p.generate(x,200) ; + + + + // C r e a t e 1 - D k e r n e l e s t i m a t i o n p d f + // --------------------------------------------------------------- + + // Create adaptive kernel estimation pdf. In this configuration the input data + // is mirrored over the boundaries to minimize edge effects in distribution + // that do not fall to zero towards the edges + RooKeysPdf kest1("kest1","kest1",x,*data1,RooKeysPdf::MirrorBoth) ; + + // An adaptive kernel estimation pdf on the same data without mirroring option + // for comparison + RooKeysPdf kest2("kest2","kest2",x,*data1,RooKeysPdf::NoMirror) ; + + + // Adaptive kernel estimation pdf with increased bandwidth scale factor + // (promotes smoothness over detail preservation) + RooKeysPdf kest3("kest1","kest1",x,*data1,RooKeysPdf::MirrorBoth,2) ; + + + // Plot kernel estimation pdfs with and without mirroring over data + RooPlot* frame = x.frame(Title("Adaptive kernel estimation pdf with and w/o mirroring"),Bins(20)) ; + data1->plotOn(frame) ; + kest1.plotOn(frame) ; + kest2.plotOn(frame,LineStyle(kDashed),LineColor(kRed)) ; + + + // Plot kernel estimation pdfs with regular and increased bandwidth + RooPlot* frame2 = x.frame(Title("Adaptive kernel estimation pdf with regular, increased bandwidth")) ; + kest1.plotOn(frame2) ; + kest3.plotOn(frame2,LineColor(kMagenta)) ; + + + + // C r e a t e l o w s t a t s 2 - D d a t a s e t + // ------------------------------------------------------- + + // Construct a 2D toy pdf for sampleing + RooRealVar y("y","y",0,20) ; + RooPolynomial py("py","py",y,RooArgList(RooConst(0.01),RooConst(0.01),RooConst(-0.0004))) ; + RooProdPdf pxy("pxy","pxy",RooArgSet(p,py)) ; + RooDataSet* data2 = pxy.generate(RooArgSet(x,y),1000) ; + + + + // C r e a t e 2 - D k e r n e l e s t i m a t i o n p d f + // --------------------------------------------------------------- + + // Create 2D adaptive kernel estimation pdf with mirroring + RooNDKeysPdf kest4("kest4","kest4",RooArgSet(x,y),*data2,"am") ; + + // Create 2D adaptive kernel estimation pdf with mirroring and double bandwidth + RooNDKeysPdf kest5("kest5","kest5",RooArgSet(x,y),*data2,"am",2) ; + + // Create a histogram of the data + TH1* hh_data = data2->createHistogram("hh_data",x,Binning(10),YVar(y,Binning(10))) ; + + // Create histogram of the 2d kernel estimation pdfs + TH1* hh_pdf = kest4.createHistogram("hh_pdf",x,Binning(25),YVar(y,Binning(25))) ; + TH1* hh_pdf2 = kest5.createHistogram("hh_pdf2",x,Binning(25),YVar(y,Binning(25))) ; + hh_pdf->SetLineColor(kBlue) ; + hh_pdf2->SetLineColor(kMagenta) ; + + + + TCanvas* c = new TCanvas("rf707_kernelestimation","rf707_kernelestimation",800,800) ; + c->Divide(2,2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.8) ; frame2->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; hh_data->GetZaxis()->SetTitleOffset(1.4) ; hh_data->Draw("lego") ; + c->cd(4) ; gPad->SetLeftMargin(0.20) ; hh_pdf->GetZaxis()->SetTitleOffset(2.4) ; hh_pdf->Draw("surf") ; hh_pdf2->Draw("surfsame") ; + + +} diff --git a/cpp/rf708_bphysics.C b/cpp/rf708_bphysics.C new file mode 100644 index 0000000..1bfe610 --- /dev/null +++ b/cpp/rf708_bphysics.C @@ -0,0 +1,214 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'SPECIAL PDFS' RooFit tutorial macro #708 +// +// Special decay pdf for B physics with mixing and/or CP violation +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooCategory.h" +#include "RooBMixDecay.h" +#include "RooBCPEffDecay.h" +#include "RooBDecay.h" +#include "RooFormulaVar.h" +#include "RooTruthModel.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +using namespace RooFit ; + +void rf708_bphysics() +{ + //////////////////////////////////////////////////// + // B - D e c a y w i t h m i x i n g // + //////////////////////////////////////////////////// + + // C o n s t r u c t p d f + // ------------------------- + + // Observable + RooRealVar dt("dt","dt",-10,10) ; + dt.setBins(40) ; + + // Parameters + RooRealVar dm("dm","delta m(B0)",0.472) ; + RooRealVar tau("tau","tau (B0)",1.547) ; + RooRealVar w("w","flavour mistag rate",0.1) ; + RooRealVar dw("dw","delta mistag rate for B0/B0bar",0.1) ; + + RooCategory mixState("mixState","B0/B0bar mixing state") ; + mixState.defineType("mixed",-1) ; + mixState.defineType("unmixed",1) ; + + RooCategory tagFlav("tagFlav","Flavour of the tagged B0") ; + tagFlav.defineType("B0",1) ; + tagFlav.defineType("B0bar",-1) ; + + // Use delta function resolution model + RooTruthModel tm("tm","truth model",dt) ; + + // Construct Bdecay with mixing + RooBMixDecay bmix("bmix","decay",dt,mixState,tagFlav,tau,dm,w,dw,tm,RooBMixDecay::DoubleSided) ; + + + + // P l o t p d f i n v a r i o u s s l i c e s + // --------------------------------------------------- + + // Generate some data + RooDataSet* data = bmix.generate(RooArgSet(dt,mixState,tagFlav),10000) ; + + // Plot B0 and B0bar tagged data separately + // For all plots below B0 and B0 tagged data will look somewhat differently + // if the flavor tagging mistag rate for B0 and B0 is different (i.e. dw!=0) + RooPlot* frame1 = dt.frame(Title("B decay distribution with mixing (B0/B0bar)")) ; + + data->plotOn(frame1,Cut("tagFlav==tagFlav::B0")) ; + bmix.plotOn(frame1,Slice(tagFlav,"B0")) ; + + data->plotOn(frame1,Cut("tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bmix.plotOn(frame1,Slice(tagFlav,"B0bar"),LineColor(kCyan)) ; + + + // Plot mixed slice for B0 and B0bar tagged data separately + RooPlot* frame2 = dt.frame(Title("B decay distribution of mixed events (B0/B0bar)")) ; + + data->plotOn(frame2,Cut("mixState==mixState::mixed&&tagFlav==tagFlav::B0")) ; + bmix.plotOn(frame2,Slice(tagFlav,"B0"),Slice(mixState,"mixed")) ; + + data->plotOn(frame2,Cut("mixState==mixState::mixed&&tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bmix.plotOn(frame2,Slice(tagFlav,"B0bar"),Slice(mixState,"mixed"),LineColor(kCyan)) ; + + + // Plot unmixed slice for B0 and B0bar tagged data separately + RooPlot* frame3 = dt.frame(Title("B decay distribution of unmixed events (B0/B0bar)")) ; + + data->plotOn(frame3,Cut("mixState==mixState::unmixed&&tagFlav==tagFlav::B0")) ; + bmix.plotOn(frame3,Slice(tagFlav,"B0"),Slice(mixState,"unmixed")) ; + + data->plotOn(frame3,Cut("mixState==mixState::unmixed&&tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bmix.plotOn(frame3,Slice(tagFlav,"B0bar"),Slice(mixState,"unmixed"),LineColor(kCyan)) ; + + + + + + /////////////////////////////////////////////////////// + // B - D e c a y w i t h C P v i o l a t i o n // + /////////////////////////////////////////////////////// + + // C o n s t r u c t p d f + // ------------------------- + + // Additional parameters needed for B decay with CPV + RooRealVar CPeigen("CPeigen","CP eigen value",-1) ; + RooRealVar absLambda("absLambda","|lambda|",1,0,2) ; + RooRealVar argLambda("absLambda","|lambda|",0.7,-1,1) ; + RooRealVar effR("effR","B0/B0bar reco efficiency ratio",1) ; + + // Construct Bdecay with CP violation + RooBCPEffDecay bcp("bcp","bcp", dt, tagFlav, tau, dm, w, CPeigen, absLambda, argLambda, effR, dw, tm, RooBCPEffDecay::DoubleSided) ; + + + + // P l o t s c e n a r i o 1 - s i n ( 2 b ) = 0 . 7 , | l | = 1 + // --------------------------------------------------------------------------- + + // Generate some data + RooDataSet* data2 = bcp.generate(RooArgSet(dt,tagFlav),10000) ; + + // Plot B0 and B0bar tagged data separately + RooPlot* frame4 = dt.frame(Title("B decay distribution with CPV(|l|=1,Im(l)=0.7) (B0/B0bar)")) ; + + data2->plotOn(frame4,Cut("tagFlav==tagFlav::B0")) ; + bcp.plotOn(frame4,Slice(tagFlav,"B0")) ; + + data2->plotOn(frame4,Cut("tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bcp.plotOn(frame4,Slice(tagFlav,"B0bar"),LineColor(kCyan)) ; + + + + // P l o t s c e n a r i o 2 - s i n ( 2 b ) = 0 . 7 , | l | = 0 . 7 + // ------------------------------------------------------------------------------- + + absLambda=0.7 ; + + // Generate some data + RooDataSet* data3 = bcp.generate(RooArgSet(dt,tagFlav),10000) ; + + // Plot B0 and B0bar tagged data separately (sin2b = 0.7 plus direct CPV |l|=0.5) + RooPlot* frame5 = dt.frame(Title("B decay distribution with CPV(|l|=0.7,Im(l)=0.7) (B0/B0bar)")) ; + + data3->plotOn(frame5,Cut("tagFlav==tagFlav::B0")) ; + bcp.plotOn(frame5,Slice(tagFlav,"B0")) ; + + data3->plotOn(frame5,Cut("tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bcp.plotOn(frame5,Slice(tagFlav,"B0bar"),LineColor(kCyan)) ; + + + + ////////////////////////////////////////////////////////////////////////////////// + // G e n e r i c B d e c a y w i t h u s e r c o e f f i c i e n t s // + ////////////////////////////////////////////////////////////////////////////////// + + // C o n s t r u c t p d f + // ------------------------- + + // Model parameters + RooRealVar DGbG("DGbG","DGamma/GammaAvg",0.5,-1,1); + RooRealVar Adir("Adir","-[1-abs(l)**2]/[1+abs(l)**2]",0); + RooRealVar Amix("Amix","2Im(l)/[1+abs(l)**2]",0.7); + RooRealVar Adel("Adel","2Re(l)/[1+abs(l)**2]",0.7); + + // Derived input parameters for pdf + RooFormulaVar DG("DG","Delta Gamma","@1/@0",RooArgList(tau,DGbG)); + + // Construct coefficient functions for sin,cos,sinh modulations of decay distribution + RooFormulaVar fsin("fsin","fsin","@0*@1*(1-2*@2)",RooArgList(Amix,tagFlav,w)); + RooFormulaVar fcos("fcos","fcos","@0*@1*(1-2*@2)",RooArgList(Adir,tagFlav,w)); + RooFormulaVar fsinh("fsinh","fsinh","@0",RooArgList(Adel)); + + // Construct generic B decay pdf using above user coefficients + RooBDecay bcpg("bcpg","bcpg",dt,tau,DG,RooConst(1),fsinh,fcos,fsin,dm,tm,RooBDecay::DoubleSided); + + + + // P l o t - I m ( l ) = 0 . 7 , R e ( l ) = 0 . 7 | l | = 1, d G / G = 0 . 5 + // ------------------------------------------------------------------------------------- + + // Generate some data + RooDataSet* data4 = bcpg.generate(RooArgSet(dt,tagFlav),10000) ; + + // Plot B0 and B0bar tagged data separately + RooPlot* frame6 = dt.frame(Title("B decay distribution with CPV(Im(l)=0.7,Re(l)=0.7,|l|=1,dG/G=0.5) (B0/B0bar)")) ; + + data4->plotOn(frame6,Cut("tagFlav==tagFlav::B0")) ; + bcpg.plotOn(frame6,Slice(tagFlav,"B0")) ; + + data4->plotOn(frame6,Cut("tagFlav==tagFlav::B0bar"),MarkerColor(kCyan)) ; + bcpg.plotOn(frame6,Slice(tagFlav,"B0bar"),LineColor(kCyan)) ; + + + + + TCanvas* c = new TCanvas("rf708_bphysics","rf708_bphysics",1200,800) ; + c->Divide(3,2) ; + 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() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.6) ; frame4->Draw() ; + c->cd(5) ; gPad->SetLeftMargin(0.15) ; frame5->GetYaxis()->SetTitleOffset(1.6) ; frame5->Draw() ; + c->cd(6) ; gPad->SetLeftMargin(0.15) ; frame6->GetYaxis()->SetTitleOffset(1.6) ; frame6->Draw() ; + +} diff --git a/cpp/rf801_mcstudy.C b/cpp/rf801_mcstudy.C new file mode 100644 index 0000000..e3a58ff --- /dev/null +++ b/cpp/rf801_mcstudy.C @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'VALIDATION AND MC STUDIES' RooFit tutorial macro #801 +// +// A Toy Monte Carlo study that perform cycles of +// event generation and fittting +// +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooMCStudy.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH2.h" +#include "RooFitResult.h" +#include "TStyle.h" +#include "TDirectory.h" + +using namespace RooFit ; + + +void rf801_mcstudy() +{ + // C r e a t e m o d e l + // ----------------------- + + // Declare observable x + RooRealVar x("x","x",0,10) ; + x.setBins(40) ; + + // Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters + RooRealVar mean("mean","mean of gaussians",5,0,10) ; + RooRealVar sigma1("sigma1","width of gaussians",0.5) ; + RooRealVar sigma2("sigma2","width of gaussians",1) ; + + RooGaussian sig1("sig1","Signal component 1",x,mean,sigma1) ; + RooGaussian sig2("sig2","Signal component 2",x,mean,sigma2) ; + + // Build Chebychev polynomial p.d.f. + RooRealVar a0("a0","a0",0.5,0.,1.) ; + RooRealVar a1("a1","a1",-0.2,-1,1.) ; + RooChebychev bkg("bkg","Background",x,RooArgSet(a0,a1)) ; + + // Sum the signal components into a composite signal p.d.f. + RooRealVar sig1frac("sig1frac","fraction of component 1 in signal",0.8,0.,1.) ; + RooAddPdf sig("sig","Signal",RooArgList(sig1,sig2),sig1frac) ; + + // Sum the composite signal and background + RooRealVar nbkg("nbkg","number of background events,",150,0,1000) ; + RooRealVar nsig("nsig","number of signal events",150,0,1000) ; + RooAddPdf model("model","g1+g2+a",RooArgList(bkg,sig),RooArgList(nbkg,nsig)) ; + + + + // C r e a t e m a n a g e r + // --------------------------- + + // Instantiate RooMCStudy manager on model with x as observable and given choice of fit options + // + // The Silence() option kills all messages below the PROGRESS level, leaving only a single message + // per sample executed, and any error message that occur during fitting + // + // The Extended() option has two effects: + // 1) The extended ML term is included in the likelihood and + // 2) A poisson fluctuation is introduced on the number of generated events + // + // The FitOptions() given here are passed to the fitting stage of each toy experiment. + // If Save() is specified, the fit result of each experiment is saved by the manager + // + // A Binned() option is added in this example to bin the data between generation and fitting + // to speed up the study at the expemse of some precision + + RooMCStudy* mcstudy = new RooMCStudy(model,x,Binned(kTRUE),Silence(),Extended(), + FitOptions(Save(kTRUE),PrintEvalErrors(0))) ; + + + // G e n e r a t e a n d f i t e v e n t s + // --------------------------------------------- + + // Generate and fit 1000 samples of Poisson(nExpected) events + mcstudy->generateAndFit(1000) ; + + + + // E x p l o r e r e s u l t s o f s t u d y + // ------------------------------------------------ + + // Make plots of the distributions of mean, the error on mean and the pull of mean + RooPlot* frame1 = mcstudy->plotParam(mean,Bins(40)) ; + RooPlot* frame2 = mcstudy->plotError(mean,Bins(40)) ; + RooPlot* frame3 = mcstudy->plotPull(mean,Bins(40),FitGauss(kTRUE)) ; + + // Plot distribution of minimized likelihood + RooPlot* frame4 = mcstudy->plotNLL(Bins(40)) ; + + // Make some histograms from the parameter dataset + TH1* hh_cor_a0_s1f = mcstudy->fitParDataSet().createHistogram("hh",a1,YVar(sig1frac)) ; + TH1* hh_cor_a0_a1 = mcstudy->fitParDataSet().createHistogram("hh",a0,YVar(a1)) ; + + // Access some of the saved fit results from individual toys + TH2* corrHist000 = mcstudy->fitResult(0)->correlationHist("c000") ; + TH2* corrHist127 = mcstudy->fitResult(127)->correlationHist("c127") ; + TH2* corrHist953 = mcstudy->fitResult(953)->correlationHist("c953") ; + + + + // Draw all plots on a canvas + gStyle->SetPalette(1) ; + gStyle->SetOptStat(0) ; + TCanvas* c = new TCanvas("rf801_mcstudy","rf801_mcstudy",900,900) ; + c->Divide(3,3) ; + 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() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.4) ; frame3->Draw() ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; frame4->GetYaxis()->SetTitleOffset(1.4) ; frame4->Draw() ; + c->cd(5) ; gPad->SetLeftMargin(0.15) ; hh_cor_a0_s1f->GetYaxis()->SetTitleOffset(1.4) ; hh_cor_a0_s1f->Draw("box") ; + c->cd(6) ; gPad->SetLeftMargin(0.15) ; hh_cor_a0_a1->GetYaxis()->SetTitleOffset(1.4) ; hh_cor_a0_a1->Draw("box") ; + c->cd(7) ; gPad->SetLeftMargin(0.15) ; corrHist000->GetYaxis()->SetTitleOffset(1.4) ; corrHist000->Draw("colz") ; + c->cd(8) ; gPad->SetLeftMargin(0.15) ; corrHist127->GetYaxis()->SetTitleOffset(1.4) ; corrHist127->Draw("colz") ; + c->cd(9) ; gPad->SetLeftMargin(0.15) ; corrHist953->GetYaxis()->SetTitleOffset(1.4) ; corrHist953->Draw("colz") ; + + // Make RooMCStudy object available on command line after + // macro finishes + gDirectory->Add(mcstudy) ; +} diff --git a/cpp/rf802_mcstudy_addons.C b/cpp/rf802_mcstudy_addons.C new file mode 100644 index 0000000..d1afe5b --- /dev/null +++ b/cpp/rf802_mcstudy_addons.C @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'VALIDATION AND MC STUDIES' RooFit tutorial macro #802 +// +// RooMCStudy: using separate fit and generator models, using the chi^2 calculator model +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooMCStudy.h" +#include "RooChi2MCSModule.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +#include "TDirectory.h" + +using namespace RooFit ; + + +void rf802_mcstudy_addons() +{ + + // C r e a t e m o d e l + // ----------------------- + + // Observables, parameters + RooRealVar x("x","x",-10,10) ; + x.setBins(10) ; + RooRealVar mean("mean","mean of gaussian",0) ; + RooRealVar sigma("sigma","width of gaussian",5,1,10) ; + + // Create Gaussian pdf + RooGaussian gauss("gauss","gaussian PDF",x,mean,sigma) ; + + + + // C r e a t e m a n a g e r w i t h c h i ^ 2 a d d - o n m o d u l e + // ---------------------------------------------------------------------------- + + // Create study manager for binned likelihood fits of a Gaussian pdf in 10 bins + RooMCStudy* mcs = new RooMCStudy(gauss,x,Silence(),Binned()) ; + + // Add chi^2 calculator module to mcs + RooChi2MCSModule chi2mod ; + mcs->addModule(chi2mod) ; + + // Generate 1000 samples of 1000 events + mcs->generateAndFit(2000,1000) ; + + // Fill histograms with distributions chi2 and prob(chi2,ndf) that + // are calculated by RooChiMCSModule + TH1* hist_chi2 = mcs->fitParDataSet().createHistogram("chi2") ; + TH1* hist_prob = mcs->fitParDataSet().createHistogram("prob") ; + + + + // C r e a t e m a n a g e r w i t h s e p a r a t e f i t m o d e l + // ---------------------------------------------------------------------------- + + // Create alternate pdf with shifted mean + RooRealVar mean2("mean2","mean of gaussian 2",0.5) ; + RooGaussian gauss2("gauss2","gaussian PDF2",x,mean2,sigma) ; + + // Create study manager with separate generation and fit model. This configuration + // is set up to generate bad fits as the fit and generator model have different means + // and the mean parameter is not floating in the fit + RooMCStudy* mcs2 = new RooMCStudy(gauss2,x,FitModel(gauss),Silence(),Binned()) ; + + // Add chi^2 calculator module to mcs + RooChi2MCSModule chi2mod2 ; + mcs2->addModule(chi2mod2) ; + + // Generate 1000 samples of 1000 events + mcs2->generateAndFit(2000,1000) ; + + // Fill histograms with distributions chi2 and prob(chi2,ndf) that + // are calculated by RooChiMCSModule + TH1* hist2_chi2 = mcs2->fitParDataSet().createHistogram("chi2") ; + TH1* hist2_prob = mcs2->fitParDataSet().createHistogram("prob") ; + hist2_chi2->SetLineColor(kRed) ; + hist2_prob->SetLineColor(kRed) ; + + + + TCanvas* c = new TCanvas("rf802_mcstudy_addons","rf802_mcstudy_addons",800,400) ; + c->Divide(2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; hist_chi2->GetYaxis()->SetTitleOffset(1.4) ; hist_chi2->Draw() ; hist2_chi2->Draw("esame") ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; hist_prob->GetYaxis()->SetTitleOffset(1.4) ; hist_prob->Draw() ; hist2_prob->Draw("esame") ; + + + + // Make RooMCStudy object available on command line after + // macro finishes + gDirectory->Add(mcs) ; +} diff --git a/cpp/rf803_mcstudy_addons2.C b/cpp/rf803_mcstudy_addons2.C new file mode 100644 index 0000000..af36a0f --- /dev/null +++ b/cpp/rf803_mcstudy_addons2.C @@ -0,0 +1,131 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'VALIDATION AND MC STUDIES' RooFit tutorial macro #803 +// +// RooMCStudy: Using the randomizer and profile likelihood add-on models +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "RooAddPdf.h" +#include "RooMCStudy.h" +#include "RooRandomizeParamMCSModule.h" +#include "RooDLLSignificanceMCSModule.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +#include "TDirectory.h" + +using namespace RooFit ; + + +void rf803_mcstudy_addons2() +{ + // C r e a t e m o d e l + // ----------------------- + + // Simulation of signal and background of top quark decaying into + // 3 jets with background + + // Observable + RooRealVar mjjj("mjjj","m(3jet) (GeV)",100,85.,350.) ; + + // Signal component (Gaussian) + RooRealVar mtop("mtop","m(top)",162) ; + RooRealVar wtop("wtop","m(top) resolution",15.2) ; + RooGaussian sig("sig","top signal",mjjj,mtop,wtop) ; + + // Background component (Chebychev) + RooRealVar c0("c0","Chebychev coefficient 0",-0.846,-1.,1.) ; + RooRealVar c1("c1","Chebychev coefficient 1", 0.112,-1.,1.) ; + RooRealVar c2("c2","Chebychev coefficient 2", 0.076,-1.,1.) ; + RooChebychev bkg("bkg","combinatorial background",mjjj,RooArgList(c0,c1,c2)) ; + + // Composite model + RooRealVar nsig("nsig","number of signal events",53,0,1e3) ; + RooRealVar nbkg("nbkg","number of background events",103,0,5e3) ; + RooAddPdf model("model","model",RooArgList(sig,bkg),RooArgList(nsig,nbkg)) ; + + + + // C r e a t e m a n a g e r + // --------------------------- + + // Configure manager to perform binned extended likelihood fits (Binned(),Extended()) on data generated + // with a Poisson fluctuation on Nobs (Extended()) + RooMCStudy* mcs = new RooMCStudy(model,mjjj,Binned(),Silence(),Extended(kTRUE), + FitOptions(Extended(kTRUE),PrintEvalErrors(-1))) ; + + + + // C u s t o m i z e m a n a g e r + // --------------------------------- + + // Add module that randomizes the summed value of nsig+nbkg + // sampling from a uniform distribution between 0 and 1000 + // + // In general one can randomize a single parameter, or a + // sum of N parameters, using either a uniform or a Gaussian + // distribution. Multiple randomization can be executed + // by a single randomizer module + + RooRandomizeParamMCSModule randModule ; + randModule.sampleSumUniform(RooArgSet(nsig,nbkg),50,500) ; + mcs->addModule(randModule) ; + + + // Add profile likelihood calculation of significance. Redo each + // fit while keeping parameter nsig fixed to zero. For each toy, + // the difference in -log(L) of both fits is stored, as well + // a simple significance interpretation of the delta(-logL) + // using Dnll = 0.5 sigma^2 + + RooDLLSignificanceMCSModule sigModule(nsig,0) ; + mcs->addModule(sigModule) ; + + + + // R u n m a n a g e r , m a k e p l o t s + // --------------------------------------------- + + // Run 1000 experiments. This configuration will generate a fair number + // of (harmless) MINUIT warnings due to the instability of the Chebychev polynomial fit + // at low statistics. + mcs->generateAndFit(500) ; + + // Make some plots + TH1* dll_vs_ngen = mcs->fitParDataSet().createHistogram("ngen,dll_nullhypo_nsig",-40,-40) ; + TH1* z_vs_ngen = mcs->fitParDataSet().createHistogram("ngen,significance_nullhypo_nsig",-40,-40) ; + TH1* errnsig_vs_ngen = mcs->fitParDataSet().createHistogram("ngen,nsigerr",-40,-40) ; + TH1* errnsig_vs_nsig = mcs->fitParDataSet().createHistogram("nsig,nsigerr",-40,-40) ; + + + // Draw plots on canvas + TCanvas* c = new TCanvas("rf803_mcstudy_addons2","rf802_mcstudy_addons2",800,800) ; + c->Divide(2,2) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; dll_vs_ngen->GetYaxis()->SetTitleOffset(1.6) ; dll_vs_ngen->Draw("box") ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; z_vs_ngen->GetYaxis()->SetTitleOffset(1.6) ; z_vs_ngen->Draw("box") ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; errnsig_vs_ngen->GetYaxis()->SetTitleOffset(1.6) ; errnsig_vs_ngen->Draw("box") ; + c->cd(4) ; gPad->SetLeftMargin(0.15) ; errnsig_vs_nsig->GetYaxis()->SetTitleOffset(1.6) ; errnsig_vs_nsig->Draw("box") ; + + + // Make RooMCStudy object available on command line after + // macro finishes + gDirectory->Add(mcs) ; + +} + + + + diff --git a/cpp/rf804_mcstudy_constr.C b/cpp/rf804_mcstudy_constr.C new file mode 100644 index 0000000..c67e526 --- /dev/null +++ b/cpp/rf804_mcstudy_constr.C @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////// +// +// 'VALIDATION AND MC STUDIES' RooFit tutorial macro #804 +// +// Using RooMCStudy on models with constrains +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "RooPolynomial.h" +#include "RooAddPdf.h" +#include "RooProdPdf.h" +#include "RooMCStudy.h" +#include "RooPlot.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "TH1.h" +using namespace RooFit ; + + +void rf804_mcstudy_constr() +{ + // C r e a t e m o d e l w i t h p a r a m e t e r c o n s t r a i n t + // --------------------------------------------------------------------------- + + // Observable + RooRealVar x("x","x",-10,10) ; + + // Signal component + RooRealVar m("m","m",0,-10,10) ; + RooRealVar s("s","s",2,0.1,10) ; + RooGaussian g("g","g",x,m,s) ; + + // Background component + RooPolynomial p("p","p",x) ; + + // Composite model + RooRealVar f("f","f",0.4,0.,1.) ; + RooAddPdf sum("sum","sum",RooArgSet(g,p),f) ; + + // Construct constraint on parameter f + RooGaussian fconstraint("fconstraint","fconstraint",f,RooConst(0.7),RooConst(0.1)) ; + + // Multiply constraint with p.d.f + RooProdPdf sumc("sumc","sum with constraint",RooArgSet(sum,fconstraint)) ; + + + + // S e t u p t o y s t u d y w i t h m o d e l + // --------------------------------------------------- + + // Perform toy study with internal constraint on f + RooMCStudy mcs(sumc,x,Constrain(f),Silence(),Binned(),FitOptions(PrintLevel(-1))) ; + + // Run 500 toys of 2000 events. + // Before each toy is generated, a value for the f is sampled from the constraint pdf and + // that value is used for the generation of that toy. + mcs.generateAndFit(500,2000) ; + + // Make plot of distribution of generated value of f parameter + TH1* h_f_gen = mcs.fitParDataSet().createHistogram("f_gen",-40) ; + + // Make plot of distribution of fitted value of f parameter + RooPlot* frame1 = mcs.plotParam(f,Bins(40)) ; + frame1->SetTitle("Distribution of fitted f values") ; + + // Make plot of pull distribution on f + RooPlot* frame2 = mcs.plotPull(f,Bins(40),FitGauss()) ; + frame1->SetTitle("Distribution of f pull values") ; + + + + TCanvas* c = new TCanvas("rf804_mcstudy_constr","rf804_mcstudy_constr",1200,400) ; + c->Divide(3) ; + c->cd(1) ; gPad->SetLeftMargin(0.15) ; h_f_gen->GetYaxis()->SetTitleOffset(1.4) ; h_f_gen->Draw() ; + c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame1->GetYaxis()->SetTitleOffset(1.4) ; frame1->Draw() ; + c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; + +} + diff --git a/cpp/rf901_numintconfig.C b/cpp/rf901_numintconfig.C new file mode 100644 index 0000000..0f00385 --- /dev/null +++ b/cpp/rf901_numintconfig.C @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'NUMERIC ALGORITHM TUNING' RooFit tutorial macro #901 +// +// Configuration and customization of how numeric (partial) integrals +// are executed +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooNumIntConfig.h" +#include "RooLandau.h" +#include "RooArgSet.h" +#include +using namespace RooFit ; + + +void rf901_numintconfig() +{ + + // A d j u s t g l o b a l 1 D i n t e g r a t i o n p r e c i s i o n + // ---------------------------------------------------------------------------- + + // Print current global default configuration for numeric integration strategies + RooAbsReal::defaultIntegratorConfig()->Print("v") ; + + // Example: Change global precision for 1D integrals from 1e-7 to 1e-6 + // + // The relative epsilon (change as fraction of current best integral estimate) and + // absolute epsilon (absolute change w.r.t last best integral estimate) can be specified + // separately. For most p.d.f integrals the relative change criterium is the most important, + // however for certain non-p.d.f functions that integrate out to zero a separate absolute + // change criterium is necessary to declare convergence of the integral + // + // NB: This change is for illustration only. In general the precision should be at least 1e-7 + // for normalization integrals for MINUIT to succeed. + // + RooAbsReal::defaultIntegratorConfig()->setEpsAbs(1e-6) ; + RooAbsReal::defaultIntegratorConfig()->setEpsRel(1e-6) ; + + + // N u m e r i c i n t e g r a t i o n o f l a n d a u p d f + // ------------------------------------------------------------------ + + // Construct p.d.f without support for analytical integrator for demonstration purposes + RooRealVar x("x","x",-10,10) ; + RooLandau landau("landau","landau",x,RooConst(0),RooConst(0.1)) ; + + + // Activate debug-level messages for topic integration to be able to follow actions below + RooMsgService::instance().addStream(DEBUG,Topic(Integration)) ; + + + // Calculate integral over landau with default choice of numeric integrator + RooAbsReal* intLandau = landau.createIntegral(x) ; + Double_t val = intLandau->getVal() ; + cout << " [1] int_dx landau(x) = " << setprecision(15) << val << endl ; + + + + // S a m e w i t h c u s t o m c o n f i g u r a t i o n + // ----------------------------------------------------------- + + + // Construct a custom configuration which uses the adaptive Gauss-Kronrod technique + // for closed 1D integrals + RooNumIntConfig customConfig(*RooAbsReal::defaultIntegratorConfig()) ; + customConfig.method1D().setLabel("RooAdaptiveGaussKronrodIntegrator1D") ; + + + // Calculate integral over landau with custom integral specification + RooAbsReal* intLandau2 = landau.createIntegral(x,NumIntConfig(customConfig)) ; + Double_t val2 = intLandau2->getVal() ; + cout << " [2] int_dx landau(x) = " << val2 << endl ; + + + + // A d j u s t i n g d e f a u l t c o n f i g f o r a s p e c i f i c p d f + // ------------------------------------------------------------------------------------- + + + // Another possibility: associate custom numeric integration configuration as default for object 'landau' + landau.setIntegratorConfig(customConfig) ; + + + // Calculate integral over landau custom numeric integrator specified as object default + RooAbsReal* intLandau3 = landau.createIntegral(x) ; + Double_t val3 = intLandau3->getVal() ; + cout << " [3] int_dx landau(x) = " << val3 << endl ; + + + // Another possibility: Change global default for 1D numeric integration strategy on finite domains + RooAbsReal::defaultIntegratorConfig()->method1D().setLabel("RooAdaptiveGaussKronrodIntegrator1D") ; + + + + // A d j u s t i n g p a r a m e t e r s o f a s p e c i f i c t e c h n i q u e + // --------------------------------------------------------------------------------------- + + // Adjust maximum number of steps of RooIntegrator1D in the global default configuration + RooAbsReal::defaultIntegratorConfig()->getConfigSection("RooIntegrator1D").setRealValue("maxSteps",30) ; + + + // Example of how to change the parameters of a numeric integrator + // (Each config section is a RooArgSet with RooRealVars holding real-valued parameters + // and RooCategories holding parameters with a finite set of options) + customConfig.getConfigSection("RooAdaptiveGaussKronrodIntegrator1D").setRealValue("maxSeg",50) ; + customConfig.getConfigSection("RooAdaptiveGaussKronrodIntegrator1D").setCatLabel("method","15Points") ; + + + // Example of how to print set of possible values for "method" category + customConfig.getConfigSection("RooAdaptiveGaussKronrodIntegrator1D").find("method")->Print("v") ; + +} diff --git a/cpp/rf902_numgenconfig.C b/cpp/rf902_numgenconfig.C new file mode 100644 index 0000000..e8a8224 --- /dev/null +++ b/cpp/rf902_numgenconfig.C @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'NUMERIC ALGORITHM TUNING' RooFit tutorial macro #902 +// +// Configuration and customization of how MC sampling algorithms +// on specific p.d.f.s are executed +// +// +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooConstVar.h" +#include "RooChebychev.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooNumGenConfig.h" +#include "RooArgSet.h" +#include +using namespace RooFit ; + + +void rf902_numgenconfig() +{ + + // A d j u s t g l o b a l MC s a m p l i n g s t r a t e g y + // ------------------------------------------------------------------ + + // Example p.d.f. for use below + RooRealVar x("x","x",0,10) ; + RooChebychev model("model","model",x,RooArgList(RooConst(0),RooConst(0.5),RooConst(-0.1))) ; + + + // Change global strategy for 1D sampling problems without conditional observable + // (1st kFALSE) and without discrete observable (2nd kFALSE) from RooFoamGenerator, + // ( an interface to the TFoam MC generator with adaptive subdivisioning strategy ) to RooAcceptReject, + // a plain accept/reject sampling algorithm [ RooFit default before ROOT 5.23/04 ] + RooAbsPdf::defaultGeneratorConfig()->method1D(kFALSE,kFALSE).setLabel("RooAcceptReject") ; + + // Generate 10Kevt using RooAcceptReject + RooDataSet* data_ar = model.generate(x,10000,Verbose(kTRUE)) ; + data_ar->Print() ; + + + // A d j u s t i n g d e f a u l t c o n f i g f o r a s p e c i f i c p d f + // ------------------------------------------------------------------------------------- + + // Another possibility: associate custom MC sampling configuration as default for object 'model' + // The kTRUE argument will install a clone of the default configuration as specialized configuration + // for this model if none existed so far + model.specialGeneratorConfig(kTRUE)->method1D(kFALSE,kFALSE).setLabel("RooFoamGenerator") ; + + + // A d j u s t i n g p a r a m e t e r s o f a s p e c i f i c t e c h n i q u e + // --------------------------------------------------------------------------------------- + + // Adjust maximum number of steps of RooIntegrator1D in the global default configuration + RooAbsPdf::defaultGeneratorConfig()->getConfigSection("RooAcceptReject").setRealValue("nTrial1D",2000) ; + + + // Example of how to change the parameters of a numeric integrator + // (Each config section is a RooArgSet with RooRealVars holding real-valued parameters + // and RooCategories holding parameters with a finite set of options) + model.specialGeneratorConfig()->getConfigSection("RooFoamGenerator").setRealValue("chatLevel",1) ; + + // Generate 10Kevt using RooFoamGenerator (FOAM verbosity increased with above chatLevel adjustment for illustration purposes) + RooDataSet* data_foam = model.generate(x,10000,Verbose()) ; + data_foam->Print() ; + + +} diff --git a/cpp/rf903_numintcache.C b/cpp/rf903_numintcache.C new file mode 100644 index 0000000..2ef2f0c --- /dev/null +++ b/cpp/rf903_numintcache.C @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// +// 'NUMERIC ALGORITHM TUNING' RooFit tutorial macro #903 +// +// Caching of slow numeric integrals and parameterizations of slow +// numeric integrals +// +// 07/2008 - Wouter Verkerke +// +///////////////////////////////////////////////////////////////////////// + +#ifndef __CINT__ +#include "RooGlobalFunc.h" +#endif +#include "RooRealVar.h" +#include "RooDataSet.h" +#include "RooDataHist.h" +#include "RooGaussian.h" +#include "RooConstVar.h" +#include "TCanvas.h" +#include "TAxis.h" +#include "RooPlot.h" +#include "RooWorkspace.h" +#include "RooExpensiveObjectCache.h" +#include "TFile.h" +#include "TH1.h" + +using namespace RooFit ; + +RooWorkspace* getWorkspace(Int_t mode) ; + +void rf903_numintcache(Int_t mode=0) +{ + // Mode = 0 : Run plain fit (slow) + // Mode = 1 : Generate workspace with precalculated integral and store it on file (prepare for accelerated running) + // Mode = 2 : Run fit from previously stored workspace including cached integrals (fast, requires run in mode=1 first) + + // C r e a t e , s a v e o r l o a d w o r k s p a c e w i t h p . d . f . + // ----------------------------------------------------------------------------------- + + // Make/load workspace, exit here in mode 1 + RooWorkspace* w = getWorkspace(mode) ; + if (mode==1) { + + // Show workspace that was created + w->Print() ; + + // Show plot of cached integral values + RooDataHist* hhcache = (RooDataHist*) w->expensiveObjectCache().getObj(1) ; + if (hhcache) { + + new TCanvas("rf903_numintcache","rf903_numintcache",600,600) ; + hhcache->createHistogram("a")->Draw() ; + + } + else { + Error("rf903_numintcache","Cached histogram is not existing in workspace"); + } + return ; + } + + // U s e p . d . f . f r o m w o r k s p a c e f o r g e n e r a t i o n a n d f i t t i n g + // ----------------------------------------------------------------------------------- + + // This is always slow (need to find maximum function value empirically in 3D space) + RooDataSet* d = w->pdf("model")->generate(RooArgSet(*w->var("x"),*w->var("y"),*w->var("z")),1000) ; + + // This is slow in mode 0, but fast in mode 1 + w->pdf("model")->fitTo(*d,Verbose(kTRUE),Timer(kTRUE)) ; + + // Projection on x (always slow as 2D integral over Y,Z at fitted value of a is not cached) + RooPlot* framex = w->var("x")->frame(Title("Projection of 3D model on X")) ; + d->plotOn(framex) ; + w->pdf("model")->plotOn(framex) ; + + // Draw x projection on canvas + new TCanvas("rf903_numintcache","rf903_numintcache",600,600) ; + framex->Draw() ; + + // Make workspace available on command line after macro finishes + gDirectory->Add(w) ; + + return ; + + +} + + + +RooWorkspace* getWorkspace(Int_t mode) +{ + // C r e a t e , s a v e o r l o a d w o r k s p a c e w i t h p . d . f . + // ----------------------------------------------------------------------------------- + // + // Mode = 0 : Create workspace for plain running (no integral caching) + // Mode = 1 : Generate workspace with precalculated integral and store it on file + // Mode = 2 : Load previously stored workspace from file + + RooWorkspace* w(0) ; + + if (mode!=2) { + + // Create empty workspace workspace + w = new RooWorkspace("w",1) ; + + // Make a difficult to normalize p.d.f. in 3 dimensions that is integrated numerically. + w->factory("EXPR::model('1/((x-a)*(x-a)+0.01)+1/((y-a)*(y-a)+0.01)+1/((z-a)*(z-a)+0.01)',x[-1,1],y[-1,1],z[-1,1],a[-5,5])") ; + } + + if (mode==1) { + + // Instruct model to precalculate normalization integral that integrate at least + // two dimensions numerically. In this specific case the integral value for + // all values of parameter 'a' are stored in a histogram and available for use + // in subsequent fitting and plotting operations (interpolation is applied) + + // w->pdf("model")->setNormValueCaching(3) ; + w->pdf("model")->setStringAttribute("CACHEPARMINT","x:y:z"); + + // Evaluate p.d.f. once to trigger filling of cache + RooArgSet normSet(*w->var("x"),*w->var("y"),*w->var("z")) ; + w->pdf("model")->getVal(&normSet) ; + w->writeToFile("rf903_numintcache.root") ; + + } + + if (mode==2) { + // Load preexisting workspace from file in mode==2 + TFile* f = new TFile("rf903_numintcache.root") ; + w = (RooWorkspace*) f->Get("w") ; + } + + // Return created or loaded workspace + return w ; +}