Hi Maurik, The restrictions about the split mode listed at the URL: http://root.cern.ch/root/HowtoWriteTree.html concern the automatic split mode. The last section of this URL says: "Making branches by hand If you are not happy with the way the automatic split algorithm works, you can create branches yourself by invoking directly the TTree::Branch function." Obviously, we encourage people to create classes such that the automatic split algorithm can be applied. When you run in "NON-SPLIT" mode, the Streamer function for the referenced object is called. When you run in SPLIT mode, each data member of the referenced object is written to a separate branch. - If Root encounters a basic type, it does not need to invoke a Streamer function (which one?). It can directly write this member to the branch buffer. - same for a static array (eg, Int_t array[12]) - If a member is a pointer to TObject* or derived, the corresponding Streamer is called to stream this object in its branch buffer. - If a member is a pointer to a TClonesArray, each member of the class referenced by the TClonesArray is written to a separate branch. No need for a Streamer in this case. Rene Brun Maurik Holtrop wrote: > > Hello Rene, > > Thank you for the reply. I re-read the documentation you reccommended, and > still don't understand through what method the classes are serialized when > split_level=1. From my tests I think it is not the Streamer method. > > The documentation states: > "In split mode, a data member cannot be a pointer to an array of basic > types." > "In split mode, a data member cannot be a C structure." > > So an array of structures is definetely out of the question with the > standard code. But can I write my own? > If I can not, is there a way to make writing a tree of my objects more > efficient than the "create" "write" "delete" cycle that is currently used? > > The full code for my classes (the one with the pointer into a big memory > array) can be found at: > http://improv.unh.edu/root_problem.txt. This file is a concat of 4 files: > TBOSBankHeader.h and .cc and TBOSRoot.h and .cc. > > Your help is much appreciated, > > Maurik Holtrop > > P.S. Here is some example code. > > Instead of the full class, I send you an example wich illustrates that the > Streamer function of a class does not get called when writing the clas with > split_level=1. This example however, works perfectly fine. When split level > =1 the variables are written to disk through some other mechanism. However, > for classes (unlike this example) that *need* a highly customized streamer, > this means writing won't work. > > The following macro (write.C) will print 10 times "Streamer called" when > split level is 0, but not when split level is 1. > > /////////////////////////// write.C: > { > tempa *part=new tempa(1,2.); > TFile hfile("split.root","RECREATE","Demo ROOT file"); > TTree *tree = new TTree("T","An example"); > tree->Branch("tempa","tempa",&part,10240,0); > > for(int i=0; i<10; i++){ > part.i=i; > part.x=i*i*10.; > tree->Fill(); > } > tree->Print(); > hfile.Write(); > hfile.Close(); > } > > ////////////////////// test2.cc > #include "test2.h" > > ClassImp(tempa) > > ostream &operator<<(ostream &os,tempa &b) > { > os << " Int: " << b.i; > os << " Float: " << b.x; > os << " C: " << b.str << endl; > return(os); > } > > void tempa::Streamer(TBuffer &R__b) > { > // Stream an object of class tempa. > cerr << "Streamer called\n"; > > if (R__b.IsReading()) { > Version_t R__v = R__b.ReadVersion(); if (R__v) { } > TObject::Streamer(R__b); > R__b >> i; > R__b >> x; > R__b.ReadStaticArray(str); > } else { > R__b.WriteVersion(tempa::IsA()); > TObject::Streamer(R__b); > R__b << i; > R__b << x; > R__b.WriteArray(str, 256); > } > } > > ///////////////////// test2.h > #ifndef __CINT__ > #include "TObject.h" > #endif > > #include <iostream.h> > > class tempa : public TObject{ > > public: > int i; > float x; > char str[256]; > public: > > tempa(){ cout << "******** tempa constructor called\n";}; > ~tempa(){cout << "######## tempa destructor called\n";}; > tempa(int a,float b){ > i=a; > x=b; > strcpy(str,"Initialized with constructor."); > } > > void Print(){ > cout << (*this) << endl; > } > > friend ostream &operator<<(ostream &os,tempa &b); > > ClassDef(tempa,1) > }; > > ------------------------------------------------------------------------ > > Maurik Holtrop <maurik.holtrop@unh.edu> > UNH Nuclear Physics > > Maurik Holtrop > UNH Nuclear Physics <maurik.holtrop@unh.edu> > 9 Library Way Fax: (603) 862-2998 > Lee Home: (603) 659-8765 > NH Work: (603) 862-2019 > 03824 Netscape Conference Address > USA > Additional Information: > Last Name Holtrop > First Name Maurik > Version 2.1
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:34 MET