Store 2D array into TTree use python

I want to store 2D array of float numbers in a Tree use python. Ideally, the 2D array has 1D fixed (8 elements) and the other dimension not fixed. But I’ll be happy even if two dimensions all with fixed length. Can anybody help or point me to some useful resource? Thanks.

I figured out how to store a 1D array, use a 1D vector. But could not find a solution for 2D array in python.

Dear zhangaw325,

Here is an example of how to store a 2D array in a TTree from Python. For the sake of illustrating the different options you have, one of the dimensions is a variable that corresponds to another branch of the tree, the other dimension is defined with a constant. Numpy is used to construct the multidimensional arrays in Python.

Here is the code that stores the array:

from ROOT import TFile, TTree
import numpy as np

f = TFile('example.root', 'recreate')
t = TTree('mytree', 'example tree')

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')

nentries = 25
for i in range(nentries):
   t.Fill()

f.Write()
f.Close()

Here’s the code that reads it back into a numpy array:

import ROOT
import numpy as np

tfile = ROOT.TFile("example.root")
ttree = tfile.mytree

nentries = 25
for i in range(nentries):
  ttree.GetEntry(i)
  print(ttree.mynum)
  print(np.reshape(ttree.myarray, (2,3)))

Best,
Enric

yes, but you clearly had to know beforehand (and remember!) the shape of that array.

this wouldn’t be needed if PyROOT understood/implemented python’s buffer protocol, as I reported a while back:

wow! time flies :slight_smile:
-s

That, of course, has nothing to do with it: the fix would have to be in the TTree pythonization (as that is where the dimensions are to be had, from the TLeaves), which can be done on top of any type of interface: old-style, new-style, or completely custom.

Note carefully how what you quote in that JIRA ticket is the use of a new buffer interface (the protocol), not an array implementation or even array interface. What went before, in the old-style days, were buffer objects that implemented the buffer interface and could thus be used as arrays. And it is the latter that is needed here, otherwise you still have nothing to loop over (memory views only support bytes, even when telling them the true type).

That doesn’t mean that the newer buffer interface is useless: it solves the problems that PyROOT has with types that are not supported in python arrays, as well as the overload problems it has with numpy arrays (that do not carry typecodes). The former is hacked around in PyROOT for a few common cases, the latter is still an open JIRA ticket.

Note that the new buffer protocol is supported in cppyy master and the changes are relatively self-contained, so they could be copied back into PyROOT.

But as said above, that wouldn’t do anything for this particular case or your JIRA ticket, which requires changes in the pythonization of TTree, completely independent of the buffer protocol.

Thank you very much for the solution!
Aiwu

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