Re: [ROOT] tree splitting

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Apr 13 2001 - 12:00:57 MEST


Hi Sue,
   
We are not making good progress with the implementation of the
new Tree branching mechanism (TTree::Bronch).
Our development version (3.01/00) includes several enhancements,
including support for pointers to abstract classes in split mode.
I tested that your example works correctly with our development version.
   
To facilitate the migration to the new branches, I have added a new
function TTree::SetBranchStyle(Int_t style=1) (a static function).
   
To use the new branching mechanism, do TTree::SetBranchStyle(1);
This will become the default very soon in the development version.
      
With this new function, you can keep the calls to TTree::Branch.
TTree::Branch will automatically call the new branches (TBronch)
or the old TBranch depending on the branching style.
      
In the development version, it is now possible to use TTree::Draw
and the TTreeViewer.
   
Our goal is to release this version in time for the ROOT workshop in June.
   
   Rene Brun
      
      

On Thu, 12 Apr 2001, Susan Kasahara wrote:

> 
> Hi Rooter's,
> I have another TTree::Bronch question.  Some time ago I posted
> a message on ROOT talk digest:
> http://root.cern.ch/root/roottalk/roottalk00/1572.html
> regarding  the capabilities of TTree::Branch to store objects
> of my class "Simple" on a ROOT TTree in splitmode, where
> this Simple class included a data member:
> TShape* fShape;
> that is actually the base class of the objects to be stored
> on the TTree.   The answer at the time was that TTree::Branch
> could not support this situation, but that it would
> be considered for future versions of ROOT.
> I am wondering if it is expected that TTree::Bronch will support
> this scenario?  I am not able to get it to work in my tests
> (using the same driver code and classes as posted on
> http://root.cern.ch/root/roottalk/roottalk00/1572.html
> but substituting:
>   simpletree -> Bronch("Simple","Simple",&simple,16000,1);
> for
>   simpletree -> Branch("Simple","Simple",&simple,16000,1);
> in the driver code),
> but I notice that it fails now in the fill of objects to the tree and
> not the read as before.
>   I am optimistic that it is at least a possibility, since TBranchElement
> does not require the derived ClassName of the object to be stored there
> as an argument (as did TBranchObject).  I am using ROOT v 3.00.06
> and gcc 2.95.2 on Linux.
> -Sue
> 
> 
> Rene Brun wrote:
> 
> > Hi Sue,
> >
> > As I said in my previous mail, the split mode supported by the current
> > TTree::Branch has many restrictions, including the one you mention
> > about the TObjArray. The new split mode supported by TTree::Bronch
> > has no limitations compared to the non-split mode. Bronch supports correctly
> > the two cases: TObjArray and TObjArray*.
> > With Bronch, the splitlevel can be used to control the depth of splitting.
> > Try for example:
> >
> >   tree -> Bronch("Validity","VldContext",&valid,32000,9);
> >
> > I encourage people to start playing with TTree::Bronch instead of TTree::Branch.
> > However, note that, as indicated in the documentation of this function,
> > one cannot use TTree::Draw or the TreeViewer with Trees created with
> > TTree::Bronch in the production version 3.00/06.
> > This already works in my development version (not yet in CVS).
> >
> > Rene Brun
> >
> > Susan Kasahara wrote:
> > >
> > > Hi Rene and Pasha,
> > > Thank you both for your advice.  I tried the TTree::Bronch method
> > > as you suggested and it did successfully write out the enumerated
> > > fDetector data member.  I did notice that when I switched to the
> > > TTree::Bronch method, i.e. from
> > >   tree -> Branch("Validity","VldContext",&valid,32000,1);
> > > to
> > >   tree -> Bronch("Validity","VldContext",&valid,32000,1);
> > > that the TObject base class of VldContext was not longer split
> > > into two separate branches for the fUniqueId and fBits data members
> > > as it was using TTree::Branch.
> > > Is this to be expected?
> > >
> > > I have another TTree splitting question.  I've noticed that when
> > > I attempt to store a class in split mode that has a TObjArray data member , e.g.
> > > class Event {
> > > public:
> > > ...
> > > private:
> > >   TObjArray fData;
> > >    Int_t          fEvtNumber;
> > > };
> > >
> > > And store it on a tree in split mode:
> > >   TTree* tree = new TTree("TestTree","test tree");
> > >   Event* event = 0;
> > >   tree -> Branch("EventBranch","Event",&event,32000,1);
> > >
> > > That ROOT will attempt to split the TObjArray (to 7 branches), and since the
> > > data member of the TObjArray which contains the array's data has been "!" out, ROOT will
> > > not write the actual data of the TObjArray to the TTree.
> > > On the other hand, storing the TObjArray by pointer as a data member of the
> > > Event class, e.g.
> > > class Event {
> > > public:
> > > ...
> > > private:
> > >   TObjArray* fData;
> > >    Int_t          fEvtNumber;
> > > };
> > > does seem to work since the customized Streamer of the TObjArray is invoked
> > > to stream the TObjArray data out to a single ROOT TBranch.
> > > I guess what I'd like is to preserve the Event structure of the first case (with
> > > the fData TObjArray stored by value), but have the  Event splitting results of the
> > > second case, with the TObjArray data streamed out to a single ROOT TBranch.
> > > Is this possible?
> > > Thanks again,
> > > -Sue
> > >
> > > Rene Brun wrote:
> > >
> > > > Hi Sue, Pasha,
> > > >
> > > > enums are not recognized by TTree::Branch in split mode.
> > > > They are supported by TTree::Bronch in 3.00/06. You can make a test
> > > > by replacing the line:
> > > >   tree -> Branch("Validity","VldContext",&valid,32000,1);
> > > > by:
> > > >   tree -> Bronch("Validity","VldContext",&valid,32000,1);
> > > >
> > > > Read TTree::Bronch for more info.
> > > > I am now finishing the implementation of the new split mode. The new split
> > > > mode (Bronch) has no limitation compared to the non-split mode.
> > > > With the next major release 3.01 scheduled for early June, Bronch will
> > > > be renamed Branch. The new split/no-split mode in Trees will have several
> > > > new features. In addition to the extended C++ support described
> > > > at http://root.cern.ch/root/SchemaEvolution.html , the new Trees will also
> > > > be connected with the TFolder structure. Trees can be generated automatically
> > > > from an existing TFolder hierarchy and vice-versa a TFolder hierarchy
> > > > automatically generated from a Tree structure.
> > > > This new functionality will be included in the first development releases
> > > > of 3.01 in 2 or 3 weeks.
> > > >
> > > > Rene Brun
> > > >
> > > > Susan Kasahara wrote:
> > > > >
> > > > > Hi rooters,
> > > > > I am having a problem with the ROOT tree splitting method.
> > > > > I have a simple class "VldContext" with just two data members:
> > > > >
> > > > >    DetectorType::Detector_t   fDetector;
> > > > >    Int_t                      fTimeStamp;
> > > > >
> > > > > The first data member is of an enumerated type Detector_t defined
> > > > > in a separate class DetectorType.  What I would like is to have these
> > > > > two data members, fDetector and fTimeStamp, be stored on two separate
> > > > > subbranches of the same TTree.
> > > > >
> > > > > I set up a tree with one main branch to hold these VldContext objects
> > > > > in split mode (split level = 1), using the form:
> > > > >
> > > > >   TTree* tree = new TTree("TestTree","test tree");
> > > > >   VldContext* valid = 0;
> > > > >   tree -> Branch("Validity","VldContext",&valid,32000,1);
> > > > >
> > > > > And have noticed that although a subbranch is created for the fTimeStamp
> > > > > data member as expected, no subbranch is created for the fDetector
> > > > > data member.  I am assuming the problem has something to do with
> > > > > fDetector's specialized enumerated data type that is somehow not being
> > > > > recognized by ROOT.
> > > > >
> > > > > I am attaching the code for the test driver program, the VldContext
> > > > > class, and the DetectorType class.  These tests are being run on a
> > > > > RH Linux system using gcc 2.95.2 and ROOT version 3.00.04.
> > > > >
> > > > > Any ideas as to how to fix this?
> > > > >
> > > > > Thanks,
> > > > > Sue Kasahara
> > > > >
> > > > > **************** The test driver program **********************************
> > > > > #include <iostream.h>
> > > > > #include "TROOT.h"
> > > > > #include "TFile.h"
> > > > > #include "TTree.h"
> > > > > #include "VldContext.h"
> > > > >
> > > > > TROOT root("TestWrt","MINOS Persistency Package Test Write");
> > > > >
> > > > > int main() {
> > > > >
> > > > >   TFile* file = TFile::Open("test.root","RECREATE","test file");
> > > > >   TTree* tree = new TTree("TestTree","test tree");
> > > > >
> > > > >   VldContext* valid = 0;
> > > > >   tree -> Branch("Validity","VldContext",&valid,32000,1);
> > > > >
> > > > >   // Begin entry loop
> > > > >   Int_t nent = 100;
> > > > >   for (Int_t ient=0; ient < nent; ient++) {
> > > > >     DetectorType::Detector_t dtype = DetectorType::kCalib;  // detector type
> > > > >     Int_t tstamp = 100;
> > > > >     VldContext* valid = new VldContext(dtype,tstamp);
> > > > >     if (valid) {
> > > > >        tree -> Fill();
> > > > >     }
> > > > >     delete valid; // clean up validity object
> > > > >   }
> > > > >
> > > > >   tree -> Write();
> > > > >   tree -> Print();
> > > > >   file -> Close();
> > > > >
> > > > >   return 0;
> > > > >
> > > > > }
> > > > >
> > > > > **************** The VldContext class **********************************
> > > > >
> > > > > #include "TObject.h"
> > > > > #include "DetectorType.h"
> > > > >
> > > > > class VldContext : public TObject {
> > > > >
> > > > >  public:
> > > > >
> > > > >    VldContext();
> > > > >    VldContext(const DetectorType::Detector_t &detector,
> > > > >               const Int_t &time);
> > > > >    virtual ~VldContext();
> > > > >
> > > > >  protected:
> > > > >
> > > > >    DetectorType::Detector_t   fDetector;
> > > > >    Int_t                      fTimeStamp;
> > > > >
> > > > >  private:
> > > > >
> > > > >    ClassDef(VldContext,1)  // VldContext version 1
> > > > > };
> > > > >
> > > > > #include "VldContext.h"
> > > > >
> > > > > ClassImp(VldContext)
> > > > >
> > > > > VldContext::VldContext()
> > > > > {
> > > > >    // Default constructor
> > > > > }
> > > > >
> > > > > VldContext::VldContext(const DetectorType::Detector_t &detector,
> > > > >                        const Int_t &tstamp)
> > > > >    : fDetector(detector), fTimeStamp(tstamp)
> > > > > {
> > > > >    // normal constructor
> > > > > }
> > > > >
> > > > > VldContext::~VldContext()
> > > > > {
> > > > >    // delete all the owned sub-objects
> > > > >
> > > > > }
> > > > >
> > > > > ********************The DetectorType class**********************************
> > > > >
> > > > > #include "Rtypes.h"
> > > > >
> > > > > class DetectorType {
> > > > >  public:
> > > > >    typedef enum EDetectorType {
> > > > >       kNear      = 0x01,
> > > > >       kFar       = 0x02,
> > > > >       kCalib     = 0x04,
> > > > >       kTestStand = 0x08,
> > > > >       kMapper    = 0x10
> > > > >    } Detector_t;
> > > > >
> > > > >    // no ctor or dtor's - this class consists of only static members
> > > > >
> > > > >    // Translation from enum to character strings
> > > > >
> > > > >    static char *AsString(Detector_t detector) {
> > > > >       switch (detector) {
> > > > >       case kNear:      return "Near";       break;
> > > > >       case kFar:       return "Far";        break;
> > > > >       case kCalib:     return "Calib";      break;
> > > > >       case kTestStand: return "TestStand";  break;
> > > > >       case kMapper:    return "Mapper";     break;
> > > > >       default:         return "Unknown";    break;
> > > > >       }
> > > > >    }
> > > > >
> > > > >    ClassDef(DetectorType,1)
> > > > >
> > > > > };
> > > > >
> > > > > #include "DetectorType.h"
> > > > >
> > > > > ClassImp(DetectorType)
> 
> 
> 



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:41 MET