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("")
newTree.Write()
fOut.Write()
fOut.Close()
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/libTree.so #13 0x07316194 in ROOT::delete_TChain () from /scratch/work/pwaller/software/root/lib/root/libTree.so #14 0x00d07f68 in TClass::Destructor () from /scratch/work/pwaller/software/root/lib/root/libCore.so #15 0x001a5e4d in PyROOT::op_dealloc_nofree () from /scratch/work/pwaller/software/root/lib/root/libPyROOT.so #16 0x001a60d9 in PyROOT::(anonymous namespace)::op_dealloc () from /scratch/work/pwaller/software/root/lib/root/libPyROOT.so #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

Hi,

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.

Cheers,
Wim

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.

Regards,

  • Peter