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
> };