RE: [ROOT] trees, tclonesarrays, and indicies

From: Philippe Canal (pcanal@fnal.gov)
Date: Thu Aug 01 2002 - 17:59:40 MEST


Hi Roy,

Thanks for your report.  This will be fixed shortly in the CVS repository.

Cheers,
Philippe.

-----Original Message-----
From: Roy Lee [mailto:rlee@heplaxp5.harvard.edu]
Sent: Wednesday, July 31, 2002 11:07 AM
To: Philippe Canal
Cc: roottalk@pcroot.cern.ch
Subject: RE: [ROOT] trees, tclonesarrays, and indicies


On Wed, 31 Jul 2002, Philippe Canal wrote:

Hi,

I've included as an attachment a tar file containing some sample code.
I have also included the source as text below in this message.  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


> Hi Roy,
>
> This ought to work as you expect.  Could you please send a little test
> program reproducing the problem?
>
> Thanks,
> Philippe
>
> -----Original Message-----
> From: owner-roottalk@pcroot.cern.ch
> [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Roy Lee
> Sent: Wednesday, July 31, 2002 9:03 AM
> To: roottalk@pcroot.cern.ch
> Subject: [ROOT] trees, tclonesarrays, and indicies
>
>
> Hi,
>
> I have the following situation when using indices in a TTree:
>
> I have a class Event which contains 2 TClonesArrays:
>
> class Event {
> private:
>   TClonesArray *strip; // array of Strip objects
>   TClonesArray *track; // array of Track objects
> }
>
> Each Event contains multiple hit strips, and may contain multiple
> tracks.  A track points to multiple strips (a strip may have
> multiple tracks pointing to it).
>
> The track TClonesArray has an index over the strip TClonesArray:
>
> class Track {
> private:
>   Int_t nstrip; // number of strips in track
>   Int_t *stp; //[nstrip]
>   Int_t *plane; //[nstrip]
> }
>
> The variable length array stp is an index over TClonesArray *strip.
> In addition to this Strip index, Track also contains an integer array
> containing the plane information for each hit strip.  This
> The Strip class is defined:
>
> class Strip {
> private:
>   Int_t plane;
> }
>
> Now let's suppose that Event is output as a TTree with name event.
> If I do a TTree::Scan() to find the plane of the first hit strip in the
> first track, I get the result I expect:
>
> event->Scan("track[0].plane[0]")
>
> > 10 (for example)
>
> I can also do
>
> event->Scan("strip[track[0].stp[0]].plane")
>
> > 10
>
> which is the same as the plane information contained directly in Track.
> I can also combine the two expressions in the same Scan command and get
> the same result:
>
> eventnt->Scan("track[0].plane[0]:strip[track[0].stp[0]].plane")
>
> > 10 : 10
>
> However, if I try to do something like
>
> eventnt->Scan("track[0].plane[0]-strip[track[0].stp[0]].plane")
>
> > N != 0
>
> Alternatively, if I try to do a Draw() command:
>
> eventnt->Draw("track[0].plane[0]:strip[track[0].stp[0]].plane")
>
> I get 10 on one axis and N != 10 on the other.
>
> If I replace the index "track[0].stp[0]" with the index (such as 2),
> everything works:
>
> eventnt->Scan("track[0].plane[0]-strip[2].plane")
>
> > 0
>
> The same goes for the Draw() command.
>
> Anyone have any ideas what is going on here?  I am using ROOT 3.03/06
> compiled with gcc 3.0 under intel redhat 7.1.
>
> Roy
>
>
> ----------------------------------------------------------------------------
> --
> Roy Lee / rlee@physics.harvard.edu / Department of Physics, Harvard
> University
>

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