/// \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();
/// 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();
/// 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(); }
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:
/// 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:
/// 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);
/// 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
+