User Tools

Site Tools


root:pyroot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
root:pyroot [2017/06/13 09:21] – [Filling a histogram from a tree] iwnroot:pyroot [2017/09/05 15:05] – [Useful pyROOT snippets] iwn
Line 1: Line 1:
 +[[root:root|Getting started with ROOT]] -> [[root:pyroot|Useful pyROOT snippets]]
 +
 ====== Useful pyROOT snippets ====== ====== Useful pyROOT snippets ======
  
-This page lists some loose examples of ''ROOT'' in ''python'' that may be useful+Here are some loose examples of ''ROOT'' in ''python'' that may be useful: 
- +  [[root:pyroot_TTree|handling TTree trees]], 
-===== Handling TTree trees ===== +  [[root:pyroot_TH1|handling TH1 histograms]], 
- +  [[root:pyroot_TFile|handling TFile files and TDirectory directories]], 
-[[root:example_TTree|Here]] is one file containing multiple examples. +  [[https://github.com/clelange/roofit|RooFit]] and [[https://github.com/clelange/roostats|RooStats]] tutorials; [[https://www.nikhef.nl/~vcroft/GettingStartedWithRooFit.html|RooFit manual]]. 
- +  [[https://wiki.physik.uzh.ch/lhcb/root:root|more by the LHCb group]].
-==== Creating a TTree with branches and writing it to a TFile ==== +
- +
-Below is an example of creating and saving a tree with two branches (variables) each containing a randomly distributed variable for each event. +
- +
-If you would fill a ''TTree'' in ''C++'', you can pass a double as a reference, called the //address// of the branch. In ''python'' however, you will need to use an array instead, for example the ''array'' class. More information on the [[https://root.cern/doc/master/classTTree.html#ac1fa9466ce018d4aa739b357f981c615|Branch(name,address, leaflist) method]]+
- +
-<file python tree.py> +
-from ROOT import TFile, TTreegRandom +
-from array import array +
- +
-# make new root file with new tree +
-file = TFile("tree.root", 'recreate'+
-tree = TTree("tree_name", "tree title"+
- +
-# create 1 dimensional float arrays as fill variables, in this way the float array serves +
-# as a pointer which can be passed to the branch +
-px  = array('d',[0]) +
-phi = array('d',[0]) +
- +
-# create the branches and assign the fill-variables to them as doubles (D) +
-tree.Branch("px",  px,  'normal/D'+
-tree.Branch("phi", phi, 'uniform/D'+
- +
-# create some random numbers, assign them into the fill variables and call Fill() +
-for i in xrange(10000): +
-    px[0 = gRandom.Gaus(20,2) +
-    phi[0= gRandom.Uniform(2*3.1416) +
-    tree.Fill() +
-     +
-# write the tree into the output file and close the file +
-file.Write() +
-file.Close() +
-</file> +
- +
-Alternativelyyou could use the ''numpy'' class: +
-<code python> +
-import numpy +
-... +
-px  = numpy.zeros(1, dtype=float) +
-phi = numpy.zeros(1, dtype=float) +
-... +
-</code> +
- +
-Note that ''file.Write()'' will write all objects (trees, histograms, graphs, ...) that are still opened. Instead, you can write an object, in this case a ''TTree'', with the [[https://root.cern.ch/doc/master/classTTree.html#af6f2d9ae4048ad85fcae5d2afa05100f|Write() method]]+
-<code python> +
-tree.Write() +
-</code> +
-Optional arguments are a string for a new name and some writing options, e.g. to overwrite with ''TFile.kOverwrite''+
- +
-==== Filling a branch with multiple values per event ==== +
- +
-Here is an example of filling a tree with a variable number of particles, each having a ''pt'' variable: +
- +
-<file python tree.py> +
-from ROOT import TFile, TTree, gRandom +
-from array import array +
- +
-file = TFile("tree.root", 'recreate'+
-tree = TTree("tree_name", "tree title"+
- +
-Nmax = 10 +
-nParticles = array( 'i', 0 ] ) +
-pt = array( 'd', Nmax*0. ] ) +
-tree.Branch( 'nParticles', nParticles, 'nParticles/I'+
-tree.Branch( 'pt', pt, 'pt[nParticles]/D'+
- +
-for i in xrange(1000): +
-    nParticles[0] = int(gRandom.Uniform()*10) +
-    for j in xrange(nParticles[0]): +
-       pt[j] = gRandom.Gaus(20,2) +
-    tree.Fill() +
-     +
-file.Write("",TFile.kOverwrite) +
-file.Close() +
-</file> +
-==== Looping over a TTree ==== +
- +
-The classic way of looping through a tree is: +
-<code python> +
-N = tree.GetEntries() +
-for i in xrange(N): +
-    tree.GetEntry(i) +
-    print tree.px +
-</code> +
-where you can access the values in branch ''px'' for each eventA more elegant and pythonic way is the following: +
-<code python> +
-for event in tree: +
-    print tree.px +
-</code> +
-If you also need the index: +
-<code python> +
-for i, event in enumerate(tree): +
-    print i, tree.px +
-</code> +
- +
- +
-==== Adding and saving a branch to a TTree in a TFile ==== +
- +
-Here is simple example of adding a completely new branch to an existing tree. +
- +
-<file python addBranch.py> +
-from ROOT import TFile, TTree, gRandom +
- +
-# reopen tree file +
-file = TFile("tree.root",'update'+
-tree = file.Get("tree_name"+
- +
-# make new variable and add it as a branch to the tree +
-py = array('d',[0]+
-branch = tree.Branch("py", py, 'py/D'+
- +
-# fill the branch +
-N = tree.GetEntries() +
-for i in xrange(N): +
-    tree.GetEntry(i) +
-    py[0= gRandom.Gaus(23,4) +
-    branch.Fill() +
- +
-# overwrite the tree in the output file and close the file +
-file.Write("",TFile.kOverwrite) +
-file.Close() +
-</file> +
- +
-More interestingly, you can access existing branches in the tree and use those values to create new variables. Here is an example of making a new branch containing transverse momentum for each event, assuming the tree has branches ''px'' and ''py'': +
-<code python> +
-import sqrt from math +
-... +
-pt = array('d',[0]) +
-branch = tree.Branch("pt", pt, 'pt/D'+
- +
-N = tree.GetEntries() +
-for i in xrange(N): +
-    tree.GetEntry(i) +
-    pt[0] = sqrt(tree.px**2 + tree.py**2) +
-    branch.Fill() +
-</code> +
- +
- +
-===== Handling TH1 histograms ===== +
- +
-==== Filling a histogram ==== +
- +
-Simple enough: +
- +
-<code python> +
-hist = TH1D("hist_name","hist title",100,0,100) +
-for i in xrange(10000): +
-    hist.Fill(gRandom.Gauss()) +
-</code> +
- +
-With some weight: +
-<code python> +
-weight = gRandom.Gauss(1,0.1) +
-hist.Fill(gRandom.Gauss(),weight) +
-</code> +
-==== Filling a histogram from a tree ==== +
- +
-The classic way would be +
-<code python> +
-hist = TH1D("hist_name","hist title",100,0,100) +
-for event in tree: +
-    hist.Fill(tree.px) +
-</code> +
- +
-But the simplest and most powerful way to draw some variable into a histogram, is with the [[https://root.cern.ch/doc/master/classTTree.html#a73450649dc6e54b5b94516c468523e45|Draw]] function: +
-<code python> +
-hist = TH1D("hist_name","hist title",100,0,100) +
-tree.Draw("px >> hist_name") +
-</code> +
-Note that the histogram has been saved into ''ROOT'''s working memory and is therefore accessible via its name in the ''Draw'' function, ''"hist_name"'' in this example. +
- +
-You can also use mathematical expressions: +
-<code python> +
-tree.Draw("2*sqrt(px*px+py*py) >> hist_name"+
-tree.Draw("abs(eta) >> hist_name"+
-</code> +
- +
-You can apply some selections using variable, available in the tree's branches: +
-<code python> +
-tree.Draw("px >> hist_name","pt>20 && E>20"+
-</code> +
- +
-You can apply some selections and/or a weight, if a weight variable is available in the tree: +
-<code python> +
-tree.Draw("px >> hist_name","(pt>20 && E>20)*weight"+
-tree.Draw("px >> hist_name","weight"+
-</code> +
- +
-An equivalent method is creating the histogram in the ''Draw'' method. If you need the ''TH1F'' object, you can still get it with ''gDirectory'' (see [[root:pyroot#gDirectory|below]]): +
-<code python> +
-from ROOT import gDirectory +
-... +
-tree.Draw("pt >> h(100,0,100)"+
-hist = gDirectory.Get("h") # will be a TH1F object +
-</code> +
- +
-It's also possible to pass some option you would normally use in "TH1::Draw()". It is passed as the third string. +
-<code python> +
-tree.Draw("px >> h1(100,0,100)","","E2"+
-tree.Draw("py >> h2(100,0,100)","","E2 SAME"+
- +
-tree.Draw("px >> h1(100,0,100)","abs(eta)>2","E2"+
-tree.Draw("px >> h2(100,0,100)","abs(eta)<2","E2 SAME"+
-</code> +
- +
-__Protip__: This is very useful for quick drawing and comparing, for example in the ''ROOT'' command line. +
-<code C++> +
-$ root -l tree.root +
-[1tree->Draw("px >> h1(100,0,100)","","E2"+
-[2tree->Draw("py >> h2(100,0,100)","","E2 SAME"+
-</code> +
-===== Handling TFiles ===== +
- +
-==== Adding a directory to a TFile ==== +
- +
-Here is a basic example creating a file with on directoryIf you want to create and save an object in this directory, e.g. a tree or histogram, use ''dir.cd()''. Pay attention to the order of creating an object, changing directory (''cd()'') and writing the object! +
- +
-<file python addDirectory.py> +
-from ROOT import TFile +
- +
-file = TFile("tree.root",'update'+
-  +
-# make directory if it does not exist +
-dir = file.GetDirectory("dir"+
-if not dir: +
-    print ">>> created dir" +
-    dir = file.mkdir("dir"+
-  +
-# make this directory the current one: everything you write will be saved here +
-dir.cd() +
- +
-# make tree, histogram, ... +
-         +
-file.Write("",TFile.kOverwrite) +
-file.Close() +
-</file> +
- +
- +
-==== gDirectory ==== +
- +
-Note that ''gDirectory'' is the current directory containing all newly created saved objects, or those saved to this directory. If you just opened a file, this will be your current directory until you close it or use ''cd()''. Test the behavior: +
- +
-<file python gDirectory.py> +
-from ROOT import TFile, TTree, TH1F, gDirectory +
- +
-def printGDirectory(): +
-    print ">>> gDirectory.GetName()\n%s" % gDirectory.GetName() +
-    print ">>> gDirectory.pwd()" +
-    gDirectory.pwd() +
-    print ">>> gDirectory.ls()" +
-    gDirectory.ls() +
-    print +
- +
-print "\ndefault" +
-printGDirectory() +
- +
-print ">>> creating some file with some contents" +
-file = TFile("test.root","recreate"+
-tree = TTree("tree","tree"+
-hist = TH1F("hist","hist",100,0,100) +
-dir1 = file.mkdir("dir1"+
-printGDirectory() +
- +
-print ">>> gDirectory.Delete(\"hist\")" +
-gDirectory.Delete("hist"+
-printGDirectory() +
- +
-print ">>> dir1.cd()" +
-dir1.cd() +
-printGDirectory()+
  
-print ">>> file.Close()" +(More snippets to follow.)
-file.Close() +
-printGDirectory() +
-</file>+
root/pyroot.txt · Last modified: 2017/09/05 15:05 by iwn