///////////////////////////////////////////////////////////////////////// // // '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) ; // 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() ; }