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