Re: [ROOT] TTree question

From: Susan Kasahara (schubert@physics.umn.edu)
Date: Thu May 25 2000 - 18:23:40 MEST


Hi Rene and Pasha,
Thank you both for your advice.  I have tried out what you suggest, Rene,
and I see that it does (rather impressively) work if I use split level = 0.   I would
really like though to keep the two data members on separate branches, so that I
can read them in separately if I wish (this is a necessity in the real version of
the simplified code that I'm presenting here).   Is there a way to make it work
in the case of split branches?
Thanks,
Sue Kasahara

Rene Brun wrote:

> Hi Sue,
> Your program is correct, except that you should not use the split mode
> in this situation. Simply replace:
>
>   simpletree->Branch("Simple","Simple",&simple,16000,1);
> by
>   simpletree->Branch("Simple","Simple",&simple,16000,0);
>
> Rene Brun
>
> Susan Kasahara wrote:
> >
> > Hi Rooter's,
> > I am wondering if the following is possible:
> >   I have a class "Simple" (since this is a simplified example of what
> > I'm actually trying to do) that has two data members:
> > Int_t   fID;
> > TShape* fShape;
> >
> > It has a constructor:
> > Simple(Int_t id, TShape* shape): fID(id), fShape(shape) { }
> >
> > that can be called with an object of any class that inherits from TShape, e.g.
> >
> > TTUBE* tube = new TTUBE("TUBE","TUBE","void",150,200,400); // TTUBE inherits from TShape
> > Simple* simple = new Simple(1,tube);  // invoke Simple constructor
> >
> > I am trying to store the Simple objects in a ROOT Tree.  What I find
> > is that when I fill the tree with the Simple objects, e.g.
> >
> > TTree *simpletree = new TTree("SimpleTree","Simple Tree");
> > Simple *simple = 0;
> > // Split branches to store fShape objects & fID on separate branches
> > simpletree->Branch("Simple","Simple",&simple,16000,1);
> > TTUBE *tube = new TTUBE("TUBE","TUBE","void",150,200,400);
> > simple = new Simple(1,tube);
> > simpletree -> Fill(); // store first Simple object in Tree
> > ...
> >
> > ,that the TTree::Fill method correctly recognizes that the fShape pointer should
> > invoke the TTUBE::Streamer method to write the TTUBE object to the TTree.
> >
> > But when I try to read the Simple object back in from the tree, e.g.:
> >
> > ...
> > // Retrieve ROOT tree holding the data
> > TTree *tree = (TTree*)file -> Get("SimpleTree");
> > Simple *simple = new Simple();
> > tree -> SetBranchAddress("Simple",&simple);
> > nb = tree -> GetEntry(0);
> > ...
> >
> > it does not invoke the TTUBE::Streamer method to read the TTUBE object
> > back into memory, instead it invokes the TShape::Streamer method (and
> > then I get an error message).
> >
> > Has anybody tried something similar or have any ideas on how to
> > make this work?  Or is this just a bad design idea, I'd appreciate input
> > on that too.
> > I attach the code that I'm using on a RH Linux 6.0 system using
> > ROOT v2.24/02.
> >
> > Thanks for any help,
> > Sue Kasahara
> >
> > #ifndef SIMPLE_H
> > #define SIMPLE_H
> > ///////////////////////////////////////////////////////////////////////////
> > //                                                                       //
> > // Simple class                                                 //
> > //                                                                       //
> > ///////////////////////////////////////////////////////////////////////////
> > #include "TShape.h"
> > #include <iostream.h>
> >
> > class Simple : public TObject {
> >
> > private:
> >    Int_t   fID;         // id number
> >    TShape* fShape;      // pointer to base class shape
> >
> > public:
> >
> >    Simple() : fID(0), fShape(0) { }
> >    Simple(Int_t id, TShape* shape): fID(id), fShape(shape) { }
> >    virtual ~Simple();
> >    virtual void Print(Option_t *option = "") const;
> >
> >    ClassDef(Simple,1)  //Simple class
> > };
> >
> > #endif                         // SIMPLE_H
> >
> > /////////////////////////////////////////////////////////////////////////////////
> > // Simple.cxx                                                          //
> > /////////////////////////////////////////////////////////////////////////////////
> > #include <iostream.h>
> > #include "Simple.h"
> >
> > ClassImp(Simple)
> >
> > Simple::~Simple() {
> > // Destructor
> >   if (fShape) {
> >     delete fShape;
> >     fShape =0;
> >   }
> > }
> >
> > void Simple::Print(Option_t *option) const {
> >   // Print the contents
> >   cout << "fID= " << fID << endl;
> >   fShape -> Print();
> >
> > }
> >
> > /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
> > // Driver code to open file, create tree, and write 3 Simple objects to     //
> > // tree.                                                                                                           //
> > ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
> > #include "TROOT.h"
> > #include "TFile.h"
> > #include "TTree.h"
> > #include "TTUBE.h"
> > #include "Simple.h"
> >
> > TROOT test("test","Program to test simple classes");
> >
> > int main(int argc, char **argv)
> > {
> >
> > // Open output file to hold events
> >   TFile *simplefile = new TFile("simple.root","RECREATE","Simple root file");
> >
> > // Create a ROOT tree to hold the simple data
> >   TTree *simpletree = new TTree("SimpleTree","Simple Tree");
> >
> >   Simple *simple = 0;
> >   // Split branches to store fShape objects & fID on separate branches
> >   simpletree->Branch("Simple","Simple",&simple,16000,1);
> >
> >   for (Int_t ient=0; ient < 3; ient++) {
> > // Create 3 Simple objects containing TTube's and store each in tree
> >     TTUBE *tube = new TTUBE("TUBE","TUBE","void",150,200,400);
> >     // tube is adopted & deleted by Simple
> >     simple = new Simple(ient,tube);
> >     simple -> Print();
> >     simpletree -> Fill();
> >     delete simple;
> >   }
> >
> > // Write the simple tree to file
> >   simplefile->Write();
> > // Print final summary of simple tree contents
> >   simpletree->Print();
> >
> >   return 0;
> > }
> >
> > ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
> > //                                                                                                                       //
> > // Code to open root file containing tree, Get tree, and attempt to read in //
> > // 3 Simple objects from tree                                                                         //
> > //                                                                                                                      //
> > //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
> > #include "TROOT.h"
> > #include "TFile.h"
> > #include "TTree.h"
> > #include "TTUBE.h"
> > #include "Simple.h"
> >
> > TROOT test("test","Program to test simple classes");
> >
> > int main(int argc, char **argv)
> > {
> >
> > // Open file to read Simple entries
> >   TFile *file = new TFile("simple.root","READ");
> >
> > // Retrieve ROOT tree holding the data
> >   TTree *tree = (TTree*)file -> Get("SimpleTree");
> >
> >   Simple *simple = new Simple();
> >   tree -> SetBranchAddress("Simple",&simple);
> >
> >   Int_t nentries = (Int_t)tree -> GetEntries();
> >   Int_t nb;
> >   for (Int_t ient=0; ient < nentries; ient++) {
> >      nb = tree -> GetEntry(ient);
> >      simple -> Print();
> >   }
> >
> >   return 0;
> >
> > }



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:26 MET