Hi all, I have the following code, which reads data from a file and make a TTree out of it.
Here’s the relevant part (Python 2.5.2 and Root 5.18 running on Kubuntu
Intrepid 8.10):
import ctypes
from ROOT import TFile, TTree, TBranch
...
class Event(ctypes.Structure):
_fields_ = [('number', ctypes.c_int),
('nhit', ctypes.c_int)]
...
event = Event(0, 0)
event_tree = TTree("event_tree", "analysis")
event_tree.Branch("event", event, "number/I:nhit")
...
for line in file:
l = [int(x) for x in line.split()]
event = Event(*l)
event_tree.Fill()
if I check the content of the event structure with a “print” statement
they are all read correctly, but the tree is filled with absurd and somewhat random numbers
like 2.356e-260. It looks like there is something wrong with memory
management.
you’re taking an address to a certain object, then let it go dodo-bird by reassigning the reference. You should 1) keep the ‘event’ object alive, which is easiest accomplished by adding it to event_tree; and 2) only assign to your original event structure as that is the one that the tree knows about. So, remove these:event = Event(0, 0)
...
event = Event(*l)since they simply create new Event objects while destroying the old one that the tree knows about, and replace them with full assignments to event.number and event.nhit. Then add somewhere at the beginning:event_tree._bufevent = eventto keep the original event object alive (at least as long as the tree is alive).
However, I feel the code is very non-pythonic.
I mean, I have equivalent code in C++, and it may be considered by reasonable standards more elegant now, which is something actually surprising.
I could hide the direct assignments in a method of the Event class, but I’m quite uncomfortable with this script anyway.
It looks like PyROOT thinks in C++, thus making implementations rather awkward sometimes.
the fact that the code underneath is C++ does show through, yes: it’s a direct binding, not a fresh minted interface on top of it. Compare it with reading the tree, which allows access of the branches as if they were members of the tree, which is a layered interface. If you have any ideas to improve writing, then I’m all ears.
However, using direct assignment to the reference, which was the main problem, can not be hidden at the global level so it’s pure python issue, not an underlying C++ one.