ROOT Version: 6.24/02
Platform: Linux
Dear experts,
I have a tree that contains among others two branches of which one is a vector and the other is a vector. Both vectors have the same size and the entries are paired (i.e. the string at index 0 belongs to the float at index 0 of the other vector).
I’m trying to create a new tree which is a clone of the old one without the two vector branches (I managed to do this successfully) but instead add a new float branch with the name of the string of vector1 and the value of vector2. The problem here is, that first the vectors are very large (like up to 700 entries) and the size is not fixed (e.g. once it’s 700 entries and for another use case it might be 500 entries or even just 20). Furthermore, the trees itself have many entries >300 millions. This has the consequence that I can’t create a new variable for each entry but need to use some sort of list/array/vector/dict/loop to store the variables. I already tried several approaches but none seems to fill the tree with the right values:
- Approach 1:
tmp_tree.SetBranchStatus("weightSystematic*",0)
#clone tree
tree =tmp_tree.CloneTree(0)
#reset branch status to have access
tmp_tree.SetBranchStatus("*",1)
tmp_tree.GetEntry(0)
varvalue=[]
for ivar in xrange(0,len(tmp_tree.weightSystematicName)):
var=str(tmp_tree.weightSystematicName[ivar])
varvalue.append(array('f',[0]))
tree.Branch(var,varvalue[ivar],var+"/F")
i=0
for i in xrange(1,tmp_tree.GetEntries()):
for ivar in xrange(0,len(tmp_tree.weightSystematicName)):
varvalue[ivar] = array('f',[tmp_tree.weightSystematicValue[ivar]])
tree.Fill()
tmp_tree.GetEntry(i)
This gives me the correct branches but the values are kind of arbitrary, either it’s some value that could correspond to another branch or it’s 0 or extremely large (values that aren’t present in the tree but I assume come from some floating point stuff. I also tried with replacing the list by a dictionary with the same result.
- Approach 2:
tmp_tree.SetBranchStatus("weightSystematic*",0)
#clone tree
tree =tmp_tree.CloneTree(0)
#reset branch status to have access
tmp_tree.SetBranchStatus("*",1)
tmp_tree.GetEntry(0)
for ivar in xrange(0,len(tmp_tree.weightSystematicName)):
var=str(tmp_tree.weightSystematicName[ivar])
value = array('f',[tmp_tree.weightSystematicValue[ivar]])
newbranch=tree.Branch(var,value,var+"/F")
for i in xrange(tmp_tree.GetEntries()):
if ivar==0: tree.Fill()
tmp_tree.GetEntry(i)
newbranch.Fill()
This only results in the last value to be filled properly, while the others are just very large values.
- Approach 3:
for i in xrange(tmp_tree.GetEntries()):
tmp_tree.GetEntry(i)
tree.Fill()
for ivar in xrange(0,len(tmp_tree.weightSystematicName)):
var=str(tmp_tree.weightSystematicName[ivar])
value = array('f',[tmp_tree.weightSystematicValue[ivar]])
if i==0:
newbranch=tree.Branch(var,value,var+"/F")
else:
newbranch=tree.GetBranch(var)
newbranch.Fill()
Very similar to approach 2 but with the order changed. And the result is also the same.
I really hope that you can maybe provide some guidance how to solve this. I looked through the forum but haven’t found a similar problem. If doing this is only possible in C++, I can also convert my code from PyROOT to “standard” Root, but I would prefer a solution in python.
Thank you very much in advance,
Kira