]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONTrackerDDLDecoder.h
Renamed output file to Vertex.Performance.root
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerDDLDecoder.h
index 694a0157d47d33d097e52aaca1c82594917c5b29..a63084c658c01bb5b54314b30daeede867501832 100644 (file)
@@ -25,7 +25,7 @@
 /// \brief  Implementation of a high performance DDL decoder for the muon tracking stations.
 ///
 /// This file implementes the AliMUONTrackerDDLDecoder class, which contains
-/// the core logic for decoding the payload in DDL streams comming from the muon
+/// the core logic for decoding the payload in DDL streams coming from the muon
 /// spectrometer's tracking chambers in a very efficient manner.
 ///
 /// This implementation is derived from work done by Christian Finck for the
 ///
 /// This class implements a high performance decoder for decoding DDL payload
 /// data coming from the muon spectrometers tracking chambers.
-/// It has been implemented using the event driven paradigm, which allows us
-/// to minimise the number of method calls made in the inner loops of the algorithm
-/// and minimise the memory footprint.
+/// It has been implemented using the event driven paradigm with templates,
+/// which allows us to minimise the number of method calls made in the inner
+/// loops of the algorithm and minimise the memory footprint. At least for
+/// optimised production compilations.
 /// The decoder class only contains the basic decoding and error checking logic.
 /// It calls methods such as OnNewBlock, OnNewBusPatch, OnData etc in
 /// the event handler during the decoding to return the decoded data.
 /// The event handler class is nothing more than a callback interface to deliver
 /// the next chunks of decoded data.
-/// To actually do something with the data one needs to implement a custom
+/// To actually do something with the data, one needs to implement a custom
 /// event handler (callback) class by inheriting from AliMUONTrackerDDLDecoderEventHandler
 /// and overriding the callback methods like so:
 /// \code
 ///  class MyCustomHandler : public AliMUONTrackerDDLDecoderEventHandler
 ///  {
 ///  public:
-///     void OnData(UInt_t data)
+///     void OnData(UInt_t data, bool parityError)
 ///     {
-///       // I can do something with 'data' here.
+///       // I can do something with 'data' here and check if there was
+///       // a parity error with 'parityError'.
 ///     }
 ///  };
 /// \endcode
 ///
-/// Once the custom handler is written then the decoder is in instantiated as
-/// shown below, to use your new custom handler. And to start decoding one needs
+/// Once the custom handler is written then the decoder is instantiated as
+/// shown below, to use your new custom handler. Also to start decoding one needs
 /// to call the Decode() method of the decoder.
 /// \code
 ///  AliMUONTrackerDDLDecoder<MyCustomHandler> myDecoder;
@@ -76,9 +78,9 @@
 /// \endcode
 ///
 /// Note that this class was written as a template on purpose. To maximise the
-/// compilers chance to make optimisations and inlining code must use a template.
-/// Depending on exactly what you do inside your handler the decoder will be
-/// significantly slower if run time polymorphism was used i.e. making the class
+/// compilers chance to make optimisations and inline the code we must use a template.
+/// Depending on exactly what you do inside your handler, the decoder could be
+/// significantly slower if run time polymorphism was used, i.e. making the class
 /// AliMUONTrackerDDLDecoderEventHandler abstract and using virtual methods.
 ///
 /// There has been a change to the data format that the real detector generates.
@@ -179,6 +181,21 @@ public:
        /// This method decodes the DDL payload contained in the buffer.
        bool Decode(const void* buffer, UInt_t bufferSize);
        
+       /// Returns the block marker key.
+       static UInt_t BlockDataKeyWord() { return fgkBlockDataKey; }
+       
+       /// Returns the DSP marker key.
+       static UInt_t DspDataKeyWord() { return fgkDSPDataKey; }
+       
+       /// Returns the bus patch marker key.
+       static UInt_t BusPatchDataKeyWord() { return fgkBusPatchDataKey; }
+       
+       /// Returns the expected padding word value.
+       static UInt_t PaddingWord() { return fgkPaddingWord; }
+       
+       /// Returns the expected end of DDL marker.
+       static UInt_t EndOfDDLWord() { return fgkEndOfDDL; }
+       
 private:
 
        bool fExitOnError; ///< Indicates if we should exit on the very first error.
@@ -313,9 +330,9 @@ void AliMUONTrackerDDLDecoder<EventHandler>::DecodeBuffer(
        /// \param start  This is the pointer to the start of the buffer.
        /// \param end  This is the pointer to the first byte just past the
        ///             end of the buffer.
-       /// \return If the blocks in the buffer were decoded without errors
-       ///      or we could recover from the errors, then true is returned.
-       ///      False is returned otherwise.
+       /// fHadError is set to true if there were any errors decoding the buffer
+       /// and the OnError method of the callback event handler is called for
+       /// each error.
        
        const UChar_t* current = start;
        const UInt_t* bufferStart = reinterpret_cast<const UInt_t*>(start);
@@ -324,7 +341,7 @@ void AliMUONTrackerDDLDecoder<EventHandler>::DecodeBuffer(
        
        // The DDL payload normally has a 2 word trailer which contains the end of
        // DDL markers 0xD000000D. But this is not the case for older simulated
-       // data so if we are autodetecting the trailer then we need to carefully
+       // data so if we are auto-detecting the trailer then we need to carefully
        // check if these words are there or not.
        const UChar_t* endOfBlocks = end;
        const UInt_t* trailerWords = reinterpret_cast<const UInt_t*>(end) - 2;
@@ -364,7 +381,7 @@ void AliMUONTrackerDDLDecoder<EventHandler>::DecodeBuffer(
                        if (fExitOnError) return;
                        
                        // Mark that there was a problem with the trailer so that
-                       // for subsequest errors we try to deal with this better.
+                       // for subsequent errors we try to deal with this better.
                        problemWithTrailer = true;
                        
                        // We can also try figure out how many trailer words there
@@ -412,7 +429,7 @@ void AliMUONTrackerDDLDecoder<EventHandler>::DecodeBuffer(
                                if (fAutoDetectTrailer)
                                {
                                        // If we got here then there is at least one correct trailer
-                                       // word, but since we did not detect a currect trailer then
+                                       // word, but since we did not detect a correct trailer then
                                        // there must be only one. Announce the error and exit.
                                        fHandler.OnError(EventHandler::kTooFewDDLTrailerWords, trailerWords);
                                        fHadError = true;
@@ -622,15 +639,29 @@ bool AliMUONTrackerDDLDecoder<EventHandler>::DecodeBlockData(
                fHandler.OnNewDSP(dspHeader, dataStart);
                
                // Check the error word in the header.
-               if (dspHeader->fErrorWord == (0x000000B1 | blockHeader->fDSPId)
-                   or dspHeader->fErrorWord == (0x00000091 | blockHeader->fDSPId)
-                  )
+               if (dspHeader->fErrorWord != 0x0)
                {
-                       // An event with a glitch in the readout has been detected.
-                       // It means that somewhere a 1 byte word has been randomly
-                       // inserted and all the readout sequence is shifted until
-                       // the next event.
-                       fHandler.OnError(EventHandler::kGlitchFound, &dspHeader->fErrorWord);
+                       if (dspHeader->fErrorWord == (0x000000B1 | blockHeader->fDSPId)
+                           or dspHeader->fErrorWord == (0x00000091 | blockHeader->fDSPId)
+                          )
+                       {
+                               // An event with a glitch in the readout has been detected.
+                               // It means that somewhere a 1 byte word has been randomly
+                               // inserted and all the readout sequence is shifted until
+                               // the next event.
+                               fHandler.OnError(EventHandler::kGlitchFound, &dspHeader->fErrorWord);
+                       }
+                       else if ((dspHeader->fErrorWord & 0x0000FFF0) == 0x220)
+                       {
+                               // Detected a TOKEN_LOST error which can affect the dead time in the DAQ.
+                               fHandler.OnError(EventHandler::kTokenLost, &dspHeader->fErrorWord);
+                       }
+                       else
+                       {
+                               // The DSP error code is non-zero but has an unknown code.
+                               fHandler.OnError(EventHandler::kUnknownDspError, &dspHeader->fErrorWord);
+                       }
+                       
                        fHadError = true;
                        if (fExitOnError)
                        {
@@ -953,7 +984,7 @@ AliMUONTrackerDDLDecoder<EventHandler>::TryRecoverStruct(
        const UInt_t* headerKey = reinterpret_cast<const UInt_t*>(structStart);
        bool headerKeyOk = (expectedKey == *headerKey);
        
-       bool lengthsMatch = (totalLength == length + headerSize);
+       bool lengthsMatch = (totalLength*4 == length*4 + headerSize);
        
        bool lengthIsCorrect = false;
        bool totalLengthIsCorrect = false;