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