Hi again,
Thanks, Wim, GetEntryWithIndex(), SetBranchAddress(), and new trees in helped a lot. In case it will help out someone out there, here’s what was needed:
To get values out of my five ntuples (named “Det1”, “Det2,”, “Det1,”, “Det4,”,and “Argu12”), I had ROOT make a struct, with one element for each leaf of each tree. Then I hooked it to all five TTrees:
#Invent a type of struct for holding stuff from the tree
ROOT.gROOT.ProcessLine(“struct treestuff { Int_t EventID; Int_t TrackID;
Float_t x1; Float_t y1; Float_t z1; Float_t t1; Float_t Px1; Float_t Py1; Float_t Pz1; Float_t PDGid1; Float_t ParentID1;
Float_t x2; Float_t y2; Float_t z2; Float_t t2; Float_t Px2; Float_t Py2; Float_t Pz2; Float_t PDGid2; Float_t ParentID2;
Float_t x3; Float_t y3; Float_t z3; Float_t t3; Float_t Px3; Float_t Py3; Float_t Pz3; Float_t PDGid3; Float_t ParentID3;
Float_t x4; Float_t y4; Float_t z4; Float_t t4; Float_t Px4; Float_t Py4; Float_t Pz4; Float_t PDGid4; Float_t ParentID4;
Float_t xT; Float_t yT; Float_t zT; Float_t tT; Float_t PxT; Float_t PyT; Float_t PzT; Float_t PDGidT; Float_t ParentIDT;
}” )
#Make one of them to use
pyTree = ROOT.treestuff()
#Hook the variables to their branches:
tuples[“Argu12”].SetBranchAddress( “EventID”,ROOT.AddressOf(pyTree,‘EventID’))
tuples[“Argu12”].SetBranchAddress( “TrackID”,ROOT.AddressOf(pyTree,‘TrackID’))
vars = (‘x’,‘y’,‘z’,‘t’,‘Px’,‘Py’,‘Pz’,‘PDGid’,‘ParentID’)
dets = (‘1’,‘2’,‘3’,‘4’,‘T’)
for var in vars:
for det in dets:
if det == ‘T’:
tuple = tuples[“Argu12”]
else:
tuple = tuples[“Det”+det]
tuple.SetBranchAddress(var, ROOT.AddressOf(pyTree,var+det))
…I also made my new tree,
The Output: A file with a tree in it.
outfile = ROOT.TFile(“MergedTree_gt1GeV.root”,“RECREATE”)
newTree = ROOT.TTree(“EventTree”,“EventTree”)
Two important branches to include:
EventID_p = array( ‘i’, [ 0 ] )
TrackID_p = array( ‘i’, [ 0 ] )
newTree.Branch(“EventID”,EventID_p,“EventID/I”)
newTree.Branch(“TrackID”,TrackID_p,“TrackID/I”)
…and all the others we want:
pointers = {}
for var in vars:
for det in dets:
name = var+det
pointers[name] = array( ‘d’, [ 0 ] )
newTree.Branch(name,pointers[name],name+"/d")
…where the tricky part is that dictionary called “pointers”, which I filled with single-entry arrays (!) of the right class type. That satisfied the pointer-to-a-variable-of-the-right-type requirement for the arguments of TTree::Branch().
Finally, my loop over one tree, get corresponding entries from all of the other four (if they exist), and stash all the variables in the new tree:
for ds_track in tuples[“Argu”+angle]:
## Unique identifiers for this track:
(event, track) = (int(ds_track.EventID), int(ds_track.TrackID))
if ds_track.Pz < 1000. : continue
Det1EntryNum = tuples["Det1"].GetEntryWithIndex(event,track)
Det2EntryNum = tuples["Det2"].GetEntryWithIndex(event,track)
Det3EntryNum = tuples["Det3"].GetEntryWithIndex(event,track)
Det4EntryNum = tuples["Det4"].GetEntryWithIndex(event,track)
## Ignore tracks not present in all detectors upstream of here:
if Det1EntryNum == -1 or Det2EntryNum == -1 or \
Det3EntryNum == -1 or Det4EntryNum == -1 : continue
## What I hate about this is that the newTree looks completely uninvolved.
## Of course, it's tied in above, at newTree.Branch(name,pointers[name],name+"/f")
EventID_p[0] = event
TrackID_p[0] = track
for name, pointer in pointers.iteritems():
## getattr can return the value of pyTree's member with the right name.
pointer[0] = getattr(pyTree,name)
newTree.Fill()
Thanks for pointing the way,
-jmsj