Analyzing xAOD in CINT/PyROOT
This is the wiki page for the xAOD-in-CINT/PyROOT hands-on session of the ATLAS LBL Software Tutorial. The material on this page comes mostly from the standard SoftwareTutorialxAODEDM Twiki.
Contents
Setting up the environment
You can reuse the work directory from the last session for this portion of the tutorial. If you're starting from a fresh terminal, RootCore can pick up the previously used Analysis Release by simply calling rcSetup from the top-level directory.
If however you're jumping into this session fresh, then create a dedicated work directory and setup the AnalysisBase release:
mkdir XAODTutorialPyROOT
cd XAODTutorialPyROOT
rcSetup Base,2.0.2
Constructing your basic macro
I will be giving all code snippets in PyROOT, but feel free to translate them into CINT if you prefer (and feel comfortable). You will have a full C++ tutorial a little later.
With your favorite editor, open up a new python script called xAODPythonMacro.py
. Next, add the appropriate lines which load all of your RootCore libraries into PyROOT:
#!/usr/bin/env python
# Set up ROOT and RootCore
import ROOT
ROOT.gROOT.Macro('$ROOTCOREDIR/scripts/load_packages.C')
Next, add the all-important line for initializing the xAOD infrastructure:
# Initialize the xAOD infrastructure
ROOT.xAOD.Init()
Now, setup the input file(s). Note that the path is of course machine-dependent. See the site-specific information for the file path on PDSF and SLAC machines.
# Set up the input files
fileName = '/afs/cern.ch/atlas/project/PAT/xAODs/r5534/valid2.117050.PowhegPythia_P2011C_ttbar.digit.AOD.e2657_s1933_s1964_r5534/AOD.01482225._000107.pool.root.1'
treeName = 'CollectionTree'
f = ROOT.TFile.Open(fileName)
Since we're using CINT or PyROOT, the template structure of TEvent is too cumbersome, and we'll instead use the transient tree for reading the objects:
# Make the "transient tree"
t = ROOT.xAOD.MakeTransientTree(f, treeName)
Now, let's loop over the entries of the tree and print some information:
# Print some information
print('Number of input events: %s' % t.GetEntries())
for entry in xrange(t.GetEntries()):
t.GetEntry(entry)
s = 'Processing run #%i, event #%i' % (t.EventInfo.runNumber(), t.EventInfo.eventNumber())
print(s)
Before moving on, try running your script either like this:
python ./xAODPythonMacro.py
or like this:
chmod +x xAODPythonMacro.py
./xAODPythonMacro.py
Accessing the EDM objects
With the transient tree, it is trivial to retrieve and use the xAOD information in PyROOT. For example, in your macro you can access the electron collection via t.ElectronCollection
, and the four-momentum variables in the usual way: t.ElectronCollection.pt()
, t.ElectronCollection.eta()
, etc. To loop over the electron collection, you can do something like this:
# loop over electron collection
for el in t.ElectronCollection:
print(' Electron trackParticle eta = %g, phi = %g' % (el.trackParticle().eta(), el.trackParticle().phi()))
Try to add the following to your python macro:
- Print the difference between the electron pt and the electron's trackParticle pt for all electrons with |eta| < 2.47.
- Count and print the number of jets with pt > 20 GeV and |eta| < 2.5.
- HINT: Use
t.AntiKt4LCTopoJets
to access the jet collection. - HINT: Momentum/energy variables in the xAOD are always in MeV!
- HINT: Use
Adding histograms
Booking and filling histograms in PyROOT is also very easy. After initializing the input tree and before looping over the entries, create your output file and book a couple of histograms:
f_out = ROOT.TFile('MyHistograms.root', 'recreate')
h_el_pt = ROOT.TH1F('el_pt', 'el_pt', 20, 0, 400)
h_jet_pt = ROOT.TH1F('jet_pt', 'jet_pt', 20, 0, 400)
Using statements like this to fill your histograms: h_el_pt.Fill(el.pt()/1000.)
, try to do the following:
- Fill the h_el_pt histogram with electron pt for all electrons with |eta| < 2.47.
- Fill the h_jet_pt histogram with jet pt for all jets with |eta| < 2.5.
- Experiment! Try to find your favorite variables to cut on in the xAOD documentation and use them.
At the end of your script, write out your histograms and close your file with
f_out.Write()
f_out.Close()
Finally, after running your script again, open the output file in an interactive session and try drawing the histograms to a canvas. Do the plots make sense?
Need help?
Here's my macro with the full solution to this hands-on material: https://gist.github.com/sparticlesteve/840c946c9ab6479c9015