/// \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.
- const AliBusPatch* Next()
- {
- do {
- if (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) return fCurrentBusPatch++;
- } while (NextDDL());
- return NULL;
- }
+ const AliBusPatch* Next();
/// Return maximum number of blocks per DDL allowed.
virtual Int_t GetMaxBlock() const { return (Int_t) fDecoder.MaxBlocks(); }
/// Set maximum number of Buspatch per Dsp allowed.
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
+ /// 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
+ /// 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
+ /// 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() { fDecoder.GetHandler().Warnings(kFALSE); }
+ void DisableWarnings() { fWarnings = kFALSE; }
/// Set warnings flag to enable warnings on data errors.
- void EnableWarnings() { fDecoder.GetHandler().Warnings(kTRUE); }
+ 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()); }
/// 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
{
Int_t GetEventId2() const {assert(fHeader != NULL); return fHeader->fEventId2;}
/// Return the header's raw data.
- const AliMUONBlockHeaderStruct* GetHeader() {return fHeader;}
+ const AliMUONBlockHeaderStruct* GetHeader() const {return fHeader;}
/// Return the next block header.
const AliBlockHeader* Next() const { return fNext; }
Int_t GetErrorWord() const {assert(fHeader != NULL); return fHeader->fErrorWord;}
/// Return raw data of header
- const AliMUONDSPHeaderStruct* GetHeader() {return fHeader;}
+ const AliMUONDSPHeaderStruct* GetHeader() const { return fHeader; }
/// Return the parent block header.
const AliBlockHeader* GetBlockHeader() const { return fBlock; }
Int_t GetBusPatchId() const {assert(fHeader != NULL); return fHeader->fBusPatchId;}
/// Return raw data of header
- const AliMUONBusPatchHeaderStruct* GetHeader() {return fHeader;}
+ 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.
/// Returns the parity bit of the n'th raw data word.
Char_t GetParity(UInt_t n) const
{
- assert( fHeader != NULL and n < fHeader->fLength );
+ 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 and n < fHeader->fLength );
+ 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 and n < fHeader->fLength );
+ 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 and n < fHeader->fLength );
+ 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 and n < fHeader->fLength );
+ assert( fHeader != NULL && n < fHeader->fLength );
return fData[n];
}
/// and kFALSE otherwise.
Bool_t IsParityOk(UInt_t n) const
{
- assert( fHeader != NULL and n < fHeader->fLength );
+ assert( fHeader != NULL && n < fHeader->fLength );
return fParityOk[n];
}
/// 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 and n < fHeader->fLength );
+ assert( fHeader != NULL && n < fHeader->fLength );
AliMUONTrackerDDLDecoderEventHandler::UnpackADC(fData[n], manuId, channelId, adc);
return fParityOk[n];
}
/// Returns the current bus patch being decoded or NULL if none found.
const AliBusPatch* CurrentBusPatch() const
{
- return (fCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ?
- fCurrentBusPatch : NULL;
+ return (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch()) ?
+ fkCurrentBusPatch : NULL;
}
/// Returns the current DSP being decoded or NULL if none found.
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:
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 blocks found in the payload.
UInt_t BlockCount() const { return fBlockCount; };
UInt_t GlitchErrorCount() const { return fGlitchErrors; }
/// Returns the number of padding errors found in the DDL.
UInt_t PaddingErrorCount() const { return fPaddingErrors; }
-
- /// Returns the warnings flag.
- Bool_t Warnings() const { return fWarnings; }
- /// Sets the warnings flag.
- void Warnings(Bool_t value) { fWarnings = value; }
+ /// 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 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*/)
- {
- assert( fBlockCount < (UInt_t)fRawStream->GetMaxBlock() and header != NULL );
- if (fBlockCount > 0) fCurrentBlock->SetNext(fCurrentBlock+1); // Link the block unless it is the first one.
- *(++fCurrentBlock) = AliBlockHeader(fCurrentDSP+1, header);
- fBlockCount++;
- }
+ 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*/)
- {
- assert( fCurrentBlock->GetDspCount() < (UInt_t)fRawStream->GetMaxDsp() and header != NULL );
- if (fCurrentBlock->GetDspCount() > 0) fCurrentDSP->SetNext(fCurrentDSP+1); // Link the DSP unless it is the first one.
- *(++fCurrentDSP) = AliDspHeader(fCurrentBlock, fCurrentBusPatch+1, header);
- fCurrentBlock->IncDspCount();
- }
+ 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)
- {
- assert( fCurrentDSP->GetBusPatchCount() < (UInt_t)fRawStream->GetMaxBus() and header != NULL and data != NULL );
- if (fCurrentDSP->GetBusPatchCount() > 0) fCurrentBusPatch->SetNext(fCurrentBusPatch+1); // Link the bus patch unless it is the first one.
- *(++fCurrentBusPatch) = AliBusPatch(fCurrentDSP, header, reinterpret_cast<const UInt_t*>(data), fCurrentParityOkFlag+1);
- fCurrentDSP->IncBusPatchCount();
- }
+ void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* data);
/// Raw data word handler.
void OnData(UInt_t /*data*/, bool parityError)
/// Not implemented
AliDecoderEventHandler& operator = (const AliDecoderEventHandler& /*obj*/);
- 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]
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.
- Bool_t fWarnings; //!< Flag indicating if we should generate a warning for errors.
+ 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.
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* fCurrentBusPatch; //!< The current data word to return by Next().
- const UInt_t* fCurrentData; //!< The current data word to return by Next().
- const UInt_t* fEndOfData; //!< The last data word in the current bus patch.
+ 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