]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTOUT.h
Cosmetics. Fixed bug preventing creation of async block list
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.h
index 3fdd32a8460a024230927f034438c4ddd63870af..747cfbad0e6c15e5cfc71c6e9ebe2645b21a3cae 100644 (file)
 
 class AliHLTOUTHandler;
 class AliHLTOUTHandlerDesc; // AliHLTModuleAgent.h
+class AliESDEvent;
+class AliHLTReconstructor;
+class AliRawReader;
+class TTree;
 
 #define AliHLTOUTInvalidIndex (~(AliHLTUInt32_t)0)
 
@@ -33,13 +37,326 @@ typedef vector<AliHLTUInt32_t> AliHLTOUTIndexList;
  * abstracts access to the complete HLTOUT data.
  * 
  */
-class AliHLTOUT : public AliHLTLogging {
+class AliHLTOUT {
  public:
   /** standard constructor */
   AliHLTOUT();
   /** standard destructor */
   virtual ~AliHLTOUT();
 
+  /**
+   * Create an AliHLTOUTRawReader instance.
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
+   */
+  static AliHLTOUT* New(AliRawReader* pRawReader);
+
+  /**
+   * Create an AliHLTOUTDigitReader instance
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
+   */
+  static AliHLTOUT* New(TTree* pDigitTree, int event=-1);
+
+  /**
+   * Create an AliHLTOUTDigitReader instance
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
+   */
+  static AliHLTOUT* New(const char* filename, int event=-1);
+
+  /**
+   * Get the global instance.
+   * The global instance is set temporarily by the AliHLTOUTGlobalInstanceGuard
+   * mainly for the sake of data input to an analysis chain. The
+   * AliHLTOUTPublisherComponent objects can access the global instance.
+   */
+  static AliHLTOUT* GetGlobalInstance() {return fgGlobalInstance;}
+
+  /**
+   * Delete an instance of the HLTOUT.
+   * Helper function to transparently access classes from the
+   * libHLTrec library. Before deleting, the availability of the
+   * library is checked.
+   */
+  static void Delete(AliHLTOUT* pInstance);
+
+  /**
+   * Locking guard for the AliHLTOUT object.
+   * If the object is locked, the selection of data blocks can not be changed.
+   */
+  class AliHLTOUTLockGuard {
+  public:
+    /** constructor */
+    AliHLTOUTLockGuard(AliHLTOUT* pInstance) : fpInstance(pInstance)
+    {if (fpInstance) fpInstance->SetStatusFlag(kLocked);}
+    /** destructor */
+    ~AliHLTOUTLockGuard()
+    {if (fpInstance) fpInstance->ClearStatusFlag(kLocked);}
+
+  private:
+    /** standard constructor prohibited */
+    AliHLTOUTLockGuard();
+    /** copy constructor prohibited */
+    AliHLTOUTLockGuard(const AliHLTOUTLockGuard&);
+    /** assignment operator prohibited */
+    AliHLTOUTLockGuard& operator=(const AliHLTOUTLockGuard&);
+
+    /** the AliHLTOUT instance the guard is locking */
+    AliHLTOUT* fpInstance; //!transient
+  };
+
+  /**
+   * Guard for handling of global AliHLTOUT instance.
+   * The global HLTOUT instance can be set for certain steps of the
+   * processing. The initial objective is to support input to the
+   * AliHLTOUTPublisherComponent running in a kChain handler.
+   *
+   * The Guard restores the original instance when closed.
+   */
+  class AliHLTOUTGlobalInstanceGuard {
+  public:
+    /** constructor */
+    AliHLTOUTGlobalInstanceGuard(AliHLTOUT* pInstance) : fpLastInstance(AliHLTOUT::fgGlobalInstance)
+    {AliHLTOUT::fgGlobalInstance=pInstance;}
+    /** destructor */
+    ~AliHLTOUTGlobalInstanceGuard()
+    {AliHLTOUT::fgGlobalInstance=fpLastInstance;}
+
+  private:
+    /** standard constructor prohibited */
+    AliHLTOUTGlobalInstanceGuard();
+    /** copy constructor prohibited */
+    AliHLTOUTGlobalInstanceGuard(const AliHLTOUTGlobalInstanceGuard&);
+    /** assignment operator prohibited */
+    AliHLTOUTGlobalInstanceGuard& operator=(const AliHLTOUTGlobalInstanceGuard&);
+
+    /** the AliHLTOUT instance the guard is locking */
+    AliHLTOUT* fpLastInstance; //!transient
+  };
+
+  /**
+   * The HLT OUT Event Header.
+   * Defined between HLT and DAQ.
+   */
+  struct AliHLTOUTEventHeader {
+    /**Total length of the data in bytes, including HLT event header, excluding CDH. */
+    AliHLTUInt32_t fLength; //! see above
+    /** version of the header */
+    AliHLTUInt32_t fVersion; //! see above
+    /** High 32 bit word of event id */
+    AliHLTUInt32_t fEventIDHigh; //! see above
+    /** Low 32 bit word of event id */
+    AliHLTUInt32_t fEventIDLow; //! see above
+  };
+
+  enum {
+    /// versions 1 of the HLT header
+    kVersion1 = 1,
+    /// versions 2 of the HLT header
+    kVersion2 = 2
+  };
+
+  enum {
+    /// size of HLT decision in data format version 1: 29x4
+    kSizeDecisionVersion1 = 116,
+    /// size of HLT decision in data format version 2: 30x4
+    kSizeDecisionVersion2 = 120
+  };
+
+  // definitions from ALICE internal notes ALICE-INT-2002-010 and
+  // ALICE-INT-2006-XXX
+  enum {
+    /** the 32bit word in the CDH containing the status flags */
+    kCDHStatusWord=4, //! see above
+    /** start of the flags in word fgkCDHStatusWord */
+    kCDHStatusFlagsOffset=12, //! see above
+    /** bit indicating HLT decision in the HLTOUT*/
+    kCDHFlagsHLTDecision=6, //! see above
+    /** bit indicating HLT payload in the HLTOUT*/
+    kCDHFlagsHLTPayload=7 //! see above
+  };
+
+  class AliHLTOUTHandlerListEntry;
+  /**
+   * Block descriptor.
+   */
+  class AliHLTOUTBlockDescriptor {
+  public:
+    AliHLTOUTBlockDescriptor(AliHLTComponentDataType dt, AliHLTUInt32_t spec, AliHLTUInt32_t index, AliHLTOUT* pCollection)
+      : fDataType(dt), fSpecification(spec), fIndex(index), fSelected(false), fProcessed(false), fpCollection(pCollection) {};
+    AliHLTOUTBlockDescriptor(const AliHLTOUTBlockDescriptor& src)
+      : fDataType(src.fDataType), fSpecification(src.fSpecification), fIndex(src.fIndex), fSelected(false), fProcessed(false), fpCollection(src.fpCollection) {}
+    AliHLTOUTBlockDescriptor& operator=(const AliHLTOUTBlockDescriptor& src)
+    { fDataType=src.fDataType; fSpecification=src.fSpecification; fIndex=src.fIndex; fSelected=false; fProcessed=false; fpCollection=src.fpCollection; return *this; }
+    ~AliHLTOUTBlockDescriptor() {}
+
+    operator AliHLTComponentDataType() const {return fDataType;}
+    operator AliHLTUInt32_t() const {return fSpecification;}
+    int operator==(AliHLTComponentDataType dt) const {return dt==fDataType;}
+    int operator==(AliHLTUInt32_t spec) const {return spec==fSpecification;}
+    int operator==(AliHLTOUT* collection) const {return collection==fpCollection;}
+
+    AliHLTUInt32_t GetIndex() const {return fIndex;}
+    AliHLTOUT* GetCollection() const {return fpCollection;}
+
+    bool IsSelected() const {return fSelected;}
+    void Select(bool selected=true) {fSelected=selected;}
+    bool IsProcessed() const {return fProcessed;}
+    void MarkProcessed() {fProcessed=true;}
+
+    /**
+     * Get the data buffer
+     * @param pBuffer [out] buffer of the selected data block
+     * @param size    [out] size of the selected data block
+     */
+    int GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size) {
+      if (fpCollection) return fpCollection->GetDataBuffer(GetIndex(), pBuffer, size);
+      return -ENODEV;
+    }
+
+    /**
+     * Get the handler descriptor
+     */
+    const AliHLTOUTHandlerListEntry& GetHandlerDesc();
+
+  private:      
+    /** data type of the block */
+    AliHLTComponentDataType fDataType; //!transient
+    /** data specification of the block */
+    AliHLTUInt32_t          fSpecification; //!transient
+    /** index in the data stream */
+    AliHLTUInt32_t          fIndex; //!transient
+    /** selection flag */
+    bool                    fSelected; //!transient
+    /** processed flag */
+    bool                    fProcessed; //!transient
+    /** the collection */
+    AliHLTOUT*              fpCollection; //!transient
+  };
+
+  class AliHLTOUTHandlerListEntry {
+  public:
+    AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler, 
+                             AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
+                             AliHLTModuleAgent* pAgent,
+                             AliHLTUInt32_t index);
+
+    /** copy constructor for vector handling */
+    AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src);
+
+    /** assignment operator for vector handling */
+    AliHLTOUTHandlerListEntry& operator=(const AliHLTOUTHandlerListEntry& src);
+
+    ~AliHLTOUTHandlerListEntry();
+
+    static const AliHLTOUTHandlerListEntry fgkVoidHandlerListEntry; //! initializer
+
+    operator AliHLTOUTHandler*() const {return fpHandler;}
+
+    // please note that fpHandlerDesc is really a pointer and is created
+    // in the constructor. Thats why it is dereferenced here. The pointer
+    // type is on purpose, even though it is a bit confusing with the 
+    // argument by reference in the AliHLTOUTHandlerListEntry constructor.
+    operator const AliHLTModuleAgent::AliHLTOUTHandlerDesc&() const 
+    {return fpHandlerDesc?*fpHandlerDesc:AliHLTModuleAgent::fgkVoidHandlerDesc;}
+    operator AliHLTModuleAgent*() const {return fpAgent;}
+
+    /**
+     * Two list entries are considered to be equal if the handlers
+     * are equal.
+     */
+    bool operator==(const AliHLTOUTHandlerListEntry& entry) const;
+
+    bool operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const;
+
+    /**
+     * Compare the handler descriptor of this list entry with another
+     * descriptor.
+     * @return true if both handler and agent match
+     */
+    bool operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const; 
+
+    AliHLTUInt32_t operator[](int i) const;
+
+    /**
+     * Add a block index to this descriptor.
+     * One descriptor can serve multiple blocks if the agent returns the
+     * same handler for all of the blocks. Instead of creating a new entry
+     * the block index ist just added
+     */
+    void AddIndex(AliHLTUInt32_t index);
+
+    /**
+     * Add all indices of the descriptor.
+     */
+    void AddIndex(AliHLTOUTHandlerListEntry &desc);
+
+    /**
+     * Check if an index is served by this descriptor.
+     * @return true if the index is in the table
+     */
+    bool HasIndex(AliHLTUInt32_t index) const;
+
+    /**
+     * Invalidate all block indices
+     */
+    void InvalidateBlocks() {fBlocks.clear();}
+
+    /**
+     * Check whether the entry has valid blocks.
+     */
+    bool IsEmpty() {return fBlocks.size()==0;}
+
+  private:
+    /** standard constructor prohibited */
+    AliHLTOUTHandlerListEntry();
+
+    /** pointer to the handler */
+    AliHLTOUTHandler* fpHandler; //! transient
+
+    /** pointer to handler description */
+    AliHLTModuleAgent::AliHLTOUTHandlerDesc* fpHandlerDesc; //! transient
+
+    /** pointer to module agent */
+    AliHLTModuleAgent* fpAgent; //! transient
+
+    /** list of block indices */
+    AliHLTOUTIndexList fBlocks; //!transient
+  };
+
+  typedef vector<AliHLTOUTHandlerListEntry> AliHLTOUTHandlerListEntryVector;
+  typedef vector<AliHLTOUTBlockDescriptor>  AliHLTOUTBlockDescriptorVector;
+  typedef vector<AliHLTOUT*>                AliHLTOUTPVector;
+
+  /**
+   * Selection guard for the AliHLTOUT object.
+   * If the object is locked, the selection of data blocks can not be changed.
+   */
+  class AliHLTOUTSelectionGuard {
+  public:
+    /** constructor */
+    AliHLTOUTSelectionGuard(AliHLTOUT* pInstance) : fpInstance(pInstance)
+    {if (fpInstance) fpInstance->SelectDataBlock();}
+    /** constructor */
+    AliHLTOUTSelectionGuard(AliHLTOUT* pInstance, const AliHLTOUTHandlerListEntry* pHandlerDesc) : fpInstance(pInstance)
+    {if (fpInstance) fpInstance->SelectDataBlocks(pHandlerDesc);}
+    /** destructor */
+    ~AliHLTOUTSelectionGuard()
+    {if (fpInstance) fpInstance->DisableBlockSelection();}
+
+  private:
+    /** standard constructor prohibited */
+    AliHLTOUTSelectionGuard();
+    /** copy constructor prohibited */
+    AliHLTOUTSelectionGuard(const AliHLTOUTSelectionGuard&);
+    /** assignment operator prohibited */
+    AliHLTOUTSelectionGuard& operator=(const AliHLTOUTSelectionGuard&);
+
+    /** the AliHLTOUT instance the guard is locking */
+    AliHLTOUT* fpInstance; //!transient
+  };
+
   /**
    * Init for processing.
    * The HLTOUT is scanned for all available data blocks and the
@@ -48,6 +365,20 @@ class AliHLTOUT : public AliHLTLogging {
    */
   int Init();
 
+  /**
+   * Reset and clear all data block descriptors.
+   * @note Since sub-collections are only referred via the block
+   * descriptors, all information on sub-collections is also lost.
+   * Child classes should implement ResetInput in order to cleanup
+   * the input devices.
+   */
+  int Reset();
+
+  /**
+   * Get the current event id
+   */
+  AliHLTUInt64_t EventId() {return fCurrentEventId;}
+
   /**
    * Get number of data blocks in the HLTOUT data
    */
@@ -62,18 +393,20 @@ class AliHLTOUT : public AliHLTLogging {
    * @param dt    [in]  data type to match                                <br>
    * @param spec  [in]  data specification to match                       <br>
    * @param handlerType [in]  type of the handler
-   * @return identifier >0 if success, 0 if no block found                <br>
+   * @param skipProcessed [in] skip all block marked processed
+   * @return block index: >= 0 if success, -ENOENT if no block found      <br>
    *         neg. error code if failed                                    <br>
    *                        -EPERM if access denied (object locked)
    */
   int SelectFirstDataBlock(AliHLTComponentDataType dt=kAliHLTAnyDataType,
                           AliHLTUInt32_t spec=kAliHLTVoidDataSpec,
-                          AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=AliHLTModuleAgent::kUnknownOutput);
+                          AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=AliHLTModuleAgent::kUnknownOutput,
+                          bool skipProcessed=true);
 
   /**
    * Select the next data block of data type and specification of the previous
    * call to @ref SelectFirstDataBlock.
-   * @return identifier >0 if success, 0 if no block found                <br>
+   * @return block index: >= 0 if success, -ENOENT if no block found      <br>
    *         neg. error code if failed                                    <br>
    *                        -EPERM if access denied (object locked)
    */
@@ -86,6 +419,17 @@ class AliHLTOUT : public AliHLTLogging {
    */
   int GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec);
 
+  /**
+   * Get handler description of the current data block.
+   */
+  const AliHLTOUTHandlerListEntry& GetDataBlockHandlerDesc();
+
+  /**
+   * Get handler type of the selected data block.
+   * @return handler type for the selected data block
+   */
+  AliHLTModuleAgent::AliHLTOUTHandlerType GetDataBlockHandlerType();
+
   /**
    * Get the index of the current data block.
    * @return index, AliHLTOUTInvalidIndex if no block selected
@@ -106,84 +450,92 @@ class AliHLTOUT : public AliHLTLogging {
   int ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer);
 
   /**
-   * Get handler for the selected data block.
+   * Get a TObject from the data buffer
+   * @return TObject pointer if data block is a streamed object
    */
-  AliHLTOUTHandler* GetHandler();
+  TObject* GetDataObject();
 
   /**
-   * Locking guard for the AliHLTOUT object.
-   * If the object is locked, the selection of data blocks can not be changed.
+   * Release data object
    */
-  class AliHLTOUTLockGuard {
-  public:
-    /** constructor */
-    AliHLTOUTLockGuard(AliHLTOUT* pInstance) : fpInstance(pInstance)
-    {if (fpInstance) fpInstance->SetStatusFlag(kLocked);}
-    /** destructor */
-    ~AliHLTOUTLockGuard()
-    {if (fpInstance) fpInstance->ClearStatusFlag(kLocked);}
+  int ReleaseDataObject(TObject* pObject);
 
-  private:
-    /** standard constructor prohibited */
-    AliHLTOUTLockGuard();
-    /** copy constructor prohibited */
-    AliHLTOUTLockGuard(const AliHLTOUTLockGuard&);
-    /** assignment operator prohibited */
-    AliHLTOUTLockGuard& operator=(const AliHLTOUTLockGuard&);
+  /**
+   * Add the current data block to the selection.
+   * Note: enables also the block selection
+   */
+  int SelectDataBlock();
 
-    /** the AliHLTOUT instance the guard is locking */
-    AliHLTOUT* fpInstance; //!transient
-  };
+  /**
+   * Add the all data blocks of a certain handler to the selection.
+   * Note: enables also the block selection
+   */
+  int SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerDesc);
 
   /**
-   * The HLT OUT Event Header.
-   * Defined between HLT and DAQ.
+   * Enable the selection of data blocks.
    */
-  struct AliHLTOUTEventHeader {
-    /**Total length of the data in bytes, including HLT event header, excluding CDH. */
-    AliHLTUInt32_t fLength; //! see above
-    /** version of the header */
-    AliHLTUInt32_t fVersion; //! see above
-    /** event id */
-    AliHLTUInt64_t fEventID; //! see above
-  };
+  int EnableBlockSelection();
 
-  // definitions from ALICE internal notes ALICE-INT-2002-010 and
-  // ALICE-INT-2006-XXX
-  /** the 32bit word in the CDH containing the status flags */
-  static const unsigned char fgkCDHStatusWord; //! see above
-  /** start of the flags in word fgkCDHStatusWord */
-  static const unsigned char fgkCDHStatusFlagsOffset; //! see above
-  /** bit indicating HLT decision in the HLTOUT*/
-  static const unsigned char fgkCDHFlagsHLTDecision; //! see above
-  /** bit indicating HLT payload in the HLTOUT*/
-  static const unsigned char fgkCDHFlagsHLTPayload; //! see above
+  /**
+   * Disable the selection of data blocks.
+   */
+  int DisableBlockSelection();
 
   /**
-   * Block descriptor.
+   * Reset the data block selection.
+   * Resets the selection list, none of the blocks is selected.
    */
-  class AliHLTOUTBlockDescriptor {
-  public:
-    AliHLTOUTBlockDescriptor(AliHLTComponentDataType dt, AliHLTUInt32_t spec, AliHLTUInt32_t index)
-      : fDataType(dt), fSpecification(spec), fIndex(index) {};
-    ~AliHLTOUTBlockDescriptor() {}
+  int ResetBlockSelection();
 
-    operator AliHLTComponentDataType() const {return fDataType;}
-    operator AliHLTUInt32_t() const {return fSpecification;}
-    int operator==(AliHLTComponentDataType dt) const {return dt==fDataType;}
-    int operator==(AliHLTUInt32_t spec) const {return spec==fSpecification;}
+  /**
+   * Mark the current block as processed.
+   */
+  int MarkDataBlockProcessed();
 
-    AliHLTUInt32_t GetIndex() const {return fIndex;}
-  private:
-    /** data type of the block */
-    AliHLTComponentDataType fDataType; //!transient
-    /** data specification of the block */
-    AliHLTUInt32_t          fSpecification; //!transient
-    /** index in the data stream */
-    AliHLTUInt32_t          fIndex; //!transient
-  };
+  /**
+   * Mark all data blocks of a certain handler processed.
+   */
+  int MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc);
+
+  /**
+   * Add a sub collection to the HLTOUT.
+   */
+  int AddSubCollection(AliHLTOUT* pCollection);
+
+  /**
+   * Release a previously added sub collection.
+   */
+  int ReleaseSubCollection(AliHLTOUT* pCollection);
+
+  /**
+   * Get module agent for the selected data block.
+   */
+  AliHLTModuleAgent* GetAgent();
+
+  /**
+   * Get handler for the selected data block.
+   */
+  AliHLTOUTHandler* GetHandler();
 
-  enum AliHLTOUTByteOrder_t {
+  /**
+   * Convert data buffer to ESD.
+   * The buffer is supposed to describe a streamed AliESDEvent object.
+   * If no target object is specified, the ESD is written to a file AliHLTdetESDs.root,
+   * where 'det' is derived from the data type origin. Each time the function is invoked
+   * a new event is created. Dummy events are added if the previous events did not contain
+   *
+   * The function needs AliRoot and might not be implemented by all AliHLTOUT
+   * implementations.
+   * a data block of this specification.
+   * @param pBuffer  [in] the data buffer
+   * @param size     [in] data buffer size
+   * @param dt       [in] data type of the block
+   * @param tgtesd   [out] optional target
+   */
+  virtual int WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliESDEvent* tgtesd=NULL) const;
+
+  enum AliHLTOUTByteOrder {
     /** no data block selected */
     kInvalidByteOrder=-1,
     kUnknownByteOrder=0,
@@ -191,7 +543,7 @@ class AliHLTOUT : public AliHLTLogging {
     kBigEndian
   };
 
-  enum AliHLTOUTDataType_t {
+  enum AliHLTOUTDataType {
     kUint64 = 0,
     kUint32 = 1,
     kUint16 = 2,
@@ -203,12 +555,55 @@ class AliHLTOUT : public AliHLTLogging {
   /**
    * Check byte order of selected block
    */
-  AliHLTOUTByteOrder_t CheckByteOrder();
+  AliHLTOUTByteOrder CheckByteOrder();
 
   /**
    * Check alignment of selected block
    */
-  int CheckAlignment(AliHLTOUT::AliHLTOUTDataType_t type);
+  int CheckAlignment(AliHLTOUT::AliHLTOUTDataType type);
+
+  /**
+   * Helper function to byte swap a 64 bit value.
+   */
+  static AliHLTUInt64_t ByteSwap64(AliHLTUInt64_t src);
+
+  /**
+   * Helper function to byte swap a 32 bit value.
+   */
+  static AliHLTUInt32_t ByteSwap32(AliHLTUInt32_t src);
+
+  /**
+   * Insert a handler item.
+   * The current list entries are checked if the handler is already in
+   * the list. It is added if not in the list, otherwise the block index
+   * is added to the existing entry.
+   * @param list     the handler list
+   * @param entry    handler list entry
+   * @return 0 if added, EEXIST (non negative!) if merged with existing entry <br>
+   *         neg. error code if failed
+   */
+  static int InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry);
+  
+  /**
+   * Insert all handlers of the specified type to the list.
+   */
+  int FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType);
+
+  /**
+   * Remove empty items which have a duplicate in the list.
+   */
+  static int RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list);
+
+  /**
+   * Find an entry of a certain description in the list.
+   * @return index of the entry if found, -ENOENT if not found
+   */
+  static int FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc);
+
+  /**
+   * Invalidate all blocks of the handlers in the list
+   */
+  static int InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list);
 
  protected:
   /**
@@ -220,6 +615,21 @@ class AliHLTOUT : public AliHLTLogging {
    */
   int AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc);
 
+  /**
+   * Set the event id, only for child classes
+   */
+  void SetEventId(AliHLTUInt64_t id);
+
+  /**
+   * Print output or suppress.
+   */
+  bool BeVerbose() {return fbVerbose;}
+
+  /**
+   * Switch output.
+   */
+  void SwitchVerbosity(bool verbose) {fbVerbose=verbose;}
+
  private:
   /** copy constructor prohibited */
   AliHLTOUT(const AliHLTOUT&);
@@ -230,7 +640,7 @@ class AliHLTOUT : public AliHLTLogging {
    * Internal status flags
    */
   enum {
-    /** the HLTOUT object is locked with the current data block */
+    /** the HLTOUT object is locked with the current data block selection */
     kLocked = 0x1,
     /** childs can add block descriptors */
     kCollecting = 0x2,
@@ -241,55 +651,15 @@ class AliHLTOUT : public AliHLTLogging {
     /** user of the data block has checked the alignment */
     kAlignmentChecked = 0x10,
     /** warning on alignment missmatch has been printed */
-    kAlignmentWarning = 0x20
+    kAlignmentWarning = 0x20,
+    /** enable block selection list */
+    kBlockSelection = 0x40,
+    /** skip processed data blocks */
+    kSkipProcessed = 0x80,
+    /** marked as sub collection */
+    kIsSubCollection = 0x100
   };
 
-  class AliHLTOUTHandlerListEntry {
-  public:
-    AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler, 
-                             AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
-                             AliHLTModuleAgent* pAgent,
-                             AliHLTUInt32_t index);
-
-    /** copy constructor for vector handling */
-    AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src);
-
-    /** assignment operator for vector handling */
-    AliHLTOUTHandlerListEntry& operator=(const AliHLTOUTHandlerListEntry& src);
-
-    ~AliHLTOUTHandlerListEntry();
-
-    static const AliHLTOUTHandlerListEntry fgkVoidHandlerListEntry;
-
-    operator AliHLTOUTHandler*() const {return fpHandler;}
-    operator AliHLTModuleAgent::AliHLTOUTHandlerDesc&() {return *fpHandlerDesc;}
-    operator AliHLTModuleAgent*() const {return fpAgent;}
-
-    bool operator==(const AliHLTOUTHandlerListEntry& entry) const;
-
-    AliHLTUInt32_t operator[](int i) const;
-
-    void AddIndex(AliHLTUInt32_t index);
-
-    bool HasIndex(AliHLTUInt32_t index);
-
-  private:
-    /** standard constructor prohibited */
-    AliHLTOUTHandlerListEntry();
-
-    /** pointer to the handler */
-    AliHLTOUTHandler* fpHandler; //! transient
-
-    /** pointer to handler description */
-    AliHLTModuleAgent::AliHLTOUTHandlerDesc* fpHandlerDesc; //! transient
-
-    /** pointer to module agent */
-    AliHLTModuleAgent* fpAgent; //! transient
-
-    /** list of block indexes */
-    AliHLTOUTIndexList fBlocks; //!transient
-  };
-  
   /**
    * Generate the index of the HLTOUT data.
    * Must be implemented by the child classes.
@@ -303,6 +673,11 @@ class AliHLTOUT : public AliHLTLogging {
    */
   int InitHandlers();
 
+  /**
+   * Cleanup and reset the data input.
+   */
+  virtual int ResetInput();
+
   /**
    * Get the data buffer
    * @param index   [in]  index of the block
@@ -315,18 +690,22 @@ class AliHLTOUT : public AliHLTLogging {
   /**
    * Check byte order of data block
    */
-  virtual AliHLTOUTByteOrder_t CheckBlockByteOrder(AliHLTUInt32_t index)=0;
+  virtual AliHLTOUTByteOrder CheckBlockByteOrder(AliHLTUInt32_t index)=0;
 
   /**
    * Check alignment of data block
    */
-  virtual int CheckBlockAlignment(AliHLTUInt32_t index, AliHLTOUT::AliHLTOUTDataType_t type)=0;
+  virtual int CheckBlockAlignment(AliHLTUInt32_t index, AliHLTOUT::AliHLTOUTDataType type)=0;
 
   /**
    * Select the data block of data type and specification of the previous
    * call to @ref SelectFirstDataBlock. Core function of @ref SelectFirstDataBlock
    * and @ref SelectNextDataBlock, starts to find a block at the current list
-   * position. 
+   * position.
+   * 
+   * The data block is searched from the conditions of fSearchDataType,
+   * fSearchSpecification, fSearchHandlerType and the selection list.
+   *
    * @return identifier >=0 if success, neg. error code if failed         <br>
    *                        -ENOENT if no block found                     <br>
    *                        -EPERM if access denied (object locked)
@@ -355,20 +734,30 @@ class AliHLTOUT : public AliHLTLogging {
   int CheckStatusFlag(unsigned int flag) const {return (fFlags&flag)==flag;}
 
   /**
-   * Insert a handler item.
-   * The current list entries are checked if the handler is already in
-   * the list. It is added if not in the list, otherwise the block index
-   * is added to the existing entry.
-   * @param entry    handler list entry
-   * @return 0 if added, EEXIST (non negative!) if merged with existing entry <br>
-   *         neg. error code if failed
+   * Find handler description for a certain block index.
    */
-  int InsertHandler(const AliHLTOUTHandlerListEntry &entry);
+  const AliHLTOUTHandlerListEntry& FindHandlerDesc(AliHLTUInt32_t blockIndex);
 
   /**
-   * Find handler description for a certain block index.
+   * Set the RawReader as parameter.
+   * The function is for internal use only in conjunction with the
+   * New() functions.
+   */
+  virtual void SetParam(AliRawReader* pRawReader);
+
+  /**
+   * Set the RunLoader as parameter
+   * The function is for internal use only in conjunction with the
+   * New() functions.
+   */
+  virtual void SetParam(TTree* pDigitTree, int event=-1);
+
+  /**
+   * Set name of the digit file as parameter
+   * The function is for internal use only in conjunction with the
+   * New() functions.
    */
-  AliHLTOUTHandlerListEntry FindHandlerDesc(AliHLTUInt32_t blockIndex);
+  virtual void SetParam(const char* filename, int event=-1);
 
   /** data type for the current block search, set from @ref SelectFirstDataBlock */
   AliHLTComponentDataType fSearchDataType; //!transient
@@ -376,21 +765,41 @@ class AliHLTOUT : public AliHLTLogging {
   /** data specification for the current block search */
   AliHLTUInt32_t fSearchSpecification; //!transient
 
+  /** handler type for the current block search */
+  AliHLTModuleAgent::AliHLTOUTHandlerType fSearchHandlerType; // !transient
+
   /** instance flags: locked, collecting, ... */
   unsigned int fFlags; //!transient
 
   /** list of block descriptors */
-  vector<AliHLTOUTBlockDescriptor> fBlockDescList; //!transient
+  AliHLTOUTBlockDescriptorVector fBlockDescList; //!transient
 
   /** current position in the list */
-  vector<AliHLTOUTBlockDescriptor>::iterator fCurrent; //!transient
+  unsigned int fCurrent; //!transient
 
   /** data buffer under processing */
   const AliHLTUInt8_t* fpBuffer; //!transient
 
   /** list of AliHLTOUTHandlers */
-  vector<AliHLTOUTHandlerListEntry> fDataHandlers; // !transient
+  AliHLTOUTHandlerListEntryVector fDataHandlers; // !transient
+
+  /** verbose or silent output */
+  bool fbVerbose; //!transient
+
+  /** gobal instance set for certain steps of the analysis */
+  static AliHLTOUT* fgGlobalInstance; //! transient
+
+  /** logging methods */
+  AliHLTLogging fLog; //! transient
+
+  /** current buffer converted to a TObject */
+  TObject* fpDataObject; //!
+  const AliHLTUInt8_t* fpObjectBuffer; //!
+  AliHLTUInt32_t fObjectBufferSize; //!
+
+  /** current event id */
+  AliHLTUInt64_t fCurrentEventId; //!
 
-  ClassDef(AliHLTOUT, 1)
+  ClassDef(AliHLTOUT, 6)
 };
 #endif