Re: [ROOT] TClonesArray gathering

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Mar 26 2004 - 14:43:48 MET


Hi Ben,

I do not understand the logic in your test program.
Nowhere you fill the TClonesArray.
I had to make a few changes to compile your code. See attached tar file.
The results correspond to what I expect from the code.
As I am now leaving for 2 weeks, I suggest you communicate directly
with Philippe to make progress.

Rene Brun

Ben Kilminster wrote:
> 
> Hi,
> 
> Here is the code to gather TClonesArrays of objects and put them in a
> TTree.
> There is a Parent class, a Daughter class, and a Thing class.
> The Parent object creates some Daughter objects.  The Daughters decide
> they want some Things.   The Parent object then checks the Daughters,
> finds out what Things are wanted and makes an entry in the tree.   The
> following example doesn't crash, but it also doesn't store the
> TClonesArray into the TTree.   I tried to do this by adding the
> Daughters' Things one at a time to the tree, but I couldn't get the
> syntax correct (commented part).
> 
> {
> // This macro requires Thing.hh, Thing.cc, Daughter.hh, Daughter.cc,
> Parent.hh, Parent.cc
> gSystem->CompileMacro("Thing.cc");
> gSystem->CompileMacro("Daughter.cc");
> gSystem->CompileMacro("Parent.cc");
> Parent P(1);
> P->HasDaughters();
> }
> 
> -----------------------------------------
> //Thing.hh
> class Thing : public TObject {
>    public:
>    Thing();
>    ~Thing() {};
>    int Value;
>    int ThingID;
>    ClassDef(Thing,1)
> };
> -----------------------------------------
> //Thing.cc
> #include "Thing.hh"
> Thing::Thing() {
>    ThingID = -999;
>    Value = -999;
> }
> ClassImp(Thing)
> -----------------------------------------
> // Daughter.hh
> #include "TClonesArray.h"
> #include "Thing.hh"
> class Daughter
> {
> public:
>    int ID;
>    int GotAThing;
>    TClonesArray* CloneThing;    Thing*  MyThing;
>    Daughter ();
>    Daughter (int minutes_apart);
>    void Reset();
>    void Want(int cash);
> };
> -----------------------------------------
> // Daughter.cc
> Daughter::Daughter (){}
> Daughter::Daughter (int minutes_apart)
> {
>         this->ID = minutes_apart;
>      CloneThing = new TClonesArray("Thing");
> }
> void Daughter::Reset()
> {
>        CloneThing->Clear();
>        GotAThing = 0;
> }
> void Daughter::Want(int cash)
> {
>      MyThing = new ((*CloneThing)[GotAThing]) Thing;
>      MyThing->ThingID = this->ID;
>      MyThing->Value = cash;
>      GotAThing++;
> }
> -----------------------------------------
> // Parent.hh
> #include "Daughter.hh"
> #include "TClonesArray.h"
> #include "TFile.h"
> #include "TTree.h"
> 
> class Parent {
> public:
>    Parent( );
>    Parent(int tree);
>    ~Parent( );
>    void  HasDaughters();
> private:
>    TFile* newfile;
>    TTree* MoneyTree;
>    Daughter* Triplet[3];
>    TClonesArray* CloneThing;
>    Thing* MyThing;
>    int numThings;
> };
> -----------------------------------------
> // Parent.cc
> #include "Parent.hh"
> #include "TClonesArray.h"
> #include "TFile.h"
> #include "TRandom.h"
> 
> #include <assert.h>
> #include <string>
> #include <strstream>
> #include <iostream>
> #include <stdio.h>
> 
> using namespace std;
> 
> Parent::Parent(int tree) {
> // Open a file, and a tree
>      newfile = new TFile("MoneyTree.root","RECREATE","Simple ROOT
> Ntuple");
>      MoneyTree = new TTree("T","MoneyTree");
> // Add a branch for things
>      CloneThing = new TClonesArray("Thing");
>      MoneyTree->Branch("CloneThing",&CloneThing,32000,2);
>      MoneyTree->Branch("numThings",&numThings,"numThings/I");
> // Verify what we have constructed...
>      newfile->ls();
>      TObjArray * br = MoneyTree->GetListOfBranches();
>      TIter i(br);
>      cout << "-----------------------------------------------------" <<
> endl;
>      cout << "Branches:" << endl;
>      while( TBranch * b = (TBranch*)i()){
>        cout << b->GetName() << " : " << b->GetTitle() << endl;
>      }
>      cout << "-----------------------------------------------------" <<
> endl;
> }
> 
> Parent::Parent( )
> {}
> Parent::~Parent( )
> {}
> 
> void Parent::HasDaughters()
> {
>    CloneThing->Clear();
>    // make daughters
>    *Triplet = new Daughter[3];
>    Triplet[0] = new Daughter(0);
>    Triplet[1] = new Daughter(35);
>    Triplet[2] = new Daughter(56);
> 
>    // Daughters want things
>    Triplet[0]->Reset();
>    Triplet[1]->Reset();
>    Triplet[2]->Reset();
>    Triplet[0]->Want(100);
>    Triplet[0]->Want(150);
>    Triplet[2]->Want(100);
> 
>    // Parent checks what daughters want, puts entry in money tree
>    numThings = 0;
>    for(int nd=0; nd <3; nd++) {
>      int wantCash =  Triplet[nd]->GotAThing;
>      printf("Daughter %d wants %d things\n",nd, wantCash);fflush(stdout);
>      // Tried to add the whole clone array: runs, but doesn't store
> Things
>      if (wantCash > 0) {
>        CloneThing =  (TClonesArray*) Triplet[nd]->CloneThing->Clone();
>        numThings += wantCash;
>      }
> 
> //     // Also tried to add one at a time, can't get syntax right
> //     for (int i = 0; i < wantCash; i++) {
> //       MyThing = new
> ((*CloneThing)[numThings])Triplet[nd]->CloneThing->At(i);
> //       numThings++;
> //     }
> 
>    }
>    MoneyTree->Fill();
> 
>    // The above steps may repeat, then the file closes
>    MoneyTree->GetCurrentFile()->Write();
>    MoneyTree->GetCurrentFile()->Close();
> }
> -----------------------------------------
> 
> On Mar 12, 2004, at 2:25 AM, Rene Brun wrote:
> 
> > Hi Ben,
> >
> > It is not obvious to follow your explanations without looking at a
> > concrete
> > piece of code ::)
> > I have the feeling that you do not fill the TClonesArray correctly.
> > You must
> > call the constructor of the class in the TClonesArray (as shown in
> > $ROOTSYS/test/Event.cxx).
> > Could you send the shortest possible file reproducing the problem?
> >
> > Rene brun
> >
> >
> >
> > Ben Kilminster wrote:
> >>
> >> I am trying to figure out how to fill a Tree in one object with a
> >> TClonesArray from another object.
> >> My code is crashing when I try to do the copying.
> >>
> >> In my main class, I define a tree with a branch, with a TClonesArray
> >> of
> >> objects in it:
> >>
> >> class MainSim
> >> {
> >>    TTree* SimTree;
> >>    TClonesArray* CloneXftpixel;
> >>    xft2Lpixel* xftpixelB;
> >> ...
> >> }
> >>
> >> MainSim::MainSim()
> >> {
> >>      CloneXftpixel = new TClonesArray("xft2Lpixel");
> >>      SimTree = new TTree("T","SimTree");
> >>      SimTree->Branch("xft2Lpixel",&CloneXftpixel,32000,2);
> >>      ...
> >> }
> >>
> >> I then fill the TClonesArray in another class, like :
> >>
> >> class FinderChip
> >> {    TClonesArray* CloneXftpixel;
> >>       xft2Lpixel*  xft2pixelF;
> >>       int iPixel;
> >> ...
> >> }
> >>
> >> FinderChip::FillBlock()
> >> {
> >>         iPixel++;
> >>         xft2pixelF = new ((*CloneXftpixel)[iPixel]) xft2Lpixel;
> >>         xft2pixelF->Chip =  this->COT_chip;
> >>                         ...
> >> }
> >>
> >> Now, I want to fill the SimTree with the array of xft2Lpixels from the
> >> FinderChip object.
> >> But I have many FinderChip objects, with any number of xft2pixelF
> >> objects,  so I have to gather them by checking the iPixel counter for
> >> each FinderChip :
> >>
> >> MainSim::FillTree()
> >> {
> >>         CloneXftpixel->Clear()
> >>
> >>      for(int nbrd=0; nbrd<8; nbrd++) {
> >>        for (int nchp=0;nchp<8;nchp++) {
> >>          int nPix =
> >> XFTSystem->finderCrate[crate]->FinderBoard2_4Elements[nbrd]-
> >>> finderChipElements[nchp]->iPixel;
> >>         if (nPix > 0)
> >>          CloneXftpixel =
> >> (TClonesArray*)XFTSystem->finderCrate[crate]-
> >>> FinderBoard2_4Elements[nbrd]->finderChipElements[nchp]-
> >>> >CloneXftpixel-
> >>> Clone();
> >>                 }
> >>         }
> >>
> >>         SimTree->Fill()
> >>
> >> This compiles and runs, but crashes filling the CloneXftpixel in the
> >> FillTree() method.
> >>
> >> Instead of the if (nPix>0), I also tried to do this with a loop as in
> >> the At() statement :
> >>          for (int i=0; i < nPix; nPix++) {
> >>            xftpixelB =
> >> (xft2Lpixel*)XFTSystem->finderCrate[crate]-
> >>> FinderBoard2_4Elements[nbrd]->finderChipElements[nchp]-
> >>> >CloneXftpixel-
> >>> At(i);
> >>           }
> >>
> >> but this crashed in the same place.
> >>
> >> What is the correct way to do this ?
> >>
> >> Cheers,
> >> Ben




This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:06 MET