CopyTree'ing several chains leads to a corrupted output tree

The following fairly simple code takes a series of tuples in a given mass range, chains them together and copies them into an output tuple.

It works fine, given a single mass range, but if I have a series of mass ranges the output files seem to become corrupted in some strange way, which means that when I try to read (TTree:GetEntry) them at certain points (EntryNumber > first file in the chain) they spit out lots of errors, or segfault.

The first output file is always fine, just the subsequent ones are broken - which makes me think that something is not being cleaned up. E.G. If I make it generate just the 60-130 mass range, the output is fine. Curiously, it has a different file size depending on whether I make it by itself [massRanges = (“60-130”,)] or several of them in one run of the program [massRanges = (“15-60”, “60-130”, “130-250”, “250-500”, “500p”)].

Am I doing something obvious wrong?

p.s. Additionally, if I do not ‘del c’ at the end of my for loop, when I do the last mass range I get a segfault (see below). The other del’s are my experimenting trying to get this to work.

[code]from ROOT import TChain, TFile, TTree

massRanges = (“15-60”, “60-130”, “130-250”, “250-500”, “500p”) # (“60-130”,) #

from os import listdir

inDir = "…"
outDir = “…”

files = listdir( inDir )

massDict = {}

for fileName in files:
for massRange in massRanges:
if massRange in fileName:
if massRange not in massDict:
massDict[massRange] = []
massDict[massRange].append( fileName )

#Mass range dict at this point looks like this

{ “15-60” : [ … list of directories containing output.root ],

“60-130” : [ … another list of directories containing output.root ], … etc… }

for massRange, files in massDict.iteritems():

# Chain together all files in a given mass range
c = TChain( "ZptNtuple" )
for fileName in files:
    c.Add( inDir + fileName + "/output.root" )
print "Copying tree for range: %10s GeV - %i events" % (massRange, c.GetEntries())
fOut = TFile( outDir + "ZptNtuple_%s.root" % massRange, "recreate" )
newTree = c.CopyTree("")
del c
del newTree
del fOut

print “Finished.”[/code]

#10 <signal handler called> #11 0x0a845bb8 in ?? () #12 0x072cb852 in TChain::~TChain$delete () from /scratch/work/pwaller/software/root/lib/root/ #13 0x07316194 in ROOT::delete_TChain () from /scratch/work/pwaller/software/root/lib/root/ #14 0x00d07f68 in TClass::Destructor () from /scratch/work/pwaller/software/root/lib/root/ #15 0x001a5e4d in PyROOT::op_dealloc_nofree () from /scratch/work/pwaller/software/root/lib/root/ #16 0x001a60d9 in PyROOT::(anonymous namespace)::op_dealloc () from /scratch/work/pwaller/software/root/lib/root/ #17 0x0067acd7 in subtype_dealloc (self=0xb7c68d74) at Objects/typeobject.c:709 #18 0x00663f4e in PyDict_SetItem (op=0xb7ed2acc, key=0xb7ef54e0, value=0x715268) at Objects/dictobject.c:416 #19 0x00667b58 in _PyModule_Clear (m=0xb7eba0ec) at Objects/moduleobject.c:136 #20 0x006c516b in PyImport_Cleanup () at Python/import.c:439 #21 0x006d2974 in Py_Finalize () at Python/pythonrun.c:399


I’ve been looking at it, but can’t figure it out. The 'del’s should be unnecessary (and if you do use them, I’d run them in reverse of the creation: “del newTree, fOut, c”). In addition, I’d expect the MemoryRegulator to prevent the double delete that appears to be happening. You can set the ownership to False:

from ROOT import SetOwnership SetOwnership( c, False )
to prevent python from calling ~TChain on ‘c’ altogether.

I don’t actually know if this is the right way to use CopyTree: the copyTree examples under tutorials use CloneTree instead, and the one use of CopyTree that I found there sets in addition a new name for the tree, but also calls BuildIndex(). Not sure if any of that makes a difference.


I think there is a bug or two here, but I am short of time, so instead I used the classic hadd macro in C, but interfaced to it from python. I cannot see any difference between what I am doing in python and what is happening in C, but for some reason the python crashes/corrupts data. I have given up trying to fix this for the moment.


  • Peter