ClassImp(AliAltroBuffer)
//_____________________________________________________________________________
-AliAltroBuffer::AliAltroBuffer(const char* fileName, const AliAltroMapping *mapping):
+AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping):
fShift(0),
fCurrentCell(0),
- fFreeCellBuffer(0),
+ fFreeCellBuffer(16),
fVerbose(0),
fFile(NULL),
fDataHeaderPos(0),
//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);
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;
}
}
-
-//_____________________________________________________________________________
-void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber,
- Int_t rowNumber, Int_t secNumber)
-{
-//Writes a trailer of 40 bits
-
- Int_t num = fFreeCellBuffer % 4;
- for(Int_t i = 0; i < num; i++) {
- FillBuffer(0x2AA);
- }//end for
- FillBuffer(wordsNumber);
- FillBuffer(padNumber);
- FillBuffer(rowNumber);
- FillBuffer(secNumber);
-}
-
//_____________________________________________________________________________
void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
Int_t rowNumber, Int_t secNumber)
//Writes a trailer of 40 bits
if (!fMapping) {
- AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!");
- return WriteDummyTrailer(wordsNumber,padNumber,
- rowNumber,secNumber);
+ AliFatal("No ALTRO mapping information is loaded!");
}
Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber);
//Write all ADC values and the trailer of a channel
Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
// write the trailer
- WriteTrailer(nWords, padNumber, rowNumber, secNumber);
+ if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber);
}
//_____________________________________________________________________________
//Write all ADC values and the trailer of a channel
Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold);
// write the trailer
- WriteTrailer(nWords, hwAddress);
+ if (nWords) WriteTrailer(nWords, hwAddress);
}
//_____________________________________________________________________________
}
//_____________________________________________________________________________
-void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
+void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t /*compressed*/)
{
//Write a (dummy or real) DDL data header,
-//set the compression bit if compressed
+//set the attributes according to the RCU version
AliRawDataHeaderSim header;
if (dummy) {
fDataHeaderPos = fFile->Tellp();
fFile->WriteBuffer((char*)(&header), sizeof(header));
} else {
+ UChar_t rcuVer = WriteRCUTrailer(0);
UInt_t currentFilePos = fFile->Tellp();
fFile->Seekp(fDataHeaderPos);
- header.fSize = currentFilePos-fDataHeaderPos;
- header.SetAttribute(0); // valid data
- if (compressed) header.SetAttribute(1);
+ header.fSize = 0xFFFFFFFF; // RCU can't write raw-data size so we always get an 'invalid' size field
+ header.fAttributesSubDetectors |= (rcuVer << 24);
fFile->WriteBuffer((char*)(&header), sizeof(header));
fFile->Seekp(currentFilePos);
}
}
+
+//_____________________________________________________________________________
+UChar_t 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 0;
+ }
+
+ // 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 & 0x7F);
+ buffer |= ((rcuId & 0x1FF) << 7);
+ buffer |= 0xAAAAU << 16;
+ fFile->WriteBuffer((char *)(&buffer),sizeof(UInt_t));
+
+ return 0;
+}