Accessing multidimensional arrays

I have TTree with a branch that is a 120x16 array of floats called low_occ

>>> t
<ROOT.TTree object ("t0x330301") at 0xa4cf940>
>>> t.GetEntry(0)
230424
>>> t.low_occ
<read-write buffer ptr 0xa5ab088, size 1920 at 0xb7113d60>

But I cannot index it twice.

>>> t.low_occ[1][2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'float' object is unsubscriptable

It seems that pyroot treats it like a 1-D array that is 120 x 16 = 1920 in length.

>>> t.low_occ[1]
1.0
>>> t.low_occ[1919]
1.0
>>> t.low_occ[1920]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: buffer index out of range

What’s the right way to access the elements of this array? It would be optimal if I could somehow fill the data into a numpy array.

Ryan,

the “right” order I always forget, but since it is simply the C pointer (that is, PyROOT always only sees a type*, not a type[] or type[][]), it is the layout that C uses. Hence, since numpy uses that same layout, and since the object from PyROOT conforms to the Python buffer interface that numpy should understand, handing it over should be straightforward.

I’m not too familiar with numpy, but I think the “shape” data member or the “reshape” function is all that is needed to turn a 1-D into a 2-D array.

Cheers,
Wim

Thanks for the suggestion Wim. For future record, I’ll describe the solution.

Assuming the array is ordered by row like a C array in memory, a 2 x 3 array for example, should be ordred like:

a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2], a[2][0], a[2][1], a[2][2].

So instead of the naive

tree.low_occ[row][col]

I used

tree.low_occ[row*n_cols + col]

which seems to work fine. Thanks.