]> 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 4586b44b67db66d357968095ff291d718906c795..747cfbad0e6c15e5cfc71c6e9ebe2645b21a3cae 100644 (file)
@@ -3,24 +3,30 @@
 
 #ifndef ALIHLTOUT_H
 #define ALIHLTOUT_H
-/* This file is property of and copyright by the ALICE HLT Project        * 
- * ALICE Experiment at CERN, All rights reserved.                         *
- * See cxx source for full Copyright notice                               */
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
 
 /** @file   AliHLTOUT.h
     @author Matthias Richter
     @date   
     @brief  The control class for HLTOUT data.
+*/
 
-// see below for class documentation
-// or
-// refer to README to build package
-// or
-// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
-
-                                                                          */
 #include <vector>
 #include "AliHLTLogging.h"
+#include "AliHLTModuleAgent.h"
+
+class AliHLTOUTHandler;
+class AliHLTOUTHandlerDesc; // AliHLTModuleAgent.h
+class AliESDEvent;
+class AliHLTReconstructor;
+class AliRawReader;
+class TTree;
+
+#define AliHLTOUTInvalidIndex (~(AliHLTUInt32_t)0)
+
+typedef vector<AliHLTUInt32_t> AliHLTOUTIndexList;
 
 /**
  * @class AliHLTOUT
@@ -31,7 +37,7 @@
  * abstracts access to the complete HLTOUT data.
  * 
  */
-class AliHLTOUT : public AliHLTLogging {
+class AliHLTOUT {
  public:
   /** standard constructor */
   AliHLTOUT();
@@ -39,50 +45,41 @@ class AliHLTOUT : public AliHLTLogging {
   virtual ~AliHLTOUT();
 
   /**
-   * Get number of data blocks in the HLTOUT data
-   */
-  int GetNofDataBlocks();
-
-  /**
-   * Select the first data block of a certain data type and specification.
-   * The selection criteria can be of kAliHLTAnyDataType and/or
-   * kAliHLTVoidDataSpec in order to be ignored and just match any data block.
-   * @param dt    [in]  data type to match                                <br>
-   * @param spec  [in]  data specification to match                       <br>
-   * @return identifier >=0 if success, neg. error code if failed         <br>
-   *                        -ENOENT if no block found                     <br>
-   *                        -EPERM if access denied (object locked)
+   * Create an AliHLTOUTRawReader instance.
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
    */
-  int SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec);
+  static AliHLTOUT* New(AliRawReader* pRawReader);
 
   /**
-   * Select the next data block of data type and specification of the previous
-   * call to @ref SelectFirstDataBlock.
-   * @return identifier >=0 if success, neg. error code if failed         <br>
-   *                        -ENOENT if no block found                     <br>
-   *                        -EPERM if access denied (object locked)
+   * Create an AliHLTOUTDigitReader instance
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
    */
-  int SelectNextDataBlock();
+  static AliHLTOUT* New(TTree* pDigitTree, int event=-1);
 
   /**
-   * Get properties of the selected data block.
-   * @param dt    [out] data type of the selected block
-   * @param spec  [out] data specification of the selected block
+   * Create an AliHLTOUTDigitReader instance
+   * Helper function to transparently access classes from the
+   * libHLTrec library.
    */
-  int GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec);
+  static AliHLTOUT* New(const char* filename, int event=-1);
 
   /**
-   * Get buffer of the selected data block.
-   * @param pBuffer [out] buffer of the selected data block
-   * @param size    [out] size of the selected data block
+   * 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.
    */
-  int GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size);
+  static AliHLTOUT* GetGlobalInstance() {return fgGlobalInstance;}
 
   /**
-   * Release buffer after use.
-   * @param pBuffer [in]  buffer of the selected data block
+   * 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.
    */
-  int ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer);
+  static void Delete(AliHLTOUT* pInstance);
 
   /**
    * Locking guard for the AliHLTOUT object.
@@ -109,6 +106,35 @@ class AliHLTOUT : public AliHLTLogging {
     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.
@@ -118,46 +144,398 @@ class AliHLTOUT : public AliHLTLogging {
     AliHLTUInt32_t fLength; //! see above
     /** version of the header */
     AliHLTUInt32_t fVersion; //! see above
-    /** event id */
-    AliHLTUInt64_t fEventID; //! 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
-  /** 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
+  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)
-      : fDataType(dt), fSpecification(spec), fIndex(index) {};
+    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;}
-  private:
+    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
   };
 
-  enum AliHLTOUTByteOrder_t {
+  /**
+   * Init for processing.
+   * The HLTOUT is scanned for all available data blocks and the
+   * AliHLTOUTHandler objects for the data blocks are created according
+   * to the module agents (see AliHLTModuleAgent).
+   */
+  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
+   */
+  int GetNofDataBlocks();
+
+  /**
+   * Select the first data block of a certain data type and specification.
+   * The selection criteria can be of kAliHLTAnyDataType and/or
+   * kAliHLTVoidDataSpec in order to be ignored and just match any data block.
+   *
+   * The search criteria can be combined with a handler type (e.g. kRawReader)
+   * @param dt    [in]  data type to match                                <br>
+   * @param spec  [in]  data specification to match                       <br>
+   * @param handlerType [in]  type of the handler
+   * @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,
+                          bool skipProcessed=true);
+
+  /**
+   * Select the next data block of data type and specification of the previous
+   * call to @ref SelectFirstDataBlock.
+   * @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 SelectNextDataBlock();
+
+  /**
+   * Get properties of the selected data block.
+   * @param dt    [out] data type of the selected block
+   * @param spec  [out] data specification of the selected block
+   */
+  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
+   */
+  AliHLTUInt32_t GetDataBlockIndex();
+
+  /**
+   * Get buffer of the selected data block.
+   * @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);
+
+  /**
+   * Release buffer after use.
+   * @param pBuffer [in]  buffer of the selected data block
+   */
+  int ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer);
+
+  /**
+   * Get a TObject from the data buffer
+   * @return TObject pointer if data block is a streamed object
+   */
+  TObject* GetDataObject();
+
+  /**
+   * Release data object
+   */
+  int ReleaseDataObject(TObject* pObject);
+
+  /**
+   * Add the current data block to the selection.
+   * Note: enables also the block selection
+   */
+  int SelectDataBlock();
+
+  /**
+   * Add the all data blocks of a certain handler to the selection.
+   * Note: enables also the block selection
+   */
+  int SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerDesc);
+
+  /**
+   * Enable the selection of data blocks.
+   */
+  int EnableBlockSelection();
+
+  /**
+   * Disable the selection of data blocks.
+   */
+  int DisableBlockSelection();
+
+  /**
+   * Reset the data block selection.
+   * Resets the selection list, none of the blocks is selected.
+   */
+  int ResetBlockSelection();
+
+  /**
+   * Mark the current block as processed.
+   */
+  int MarkDataBlockProcessed();
+
+  /**
+   * 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();
+
+  /**
+   * 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,
@@ -165,7 +543,7 @@ class AliHLTOUT : public AliHLTLogging {
     kBigEndian
   };
 
-  enum AliHLTOUTDataType_t {
+  enum AliHLTOUTDataType {
     kUint64 = 0,
     kUint32 = 1,
     kUint16 = 2,
@@ -177,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:
   /**
@@ -194,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&);
@@ -204,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,
@@ -215,7 +651,13 @@ 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
   };
 
   /**
@@ -224,6 +666,18 @@ class AliHLTOUT : public AliHLTLogging {
    */
   virtual int GenerateIndex()=0;
 
+  /**
+   * Find AliHLTOUTHandler objects for the data blocks.
+   * The available AliHLTModuleAgents are probed whether they provide
+   * handlers for data processing.
+   */
+  int InitHandlers();
+
+  /**
+   * Cleanup and reset the data input.
+   */
+  virtual int ResetInput();
+
   /**
    * Get the data buffer
    * @param index   [in]  index of the block
@@ -236,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)
@@ -275,24 +733,73 @@ class AliHLTOUT : public AliHLTLogging {
    */
   int CheckStatusFlag(unsigned int flag) const {return (fFlags&flag)==flag;}
 
+  /**
+   * Find handler description for a certain block index.
+   */
+  const AliHLTOUTHandlerListEntry& FindHandlerDesc(AliHLTUInt32_t blockIndex);
+
+  /**
+   * 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.
+   */
+  virtual void SetParam(const char* filename, int event=-1);
+
   /** data type for the current block search, set from @ref SelectFirstDataBlock */
   AliHLTComponentDataType fSearchDataType; //!transient
 
   /** 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
 
-  ClassDef(AliHLTOUT, 0)
+  /** list of AliHLTOUTHandlers */
+  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, 6)
 };
 #endif