TTree I/O for TClonesArrays holding objects with pointers

Dear RootTalk,

This is a follow-up question to an earlier post:
http://root.cern.ch/phpBB2/viewtopic.php?t=9685

I would like to make a tree with a branch that holds TClonesArrays. The TClonesArrays contain a class that derives from TNamed and this time contain two new data members: a float (_value) and a TTimeStamp pointer (*_timeStamp).

Below, I show code that writes/reads the TTree. Again, I modeled this code after $ROOTSYS/tutorials/tree/tcl.C. The tree creation step appears to run correctly (doesn’t crash). The code to read the tree compiles, but seg-faults at runtime on tree->GetEvent(0) executes.

Any suggestions as to why this code fails? Perhaps the problem relates to streaming pointer data members? Apologies if this answer is in the User Guide. I was not able to find it there.

Also, a few other questions:

  1. In the tree writing step, is the TClonesArray->BypassStreamer() required (it was in the tutorial example)? From the TCA class documentation, it seems that this is only important when using different split levels (not the case here).

  2. In the tree reading step, is the Branch()->SetAutoDelete(kFALSE) required?

  3. In the MyClass.hh file, should I have included a //-> after TTimeStamp declaration:
    TTimeStamp *_timeStamp; //->
    I tried this as well, but still got the seg fault when reading the tree.

MyClass.hh[code]
#ifndef MYCLASS_HH
#define MYCLASS_HH

#include “TROOT.h”
#include “TNamed.h”
#include “TTimeStamp.h”

class TString;

class MyClass : public TNamed {

public:
MyClass();
MyClass(TString name, TString title);
MyClass(const MyClass &other);
virtual ~MyClass();
virtual void SetValue(Float_t newVal) {_value = newVal; }
virtual void SetTimeStamp(TTimeStamp newTime) { _timeStamp = newTime; }
virtual Float_t GetValue() { return _value; }
virtual TTimeStamp
GetTimeStamp() { return _timeStamp; }

void print();

private:

Float_t _value; // value of parameter
TTimeStamp *_timeStamp; // time the value was obtained
ClassDef(MyClass,1)

};
#endif[/code]

MyClass.cc[code]#include “MyClass.hh”
#include “TROOT.h”

#include
using std::cout;
using std::endl;

ClassImp(MyClass)

MyClass::MyClass(TString name, TString title) : TNamed(name, title) {}
MyClass::MyClass(const MyClass &other) : TNamed(other), _value(other._value) {
//cout << “copy ctor” << endl;
//cout << "other._value = " << other._value << endl;
//cout << "_value = " << _value << endl;
}
MyClass::MyClass() { cout << “def ctor” << endl; }
MyClass::~MyClass() {}

void MyClass::print() {
cout << "MyClass: name, title, value, timestamp = "
<< GetName() << ", " << GetTitle() << ", "
<< GetValue() << ", " << GetTimeStamp()->GetTime() << endl;
}[/code]

testtcaptr.cxx[code]
#include
#include “TClonesArray.h”
#include “TFile.h”
#include “TTree.h”
#include “TBranch.h”
#include “TString.h”
#include “TTimeStamp.h”
#include “…/MyClass.hh”

using namespace std;

void testtcawrite() {

TFile *logfile = new TFile(“junk.root”, “RECREATE”);
logfile->SetCompressionLevel(1); // is this required?
TTree *logtree = new TTree(“logtree”, “environment”);
TClonesArray *tca_ptr = new TClonesArray(“MyClass”);

logtree->Branch(“myBranch”, “TClonesArray”, &tca_ptr, 32000, 0);
tca_ptr->BypassStreamer(); // is this necessary? (taken from tutorial…)

for (Int_t ev=0; ev<5; ev++) {
tca_ptr->Clear();
Int_t nentries = 3;
for (Int_t ii=0; ii<nentries; ii++) {
MyClass myClass(“myClass”, “myClass entry”);
myClass.SetValue(ii+1);
TTimeStamp *myTime = new TTimeStamp();
myClass.SetTimeStamp(myTime);
new ( (*tca_ptr)[ii] ) MyClass(myClass);
}
logtree->Fill();
}

logtree->Print();
logtree->Write();
logfile->Close();
}

void testtcaread() {

TFile *f = new TFile(“junk.root”);
TTree t = (TTree)f->Get(“logtree”);

TClonesArray *tca = new TClonesArray(“MyClass”);
t->GetBranch(“myBranch”)->SetAutoDelete(kFALSE); // from tutorial…
t->SetBranchAddress(“myBranch”, &tca);

Int_t nentries = (Int_t)(t->GetEntries());
cout << "t->GetEntries() = " << nentries << endl;

tca->Clear();

cout << “t->GetEvent(0)” << endl;
t->GetEvent(0); // crashes…

}[/code]

Here’s the output I get:

root [0] .L testtcaptr.cxx+
root [1] testtcawrite()    
def ctor
******************************************************************************
*Tree    :logtree   : environment                                            *
*Entries :        5 : Total =            1942 bytes  File  Size =          0 *
*        :          : Tree compression factor =   1.00                       *
******************************************************************************
*Br    0 :myBranch  :                                                        *
*Entries :        5 : Total  Size=       1649 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*

root [2] testtcaread()     
t->GetEntries() = 5
t->GetEvent(0)
def ctor
def ctor
def ctor

 *** Break *** segmentation violation
(no debugging symbols found)
Attaching to program: /proc/26837/exe, process 26837
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0xb7f438e0 (LWP 26837)]
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.
(no debugging symbols found)...done.

0x007a8402 in __kernel_vsyscall ()
#1  0x0608bdf3 in __waitpid_nocancel () from /lib/libc.so.6
#2  0x0603106b in do_system () from /lib/libc.so.6
#3  0x0544687d in system () from /lib/libpthread.so.0
#4  0x00cdfb2b in TUnixSystem::Exec () from /usr/local/cern/root/lib/libCore.so
#5  0x00ce469b in TUnixSystem::StackTrace () from /usr/local/cern/root/lib/libCore.so
#6  0x00ce3695 in TUnixSystem::DispatchSignals () from /usr/local/cern/root/lib/libCore.so
#7  0x00ce3827 in SigHandler () from /usr/local/cern/root/lib/libCore.so
#8  0x00cdcc5d in sighandler () from /usr/local/cern/root/lib/libCore.so
#9  <signal handler called>
#10 0x00f07976 in ROOT::delete_TTimeStamp () from /usr/local/cern/root/lib/libCore.so
#11 0x00c556c5 in TClass::Destructor () from /usr/local/cern/root/lib/libCore.so
#12 0x00b8cf36 in TBuffer::ReadFastArray () from /usr/local/cern/root/lib/libCore.so
#13 0x00cb164d in TStreamerInfo::ReadBuffer<char**> () from /usr/local/cern/root/lib/libCore.so
#14 0x00c7ee59 in TStreamerInfo::ReadBufferClones () from /usr/local/cern/root/lib/libCore.so
#15 0x00c2f3bf in TClonesArray::Streamer () from /usr/local/cern/root/lib/libCore.so
#16 0x02ddfd58 in TLeafObject::ReadBasket () from /usr/local/cern/root/lib/libTree.so
#17 0x02db18af in TBranch::ReadLeaves () from /usr/local/cern/root/lib/libTree.so
#18 0x02db2fa8 in TBranch::GetEntry () from /usr/local/cern/root/lib/libTree.so
#19 0x02dc5918 in TBranchObject::GetEntry () from /usr/local/cern/root/lib/libTree.so
#20 0x02df8a31 in TTree::GetEntry () from /usr/local/cern/root/lib/libTree.so
#21 0x06a1e2fa in testtcaread () from /home/jbattat/projects/DarkMatter/MaxCam/examples/./testtcaptr_cxx.so
#22 0x06a1e319 in G__fileuOEB8A__0_1650 ()
   from /home/jbattat/projects/DarkMatter/MaxCam/examples/./testtcaptr_cxx.so
#23 0x0014d825 in Cint::G__ExceptionWrapper () from /usr/local/cern/root/lib/libCint.so
#24 0x00222d66 in G__call_cppfunc () from /usr/local/cern/root/lib/libCint.so
#25 0x001fbf58 in G__interpret_func () from /usr/local/cern/root/lib/libCint.so
#26 0x001f0525 in G__getfunction () from /usr/local/cern/root/lib/libCint.so
#27 0x001c76ae in G__getitem () from /usr/local/cern/root/lib/libCint.so
#28 0x001d6d38 in G__getexpr () from /usr/local/cern/root/lib/libCint.so
#29 0x00230bd8 in G__exec_function () from /usr/local/cern/root/lib/libCint.so
#30 0x00236080 in G__exec_statement () from /usr/local/cern/root/lib/libCint.so
#31 0x001b3d45 in G__exec_tempfile_core () from /usr/local/cern/root/lib/libCint.so
#32 0x001b4003 in G__exec_tempfile_fp () from /usr/local/cern/root/lib/libCint.so
#33 0x0024327f in G__process_cmd () from /usr/local/cern/root/lib/libCint.so
#34 0x00c53d64 in TCint::ProcessLine () from /usr/local/cern/root/lib/libCore.so
#35 0x00b7e224 in TApplication::ProcessLine () from /usr/local/cern/root/lib/libCore.so
#36 0x007836d0 in TRint::HandleTermInput () from /usr/local/cern/root/lib/libRint.so
#37 0x00782d3d in TTermInputHandler::Notify () from /usr/local/cern/root/lib/libRint.so
#38 0x00784cb6 in TTermInputHandler::ReadNotify () from /usr/local/cern/root/lib/libRint.so
#39 0x00ce335c in TUnixSystem::CheckDescriptors () from /usr/local/cern/root/lib/libCore.so
#40 0x00ce3970 in TUnixSystem::DispatchOneEvent () from /usr/local/cern/root/lib/libCore.so
#41 0x00c023b3 in TSystem::InnerLoop () from /usr/local/cern/root/lib/libCore.so
#42 0x00c038c7 in TSystem::Run () from /usr/local/cern/root/lib/libCore.so
#43 0x00b7d37c in TApplication::Run () from /usr/local/cern/root/lib/libCore.so
#44 0x00784ab9 in TRint::Run () from /usr/local/cern/root/lib/libRint.so
#45 0x08048d20 in main ()
The program is running.  Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
Detaching from program: /proc/26837/exe, process 26837
Root > 

Thank you,
James

You have at least an obvious bug in MyClass. you should initialize the member _timeStamp=0 in your constructors.

Rene