00001 ////////////////////////////////////////////////////////////////////////// 00002 // 00003 // 'BASIC FUNCTIONALITY' RooFit tutorial macro #102 00004 // 00005 // Importing data from ROOT TTrees and THx histograms 00006 // 00007 // 00008 // 00009 // 07/2008 - Wouter Verkerke 00010 // 00011 ///////////////////////////////////////////////////////////////////////// 00012 00013 00014 #ifndef __CINT__ 00015 #include "RooGlobalFunc.h" 00016 #endif 00017 #include "RooRealVar.h" 00018 #include "RooDataSet.h" 00019 #include "RooGaussian.h" 00020 #include "TCanvas.h" 00021 #include "RooPlot.h" 00022 #include "TTree.h" 00023 #include "TH1D.h" 00024 #include "TRandom.h" 00025 using namespace RooFit ; 00026 00027 00028 class TestBasic102 : public RooFitTestUnit 00029 { 00030 public: 00031 TestBasic102(TFile* refFile, Bool_t writeRef, Int_t verbose) : RooFitTestUnit("Data import methods",refFile,writeRef,verbose) {} ; 00032 00033 TH1* makeTH1() 00034 { 00035 // Create ROOT TH1 filled with a Gaussian distribution 00036 00037 TH1D* hh = new TH1D("hh","hh",25,-10,10) ; 00038 for (int i=0 ; i<100 ; i++) { 00039 hh->Fill(gRandom->Gaus(0,3)) ; 00040 } 00041 return hh ; 00042 } 00043 00044 00045 TTree* makeTTree() 00046 { 00047 // Create ROOT TTree filled with a Gaussian distribution in x and a uniform distribution in y 00048 00049 TTree* tree = new TTree("tree","tree") ; 00050 Double_t* px = new Double_t ; 00051 Double_t* py = new Double_t ; 00052 tree->Branch("x",px,"x/D") ; 00053 tree->Branch("y",py,"y/D") ; 00054 for (int i=0 ; i<100 ; i++) { 00055 *px = gRandom->Gaus(0,3) ; 00056 *py = gRandom->Uniform()*30 - 15 ; 00057 tree->Fill() ; 00058 } 00059 00060 //delete px ; 00061 //delete py ; 00062 00063 return tree ; 00064 } 00065 00066 Bool_t testCode() { 00067 00068 //////////////////////////////////////////////////////// 00069 // I m p o r t i n g R O O T h i s t o g r a m s // 00070 //////////////////////////////////////////////////////// 00071 00072 // 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 00073 // --------------------------------------------------------- 00074 00075 // Create a ROOT TH1 histogram 00076 TH1* hh = makeTH1() ; 00077 00078 // Declare observable x 00079 RooRealVar x("x","x",-10,10) ; 00080 00081 // Create a binned dataset that imports contents of TH1 and associates its contents to observable 'x' 00082 RooDataHist dh("dh","dh",x,Import(*hh)) ; 00083 00084 00085 // P l o t a n d f i t a R o o D a t a H i s t 00086 // --------------------------------------------------- 00087 00088 // Make plot of binned dataset showing Poisson error bars (RooFit default) 00089 RooPlot* frame = x.frame(Title("Imported TH1 with Poisson error bars")) ; 00090 dh.plotOn(frame) ; 00091 00092 // Fit a Gaussian p.d.f to the data 00093 RooRealVar mean("mean","mean",0,-10,10) ; 00094 RooRealVar sigma("sigma","sigma",3,0.1,10) ; 00095 RooGaussian gauss("gauss","gauss",x,mean,sigma) ; 00096 gauss.fitTo(dh) ; 00097 gauss.plotOn(frame) ; 00098 00099 // 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 00100 // --------------------------------------------------------------------------------------------- 00101 00102 // If histogram has custom error (i.e. its contents is does not originate from a Poisson process 00103 // but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead 00104 // (same error bars as shown by ROOT) 00105 RooPlot* frame2 = x.frame(Title("Imported TH1 with internal errors")) ; 00106 dh.plotOn(frame2,DataError(RooAbsData::SumW2)) ; 00107 gauss.plotOn(frame2) ; 00108 00109 // Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used 00110 // in a maximum likelihood fit 00111 // 00112 // A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition 00113 // of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly 00114 // fitted with a chi^2 fit (see rf602_chi2fit.C) 00115 00116 00117 //////////////////////////////////////////////// 00118 // I m p o r t i n g R O O T T T r e e s // 00119 //////////////////////////////////////////////// 00120 00121 00122 // 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 00123 // ----------------------------------------------------------- 00124 00125 TTree* tree = makeTTree() ; 00126 00127 // Define 2nd observable y 00128 RooRealVar y("y","y",-10,10) ; 00129 00130 // Construct unbinned dataset importing tree branches x and y matching between branches and RooRealVars 00131 // is done by name of the branch/RRV 00132 // 00133 // Note that ONLY entries for which x,y have values within their allowed ranges as defined in 00134 // RooRealVar x and y are imported. Since the y values in the import tree are in the range [-15,15] 00135 // and RRV y defines a range [-10,10] this means that the RooDataSet below will have less entries than the TTree 'tree' 00136 00137 RooDataSet ds("ds","ds",RooArgSet(x,y),Import(*tree)) ; 00138 00139 00140 // 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 00141 // ------------------------------------------------------------------------------------ 00142 00143 // Print unbinned dataset with default frame binning (100 bins) 00144 RooPlot* frame3 = y.frame(Title("Unbinned data shown in default frame binning")) ; 00145 ds.plotOn(frame3) ; 00146 00147 // Print unbinned dataset with custom binning choice (20 bins) 00148 RooPlot* frame4 = y.frame(Title("Unbinned data shown with custom binning")) ; 00149 ds.plotOn(frame4,Binning(20)) ; 00150 00151 // Draw all frames on a canvas 00152 regPlot(frame ,"rf102_plot1") ; 00153 regPlot(frame2,"rf102_plot2") ; 00154 regPlot(frame3,"rf102_plot3") ; 00155 regPlot(frame4,"rf102_plot4") ; 00156 00157 delete hh ; 00158 delete tree ; 00159 00160 return kTRUE ; 00161 } 00162 } ; 00163 00164 00165 00166 00167 00168 00169