Hey guys,
I’d like to iterate over the events of a tree and randomly add them to two other trees: tree1 and tree2. I am quite new to this so excuse me if some things are wrong. I iterate over some root files, get their respective trees. I then create two new trees and two root files. I am now confused as to how I would go about getting an event from the original tree and then adding them to either tree1 or tree2. It’s not so much the process of randomly sorting them, rather I am not sure of the syntax used to getting an event and adding it to a tree. this is what I have so far:
def test():
bins = ["ybins","ptbins","y_ptbins"]
for i in os.listdir(TUPLE_PATH):
for bin_type in bins:
##DATASET1
if not os.path.exists(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/"):
os.makedirs(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/")
##DATASET2
if not os.path.exists(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/"):
os.makedirs(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/")
for root_file in os.listdir(TUPLE_PATH+i+"/bins/"+bin_type+"/"):
name = root_file
read_file = ROOT.TFile(TUPLE_PATH+i+"/bins/"+bin_type+"/"+name, "READ")
dataTree = read_file.Get("DecayTree")
file1 = ROOT.TFile(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/"+name,"RECREATE")
file2 = ROOT.TFile(TUPLE_PATH+i+"/random_data/dataset2/"+bin_type+"/"+name,"RECREATE")
tree1 = ROOT.TTree("DecayTree","DecayTree")
tree2 = ROOT.TTree("DecayTree","DecayTree")
You could either use TTree::AddClone or take advantage of RDataFrame with a Filter that selects random events and a Snapshot that writes out the output file.
Here is the AddClone versoin:
import ROOT
ROOT.RDataFrame(2).Define("x", "42").Snapshot("t", "f.root")
f = ROOT.TFile("f.root")
t = f.Get("t")
f2 = ROOT.TFile("f2.root", "recreate")
t2 = ROOT.TTree("t2", "t2")
t.AddClone(t2)
n = t.GetEntries()
for i in range(n):
t.GetEntry(0)
t2.Fill()
f2.Write()
Thanks for your suggestion. I used a bit of what you’ve told me. Here’s my code:
name = root_file
read_file = ROOT.TFile(TUPLE_PATH+i+"/bins/"+bin_type+"/"+name, "READ")
dataTree = read_file.Get("DecayTree")
file1 = ROOT.TFile.Open(TUPLE_PATH+i+"/random_data/dataset1/"+bin_type+"/"+name,"RECREATE")
file2 = ROOT.TFile.Open(TUPLE_PATH+i+"/random_data/dataset2/"+bin_type+"/"+name,"RECREATE")
tree1 = ROOT.TTree("DecayTree","DecayTree")
tree2 = ROOT.TTree("DecayTree","DecayTree")
tree1 = dataTree.CloneTree(0)
tree2 = dataTree.CloneTree(0)
n = dataTree.GetEntries()
x = 0
for entry in range(dataTree.GetEntries()):
#Progress
if(x%1000==0):
j = (x / n)*100
sys.stdout.write('\r')
sys.stdout.write("{0}%".format(str(int(j))))
sys.stdout.flush()
if(x==n):
sys.stdout.write("\r")
sys.stdout.write("100%")
sys.stdout.flush()
#50% probability of being added to dataset1 or dataset2
if(random.rand()>0.5):
dataTree.GetEntry(entry)
tree1.Fill()
else:
dataTree.GetEntry(entry)
tree2.Fill()
x+=1
file1.cd()
tree1.Write()
print("\nEvents in tree1: "+str(tree1.GetEntries()))
file1.Close()
file2.cd()
tree2.Write()
print("\nEvents in tree2: "+str(tree2.GetEntries()))
file2.Close()
read_file.Close()
print("\nRandomisation finished for: "+name)
basically I iterate over the events of a tree (dataTree) from a root file (read_file). and then I add events from this tree to two other trees (tree1 and tree2). ignore the file paths and etc. It successfully writes the trees and splits the events. However, when I open one of these files with the new trees, I have the events, but they have no distribution, rather they are all centered at 0. And I do get this error:
Error in <TFile::ReadBuffer>: error reading all requested bytes from file Xic_ybin_2.0-2.5.root, got 0 of 8141
@pcanal, this worked perfectly! However, do you have any idea why each file has two decay trees?
The original root files do have two decay trees, however I ran the program to clone the tree and write it to a new file and then immediately stop the script. When I looked at it in a TBrowser, there was only one decay tree as needed. However, when I let the script run its full course and actually add entries to this new tree, it creates two decay trees in the new file. Any idea why?