Writing TClonesArray to File

From: Oliver Oberst <oberst_at_ekp.uni-karlsruhe.de>
Date: Wed, 20 Dec 2006 19:15:40 +0100


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
-------------------------------------------------------------
Received on Wed Dec 20 2006 - 19:16:00 MET

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