Is there some trick to using TChains in pyroot? When I try to use them, I get a seg fault that appears to come from their destruction at the end of a job. I’m using ROOT version 5.20/00 with python version 2.5.2, and the effect seems pretty stable over different ntuples and minor variations of the access method.
What I’m doing is something like this:
[code]>>> import ROOT
chain = ROOT.TChain(‘CollectionTree’)
TClass::TClass:0: RuntimeWarning: no dictionary for class AttributeListLayout is available
TClass::TClass:0: RuntimeWarning: no dictionary for class pair<string,string> is available
That much is fine. But when I exit, I get the aforementioned seg fault. The output of this, and an example ntuple file which can produce these results are both on lxplus (~flowerde/public/testNtuple/). If I don’t call chain.GetEntries(), I get no seg fault, and I also get nothing odd in “normal” ROOT.
Thanks for any help,
the file that the TChain holds onto has is being removed on gROOT cleanup and the TChain doesn’t get or doesn’t take notification. The cleanup had to be done or similar crashes would be seen with proof, but apparently it’s still to early when running in an interactive session.
Under C++, the shutdown sequence is a little different.
What helps is to destroy the TChain explicitly at the end of the session:[code]>>> del chain
I can’t think of anything smarter right now …
Thanks for the quick, clear reply. This seems to work, but only if called in the main script. In reality, I handle the TChain through a python object, and apparently its del method is also too late to delete the chain (even if I delete the object - but not its chain - in the main script).
For TTrees, keeping an explicit reference to the corresponding TFile seemed to be necessary to avoid errors, but my naive attempts to keep a list of TFiles corresponding to the TChain didn’t work. Is there some way of associating a TChain directly with an existing TFile? I mean, in the way that TFile::Get does for a TTree (but I notice there’s no TChain::Add(TTree*) method). On the other hand, my guess here may be way off mark, please ignore if it’s obvious rubbish
the object with a TChain data member should work (and does, for me). The deletion problem can’t be helped that easily from the python side, as it all happens on the C++ side and the cleanup of gROOT happens at shutdown of the python interpreter, not after its shutdown.
That is, ROOT has a “CleanUpROOTAtExit” method that is called by the C-version of atexit, whereas the equivalent for PyROOT is called at the python version of atexit. Note that the C atexit is also called with python, but as said, that caused crashes with PROOF (deletion being too late).
It may be good enough to only clean out the list of sockets early, and leave the files to the C atexit. I’ll play with that.
Is there in the meantime a nicer solution around than “del chain”?
Or is it planned to solve that?
it is fixed in trunk as well as in 5.22-patches.
But the only nicer solution than del chain, is to scope the chain in a function (so that it becomes a local variable and gets automatically removed).