New version of the Altro raw data coding and decoding. Two basic changes. 1. The...
authorcvetan <cvetan@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 May 2006 14:42:10 +0000 (14:42 +0000)
committercvetan <cvetan@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 May 2006 14:42:10 +0000 (14:42 +0000)
RAW/AliAltroBuffer.cxx
RAW/AliAltroBuffer.h
RAW/AliAltroRawStream.cxx
RAW/AliAltroRawStream.h

index 011c30c11de6f3391be8fdce95c91f8e44f5e684..a06927f834ff1ac5a0aec5488633290fe48f6166 100644 (file)
@@ -34,7 +34,7 @@ ClassImp(AliAltroBuffer)
 AliAltroBuffer::AliAltroBuffer(const char* fileName, const AliAltroMapping *mapping):
   fShift(0),
   fCurrentCell(0),
-  fFreeCellBuffer(0),
+  fFreeCellBuffer(16),
   fVerbose(0),
   fFile(NULL),
   fDataHeaderPos(0),
@@ -43,8 +43,6 @@ AliAltroBuffer::AliAltroBuffer(const char* fileName, const AliAltroMapping *mapp
   //the buffer is cleaned 
   for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
 
-  fFreeCellBuffer = 16;
-  fShift = 32; 
   //open the output file
   fFile = new AliFstream(fileName);
 
@@ -110,23 +108,22 @@ void AliAltroBuffer::FillBuffer(Int_t val)
     val = 0x3FF;
   }
   fFreeCellBuffer--;
-  if (fShift < 10) {
-    Int_t temp = val;
-    val = val >> (10-fShift);
-    fBuffer[fCurrentCell] |= val;
+
+  fBuffer[fCurrentCell] |= (val << fShift);
+  fShift += 10;
+
+  if (fShift > 32) {
     fCurrentCell++;
-    fShift += 32;
-    val = temp;
+    fShift -= 32;
+    fBuffer[fCurrentCell] |= (val >> (10 - fShift));
   }
-  fShift -= 10;
-  val = val << fShift;
-  fBuffer[fCurrentCell] |= val;
-  if (!fShift) {
+
+  if (fShift == 32) {
     //Buffer is written into a file
     fFile->WriteBuffer((char*)fBuffer, sizeof(UInt_t)*5);
     //Buffer is empty
     for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
-    fShift = 32;
+    fShift = 0;
     fCurrentCell = 0;
     fFreeCellBuffer = 16;
   }
@@ -265,6 +262,7 @@ void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
     fDataHeaderPos = fFile->Tellp();
     fFile->WriteBuffer((char*)(&header), sizeof(header));
   } else {
+    WriteRCUTrailer(0);
     UInt_t currentFilePos = fFile->Tellp();
     fFile->Seekp(fDataHeaderPos);
     header.fSize = currentFilePos-fDataHeaderPos;
@@ -274,3 +272,41 @@ void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
     fFile->Seekp(currentFilePos);
   }
 }
+
+//_____________________________________________________________________________
+void AliAltroBuffer::WriteRCUTrailer(Int_t rcuId)
+{
+  // Writes the RCU trailer
+  // rcuId the is serial number of the corresponding
+  // RCU. The basic format of the trailer can be
+  // found in the RCU manual.
+  // This method should be called at the end of
+  // raw data writing.
+
+  UInt_t currentFilePos = fFile->Tellp();
+  UInt_t size = currentFilePos-fDataHeaderPos;
+  size -= sizeof(AliRawDataHeader);
+  
+  if ((size % 5) != 0) {
+    AliFatal(Form("The current raw data payload is not a mutiple of 5 (%d) ! Can not write the RCU trailer !",size));
+    return;
+  }
+
+  // Now put the size in unit of number of 40bit words
+  size /= 5;
+  fFile->WriteBuffer((char *)(&size),sizeof(UInt_t));
+
+  // Now several not yet full defined fields
+  // In principle they are supposed to contain
+  // information about the sampling frequency,
+  // L1 phase, list of 'dead' FECs, etc.
+  //  UInt_t buffer[n];
+  //  fFile->WriteBuffer((char *)(buffer),sizeof(UInt_t)*n);
+  
+  //  Now the RCU identifier and size of the trailer
+  //  FOr the moment the triler size is 2 32-bit words
+  UInt_t buffer = 2;
+  buffer |= ((rcuId & 0x3FF) << 22);
+  fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));
+
+}
index e4eab37245cb0c409e7a592a0975df89fdb701a7..edf48132a1c63feb5568a8e39880b416c125b89e 100644 (file)
@@ -56,6 +56,10 @@ class AliAltroBuffer: public TObject {
 
   void  WriteDataHeader(Bool_t dummy, Bool_t compressed);
   //this method is used to write the data header
+
+  void  WriteRCUTrailer(Int_t rcuId);
+  //this method is used to write the RCU trailer
+
   void  SetVerbose(Int_t val) {fVerbose = val;}
   //this method is used to set the verbose level 
   //level  0 no output messages
index bb5ba558c9344d504c48cc193cce293a939e22f7..be92382744c0d527e5af307e43931d067f76799c 100644 (file)
@@ -38,6 +38,8 @@ AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
   fNoAltroMapping(kTRUE),
   fDDLNumber(-1),
   fPrevDDLNumber(-1),
+  fRCUId(-1),
+  fPrevRCUId(-1),
   fHWAddress(-1),
   fPrevHWAddress(-1),
   fTime(-1),
@@ -48,7 +50,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;
@@ -60,6 +64,8 @@ AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
   fNoAltroMapping(kTRUE),
   fDDLNumber(-1),
   fPrevDDLNumber(-1),
+  fRCUId(-1),
+  fPrevRCUId(-1),
   fHWAddress(-1),
   fPrevHWAddress(-1),
   fTime(-1),
@@ -70,7 +76,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 +105,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 +122,7 @@ Bool_t AliAltroRawStream::Next()
 // returns kFALSE if there is no digit left
 
   fPrevDDLNumber = fDDLNumber;
+  fPrevRCUId = fRCUId;
   fPrevHWAddress = fHWAddress;
   fPrevTime = fTime;
 
@@ -160,13 +172,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;
 }
 
@@ -270,7 +280,81 @@ 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.
+
+  // 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)
+    AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4));
+  fRCUTrailerSize = (trailerSize-2)*4;
+  index -= fRCUTrailerSize;
+  if (index < 4)
+    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)
+    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;
+}
+
+//_____________________________________________________________________________
+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)
+    AliFatal("Raw data paylod buffer is not yet initialized !");
+  if (index < 4)
+    AliFatal(Form("Invalid raw data payload index (%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;
 }
index c391d6edd7304f0da9bb4b54304e8a0ac3ac0df4..ff9663d4a9ebe2de3e41cd52c2a4fa62cdbb14d8 100644 (file)
@@ -26,6 +26,9 @@ class AliAltroRawStream: public TObject {
     inline Int_t GetDDLNumber()  const { return fDDLNumber; }  // Provide current DDL number
     inline Int_t GetPrevDDLNumber() const { return fPrevDDLNumber; }// Provide previous DDL number
     inline Bool_t  IsNewDDLNumber() const {return (fDDLNumber != fPrevDDLNumber);};
+    inline Int_t GetRCUId()      const { return fRCUId; }      // Provide current RCU identifier
+    inline Int_t GetPrevRCUId()  const { return fPrevRCUId; }  // Provide previous RCU identifier
+    inline Bool_t  IsNewRCUId() const {return (fRCUId != fPrevRCUId);};
     inline Int_t GetHWAddress()  const { return fHWAddress; }  // Provide current hardware address
     inline Int_t GetPrevHWAddress() const { return fPrevHWAddress; }  // Provide previous hardware address
     inline Bool_t  IsNewHWAddress() const {return (fHWAddress != fPrevHWAddress) || IsNewDDLNumber();};
@@ -35,6 +38,9 @@ class AliAltroRawStream: public TObject {
     inline Int_t GetSignal()     const { return fSignal; }     // Provide signal in ADC counts
     inline Int_t GetTimeLength() const { return fTimeBunch; }  // Provide total length of current time bunch
 
+           Bool_t  GetRCUTrailerData(UChar_t*& data) const;              // Provide a pointer to RCU trailer
+    inline Int_t   GetRCUTrailerSize() const { return fRCUTrailerSize; } // Provide size of RCU trailer
+
     void SelectRawData(Int_t detId);                           // Select raw data for specific detector id
 
   protected:
@@ -52,9 +58,12 @@ class AliAltroRawStream: public TObject {
     void             ReadBunch();
     void             ReadAmplitude();
     Int_t            GetPosition();
+    UInt_t           Get32bitWord(Int_t &index);
 
     Int_t            fDDLNumber;    // index of current DDL number
-    Int_t            fPrevDDLNumber;// index of current DDL number
+    Int_t            fPrevDDLNumber;// index of previous DDL number
+    Int_t            fRCUId;        // current RCU identifier
+    Int_t            fPrevRCUId;    // previous RCU identifier
     Short_t          fHWAddress;    // current hardware address
     Short_t          fPrevHWAddress;// previous hardware address
     Int_t            fTime;         // index of current time bin
@@ -71,6 +80,9 @@ class AliAltroRawStream: public TObject {
     Int_t            fCount;        // counter of words to be read for current trailer
     Int_t            fBunchLength;  // remaining number of signal bins in the current bunch
 
+    UChar_t*         fRCUTrailerData; // pointer to RCU trailer data
+    Int_t            fRCUTrailerSize; // size of RCU trailer data in bytes
+
     ClassDef(AliAltroRawStream, 0)  // base class for reading Altro raw digits
 };