Branch in PyROOT

I try fill branches and hists by elements of numpy array. Hists are ok, but branches are contain trash. What is the problem?

#!/usr/bin/env python
from ROOT import TTree, TBranch, TFile, TH1F
import numpy as np
import random as rnd
output = TFile('tree.root', 'recreate')
events = 1000
num_branch = 10
mean = 5
sigma = 2
hist = []
data = np.zeros((num_branch,events))
tree = TTree('new_tree', 'Main_tree')
for b in range(num_branch):
	name_hist = "hist of branch_"+str(b+1)
	hist.append(TH1F(name_hist,name_hist,10*(mean+b),0,2*(mean+b)))
	branch_name = "branch_" + str(b+1)
	tree.Branch(branch_name, data[b], branch_name+"/F")
for e in range(events):
	for b in range(num_branch):	
		data[b][e] = rnd.gauss(mean+b, sigma*(b+1))
		hist[b].Fill(data[b][e])
		tree.Fill()
output.Write()
output.Close()

tree.root (16.8 KB)


ROOT Version ( 6.10/02):
Platform, compiler (Ubuntu 16.04.4 LTS, gcc 5.4, python 2.7.12):


Hi @Buzinowski,

I believe what is missing in your code is to specify the length of your array branch in TTree::Branch. Please have a look at this post:

where there is an example of how to define branches that are numpy arrays, write them and read them back from Python.

Cheers,

Enric

Sorry, but i don’t understand. In example you demonstrate two cases of branches. Firs is one-d branch data, second is 2-d array data type. I have some data in the type of matrix with n rows and m columns. Each row contains data for one branch.

n = np.array(2, dtype=np.int32)
t.Branch('mynum', n, 'mynum/I')
x = np.array([[1., 2., 3.], [4., 5., 6.]])
t.Branch('myarray', x, 'myarray[mynum][3]/D')

How branch ‘myarray’ and ‘mynum’ are related? As i understood correctly in ‘myarray[mynum][3]/D’ [3] means length of array, but in my case the length of branch is variable (int events). And what does mean [mynum] in this case?

Hi,

In your case you have branches that are 1-D arrays. When you define those branches with TTree::Branch, you need to specify the size of those arrays.

In the example, myarray has one dimension that is defined by another branch mynum, and the size of the other dimension is defined by a constant. In your case, you need to follow a similar strategy: you can have another branch with the variable size of your array branches.

Also, I am not sure why you do tree.Fill once per event and per branch, I believe you should do it once per event, once the whole array branch contains the right values you want to store.

Cheers,

Enric

Code was changed, but branches have nothing. What am i doing wrong?

#!/usr/bin/env python
from ROOT import TTree, TBranch, TFile, TH1F
import numpy as np
import random as rnd
output = TFile('tree.root', 'recreate')
events = 1000 #number of entries
num = 10 #number of branches
mean = 5
sigma = 2
hist = []

length = np.array(events, dtype = np.int32)
num_branch = np.array(num, dtype = np.int32)
data = np.zeros(shape = (num,events), dtype = np.float32)

tree = TTree('new_tree', 'Main_tree')
tree.Branch("num_of_branch", num_branch, "num_of_branch/I")
tree.Branch("length_of_branch", length, "length_of_branch/I")
for b in range(num):
	name_hist = "hist of branch_"+str(b+1)
	hist.append(TH1F(name_hist,name_hist,10*(mean+b),0,2*(mean+b)))
	branch_name = "branch_" + str(b+1)
	tree.Branch(branch_name, data[b], branch_name+'[num_of_branch][length_of_branch]/F')
for e in range(events):
	for b in range(num):	
		data[b][e] = rnd.gauss(mean+b, sigma*(0.1*b+1))
		hist[b].Fill(data[b][e])
	tree.Fill()

tree.Print()
output.Write()
output.Close()

In this line:

tree.Branch(branch_name, data[b], branch_name+'[num_of_branch][length_of_branch]/F')

you are declaring your branch as a 2-D array, but data[b] is a 1-D array. Also, you do not assign a value to length anywhere, for each event it should contain the length of you array branches, and that length will be stored too in its branch.

In order to start with something simpler, why don’t you try an example with just one array branch and one length branch, and try to make that one work? Once that is fine, you can try with the big example.

Enric

Thank you for your help.

tree.Branch(branch_name, data[b], branch_name+'[length_of_branch]/F')

This line give something like true, but in zero bin i have many zeros. If ignore this i have normal distribution.
In some examples i have situation like these (entries in zero bin).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.