Issues trying to open a bi-dimensional array leave contained in a ROOT Tree in Pyroot

248 Views Asked by At

I’m stuck with a problem using Pyroot. I’m not able to read a leaf on a tree which is a two dimensional array of float values. You can see the related Tree in the following:

root [1] TTree tr=(TTree)g->Get(“tevent_2nd_integral”)
root [2] tr.Print()
*Tree :tevent_2nd_integral: Event packet tree 2nd GTUs integral *
*Entries : 57344 : Total = 548967602 bytes File Size = 412690067 *

:          : Tree compression factor =   1.33                 *
*Br 7 :photon_count_data : photon_count_data[1][1][48][48]/F *
*Entries : 57344 : Total Size= 530758073 bytes File Size = 411860735 *
*Baskets : 19121 : Basket Size= 32000 bytes Compression= 1.29 *
…

The array (the bold one) is photon_count_data[1][1][48][48]. Actually i have several root files and I tried both to make a chain and to use hadd method like hadd file.root 'ls /path/.root’.* I tried several ways as i will show soon. Anytime i found different problem: once the numpy array which should contain the 48x48 values per each event was not created at all, others just didn’t write anything or strange values (negative also which is not possible). My code is the following:

# calling the root file after using hadd to merge all files
rootFile = path+"merge.root"
f = XROOT.TFile(rootFile,'read')
tree = f.Get('tevent_2nd_integral')

# making a chain
PDMchain=TChain("tevent_2nd_integral")
for filename in sorted(os.listdir(path)):
    if filename.endswith('.root') and("CPU_RUN_MAIN"  in filename) :
        PDMchain.Add(filename)

pdm_counts = []
#First method using python pyl class
leaves = tree.GetListOfLeaves()
# define dynamically a python class containing root Leaves objects
class PyListOfLeaves(dict) :
    pass

# create an istance
pyl = PyListOfLeaves()

for i in range(0,leaves.GetEntries() ) :
    leaf = leaves.At(i)
    name = leaf.GetName()
    # add dynamically attribute to my class 
    pyl.__setattr__(name,leaf)

for iev in range(0,nEntries_pixel) :
    tree.GetEntry(iev) 
    pdm_counts.append(pyl.photon_count_data.GetValue())

# the Draw method
count = tree.Draw("photon_count_data","","")
pdm_counts.append(np.array(np.frombuffer(tree.GetV1(), dtype=np.float64, count=count)))

#ROOT buffer method
for event in PDMchain:
    pdm_data_for_this_event = event.photon_count_data
    pdm_data_for_this_event.SetSize(2304)  #ROOT buffer
    pdm_couts.append(np.array(pdm_data_for_this_event,copy=True))
  1. with the python class method the array pdm_counts is filled with just the first element contained in photon_count_data
  2. with the Draw method I get a segmentation violation or a strange kernel issue
  3. with the root buffer method I get right back a list containing all the 2304 (48x48) values but they are completely different from those in the photon_count_data, id est, negative values or orders of magnitude senseless

Could you tell me where I’m wrong or if there could be a more elegant and quick method to do so. Thanks in advance

1

There are 1 best solutions below

0
On

actually I found the solution and I would like to share it if anytime someone will need it! Actually the third method explained

for event in PDMchain:
    pdm_data_for_this_event = event.photon_count_data
    pdm_data_for_this_event.SetSize(2304)  #ROOT buffer
    pdm_couts.append(np.array(pdm_data_for_this_event,copy=True))

works, but unfortunately I was using Spyder to visualize data and for some reason it return strange values which are not right! So...don't use Spyder!!! Moreover another method works fine:

from root_pandas import read_root
data = read_root('merge.root', 'tevent_2nd_integral', columns=['cpu_packet_time', 'photon_count_data'])

Cheers!