Python fill variable length array to tree

Hi,
I am trying to convert the content of a bunch of txt files to a root tree.
Each of the txt files corresponds to one event and just contains two columns, time and amplitude:

1.800015e-05, 4.000000e-03
1.801015e-05, 1.200000e-02
1.802015e-05, 8.000000e-03
1.803015e-05, 8.000000e-03
1.804015e-05, 8.000000e-03
1.805015e-05, 4.000000e-03
1.806015e-05, 4.000000e-03
1.807015e-05, 4.000000e-03
1.808015e-05, 8.000000e-03
1.809015e-05, 8.000000e-03

I want to fill these wave forms into a tree. This is my code:

rfile = root.TFile.Open("tree.root", "RECREATE")
tree = root.TTree("tree","tree")
wf_length = array('i',[0])
wf_time = array('d', 10000*[0.])
wf_ampl = array('d', 10000*[0.])

tree.Branch('wf_length', wf_length, 'wf_length/I')
tree.Branch('wf_time', wf_time, 'wf_time[wf_length]/D')
tree.Branch('wf_ampl', wf_ampl, 'wf_ampl[wf_length]/D')

for f in file_list:
    f = args.inpath + f
    v = np.loadtxt(f,unpack=True, comments="#",skiprows=0,delimiter=',')

    wf_length[0] = len(v[0])

    # does not work                                                                                                               
    #wf_time = v[0]                                                                                                               
    #wf_ampl = v[1]    
                                                                                                       
    # does not work                                                                                                               
    #wf_time = array('d',v[0])                                                                                                    
    #wf_ampl = array('d',v[1])        

    # this works                                                                                  
    for i in range(wf_length[0]):
        wf_time[i] = v[0][i]
        wf_ampl[i] = v[1][i]


    tree.Fill()

rfile.Write("",root.TFile.kOverwrite)
rfile.Close()

As you can see, I manage to accomplish my goal, but I would have assumed that tone of the two options with are commented “does not work” would give the same results.
I would appreciate some suggestions.
I am using:
ROOT Version: 6.24/04
Built for linuxx8664gcc on Aug 25 2021, 12:59:28
From tags/v6-24-04@v6-24-04
Python 2.7.16

Hi,

Thanks for the instructive post and welcome to the ROOT community!
I think what is happening is linked to what Python does upon assignment, and ultimately its memory management. With these three lines

tree.Branch('wf_length', wf_length, 'wf_length/I')
tree.Branch('wf_time', wf_time, 'wf_time[wf_length]/D')
tree.Branch('wf_ampl', wf_ampl, 'wf_ampl[wf_length]/D')

you instructed the TTree instance tree to flush on disk the content pointed by the arrays wf_length/time/ampl. This is very efficient: you fill your data structures in the event loop (even if in your case this loop has logically length 1) and when TTree.Fill is called, the content of those data structures is “snapshotted” as an entry (“row”) of the TTree.

With assignments like these ones

wf_time = v[0]

in Python you are basically loosing track of the original memory pointed by wf_time, and the variable wf_time becomes an alias of v[0] (it points to its address in memory). The TTree, however, is linked to the original pointee of wf_time.
This is why filling the content of the vectors, your 3rd case, works.

I hope this clarifies a bit the situation.

Cheers,
D

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