You are here

How to Write a TTree in Python?

This how to is based on this document by Wim.

Writing a ROOT TTree in a python session is a little convoluted, if only because you'll need a C++ class to make sure that data members can be mapped (trees work with direct memory access), unless you're working with builtin types. Here is an example for working with the latter only:

from ROOT import TFile, TTree
from array import array
 
h = TH1F( 'h1', 'test', 100, -10., 10. )
 
f = TFile( 'test.root', 'recreate' )
t = TTree( 't1', 'tree with histos' )
 
maxn = 10
n = array( 'i', [ 0 ] )
d = array( 'f', maxn*[ 0. ] )
t.Branch( 'mynum', n, 'mynum/I' )
t.Branch( 'myval', d, 'myval[mynum]/F' )
 
for i in range(25):
   n[0] = min(i,maxn)
   for j in range(n[0]):
      d[j] = i*0.1+j
   t.Fill()
 
f.Write()
f.Close()

The use of arrays is needed, because the pointer to the address of the object that is used for filling must be given to the TTree::Branch() call, even though the formal argument is declared a void*.

In the case of ROOT objects, similar pointer manipulation is unneccessary, because the full type information is available, and TTree::Branch() has been pythonized to take care of the call details. However, data members of such objects that are of builtin types, still require something extra since they are normally translated to python primitive types on access and hence their address can not be taken. For that purpose, there is the AddressOf() function. As an example:

from ROOT import TFile, TTree
from ROOT import gROOT, AddressOf
 
gROOT.ProcessLine(
"struct MyStruct {\
   Int_t     fMyInt1;\
   Int_t     fMyInt2;\
   Int_t     fMyInt3;\
   Char_t    fMyCode[4];\
};" );
 
from ROOT import MyStruct
mystruct = MyStruct()
 
f = TFile( 'mytree.root', 'RECREATE' )
tree = TTree( 'T', 'Just A Tree' )
tree.Branch( 'myints', mystruct, 'MyInt1/I:MyInt2:MyInt3' )
tree.Branch( 'mycode', AddressOf( mystruct, 'fMyCode' ), 'MyCode/C' )
 
for i in range(10):
   mystruct.fMyInt1   = i
   mystruct.fMyInt2   = i*i
   mystruct.fMyInt3   = i*i*i
   mystruct.fMyCode   = "%03d" % i      # note string assignment
 
   tree.Fill()
 
f.Write()
f.Close()