Reading TClonesArray

Hi,
A begginers question:
I have two classes for defining my tree: (picked up from the Event example)

class Event : public TObject {
public:
int ENumber;
int RMode; //event type
int fNtrack; //Total Number of tracks
int fNtrack0; // number of final state tracks (after interaction)
int fNtrack1; // number of intial state tracks
int fNtrack2; // nnumber of intermediate state tracks
TRef fLastTrack; //reference pointer to last track
TClonesArray *fTracks; //->array with all tracks
static TClonesArray *fgTracks;
float Vx,Vy,Vz,Vt;
float Info1,Info2;
float NFlux;
Bool_t fIsValid; //
public:
Event();
virtual ~Event();
Track *AddTrack(Float_t random, Float_t ptmin=1);
TClonesArray *GetTracks() const {return fTracks;}
ClassDef(Event,1) //Event structure
};

and

class Track : public TObject {
public:
float E,Px,Py,Pz; // Energy and 3 momenta
int PCode, State; // Particle Code and state (initial -1, intermediate -2 and final 0)
public:
Track();
Track(const Track& orig);
Track(Float_t random);
virtual ~Track();
ClassDef(Track,2) //A track segment
};

Each event has N number of tracks where N varies from event to event.
I could fill the tree (spilt level 2).
I can read the members of the Event class using SetAddress, GetEntry methods and so on. But I do not know how to get the members of the Track of that particluar event.
I used something like:
TClonesArray &tracks = *fTracks; //where fTracks is returned by the GetTracks Method.
Track *track = new(tracks[fNtrack++]) Track(random);
fNtrack has been initialized before.
but the second line gives me an error :

form1.ui.h:104: error: no matching function for call to `Track::operator new(unsigned int, TClonesArray&)’
/home//Programs/root/include/TObject.h:156: note: candidates are: static void* TObject::operator new(size_t)
/home/Programs/root/include/TObject.h:158: note: static void* TObject::operator new(size_t, void*)

can any one give me an idea?
Thanks,
dsmcc

Hi,

This is strange. The code has you copied it in this message seems to be an exact copy/paste from the Event.cxx in $ROOTSYS/test which compiles just fine. However the message the compiler issues is a bit odd, It says:form1.ui.h:104: ... for call to `Track::operator new(unsigned int, TClonesArray&)'Now, guessing that form1.ui.h line 104 is the line you copied:Track *track = new(tracks[fNtrack++]) Track(random); then the compile claims that ‘tracks[int]’ is returning a TClonesArray … which is not really possible … (because track is a TClonesArray& and that operator[] for TClonesArray return a TObject*) …
So there is something that you did not provide that is causing the problem (either you did not provide the code at line 104 or some definition that you did not provide altering some of my guess on the types) … To understand this any further we would need a complete example reproducing the issue.

Cheers,
Philippe.

Hi,
Sorry, I was working to sort this error out. I just regenerated the dictionaries and it worked.
But now I am still facing a problem. Simply put, I just dont know how to go about reading back a TClonesArray from a tree. Here is the problem I face:
The Classes Event and Track have been posted in my first query. They are similar to the classes given in the Event example in the root directory
I fill up a tree like:

f = new TFile(“Nu1.root”,“RECREATE”);
tree = new TTree(“tree”,“Nuance Root File”);
tree->Branch(“Event_Branch”,“Event”,&E1,1600000,2);


E1->fNtrack=x; and so on for the members of the Event Class
and for the members of the Track Class I do something like:
T1= E1->AddTrack(0,0);
T1->PCode = 123; and so on…

The method AddTrack returns a pointer to the class Track (exact copy from the Event example.
Track * Event::AddTrack(Float_t random, Float_t ptmin)
{
// Add a new track to the list of tracks for this event.
TClonesArray &tracks = *fTracks;
Track *track = new(tracks[fNtrack++]) Track(random);
//Save reference to last Track in the collection of Tracks
fLastTrack = track;
return track;
}
I Fill the tree using tree->Fill(); and finally f->Write();
Now when I read this tree out:
Event *E2 = new Event();
TBranch *branch = tree->GetBranch(“Event_Branch”); //"Event_Branch"
branch->SetAddress(&E2);
tree->GetEntry(VEvent-1); // its a zero based index
sprintf(PrintBuffer,“RMode:%d::NFlux %G”,E2->RMode,E2->NFlux);
and this works correctly.
I am stranded at this point.How do read the members of the Track Class for this particular event ?. How do I call SetAddress for the Track Class.I tried various methods but all gave me junk values and run time errors and I cant post them all here for brevity. Can anyone guide me by giving me an idea to get the Track members ?
Thanks,
dsmcc

TBranch *branch = tree->GetBranch("Event_Branch"); //"Event_Branch" branch->SetAddress(&E2); It is better to use tree->SetBranchAddress("Event_Branch",&E2);

Cheers,
Philippe.

Thanks Philippe.
That worked ! but I do not see any documentation about the “At” Method anywhere…
Regards,
dsmcc.

Hi,

It is a member function of the base class of TClonesArray (i.e TObjArray).
You could also have used the operator[]:Track *t = (Track*) (*(E2->GetTracks()))[3];

Cheers,
Philippe.