LCOV - code coverage report
Current view: top level - RAW/RAWDatarec - AliAltroRawStreamV3.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 196 424 46.2 %
Date: 2016-06-14 17:26:59 Functions: 14 30 46.7 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : ///////////////////////////////////////////////////////////////////////////////
      17             : ///
      18             : /// This is a base class for reading raw data digits in Altro format.
      19             : /// The class is able to read the RCU v3 and above formats.
      20             : /// The main difference between the format V3 and older ones is in
      21             : /// the coding of the 10-bit Altro payload words. In V3 3 10-bit words
      22             : /// are coded in one 32-bit word. The bits 30 and 31 are used to identify
      23             : /// the payload, altro header and RCU trailer contents.
      24             : ///
      25             : ///
      26             : /// cvetan.cheshkov@cern.ch 1/04/2009
      27             : ///////////////////////////////////////////////////////////////////////////////
      28             : 
      29             : #include "AliAltroRawStreamV3.h"
      30             : #include "AliRawReader.h"
      31             : #include "AliLog.h"
      32             : #include "AliAltroRawStream.h"
      33             : #include "AliRawEventHeaderBase.h"
      34             : 
      35         128 : ClassImp(AliAltroRawStreamV3)
      36             : 
      37             : 
      38             : //_____________________________________________________________________________
      39          20 : AliAltroRawStreamV3::AliAltroRawStreamV3(AliRawReader* rawReader) :
      40          20 :   fIsShortDataHeader(kFALSE),
      41          20 :   fDDLNumber(-1),
      42          20 :   fRCUId(-1),
      43          20 :   fHWAddress(-1),
      44          20 :   fRawReader(rawReader),
      45          20 :   fData(NULL),
      46          20 :   fChannelStartPos(-1),
      47          20 :   fPosition(-1),
      48          20 :   fCount(-1),
      49          20 :   fStartTimeBin(-1),
      50          20 :   fBunchLength(-1),
      51          20 :   fBadChannel(kFALSE),
      52          20 :   fPayloadSize(-1),
      53          20 :   fChannelPayloadSize(-1),
      54          20 :   fBunchDataPointer(NULL),
      55          20 :   fBunchDataIndex(-1),
      56          20 :   fRCUTrailerData(NULL),
      57          20 :   fRCUTrailerSize(0),
      58          20 :   fFECERRA(0),
      59          20 :   fFECERRB(0),
      60          20 :   fERRREG2(0),
      61          20 :   fERRREG3(0),
      62          20 :   fActiveFECsA(0),
      63          20 :   fActiveFECsB(0),
      64          20 :   fAltroCFG1(0),
      65          20 :   fAltroCFG2(0),
      66          20 :   fOldStream(NULL),
      67          20 :   fCheckAltroPayload(kTRUE),
      68          20 :   fFormatVersion(0)
      69          68 : {
      70             :   // Constructor
      71             :   // Create an object to read Altro raw digits in
      72             :   // RCU version 3 and beyond format
      73       41000 :   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = 0;
      74          24 : }
      75             : 
      76             : //_____________________________________________________________________________
      77             : AliAltroRawStreamV3::~AliAltroRawStreamV3()
      78          48 : {
      79             : // destructor
      80             : // delete old stream object if one exists
      81          44 :   if (fOldStream) delete fOldStream;
      82          24 : }
      83             : 
      84             : //_____________________________________________________________________________
      85             : AliAltroRawStreamV3::AliAltroRawStreamV3(const AliAltroRawStreamV3& stream) :
      86           0 :   TObject(stream),
      87           0 :   fIsShortDataHeader(stream.fIsShortDataHeader),
      88           0 :   fDDLNumber(stream.fDDLNumber),
      89           0 :   fRCUId(stream.fRCUId),
      90           0 :   fHWAddress(stream.fHWAddress),
      91           0 :   fRawReader(stream.fRawReader),
      92           0 :   fData(stream.fData),
      93           0 :   fChannelStartPos(stream.fChannelStartPos),
      94           0 :   fPosition(stream.fPosition),
      95           0 :   fCount(stream.fCount),
      96           0 :   fStartTimeBin(stream.fStartTimeBin),
      97           0 :   fBunchLength(stream.fBunchLength),
      98           0 :   fBadChannel(stream.fBadChannel),
      99           0 :   fPayloadSize(stream.fPayloadSize),
     100           0 :   fChannelPayloadSize(stream.fChannelPayloadSize),
     101           0 :   fBunchDataPointer(stream.fBunchDataPointer),
     102           0 :   fBunchDataIndex(stream.fBunchDataIndex),
     103           0 :   fRCUTrailerData(stream.fRCUTrailerData),
     104           0 :   fRCUTrailerSize(stream.fRCUTrailerSize),
     105           0 :   fFECERRA(stream.fFECERRA),
     106           0 :   fFECERRB(stream.fFECERRB),
     107           0 :   fERRREG2(stream.fERRREG2),
     108           0 :   fERRREG3(stream.fERRREG3),
     109           0 :   fActiveFECsA(stream.fActiveFECsA),
     110           0 :   fActiveFECsB(stream.fActiveFECsB),
     111           0 :   fAltroCFG1(stream.fAltroCFG1),
     112           0 :   fAltroCFG2(stream.fAltroCFG2),
     113           0 :   fOldStream(NULL),
     114           0 :   fCheckAltroPayload(stream.fCheckAltroPayload),
     115           0 :   fFormatVersion(0)
     116           0 : {
     117             :   // Copy constructor
     118             :   // Copy the bunch data array
     119           0 :   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
     120             : 
     121           0 :   if (stream.fOldStream)
     122           0 :     fOldStream = new AliAltroRawStream(*stream.fOldStream);
     123           0 : }
     124             : 
     125             : //_____________________________________________________________________________
     126             : AliAltroRawStreamV3& AliAltroRawStreamV3::operator = (const AliAltroRawStreamV3& stream)
     127             : {
     128             :   // assignment operator
     129             :   // ... 
     130           0 :   if(&stream == this) return *this;
     131             : 
     132           0 :   fIsShortDataHeader = stream.fIsShortDataHeader;
     133           0 :   fDDLNumber         = stream.fDDLNumber;
     134           0 :   fRCUId             = stream.fRCUId;
     135           0 :   fHWAddress         = stream.fHWAddress;
     136           0 :   fRawReader         = stream.fRawReader;
     137           0 :   fData              = stream.fData;
     138           0 :   fChannelStartPos   = stream.fChannelStartPos;
     139           0 :   fPosition          = stream.fPosition;
     140           0 :   fCount             = stream.fCount;
     141           0 :   fStartTimeBin      = stream.fStartTimeBin;
     142           0 :   fBunchLength       = stream.fBunchLength;
     143           0 :   fBadChannel        = stream.fBadChannel;
     144           0 :   fPayloadSize       = stream.fPayloadSize;
     145           0 :   fChannelPayloadSize= stream.fChannelPayloadSize;
     146           0 :   fBunchDataPointer  = stream.fBunchDataPointer;
     147           0 :   fBunchDataIndex    = stream.fBunchDataIndex;
     148           0 :   fRCUTrailerData    = stream.fRCUTrailerData;
     149           0 :   fRCUTrailerSize    = stream.fRCUTrailerSize;
     150           0 :   fFECERRA           = stream.fFECERRA;
     151           0 :   fFECERRB           = stream.fFECERRB;
     152           0 :   fERRREG2           = stream.fERRREG2;
     153           0 :   fERRREG3           = stream.fERRREG3;
     154           0 :   fActiveFECsA       = stream.fActiveFECsA;
     155           0 :   fActiveFECsB       = stream.fActiveFECsB;
     156           0 :   fAltroCFG1         = stream.fAltroCFG1;
     157           0 :   fAltroCFG2         = stream.fAltroCFG2;
     158           0 :   fFormatVersion     = stream.fFormatVersion;
     159             : 
     160           0 :   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
     161             : 
     162           0 :   if (stream.fOldStream) {
     163           0 :     if (fOldStream) delete fOldStream;
     164           0 :     fOldStream = new AliAltroRawStream(stream.fRawReader);
     165           0 :     *fOldStream = *stream.fOldStream;
     166           0 :   }
     167             : 
     168           0 :   fCheckAltroPayload = stream.fCheckAltroPayload;
     169             : 
     170           0 :   return *this;
     171           0 : }
     172             : 
     173             : //_____________________________________________________________________________
     174             : void AliAltroRawStreamV3::Reset()
     175             : {
     176             : // Complete reset of raw stream params
     177             : // Reset of the raw-reader as well
     178             : 
     179           8 :   fDDLNumber = fRCUId = fHWAddress = -1;
     180           4 :   fChannelStartPos = -1;
     181           4 :   fPosition = fCount = -1;
     182           4 :   fBunchLength = fStartTimeBin = -1;
     183           4 :   fBadChannel = kFALSE;
     184           4 :   fPayloadSize = -1;
     185           4 :   fChannelPayloadSize = -1;
     186           4 :   fBunchDataPointer = NULL;
     187           4 :   fBunchDataIndex = -1;
     188             : 
     189           4 :   fRCUTrailerData = NULL;
     190           4 :   fRCUTrailerSize = 0;
     191             : 
     192           4 :   fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
     193             : 
     194           8 :   if (fRawReader) fRawReader->Reset();
     195             : 
     196           4 :   if (fOldStream) fOldStream->Reset();
     197           4 : }
     198             : 
     199             : //_____________________________________________________________________________
     200             : Bool_t AliAltroRawStreamV3::NextDDL()
     201             : {
     202             : // Read the next DDL payload (CDH + RCU trailer)
     203             : // Updates the information which is coming from these
     204             : // two sources
     205        2344 :   fFormatVersion = 0;
     206        1172 :   fPosition = 0;
     207             :   // Get next DDL payload
     208             :   // return wtih false in case no more data payloads
     209             :   // are found
     210        1172 :   do {
     211        1476 :     if (!fRawReader->ReadNextData(fData)) return kFALSE;
     212         868 :   } while (fRawReader->GetDataSize() == 0);
     213             : 
     214         868 :   fDDLNumber = fRawReader->GetDDLID();
     215         868 :   fChannelPayloadSize = -1;
     216         868 :   fChannelStartPos = -1;
     217             : 
     218         868 :   fFormatVersion = (fRawReader->GetBlockAttributes() & 0xF);
     219             : 
     220         868 :   if (fFormatVersion < 2) {
     221             :     // old altro format data
     222          74 :     if (!fOldStream) {
     223          24 :       fOldStream = new AliAltroRawStream(fRawReader);
     224          12 :       AliInfo(Form("RCU firmware verion %d detected. Using AliAltroRawStream to decode the data.",
     225             :                    fFormatVersion));
     226          12 :     }
     227          74 :     Bool_t status = fOldStream->NextDDL(fData);
     228          74 :     if (status) {
     229          74 :       fRCUId = fOldStream->GetRCUId();
     230          74 :       fRCUTrailerSize = fOldStream->GetRCUTrailerSize();
     231          74 :       fOldStream->GetRCUTrailerData(fRCUTrailerData);
     232          74 :       fFECERRA = fOldStream->GetFECERRA();
     233          74 :       fFECERRB = fOldStream->GetFECERRB();
     234          74 :       fERRREG2 = fOldStream->GetERRREG2();
     235         148 :       fERRREG3 = ((UInt_t)fOldStream->GetNChAddrMismatch()) |
     236          74 :         (((UInt_t)fOldStream->GetNChLengthMismatch()) << 12);
     237          74 :       fActiveFECsA = fOldStream->GetActiveFECsA();
     238          74 :       fActiveFECsB = fOldStream->GetActiveFECsB();
     239          74 :       fAltroCFG1 = fOldStream->GetAltroCFG1();
     240          74 :       fAltroCFG2 = fOldStream->GetAltroCFG2();
     241          74 :       if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData)
     242           0 :         fPayloadSize = fOldStream->GetRCUPayloadSizeInSOD();
     243             :     }
     244             :     return status;
     245             :   }
     246             : 
     247         794 :   return ReadRCUTrailer(fFormatVersion);
     248        1172 : }
     249             : 
     250             : //_____________________________________________________________________________
     251             : Bool_t AliAltroRawStreamV3::NextChannel()
     252             : {
     253             :   // Read the next Altro channel from the
     254             :   // raw-data stream
     255             :   // Updates the channel hardware address member and
     256             :   // channel data size. Sets the error flag in case
     257             :   // RCU signals readout error in this channel
     258      100428 :   if (fOldStream) {
     259         469 :     Bool_t status = fOldStream->NextChannel();
     260         469 :     if (status) {
     261         395 :       fHWAddress = fOldStream->GetHWAddress();
     262         395 :       fChannelPayloadSize = fOldStream->GetChannelPayloadSize();
     263         395 :     }
     264             :     return status;
     265             :   }
     266             : 
     267       49745 :   Int_t channelStartPos=fPosition;
     268       49745 :   fChannelStartPos = -1;
     269       49745 :   fCount = -1;
     270       49745 :   fBadChannel = kFALSE;
     271       49745 :   fBunchDataIndex = 0;
     272       49745 :   fBunchLength = -1;
     273             : 
     274             :   UInt_t word = 0;
     275       49745 :   do {
     276       49853 :     word = Get32bitWord(fPosition++);
     277       50647 :     if (fPosition > fPayloadSize) return kFALSE;
     278       49059 :   }
     279       49059 :   while ((word >> 30) != 1);
     280             : 
     281             :   // check for readout errors
     282       48951 :   fBadChannel = (word >> 29) & 0x1;
     283             : 
     284             :   // extract channel payload and hw address
     285       48951 :   fCount = (word >> 16) & 0x3FF; 
     286       48951 :   fChannelPayloadSize = fCount;
     287       48951 :   fHWAddress = word & 0xFFF;
     288             : 
     289             :   // Now unpack the altro data
     290             :   // Revert the order of the samples
     291             :   // inside the bunch so that the
     292             :   // first time is first in the samples
     293             :   // array
     294             :   Int_t isample = 0;
     295       48951 :   Int_t nwords = (fCount+2)/3;
     296     1202297 :   for (Int_t iword = 0; iword < nwords; iword++) {
     297      527722 :     word = Get32bitWord(fPosition++);
     298      527722 :     if ((word >> 30) != 0) {
     299             :       // Unexpected end of altro channel payload
     300           0 :       static bool show_info = !(getenv("HLT_ONLINE_MODE") && strcmp(getenv("HLT_ONLINE_MODE"), "on") == 0);
     301             :       static int nErrors = 0;
     302           0 :       if (show_info || nErrors++ < 10)
     303             :       {
     304           0 :           AliWarning(Form("Unexpected end of payload in altro channel payload! DDL=%03d, Address=0x%x, word=0x%x",
     305             :                       fDDLNumber,fHWAddress,word));
     306           0 :       }
     307           0 :       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
     308           0 :       if (AliDebugLevel() > 0) HexDumpChannel();
     309           0 :       fCount = -1;
     310           0 :       fPosition--;
     311           0 :       return kFALSE;
     312             :     }
     313      527722 :     fBunchData[isample++] = (word >> 20) & 0x3FF;
     314      527722 :     fBunchData[isample++] = (word >> 10) & 0x3FF;
     315      527722 :     fBunchData[isample++] = word & 0x3FF;
     316             :   }  
     317             : 
     318       48951 :   fChannelStartPos=channelStartPos;
     319       48951 :   return kTRUE;
     320       50214 : }
     321             : 
     322             : //_____________________________________________________________________________
     323             : Bool_t AliAltroRawStreamV3::NextBunch()
     324             : {
     325             :   // Read next altro bunch from the
     326             :   // raw-data stream.
     327             :   // Updates the start/end time-bins
     328             :   // and the array with altro samples
     329      350172 :   if (fOldStream) {
     330         424 :     Bool_t status = fOldStream->NextBunch(fBunchData,fBunchLength,fStartTimeBin);
     331         636 :     if (status) fBunchDataPointer = &fBunchData[0];
     332         212 :     else fBunchDataPointer = NULL;
     333             :     return status;
     334             :   }
     335             : 
     336      475035 :   Int_t prevTimeBin = (fBunchLength > 0) ? fStartTimeBin-fBunchLength+1 : 1024;
     337      174662 :   fBunchLength = fStartTimeBin = -1;
     338      174662 :   fBunchDataPointer = NULL;
     339             : 
     340      349324 :   if ((fBunchDataIndex >= fCount) || fBadChannel) return kFALSE;
     341             : 
     342      125711 :   fBunchLength = fBunchData[fBunchDataIndex];
     343      125711 :   if (fBunchLength <= 2) {
     344             :     // Invalid bunch size
     345           0 :      AliDebug(1,Form("Too short bunch length (%d) @ %d in Address=0x%x (DDL=%03d)!",
     346             :                     fBunchLength,fBunchDataIndex,fHWAddress,fDDLNumber));
     347           0 :     fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
     348           0 :     if (AliDebugLevel() > 0) HexDumpChannel();
     349           0 :     fCount = fBunchLength = -1;
     350           0 :     return kFALSE;
     351             :   }
     352      125711 :   if ((fBunchDataIndex + fBunchLength) > fCount) {
     353             :     // Too long bunch detected
     354           0 :     AliDebug(1,Form("Too long bunch detected @ %d in Address=0x%x (DDL=%03d) ! Expected <= %d 10-bit words, found %d !", fBunchDataIndex,
     355             :                     fHWAddress,fDDLNumber,fCount-fBunchDataIndex,fBunchLength));
     356           0 :     fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
     357           0 :     if (AliDebugLevel() > 0) HexDumpChannel();
     358           0 :     fCount = fBunchLength = -1;
     359           0 :     return kFALSE;
     360             :   }
     361      125711 :   fBunchDataIndex++;
     362      125711 :   fBunchLength -= 2;
     363             : 
     364      125711 :   fStartTimeBin = fBunchData[fBunchDataIndex++];
     365      125711 :   if (fCheckAltroPayload) {
     366      124115 :     static bool show_info = !(getenv("HLT_ONLINE_MODE") && strcmp(getenv("HLT_ONLINE_MODE"), "on") == 0);
     367      124111 :     if ((fStartTimeBin-fBunchLength+1) < 0) {
     368             :       static int nErrors = 0;
     369           0 :       if (show_info || nErrors++ < 10)
     370             :       {
     371           0 :         AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d-%d+1) < 0", fBunchDataIndex-1,
     372             :                         fHWAddress,fDDLNumber,fStartTimeBin,fBunchLength));
     373           0 :       }
     374           0 :       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
     375           0 :       if (AliDebugLevel() > 0) HexDumpChannel();
     376           0 :       fCount = fBunchLength = -1;
     377           0 :       return kFALSE;
     378             :     }
     379      124111 :     if (fStartTimeBin >= prevTimeBin) {
     380             :       static int nErrors = 0;
     381           0 :       if (show_info || nErrors++ < 100)
     382             :       {
     383           0 :         AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d>=%d)", fBunchDataIndex-1,
     384             :                         fHWAddress,fDDLNumber,fStartTimeBin,prevTimeBin));
     385           0 :       }
     386           0 :       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
     387           0 :       if (AliDebugLevel() > 0) HexDumpChannel();
     388           0 :       fCount = fBunchLength = -1;
     389           0 :       return kFALSE;
     390             :     }
     391             :   }
     392             : 
     393      125711 :   fBunchDataPointer = &fBunchData[fBunchDataIndex];
     394             : 
     395      125711 :   fBunchDataIndex += fBunchLength;
     396             : 
     397      125711 :   return kTRUE;
     398      175086 : }
     399             : 
     400             : //_____________________________________________________________________________
     401             : const UChar_t *AliAltroRawStreamV3::GetChannelPayload() const
     402             : {
     403             :   //returns raw channel data, length 4+(fChannelPayloadSize+2)/3*4
     404           0 :   if (fChannelStartPos<0 || fChannelPayloadSize<0) return NULL;
     405           0 :   Int_t channelSize=1+(fChannelPayloadSize+2)/3; // nof 32bit words
     406           0 :   if (fPosition<fChannelStartPos+channelSize) return NULL;
     407           0 :   return fData+(fChannelStartPos<<2);
     408           0 : }
     409             : 
     410             : //_____________________________________________________________________________
     411             : UInt_t AliAltroRawStreamV3::Get32bitWord(Int_t index) const
     412             : {
     413             :   // This method returns the 32 bit word at a given
     414             :   // position inside the raw data payload.
     415             :   // The 'index' points to the beginning of the word.
     416             :   // The method is supposed to be endian (platform)
     417             :   // independent.
     418             : 
     419     1169442 :   index = (index << 2); 
     420             :   UInt_t word  = 0;
     421      584721 :   word |= fData[index++];
     422      584721 :   word |= fData[index++] << 8;
     423      584721 :   word |= fData[index++] << 16;
     424      584721 :   word |= fData[index++] << 24;
     425             : 
     426      584721 :   return word;
     427             : }
     428             : 
     429             : ///_____________________________________________________________________________
     430             : Bool_t AliAltroRawStreamV3::ReadRCUTrailer(UChar_t rcuVer)
     431             : {
     432             :   // Read the RCU trailer according
     433             :   // to the RCU formware version
     434             :   // specified in CDH
     435             :   // Cross-check with version found in the
     436             :   // trailer
     437             : 
     438        1588 :   fRCUTrailerData = NULL;
     439         794 :   fRCUTrailerSize = 0;
     440         794 :   fPayloadSize = -1;
     441             : 
     442         794 :   Int_t index = fRawReader->GetDataSize()/4;
     443             : 
     444             :   // First read 32-bit word with the
     445             :   // trailer size (7 bits), RCU ID (9 bits) and
     446             :   // RCU firmware version (8 bits?)
     447             :   // The two major bit should be 11 (identifies
     448             :   // the end of the trailer)
     449         794 :   UInt_t word = Get32bitWord(--index);
     450             : 
     451         794 :   if ((word >> 30) != 3) {
     452           0 :     fRawReader->AddFatalErrorLog(kRCUTrailerErr,"");
     453           0 :     AliError("Last RCU trailer word not found!");
     454           0 :     return kFALSE;
     455             :   }
     456             : 
     457         794 :   UChar_t ver = (word >> 16) & 0xFF;
     458         794 :   if (ver != rcuVer) {
     459             :     // Wrong RCU firmware version detected
     460           0 :     fRawReader->AddMajorErrorLog(kRCUVerErr,Form("%d!=%d",
     461             :                                                  ver,rcuVer));
     462           0 :     AliDebug(1,Form("Wrong RCU firmware version detected: %d != %d",
     463             :                     ver,rcuVer));
     464             :   }
     465             : 
     466         794 :   fRCUId = (Int_t)((word >> 7) & 0x1FF);
     467         794 :   Int_t trailerSize = (word & 0x7F);
     468             : 
     469             :   // Now read the beginning of the trailer
     470             :   // where the payload size is written
     471         794 :   if (trailerSize < 2) {
     472           0 :     fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
     473           0 :                                                      trailerSize*4));
     474           0 :     AliWarning(Form("Invalid trailer size found (%d bytes) !",
     475             :                     trailerSize*4));
     476           0 :     return kFALSE;
     477             :   }
     478             : 
     479         794 :   trailerSize -= 2;
     480         794 :   fRCUTrailerSize = trailerSize*4;
     481             : 
     482       12704 :   for (; trailerSize > 0; trailerSize--) {
     483        5558 :     word = Get32bitWord(--index);
     484        5558 :     if ((word >> 30) != 2) {
     485           0 :       fRawReader->AddMinorErrorLog(kRCUTrailerErr,"missing 10");
     486           0 :       AliWarning("Missing RCU trailer identifier pattern!");
     487           0 :       continue;
     488             :     }
     489        5558 :     Int_t parCode = (word >> 26) & 0xF;
     490        5558 :     Int_t parData = word & 0x3FFFFFF;
     491        5558 :     switch (parCode) {
     492             :     case 1:
     493             :       // ERR_REG1
     494         794 :       fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
     495         794 :       fFECERRB = ((parData & 0x1FFF)) << 7;
     496         794 :       break;
     497             :     case 2:
     498             :       // ERR_REG2
     499         794 :       fERRREG2 = parData & 0x1FF;
     500         794 :       break;
     501             :     case 3:
     502             :       // ERR_REG3
     503         794 :       fERRREG3 = parData & 0x1FFFFFF;
     504         794 :       break;
     505             :     case 4:
     506             :       // FEC_RO_A
     507         794 :       fActiveFECsA = parData & 0xFFFF;
     508         794 :       break;
     509             :     case 5:
     510             :       // FEC_RO_B
     511         794 :       fActiveFECsB = parData & 0xFFFF;
     512         794 :       break;
     513             :     case 6:
     514             :       // RDO_CFG1
     515         794 :       fAltroCFG1 = parData & 0xFFFFF;
     516         794 :       break;
     517             :     case 7:
     518             :       // RDO_CFG2
     519         794 :       fAltroCFG2 = parData & 0x1FFFFFF;
     520         794 :      break;
     521             :     default:
     522           0 :       fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
     523           0 :       AliWarning(Form("Undefined parameter code %d, ignore it !",
     524             :                       parCode));
     525           0 :       break;
     526             :     }
     527        5558 :   }
     528             : 
     529         794 :   if (index < 1) {
     530           0 :     fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
     531           0 :                                                      fRCUTrailerSize+8,
     532           0 :                                                      fRawReader->GetDataSize()));
     533           0 :     AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
     534             :                     fRCUTrailerSize,
     535             :                     fRawReader->GetDataSize()));
     536           0 :   }
     537             : 
     538         794 :   fRCUTrailerData = fData + index*4;
     539             : 
     540             :   // Now read the payload size
     541             :   // (First word in the RCU trailer)
     542         794 :   fPayloadSize = Get32bitWord(--index) & 0x3FFFFFF;
     543             : 
     544         794 :   if ((fRawReader->GetDataSize() - fRCUTrailerSize - 8) != (fPayloadSize*4)) {
     545           0 :     fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
     546           0 :                                                          fRawReader->GetDataSize(),
     547           0 :                                                          fRCUTrailerSize+8,
     548           0 :                                                          fPayloadSize*4));
     549           0 :     AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
     550             :                     fRawReader->GetDataSize(),
     551             :                     fRCUTrailerSize+8,
     552             :                     fPayloadSize*4));
     553           0 :   }
     554             : 
     555         794 :   return kTRUE;
     556         794 : }
     557             : 
     558             : //_____________________________________________________________________________
     559             : Int_t AliAltroRawStreamV3::GetBranch() const
     560             : {
     561             :   // The method provides the RCU branch index (0 or 1)
     562             :   // for the current hardware address.
     563             :   // In case the hardware address has not been yet
     564             :   // initialized, the method returns -1
     565           0 :   if (fHWAddress == -1) return -1;
     566             : 
     567           0 :   return ((fHWAddress >> 11) & 0x1);
     568           0 : }
     569             : 
     570             : //_____________________________________________________________________________
     571             : Int_t AliAltroRawStreamV3::GetFEC() const
     572             : {
     573             :   // The method provides the front-end card index
     574             :   // for the current hardware address.
     575             :   // In case the hardware address has not been yet
     576             :   // initialized, the method returns -1
     577           0 :   if (fHWAddress == -1) return -1;
     578             : 
     579           0 :   return ((fHWAddress >> 7) & 0xF);
     580           0 : }
     581             : 
     582             : //_____________________________________________________________________________
     583             : Int_t AliAltroRawStreamV3::GetAltro() const
     584             : {
     585             :   // The method provides the altro chip index
     586             :   // for the current hardware address.
     587             :   // In case the hardware address has not been yet
     588             :   // initialized, the method returns -1
     589           0 :   if (fHWAddress == -1) return -1;
     590             : 
     591           0 :   return ((fHWAddress >> 4) & 0x7);
     592           0 : }
     593             : 
     594             : //_____________________________________________________________________________
     595             : Int_t AliAltroRawStreamV3::GetChannel() const
     596             : {
     597             :   // The method provides the channel index
     598             :   // for the current hardware address.
     599             :   // In case the hardware address has not been yet
     600             :   // initialized, the method returns -1
     601           0 :   if (fHWAddress == -1) return -1;
     602             : 
     603           0 :   return (fHWAddress & 0xF);
     604           0 : }
     605             : 
     606             : //_____________________________________________________________________________
     607             : Bool_t AliAltroRawStreamV3::GetRCUTrailerData(UChar_t*& data) const
     608             : {
     609             :   // Return a pointer to the RCU trailer
     610             :   // data. Should be called always after
     611             :   // the RCU trailer was already processed
     612             :   // in the GetPosition() method
     613           0 :   if (!fRCUTrailerSize || !fRCUTrailerData) {
     614           0 :     AliError("No valid RCU trailer data is found !");
     615           0 :     data = NULL;
     616           0 :     return kFALSE;
     617             :   }
     618             : 
     619           0 :   data = fRCUTrailerData;
     620             : 
     621           0 :   return kTRUE;
     622           0 : }
     623             : 
     624             : //_____________________________________________________________________________
     625             : void AliAltroRawStreamV3::PrintRCUTrailer() const
     626             : {
     627             :   // Prints the contents of
     628             :   // the RCU trailer data
     629           0 :   printf("RCU trailer (Format version %d):\n"
     630           0 :          "==================================================\n",  GetFormatVersion());
     631           0 :   printf("FECERRA:                                   0x%x\n", fFECERRA);
     632           0 :   printf("FECERRB:                                   0x%x\n", fFECERRB);
     633           0 :   printf("ERRREG2:                                   0x%x\n", fERRREG2);
     634           0 :   printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
     635           0 :   printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
     636           0 :   printf("Active FECs (branch A):                    0x%x\n", fActiveFECsA);
     637           0 :   printf("Active FECs (branch B):                    0x%x\n", fActiveFECsB);
     638           0 :   printf("Baseline corr:                             0x%x\n",GetBaselineCorr());
     639           0 :   printf("Number of presamples:                      %d\n", GetNPresamples());
     640           0 :   printf("Number of postsamples:                     %d\n",GetNPostsamples());
     641           0 :   printf("Second baseline corr:                      %d\n",GetSecondBaselineCorr());
     642           0 :   printf("GlitchFilter:                              %d\n",GetGlitchFilter());
     643           0 :   printf("Number of non-ZS postsamples:              %d\n",GetNNonZSPostsamples());
     644           0 :   printf("Number of non-ZS presamples:               %d\n",GetNNonZSPresamples());
     645           0 :   printf("Number of ALTRO buffers:                   %d\n",GetNAltroBuffers());
     646           0 :   printf("Number of pretrigger samples:              %d\n",GetNPretriggerSamples());
     647           0 :   printf("Number of samples per channel:             %d\n",GetNSamplesPerCh());
     648           0 :   printf("Sparse readout:                            %d\n",GetSparseRO());
     649           0 :   printf("Sampling time:                             %e s\n",GetTSample());
     650           0 :   printf("L1 Phase:                                  %e s\n",GetL1Phase());
     651           0 :   printf("AltroCFG1:                                 0x%x\n",GetAltroCFG1());
     652           0 :   printf("AltroCFG2:                                 0x%x\n",GetAltroCFG2());
     653           0 :   printf("==================================================\n");
     654           0 : }
     655             : 
     656             : //_____________________________________________________________________________
     657             : void AliAltroRawStreamV3::SelectRawData(Int_t detId)
     658             : {
     659             :   // Select the raw data for specific
     660             :   // detector id
     661           0 :   AliDebug(1,Form("Selecting raw data for detector %d",detId));
     662           0 :   fRawReader->Select(detId);
     663           0 : }
     664             : 
     665             : //_____________________________________________________________________________
     666             : void AliAltroRawStreamV3::SelectRawData(const char *detName)
     667             : {
     668             :   // Select the raw data for specific
     669             :   // detector name
     670          80 :   AliDebug(1,Form("Selecting raw data for detector %s",detName));
     671          20 :   fRawReader->Select(detName);
     672          20 : }
     673             : 
     674             : //_____________________________________________________________________________
     675             : Double_t AliAltroRawStreamV3::GetTSample() const
     676             : {
     677             :   // Returns the sampling time
     678             :   // in seconds. In case the rcu trailer
     679             :   // was note read, return an invalid number (0)
     680             : 
     681         624 :   if (!fRCUTrailerData) return 0.;
     682             : 
     683             :   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
     684         312 :   UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
     685             :   Double_t tSample;
     686         312 :   switch (fq) {
     687             :   case 0:
     688             :     // 20 MHz
     689             :     tSample = 2.0*kLHCTimeSample;
     690         312 :     break;
     691             :   case 1:
     692             :     // 10 Mhz
     693             :     tSample = 4.0*kLHCTimeSample;
     694           0 :     break;
     695             :   case 2:
     696             :     // 5 MHz
     697             :     tSample = 8.0*kLHCTimeSample;
     698           0 :     break;
     699             :   default:
     700           0 :     AliWarning(Form("Invalid sampling frequency value %d !",
     701             :                       fq));
     702             :     tSample = 0.;
     703           0 :     break;
     704             :   }
     705             : 
     706             :   return tSample;
     707         312 : }
     708             : 
     709             : //_____________________________________________________________________________
     710             : Double_t AliAltroRawStreamV3::GetL1Phase() const
     711             : {
     712             :   // Returns the L1 phase w.r.t to the
     713             :   // LHC clock
     714         624 :   if (!fRCUTrailerData) return 0.;
     715             : 
     716             :   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
     717         312 :   Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
     718             : 
     719         312 :   Double_t tSample = GetTSample();
     720         312 :   if (phase >= tSample) {
     721           0 :     AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
     722             :                     phase,tSample));
     723             :     phase = 0.;
     724           0 :   }
     725             : 
     726             :   return phase;
     727         312 : }
     728             : 
     729             : //_____________________________________________________________________________
     730             : void AliAltroRawStreamV3::AddMappingErrorLog(const char *message)
     731             : {
     732             :   // Signal a mapping error
     733             :   // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
     734             :   // classes in order to log an error related to bad altro mapping
     735             : 
     736           0 :   if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
     737           0 : }
     738             : 
     739             : //_____________________________________________________________________________
     740             : UChar_t *AliAltroRawStreamV3::GetRCUPayloadInSOD() const
     741             : {
     742             :   // Get a pointer to the data in case
     743             :   // of SOD events
     744           0 :   if (fRawReader) {
     745           0 :     if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
     746           0 :       return fData;
     747             :     }
     748             :   }
     749           0 :   return NULL;
     750           0 : }
     751             : 
     752             : //_____________________________________________________________________________
     753             : Int_t AliAltroRawStreamV3::GetRCUPayloadSizeInSOD() const
     754             : {
     755             :   // Get the size of the RCU data in case
     756             :   // of SOD events
     757           0 :   if (fRawReader) {
     758           0 :     if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
     759           0 :       return fPayloadSize;
     760             :     }
     761             :   }
     762           0 :   return -1;
     763           0 : }
     764             : 
     765             : //_____________________________________________________________________________
     766             : 
     767             : void AliAltroRawStreamV3::HexDumpChannel() const
     768             : {
     769             :   // Print of the Hex Data of the current channel
     770             :   // to decipher read-out warnings and errors
     771           0 :   if (fCount>0 && fPosition>0) {
     772           0 :     printf("Hex-Dump of DDL: %3d, RCU ID: %d, HWADDR: 0x%03x\n",
     773           0 :            fDDLNumber,fRCUId,fHWAddress);
     774           0 :     printf("32-bit     - 2bit 10bit 10bit 10bit - ");
     775           0 :     printf("Index 10bit  10bit  10bit\n");
     776           0 :     printf("**********   **** ***** ***** ***** - ");
     777           0 :     printf("***** ****** ****** ******\n");
     778           0 :     Int_t nwords = (fCount+2)/3+1;
     779           0 :     for (Int_t iword = 0; iword < nwords; iword++) {
     780           0 :       UInt_t word32 = Get32bitWord(fPosition-nwords+iword);
     781           0 :       UInt_t marker  = word32 >> 30 & 0x3;
     782           0 :       UInt_t word101 = word32 >> 20 & 0x3FF;
     783           0 :       UInt_t word102 = word32 >> 10 & 0x3FF;
     784           0 :       UInt_t word103 = word32 >> 00 & 0x3FF; // nice octal number
     785           0 :       printf("0x%08x - 0b%1d%1d 0x%03x 0x%03x 0x%03x",
     786           0 :              word32,marker>>1,marker&0x1,word101,word102,word103);
     787           0 :       if (iword == 0) { printf(" - Channel Header\n"); continue; }
     788           0 :       Int_t base = 3*(iword-1);
     789           0 :       printf(" - %5d 0x%03x%c 0x%03x%c 0x%03x%c\n", base,
     790           0 :              fBunchData[base],   (fBunchDataIndex == base   ? '*' : ' '),
     791           0 :              fBunchData[base+1], (fBunchDataIndex == base+1 ? '*' : ' '),
     792           0 :              fBunchData[base+2], (fBunchDataIndex == base+2 ? '*' : ' '));
     793           0 :     }
     794           0 :   }
     795           0 : }

Generated by: LCOV version 1.11