LCOV - code coverage report
Current view: top level - MUON/MUONraw - AliMUONRawStreamTrackerHP.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 152 410 37.1 %
Date: 2016-06-14 17:26:59 Functions: 15 28 53.6 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * This file is property of and copyright by the ALICE HLT Project        *
       3             :  * All rights reserved.                                                   *
       4             :  *                                                                        *
       5             :  * Primary Authors:                                                       *
       6             :  *   Artur Szostak <artursz@iafrica.com>                                  *
       7             :  *                                                                        *
       8             :  * Permission to use, copy, modify and distribute this software and its   *
       9             :  * documentation strictly for non-commercial purposes is hereby granted   *
      10             :  * without fee, provided that the above copyright notice appears in all   *
      11             :  * copies and that both the copyright notice and this permission notice   *
      12             :  * appear in the supporting documentation. The authors make no claims     *
      13             :  * about the suitability of this software for any purpose. It is          *
      14             :  * provided "as is" without express or implied warranty.                  *
      15             :  **************************************************************************/
      16             : 
      17             : /* $Id$*/
      18             : 
      19             : ///
      20             : /// \file   AliMUONRawStreamTrackerHP.cxx
      21             : /// \author Artur Szostak <artursz@iafrica.com>
      22             : /// \date   29-11-2007
      23             : /// \brief  Implementation of the the high performance decoder AliMUONRawStreamTrackerHP.
      24             : ///
      25             : 
      26             : //-----------------------------------------------------------------------------
      27             : /// \ingroup raw
      28             : /// \class AliMUONRawStreamTrackerHP
      29             : /// \brief A high performance stream decoder for muon tracking DDL streams.
      30             : ///
      31             : /// This is the raw stream class which interfaces between the high performance
      32             : /// core decoder and the AliRawReader class.
      33             : /// To gain the most out of the decoder, the Next() method which returns batches
      34             : /// of decoded digit / channel information should be used. That is:
      35             : /// \code
      36             : ///   const AliBusPatch* Next();
      37             : /// \endcode
      38             : ///
      39             : /// This decoder tries to implement as similar an interface as possible to
      40             : /// AliMUONRawStreamTracker where possible. However certain constructs which
      41             : /// would slow us down too much are avoided.
      42             : ///
      43             : /// \author Artur Szostak <artursz@iafrica.com>
      44             : //-----------------------------------------------------------------------------
      45             : 
      46             : #include "AliMUONRawStreamTrackerHP.h"
      47             : #include "AliMUONTrackerDDLDecoder.h"
      48             : #include "AliMUONDspHeader.h"
      49             : #include "AliMUONBlockHeader.h"
      50             : #include "AliMUONBusStruct.h"
      51             : #include "AliMUONDDLTracker.h"
      52             : #include "AliMUONLogger.h"
      53             : #include "AliRawReader.h"
      54             : #include "AliRawDataHeaderV3.h"
      55             : #include "AliLog.h"
      56             : #include "AliDAQ.h"
      57             : #include <cassert>
      58             : #include <iostream>
      59             : using std::cout;
      60             : using std::endl;
      61             : using std::hex;
      62             : using std::dec;
      63             : 
      64             : /// \cond CLASSIMP
      65          18 : ClassImp(AliMUONRawStreamTrackerHP)
      66             : /// \endcond
      67             : 
      68             : const Int_t AliMUONRawStreamTrackerHP::fgkMaxDDL = 20;
      69             : 
      70             : AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP() :
      71           9 :         TObject(),
      72           9 :         fRawReader(NULL),
      73           9 :         fLogger(NULL),
      74           9 :         fDetailLevel(kMediumErrorDetail),
      75           9 :         fEnableMUONErrorLogger(kFALSE),
      76           9 :         fEnableRawReaderErrorLogger(kFALSE),
      77           9 :         fWarnings(kTRUE),
      78           9 :         fDecoder(),
      79           9 :         fDDL(0),
      80           9 :         fBufferSize(8192),
      81          18 :         fBuffer(new UChar_t[8192]),
      82           9 :         fkCurrentBusPatch(NULL),
      83           9 :         fkCurrentData(NULL),
      84           9 :         fkEndOfData(NULL),
      85           9 :         fHadError(kFALSE),
      86           9 :         fDone(kFALSE),
      87           9 :         fDDLObject(NULL),
      88           9 :         fTotalNumberOfGlitchErrors(0),
      89           9 :         fTotalNumberOfParityErrors(0),
      90           9 :         fTotalNumberOfPaddingErrors(0),
      91           9 :         fTotalNumberOfTokenLostErrors(0)
      92          45 : {
      93             :         ///
      94             :         /// Default constructor.
      95             :         ///
      96             :         
      97             :         // Must set this flag to get all information about parity errors though
      98             :         // the OnData method. OnError gets them either way.
      99           9 :         fDecoder.ExitOnError(false);
     100           9 :         fDecoder.SendDataOnParityError(true);
     101             : 
     102          18 :         fDecoder.GetHandler().SetMaxStructs(
     103           9 :                         fDecoder.MaxBlocks(),
     104           9 :                         fDecoder.MaxDSPs(),
     105           9 :                         fDecoder.MaxBusPatches()
     106             :                 );
     107             :         
     108           9 :         fDecoder.GetHandler().SetRawStream(this);
     109          18 : }
     110             : 
     111             : 
     112             : AliMUONRawStreamTrackerHP::AliMUONRawStreamTrackerHP(AliRawReader* rawReader) :
     113           0 :         TObject(),
     114           0 :         fRawReader(rawReader),
     115           0 :         fLogger(NULL),
     116           0 :         fDetailLevel(kMediumErrorDetail),
     117           0 :         fEnableMUONErrorLogger(kFALSE),
     118           0 :         fEnableRawReaderErrorLogger(kFALSE),
     119           0 :         fWarnings(kTRUE),
     120           0 :         fDecoder(),
     121           0 :         fDDL(0),
     122           0 :         fBufferSize(8192),
     123           0 :         fBuffer(new UChar_t[8192]),
     124           0 :         fkCurrentBusPatch(NULL),
     125           0 :         fkCurrentData(NULL),
     126           0 :         fkEndOfData(NULL),
     127           0 :         fHadError(kFALSE),
     128           0 :         fDone(kFALSE),
     129           0 :         fDDLObject(NULL),
     130           0 :         fTotalNumberOfGlitchErrors(0),
     131           0 :         fTotalNumberOfParityErrors(0),
     132           0 :         fTotalNumberOfPaddingErrors(0),
     133           0 :         fTotalNumberOfTokenLostErrors(0)
     134           0 : {
     135             :         ///
     136             :         /// Constructor with AliRawReader as argument.
     137             :         ///
     138             :         
     139             :         // Must set this flag to get all information about parity errors though
     140             :         // the OnData method. OnError gets them either way.
     141           0 :         fDecoder.ExitOnError(false);
     142           0 :         fDecoder.SendDataOnParityError(true);
     143             : 
     144           0 :         fDecoder.GetHandler().SetMaxStructs(
     145           0 :                         fDecoder.MaxBlocks(),
     146           0 :                         fDecoder.MaxDSPs(),
     147           0 :                         fDecoder.MaxBusPatches()
     148             :                 );
     149             :         
     150           0 :         fDecoder.GetHandler().SetRawStream(this);
     151           0 : }
     152             : 
     153             : 
     154             : AliMUONRawStreamTrackerHP::~AliMUONRawStreamTrackerHP()
     155          30 : {
     156             :         ///
     157             :         /// Default destructor.
     158             :         ///
     159             :         
     160           5 :         if (fBuffer != NULL)
     161             :         {
     162          10 :                 delete [] fBuffer;
     163             :         }
     164           5 :         if (fDDLObject != NULL)
     165             :         {
     166           0 :                 delete fDDLObject;
     167             :         }
     168          15 : }
     169             : 
     170             : 
     171             : void AliMUONRawStreamTrackerHP::First()
     172             : {
     173             :         /// Initialise or reset the iterator.
     174             :         /// The first DDL will be found and decoded.
     175             :         
     176           8 :         assert( GetReader() != NULL );
     177             :         
     178           4 :         fDDL = 0;
     179           4 :         fDone = kFALSE;
     180           4 :         NextDDL();
     181           4 :         fTotalNumberOfGlitchErrors = 0;
     182           4 :         fTotalNumberOfPaddingErrors = 0;
     183           4 :         fTotalNumberOfParityErrors = 0;
     184           4 :         fTotalNumberOfTokenLostErrors = 0;
     185           4 : }
     186             : 
     187             : 
     188             : Bool_t AliMUONRawStreamTrackerHP::NextDDL()
     189             : {
     190             :         /// Reading the next tracker DDL and decode the payload with the 
     191             :         /// high performance decoder.
     192             :         /// \return kTRUE if the next DDL was successfully read and kFALSE otherwise.
     193             : 
     194         168 :         assert( GetReader() != NULL );
     195             :         
     196             :         // The temporary object if generated in GetDDLTracker, is now stale,
     197             :         // so delete it.
     198          84 :         if (fDDLObject != NULL)
     199             :         {
     200           0 :                 delete fDDLObject;
     201           0 :                 fDDLObject = NULL;
     202           0 :         }
     203             :         
     204             :         // Better to reset these pointers.
     205          84 :         fkCurrentBusPatch = NULL;
     206          84 :         fkCurrentData = NULL;
     207          84 :         fkEndOfData = NULL;
     208             :         
     209         168 :         while (fDDL < GetMaxDDL())
     210             :         {
     211          80 :                 GetReader()->Reset();
     212          80 :                 GetReader()->Select("MUONTRK", fDDL, fDDL);  // Select the DDL file to be read.
     213          80 :                 if (GetReader()->ReadHeader()) break;
     214           0 :                 AliDebug(3, Form("Skipping DDL %d which does not seem to be there", fDDL+1));
     215           0 :                 fDDL++;
     216             :         }
     217             : 
     218             :         // If we reach the end of the DDL list for this event then reset the
     219             :         // DDL counter, mark the iteration as done and exit.
     220          84 :         if (fDDL >= GetMaxDDL())
     221             :         {
     222           4 :                 fDDL = 0;
     223           4 :                 fDone = kTRUE;
     224           4 :                 return kFALSE;
     225             :         }
     226             :         else
     227             :         {
     228          80 :                 fDone = kFALSE;
     229             :         }
     230             : 
     231         240 :         AliDebug(3, Form("DDL Number %d\n", fDDL));
     232             :         
     233          80 :         Int_t dataSize = GetReader()->GetDataSize(); // in bytes
     234             :         // Check if we have enough buffer space already in fBuffer. If we do then
     235             :         // just continue reading otherwise we need to resize the buffer.
     236          80 :         if (fBufferSize < dataSize)
     237             :         {
     238           0 :                 if (fBuffer != NULL)
     239             :                 {
     240           0 :                         delete [] fBuffer;
     241           0 :                         fBuffer = NULL;
     242           0 :                         fBufferSize = 0;
     243           0 :                 }
     244             :                 try
     245             :                 {
     246           0 :                         fBuffer = new UChar_t[dataSize];
     247           0 :                         fBufferSize = dataSize;
     248           0 :                 }
     249             :                 catch (const std::bad_alloc&)
     250             :                 {
     251           0 :                         AliError("Could not allocate more buffer space. Cannot decode DDL.");
     252             :                         return kFALSE;
     253           0 :                 }
     254           0 :         }
     255             :         
     256          80 :         if (not GetReader()->ReadNext(fBuffer, dataSize))
     257             :         {
     258           0 :                 return kFALSE;
     259             :         }
     260             :         
     261             : #ifndef R__BYTESWAP
     262             :         Swap(reinterpret_cast<UInt_t*>(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc.
     263             : #endif
     264             :         
     265          80 :         fDDL++; // Remember to increment index to next DDL before the calls to
     266             :                 // fDecoder.Decode since the callback methods of the decoder will
     267             :                 // use AliMUONRawStreamTrackerHP::GetDDL()
     268             :         
     269             :         bool result = false;
     270             :         try
     271             :         {
     272             :                 // Since we might allocate memory inside OnNewBuffer in the event
     273             :                 // handler we need to trap any memory allocation exception to be robust.
     274         160 :                 result = fDecoder.Decode(fBuffer, dataSize);
     275          80 :                 fHadError = (result == true ? kFALSE : kTRUE);
     276          80 :                 fTotalNumberOfGlitchErrors += fDecoder.GetHandler().GlitchErrorCount();
     277          80 :                 fTotalNumberOfParityErrors += fDecoder.GetHandler().ParityErrorCount();
     278          80 :                 fTotalNumberOfPaddingErrors += fDecoder.GetHandler().PaddingErrorCount();
     279          80 :                 fTotalNumberOfTokenLostErrors += fDecoder.GetHandler().TokenLostCount();
     280           0 :         }
     281             :         catch (const std::bad_alloc&)
     282             :         {
     283           0 :                 AliError("Could not allocate more buffer space. Cannot decode DDL.");
     284             :                 return kFALSE;
     285           0 :         }
     286             : 
     287             :         // Update the current bus patch pointers.
     288          80 :         fkCurrentBusPatch = fDecoder.GetHandler().FirstBusPatch();
     289          80 :         if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
     290             :         {
     291          80 :                 fkCurrentData = fkCurrentBusPatch->GetData();
     292          80 :                 fkEndOfData = fkCurrentData + fkCurrentBusPatch->GetDataCount();
     293          80 :         }
     294             :         else
     295             :         {
     296             :                 // If the DDL did not have any bus patches then mark both fCurrentData
     297             :                 // and fEndOfData as NULL so that in Next() we are forced to find the
     298             :                 // first non empty DDL.
     299           0 :                 fkCurrentData = fkEndOfData = NULL;
     300             :         }
     301             : 
     302          80 :         return kTRUE;
     303          84 : }
     304             : 
     305             : 
     306             : Bool_t AliMUONRawStreamTrackerHP::IsDone() const
     307             : {
     308             :         /// Indicates whether the iteration is finished or not.
     309             :         /// \return kTRUE if we already read all the digits and kFALSE if not.
     310             :         
     311           0 :         return fDone;
     312             : }
     313             : 
     314             : 
     315             : Bool_t AliMUONRawStreamTrackerHP::Next(Int_t& busPatchId, 
     316             :                                        UShort_t& manuId, 
     317             :                                        UChar_t& manuChannel,
     318             :                                        UShort_t& adc, 
     319             :                                        Bool_t skipParityErrors)
     320             : {
     321             :         /// Advance one step in the iteration. Returns false if finished.
     322             :         /// [out] \param busPatchId  This is filled with the bus patch ID of the digit.
     323             :         /// [out] \param manuId      This is filled with the MANU ID of the digit.
     324             :         /// [out] \param manuChannel This is filled with the MANU channel ID of the digit.
     325             :         /// [out] \param adc         This is filled with the ADC signal value of the digit.
     326             :         /// [in] \param skipParityErrors If this is kTRUE, we'll skip the buspatches that
     327             :         ///                              have some parity errors
     328             :         /// \return kTRUE if we read another digit and kFALSE if we have read all the
     329             :         ///    digits already, i.e. at the end of the iteration.
     330             :         
     331         712 :         if (fkCurrentData == NULL) return kFALSE;
     332             :         
     333             : retry:
     334             :         // Check if we still have data to be returned for the current bus patch.
     335        8520 :         if (fkCurrentData != fkEndOfData)
     336             :         {
     337        4968 :                 busPatchId = fkCurrentBusPatch->GetBusPatchId();
     338         708 :                 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(*fkCurrentData, manuId, manuChannel, adc);
     339         708 :                 fkCurrentData++;
     340         708 :                 return kTRUE;
     341             :         }
     342             :         else
     343             :         {
     344             :                 // We hit the end of the current bus patch so check if we have any more
     345             :                 // bus patches to process for the current DDL. If we do, then increment
     346             :                 // the current bus patch, make sure it is not the last one and then try
     347             :                 // reading the first element again.
     348        3552 :                 if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
     349             :                 {
     350        3552 :                         fkCurrentBusPatch++;
     351        3552 :                         if (fkCurrentBusPatch != fDecoder.GetHandler().EndOfBusPatch())
     352             :                         {
     353        3472 :                                 fkCurrentData = fkCurrentBusPatch->GetData();
     354        3472 :                                 fkEndOfData = fkCurrentData + fkCurrentBusPatch->GetDataCount();
     355        3472 :                                 if ( skipParityErrors )
     356             :                                 {
     357             :                                         Bool_t ok(kTRUE);
     358        8360 :                                         for ( Int_t i = 0; i < fkCurrentBusPatch->GetLength() && ok; ++ i )
     359             :                                         {
     360         708 :                                                 ok = fkCurrentBusPatch->IsParityOk(i);
     361             :                                         }
     362        3472 :                                         if (!ok) fkCurrentData = fkEndOfData;
     363        3472 :                                 }
     364             :                                 goto retry;
     365             :                         }
     366             :                 }
     367             : 
     368             :                 // This was the last bus patch in the DDL so read in the next one and
     369             :                 // try reading the first data element again.
     370             :                 // Note: fCurrentBusPatch is set inside NextDDL().
     371          80 :                 if (NextDDL()) goto retry;
     372             :         }
     373           4 :         return kFALSE;
     374         712 : }
     375             : 
     376             : 
     377             : AliMUONDDLTracker* AliMUONRawStreamTrackerHP::GetDDLTracker() const
     378             : {
     379             :         /// Construct and return a pointer to the DDL payload object.
     380             :         /// \return Pointer to internally constructed AliMUONDDLTracker object.
     381             :         ///         The object is owned by this class and should not be deleted
     382             :         ///         by the caller.
     383             :         ///
     384             :         /// \note This method should not be used just to gain access to the DDL
     385             :         /// payload, unless there is a good reason to have the AliMUONDDLTracker
     386             :         /// object. For example, if you want to modify the data and then save it
     387             :         /// to another DDL stream. Otherwise it can be an order of magnitude
     388             :         /// faster to access the DDL headers and data with the GetBlockHeader,
     389             :         /// GetDspHeader and GetBusPatch methods for example.
     390             :         /// Refer to the MUONRawStreamTracker.C macro to see how to use the fast
     391             :         /// decoder interface optimally.
     392             :         
     393           0 :         if (fDDLObject != NULL) return fDDLObject;
     394             :         
     395           0 :         fDDLObject = new AliMUONDDLTracker;
     396           0 :         for (Int_t iBlock = 0; iBlock < (Int_t)GetBlockCount(); iBlock++)
     397             :         {
     398           0 :                 AliMUONBlockHeader blockHeader;
     399           0 :                 AliMUONDspHeader dspHeader;
     400           0 :                 AliMUONBusStruct busPatch;
     401             :                 
     402           0 :                 const AliBlockHeader* bh = GetBlockHeader(iBlock);
     403             :                 // Copy block header and add it to the DDL object.
     404           0 :                 memcpy(blockHeader.GetHeader(), bh->GetHeader(), sizeof(AliMUONBlockHeaderStruct));
     405           0 :                 fDDLObject->AddBlkHeader(blockHeader);
     406             :                 
     407           0 :                 for (Int_t iDsp = 0; iDsp < (Int_t)bh->GetDspCount(); iDsp++)
     408             :                 {
     409           0 :                         const AliDspHeader* dh = bh->GetDspHeader(iDsp);
     410             :                         // Copy DSP header and add it to the DDL object.
     411           0 :                         memcpy(dspHeader.GetHeader(), dh->GetHeader(), sizeof(AliMUONDSPHeaderStruct));
     412           0 :                         fDDLObject->AddDspHeader(dspHeader, iBlock);
     413             :                         
     414           0 :                         const AliBusPatch* bp = dh->GetFirstBusPatch();
     415           0 :                         while (bp != NULL)
     416             :                         {
     417             :                                 // Copy bus patch header, data and add everything into DDL object.
     418           0 :                                 memcpy(busPatch.GetHeader(), bp->GetHeader(), sizeof(AliMUONBusPatchHeaderStruct));
     419           0 :                                 busPatch.SetAlloc(bp->GetLength());
     420           0 :                                 memcpy(busPatch.GetData(), bp->GetData(), bp->GetDataCount()*sizeof(UInt_t));
     421           0 :                                 busPatch.SetBlockId(iBlock);
     422           0 :                                 busPatch.SetDspId(iDsp);
     423           0 :                                 fDDLObject->AddBusPatch(busPatch, iBlock, iDsp);
     424           0 :                                 bp = bp->Next();
     425             :                         }
     426             :                 }
     427           0 :         }
     428             :         
     429           0 :         return fDDLObject;
     430           0 : }
     431             : 
     432             : 
     433             : void AliMUONRawStreamTrackerHP::SetMaxBlock(Int_t blk)
     434             : {
     435             :         /// Set maximum number of blocks per DDL allowed.
     436           0 :         fDecoder.MaxBlocks( (UInt_t) blk );
     437             :         
     438           0 :         fDecoder.GetHandler().SetMaxStructs(
     439           0 :                         fDecoder.MaxBlocks(),
     440           0 :                         fDecoder.MaxDSPs(),
     441           0 :                         fDecoder.MaxBusPatches()
     442             :                 );
     443           0 : }
     444             : 
     445             : 
     446             : void AliMUONRawStreamTrackerHP::SetMaxDsp(Int_t dsp)
     447             : {
     448             :         /// Set maximum number of Dsp per block allowed.
     449           0 :         fDecoder.MaxDSPs( (UInt_t) dsp );
     450             :         
     451           0 :         fDecoder.GetHandler().SetMaxStructs(
     452           0 :                         fDecoder.MaxBlocks(),
     453           0 :                         fDecoder.MaxDSPs(),
     454           0 :                         fDecoder.MaxBusPatches()
     455             :                 );
     456           0 : }
     457             : 
     458             : 
     459             : void AliMUONRawStreamTrackerHP::SetMaxBus(Int_t bus)
     460             : {
     461             :         /// Set maximum number of Buspatch per Dsp allowed.
     462           0 :         fDecoder.MaxBusPatches( (UInt_t) bus );
     463             :         
     464           0 :         fDecoder.GetHandler().SetMaxStructs(
     465           0 :                         fDecoder.MaxBlocks(),
     466           0 :                         fDecoder.MaxDSPs(),
     467           0 :                         fDecoder.MaxBusPatches()
     468             :                 );
     469           0 : }
     470             : 
     471             : ///////////////////////////////////////////////////////////////////////////////
     472             : 
     473             : void AliMUONRawStreamTrackerHP::AliBlockHeader::Print() const
     474             : {
     475             :         /// Print header to screen.
     476             :         
     477           0 :         cout << "CRT info"        << endl;
     478           0 :         if (fHeader == NULL)
     479             :         {
     480           0 :                 cout << "Header is NULL" << endl;
     481           0 :                 return;
     482             :         }
     483           0 :         cout << "DataKey: 0x"     << hex << fHeader->fDataKey << dec << endl;
     484           0 :         cout << "TotalLength: "   << fHeader->fTotalLength << endl;
     485           0 :         cout << "Length: "        << fHeader->fLength << endl;
     486           0 :         cout << "DspId: "         << fHeader->fDSPId << endl;
     487           0 :         cout << "L0Trigger: "     << fHeader->fL0Trigger << endl;
     488           0 :         cout << "MiniEventId: "   << fHeader->fMiniEventId<< endl; 
     489           0 :         cout << "EventId1: "      << fHeader->fEventId1 << endl;
     490           0 :         cout << "EventId2: "      << fHeader->fEventId2 << endl;
     491           0 : }
     492             : 
     493             : 
     494             : void AliMUONRawStreamTrackerHP::AliDspHeader::Print() const
     495             : {
     496             :         /// Print header to screen.
     497             :         
     498           0 :         cout << "FRT info"        << endl;
     499           0 :         if (fHeader == NULL)
     500             :         {
     501           0 :                 cout << "Header is NULL" << endl;
     502           0 :                 return;
     503             :         }
     504           0 :         cout << "DataKey: 0x"     << hex << fHeader->fDataKey << dec << endl;
     505           0 :         cout << "TotalLength: "   << fHeader->fTotalLength << endl;
     506           0 :         cout << "Length : "       << fHeader->fLength << endl;
     507           0 :         cout << "DspId: "         << fHeader->fDSPId << endl;
     508           0 :         cout << "BlkL1ATrigger: " << fHeader->fBlkL1ATrigger << endl;
     509           0 :         cout << "MiniEventId: "   << fHeader->fMiniEventId << endl;
     510           0 :         cout << "L1ATrigger: "    << fHeader->fL1ATrigger << endl;
     511           0 :         cout << "L1RTrigger: "    << fHeader->fL1RTrigger << endl;
     512           0 :         cout << "PaddingWord: "   << fHeader->fPaddingWord << endl;
     513           0 :         cout << "ErrorWord: "     << fHeader->fErrorWord << endl;
     514           0 : }
     515             : 
     516             : 
     517             : void AliMUONRawStreamTrackerHP::AliBusPatch::Print(const Option_t* opt) const
     518             : {
     519             :         /// Print header to screen.
     520           0 :         cout << "Bus patch info" << endl;
     521           0 :         if (fHeader == NULL)
     522             :         {
     523           0 :                 cout << "Header is NULL" << endl;
     524           0 :                 return;
     525             :         }
     526           0 :         cout << "DataKey: 0x"    << hex << fHeader->fDataKey << dec << endl;
     527           0 :         cout << "fTotalLength: " << fHeader->fTotalLength << endl;
     528           0 :         cout << "fLength: "      << fHeader->fLength << endl;
     529           0 :         cout << "fBusPatchId: "  << fHeader->fBusPatchId << endl;
     530             : 
     531           0 :         if (TString(opt).Contains("all"))
     532             :         {
     533           0 :                 for (UInt_t i = 0; i < fHeader->fLength; ++i)
     534           0 :                         cout << "Data["<< i << "] = " << fData[i] << endl;
     535           0 :         }
     536           0 : }
     537             : 
     538             : ///////////////////////////////////////////////////////////////////////////////
     539             : 
     540           9 : AliMUONRawStreamTrackerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
     541           9 :         fRawStream(NULL),
     542           9 :         fBufferStart(NULL),
     543           9 :         fBlockCount(0),
     544           9 :         fBlocks(NULL),
     545           9 :         fDSPs(NULL),
     546           9 :         fBusPatches(NULL),
     547           9 :         fEndOfBusPatches(NULL),
     548           9 :         fMaxChannels(8192),
     549          18 :         fParityOk(new Bool_t[8192]),
     550           9 :         fCurrentBlock(NULL),
     551           9 :         fCurrentDSP(NULL),
     552           9 :         fCurrentBusPatch(NULL),
     553           9 :         fCurrentParityOkFlag(NULL),
     554           9 :         fParityErrors(0),
     555           9 :         fGlitchErrors(0),
     556           9 :         fPaddingErrors(0),
     557           9 :         fTokenLostErrors(0),
     558           9 :         fMaxBlocks(),
     559           9 :         fMaxDsps(),
     560           9 :         fMaxBusPatches()
     561          45 : {
     562             :         /// Default constructor initialises the internal parity flags buffer to
     563             :         /// store 8192 elements. This array will grow dynamically if needed.
     564          18 : }
     565             : 
     566             : 
     567             : AliMUONRawStreamTrackerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
     568          20 : {
     569             :         /// Default destructor cleans up the allocated memory.
     570             :         
     571          15 :         if (fParityOk != NULL) delete [] fParityOk;
     572          30 :         if (fBlocks != NULL) delete [] fBlocks;
     573          70 :         if (fDSPs != NULL) delete [] fDSPs;
     574         270 :         if (fBusPatches != NULL) delete [] fBusPatches;
     575          10 : }
     576             : 
     577             : 
     578             : void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::SetMaxStructs(
     579             :                 UInt_t maxBlocks, UInt_t maxDsps, UInt_t maxBusPatches
     580             :         )
     581             : {
     582             :         /// Sets the maximum number of structures allowed.
     583             :         
     584             :         // Start by clearing the current arrays.
     585          18 :         if (fBlocks != NULL)
     586             :         {
     587           0 :                 delete [] fBlocks;
     588           0 :                 fBlocks = NULL;
     589           0 :         }
     590           9 :         if (fDSPs != NULL)
     591             :         {
     592           0 :                 delete [] fDSPs;
     593           0 :                 fDSPs = NULL;
     594           0 :         }
     595           9 :         if (fBusPatches != NULL)
     596             :         {
     597           0 :                 delete [] fBusPatches;
     598           0 :                 fBusPatches = NULL;
     599           0 :         }
     600           9 :         fCurrentBlock = NULL;
     601           9 :         fCurrentDSP = NULL;
     602           9 :         fCurrentBusPatch = NULL;
     603             :         
     604             :         // Allocate new memory.
     605          63 :         fBlocks = new AliBlockHeader[maxBlocks];
     606         207 :         fDSPs = new AliDspHeader[maxBlocks*maxDsps];
     607         927 :         fBusPatches = new AliBusPatch[maxBlocks*maxDsps*maxBusPatches];
     608           9 :         fEndOfBusPatches = fBusPatches;
     609             : 
     610           9 :         fMaxBlocks = maxBlocks;
     611           9 :         fMaxDsps = maxDsps;
     612           9 :         fMaxBusPatches = maxBusPatches;
     613           9 : }
     614             : 
     615             : 
     616             : void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnNewBuffer(
     617             :                 const void* buffer, UInt_t bufferSize
     618             :         )
     619             : {
     620             :         /// This is called by the high performance decoder when a new DDL payload
     621             :         /// is about to be decoded.
     622             :         /// \param buffer  The pointer to the buffer storing the DDL payload.
     623             :         /// \param bufferSize  The size of the buffer in bytes.
     624             : 
     625             :         // remember the start of the buffer to be used in OnError.
     626         160 :         fBufferStart = buffer;
     627             : 
     628             :         // Reset error counters.
     629          80 :         fParityErrors = 0;
     630          80 :         fGlitchErrors = 0;
     631          80 :         fPaddingErrors = 0;
     632          80 :         fTokenLostErrors = 0;
     633             : 
     634             :         // Check if we will have enough space in the fParityOk array.
     635             :         // If we do not then we need to resize the array.
     636             :         // bufferSize / sizeof(UInt_t) will be a safe over estimate of the
     637             :         // number of channels that we will find.
     638          80 :         UInt_t maxChannelsPossible = bufferSize / sizeof(UInt_t);
     639          80 :         if (maxChannelsPossible > fMaxChannels)
     640             :         {
     641           0 :                 if (fParityOk != NULL)
     642             :                 {
     643           0 :                         delete [] fParityOk;
     644           0 :                         fParityOk = NULL;
     645           0 :                         fMaxChannels = 0;
     646           0 :                 }
     647           0 :                 fParityOk = new Bool_t[maxChannelsPossible];
     648           0 :                 fMaxChannels = maxChannelsPossible;
     649           0 :         }
     650             :         
     651             :         // Reset the current pointers which will be used to track where we need to
     652             :         // fill fBlocks, fDSPs, fBusPatches and the parity flag. We have to subtract
     653             :         // one space because we will increment the pointer the first time in the
     654             :         // OnNewXZY methods.
     655          80 :         fCurrentBlock = fBlocks-1;
     656          80 :         fCurrentDSP = fDSPs-1;
     657          80 :         fCurrentBusPatch = fBusPatches-1;
     658          80 :         fCurrentParityOkFlag = fParityOk-1;
     659          80 :         fBlockCount = 0;
     660          80 : }
     661             : 
     662             : 
     663             : void AliMUONRawStreamTrackerHP::Swap(UInt_t* buffer, Int_t size) const
     664             : {
     665             :         // swap from little to big endian
     666             :         
     667             :         typedef struct {
     668             :                 UInt_t b1:8; ///< first byte word
     669             :                 UInt_t b2:8; ///< second byte word
     670             :                 UInt_t b3:8; ///< third byte word
     671             :                 UInt_t b4:8; ///< fourth byte word
     672             :         } RawWord;
     673             :         
     674             :         RawWord* word, temp;
     675           0 :         word = (RawWord*) buffer;
     676             :         
     677           0 :         for (Int_t i = 0; i < size; i++)
     678             :         {
     679           0 :                 temp = *(((RawWord*)buffer)+i);
     680           0 :                 word->b1 = temp.b4;
     681           0 :                 word->b2 = temp.b3;
     682           0 :                 word->b3 = temp.b2;
     683           0 :                 word->b4 = temp.b1;
     684           0 :                 word++;
     685             :         }
     686           0 : }
     687             : 
     688             : 
     689             : void AliMUONRawStreamTrackerHP::AliDecoderEventHandler::OnError(
     690             :                 ErrorCode error, const void* location
     691             :         )
     692             : {
     693             :         /// This is called by the high performance decoder when a error occurs
     694             :         /// when trying to decode the DDL payload. This indicates corruption in
     695             :         /// the data. This method converts the error code to a descriptive message
     696             :         /// and logs this with the logger object.
     697             :         /// \param error  The error code indicating the problem.
     698             :         /// \param location  A pointer to the location within the DDL payload buffer
     699             :         ///              being decoded where the problem with the data was found.
     700             :         
     701           0 :         assert(fRawStream != NULL);
     702             :         
     703             :         const char* message = NULL;
     704             :         UInt_t word = 0;
     705             :         bool logAsMajorError = true;
     706             :         
     707             :         // Build the detailed part of the error message if high detail selected.
     708             :         const char* detail = "";
     709           0 :         if (fRawStream->GetLoggingDetailLevel() == kHighErrorDetail)
     710             :         {
     711           0 :                 bool blockPtrOk = fBlockCount > 0;
     712           0 :                 bool dspPtrOk = blockPtrOk ? fCurrentBlock->GetDspCount() > 0 : false;
     713           0 :                 bool buspatchPtrOk = dspPtrOk ? fCurrentDSP->GetBusPatchCount() > 0 : false;
     714             :                 // We subtract 1 from the current numbers of blocks, DSPs
     715             :                 // and bus patches to get the iBlock, iDsp and iBus indices.
     716           0 :                 detail = Form(
     717             :                         "At byte %lu in DDL %d, event %d, iBlock %d, iDsp %d [DSP ID: %d (0x%X)],"
     718             :                         " iBus %d [bus patch ID: %d (0x%X)].",
     719           0 :                         (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeaderV3),
     720           0 :                         AliDAQ::DdlID("MUONTRK", fRawStream->GetDDL()),
     721           0 :                         fRawStream->GetReader()->GetEventIndex(),
     722           0 :                         int(fBlockCount)-1,
     723           0 :                         blockPtrOk ? int(fCurrentBlock->GetDspCount())-1 : -1,
     724           0 :                         blockPtrOk ? fCurrentBlock->GetDspId() : -1,
     725           0 :                         blockPtrOk ? fCurrentBlock->GetDspId() : -1,
     726           0 :                         dspPtrOk ? int(fCurrentDSP->GetBusPatchCount())-1 : -1,
     727           0 :                         buspatchPtrOk ? fCurrentBusPatch->GetBusPatchId() : -1,
     728           0 :                         buspatchPtrOk ? fCurrentBusPatch->GetBusPatchId() : -1
     729             :                 );
     730           0 :         }
     731             :         
     732             :         // Build the log message.
     733           0 :         switch (error)
     734             :         {
     735             :         case kGlitchFound:
     736           0 :                 fGlitchErrors++;
     737           0 :                 switch (fRawStream->GetLoggingDetailLevel())
     738             :                 {
     739             :                 case kLowErrorDetail:
     740             :                         message = "Glitch error detected.";
     741           0 :                         break;
     742             :                 case kMediumErrorDetail:
     743           0 :                         message = Form(
     744             :                                 "Glitch error detected in DSP %d (0x%X), skipping event.",
     745           0 :                                 fCurrentBlock->GetDspId(), fCurrentBlock->GetDspId()
     746             :                         );
     747           0 :                         break;
     748             :                 case kHighErrorDetail:
     749             :                 default:
     750           0 :                         message = Form("%s %s", ErrorCodeToMessage(error), detail);
     751           0 :                         break;
     752             :                 }
     753             :                 logAsMajorError = true;
     754           0 :                 break;
     755             : 
     756             :         case kBadPaddingWord:
     757           0 :                 fPaddingErrors++;
     758           0 :                 switch (fRawStream->GetLoggingDetailLevel())
     759             :                 {
     760             :                 case kLowErrorDetail:
     761             :                         message = "Padding word error detected.";
     762           0 :                         break;
     763             :                 case kMediumErrorDetail:
     764             :                         // We subtract 1 from the current numbers of blocks, DSPs
     765             :                         // and bus patches to get the indices.
     766           0 :                         message = Form(
     767             :                                 "Padding word error for iBlock %d, iDsp %d, iBus %d.",
     768           0 :                                 fBlockCount-1,
     769           0 :                                 fCurrentBlock->GetDspCount()-1,
     770           0 :                                 fCurrentDSP->GetBusPatchCount()-1
     771             :                         );
     772           0 :                         break;
     773             :                 case kHighErrorDetail:
     774             :                 default:
     775           0 :                         message = Form("%s %s", ErrorCodeToMessage(error), detail);
     776           0 :                         break;
     777             :                 }
     778             :                 logAsMajorError = false;
     779           0 :                 break;
     780             : 
     781             :         case kParityError:
     782           0 :                 fParityErrors++;
     783           0 :                 switch (fRawStream->GetLoggingDetailLevel())
     784             :                 {
     785             :                 case kLowErrorDetail:
     786             :                         message = "Parity error detected.";
     787           0 :                         break;
     788             :                 case kMediumErrorDetail:
     789           0 :                         message = Form(
     790             :                                 "Parity error in buspatch %d (0x%X).",
     791           0 :                                 fCurrentBusPatch->GetBusPatchId(),
     792           0 :                                 fCurrentBusPatch->GetBusPatchId()
     793             :                         );
     794           0 :                         break;
     795             :                 case kHighErrorDetail:
     796             :                 default:
     797             :                         // location points to the incorrect data word and
     798             :                         // fCurrentBusPatch->GetData() returns a pointer to the start of
     799             :                         // bus patches data, so the difference divided by 4 gives the 32
     800             :                         // bit word number.
     801           0 :                         word = (reinterpret_cast<size_t>(location) - reinterpret_cast<size_t>(fCurrentBusPatch->GetData()))
     802           0 :                                 / sizeof(UInt_t);
     803           0 :                         message = Form(
     804             :                                 "Parity error in word %d for manuId %d and channel %d in buspatch %d. %s",
     805             :                                 word,
     806           0 :                                 fCurrentBusPatch->GetManuId(word),
     807           0 :                                 fCurrentBusPatch->GetChannelId(word),
     808           0 :                                 fCurrentBusPatch->GetBusPatchId(),
     809             :                                 detail
     810             :                         );
     811           0 :                         break;
     812             :                 }
     813             :                 logAsMajorError = false;
     814           0 :                 break;
     815             :                 
     816             :         case kTokenLost:
     817           0 :                 fTokenLostErrors++;
     818           0 :                 switch (fRawStream->GetLoggingDetailLevel())
     819             :                 {
     820             :                 case kLowErrorDetail:
     821             :                         message = "Lost token error detected.";
     822           0 :                         break;
     823             :                 case kMediumErrorDetail:
     824           0 :                         word = *reinterpret_cast<const UInt_t*>(location);
     825           0 :                         message = Form(
     826             :                                 "Lost token error detected with address 0x%X of DDL %d and code %d.",
     827           0 :                                 ((word & 0xFFFF0000)),
     828           0 :                                 fRawStream->GetDDL(),
     829           0 :                                 (word & 0xF)
     830             :                         );
     831           0 :                         break;
     832             :                 case kHighErrorDetail:
     833             :                 default:
     834           0 :                         word = *reinterpret_cast<const UInt_t*>(location);
     835           0 :                         message = Form(
     836             :                                 "Lost token error detected with address 0x%X and code %d. %s",
     837           0 :                                 ((word & 0xFFFF0000)),
     838           0 :                                 (word & 0xF),
     839             :                                 detail
     840             :                         );
     841           0 :                         break;
     842             :                 }
     843             :                 logAsMajorError = false;
     844           0 :                 break;
     845             : 
     846             :         default:
     847           0 :                 switch (fRawStream->GetLoggingDetailLevel())
     848             :                 {
     849             :                 case kLowErrorDetail:
     850           0 :                         message = ErrorCodeToMessage(error);
     851           0 :                         break;
     852             :                 case kMediumErrorDetail:
     853           0 :                         message = Form(
     854             :                                 "%s (At byte %lu)",
     855           0 :                                 ErrorCodeToMessage(error),
     856           0 :                                 (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeaderV3)
     857             :                         );
     858           0 :                         break;
     859             :                 case kHighErrorDetail:
     860             :                 default:
     861           0 :                         message = Form(
     862             :                                 "%s Error code: %d (%s). %s",
     863           0 :                                 ErrorCodeToMessage(error),
     864           0 :                                 error, ErrorCodeToString(error),
     865             :                                 detail
     866             :                         );
     867           0 :                         break;
     868             :                 }
     869             :                 logAsMajorError = true;
     870           0 :                 break;
     871             :         }
     872             :         
     873             :         // Now log the error message depending on the logging flags set.
     874           0 :         if (fRawStream->IsRawReaderErrorLoggerEnabled())
     875             :         {
     876           0 :                 if (logAsMajorError)
     877           0 :                         fRawStream->GetReader()->AddMajorErrorLog(Int_t(error), message);
     878             :                 else
     879           0 :                         fRawStream->GetReader()->AddMinorErrorLog(Int_t(error), message);
     880             :         }
     881           0 :         if (fRawStream->IsMUONErrorLoggerEnabled())
     882             :         {
     883           0 :                 AliMUONLogger* logger = fRawStream->GetMUONErrorLogger();
     884           0 :                 if (logger != NULL)
     885             :                 {
     886           0 :                         logger->Log(message);
     887           0 :                 }
     888             :                 else
     889             :                 {
     890           0 :                         AliErrorGeneral(
     891             :                                 "AliMUONRawStreamTrackerHP::AliDecoderEventHandler",
     892             :                                 "Enabled logging to AliMUONLogger, but the logger object"
     893             :                                 " was not set with SetMUONErrorLogger()."
     894             :                         );
     895             :                 }
     896           0 :         }
     897           0 :         if (fRawStream->IsWarningsEnabled())
     898             :         {
     899           0 :                 AliWarningGeneral(
     900             :                                 "AliMUONRawStreamTrackerHP::AliDecoderEventHandler",
     901             :                                 message
     902             :                         );
     903           0 :         }
     904           0 : }
     905             : 

Generated by: LCOV version 1.11