Re: [ROOT] Folder/Tree; ERRATUM

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Feb 21 2002 - 13:03:12 MET


In my reply to Jean-Eric, I had several mistakes in my proposed
implementation. Thanks to Jean-Eric, Fred, Fons, Michel, Ernouan
and Sue for reporting the anomalies. Here is a corrected version
of my mail with also some additions.


My proposed solution to your simple problem is the following:

Create two TClonesArray for hits and digits and post them to a folder.
Assuming that you have created the folder "/Event/MC" pointer by
  TFolder *MC
for example with:

    TFolder *EvFolder, *MC;
    EvFolder = gROOT->GetRootFolder()->AddFolder("Event","Event folder");
    gROOT->GetListOfBrowsables()->Add(EvFolder, "Event Folder");
    MC = EvFolder->AddFolder ("MC", "MC hits and Digits folder");
 
    TClonesArray  *fHits   = new TClonesArray("MCHits");
    TClonesArray  *fDigits = new TClonesArray("MCDigits");
    fHits->SetName("Hits");
    fDigits->SetName("Digits");
    MC->Add(fHits);
    MC->add(fDigits);

- Now produce a TTree (eg, TreeH) with
   TFile f("hits.root","recreate");
   TClonesArray *myhits = MC->FindObject("Hits); //should be equal to fHits
   void *adh = (void*)MC->GetListOfFolders()->GetObjectRef(myhits);
   TTree *TreeH = new TTree("TreeH","bla bla");
   void* adh =
(void*)MC->GetListOfFolders()->GetObjectRef(myhits);                   
   treeH->Branch("hits","TClonesArray",adh);
   // fill your TClonesArray with MCHits objects
   TreeH->Fill();

- In your step 2:
  //if a separate job, create the folder structure as above
  TFile f("hits.root","update");
  TTree *TreeH = (TTree*)f.Get(TreeH"):
  TClonesArray *myhits = MC->FindObject("Hits);
  void* adh =
(void*)MC->GetListOfFolders()->GetObjectRef(myhits);                   
  TreeH->SetBranchAddress("hits",adh);

  TTree *TreeD = new TTree("TreeD","bla bla2");
  TClonesArray *mydigits = MC->FindObject("Digits);
  void* add =
(void*)MC->GetListOfFolders()->GetObjectRef(mydigits);                   
  treeD->Branch("digits","TClonesArray",add);
  //start the loop on events. for each event, do:
  TreeH->GetEntry(evnumber);
  //fill your fDigits from fHits
  TreeD->Fill();

  Note that instead of updating the file hits.root, it might be more
  convenient to create a separated file digits.root in case you want to run
  multiple digitisation algorithms.

  If in a next job, you want to read TreeH and TreeD in parallel,
  it may be convenient to declare TreeD a friend of TreeH.

I already implemented a TTree::Branch function accepting a folder name
in input (this saves a few lines above). Unfortunately, I have not yet
implemented the automatic creation of a TFolder structure when
connecting a Tree. This is on my todo list.

Currently, one can already replace the lines creating a Tree like:
   TClonesArray *myhits = MC->FindObject("Hits); //should be equal to fHits
   void *adh = (void*)MC->GetListOfFolders()->GetObjectRef(myhits);
   TTree *TreeH = new TTree("TreeH","bla bla");
   void* adh =
(void*)MC->GetListOfFolders()->GetObjectRef(myhits);                   
   treeH->Branch("hits","TClonesArray",adh);
by
   TTree *TreeH = new TTree("TreeH","bla bla");
   treeH->Branch("/Event/MC");

I still have to implement the equivalent statement when reading the Tree
to connect a branch to a folder.

Rene Brun



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