How to write a TTree for an existing numpy array using pyroot

Hey Root Experts

from ROOT import *
import numpy as np

file = TFile("tree.root", 'recreate')
tree = TTree("tree_name", "tree title")

px  = np.array([1,2,3.5])

tree.Branch("px",  px,  'normal/D')

for i in range(len(px)):
    tree.Fill()

file.Write()
file.Close()

I’m new to the ROOT community and I know this is very simple thing. But I’m having a hard time storing a numpy array to a TTree object as one of its branch and access the branch. Right now this code should Fill the tree same px array for 3 times. But I want the values of the array in tree not the whole array 3 times.
What should I do?

Hello,

So if I understand correctly, you want to fill a branch of type double with the values contained in a numpy array of doubles.

One way to do it is via RDataFrame, this tutorial shows exactly how to do it:

https://root.cern/doc/master/df032__MakeNumpyDataFrame_8py.html

Another (more complicated) way is to do the loop in Python as you were doing. But when you define the branch, you need to pass a numpy array of just one position.

px  = np.array([0], dtype=np.float64)

tree.Branch("px",  px,  'normal/D')

and then inside the loop you would need to assign a new value to that position in every iteration, so that a single double is filled at each iteration:

for i in range(num_elems):
    px[0] = current_elem
    tree.Fill()

I forgot to thank you.
Thank you so much.
The RDataFrame tutorial didn’t work for me. It throws this error:

But, I’m trying to work with the other solution. It worked but my problem also changed a bit.
I need to create a tree with multiple branches, but the branch length is not same for all. To do that, I wrote this:

a = np.array([1,2,3.2])
b = np.array([1,2,3.2, 5])

file = TFile("tree.root", 'recreate')
tree = TTree("tree_name", "tree title")
# Placeholder variable
ax  = np.array([0], dtype=np.float64)
bx  = np.array([0], dtype=np.float64)
# Creating branches
tree.Branch("a",  ax,  'normal/D')
tree.Branch("b",  bx,  'normal/D')

for i in a:
    print(i)
    ax[0] = i
    tree.Fill()

for i in b:
    print(i)
    bx[0] = i
    tree.Fill()

file.Write()
file.Close()

type or paste code here

It’s not quite right as I’m using tree.Fill() two times, and I guess the branch ‘a’ also gets filled partially for the second time I call tree.Fill().


This is probably due to the ROOT version you are using, could you try updating to a more recent one (e.g. 6.24 or 6.26)?

Yes indeed, if you use this alternative, the second fill will also fill the a branch. You need to have one loop where at every iteration you assign the values for a and b and you fill an entry with those values.