X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=RAW%2FAliAltroBuffer.cxx;h=815cfd67b0e7cc7d4d5af5cbe7f32144135fbf25;hb=bd0c5c47f9732a4b475118f8839cd81745291868;hp=d9e6350a236b6b5a5ae6bb050866d5c586be6917;hpb=16e29964cd3f9eebb0ba2d3724f76e3bb66ec0b4;p=u%2Fmrichter%2FAliRoot.git diff --git a/RAW/AliAltroBuffer.cxx b/RAW/AliAltroBuffer.cxx index d9e6350a236..815cfd67b0e 100644 --- a/RAW/AliAltroBuffer.cxx +++ b/RAW/AliAltroBuffer.cxx @@ -19,66 +19,32 @@ // to read and write digits // To be used in Alice Data Challenges // and in the compression of the RAW data -// Author: D.Favretto #include "AliAltroBuffer.h" #include "AliAltroMapping.h" -#include "AliRawDataHeader.h" +#include "AliRawDataHeaderSim.h" #include "AliLog.h" -#include -#include +#include "AliFstream.h" +//#include ClassImp(AliAltroBuffer) //_____________________________________________________________________________ -AliAltroBuffer::AliAltroBuffer(const char* fileName, Int_t flag, const AliAltroMapping *mapping): +AliAltroBuffer::AliAltroBuffer(const char* fileName, AliAltroMapping *mapping): fShift(0), fCurrentCell(0), - fFreeCellBuffer(0), - fFlag(flag), + fFreeCellBuffer(16), fVerbose(0), fFile(NULL), - fMaskBackward(0xFF), - fFilePosition(0), - fFileEnd(0), fDataHeaderPos(0), - fEndingFillWords(0), fMapping(mapping) { -//if flag = 1 the actual object is used in the write mode -//if flag = 0 the actual object is used in the read mode - //the buffer is cleaned for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0; - if (flag) { - fFreeCellBuffer = 16; - fShift = 32; - //open the output file -#ifndef __DECCXX - fFile = new fstream(fileName, ios::binary|ios::out); -#else - fFile = new fstream(fileName, ios::out); -#endif - } else { - //open the input file -#ifndef __DECCXX - fFile = new fstream(fileName, ios::binary|ios::in); -#else - fFile = new fstream(fileName, ios::in); -#endif - if (!fFile) { - Error("AliAltroBuffer", "File doesn't exist: %s", fileName); - return; - } - fShift = 0; - //To get the file dimension (position of the last element in term of bytes) - fFile->seekg(0, ios::end); - fFilePosition = fFile->tellg(); - fFileEnd = fFilePosition; - fFile->seekg(0); - } + //open the output file + fFile = new AliFstream(fileName); } @@ -87,12 +53,10 @@ AliAltroBuffer::~AliAltroBuffer() { // destructor - if (fFlag) { - //Flush out the Buffer content at the end only if Buffer wasn't completely filled - Flush(); - if (fVerbose) Info("~AliAltroBuffer", "File Created"); - }//end if - fFile->close(); + //Flush out the Buffer content at the end only if Buffer wasn't completely filled + Flush(); + if (fVerbose) Info("~AliAltroBuffer", "File Created"); + delete fFile; } @@ -103,14 +67,9 @@ AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source): fShift(source.fShift), fCurrentCell(source.fCurrentCell), fFreeCellBuffer(source.fFreeCellBuffer), - fFlag(source.fFlag), fVerbose(source.fVerbose), fFile(NULL), - fMaskBackward(source.fMaskBackward), - fFilePosition(source.fFilePosition), - fFileEnd(source.fFileEnd), fDataHeaderPos(source.fDataHeaderPos), - fEndingFillWords(source.fEndingFillWords), fMapping(source.fMapping) { // Copy Constructor @@ -127,98 +86,6 @@ AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/) return *this; } - -//_____________________________________________________________________________ -Int_t AliAltroBuffer::GetNext() -{ -//It reads a 10 bits word in forward dicection from the Buffer. -//A new Buffer is read from the file only when Buffer is empty. -//If there aren't elements anymore -1 is returned otherwise -//the next element is returned - - UInt_t mask = 0xFFC00000; - UInt_t temp; - UInt_t value; - if (!fShift) { - if (fFile->tellg() >= (Int_t)fFileEnd) return -1; - if (fFile->read((char*)fBuffer, sizeof(UInt_t)*5)) { - fCurrentCell = 0; - fShift = 22; - value = fBuffer[fCurrentCell] & mask; - value = value >> 22; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; - return value; - } else { - return -1; - } - } else { - if (fShift >= 10) { - value = fBuffer[fCurrentCell] & mask; - value = value >> 22; - fShift -= 10; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; - } else { - value = fBuffer[fCurrentCell] & mask; - fCurrentCell++; - temp = fBuffer[fCurrentCell]; - temp = temp >> fShift; - temp = temp & mask; - value = value | temp; - value = value >> 22; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << (10-fShift); - fShift += 22; - } - return value; - }//end else -} - -//_____________________________________________________________________________ -Int_t AliAltroBuffer::GetNextBackWord() -{ -//It reads a 10 bits word in backward dicection from the Buffer. -//A new Buffer is read from the file only when Buffer is empty. -//If there aren't elements anymore -1 is returned otherwise -//the next element is returned - - UInt_t mask = 0x3FF; - UInt_t temp; - UInt_t value; - if (!fShift) { - if (fFilePosition > fDataHeaderPos){ - fFilePosition -= sizeof(UInt_t)*5; - fFile->seekg(fFilePosition); - fFile->read((char*)fBuffer, sizeof(UInt_t)*5); - - fCurrentCell = 4; - fShift = 22; - fMaskBackward = 0xFF; - value = fBuffer[fCurrentCell] & mask; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; - return value; - } else { - fFile->seekg(fDataHeaderPos); - return -1; - } - } else { - if (fShift >= 10) { - value = fBuffer[fCurrentCell] & mask; - fShift -= 10; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; - } else { - value = fBuffer[fCurrentCell]; - fCurrentCell--; - temp = fBuffer[fCurrentCell] & mask; - temp = temp & fMaskBackward; - fMaskBackward = fMaskBackward >> 2; - temp = temp << fShift; - value = value | temp; - fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> (10-fShift); - fShift = 22 + fShift; - } - return value; - }//end else -} - //_____________________________________________________________________________ void AliAltroBuffer::Flush() { @@ -241,45 +108,27 @@ 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->write((char*)fBuffer, sizeof(UInt_t)*5); + 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) @@ -287,119 +136,70 @@ void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber, //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); + if (hwAddress == -1) + AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber)); + WriteTrailer(wordsNumber,hwAddress); +} + +//_____________________________________________________________________________ +void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress) +{ +//Writes a trailer of 40 bits using +//a given hardware adress Int_t num = fFreeCellBuffer % 4; for(Int_t i = 0; i < num; i++) { FillBuffer(0x2AA); }//end for Int_t temp; - temp = 0x2AA; - FillBuffer(temp); - temp = 0xA << 6; - temp |= ((wordsNumber & 0x3FF) >> 4); + temp = hwAddress & 0x3FF; FillBuffer(temp); + temp = (wordsNumber << 6) & 0x3FF; temp |= (0xA << 2); + temp |= ((hwAddress >> 10) & 0x3); + FillBuffer(temp); - Short_t hwAdress = fMapping->GetHWAdress(rowNumber,padNumber,secNumber); - if (hwAdress == -1) - AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber)); - - temp |= (hwAdress >> 10) & 0x3; + temp = 0xA << 6; + temp |= ((wordsNumber & 0x3FF) >> 4); FillBuffer(temp); - temp = hwAdress & 0x3FF; + + temp = 0x2AA; FillBuffer(temp); } //_____________________________________________________________________________ -Bool_t AliAltroBuffer::ReadDummyTrailer(Int_t& wordsNumber, Int_t& padNumber, - Int_t& rowNumber, Int_t& secNumber) +void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, + Int_t secNumber, + Int_t nTimeBins, const Int_t* adcValues, + Int_t threshold) { -//Read a dummy trailer of 40 bits in the forward reading mode - - wordsNumber = GetNext(); - if (wordsNumber == -1) return kFALSE; - padNumber = GetNext(); - if (padNumber == -1) return kFALSE; - rowNumber = GetNext(); - if (rowNumber == -1) return kFALSE; - secNumber = GetNext(); - if (secNumber == -1) return kFALSE; - return kTRUE; + //Write all ADC values and the trailer of a channel + Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); + // write the trailer + if (nWords) WriteTrailer(nWords, padNumber, rowNumber, secNumber); } //_____________________________________________________________________________ -Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Int_t& padNumber, - Int_t& rowNumber, Int_t& secNumber) +void AliAltroBuffer::WriteChannel(Short_t hwAddress, + Int_t nTimeBins, const Int_t* adcValues, + Int_t threshold) { -//Read a trailer of 40 bits in the forward reading mode - if (!fMapping) { - AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); - return ReadDummyTrailer(wordsNumber,padNumber, - rowNumber,secNumber); - } - - Int_t temp = GetNext(); - if (temp != 0x2AA) - AliFatal(Form("Incorrect trailer found ! Expecting 0x2AA but found %x !",temp)); - - temp = GetNext(); - if ((temp >> 6) != 0xA) - AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); - wordsNumber = (temp << 4) & 0x3FF; - - temp = GetNext(); - wordsNumber |= (temp >> 6); - if ((temp & 0xF) != 0xA) - AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",temp >> 6)); - Int_t hwAdress = (temp & 0x3) << 10; - - temp = GetNext(); - hwAdress |= temp; - - rowNumber = fMapping->GetPadRow(hwAdress); - padNumber = fMapping->GetPad(hwAdress); - secNumber = fMapping->GetSector(hwAdress); - return kTRUE; + //Write all ADC values and the trailer of a channel + Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); + // write the trailer + if (nWords) WriteTrailer(nWords, hwAddress); } //_____________________________________________________________________________ -Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber, - Int_t& padNumber, - Int_t& rowNumber, Int_t& secNumber) -{ -//Read a trailer of 40 bits in the backward reading mode - - Int_t temp; - fEndingFillWords = 0; - do { - temp = GetNextBackWord(); - fEndingFillWords++; - if (temp == -1) return kFALSE; - } while (temp == 0x2AA); - fEndingFillWords--; - secNumber = temp; - rowNumber = GetNextBackWord(); - if (rowNumber == -1) return kFALSE; - padNumber = GetNextBackWord(); - if (padNumber == -1) return kFALSE; - wordsNumber = GetNextBackWord(); - if (wordsNumber == -1) return kFALSE; - return kTRUE; -} - - -//_____________________________________________________________________________ -void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, - Int_t secNumber, - Int_t nTimeBins, const Int_t* adcValues, - Int_t threshold) +Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues, + Int_t threshold) { -//Write all ADC values and the trailer of a channel + //Write all ADC values + //Return number of words written Int_t nWords = 0; Int_t timeBin = -1; @@ -428,45 +228,67 @@ void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, nWords += 2; } - // write the trailer - WriteTrailer(nWords, padNumber, rowNumber, secNumber); + return nWords; } - //_____________________________________________________________________________ -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 - AliRawDataHeader header; + AliRawDataHeaderSim header; if (dummy) { //if size=0 it means that this data header is a dummy data header - fDataHeaderPos = fFile->tellp(); - fFile->write((char*)(&header), sizeof(header)); + fDataHeaderPos = fFile->Tellp(); + fFile->WriteBuffer((char*)(&header), sizeof(header)); } else { - UInt_t currentFilePos = fFile->tellp(); - fFile->seekp(fDataHeaderPos); - header.fSize = currentFilePos-fDataHeaderPos; - header.SetAttribute(0); // valid data - if (compressed) header.SetAttribute(1); - fFile->write((char*)(&header), sizeof(header)); - fFile->seekp(currentFilePos); + UChar_t rcuVer = WriteRCUTrailer(0); + UInt_t currentFilePos = fFile->Tellp(); + fFile->Seekp(fDataHeaderPos); + 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); } } //_____________________________________________________________________________ -Bool_t AliAltroBuffer::ReadDataHeader() +UChar_t AliAltroBuffer::WriteRCUTrailer(Int_t rcuId) { -//Read the DDL data header at the beginning of the file, -//returns true in case of valid data - - AliRawDataHeader header; - UInt_t currentPos = fFile->tellp(); - fFile->seekp(0); - if (!fFile->read((char*)(&header), sizeof(header))) return kFALSE; - fDataHeaderPos = fFile->tellp(); - fFile->seekp(currentPos); - return header.TestAttribute(0); -} + // 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(AliRawDataHeaderV3); + + 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; +}