Tree Reading with Pyroot issues

hello All,

I have a tree that I am attempting to process with PyROOT and there are a couple issues that I have been unable to work around.

The root file has a tree called ‘scalerTree’ with a single branch called ‘scalers’ and a number of leafs associated with it. Here is the structure:

>>> tree.Print()
******************************************************************************
*Tree    :scalerTree: Scalers                                                *
*Entries :      898 : Total =          141451 bytes  File  Size =      37294 *
*        :          : Tree compression factor =   3.79                       *
******************************************************************************
*Branch  :scaler                                                             *
*Entries :      898 : BranchElement (see below)                              *
*............................................................................*
*Br    0 :fUniqueID : UInt_t                                                 *
*Entries :      898 : Total  Size=       4183 bytes  File Size  =        129 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=  28.48     *
*............................................................................*
*Br    1 :fBits     : UInt_t                                                 *
*Entries :      898 : Total  Size=       7763 bytes  File Size  =       1269 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   5.73     *
*............................................................................*
*Br    2 :scalerStartTime : UInt_t                                           *
*Entries :      898 : Total  Size=       4213 bytes  File Size  =       1807 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   2.04     *
*............................................................................*
*Br    3 :scalerEndTime : UInt_t                                             *
*Entries :      898 : Total  Size=       4203 bytes  File Size  =       1805 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   2.04     *
*............................................................................*
*Br    4 :scalers[32] : UInt_t                                               *
*Entries :      898 : Total  Size=     119417 bytes  File Size  =      31159 *
*Baskets :        4 : Basket Size=      32000 bytes  Compression=   3.82     *
*............................................................................*

With reading a branch with no leafs and a non-array value, I have been able to do that using, (for example)

    tree.GetEntry(0)
    print tree.Branch

However, attempting to get to out the leaf values from the scalers branch above is proving, at least to me, not straightforward. I have attempted an old solution I found, works but inelegantly,

tree.GetEntry(0)
Y = tree.GetLeaf("scalerEndTime").GetValue()

This method I can get the two leafs (scalerEndTime and scalerStartTime) for each event, but I am uncertain how I can read our the scalers[32] array.

If I simply do the following:

tree.GetEntry(0)
Y = tree.scalers
for x in Y:
    print x

Y is a pointer to all the data and I can access it by looking at elements of Y, i.e. Y[0], Y[1], etc. However, iterating through it, it does NOT contain all of the data as its length is only 32 while just the scalers[32] array is that length alone.

My question is how can I efficiently get the data from this branch? It would be nice to read out the scalers[32] leaf into an array rather than have to look over all 32 entries of that leaf to read out the values.

Thank you for any help,


ROOT Version: 6.14.06
Platform: OSX 10.14 Mojave
Compiler: Not Provided


Hi @megooden

What is exactly what you want to do with the scalers[32] branch? It will be read by PyROOT into a unsigned int buffer of size 32, which can be accessed by position or iterated as you saw.

Regarding your statement:
However, iterating through it, it does NOT contain all of the data as its length is only 32 while just the scalers[32] array is that length alone.
Does this mean that the data is not correct? It does not contain the 32 values that you would expect?

When I run the following:

tree.GetEntry(0)
for y in tree.scalers:
    print y

The Len(tree.scalers) is 32, but the print out from the loop prints out the values of the other branches, some padding 0’s and then only about 19 entries from the actual scalers[32] branch. The main branch is called scaler (no s) and the leaf I want is indeed the scalers[32]. I get the same result whether I print out tree.scaler (no s, the branch name) or tree.scalers (the leaf I actually want). Below is the scan and print statements to show what I mean:

>>> tree.Scan()
***********************************************************************************
*    Row   * Instance * scaler.fU * scaler.fB * scaler.sc * scaler.sc * scaler.sc *
***********************************************************************************
*        0 *        0 *         0 *  50331648 *         0 *         8 *       447 *
*        0 *        1 *         0 *  50331648 *         0 *         8 *       214 *
*        0 *        2 *         0 *  50331648 *         0 *         8 *       418 *
*        0 *        3 *         0 *  50331648 *         0 *         8 *       225 *
*        0 *        4 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *        5 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *        6 *         0 *  50331648 *         0 *         8 *      1142 *
*        0 *        7 *         0 *  50331648 *         0 *         8 *       365 *
*        0 *        8 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *        9 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       10 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       11 *         0 *  50331648 *         0 *         8 *       172 *
*        0 *       12 *         0 *  50331648 *         0 *         8 *        82 *
*        0 *       13 *         0 *  50331648 *         0 *         8 *       208 *
*        0 *       14 *         0 *  50331648 *         0 *         8 *        42 *
*        0 *       15 *         0 *  50331648 *         0 *         8 *     77544 *
*        0 *       16 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       17 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       18 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       19 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       20 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       21 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       22 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       23 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       24 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       25 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       26 *         0 *  50331648 *         0 *         8 *        31 *
*        0 *       27 *         0 *  50331648 *         0 *         8 *        51 *
*        0 *       28 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       29 *         0 *  50331648 *         0 *         8 *       365 *
*        0 *       30 *         0 *  50331648 *         0 *         8 *         0 *
*        0 *       31 *         0 *  50331648 *         0 *         8 *         0 *

>>> Y = [y for y in tree.scalers]
>>> Y
[282595920, 1, 0, 50331648, 1784035568, 32685, 0, 0, 8, 0, 447, 214, 418, 225, 0, 0, 1142, 365, 0, 0, 0, 172, 82, 208, 42, 77544, 0, 0, 0, 0, 0, 0]

All the leaf names start with ‘sc’ so the scan shows everything as scaler.sc, but the last column is the array scalers[32] that I want to get out. If you inspect the list Y, you will see that it grabs values from the other branchs (scaler.fU, scaler.fB, etc) by seeing the Y[3] = 50331648, Y[6]= 0 and Y[8] = 8. But the list Y that I have made only has data from the scalers[32] array up to entry 21. You can see this by the value 77544 and the 6 zeros, it never gets to the 31, 51, … So I am missing the other 10 entries and I am not sure why.

I am just learning python/pyroot and so I wasn’t sure if somehow I needed to declare an array for the scalers[32] to get put into as in C++ and using setbranchaddress but that hasn’t yielded any results. I find the behavior odd to be the list Y, is the same whether I use tree.scalers or tree.scaler (no s).

Hi @megooden

Does it read the right values if you do this:

from array import array
a = array('I', 32 * [0])
t.SetBranchAddress('scalers[32]', a)
t.GetEntry(0)
for x in a:
    print(x)

An update on my previous post: since you have one top-level branch (scaler) that contains the other sub-branches, in order to directly read the sub-branches you need to specify a flag to the tree.

So the final code looks like this:

from array import array
a = array('I', 32 * [0])
t.SetMakeClass(1) # tell ROOT that we are reading branches in decomposed mode
t.SetBranchAddress('scalers[32]', a)
t.GetEntry(0)
for x in a:
    print(x)

@etejedor,

Thank you very much for this solution, it does work and I get the correct values! I had attempted the same thing at one point but I did not use SetMakeClass. I also might have not included the array portion of the scalers name in SetBranchAddress (i.e. [32]).

Thank you for the help,

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