]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONRawStreamTrackerHP.h
In AliMUONReconstructor:
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTrackerHP.h
index f4fbc8e0567473afa03b5ea0fcb3b4447678b0d4..9f9be0dbe8b0614eaa838ab26a23a429667ea909 100644 (file)
 /// \brief  Declaration of the high performance decoder for muon trigger chamber raw streams.
 ///
 
-#include "AliMUONVRawStreamTracker.h"
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
 #include "AliMUONTrackerDDLDecoder.h"
 
-class AliMUONRawStreamTrackerHP : public AliMUONVRawStreamTracker
+#include <cstring>
+
+class AliMUONDDLTracker;
+class AliRawReader;
+class AliMUONLogger;
+
+class AliMUONRawStreamTrackerHP : public TObject
 {
 public:
+       class AliDspHeader;
+       class AliBusPatch;
+       
+       /// Values indicating the logging detail level to use for error messages.
+       enum EDetailLevel
+       {
+               kLowErrorDetail,     /// Logs minimal information in the error messages.
+               kMediumErrorDetail,  /// Logs a medium level of detail in the error messages.
+               kHighErrorDetail     /// Logs maximum information in the error messages.
+       };
 
        /// Default constructor.
        AliMUONRawStreamTrackerHP();
@@ -29,7 +47,11 @@ public:
        /// Default destructor.
        virtual ~AliMUONRawStreamTrackerHP();
        
-       // The following public methods are all inherited from AliMUONVRawStreamTracker:
+       /// Get object for reading the raw data
+       virtual AliRawReader* GetReader() { return fRawReader; }
+       
+       /// Set the raw reader
+       void SetReader(AliRawReader* reader) { fRawReader = reader; }
        
        /// Initialize iterator
        virtual void First();
@@ -39,18 +61,24 @@ public:
        
        /// Whether the iteration is finished or not
        virtual Bool_t IsDone() const;
-       
-       /// Nothing is actually done in the AddErrorMessage method because we log
-       /// the error messages as we find them in AliDecoderEventHandler::OnError().
-       virtual void AddErrorMessage() {};
+
+       /// Advance one step in the iteration. Returns false if finished.
+       virtual Bool_t Next(Int_t& busPatchId,
+                           UShort_t& manuId, UChar_t& manuChannel,
+                           UShort_t& adc) { return Next(busPatchId,manuId,manuChannel,adc,kTRUE); }
        
        /// Advance one step in the iteration. Returns false if finished.
        virtual Bool_t Next(Int_t& busPatchId,
-                               UShort_t& manuId, UChar_t& manuChannel,
-                               UShort_t& adc);
+                      UShort_t& manuId,
+                      UChar_t& manuChannel,
+                      UShort_t& adc,
+                      Bool_t skipParityErrors);
+
+       /// Construct and return a pointer to the DDL payload object.
+       virtual AliMUONDDLTracker* GetDDLTracker() const;
        
        /// Returns the next batch of decoded channel data.
-       virtual UInt_t Next(const AliChannelInfo*& channels);
+       const AliBusPatch* Next();
        
        /// Return maximum number of blocks per DDL allowed.
        virtual Int_t GetMaxBlock() const { return (Int_t) fDecoder.MaxBlocks(); }
@@ -60,17 +88,503 @@ public:
        virtual Int_t GetMaxBus() const { return (Int_t) fDecoder.MaxBusPatches(); }
        
        /// Set maximum number of blocks per DDL allowed.
-       virtual void SetMaxBlock(Int_t blk) { fDecoder.MaxBlocks( (UInt_t) blk ); }
+       virtual void SetMaxBlock(Int_t blk);
        /// Set maximum number of Dsp per block allowed.
-       virtual void SetMaxDsp(Int_t dsp) { fDecoder.MaxDSPs( (UInt_t) dsp ); }
+       virtual void SetMaxDsp(Int_t dsp);
        /// Set maximum number of Buspatch per Dsp allowed.
-       virtual void SetMaxBus(Int_t bus) { fDecoder.MaxBusPatches( (UInt_t) bus ); }
+       virtual void SetMaxBus(Int_t bus);
        
-       /// Return number of the current DDL.
+       /// Return number of the current DDL being processed in the range [0..19] or -1 if no DDL set.
        virtual Int_t GetDDL() const { return fDDL - 1; }
        
        /// check error/Warning presence
        virtual Bool_t IsErrorMessage() const { return fHadError; }
+       
+       /// Get number of parity errors in the DDL last decoded.
+       Int_t   GetParityErrors() const
+       {
+               return (Int_t) fDecoder.GetHandler().ParityErrorCount();
+       }
+
+       /// Get number of glitch errors in the DDL last decoded.
+       Int_t   GetGlitchErrors() const
+       {
+               return (Int_t) fDecoder.GetHandler().GlitchErrorCount();
+       }
+
+       /// Get number of padding word errors in the DDL last decoded.
+       Int_t   GetPaddingErrors() const
+       {
+               return (Int_t) fDecoder.GetHandler().PaddingErrorCount();
+       }
+
+       /// Get number of token lost errors in the DDL last decoded.
+       Int_t   GetTokenLostErrors() const
+       {
+               return (Int_t) fDecoder.GetHandler().TokenLostCount();
+       }
+
+       /// Set warnings flag to disable warnings on data errors.
+       void DisableWarnings() { fWarnings = kFALSE; }
+       /// Set warnings flag to enable warnings on data errors.
+       void EnableWarnings() { fWarnings = kTRUE; }
+       
+        /// Returns the flag indicating if we should generate a warning for errors.
+       Bool_t IsWarningsEnabled() const { return fWarnings; }
+
+       /// Returns the "try to recover from errors" flag.
+       Bool_t TryRecover() const { return Bool_t(fDecoder.TryRecover()); }
+       
+       /// Sets the "try to recover from errors" flag.
+       /// i.e. should the decoder try to recover from errors found in the
+       /// payload headers.
+       void TryRecover(Bool_t value) { fDecoder.TryRecover(bool(value)); }
+       
+       /// Returns the auto-detect trailer words flag.
+       Bool_t AutoDetectTrailer() const { return Bool_t(fDecoder.AutoDetectTrailer()); }
+       
+       /// Sets the auto-detect trailer words flag.
+       /// When set to true the decoder will try to detect if the end of DDL
+       /// keys are in the trailer words or not. These are generated by the
+       /// detector but not the older versions of AliRoot simulations.
+       void AutoDetectTrailer(Bool_t value) { fDecoder.AutoDetectTrailer(bool(value)); }
+
+       /// Returns the flag indicating if the data is expected to have the
+       /// end of DDL keys in the trailer. This flag is ignored if AutoDetectTrailer()
+       /// was set to true.
+       Bool_t CheckForTrailer() const { return Bool_t(fDecoder.CheckForTrailer()); }
+       
+       /// Sets the flag indicating if the trailer words should contain the
+       /// end of DDL key.
+       void CheckForTrailer(Bool_t value) { fDecoder.CheckForTrailer(bool(value)); }
+       
+       /// Light weight interface class to the block header data.
+       class AliBlockHeader
+       {
+       public:
+               /// Default constructor.
+               AliBlockHeader(
+                               AliDspHeader* dspArray = NULL,
+                               const AliMUONBlockHeaderStruct* header = NULL
+                       )
+                       : fNext(NULL), fDspCount(0), fFirstDsp(dspArray), fHeader(header)
+               {
+               }
+               
+               /// Implement shallow copying in the copy constructor.
+               AliBlockHeader(const AliBlockHeader& o) :
+                       fNext(o.fNext), fDspCount(o.fDspCount), fFirstDsp(o.fFirstDsp), fHeader(o.fHeader)
+               {
+               }
+               
+               /// Implement shallow copying in the assignment operator.
+               AliBlockHeader& operator = (const AliBlockHeader& object)
+               {
+                       memcpy(this, &object, sizeof(AliBlockHeader));
+                       return *this;
+               }
+       
+               /// Default destructor.
+               ~AliBlockHeader() {};
+       
+               /// Return data key word for CRT header
+               Int_t   GetDataKey()        const {assert(fHeader != NULL); return fHeader->fDataKey;}
+               /// Return total length of block structure (w/o padding word)
+               Int_t   GetTotalLength()    const {assert(fHeader != NULL); return fHeader->fTotalLength;}
+               /// Return length of raw data
+               Int_t   GetLength()         const {assert(fHeader != NULL); return fHeader->fLength;}
+               /// Return Dsp id
+               Int_t   GetDspId()          const {assert(fHeader != NULL); return fHeader->fDSPId;}
+               /// Return L0 trigger word
+               Int_t   GetL0Trigger()      const {assert(fHeader != NULL); return fHeader->fL0Trigger;}
+               /// Return Bunch Crossing for mini-event id (see TDR chapter 8)
+               Int_t   GetMiniEventId()    const {assert(fHeader != NULL); return fHeader->fMiniEventId;}
+               /// Return Event Id in bunch crossing
+               Int_t   GetEventId1()       const {assert(fHeader != NULL); return fHeader->fEventId1;}
+               /// Return Event Id in orbit number
+               Int_t   GetEventId2()       const {assert(fHeader != NULL); return fHeader->fEventId2;}
+       
+               /// Return the header's raw data.
+               const AliMUONBlockHeaderStruct* GetHeader() const {return fHeader;}
+               
+               /// Return the next block header.
+               const AliBlockHeader* Next() const { return fNext; }
+               
+               /// Returns the first AliDspHeader class in this block.
+               const AliDspHeader* GetFirstDspHeader() const { return fFirstDsp; }
+               
+               /// Returns the number of DSPs within this block.
+               UInt_t GetDspCount() const { return fDspCount; }
+       
+               /// Return the i'th DSP in this block.
+               const AliDspHeader* GetDspHeader(UInt_t i) const
+               {
+                       return i < fDspCount ? GetFirstDspHeader() + i : NULL;
+               }
+               
+               /// Sets the next block header.
+               void SetNext(const AliBlockHeader* next) { fNext = next; }
+
+               /// Increments the DSP count.
+               void IncDspCount() { fDspCount++; };
+               
+               /// Print the contents of the header to screen.
+               void Print() const;
+       
+       private:
+       
+               const AliBlockHeader* fNext;  ///< Pointer to next block.
+               UInt_t fDspCount;    ///< The number of AliDspHeader objects found in the array pointed to by fFirstDsp.
+               const AliDspHeader* fFirstDsp;  ///< The first DSP associated with this block.
+               const AliMUONBlockHeaderStruct*  fHeader;  ///< Pointer to header in DDL payload.
+       };
+       
+       /// Light weight interface class to the DSP header data.
+       class AliDspHeader
+       {
+       public:
+               /// Default constructor.
+               AliDspHeader(
+                               const AliBlockHeader* block = NULL,
+                               const AliBusPatch* busPatchArray = NULL,
+                               const AliMUONDSPHeaderStruct* header = NULL
+                       ) :
+                       fBlock(block), fNext(NULL), fBusPatchCount(0),
+                       fFirstBusPatch(busPatchArray), fHeader(header)
+               {
+               }
+               
+               /// Implement shallow copying in the copy constructor.
+               AliDspHeader(const AliDspHeader& o) :
+                       fBlock(o.fBlock), fNext(o.fNext), fBusPatchCount(o.fBusPatchCount),
+                       fFirstBusPatch(o.fFirstBusPatch), fHeader(o.fHeader)
+               {
+               }
+               
+               /// Implement shallow copying in the assignment operator.
+               AliDspHeader& operator = (const AliDspHeader& object)
+               {
+                       memcpy(this, &object, sizeof(AliDspHeader));
+                       return *this;
+               }
+       
+               /// Default destructor.
+               ~AliDspHeader() {};
+       
+               /// Return Data key word for FRT header
+               Int_t   GetDataKey()        const {assert(fHeader != NULL); return fHeader->fDataKey;}
+               /// Return total length of block structure
+               Int_t   GetTotalLength()    const {assert(fHeader != NULL); return fHeader->fTotalLength;}
+               /// Return length of raw data
+               Int_t   GetLength()         const {assert(fHeader != NULL); return fHeader->fLength;}
+               /// Return Dsp id
+               Int_t   GetDspId()          const {assert(fHeader != NULL); return fHeader->fDSPId;}
+               /// Return L1 accept in Block Structure (CRT)
+               Int_t   GetBlkL1ATrigger()  const {assert(fHeader != NULL); return fHeader->fBlkL1ATrigger;}
+               /// Return Mini Event Id in bunch crossing
+               Int_t   GetMiniEventId()    const {assert(fHeader != NULL); return fHeader->fMiniEventId;}
+               /// Return Number of L1 accept in DSP Structure (FRT)
+               Int_t   GetL1ATrigger()     const {assert(fHeader != NULL); return fHeader->fL1ATrigger;}
+               /// Return Number of L1 reject in DSP Structure (FRT)
+               Int_t   GetL1RTrigger()     const {assert(fHeader != NULL); return fHeader->fL1RTrigger;}
+               /// Return padding dummy word for 64 bits transfer
+               UInt_t  GetPaddingWord()    const {assert(fHeader != NULL); return fHeader->fPaddingWord;}
+               /// Return Error word
+               Int_t   GetErrorWord()      const {assert(fHeader != NULL); return fHeader->fErrorWord;}
+       
+               /// Return raw data of header
+               const AliMUONDSPHeaderStruct* GetHeader() const { return fHeader; }
+               
+               /// Return the parent block header.
+               const AliBlockHeader* GetBlockHeader() const { return fBlock; }
+               
+               /// Return the next DSP header.
+               const AliDspHeader* Next() const { return fNext; }
+               
+               /// Returns the first AliBusPatch class in this DSP.
+               const AliBusPatch* GetFirstBusPatch() const { return fFirstBusPatch; }
+               
+               /// Returns the number of bus patches within this DSP.
+               UInt_t GetBusPatchCount() const { return fBusPatchCount; }
+       
+               /// Return the i'th bus patch in this DSP.
+               const AliBusPatch* GetBusPatch(UInt_t i) const
+               {
+                       return i < fBusPatchCount ? GetFirstBusPatch() + i : NULL;
+               }
+       
+               /// Sets the next DSP header.
+               void SetNext(const AliDspHeader* next) { fNext = next; }
+
+               /// Increments the bus patch count.
+               void IncBusPatchCount() { fBusPatchCount++; };
+               
+               /// Print the contents of the header to screen.
+               void Print() const;
+       
+       private:
+       
+               const AliBlockHeader* fBlock;  ///< Pointer to parent block structure.
+               const AliDspHeader* fNext;  ///< Pointer to next DSP.
+               UInt_t fBusPatchCount;    ///< The number of AliDspHeader objects found in the array pointed to by fFirstBusPatch
+               const AliBusPatch* fFirstBusPatch;  ///< The first bus patch of this DSP.
+               const AliMUONDSPHeaderStruct*  fHeader;  ///< Pointer to header in DDL payload.
+       };
+       
+       /// Light weight interface class to the bus patch data.
+       class AliBusPatch
+       {
+       public:
+               /// Default constructor.
+               AliBusPatch(
+                               const AliDspHeader* dsp = NULL,
+                               const AliMUONBusPatchHeaderStruct* header = NULL,
+                               const UInt_t* data = NULL,
+                               const Bool_t* parityOk = NULL
+                       ) :
+                       fDSP(dsp),
+                       fNext(NULL),
+                       fHeader(header),
+                       fData(data),
+                       fParityOk(parityOk)
+               {
+               }
+               
+               /// Implement shallow copying in the copy constructor.
+               AliBusPatch(const AliBusPatch& o) :
+                       fDSP(o.fDSP),
+                       fNext(o.fNext),
+                       fHeader(o.fHeader),
+                       fData(o.fData),
+                       fParityOk(o.fParityOk)
+               {
+               }
+               
+               /// Implement shallow copying in the assignment operator.
+               AliBusPatch& operator = (const AliBusPatch& object)
+               {
+                       memcpy(this, &object, sizeof(AliBusPatch));
+                       return *this;
+               }
+       
+               /// Default destructor.
+               ~AliBusPatch() {};
+               
+               /// Return Data key word for bus patch header.
+               Int_t   GetDataKey()     const {assert(fHeader != NULL); return fHeader->fDataKey;}
+               /// Return total length of buspatch structure
+               Int_t   GetTotalLength() const {assert(fHeader != NULL); return fHeader->fTotalLength;}
+               /// Return length of raw data
+               Int_t   GetLength()      const {assert(fHeader != NULL); return fHeader->fLength;}
+               /// Return bus patch id
+               Int_t   GetBusPatchId()  const {assert(fHeader != NULL); return fHeader->fBusPatchId;}
+
+               /// Return raw data of header
+               const AliMUONBusPatchHeaderStruct* GetHeader() const {return fHeader;}
+               /// Return raw digit data
+               const UInt_t* GetData()  const {return fData;}
+               /// Returns the number of raw data words within this bus patch.
+               UInt_t GetDataCount() const { return (UInt_t)GetLength(); }
+
+               /// Returns the parity bit of the n'th raw data word.
+               Char_t GetParity(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return (Char_t)(fData[n] >> 31) &  0x1;
+               }
+               
+               /// Returns the MANU ID of the n'th raw data word.
+               UShort_t GetManuId(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return (UShort_t)(fData[n] >> 18) &  0x7FF;
+               }
+               
+               /// Returns the channel ID of the n'th raw data word.
+               UChar_t GetChannelId(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return (Char_t)(fData[n] >> 12) & 0x3F;
+               }
+               
+               /// Returns the charge/signal of the n'th raw data word.
+               UShort_t GetCharge(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return (UShort_t)(fData[n] & 0xFFF);
+               }
+               
+               /// Returns the n'th raw data word.
+               UInt_t GetData(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return fData[n];
+               }
+               
+               /// Returns kTRUE if the parity of the n'th raw data word is OK
+               /// and kFALSE otherwise.
+               Bool_t IsParityOk(UInt_t n) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       return fParityOk[n];
+               }
+               
+               /// Unpacks and returns the fields of the n'th raw data word. kTRUE
+               /// is returned if the data word's parity was OK and kFALSE otherwise.
+               Bool_t GetData(UInt_t n, UShort_t& manuId, UChar_t& channelId, UShort_t& adc) const
+               {
+                       assert( fHeader != NULL && n < fHeader->fLength );
+                       AliMUONTrackerDDLDecoderEventHandler::UnpackADC(fData[n], manuId, channelId, adc);
+                       return fParityOk[n];
+               }
+               
+               /// Return the parent block header.
+               const AliDspHeader* GetDspHeader() const { return fDSP; }
+               
+               /// Return the next bus patch header.
+               const AliBusPatch* Next() const { return fNext; }
+               
+               /// Sets the next bus patch.
+               void SetNext(const AliBusPatch* next) { fNext = next; }
+               
+               /// Print the contents of the bus patch to screen.
+               void Print(const Option_t* opt = "") const;
+       
+       private:
+       
+               const AliDspHeader* fDSP;   ///< The DSP this bus patch belongs to.
+               const AliBusPatch* fNext;  ///< Next bus patch object in the DSP.
+               const AliMUONBusPatchHeaderStruct*  fHeader;  ///< Pointer to bus patch in DDL payload.
+               const UInt_t* fData;  ///< Pointer to the bus patch data.
+               const Bool_t* fParityOk;  ///< Array of flags indicating if the parity of the given data word in fData is good or not.          
+       };
+       
+       /// Return the number of blocks in the DDL payload.
+       UInt_t GetBlockCount() const
+       {
+               return fDecoder.GetHandler().BlockCount();
+       }
+       
+       /// Return the first block header.
+       const AliBlockHeader* GetFirstBlockHeader() const
+       {
+               return fDecoder.GetHandler().BlockHeader(0);
+       }
+       
+       /// Return the i'th block header or NULL if not found.
+       const AliBlockHeader* GetBlockHeader(UInt_t i) const
+       {
+               return fDecoder.GetHandler().BlockHeader(i);
+       }
+       
+       /// Returns the number of DSPs for the given block number.
+       UInt_t GetDspCount(UInt_t block) const
+       {
+               const AliBlockHeader* b = GetBlockHeader(block);
+               return b != NULL ? b->GetDspCount() : 0;
+       }
+       
+       /// Returns the i'th DSP header for the given block number or NULL if not found.
+       const AliDspHeader* GetDspHeader(UInt_t block, UInt_t i) const
+       {
+               const AliBlockHeader* b = GetBlockHeader(block);
+               return b != NULL ? b->GetDspHeader(i) : NULL;
+       }
+       
+       /// Returns the number of bus patches for the given block and dsp number.
+       UInt_t GetBusPatchCount(UInt_t block, UInt_t dsp) const
+       {
+               const AliDspHeader* d = GetDspHeader(block, dsp);
+               return d != NULL ? d->GetBusPatchCount() : 0;
+       }
+       
+       /// Returns the i'th bus patch for the given block and dsp.
+       const AliBusPatch* GetBusPatch(UInt_t block, UInt_t dsp, UInt_t i) const
+       {
+               const AliDspHeader* d = GetDspHeader(block, dsp);
+               return d != NULL ? d->GetBusPatch(i) : NULL;
+       }
+
+       /// Returns the current bus patch being decoded or NULL if none found.
+       const AliBusPatch* CurrentBusPatch() const
+       {
+               return (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ?
+                       fkCurrentBusPatch : NULL;
+       }
+
+       /// Returns the current DSP being decoded or NULL if none found.
+       const AliDspHeader* CurrentDspHeader() const
+       {
+               const AliBusPatch* busPatch = CurrentBusPatch();
+               return (busPatch != NULL) ? busPatch->GetDspHeader() : NULL;
+       }
+
+       /// Returns the current block header being decoded or NULL if none found.
+       const AliBlockHeader* CurrentBlockHeader() const
+       {
+               const AliDspHeader* dsp = CurrentDspHeader();
+               return (dsp != NULL) ? dsp->GetBlockHeader() : NULL;
+       }
+       
+       /// Enable error logging to the raw reader. \note Kept for backward compatibility.
+       virtual void EnabbleErrorLogger() { EnableRawReaderErrorLogger(); }
+       
+       /// Enable error info logging to AliMUONLogger.
+       void EnableMUONErrorLogger() { fEnableMUONErrorLogger = kTRUE; }
+       
+       /// Disable logging to AliMUONLogger.
+       void DisableMUONErrorLogger() { fEnableMUONErrorLogger = kFALSE; }
+       
+       /// Enable error info logging to raw reader.
+       void EnableRawReaderErrorLogger() { fEnableRawReaderErrorLogger = kTRUE; }
+       
+       /// Disable logging to the raw reader.
+       void DisableRawReaderErrorLogger() { fEnableRawReaderErrorLogger = kFALSE; }
+       
+       /// Check if the AliMUONLogger is enabled for error logging.
+       Bool_t IsMUONErrorLoggerEnabled() const { return fEnableMUONErrorLogger; }
+       
+       /// Check if the AliMUONLogger is enabled for error logging.
+       Bool_t IsRawReaderErrorLoggerEnabled() const { return fEnableRawReaderErrorLogger; }
+       
+       /// Returns the logger object. (constant version)
+       const AliMUONLogger* GetMUONErrorLogger() const { return fLogger; }
+       
+       /// Returns the logger object.
+       AliMUONLogger* GetMUONErrorLogger() { return fLogger; }
+       
+       /// Sets the logger object to use. Ownership of the logger object remains with the caller.
+       void SetMUONErrorLogger(AliMUONLogger* logger) { fLogger = logger; }
+       
+       /// Returns the level of detail used in the error messages.
+       EDetailLevel GetLoggingDetailLevel() const { return fDetailLevel; }
+       
+       /// Sets the level of detail used in the error messages.
+       void SetLoggingDetailLevel(EDetailLevel level) { fDetailLevel = level; }
+       
+       /// Number of glitch errors since First() was called
+       UInt_t NumberOfGlitchErrors() const { return fTotalNumberOfGlitchErrors; }
+       
+       /// Number of padding errors since First() was called
+       UInt_t NumberOfPaddingErrors() const { return fTotalNumberOfPaddingErrors; }
+       
+       /// Number of parity errors since First() was called
+       UInt_t NumberOfParityErrors() const { return fTotalNumberOfParityErrors; }
+       
+       /// Number of token lost errors since First() was called
+       UInt_t NumberOfTokenLostErrors() const { return fTotalNumberOfTokenLostErrors; }
+       
+       /// Whether we got glitch errors or not
+       Bool_t HasGlitchError() const { return NumberOfGlitchErrors() > 0; }
+       
+       /// Whether we got padding errors or not
+       Bool_t HasPaddingError() const { return NumberOfPaddingErrors() > 0; }
+       
+       /// Whether we got parity errors or not
+       Bool_t HasParityError() const { return NumberOfParityErrors() > 0; }
+       
+       /// Whether we got token lost errors or not
+       Bool_t HasTokenLostError() const { return NumberOfTokenLostErrors() > 0; }
 
 private:
 
@@ -80,11 +594,15 @@ private:
         /// Not implemented
        AliMUONRawStreamTrackerHP& operator = (const AliMUONRawStreamTrackerHP& stream);
        
+       /// Return max number of tracker DDLs
+       Int_t GetMaxDDL() const { return fgkMaxDDL; }
+       
+       /// swap method for Power PC
+       virtual void Swap(UInt_t* buffer, Int_t size) const;
+       
        /// This is the custom event handler (callback interface) class which
        /// unpacks raw data words and fills an internal buffer with decoded digits
        /// as they are decoded by the high performance decoder.
-       /// Any errors are logged to the parent AliMUONVRawStreamTracker, so one
-       /// must set this pointer appropriately before decoding and DDL payload.
        class AliDecoderEventHandler : public AliMUONTrackerDDLDecoderEventHandler
        {
        public:
@@ -94,25 +612,68 @@ private:
                /// Default destructor.
                virtual ~AliDecoderEventHandler();
                
+               /// Sets the internal arrays based on the maximum number of structures allowed.
+               void SetMaxStructs(UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches);
+               
                /// Sets the raw stream object which should be the parent of this class.
-               void SetRawStream(AliMUONVRawStreamTracker* rawStream) { fRawStream = rawStream; }
+               void SetRawStream(AliMUONRawStreamTrackerHP* rawStream) { fRawStream = rawStream; }
                
-               /// Return the number of channels in the buffer returned by Channels().
-               UInt_t ChannelCount() const { return fChannelCount; }
+               /// Return the number of blocks found in the payload.
+               UInt_t BlockCount() const { return fBlockCount; };
                
-               /// Return the buffer of decoded channel data.
-               const AliChannelInfo* Channels() const { return fChannelBuffer; }
+               /// Return the i'th block structure.
+               const AliBlockHeader* BlockHeader(UInt_t i) const
+               {
+                       return i < fBlockCount ? &fBlocks[i] : NULL;
+               }
+
+               /// Return the first bus patch decoded.
+               const AliBusPatch* FirstBusPatch() const { return fBusPatches; }
+
+               /// Returns the marker to the end of bus patches. i.e. one position past the last bus patch.
+               const AliBusPatch* EndOfBusPatch() const { return fEndOfBusPatches; }
+
+               /// Returns the number of parity errors found in the DDL.
+               UInt_t ParityErrorCount() const { return fParityErrors; }
+               /// Returns the number of glitch errors found in the DDL.
+               UInt_t GlitchErrorCount() const { return fGlitchErrors; }
+               /// Returns the number of padding errors found in the DDL.
+               UInt_t PaddingErrorCount() const { return fPaddingErrors; }
+               /// Returns the number of token lost errors found in the DDL.
+               UInt_t TokenLostCount() const { return fTokenLostErrors; }
                
                // The following methods are inherited from AliMUONTrackerDDLDecoderEventHandler:
                
                /// New buffer handler.
                void OnNewBuffer(const void* buffer, UInt_t bufferSize);
+
+               /// End of buffer handler marks the end of bus patches.
+               void OnEndOfBuffer(const void* /*buffer*/, UInt_t /*bufferSize*/)
+               {
+                       fEndOfBusPatches = fCurrentBusPatch+1;
+               }
+               
+               /// New block handler is called by the decoder whenever a new block
+               /// structure is found. We just mark the new block and increment the
+               /// internal counter.
+               void OnNewBlock(const AliMUONBlockHeaderStruct* header, const void* /*data*/);
+               
+               /// New DSP handler is called by the decoder whenever a new DSP
+               /// structure is found. We just mark the DSP and increment the
+               /// appropriate counters.
+               void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
                
                /// New bus patch handler.
+               /// This is called by the high performance decoder when a new bus patch
+               /// is found within the DDL payload.
                void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data);
                
                /// Raw data word handler.
-               void OnData(UInt_t data);
+               void OnData(UInt_t /*data*/, bool parityError)
+               {
+                       assert( fCurrentParityOkFlag < fParityOk + fMaxChannels );
+                       *(++fCurrentParityOkFlag) = Bool_t(not parityError);
+               }
                
                /// Error handler.
                void OnError(ErrorCode error, const void* location);
@@ -125,22 +686,120 @@ private:
                 /// Not implemented
                AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/);
 
-               Int_t fBusPatchId;     //!< The bus patch ID of the current bus patch being decoded.
-               UInt_t fChannelCount;  //!< Number of elements in fChannelBuffer.
-               UInt_t fMaxChannels;   //!< Maximum number of elements that can be stored in fChannelBuffer.
-               AliChannelInfo* fChannelBuffer;  //!< Buffer of decoded channel structures.
-               AliMUONVRawStreamTracker* fRawStream; //!< Pointer to the parent raw stream object.
+               AliMUONRawStreamTrackerHP* fRawStream; //!< Pointer to the parent raw stream object.
                const void* fBufferStart;   //!< Pointer to the start of the current DDL payload buffer.
+               UInt_t fBlockCount;  //!< Number of blocks filled in fBlocks.
+               AliBlockHeader* fBlocks;  //!< Array of blocks. [0..fMaxBlocks-1]
+               AliDspHeader* fDSPs;      //!< Array of DSPs. [0..fMaxDsps*fMaxBlocks-1]
+               AliBusPatch* fBusPatches; //!< Array of bus patches. [0..fMaxBusPatches*fMaxDsps*fMaxBlocks-1]
+               AliBusPatch* fEndOfBusPatches;  //!< Marks the last bus patch.
+               UInt_t fMaxChannels;   //!< Maximum number of elements that can be stored in fParityOk.
+               Bool_t* fParityOk;     //!< Array of flags for indicating if the parity is good for a raw data word.
+               AliBlockHeader* fCurrentBlock;  //!< Current block in fBlocks.
+               AliDspHeader* fCurrentDSP;      //!< Current DSP in fDSPs.
+               AliBusPatch* fCurrentBusPatch;  //!< Current bus patch in fBusPatches.
+               Bool_t* fCurrentParityOkFlag;  //!< Current parity flag to be set in fParityOk.
+               UInt_t fParityErrors;   //!< Number of parity errors found in DDL.
+               UInt_t fGlitchErrors;   //!< Number of glitch errors found in DDL.
+               UInt_t fPaddingErrors;  //!< Number of padding errors found in DDL.
+               UInt_t fTokenLostErrors;  //!< Number of token lost errors found in DDL.
+               UInt_t fMaxBlocks; //!< max number of blocks
+               UInt_t fMaxDsps; //!< max number of dsps per block
+               UInt_t fMaxBusPatches; //!< max number of buspatches per dsp
        };
-       
+
+       AliRawReader* fRawReader; //!< Pointer to the raw reader
+       AliMUONLogger* fLogger; //!< Logger object to store error messages.
+       EDetailLevel fDetailLevel;  //!< The logging detail level used in the error messages generated in OnError.
+       Bool_t fEnableMUONErrorLogger; //!< whether or not we log errors to AliMUONLogger
+       Bool_t fEnableRawReaderErrorLogger; //!< whether or not we log errors to the raw reader.
+       Bool_t fWarnings;       //!< Flag indicating if we should generate a warning for errors.
        AliMUONTrackerDDLDecoder<AliDecoderEventHandler> fDecoder;  //!< The decoder for the DDL payload.
        Int_t fDDL;         //!< The current DDL number being handled.
-       UInt_t fCurrentChannel;  //!< The current channel to return by Next().
        Int_t fBufferSize;  //!< This is the buffer size in bytes of fBuffer.
        UChar_t* fBuffer;   //!< This is the buffer in which we store the DDL payload read from AliRawReader.
+       const AliBusPatch* fkCurrentBusPatch;  //!< The current bus patch being handled by Next().
+       const UInt_t* fkCurrentData;  //!< The current data word to return by Next().
+       const UInt_t* fkEndOfData;  //!< The last data word in the current bus patch.
        Bool_t fHadError;   //!< Flag indicating if there was a decoding error or not.
+       Bool_t fDone;       //!< Flag indicating if the iteration is done or not.
+       mutable AliMUONDDLTracker* fDDLObject; //!< Temporary DDL object used by GetDDLTracker() for caching.
+       UInt_t fTotalNumberOfGlitchErrors; //!< number of glitch errors since First() was called
+       UInt_t fTotalNumberOfParityErrors; //!< number of parity errors since First() was called
+       UInt_t fTotalNumberOfPaddingErrors; //!< number of padding errors since First() was called
+       UInt_t fTotalNumberOfTokenLostErrors; //!< number of token lost errors since First() was called
+       
+       static const Int_t fgkMaxDDL; //!< max number of tracker DDLs
 
        ClassDef(AliMUONRawStreamTrackerHP, 0) // High performance decoder for reading MUON raw digits from tracking chamber DDL data.
 };
 
+////////////////////////////////////////////////////////////////////////////////
+
+inline const AliMUONRawStreamTrackerHP::AliBusPatch* AliMUONRawStreamTrackerHP::Next()
+{
+       /// Returns the next batch of decoded channel data.
+       if (fkCurrentBusPatch == NULL) return NULL;
+       do {
+               if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
+                       return fkCurrentBusPatch++;
+       } while (NextDDL());
+       return NULL;
+}
+
+inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBlock(
+               const AliMUONBlockHeaderStruct* header, const void* /*data*/
+       )
+{
+       /// New block handler is called by the decoder whenever a new block
+       /// structure is found. We just mark the new block and increment the
+       /// internal counter.
+
+       assert( header != NULL );
+       assert( fBlockCount < fMaxBlocks );
+       // Link the block unless it is the first one.
+       if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1);
+       *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header);
+       fBlockCount++;
+}
+
+inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewDSP(
+               const AliMUONDSPHeaderStruct* header, const void* /*data*/
+       )
+{
+       /// New DSP handler is called by the decoder whenever a new DSP
+       /// structure is found. We just mark the DSP and increment the
+       /// appropriate counters.
+       
+       assert( header != NULL );
+       assert( fCurrentBlock->GetDspCount() < fMaxDsps );
+       // Link the DSP unless it is the first one.
+       if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1);
+       *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header);
+       fCurrentBlock->IncDspCount();
+}
+
+inline void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBusPatch(
+               const AliMUONBusPatchHeaderStruct* header, const void* data
+       )
+{
+       /// New bus patch handler.
+       /// This is called by the high performance decoder when a new bus patch
+       /// is found within the DDL payload.
+
+       assert( header != NULL );
+       assert( data != NULL );
+       assert( fCurrentDSP->GetBusPatchCount() < fMaxBusPatches );
+       // Link the bus patch unless it is the first one. 
+       if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1);
+       *(++fCurrentBusPatch) = AliBusPatch(
+                       fCurrentDSP,
+                       header,
+                       reinterpret_cast<const UInt_t*>(data),
+                       fCurrentParityOkFlag+1
+               );
+       fCurrentDSP->IncBusPatchCount();
+}
+
 #endif  // ALIMUONRAWSTREAMTRACKERHP_H
+