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