TTree in python root session

Hello

I am trying to fill a TTree inside the attached python code, but I am getting a seg fault. Any help is highly appreciated.

Cheers,
Ignacio

*** Break *** segmentation violation
Attaching to program: /proc/32642/exe, process 32642
[Thread debugging using libthread_db enabled]
[New Thread 0xf5724b90 (LWP 32648)]
0xffffe410 in __kernel_vsyscall ()
Thread 2 (Thread 0xf5724b90 (LWP 32648)):
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x00621e45 in sem_wait@@GLIBC_2.1 () from /lib/libpthread.so.0
#2 0x080ea093 in fix_status (lock=0x9851008, waitflag=1) at Python/thread_pthread.h:334
#3 PyThread_acquire_lock (lock=0x9851008, waitflag=1) at Python/thread.c:349
#4 0x080b9208 in PyEval_AcquireThread (tstate=0xa5d89d0) at Python/ceval.c:251
#5 0x080ee519 in t_bootstrap (boot_raw=0x9a9d358) at ./Modules/threadmodule.c:426
#6 0x0061b832 in start_thread () from /lib/libpthread.so.0
#7 0x0055be0e in clone () from /lib/libc.so.6

Thread 1 (Thread 0xf7fbaac0 (LWP 32642)):
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x0051b5db in waitpid () from /lib/libc.so.6
#2 0x004c007b in do_system () from /lib/libc.so.6
#3 0x004c0412 in system () from /lib/libc.so.6
#4 0x00623ead in system () from /lib/libpthread.so.0
#5 0xf77d95e3 in TUnixSystem::Exec(char const*) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#6 0xf77df27b in TUnixSystem::StackTrace() ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#7 0xf77dbc76 in TUnixSystem::DispatchSignals(ESignals) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#8 0xf77dbd04 in SigHandler(ESignals) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#9 0xf77daf81 in sighandler(int) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#10
#11 0xf6e05e9a in TGenCollectionStreamer::WriteObjects(int, TBuffer&) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#12 0xf6e07806 in TGenCollectionStreamer::Streamer(TBuffer&) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#13 0xf6dddd99 in TCollectionStreamer::Streamer(TBuffer&, void*, int, TClass*) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#14 0xf6dde7b7 in TCollectionClassStreamer::operator()(TBuffer&, void*) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#15 0xf779c1a6 in TClass::Streamer(void*, TBuffer&, TClass const*) const ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCore.so
#16 0xf6dd9d8e in TBufferFile::WriteFastArray(void*, TClass const*, int, TMemberStreamer*) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#17 0xf6ea23b5 in int TStreamerInfo::WriteBufferAux<char**>(TBuffer&, char** const&, int, int, int, int) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libRIO.so
#18 0xf6501013 in TBranchElement::FillLeaves(TBuffer&) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libTree.so
#19 0xf64fbc0d in TBranch::Fill() ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libTree.so
#20 0xf6500cca in TBranchElement::Fill() ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libTree.so
#21 0xf65490c8 in TTree::Fill() ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libTree.so
#22 0xf657418d in G__G__Tree_109_0_44(G__value*, char const*, G__param*, int) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libTree.so
#23 0xf6f86061 in Cint::G__CallFunc::Execute(void*) ()
from /afs/cern.ch/atlas/offline/external/LCGCMT/LCGCMT_56c/InstallArea/i686-slc4-gcc34-opt/lib/libCint.so
#24 0xf7c7ff1e in PyROOT::TIntExecutor::Execute(Cint::G__CallFunc*, void*) ()
from /afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/slc4_ia32_gcc34/root/lib/libPyROOT.so
#25 0xf7c85f08 in PyROOT::TMethodHolder<PyROOT::TScopeAdapter, PyROOT::TMemberAdapter>::CallSafe(void*) ()
from /afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/slc4_ia32_gcc34/root/lib/libPyROOT.so
#26 0xf7c86124 in PyROOT::TMethodHolder<PyROOT::TScopeAdapter, PyROOT::TMemberAdapter>::Execute(void*) ()
from /afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/slc4_ia32_gcc34/root/lib/libPyROOT.so
#27 0xf7c896cc in PyROOT::TMethodHolder<PyROOT::TScopeAdapter, PyROOT::TMemberAdapter>::operator()(PyROOT::ObjectProxy*, _object*, _object*) ()
from /afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/slc4_ia32_gcc34/root/lib/libPyROOT.so
#28 0xf7c8e16e in PyROOT::(anonymous namespace)::mp_call(PyROOT::MethodProxy*, _object*, _object*) ()
from /afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/slc4_ia32_gcc34/root/lib/libPyROOT.so
#29 0x0805e128 in PyObject_Call (func=0xa, arg=0xf7f7a02c, kw=0x0) at Objects/abstract.c:1861
#30 0x080bb90d in call_function (f=0x96821ac, throwflag=0) at Python/ceval.c:3823
#31 PyEval_EvalFrameEx (f=0x96821ac, throwflag=0) at Python/ceval.c:2304
#32 0x080c0ce5 in PyEval_EvalCodeEx (co=0xf7f39f08, globals=0xf7f96acc, locals=0xf7f96acc, args=0x0,
argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2875
#33 0x080c0e73 in PyEval_EvalCode (co=0xf7f39f08, globals=0xf7f96acc, locals=0xf7f96acc) at Python/ceval.c:514
#34 0x080e131c in run_mod (fp=0x963a008, filename=0xff9e1883 “ttreepyroot.py”, start=257, globals=0xf7f96acc,
locals=0xf7f96acc, closeit=1, flags=0xff9e054c) at Python/pythonrun.c:1273
#35 PyRun_FileExFlags (fp=0x963a008, filename=0xff9e1883 “ttreepyroot.py”, start=257, globals=0xf7f96acc,
locals=0xf7f96acc, closeit=1, flags=0xff9e054c) at Python/pythonrun.c:1259
#36 0x080e1e8a in PyRun_SimpleFileExFlags (fp=0x963a008, filename=0xff9e1883 “ttreepyroot.py”, closeit=1,
flags=0xff9e054c) at Python/pythonrun.c:879
#37 0x080e2925 in PyRun_AnyFileExFlags (fp=0x963a008, filename=0xff9e1883 “ttreepyroot.py”, closeit=1,
flags=0xff9e054c) at Python/pythonrun.c:698
#38 0x08057318 in Py_Main (argc=1, argv=0xff9e0684) at Modules/main.c:532
#39 0x08056812 in main (argc=2, argv=0xff9e0684) at ./Modules/python.c:23
A debugging session is active.

    Inferior 1 [process 32642] will be detached.

hltstruct.h (248 Bytes)
ttreepyroot.py (914 Bytes)

Hi,

Which version of ROOT are you using? Did you try with

tree.Branch("Type",ROOT.AddressOf(s,'type') )

Cheers,
Philippe.

Hi,

the version must be ‘5.22.00d’ (see the traceback), and the AddressOf should be applied automagically.

Cheers,
Wim

Hi,

I think I know what it is: the branch needs a pointer to a pointer and so it is given the address to the data member of the wrapper object of the vector. Problem is that the (python) property implementation is such that a new wrapper is created on each lookup (the property implementation makes the lookup go through functions rather than returning an object from the dictionary), and of course the result can be garbage collected any time after the lookup is done.

So the solution is to either use AddressOf() for these member just like it is done for the other members:tree.Branch("Type",ROOT.AddressOf(s,'type'),s.type.__class__.__name__) tree.Branch("Typesize",ROOT.AddressOf(s,'typesize'),s.typesize.__class__.__name__)or to keep a reference alive to these data members and use those.

This is actually an old problem in a different way: a struct that has a struct datamember can fail the lookup when going through two indirections, as the “middle” object may go dodo-bird along the way.

Cheers,
Wim

P.S. Edit: the second line should have read “typesize” instead of “type”, of course.

Hello Wim

thanks a lot Wim, with your suggestion it runs now. However it looks like the vector Branch is not being filled correctly. I modified my test code to something like :

for f in range(1,100):
s.eventnumber = f
for j in [‘a’,‘b’,‘c’]:
print j
s.type.push_back(j)
tree.Fill()
myfile.Write()
myfile.Close()

but when I scan thoroug the output I only see this:
root [1] hltresult->Scan(“EventNumber:Type”)


  • Row * EventNumb * Type *

  •    0 *         1 * 2.354e-32 *
    
  •    1 *         2 * 2.355e-32 *
    
  •    2 *         3 * 2.380e-32 *
    
  •    3 *         4 * 2.380e-32 *
    
  •    4 *         5 * 2.380e-32 *
    

etc
I would expect to see ‘a’,‘b’,‘c’ for each event. I must be missing something somewhere.

thanks again for your help.

Ignacio

Ignacio,

it’s not yet clear to me what exactly is going wrong as I haven’t had the time today to look into it. For now, this does work (artificially keeping the reference object alive): vs = s.type vt = s.typesize tree.Branch("Type",vs) tree.Branch("Typesize",vt)
More later.

Cheers,
Wim

Wim,

thank you, that works for now.

Cheers,
Ignacio

Ignacio,

I get it … I was misunderstanding the usage of TTree::Branch … If a class name is provided the order is “class name, object” not the other way around as I did above (in which case the class name is interpreted as a leaf list and that doesn’t get it the right type, hence the funky result of Scan()):tree.Branch("Type",s.type.__class__.__name__,s.type) tree.Branch("Typesize",s.typesize.__class__.__name__,s.typesize)as is per the TTree header:virtual TBranch *Branch(const char* name, void* address, const char* leaflist, ... virtual TBranch *Branch(const char* name, const char* classname, void* addobj, ...
Cheers,
Wim

Hi Wim

awesome! thanks a lot!

Ignacio