]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliAltroRawStream.cxx
Removing AliFatal from the altro decoding class. Decoding errors are now stored in...
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStream.cxx
index bb5ba558c9344d504c48cc193cce293a939e22f7..b36108b4f6b9e7b5857e22a428ead70f96596469 100644 (file)
@@ -36,8 +36,12 @@ ClassImp(AliAltroRawStream)
 //_____________________________________________________________________________
 AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
   fNoAltroMapping(kTRUE),
+  fIsOldRCUFormat(kFALSE),
+  fIsShortDataHeader(kFALSE),
   fDDLNumber(-1),
   fPrevDDLNumber(-1),
+  fRCUId(-1),
+  fPrevRCUId(-1),
   fHWAddress(-1),
   fPrevHWAddress(-1),
   fTime(-1),
@@ -48,7 +52,9 @@ AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
   fData(NULL),
   fPosition(0),
   fCount(0),
-  fBunchLength(0)
+  fBunchLength(0),
+  fRCUTrailerData(NULL),
+  fRCUTrailerSize(0)
 {
 // create an object to read Altro raw digits
   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
@@ -58,8 +64,12 @@ AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
 AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
   TObject(stream),
   fNoAltroMapping(kTRUE),
+  fIsOldRCUFormat(kFALSE),
+  fIsShortDataHeader(kFALSE),
   fDDLNumber(-1),
   fPrevDDLNumber(-1),
+  fRCUId(-1),
+  fPrevRCUId(-1),
   fHWAddress(-1),
   fPrevHWAddress(-1),
   fTime(-1),
@@ -70,7 +80,9 @@ AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
   fData(NULL),
   fPosition(0),
   fCount(0),
-  fBunchLength(0)
+  fBunchLength(0),
+  fRCUTrailerData(NULL),
+  fRCUTrailerSize(0)
 {
   Fatal("AliAltroRawStream", "copy constructor not implemented");
 }
@@ -97,7 +109,10 @@ void AliAltroRawStream::Reset()
 
   fPosition = fCount = fBunchLength = 0;
 
-  fDDLNumber = fPrevDDLNumber = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
+  fRCUTrailerData = NULL;
+  fRCUTrailerSize = 0;
+
+  fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
 
   if (fRawReader) fRawReader->Reset();
 
@@ -111,6 +126,7 @@ Bool_t AliAltroRawStream::Next()
 // returns kFALSE if there is no digit left
 
   fPrevDDLNumber = fDDLNumber;
+  fPrevRCUId = fRCUId;
   fPrevHWAddress = fHWAddress;
   fPrevTime = fTime;
 
@@ -125,8 +141,7 @@ Bool_t AliAltroRawStream::Next()
       fPosition = GetPosition();
     }
 
-    if (!ReadTrailer())
-      AliFatal("Incorrect trailer information !");
+    ReadTrailer();
 
     fBunchLength = 0;
   }
@@ -148,6 +163,15 @@ void AliAltroRawStream::SelectRawData(Int_t detId)
   fRawReader->Select(detId);
 }
 
+//_____________________________________________________________________________
+void AliAltroRawStream::SelectRawData(const char *detName)
+{
+  // Select the raw data for specific
+  // detector name
+  AliDebug(1,Form("Selecting raw data for detector %s",detName));
+  fRawReader->Select(detName);
+}
+
 //_____________________________________________________________________________
 UShort_t AliAltroRawStream::GetNextWord()
 {
@@ -160,13 +184,11 @@ UShort_t AliAltroRawStream::GetNextWord()
   Int_t iByte = iBit / 8;
   Int_t shift = iBit % 8;
 
-  // recalculate the byte numbers and the shift because
-  // the raw data is written as integers where the high bits are filled first
+  // the raw data is written as integers where the low bits are filled first
   // -> little endian is assumed here !
-  Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
+  Int_t iByteLow = iByte;
   iByte++;
-  Int_t iByteLow  = 4 * (iByte / 4) + 3 - (iByte % 4);
-  shift = 6 - shift;
+  Int_t iByteHigh  = iByte;
   return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
 }
 
@@ -184,21 +206,47 @@ Bool_t AliAltroRawStream::ReadTrailer()
   UShort_t temp;
   Int_t nFillWords = 0;
   while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
-  if (nFillWords == 0)
-    AliFatal("Incorrect trailer found ! Expected 0x2AA not found !");
+  if (nFillWords == 0) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0x2AA");
+    //    PrintDebug();
+    AliWarning("Incorrect trailer found ! Expected 0x2AA not found !");
+    // trying to recover and find the next bunch
+    while ((fPosition > 5) && (temp != 0x2AA)) temp = GetNextWord();
+    if (temp != 0x2AA) {
+      fCount = fPosition = 0;
+      return kFALSE;
+    }
+    temp = GetNextWord();
+  }
 
   //Then read the trailer
-  if (fPosition <= 4)
-    AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition));
+  if (fPosition < 5) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,Form("size %d < 5",
+                                                   fPosition));
+    //    PrintDebug();
+    AliWarning(Form("Incorrect raw data size ! Expected at least 5 words but found %d !",fPosition));
+    fCount = fPosition = 0;
+    return kFALSE;
+  }
 
   fCount = (temp << 4) & 0x3FF;
-  if ((temp >> 6) != 0xA)
-    AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6));
+  if ((temp >> 6) != 0xA) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0xA");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! Expecting 0xA but found 0x%x !",temp >> 6));
+    fCount = 0;
+    return kFALSE;
+  }
 
   temp = GetNextWord();
   fHWAddress = (temp & 0x3) << 10;
-  if (((temp >> 2) & 0xF) != 0xA)
-    AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF));
+  if (((temp >> 2) & 0xF) != 0xA) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no second 0xA");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! Expecting second 0xA but found 0x%x !",(temp >> 2) & 0xF));
+    fCount = 0;
+    return kFALSE;
+  }
   fCount |= ((temp & 0x3FF) >> 6);
   if (fCount == 0) return kFALSE;
 
@@ -235,15 +283,21 @@ void AliAltroRawStream::ReadBunch()
 {
   // Read altro payload in 
   // backward direction
-  if (fPosition <= 0)
-    AliFatal("Could not read bunch length !");
+  if (fPosition <= 0) {
+    fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
+    //    PrintDebug();
+    AliWarning("Could not read bunch length !");
+  }
 
   fBunchLength = GetNextWord() - 2;
   fTimeBunch = fBunchLength;
   fCount--;
 
-  if (fPosition <= 0)
-    AliFatal("Could not read time bin !");
+  if (fPosition <= 0) {
+    fRawReader->AddMinorErrorLog(kTimeBinReadErr,"");
+    //    PrintDebug();
+    AliWarning("Could not read time bin !");
+  }
 
   fTime = GetNextWord();
   fCount--;
@@ -255,8 +309,11 @@ void AliAltroRawStream::ReadBunch()
 void AliAltroRawStream::ReadAmplitude()
 {
   // Read next time bin amplitude
-  if (fPosition <= 0)
-    AliFatal("Could not read sample amplitude !");
+  if (fPosition <= 0) {
+    fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
+    //    PrintDebug();
+    AliWarning("Could not read sample amplitude !");
+  }
 
   fSignal = GetNextWord();
   fCount--;
@@ -270,7 +327,220 @@ Int_t AliAltroRawStream::GetPosition()
 {
   // Sets the position in the
   // input stream
-  if (((fRawReader->GetDataSize() * 8) % 10) != 0)
-    AliFatal(Form("Incorrect raw data size ! %d words are found !",fRawReader->GetDataSize()));
-  return (fRawReader->GetDataSize() * 8) / 10;
+  // Read the RCU trailer
+  // This includes the trailer size,
+  // RCU identifier and raw data payload.
+  // The RCU trailer format is described
+  // in details in the RCU manual.
+
+  if (!fIsOldRCUFormat) {
+    // First read 32-bit word with the
+    // trailer size (22 bits) and RCU ID (the rest)
+    Int_t index = fRawReader->GetDataSize();
+    UInt_t word = Get32bitWord(index);
+    fRCUId = (Int_t)(word >> 22);
+    Int_t trailerSize = (word & 0x3FFFFF);
+
+    // Now read the beginning of the trailer
+    // where the payload size is written
+    if (trailerSize < 2) {
+      PrintDebug();
+      AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4));
+    }
+    fRCUTrailerSize = (trailerSize-2)*4;
+    index -= fRCUTrailerSize;
+    if (index < 4) {
+      PrintDebug();
+      AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
+                   trailerSize*4,
+                   fRawReader->GetDataSize()));
+    }
+    fRCUTrailerData = fData + index;
+    Int_t position = Get32bitWord(index);
+    // The size is specified in a number of 40bits
+    // Therefore we need to transform it to number of bytes
+    position *= 5;
+
+    // Check the consistency of the header and trailer
+    if ((fRawReader->GetDataSize() - trailerSize*4) != position) {
+      PrintDebug();
+      AliFatal(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
+                   fRawReader->GetDataSize(),
+                   trailerSize*4,
+                   position));
+    }
+
+    return position * 8 / 10;
+  }
+  else {
+    // In case of the Old RCU trailer format
+    // we have to read just the size of altro payload
+    // in units of 40-bit words
+    Int_t index = fRawReader->GetDataSize();
+    Int_t position = Get32bitWord(index);
+
+    fRCUId = -1;
+    fRCUTrailerSize = 0;
+    fRCUTrailerData = NULL;
+
+    // The size is specified in a number of 40bits
+    // Therefore we need to transform it to number of bytes
+    position *= 5;
+
+    if (!fIsShortDataHeader) {
+
+      // Check the consistency of the header and trailer
+      if ((fRawReader->GetDataSize() - 4) != position) {
+       fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
+                                                            fRawReader->GetDataSize()-4,
+                                                            position));
+       //      PrintDebug();
+       AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
+                       fRawReader->GetDataSize()-4,
+                       position));
+       position = fRawReader->GetDataSize()-4;
+      }
+    }
+    else {
+      // Check the consistency of the header and trailer
+      // In this case the header is shorter by 4 bytes
+      if (fRawReader->GetDataSize() != position) {
+       fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
+                                                            fRawReader->GetDataSize(),
+                                                            position));
+       //      PrintDebug();
+       AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
+                       fRawReader->GetDataSize(),
+                       position));
+       position = fRawReader->GetDataSize();
+      }
+
+      // 7 32-bit words Common Data Header
+      // therefore we have to shift back by 4 bytes
+      // the pointer to the raw data payload
+      fData -= 4;
+    }
+     
+    // Return the position in units of 10-bit words
+    return position*8/10;
+  }
+}
+
+//_____________________________________________________________________________
+UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
+{
+  // This method returns the 32 bit word at a given
+  // position inside the raw data payload.
+  // The 'index' points to the beginning of the next word.
+  // The method is supposed to be endian (platform)
+  // independent.
+  if (!fData) {
+    PrintDebug();
+    AliFatal("Raw data paylod buffer is not yet initialized !");
+  }
+
+  if (index < 4) {
+    fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
+    //    PrintDebug();
+    AliWarning(Form("Invalid raw data payload position (%d) !",index));
+  }
+
+  UInt_t word = 0;
+  word  = fData[--index] << 24;
+  word |= fData[--index] << 16;
+  word |= fData[--index] << 8;
+  word |= fData[--index];
+
+  return word;
+}
+
+//_____________________________________________________________________________
+Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
+{
+  // Return a pointer to the RCU trailer
+  // data. Should be called always after
+  // the RCU trailer was already processed
+  // in the GetPosition() method
+  if (!fRCUTrailerSize || !fRCUTrailerData) {
+    AliError("No valid RCU trailer data is found !");
+    data = NULL;
+    return kFALSE;
+  }
+
+  data = fRCUTrailerData;
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void AliAltroRawStream::PrintDebug() const
+{
+  // The method prints all the available
+  // debug information.
+  // Its is used in case of decoding errors.
+
+  AliError("Start of debug printout\n--------------------");
+
+  Dump();
+  if (fRawReader) fRawReader->Dump();
+
+  AliError("End of debug printout\n--------------------");
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetBranch() const
+{
+  // The method provides the RCU branch index (0 or 1)
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 11) & 0x1);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetFEC() const
+{
+  // The method provides the front-end card index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 7) & 0xF);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetAltro() const
+{
+  // The method provides the altro chip index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 4) & 0x7);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetChannel() const
+{
+  // The method provides the channel index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return (fHWAddress & 0xF);
+}
+
+//_____________________________________________________________________________
+void AliAltroRawStream::AddMappingErrorLog(const char *message)
+{
+  // Signal a mapping error
+  // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
+  // classes in order to log an error related to bad altro mapping
+
+  if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
 }