Re: TTrees of TTrees..?

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Oct 30 1997 - 09:13:41 MET


William J. Deninger wrote:
> 
> Hello,
> 
> I'm trying to organize positron track data from E821 at BNL and have a
> question concerning the use of trees.  The data is naturally divided
> into the hiarchial levels: run number, record number, fill number,
> straws hit, and finally tracks.  My question is, how do I organize a
> tree such that the data is divided into the following?
> 
>     ROOT
>      /\
>     /  \
>  run 1  run 2 ....
>           /\
>          /  \
>      rec 1  rec 2 ...
>               /\
>              /  \
>         fill 1  fill 2 ....
>                   /\
>                  /  \
>             track 1  track 2 ....
>                         /\
>                        /  \
>               (raw)  data1  data2 ..
> 
> To I want to make several trees and enter them into the branches?  For
> example, the first tree comprises the ROOT, the branches of the root
> contain several trees for each record, whose branches contain trees for
> fills, etc. etc. etc... , all the way to the data which is contained in
> branches themselves?  Or should the raw data be kept in a TClonesArray,
> but everything else is fine?  What is the best way to approach this
> organization, and how is it booked? Is it booked from Root down, or from
> data up?

Look into the example provided in $ROOTSYS/test/Event.

I suggest the following Event model:
class Event: public TObject {
  EventHeader   header;
  RawData      *rawdata;
  TClonesArray *tracks;
}

with:
class EventHeader {
  Int_t   run;
  Int_t   record;
  Int_t   fill;
  Int_t   event_number;
  ...
}

class RawData : public TObject {
   TarrayI   rawTracker;  // arrays of Int_t (or floats, shorts,etc..
   TArrayI   rawCalo;     // with your original raw data
   TArrayI   rawMuon;     // This can be a more sophisticated model !!
   ..
}

class Track : public TObject {
   Float_t   px;
   Float_t   py;
   ...
}

// Create one file per run/rec/fill
{
   char filename[64];
   sprintf(filename,"run%i_rec%i_fill%i",run,rec,fill);
   TFile dst(filename,"recreate")
   TTree T("T",filename);
   EVent *event = new Event();
   T.Branch("event","Event",&event,8000,1);

//  Read raw data file and fill tree
   while(..) {
      event->ReadRawData();
      event->Reconstruct();
      T.Fill();
   }
   T.Write();
}

In this example, ROOT will create a Tree automatically splitting
the event into the following branches:
  - one branch for each data member of EventHeader
  - one single branch for the raw data. You can structure this part
    to force one branch per detector component.
  - one superbranch for the tracks. This superbranch will have one
branch
    for each data member of Track.

With this structure, when you process the Tree in a Root session:
  Root > TFile dst("....);
  Root > T.Draw("event_number");   // reads only event_number branch
  Root > T.Draw("px");             // reads only subbranch px

You can group many data bases into a logical chain)
  TChain rec25("rec25","T");
  rec25.Add("dst_run1_rec25_fill1");
  rec25.Add("dst_run1_rec25_fill2");
  rec25.Add("dst_run1_rec25_fill3");
  rec25.Draw("px");  will sequentially process all 3 files

More details are given in the $ROOTSYS/test/Event example.

Rene Brun



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:26:22 MET