Re: problems with modified Event example

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Jun 19 1998 - 09:15:15 MEST


Hi Steffen,
Looking quickly through your code, I see a potential problem.

IMPORTANT NOTE
==============
When you invoke TTree::Branch, the pointer to the branch must
be initialized. You can either set the pointer to 0 or move
the statements like
    fheader = new TOscarFileHeader();
before tree->Branch.

Let me know if this fixes your problem. Otherwise, provide
a code that I can use for more investigation.

Rene Brun



Steffen A. Bass wrote:
> 
> Hello rooters,
> I have modified the Event example from the root distribution for
> my own purposes. It works fine as long as I only write a small number of
> event objects with small array sizes. If I increase the number of events
> and their size I get a segmentation violation.
> My main program is given below, the class definitions and implementations
> are in the attachments (beware, the stuff is not compilable since I
> truncated the main program to the parts relevant for my problem).
> 
> I'd be grateful for any hints on what is going wrong.
> Thanks a lot,
>         Steffen
> 
> --------------------------------------------------------------------------
>   Dr. Steffen A. Bass                           phone : [01] 919 660 2570
>   Duke University, Dept. of Physics             fax   : [01] 919 660 2464
>   Box 90305, Durham N.C. 27708-0305, USA        e-mail: bass@phy.duke.edu
> --------------------------------------------------------------------------
> 
> // globals and include files
> #include <stdlib.h>
> #include <stdio.h>
> #include <iostream.h>
> 
> #include "TROOT.h"
> #include "TFile.h"
> #include "TBranch.h"
> #include "TTree.h"
> #include "TClonesArray.h"
> #include "TMath.h"
> 
> #include "TOscarEvent.h"  // here are the new event classes
> 
> //--------------------------------------------------------------------------
> main()
> {
>   TROOT simple("simple","tree for OSCAR events");
> 
>    Int_t nevent = 0;
>    Int_t comp   = 2;       // by default file is compressed
>    Int_t split  = 1;       // by default, split Event in sub branches
> 
>    TOscarEvent *event=0;  // create event, header and particle objects
>    TOscarFileHeader *fheader;
>    TParticle *particle;
> 
>    Int_t nb = 0;
>    Int_t bufsize;
> 
>    // Create a new ROOT binary machine independent file.
>    // Note that this file may contain any kind of ROOT objects, histograms,
>    // pictures, graphics objects, detector geometries, tracks, events, etc..
>    // This file is now becoming the current directory.
> 
>    TFile *hfile = new TFile("Event.root","RECREATE","TTree ROOT file");
>    hfile->SetCompressionLevel(comp);
> 
>    // Create a ROOT Tree
>    TTree *tree = new TTree("T","ROOT tree");
>    tree->SetAutoSave(100000);  // autosave when 1 Mbyte written
>    bufsize = 400000;
>    if (split)  bufsize /= 4;
> 
>    tree->Branch("fHeaderBranch","TOscarFileHeader", &fheader, bufsize,split);
> 
>    fheader = new TOscarFileHeader();
> 
> // ... initialize fheader object
> 
>    tree->Branch("EventBranch", "TOscarEvent", &event, bufsize,split);
> 
>   while(... generating event data ...)
>     {
> 
>       event = new TOscarEvent();
> 
>       for (Int_t i = 0; i < part_mult ; i++)
>         {
>           particle = new TParticle();
> 
>         ... filling particle object ...
> 
>           event->AddParticle(particle);
> 
>           delete particle;
>         }
> 
>       nb += tree->Fill();  //fill the branch - the segmentation violation
>                            // happens here
> 
>       delete event;
> 
>       nevent++;
>       cout << "processing event # " << nevent << endl;
> 
>     }
> 
>   hfile->Write(); // write tree to file
>   //  tree->Print();
> 
> 
>   Double_t mbytes = 0.000001*nb;
> 
>   printf("\n%d events and %f Mbytes processed.\n",nevent,mbytes);
>   printf("file compression factor = %f\n",hfile->GetCompressionFactor());
> 
>   hfile->Close();
>   return 0;
> }
> 
> 
>     ---------------------------------------------------------------
> #include "TOscarEvent.h"
> #include "TRandom.h"
> 
> ClassImp(TOscarFileHeader)
> ClassImp(TOscarEvent)
> ClassImp(TParticle)
> 
> TClonesArray *gParticles;
> Int_t gPartCount;
> Int_t gArraySize=50000;
> 
> //____________________________________________________________________________
>  TOscarEvent::TOscarEvent()
> {
> //   Create one Event object
> //   When the constructor is invoked for the first time, the global
> //   variable gParticles is NULL. The TClonesArray gParticles is created.
> //
>    gPartCount= 0;
>    if (!gParticles) gParticles = new TClonesArray("TParticle", gArraySize);
>    fParticles = gParticles;
> }
> 
> //____________________________________________________________________________
>  TOscarEvent::~TOscarEvent()
> {
>   //Clear();
>   fParticles->Clear();
>    // cout << "destructing event " << endl;
> }
> 
> //____________________________________________________________________________
> void TOscarEvent::AddParticle(TParticle *part)
> {
> // Add a new particle to the list of particles for this event.
> // To avoid calling the very time consuming operator new for each track,
> // the standard but not well know C++ operator "new with placement" is called.
> // if tracks[i] is NULL, a new Track object will be created
> // otherwise the previous Track[i] will be overwritten.
> 
>    TClonesArray &particles = *fParticles;
>    if(gPartCount==gArraySize)
>      {
>        cout << " ERROR : too many particles in TClonesArray !! " << endl
>             << "         -> resize gArraySize " << endl;
>          return;
>      }
>       new(particles[gPartCount++]) TParticle(part);
>    //   particles[gPartCount++] = new TParticle(part);
> 
> }
> 
> //____________________________________________________________________________
> 
> TParticle::TParticle(TParticle *part) :TObject()
> {
> //*-*-*-*-*-*-*-*-*-*-*Particle copy constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
> //*-*                  =======================
> 
>   fP0   =  part->fP0;
>   fPx   =  part->fPx;
>   fPy   =  part->fPy;
>   fPz   =  part->fPz;
>   fMass =  part->fMass;
>   fR0   =  part->fR0;
>   fRx   =  part->fRx;
>   fRy   =  part->fRy;
>   fRz   =  part->fRz;
>   fNum  =  part->fNum;
>   fId   =  part->fId;
>   //
>   fPt   =  part->fPt;
>   fY    =  part->fY;
>   fPhi  =  part->fPhi;
>   fTheta=  part->fTheta;
>   fPabs =  part->fPabs;
> }
> 
>     ---------------------------------------------------------------
> #include "TObject.h"
> #include "TClonesArray.h"
> #include "TMath.h"
> #include <iostream.h>
> 
> class TParticle: public TObject {
> // Steffen A. Bass
> // simple particle class, contains one TClonesArray, otherwise only
> // basic types in order not to have any problems in ROOT
> 
> private:
>         Double_t      fP0;           // energy
>         Double_t      fPx;           // X component of the momentum
>         Double_t      fPy;           // Y component of the momentum
>         Double_t      fPz;           // Z component of the momentum
>         Double_t      fMass;         // mass of particle
>         Double_t      fR0;           // r_0 of particle
>         Double_t      fRx;           // X location
>         Double_t      fRy;           // Y
>         Double_t      fRz;           // Z
>         Int_t         fNum;          // particle number
>         Int_t         fId;           // particle ID
>         // members to be calculated
>         Double_t      fPt;           // transverse momentum
>         Double_t      fY;            // rapidity
>         Double_t      fPhi;          // azimuthal angle
>         Double_t      fTheta;        // polar angle
>         Double_t      fPabs;         // total momentum
> 
> public:
>         TParticle() {;}
>         TParticle(TParticle *part);
>         ~TParticle() {;}
> 
>         Double_t       GetPx()    {return fPx;}
>         Double_t       GetPy()    {return fPy;}
>         Double_t       GetPz()    {return fPz;}
>         Double_t       GetP0()    {return fP0;}
>         Double_t       GetR0()    {return fR0;}
>         Double_t       GetRx()    {return fRx;}
>         Double_t       GetRy()    {return fRy;}
>         Double_t       GetRz()    {return fRz;}
>         Double_t       GetMass()  {return fMass;}
>         Int_t          GetNum()   {return fNum;}
>         Int_t          GetId()    {return fId;}
>         Double_t       GetPt()    {return fPt;}
>         Double_t       GetY()     {return fY;}
>         Double_t       GetPhi()   {return fPhi;}
>         Double_t       GetTheta() {return fTheta;}
>         Double_t       GetPabs()  {return fPabs;}
> 
>         void SetMomenta(Double_t px, Double_t py, Double_t pz)
>           {
>             fPx=px;
>             fPy=py;
>             fPz=pz;
>           }
> 
>         void SetLocation(Double_t rx, Double_t ry, Double_t rz)
>           {
>             fRx=rx;
>             fRy=ry;
>             fRz=rz;
>           }
> 
>         void SetTime(Double_t r0)     { fR0=r0; }
>         void SetEnergy(Double_t p0)   { fP0=p0; }
>         void SetMass(Double_t m)      { fMass=m; }
>         void SetId(Int_t i)           { fId=i; }
>         void SetNum(Int_t num)        { fNum=num; }
>         void SetPt(Double_t pt)       { fPt=pt; }
>         void SetY(Double_t y)         { fY=y; }
>         void SetPhi(Double_t phi)     { fPhi=phi; }
>         void SetTheta(Double_t theta) { fTheta=theta; }
>         void SetPabs(Double_t pabs)   { fPabs=pabs; }
> 
>         ClassDef(TParticle,1)
> };
> 
> class TOscarFileHeader : public TObject {
> // Steffen A. Bass
> // class for OSCAR fileheader
> 
> public:
>   Char_t   fOscarTag[13];
>   Char_t   fOscarFiletype[13];
>   Char_t   fModelName[9];
>   Char_t   fModelVersion[9];
>   Int_t    fProjMass;
>   Int_t    fTarMass;
>   Int_t    fProjCharge;
>   Int_t    fTarCharge;
>   Char_t   fRefFrame[5];
>   Double_t fEBeam;
>   Int_t    fNumTestPtcls;
> 
> public:
>   TOscarFileHeader(){;}
>   ~TOscarFileHeader(){;}
> 
>    void SetFileType(Char_t *oftag, Char_t *oftype)
>      {
>        for(Int_t i=0; i<12; i++) {fOscarTag[i]=oftag[i];}
>        for(Int_t i=0; i<12; i++) {fOscarFiletype[i]=oftype[i];}
>      }
> 
>    void SetModelType( Char_t *model, Char_t *version)
>      {
>        for(Int_t i=0; i<8; i++) {fModelName[i]=model[i];}
>        for(Int_t i=0; i<8; i++) {fModelVersion[i]=version[i];}
>      }
> 
>    void SetCollSystem(Int_t ap, Int_t zp, Int_t at, Int_t zt, Double_t eb)
>      {
>        fProjMass=ap;
>        fProjCharge=zp;
>        fTarMass=at;
>        fTarCharge=zt;
>        fEBeam=eb;
>      }
> 
>    void SetRefFrame(Char_t *refsys)
>      {
>        for(Int_t i=0; i<4; i++) {fRefFrame[i]=refsys[i];}
>      }
> 
>    void SetTestPtcls(Int_t tp)
>      {
>        fNumTestPtcls=tp;
>      }
> 
>    Int_t      GetProjMass()   { return fProjMass; }
>    Int_t      GetProjCharge() { return fProjCharge; }
>    Int_t      GetTarMass()    { return fTarMass; }
>    Int_t      GetTarCharge()  { return fTarCharge; }
>    Double_t   GetEbeam()      { return fEBeam; }
>    Int_t      GetTestPtcls()  { return fNumTestPtcls; }
>    Char_t     *GetRefFrame()  { return fRefFrame; }
> 
>     ClassDef(TOscarFileHeader,1)  //Event Header
> };
> 
> class TOscarEvent : public TObject {
> // Steffen A. Bass
> // class for OSCAR events (final_id_px format)
> 
> public:
>    Int_t                fEventNumber;
>    Int_t                fPartMult;
>    Double_t             fImpactParameter;
>    TClonesArray         *fParticles;
> 
> public:
>    TOscarEvent();
>    ~TOscarEvent();
> 
>    void          SetEventNumber(Int_t evnum) { fEventNumber = evnum; }
>    void          SetPartMult(Int_t pmult) { fPartMult = pmult; }
>    void          SetImpactParameter(Double_t b) { fImpactParameter = b; }
> 
>    void          AddParticle(TParticle *part);
> 
>    Int_t              GetEventNumber()     { return fEventNumber; }
>    Int_t              GetPartMult()        { return fPartMult; }
>    Double_t           GetImpactParameter() { return fImpactParameter;}
>    TClonesArray      *GetParticles()       { return fParticles; }
> 
>     ClassDef(TOscarEvent,1)  //Event structure
> };



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:34 MET