RE: Writing TClonesArray to File

From: Oliver Oberst <oberst_at_ekp.uni-karlsruhe.de>
Date: Thu, 21 Dec 2006 18:24:56 +0100


Hi Philippe,

thanks for your fast answer. Unfortunately your suggestion did not work and the TClonesArray is still not browsable. If you want I can send you the tarball and the instructions how to get it run, but before I do so (getting everything to run is realy timeconsuming) just look at this perhaps it will be a better hint to the problem:

I did this on my rootfile (now made with new dictionary with updated LinkDef)

root [0] .L /path/to/my/shared/lib/libHepMCEvent.so
root [1] TFile *f = new TFile("herwig++.root"); 
root [2] TTree *t4= (TTree*)f->Get("HepMCEvents"); 
root [3] TBranch *branch = t4->GetBranch("EventBranch");
root [4] HepMCEvent *evento = new HepMCEvent();
root [5] branch->SetAddress(&evento);
root [6] Int_t nevent = t4->GetEntries();
root [7] cout << nevent

100(class ostream)-1233807200
root [8] for (Int_t i=0; i<nevent; i++){ t4->GetEntry(i);}

her i get segfault with:

Cutting the TClonesArray out of the Code and just writing the 'event branch' works without segfaults...

Thx
Oliver

On Wed, 2006-12-20 at 13:36 -0600, Philippe Canal wrote:
> Hi Olivier,
>
> We strongly recommend that you update your LinkDef to generate
> the 'new' type of streamer (based on TStreamerInfos) (this
> will improve performance and add support for schema evolution)
>
> #pragma link C++ class HepMCEvent+;
>
> [Note the trailing +].
>
> When splitting the Streamer function should NOT be called
> (in part because the data member of a single object are NOT
> saved serially).
>
> If after changing your linkdef file, you still see the
> problem, please send us a tar file containing all the source
> (and makefile) necessary to build your example and describe
> precisely what you see and how it differs from what you expect.
>
> Cheers,
> Philippe.
>
>
> -----Original Message-----
> From: owner-roottalk_at_pcroot.cern.ch [mailto:owner-roottalk_at_pcroot.cern.ch]
> On Behalf Of Oliver Oberst
> Sent: Wednesday, December 20, 2006 12:16 PM
> To: roottalk_at_pcroot.cern.ch
> Subject: [ROOT] Writing TClonesArray to File
>
> Hello,
>
> I am writing a rootinterface for a MC Generator. I wrote my on
> eventclass, verticesclass and particleclass all inheriting from TObject.
> Now in the interface i make a tree and give a Branch the events address.
> in This eventbrach i want to have a TClonesArray of my vertexobjects.
> I built the dictionary and it worked so that the event and the vertex
> class have their own streamer.
> I tested the TClonesarray in the code so that i now know that filling
> the TClonesArray workes(I can readout vertex members after filling the
> array).
> I think the problem is when the event streamer calls the
> 'TClonesArrayobject'->Streamer(b) and there the Vertex Streamer is not
> called. Because i only see the events members as leafes and one leaf
> with the name of the TClonesArray. Normaly it should be browsable
> because i split the tree (with 99). I now do not see why the
> TClonesArray with my Vertex Objects are not streamed in the file and it
> is not browsable...
>
> Code:
> -------------------------------------------------------------------
> Streamers in dictionary which is linked in my shared lib:
>
> void HepMCEvent::Streamer(TBuffer &R__b)
> {
> // Stream an object of class HepMCEvent.
>
> UInt_t R__s, R__c;
> if (R__b.IsReading()) {
> Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
> TObject::Streamer(R__b);
> R__b >> signal_process_id;
> R__b >> event_number;
> R__b >> event_scale;
> R__b >> alphaQCD;
> R__b >> alphaQED;
> R__b >> vertices_size;
> Vertices->Streamer(R__b);
> R__b.CheckByteCount(R__s, R__c, HepMCEvent::IsA());
> } else {
> R__c = R__b.WriteVersion(HepMCEvent::IsA(), kTRUE);
> TObject::Streamer(R__b);
> R__b << signal_process_id;
> R__b << event_number;
> R__b << event_scale;
> R__b << alphaQCD;
> R__b << alphaQED;
> R__b << vertices_size;
> Vertices->Streamer(R__b);
> R__b.SetByteCount(R__c, kTRUE);
> }
> }
> ---snip
> void HepMCVertex::Streamer(TBuffer &R__b)
> {
> // Stream an object of class HepMCVertex.
>
> UInt_t R__s, R__c;
> if (R__b.IsReading()) {
> Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
> TObject::Streamer(R__b);
> R__b >> barcode;
> R__b >> id;
> R__b >> position_x;
> R__b >> position_y;
> R__b >> position_z;
> R__b >> position_t;
> R__b >> numOrphan;
> R__b >> particles_out_size;
> R__b.CheckByteCount(R__s, R__c, HepMCVertex::IsA());
> } else {
> R__c = R__b.WriteVersion(HepMCVertex::IsA(), kTRUE);
> TObject::Streamer(R__b);
> R__b << barcode;
> R__b << id;
> R__b << position_x;
> R__b << position_y;
> R__b << position_z;
> R__b << position_t;
> R__b << numOrphan;
> R__b << particles_out_size;
> R__b.SetByteCount(R__c, kTRUE);
> }
> ----------------------------------------------------------------------------
> ------
> ----------------------------------------------------------------------------
> --------
> The EventHeader:
> ----------------------------------------------------------------------------
> ------
> #ifndef HepMCEvent_H
> #define HepMCEvent_H
>
> #include"TObject.h"
> #include"TClonesArray.h"
>
> #ifndef __MAKECINT__
> #include "CLHEP/HepMC/GenEvent.h"
> #endif
>
> class TClonesArray;
> class HepMCVertex;
>
> class HepMCEvent : public TObject{
>
> public:
> HepMCEvent(){};
> ~HepMCEvent(){};
>
> #ifndef __MAKECINT__
> HepMCEvent(HepMC::GenEvent *hepmc);
> #endif
>
> void finish();
>
> private:
>
> int signal_process_id;
> int event_number;
> double event_scale;
> double alphaQCD;
> double alphaQED;
>
> int vertices_size;
>
> TClonesArray *Vertices; //-> TClonesArray of my Vertices
>
> ClassDef(HepMCEvent,1)
>
> };
>
> #endif
> --------------------------------------------------------------
> -------------------------------------------------------------
> The Event Body:
> --------------------------------------------------------------
> #include <iostream>
> #include "HepMCEvent.h"
> #include "HepMCVertex.h"
>
> ClassImp(HepMCEvent);
>
> using namespace std;
>
> HepMCEvent::HepMCEvent(HepMC::GenEvent *hepmc){
> signal_process_id = hepmc->signal_process_id();
> event_number = hepmc->event_number();
> event_scale = hepmc->event_scale();
> alphaQCD = hepmc->alphaQCD();
> alphaQED = hepmc->alphaQED();
> vertices_size = hepmc->vertices_size();
>
> Vertices = new TClonesArray("HepMCVertex", vertices_size);
> //TClonesArray Vert("HepMCVertex", vertices_size);
>
> int vert_count = 0;
> for( HepMC::GenEvent::vertex_const_iterator v =
> hepmc->vertices_begin();
> v != hepmc->vertices_end(); ++v ){
> new((*Vertices)[vert_count]) HepMCVertex(*v);
> vert_count++;
> }
> //HepMCVertex *temp = (HepMCVertex*) Vertices->At(0);
> // temp->print_barcode();
> }
>
> void HepMCEvent::finish(){
>
> }
> --------------------------------------------------------------
> --------------------------------------------------------------
> The Vertex Header:
> --------------------------------------------------------------
> #ifndef HepMCVertex_H
> #define HepMCVertex_H
>
> #include"TObject.h"
>
> #ifndef __MAKECINT__
> #include "CLHEP/HepMC/GenEvent.h"
> #include "CLHEP/HepMC/GenVertex.h"
> #endif
>
> class HepMCEvent;
>
> class HepMCVertex : public TObject{
>
> public:
>
> HepMCVertex(){};
> ~HepMCVertex(){};
>
> #ifndef __MAKECINT__
> HepMCVertex(HepMC::GenVertex *vertex);
> #endif
>
> void print_barcode();
> private:
>
> int barcode;
> int id;
> double position_x;
> double position_y;
> double position_z;
> double position_t;
>
> int numOrphan;
> int particles_out_size;
>
> ClassDef(HepMCVertex,1)
> };
>
> #endif
> --------------------------------------------------------------
> -------------------------------------------------------------
> The Vertex Body:
> --------------------------------------------------------------
> #include <iostream>
> #include "HepMCVertex.h"
>
> ClassImp(HepMCVertex);
>
> using namespace std;
>
> HepMCVertex::HepMCVertex(HepMC::GenVertex *vertex){
> int numOrph = 0;
> for ( HepMC::GenVertex::particles_in_const_iterator p =
> vertex->particles_in_const_begin();
> p != vertex->particles_in_const_end(); ++p ){
> if ( !(*p)->production_vertex() ) ++ numOrph;
> }
>
> barcode = vertex->barcode();
> id = vertex->id();
> position_x = vertex->position().x();
> position_y = vertex->position().y();
> position_z = vertex->position().z();
> position_t = vertex->position().t();
> particles_out_size = vertex->particles_out_size();
>
> numOrphan = numOrph;
>
> }
>
> void HepMCVertex::print_barcode(){
> cout<< "barcode : " << barcode << endl;
> }
> ----------------------------------------------------------
> ---------------------------------------------------------
> The RootFilewriter Body:
> #include <iostream>
>
>
> #include "RootFileWriter.h"
> #include "HepMCEvent.h"
>
> using namespace std;
>
> void RootFileWriter::init(string filename, string treename){
> f = new TFile(filename.c_str(),"RECREATE");
> tree = new TTree(treename.c_str(),treename.c_str());
> cout << "Opening File: " << filename.c_str() << endl;
> tree->Branch("EventBranch","HepMCEvent",&event,16000,99);
> }
>
> void RootFileWriter::finish(){
> f->Write();
> cout << "File wrote. " << endl;
> f->Close();
> cout << "File closed. " << endl;
> }
>
>
> void RootFileWriter::fill(HepMC::GenEvent *hepMCgenEvt){
>
> string treename = "HepMCEvents";
> event = new HepMCEvent(hepMCgenEvt);
>
> tree->Fill();
> event->Clear();
> delete event;
> }
> -----------------------------------------------------
> -----------------------------------------------------------
> The Dump output of the Vertices(the TClonesArray):
> -----------------------------------------------------------
> ==> Dumping object at: 0x08ef4f60, name=Vertices, class=TBranchElement
>
> fClassName ->8ef507c Class name of referenced
> object
> fClassName.*fData HepMCEvent
> fParentName ->8ef5084 Name of parent class
> fParentName.*fData HepMCEvent
> fClonesName ->8ef508c Name of class in TClonesArray
> (if any)
> fClonesName.*fData
> *fCollProxy ->0 ! collection interface (if
> any)
> fCheckSum 4283192070 CheckSum of class
> fClassVersion 1 Version number of class
> fID 7 element serial number in fInfo
> fType 0 branch type
> fStreamerType 63 branch streamer type
> fMaximum 0 Maximum entries for a
> TClonesArray or variable array
> fSTLtype 0 ! STL container type
> fNdata 1 ! Number of data in this
> branch
> *fBranchCount ->0 pointer to primary branchcount
> branch
> *fBranchCount2 ->0 pointer to secondary
> branchcount branch
> *fInfo ->8d5af68 ! Pointer to StreamerInfo
> *fObject (
> fInit true ! Initialization flag for
> branch assignment
> fInitOffsets true ! Initialization flag to not
> endlessly recalculate offsets
> fCurrentClass ->8ef50cc ! Reference to current
> (transient) class definition
> fCurrentClass.fClassName ->8ef50cc Name of referenced class
> fCurrentClass.*fClassPtr ->0 ! Ptr to the TClass object
> fCurrentClass.*fPrevious ->0 ! link to the previous refs
> fCurrentClass.*fNext ->0 ! link to the next refs
> fParentClass ->8ef50dc ! Reference to class
> definition in fParentName
> fParentClass.fClassName ->8ef50dc Name of referenced class
> fParentClass.*fClassPtr ->8d3f688 ! Ptr to the TClass object
> fParentClass.*fPrevious ->0 ! link to the previous refs
> fParentClass.*fNext ->8ef0c4c ! link to the next refs
> fBranchClass ->8ef50ec ! Reference to class
> definition in fClassName
> fBranchClass.fClassName ->8ef50ec Name of referenced class
> fBranchClass.*fClassPtr ->8d3f688 ! Ptr to the TClass object
> fBranchClass.*fPrevious ->8eaf7b4 ! link to the previous refs
> fBranchClass.*fNext ->8ef0c5c ! link to the next refs
> *fBranchOffset ->0 ! Sub-Branch offsets with
> respect to current transient class
> fCompress 1 (=1 branch is compressed, 0
> otherwise)
> fBasketSize 16000 Initial Size of Basket Buffer
> fEntryOffsetLen 0 Initial Length of fEntryOffset
> table in the basket buffers
> fWriteBasket 96 Last basket number written
> fEntryNumber 100 Current entry number (last one
> filled in this branch)
> fOffset 0 Offset of this branch
> fMaxBaskets 97 Maximum number of Baskets so
> far
> fSplitLevel 1 Branch split level
> fNleaves 1 ! Number of leaves
> fReadBasket 95 ! Current basket number when
> reading
> fReadEntry 99 ! Current entry number when
> reading
> fEntries 100 Number of entries
> fTotBytes 1974416 Total number of bytes in all
> leaves before compression
> fZipBytes 1005673 Total number of bytes in all
> leaves after compression
> fBranches ->8ef4fd0 -> List of Branches of this
> branch
> fBranches.*fCont ->8ef5108 !Array contents
> fBranches.fLowerBound 0 Lower bound of the array
> fBranches.fLast -1 Last element in array
> containing an object
> fBranches.fSorted false true if collection has been
> sorted
> fBranches.fName ->8ef4fdc name of the collection
> fBranches.fName.*fData
> fBranches.fSize 16 number of elements in
> collection
> fBranches.fUniqueID 0 object unique identifier
> fBranches.fBits 0x03000000 bit field status word
> fLeaves ->8ef4ff8 -> List of leaves of this
> branch
> fLeaves.*fCont ->8ef5150 !Array contents
> fLeaves.fLowerBound 0 Lower bound of the array
> fLeaves.fLast 0 Last element in array
> containing an object
> fLeaves.fSorted false true if collection has been
> sorted
> fLeaves.fName ->8ef5004 name of the collection
> fLeaves.fName.*fData
> fLeaves.fSize 16 number of elements in
> collection
> fLeaves.fUniqueID 0 object unique identifier
> fLeaves.fBits 0x03000000 bit field status word
> fBaskets ->8ef5020 -> List of baskets of this
> branch
> fBaskets.*fCont ->8ef52d8 !Array contents
> fBaskets.fLowerBound 0 Lower bound of the array
> fBaskets.fLast 96 Last element in array
> containing an object
> fBaskets.fSorted false true if collection has been
> sorted
> fBaskets.fName ->8ef502c name of the collection
> fBaskets.fName.*fData
> fBaskets.fSize 97 number of elements in
> collection
> fBaskets.fUniqueID 0 object unique identifier
> fBaskets.fBits 0x03000000 bit field status word
> fNBasketRAM 1 ! Number of baskets in
> fBasketRAM
> *fBasketRAM 95 ! [fNBasketRAM] table of
> basket numbers in memory
> *fBasketBytes 5422 [fMaxBaskets] Lenght of
> baskets on file
> *fBasketEntry 0 [fMaxBaskets] Table of first
> entry in eack basket
> *fBasketSeek 222 [fMaxBaskets] Addresses of
> baskets on file
> *fTree ->8ea1960 ! Pointer to Tree header
> *fAddress (
> *fDirectory ->8d3d958 ! Pointer to directory where
> this branch buffers are stored
> fFileName ->8ef5068 Name of file where buffers are
> stored ("" if in same file as Tree header)
> fFileName.*fData
> *fEntryBuffer ->0 ! Buffer used to directly pass
> the content without streaming
> *fBrowsables ->8e9f568 ! List of
> TVirtualBranchBrowsables used for Browse()
> fSkipZip false !After being read, the buffer
> will not be unziped.
> fName ->8ef4f6c object identifier
> fName.*fData Vertices
> fTitle ->8ef4f74 object title
> fTitle.*fData Vertices
> fUniqueID 0 object unique identifier
> fBits 0x03001008 bit field status word
> fFillColor 0 fill area color
> fFillStyle 1001 fill area style
>
> --------------------------------------------------------------------
> ---------------------------------------------------------------------
>
> Thx
> Oliver
>
> -------------------------------------------------------------
> Oliver Oberst
> oberst_at_ekp.physik.uni-karlsruhe.de IEKP, Uni Karlsruhe
> Wolfgang-Gaede-Str. 1
> Tel: +49-(0)721 608-7243 D-76128 Karlsruhe
> -------------------------------------------------------------
>
>
>

-- 

-------------------------------------------------------------
Oliver Oberst                           
oberst_at_ekp.physik.uni-karlsruhe.de        IEKP, Uni Karlsruhe
                                        Wolfgang-Gaede-Str. 1 
Tel: +49-(0)721 608-7243                    D-76128 Karlsruhe
-------------------------------------------------------------
Received on Thu Dec 21 2006 - 18:25:25 MET

This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:32:02 MET