Hi Sue, I agree that it would be nice to support your model in split mode as well. The change should be transparent, but it requires some work. On my shopping list. Rene Brun Susan Kasahara wrote: > > 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