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