X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONRawStreamTrackerHP.cxx;h=aea24c770cd11432db259e2b619cab19ae7be908;hb=9b7804183c950b8cbd9e0c179a1bf691362bf63c;hp=c6118172b37828dea9b02006f7c9232f1990dbec;hpb=bc057b0a92f809a918db8f17ff2ff40cb222ca48;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONRawStreamTrackerHP.cxx b/MUON/AliMUONRawStreamTrackerHP.cxx index c6118172b37..aea24c770cd 100644 --- a/MUON/AliMUONRawStreamTrackerHP.cxx +++ b/MUON/AliMUONRawStreamTrackerHP.cxx @@ -49,8 +49,10 @@ #include "AliMUONBlockHeader.h" #include "AliMUONBusStruct.h" #include "AliMUONDDLTracker.h" +#include "AliMUONLogger.h" #include "AliRawReader.h" #include "AliLog.h" +#include "AliDAQ.h" #include #include using std::cout; @@ -62,9 +64,16 @@ using std::dec; ClassImp(AliMUONRawStreamTrackerHP) /// \endcond +const Int_t AliMUONRawStreamTrackerHP::fgkMaxDDL = 20; AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() : - AliMUONVRawStreamTracker(), + TObject(), + fRawReader(NULL), + fLogger(NULL), + fDetailLevel(kMediumErrorDetail), + fEnableMUONErrorLogger(kFALSE), + fEnableRawReaderErrorLogger(kFALSE), + fWarnings(kTRUE), fDecoder(), fDDL(0), fBufferSize(8192), @@ -74,7 +83,11 @@ AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() : fkEndOfData(NULL), fHadError(kFALSE), fDone(kFALSE), - fDDLObject(NULL) + fDDLObject(NULL), + fTotalNumberOfGlitchErrors(0), + fTotalNumberOfParityErrors(0), + fTotalNumberOfPaddingErrors(0), + fTotalNumberOfTokenLostErrors(0) { /// /// Default constructor. @@ -90,13 +103,19 @@ AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() : fDecoder.MaxDSPs(), fDecoder.MaxBusPatches() ); - + fDecoder.GetHandler().SetRawStream(this); } AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP(AliRawReader* rawReader) : - AliMUONVRawStreamTracker(rawReader), + TObject(), + fRawReader(rawReader), + fLogger(NULL), + fDetailLevel(kMediumErrorDetail), + fEnableMUONErrorLogger(kFALSE), + fEnableRawReaderErrorLogger(kFALSE), + fWarnings(kTRUE), fDecoder(), fDDL(0), fBufferSize(8192), @@ -106,7 +125,11 @@ AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP(AliRawReader* rawReader) : fkEndOfData(NULL), fHadError(kFALSE), fDone(kFALSE), - fDDLObject(NULL) + fDDLObject(NULL), + fTotalNumberOfGlitchErrors(0), + fTotalNumberOfParityErrors(0), + fTotalNumberOfPaddingErrors(0), + fTotalNumberOfTokenLostErrors(0) { /// /// Constructor with AliRawReader as argument. @@ -154,6 +177,10 @@ void AliMUONRawStreamTrackerHP::First() fDDL = 0; fDone = kFALSE; NextDDL(); + fTotalNumberOfGlitchErrors = 0; + fTotalNumberOfPaddingErrors = 0; + fTotalNumberOfParityErrors = 0; + fTotalNumberOfTokenLostErrors = 0; } @@ -234,6 +261,10 @@ Bool_t AliMUONRawStreamTrackerHP::NextDDL() Swap(reinterpret_cast(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc. #endif + fDDL++; // Remember to increment index to next DDL before the calls to + // fDecoder.Decode since the callback methods of the decoder will + // use AliMUONRawStreamTrackerHP::GetDDL() + bool result = false; try { @@ -241,6 +272,10 @@ Bool_t AliMUONRawStreamTrackerHP::NextDDL() // handler we need to trap any memory allocation exception to be robust. result = fDecoder.Decode(fBuffer, dataSize); fHadError = (result == true ? kFALSE : kTRUE); + fTotalNumberOfGlitchErrors += fDecoder.GetHandler().GlitchErrorCount(); + fTotalNumberOfParityErrors += fDecoder.GetHandler().ParityErrorCount(); + fTotalNumberOfPaddingErrors += fDecoder.GetHandler().PaddingErrorCount(); + fTotalNumberOfTokenLostErrors += fDecoder.GetHandler().TokenLostCount(); } catch (const std::bad_alloc&) { @@ -263,7 +298,6 @@ Bool_t AliMUONRawStreamTrackerHP::NextDDL() fkCurrentData = fkEndOfData = NULL; } - fDDL++; // Remember to increment index to next DDL. return kTRUE; } @@ -277,25 +311,24 @@ Bool_t AliMUONRawStreamTrackerHP::IsDone() const } -Bool_t AliMUONRawStreamTrackerHP::Next( - Int_t& busPatchId, UShort_t& manuId, UChar_t& manuChannel, - UShort_t& adc, Bool_t skipParityErrors - ) +Bool_t AliMUONRawStreamTrackerHP::Next(Int_t& busPatchId, + UShort_t& manuId, + UChar_t& manuChannel, + UShort_t& adc, + Bool_t skipParityErrors) { /// Advance one step in the iteration. Returns false if finished. /// [out] \param busPatchId This is filled with the bus patch ID of the digit. /// [out] \param manuId This is filled with the MANU ID of the digit. /// [out] \param manuChannel This is filled with the MANU channel ID of the digit. /// [out] \param adc This is filled with the ADC signal value of the digit. - /// [in] \param skipParityErrors If this is kTRUE, we'll skip the buspatches that - /// have some parity errors + /// [in] \param skipParityErrors If this is kTRUE, we'll skip the buspatches that + /// have some parity errors /// \return kTRUE if we read another digit and kFALSE if we have read all the /// digits already, i.e. at the end of the iteration. if (fkCurrentData == NULL) return kFALSE; - fDecoder.SendDataOnParityError(skipParityErrors); - retry: // Check if we still have data to be returned for the current bus patch. if (fkCurrentData != fkEndOfData) @@ -318,6 +351,15 @@ retry: { fkCurrentData = fkCurrentBusPatch->GetData(); fkEndOfData = fkCurrentData + fkCurrentBusPatch->GetDataCount(); + if ( skipParityErrors ) + { + Bool_t ok(kTRUE); + for ( Int_t i = 0; i < fkCurrentBusPatch->GetLength() && ok; ++ i ) + { + ok = fkCurrentBusPatch->IsParityOk(i); + } + if (!ok) fkCurrentData = fkEndOfData; + } goto retry; } } @@ -511,7 +553,10 @@ AliMUONRawStreamTrackerHP::AliDecoderEventHandler::AliDecoderEventHandler() : fParityErrors(0), fGlitchErrors(0), fPaddingErrors(0), - fWarnings(kTRUE) + fTokenLostErrors(0), + fMaxBlocks(), + fMaxDsps(), + fMaxBusPatches() { /// Default constructor initialises the internal parity flags buffer to /// store 8192 elements. This array will grow dynamically if needed. @@ -560,6 +605,10 @@ void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::SetMaxStructs( fDSPs = new AliDspHeader[maxBlocks*maxDsps]; fBusPatches = new AliBusPatch[maxBlocks*maxDsps*maxBusPatches]; fEndOfBusPatches = fBusPatches; + + fMaxBlocks = maxBlocks; + fMaxDsps = maxDsps; + fMaxBusPatches = maxBusPatches; } @@ -572,8 +621,6 @@ void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer( /// \param buffer The pointer to the buffer storing the DDL payload. /// \param bufferSize The size of the buffer in bytes. - assert( fRawStream != NULL ); - // remember the start of the buffer to be used in OnError. fBufferStart = buffer; @@ -581,6 +628,7 @@ void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer( fParityErrors = 0; fGlitchErrors = 0; fPaddingErrors = 0; + fTokenLostErrors = 0; // Check if we will have enough space in the fParityOk array. // If we do not then we need to resize the array. @@ -611,6 +659,32 @@ void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer( } +void AliMUONRawStreamTrackerHP::Swap(UInt_t* buffer, Int_t size) const +{ + // swap from little to big endian + + typedef struct { + UInt_t b1:8; ///< first byte word + UInt_t b2:8; ///< second byte word + UInt_t b3:8; ///< third byte word + UInt_t b4:8; ///< fourth byte word + } RawWord; + + RawWord* word, temp; + word = (RawWord*) buffer; + + for (Int_t i = 0; i < size; i++) + { + temp = *(((RawWord*)buffer)+i); + word->b1 = temp.b4; + word->b2 = temp.b3; + word->b3 = temp.b2; + word->b4 = temp.b1; + word++; + } +} + + void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnError( ErrorCode error, const void* location ) @@ -618,70 +692,208 @@ void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnError( /// This is called by the high performance decoder when a error occurs /// when trying to decode the DDL payload. This indicates corruption in /// the data. This method converts the error code to a descriptive message - /// and logs this with the raw reader. + /// and logs this with the logger object. /// \param error The error code indicating the problem. /// \param location A pointer to the location within the DDL payload buffer /// being decoded where the problem with the data was found. - - assert( fRawStream != NULL ); - assert( fRawStream->GetReader() != NULL ); - Char_t* message = NULL; + assert(fRawStream != NULL); + + const char* message = NULL; UInt_t word = 0; - + bool logAsMajorError = true; + + // Build the detailed part of the error message if high detail selected. + const char* detail = ""; + if (fRawStream->GetLoggingDetailLevel() == kHighErrorDetail) + { + bool blockPtrOk = fBlockCount > 0; + bool dspPtrOk = blockPtrOk ? fCurrentBlock->GetDspCount() > 0 : false; + bool buspatchPtrOk = dspPtrOk ? fCurrentDSP->GetBusPatchCount() > 0 : false; + // We subtract 1 from the current numbers of blocks, DSPs + // and bus patches to get the iBlock, iDsp and iBus indices. + detail = Form( + "At byte %lu in DDL %d, event %d, iBlock %d, iDsp %d [DSP ID: %d (0x%X)]," + " iBus %d [bus patch ID: %d (0x%X)].", + (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader), + AliDAQ::DdlID("MUONTRK", fRawStream->GetDDL()), + fRawStream->GetReader()->GetEventIndex(), + int(fBlockCount)-1, + blockPtrOk ? int(fCurrentBlock->GetDspCount())-1 : -1, + blockPtrOk ? fCurrentBlock->GetDspId() : -1, + blockPtrOk ? fCurrentBlock->GetDspId() : -1, + dspPtrOk ? int(fCurrentDSP->GetBusPatchCount())-1 : -1, + buspatchPtrOk ? fCurrentBusPatch->GetBusPatchId() : -1, + buspatchPtrOk ? fCurrentBusPatch->GetBusPatchId() : -1 + ); + } + + // Build the log message. switch (error) { case kGlitchFound: fGlitchErrors++; - message = Form( - "Glitch error detected in DSP %d, skipping event ", - fCurrentBlock->GetDspId() - ); - fRawStream->GetReader()->AddMajorErrorLog(error, message); + switch (fRawStream->GetLoggingDetailLevel()) + { + case kLowErrorDetail: + message = "Glitch error detected."; + break; + case kMediumErrorDetail: + message = Form( + "Glitch error detected in DSP %d (0x%X), skipping event.", + fCurrentBlock->GetDspId(), fCurrentBlock->GetDspId() + ); + break; + case kHighErrorDetail: + default: + message = Form("%s %s", ErrorCodeToMessage(error), detail); + break; + } + logAsMajorError = true; break; case kBadPaddingWord: fPaddingErrors++; - // We subtract 1 from the current numbers of blocks, DSPs - // and bus patches to get the indices. - message = Form( - "Padding word error for iBlock %d, iDsp %d, iBus %d\n", - fBlockCount-1, - fCurrentBlock->GetDspCount()-1, - fCurrentDSP->GetBusPatchCount()-1 - ); - fRawStream->GetReader()->AddMinorErrorLog(error, message); + switch (fRawStream->GetLoggingDetailLevel()) + { + case kLowErrorDetail: + message = "Padding word error detected."; + break; + case kMediumErrorDetail: + // We subtract 1 from the current numbers of blocks, DSPs + // and bus patches to get the indices. + message = Form( + "Padding word error for iBlock %d, iDsp %d, iBus %d.", + fBlockCount-1, + fCurrentBlock->GetDspCount()-1, + fCurrentDSP->GetBusPatchCount()-1 + ); + break; + case kHighErrorDetail: + default: + message = Form("%s %s", ErrorCodeToMessage(error), detail); + break; + } + logAsMajorError = false; break; case kParityError: fParityErrors++; - // location points to the incorrect data word and - // fCurrentBusPatch->GetData() returns a pointer to the start of - // bus patches data, so the difference divided by 4 gives the 32 - // bit word number. - word = ((unsigned long)location - (unsigned long)fCurrentBusPatch->GetData()) + switch (fRawStream->GetLoggingDetailLevel()) + { + case kLowErrorDetail: + message = "Parity error detected."; + break; + case kMediumErrorDetail: + message = Form( + "Parity error in buspatch %d (0x%X).", + fCurrentBusPatch->GetBusPatchId(), + fCurrentBusPatch->GetBusPatchId() + ); + break; + case kHighErrorDetail: + default: + // location points to the incorrect data word and + // fCurrentBusPatch->GetData() returns a pointer to the start of + // bus patches data, so the difference divided by 4 gives the 32 + // bit word number. + word = ((unsigned long)location - (unsigned long)fCurrentBusPatch->GetData()) / sizeof(UInt_t); - message = Form( - "Parity error in word %d for manuId %d and channel %d in buspatch %d\n", - word, - fCurrentBusPatch->GetManuId(word), - fCurrentBusPatch->GetChannelId(word), - fCurrentBusPatch->GetBusPatchId() - ); - fRawStream->GetReader()->AddMinorErrorLog(error, message); + message = Form( + "Parity error in word %d for manuId %d and channel %d in buspatch %d. %s", + word, + fCurrentBusPatch->GetManuId(word), + fCurrentBusPatch->GetChannelId(word), + fCurrentBusPatch->GetBusPatchId(), + detail + ); + break; + } + logAsMajorError = false; + break; + + case kTokenLost: + fTokenLostErrors++; + switch (fRawStream->GetLoggingDetailLevel()) + { + case kLowErrorDetail: + message = "Lost token error detected."; + break; + case kMediumErrorDetail: + word = *reinterpret_cast(location); + message = Form( + "Lost token error detected with address 0x%X of DDL %d and code %d.", + ((word & 0xFFFF0000)), + fRawStream->GetDDL(), + (word & 0xF) + ); + break; + case kHighErrorDetail: + default: + word = *reinterpret_cast(location); + message = Form( + "Lost token error detected with address 0x%X and code %d. %s", + ((word & 0xFFFF0000)), + (word & 0xF), + detail + ); + break; + } + logAsMajorError = false; break; default: - message = Form( - "%s (At byte %d in DDL.)", - ErrorCodeToMessage(error), - (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader) - ); - fRawStream->GetReader()->AddMajorErrorLog(error, message); + switch (fRawStream->GetLoggingDetailLevel()) + { + case kLowErrorDetail: + message = ErrorCodeToMessage(error); + break; + case kMediumErrorDetail: + message = Form( + "%s (At byte %lu)", + ErrorCodeToMessage(error), + (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader) + ); + break; + case kHighErrorDetail: + default: + message = Form( + "%s Error code: %d (%s). %s", + ErrorCodeToMessage(error), + error, ErrorCodeToString(error), + detail + ); + break; + } + logAsMajorError = true; break; } - - if (fWarnings) + + // Now log the error message depending on the logging flags set. + if (fRawStream->IsRawReaderErrorLoggerEnabled()) + { + if (logAsMajorError) + fRawStream->GetReader()->AddMajorErrorLog(Int_t(error), message); + else + fRawStream->GetReader()->AddMinorErrorLog(Int_t(error), message); + } + if (fRawStream->IsMUONErrorLoggerEnabled()) + { + AliMUONLogger* logger = fRawStream->GetMUONErrorLogger(); + if (logger != NULL) + { + logger->Log(message); + } + else + { + AliErrorGeneral( + "AliMUONRawStreamTrackerHP::AliDecoderEventHandler", + "Enabled logging to AliMUONLogger, but the logger object" + " was not set with SetMUONErrorLogger()." + ); + } + } + if (fRawStream->IsWarningsEnabled()) { AliWarningGeneral( "AliMUONRawStreamTrackerHP::AliDecoderEventHandler",