Re: BrOutputTreeModule

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Wed Sep 25 2002 - 08:31:57 EDT

  • Next message: Andrey Makeev: "ZDC calibrations (runs 4954-5002)"

    Hi Jens, Peter, et al, 
    
    Just a few comments on BrOutputTreeModule in general.  
    
    The approach of registering output modules by class name and pointer,
    and always using a TClonesArray (as I think you do), I'm afraid I find
    a bit ill.  I once made a small example of how one could make a
    BRAT-like framework in ROOT, using TTask, TFolder, TTree, and
    similar.  Take a look at here [1].  
    
    In essence, I think you should have modules that follows the
    BrOutputTreeModule that does: 
    
    
      Init: 
        Register branches in the tree.  That means that BrOutputTreeModule
        should either be a container that passes down the TTree, or it
        should be a static (singleton) object.
    
      Event:  
        Read whatever data object form the input event node and as the
        object to be stored on a branch. 
    
        BrOutputTreeModule then needs to send the message Fill to the
        tree.  
    
    Example code: 
    
    
      class BtContainer : public BrModuleContainer { 
      private: 
        TTree* fTree; 
        ... 
      public: 
        ... 
        void  AddModule(BrModule* m) { MayNotCall(...); }
        void  AddModule(BtModule* m) { BrModuleContainer::Add(m); }
        ...
        void Init() { 
          fTree = new TTree("T", ...); 
          ...
          TIter next(fModules); 
          BtModule* b = 0; 
          while ((b = (BtModule*)next())) b->Init(fTree); 
          ...
        }
        ...
      }; 
    
      class BtModule : public BrModule { 
        ...
      }
    
      class BtTrackModule : public BtModule { 
      private:    
        TClonesArray* fCache; 
      public: 
        ...
        void Init(TTree* tree) { 
          fTracks = new TClonesArray("BrTrack"); 
          tree->Branch(GetName(), &fTracks); 
        } 
        void Event(BrEventNode* inNode, BrEventNode*) { 
          BrDataTable* t = inNode->GetDataTable(GetName()); 
          
          for (Int_t i = 0; i < t->GetEntries(); i++) 
            fTracks->operator()[i] = (BrTrack*)t->At(i);
        }
        ...
      };
    
      class BtVertexModule : puclic BtModule { 
      private: 
        BrVertex* fVertex; 
      public:
        ... 
        void Init(TTree* tree) { 
          tree->Branch(GetName(), "BrVertex", &fVertex, 32000, 99);
        }; 
        void Event(BrEventNode* inNode, BrEventNode*) {
          fVertex = (BrVertex*)inNode->GetDataObject(GetName()); 
        }
        ...
      };
    
    The reason why I like this kind of approach better, is that you don't
    have to deal directly with ROOT's meta information, which is a hairy
    matter.   Second off, it points in a direction I think we should take
    BRAT in: Storage is done on much more `browsable' trees, and more use
    of cached memory (currently, we basically recreate a large number of
    objects at each event pass - very inefficient).  Also the above
    approach is much more flexible.  And finally, you achive a clear
    seperation in small classes (modules) that does exactly one thing -
    the Right Way(tm) for OOP. 
     
    Yours, 
    
     ____ |  Christian Holm Christensen 
      |_| |	 -------------------------------------------------------------
        | |	 Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
         _|	          DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
        _|	          Denmark                    Office: (+45) 353  25 305
     ____|	 Email:   cholm@nbi.dk               Web:    www.nbi.dk/~cholm
     | |
    
    [1] http://cholm.home.cern.ch/cholm/root/#rootfw 
    



    This archive was generated by hypermail 2b30 : Wed Sep 25 2002 - 08:32:51 EDT