[ROOT] Re: trees, tclonesarrays, and indices

From: Roy Lee (rlee@heplaxp5.harvard.edu)
Date: Wed Jul 31 2002 - 19:15:56 MEST


Hi,

I have included the some code as text below in this message. One can
also get the source as a tar file from my web page:

  http://www.hepl.harvard.edu/~rlee/roottest.tar

Do a 'gmake' in the roottest directory, and run the binary Event without
any arguments.  This will produce the output file Event.root.

There is 1 event which contains 2 TClonesArrays, one for Tracks and one
for Hits.  There is 1 Track in this event which has 10 even plane Hits,
and a total of 20 Hits (half even planes, half odd planes).  Here is some
sample output which illustrates the problem:

[rlee@heplminos6 roottest]$ root Event.root
  *******************************************
  *                                         *
  *        W E L C O M E  to  R O O T       *
  *                                         *
  *   Version   3.03/06      28 July 2002   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

Compiled for linux with thread support.

CINT/ROOT C/C++ Interpreter version 5.15.49, July 2 2002
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0]
Attaching file Event.root...
Warning in <TClass::TClass>: no dictionary for class Event is available
Warning in <TClass::TClass>: no dictionary for class Hit is available
Warning in <TClass::TClass>: no dictionary for class Track is available
root [1] T->Scan("hit[track[0].hit[5]].plane:track[0].plane[5]")
************************************
*    Row   * hit[track * track[0]. *
************************************
*        0 *        10 *        10 *
************************************
(Int_t)1
root [2] T->Scan("hit[track[0].hit[5]].plane-track[0].plane[5]")
************************
*    Row   * hit[track *
************************
*        0 *       -10 *
************************
(Int_t)1


As you can see, when I do a Scan with two expressions separated by :, you
get the expected answer.  When you try to combine the expressions (such as
with the - above) you get something nonsensible (similarly if you try a
Draw).

Roy


Event.cxx:

#include <cassert>
#include <iostream>

#include "Event.h"

ClassImp(Event)
ClassImp(Track)
ClassImp(Hit)



Event::Event()
{
  nhit = 0;
  ntrack = 0;
  hit = 0;
  track = 0;
}

Event::~Event()
{
  if (hit) {
    hit->Delete();
    delete hit;
  }
  if (track) {
    track->Delete();
    delete track;
  }
}


Track::Track()
{
  nhit = 0;
  hit = 0;
  plane = 0;
}

Track::~Track()
{
  if (hit) {
    delete hit;
  }
  if (plane) {
    delete plane;
  }
}

Hit::Hit()
{
  plane = 0;
}

Hit::~Hit()
{
}



Event.h:

#ifndef EVENT_H
#define EVENT_H

#include "TClonesArray.h"
#include "TObject.h"

class Hit : public TObject
{

public:
  Hit();
  ~Hit();
  Int_t plane;

  ClassDef(Hit,1)              // Hit version 1
};

class Track : public TObject
{

public:
  Track();
  ~Track();
  Int_t nhit;
  Int_t *hit; //[nhit]
  Int_t *plane; //[nhit]

  ClassDef(Track,1)              // Track version 1
};

class Event : public TObject
{

public:
  Event();
  ~Event();
  Int_t nhit;
  Int_t ntrack;
  TClonesArray *hit;
  TClonesArray *track;

  ClassDef(Event,1)              // Event version 1
};


#endif // EVENT_H



MainEvent.cxx:

#include <stdlib.h>

#include "Riostream.h"
#include "TROOT.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TClonesArray.h"

#include "Event.h"


//______________________________________________________________________________
int main(int argc, char **argv)
{

   TFile *hfile;
   TTree *tree;
   Event *event = 0;

   hfile = new TFile("Event.root","RECREATE","TTree benchmark ROOT file");

   tree = new TTree("T","An example of a ROOT tree");
   Int_t bufsize = 16000;
   event = new Event();
   event->track = new TClonesArray("Track");
   event->hit = new TClonesArray("Hit");
   TBranch *branch = tree->Branch("event", "Event", &event, bufsize,99);
   branch->SetAutoDelete(kFALSE);

   for (Int_t ev = 0; ev < 1; ev++) {
     event->ntrack = 1;
     event->nhit = 20;
     TClonesArray &tracklist = *(event->track);
     new(tracklist[0]) Track();
     Track *track = (Track*)(tracklist[0]);
     track->nhit = 10;
     track->hit = new Int_t[track->nhit];
     track->plane = new Int_t[track->nhit];
     for (Int_t i=0; i<track->nhit; i++) {
       track->hit[i] = i*2;
       track->plane[i] = i*2;
     }
     for (int i=0; i<event->nhit; i++) {
       TClonesArray &hitlist = *(event->hit);
       new(hitlist[i]) Hit();
       Hit *hit = (Hit*)(hitlist[i]);
       hit->plane = i;
     }
     tree->Fill();
   }
   hfile->Write();
   hfile->Close();
   return 0;
}



EventLinkDef.h:

#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class Event+;
#pragma link C++ class Hit+;
#pragma link C++ class Track+;

#endif


On Wed, 31 Jul 2002, Philippe Canal wrote:

> Hi Roy,
>
> This ought to work as you expect.  Could you please send a little test
> program reproducing the problem?
>
> Thanks,
> Philippe
>

------------------------------------------------------------------------------
Roy Lee / rlee@physics.harvard.edu / Department of Physics, Harvard University



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:02 MET