Hi everybody, I have to say from the start, that I'm quite new to c++ and ROOT, so I'm probably asking about some trivial things. I'm trying to use ROOT to replace some ZEBRA data banks and the information about an event consists of few integers and floats and a variable length array of floats. So I wrote a small program to accomplish this, trying to follow closely examples 'Event.h, Event.cxx, MainEvent.cxx' from $ROOTSYS/test directory. First I wanted to make a pointer to TArrayF to be a data member of my class "MyTrack", then I read in documentation, that for classes, not derived from TObject (and TArray is not) 'Streamer' method is not generated automatically, so it's not possible to write them into a file. Then I thought I can just copy 'Event.h', having a pointer to TClonesArray a data member and just replacing 'Tracks' with 'object numbers', i.e. floats, derived from TObject, but there is no such thing in ROOT by default. I got my program working using 'TObjNum' class, like the one from 'tcollex.cxx', but because there's no such 'built-in' class, I thought that there should be a better way to manage an array of floats. My last try was to use a pointer to TVector as a data member, because it is an array of floats, derived from TObject, this is how it looks: MuTrack.h: #ifndef __MuTrack__ #define __MuTrack__ ////////////////////////////////////////////////////////////////////////// // // // MuTrack // // // // Class definition for storing muon track pulseheights // // // ////////////////////////////////////////////////////////////////////////// #include "TObject.h" #include "TVector.h" class MuTrack : public TObject { private: Int_t fLength; // Track length Int_t fStart; // Most upstream counter of the track Int_t fShwrLength; // Shower length of the event, muon track // taken from Float_t fShwrEnergy; // Shower energy Float_t fMuEnergy; // Muon energy TVector *fMuPulseHeights; // Vector of muon pulseheights static TVector* fgMuPulseHeights; public: MuTrack(); // Default constructor virtual ~MuTrack(); // Destructor void SetLength(Int_t n) { fLength = n; } void SetStart(Int_t n) { fStart = n; } void SetShwrLength(Int_t n) { fShwrLength = n; } void SetShwrEnergy(Float_t e) { fShwrEnergy = e; } void SetMuEnergy(Float_t e) { fMuEnergy = e; } void ResizeTo(Int_t n) { fMuPulseHeights->ResizeTo(n); } void Copy(TVector& v) { fMuPulseHeights->operator=(v); } TVector* GetMuPulseHeights() const { return fMuPulseHeights; } ClassDef(MuTrack,1) // Class definition macro }; #endif ------------------------------------------------------------------------ MuTrack.cxx: #include "MuTrack.h" #include <iostream.h> ClassImp(MuTrack) TVector* MuTrack::fgMuPulseHeights = 0; //___________________________________________________________________________ MuTrack::MuTrack() { // Create a MuTrack object. // When the constructor is invoked for the first time, the class static // variable fgMuPulseHeights is 0 and the TVector fgMuPulseHeights // is created. if (!fgMuPulseHeights) fgMuPulseHeights = new TVector(84); fMuPulseHeights = fgMuPulseHeights; fLength = 0; fStart = 0; fShwrLength = 0; fShwrEnergy = 0.0; fMuEnergy = 0.0; } MuTrack::~MuTrack () { } --------------------------------------------------------------------------- MainMuTrack.cxx : #include <stdlib.h> #include <iostream.h> #include "TROOT.h" #include "TFile.h" #include "TRandom.h" #include "TTree.h" #include "TBranch.h" #include "TVector.h" #include "MuTrack.h" //____________________________________________________________________________ int main() { TROOT simple("simple","Example of creation of a tree"); Int_t nevent = 400; // by default create 400 events Int_t comp = 1; // by default file is compressed Int_t split = 1; // by default, split Event in sub branches TFile* hfile; MuTrack* mutrack; TTree* tree; Int_t nb = 0; Int_t ev; 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. hfile = new TFile("Event.root","RECREATE","TTree benchmark ROOT file"); hfile->SetCompressionLevel(comp); // Create one event mutrack = new MuTrack(); // Create a ROOT Tree and one superbranch tree = new TTree("T","An example of a ROOT tree"); tree->SetAutoSave(1000000); // autosave when 1 Mbyte written bufsize = 256000; if (split) bufsize /= 4; tree->Branch("event", "MuTrack", &mutrack, bufsize,split); // Write out 'nevent' random events. for (ev = 0; ev < nevent; ev++) { cout << "Event " << ev << endl; Int_t length = (Int_t)(50*gRandom->Rndm(1)+1); Int_t start = (Int_t)(80*gRandom->Rndm(1)+1); Int_t shwrlength = (Int_t)(10*gRandom->Rndm(1)+1); Float_t shwrenergy = gRandom->Rndm(1)*200.0; Float_t muenergy = gRandom->Rndm(1)*90.0; mutrack->SetLength(length); mutrack->SetStart(start); mutrack->SetShwrLength(shwrlength); mutrack->SetShwrEnergy(shwrenergy); mutrack->SetMuEnergy(muenergy); TVector* vector = new TVector(length); for (Int_t i = 0; i < length; i++) { Float_t ph = gRandom->Rndm(1)*90.0; vector->operator()(i) = ph; } mutrack->ResizeTo(length); mutrack->Copy(*vector); delete vector; nb += tree->Fill(); //fill the tree } hfile->Write(); tree->Print(); hfile->Close(); return 0; } --------------------------------------------------------------------------- This program works, but occasionally I it prints out error messages: CustomReAlloc2: oldsize != size I sort of figured out that these errors are from resizing vector *fMuPulseHeights, the memory checker reports an error despite, that MuTrack() constructor 'reserves' enough memory, with fgMuPulseHeights = new TVector(84), to hold the largest possible vector. What I don't understand is why this error is not printed every time the size of *fMuPulseHeights gets increased, but only occasionally. So my questions are - first, how to fix this program, eliminating these memory errors, and second what is the 'best' way to have an array of floats as a data member of the class, so that it's 'easy' to write objects of this class into a root file? Thank you very much, especially to those, who read the entire posting. Sergei Avvakumov avva@fnal.gov
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:39 MET