Thanks for the answer, but I’m still rather confused. Below is the actual code I wish to use (with irrelevant bits removed). Perhaps this will make it more clear what I am trying to do.
outfile = ROOT.TFile("testout.root","recreate")
outtree = ROOT.TTree("proto2",outfile.GetName())
pairinfo_def = "struct pairinfo{\
Int_t n_pair;\
Float_t arrival_time,charge;\
};\
"
ROOT.gROOT.ProcessLine(pairinfo_def)
#For each electron-ion pair in each cluster there is a pairinfo.
from ROOT import pairinfo
NPAIRSMAX = 300
ROOT.gROOT.ProcessLine(\
"struct clusterinfo{\
Int_t n_cluster;\
Float_t drift_time, diffusion;\
Int_t pairs;\
pairinfo pair["+str(NPAIRSMAX)+"];\
};")
#For each cluster in each track there is a clusterinfo.
from ROOT import clusterinfo
NSAMPLES = 1024
ROOT.gROOT.ProcessLine(\
"struct signalinfo{\
Int_t n_wire;\
Float_t signal["+str(NSAMPLES)+"];\
Int_t timeidx["+str(NSAMPLES)+"];\
};")
#I have one signalinfo per signal saved per track.
from ROOT import signalinfo
NCLUSTERSMAX = 300
NSIGNALS = 1
ROOT.gROOT.ProcessLine(\
"struct trackinfo{\
Int_t n_track;\
Float_t x0,y0,z0,x1,y1,z1;\
Int_t n_clusters;\
clusterinfo cluster["+str(NCLUSTERSMAX)+"];\
signalinfo signals["+str(NSIGNALS)+"];\
};")
#I have one trackinfo per track, with many clusterinfos inside.
#There are also signalinfos inside the trackinfo.
from ROOT import trackinfo
track = ROOT.trackinfo()
for i in range(NCLUSTERSMAX):
track.cluster[i] = ROOT.clusterinfo()
for cluster in track.cluster:
cluster.pair = [ROOT.pairinfo() for i in range(NPAIRSMAX)]
track.signal = [ROOT.signalinfo() for i in range(NSIGNALS)]
outtree.Branch('n_track',ROOT.AddressOf(track,'n_track'),'n_track/i')
outtree.Branch('x0',ROOT.AddressOf(track,'x0'),'x0/F')
outtree.Branch('y0',ROOT.AddressOf(track,'y0'),'y0/F')
outtree.Branch('z0',ROOT.AddressOf(track,'z0'),'z0/F')
outtree.Branch('x1',ROOT.AddressOf(track,'x1'),'x1/F')
outtree.Branch('y1',ROOT.AddressOf(track,'y1'),'y1/F')
outtree.Branch('z1',ROOT.AddressOf(track,'z1'),'z1/F')
outtree.Branch('n_clusters',ROOT.AddressOf(track,'n_clusters'),'n_clusters/i')
outtree.Branch('cluster','clusterinfo',track.cluster)
outtree.Branch('signal','signalinfo',track.signal)
while True:
fill_each_variable()
outtree.Fill()
outfile.Write()
outfile.Close()
end_time = time.time()
Of course this one does not work, it fails on
with error message: ‘clusterinfo’ object does not support item assignment
My plan was to have one trackinfo object only, including all the data members clusterinfo, signalinfo, and pairsinfo. After filling all of these, I would call outtree.Fill(), then change all the values and fill() again. At the end I would write to the file and close it.
Is it possible, or is my proposed data structure too complex? Would it be easier to “flatten” the tree? Instead of giving each entry an array of clusterinfo objects, I could just give the entry a whole bunch of individually addressed clusterinfos. I could probably do all the outtree.Branch() calls in a loop. That feels like giving up though.
Jean-François