Logo ROOT  
Reference Guide
rf102_dataimport.py
Go to the documentation of this file.
1## \file
2## \ingroup tutorial_roofit
3## \notebook
4## 'BASIC FUNCTIONALITY' RooFit tutorial macro #102
5## Importing data from ROOT TTrees and THx histograms
6##
7## \macro_code
8##
9## \date February 2018
10## \authors Clemens Lange, Wouter Verkerke (C version)
11
12import ROOT
13from array import array
14
15
16def makeTH1():
17
18 # Create ROOT ROOT.TH1 filled with a Gaussian distribution
19
20 hh = ROOT.TH1D("hh", "hh", 25, -10, 10)
21 for i in range(100):
22 hh.Fill(ROOT.gRandom.Gaus(0, 3))
23 return hh
24
25
26def makeTTree():
27 # Create ROOT ROOT.TTree filled with a Gaussian distribution in x and a
28 # uniform distribution in y
29
30 tree = ROOT.TTree("tree", "tree")
31 px = array("d", [0])
32 py = array("d", [0])
33 tree.Branch("x", px, "x/D")
34 tree.Branch("y", py, "y/D")
35 for i in range(100):
36 px[0] = ROOT.gRandom.Gaus(0, 3)
37 py[0] = ROOT.gRandom.Uniform() * 30 - 15
38 tree.Fill()
39 return tree
40
41
42############################
43# Importing ROOT histograms
44############################
45# Import ROOT TH1 into a RooDataHist
46# ---------------------------------------------------------
47# Create a ROOT TH1 histogram
48hh = makeTH1()
49
50# Declare observable x
51x = ROOT.RooRealVar("x", "x", -10, 10)
52
53# Create a binned dataset that imports contents of ROOT.TH1 and associates
54# its contents to observable 'x'
55dh = ROOT.RooDataHist("dh", "dh", [x], Import=hh)
56
57# Plot and fit a RooDataHist
58# ---------------------------------------------------
59# Make plot of binned dataset showing Poisson error bars (ROOT.RooFit
60# default)
61frame = x.frame(Title="Imported ROOT.TH1 with Poisson error bars")
62dh.plotOn(frame)
63
64# Fit a Gaussian p.d.f to the data
65mean = ROOT.RooRealVar("mean", "mean", 0, -10, 10)
66sigma = ROOT.RooRealVar("sigma", "sigma", 3, 0.1, 10)
67gauss = ROOT.RooGaussian("gauss", "gauss", x, mean, sigma)
68gauss.fitTo(dh)
69gauss.plotOn(frame)
70
71# Plot and fit a RooDataHist with internal errors
72# ---------------------------------------------------------------------------------------------
73
74# If histogram has custom error (i.e. its contents is does not originate from a Poisson process
75# but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead
76# (same error bars as shown by ROOT)
77frame2 = x.frame(Title="Imported ROOT.TH1 with internal errors")
78dh.plotOn(frame2, DataError="SumW2")
79gauss.plotOn(frame2)
80
81# Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used
82# in a maximum likelihood fit
83#
84# A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition
85# of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly
86# fitted with a chi^2 fit (see rf602_chi2fit.py)
87#
88# Importing ROOT TTrees
89# -----------------------------------------------------------
90# Import ROOT TTree into a RooDataSet
91
92tree = makeTTree()
93
94# Define 2nd observable y
95y = ROOT.RooRealVar("y", "y", -10, 10)
96
97# Construct unbinned dataset importing tree branches x and y matching between branches and ROOT.RooRealVars
98# is done by name of the branch/RRV
99#
100# Note that ONLY entries for which x,y have values within their allowed ranges as defined in
101# ROOT.RooRealVar x and y are imported. Since the y values in the import tree are in the range [-15,15]
102# and RRV y defines a range [-10,10] this means that the ROOT.RooDataSet
103# below will have less entries than the ROOT.TTree 'tree'
104
105ds = ROOT.RooDataSet("ds", "ds", {x, y}, ROOT.RooFit.Import(tree))
106
107# Use ascii import/export for datasets
108# ------------------------------------------------------------------------------------
109
110
111def write_dataset(ds, filename):
112 # Write data to output stream
113 outstream = ROOT.std.ofstream(filename)
114 # Optionally, adjust the stream here (e.g. std::setprecision)
115 ds.write(outstream)
116 outstream.close()
117
118
119write_dataset(ds, "rf102_testData.txt")
120
121# Read data from input stream. The variables of the dataset need to be supplied
122# to the RooDataSet::read() function.
123print("\n-----------------------\nReading data from ASCII")
124dataReadBack = ROOT.RooDataSet.read(
125 "rf102_testData.txt",
126 [x, y], # variables to be read. If the file has more fields, these are ignored.
127 "D", # Prints if a RooFit message stream listens for debug messages. Use Q for quiet.
128)
129
130dataReadBack.Print("V")
131
132print("\nOriginal data, line 20:")
133ds.get(20).Print("V")
134
135print("\nRead-back data, line 20:")
136dataReadBack.get(20).Print("V")
137
138
139# Plot data set with multiple binning choices
140# ------------------------------------------------------------------------------------
141# Print number of events in dataset
142ds.Print()
143
144# Print unbinned dataset with default frame binning (100 bins)
145frame3 = y.frame(Title="Unbinned data shown in default frame binning")
146ds.plotOn(frame3)
147
148# Print unbinned dataset with custom binning choice (20 bins)
149frame4 = y.frame(Title="Unbinned data shown with custom binning")
150ds.plotOn(frame4, Binning=20)
151
152frame5 = y.frame(Title="Unbinned data read back from ASCII file")
153ds.plotOn(frame5, Binning=20)
154dataReadBack.plotOn(frame5, Binning=20, MarkerColor="r", MarkerStyle=5)
155
156# Draw all frames on a canvas
157c = ROOT.TCanvas("rf102_dataimport", "rf102_dataimport", 800, 800)
158c.Divide(3, 2)
159c.cd(1)
160ROOT.gPad.SetLeftMargin(0.15)
161frame.GetYaxis().SetTitleOffset(1.4)
162frame.Draw()
163c.cd(2)
164ROOT.gPad.SetLeftMargin(0.15)
165frame2.GetYaxis().SetTitleOffset(1.4)
166frame2.Draw()
167c.cd(4)
168ROOT.gPad.SetLeftMargin(0.15)
169frame3.GetYaxis().SetTitleOffset(1.4)
170frame3.Draw()
171c.cd(5)
172ROOT.gPad.SetLeftMargin(0.15)
173frame4.GetYaxis().SetTitleOffset(1.4)
174frame4.Draw()
175c.cd(6)
176ROOT.gPad.SetLeftMargin(0.15)
177frame4.GetYaxis().SetTitleOffset(1.4)
178frame5.Draw()
179
180c.SaveAs("rf102_dataimport.png")
void Print(std::ostream &os, const OptionType &opt)