1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 // Interface to the Altro format
19 // to read and write digits
20 // To be used in Alice Data Challenges
21 // and in the compression of the RAW data
24 #include "AliAltroBuffer.h"
25 #include "AliRawDataHeader.h"
26 #include <Riostream.h>
30 ClassImp(AliAltroBuffer)
33 //_____________________________________________________________________________
34 AliAltroBuffer::AliAltroBuffer(const char* fileName, Int_t flag):
47 //if flag = 1 the actual object is used in the write mode
48 //if flag = 0 the actual object is used in the read mode
50 //the buffer is cleaned
51 for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
56 //open the output file
58 fFile = new fstream(fileName, ios::binary|ios::out);
60 fFile = new fstream(fileName, ios::out);
65 fFile = new fstream(fileName, ios::binary|ios::in);
67 fFile = new fstream(fileName, ios::in);
70 Error("AliAltroBuffer", "File doesn't exist: %s", fileName);
74 //To get the file dimension (position of the last element in term of bytes)
75 fFile->seekg(0, ios::end);
76 fFilePosition = fFile->tellg();
77 fFileEnd = fFilePosition;
82 //_____________________________________________________________________________
83 AliAltroBuffer::~AliAltroBuffer()
88 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
90 if (fVerbose) Info("~AliAltroBuffer", "File Created");
96 //_____________________________________________________________________________
97 AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
99 fShift(source.fShift),
100 fCurrentCell(source.fCurrentCell),
101 fFreeCellBuffer(source.fFreeCellBuffer),
103 fVerbose(source.fVerbose),
105 fMaskBackward(source.fMaskBackward),
106 fFilePosition(source.fFilePosition),
107 fFileEnd(source.fFileEnd),
108 fDataHeaderPos(source.fDataHeaderPos),
109 fEndingFillWords(source.fEndingFillWords)
113 Fatal("AliAltroBuffer", "copy constructor not implemented");
116 //_____________________________________________________________________________
117 AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
121 Fatal("operator =", "assignment operator not implemented");
126 //_____________________________________________________________________________
127 Int_t AliAltroBuffer::GetNext()
129 //It reads a 10 bits word in forward dicection from the Buffer.
130 //A new Buffer is read from the file only when Buffer is empty.
131 //If there aren't elements anymore -1 is returned otherwise
132 //the next element is returned
134 UInt_t mask = 0xFFC00000;
138 if (fFile->tellg() >= (Int_t)fFileEnd) return -1;
139 if (fFile->read((char*)fBuffer, sizeof(UInt_t)*5)) {
142 value = fBuffer[fCurrentCell] & mask;
144 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10;
151 value = fBuffer[fCurrentCell] & mask;
154 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10;
156 value = fBuffer[fCurrentCell] & mask;
158 temp = fBuffer[fCurrentCell];
159 temp = temp >> fShift;
161 value = value | temp;
163 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << (10-fShift);
170 //_____________________________________________________________________________
171 Int_t AliAltroBuffer::GetNextBackWord()
173 //It reads a 10 bits word in backward dicection from the Buffer.
174 //A new Buffer is read from the file only when Buffer is empty.
175 //If there aren't elements anymore -1 is returned otherwise
176 //the next element is returned
182 if (fFilePosition > fDataHeaderPos){
183 fFilePosition -= sizeof(UInt_t)*5;
184 fFile->seekg(fFilePosition);
185 fFile->read((char*)fBuffer, sizeof(UInt_t)*5);
189 fMaskBackward = 0xFF;
190 value = fBuffer[fCurrentCell] & mask;
191 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10;
194 fFile->seekg(fDataHeaderPos);
199 value = fBuffer[fCurrentCell] & mask;
201 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10;
203 value = fBuffer[fCurrentCell];
205 temp = fBuffer[fCurrentCell] & mask;
206 temp = temp & fMaskBackward;
207 fMaskBackward = fMaskBackward >> 2;
208 temp = temp << fShift;
209 value = value | temp;
210 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> (10-fShift);
211 fShift = 22 + fShift;
217 //_____________________________________________________________________________
218 void AliAltroBuffer::Flush()
220 // Flushes the Buffer content
221 if (fFreeCellBuffer != 16) {
222 Int_t temp = fFreeCellBuffer;
223 for (Int_t i = 0; i < temp; i++){
229 //_____________________________________________________________________________
230 void AliAltroBuffer::FillBuffer(Int_t val)
232 //Fills the Buffer with 16 ten bits words and write into a file
234 if ((val > 0x3FF) || (val < 0)) {
235 Error("FillBuffer", "Value out of range (10 bits): %d", val);
241 val = val >> (10-fShift);
242 fBuffer[fCurrentCell] |= val;
249 fBuffer[fCurrentCell] |= val;
251 //Buffer is written into a file
252 fFile->write((char*)fBuffer, sizeof(UInt_t)*5);
254 for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
257 fFreeCellBuffer = 16;
262 //_____________________________________________________________________________
263 void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
264 Int_t rowNumber, Int_t secNumber)
266 //Writes a trailer of 40 bits
268 Int_t num = fFreeCellBuffer % 4;
269 for(Int_t i = 0; i < num; i++) {
272 FillBuffer(wordsNumber);
273 FillBuffer(padNumber);
274 FillBuffer(rowNumber);
275 FillBuffer(secNumber);
278 //_____________________________________________________________________________
279 Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Int_t& padNumber,
280 Int_t& rowNumber, Int_t& secNumber)
282 //Read a trailer of 40 bits in the forward reading mode
284 wordsNumber = GetNext();
285 if (wordsNumber == -1) return kFALSE;
286 padNumber = GetNext();
287 if (padNumber == -1) return kFALSE;
288 rowNumber = GetNext();
289 if (rowNumber == -1) return kFALSE;
290 secNumber = GetNext();
291 if (secNumber == -1) return kFALSE;
295 //_____________________________________________________________________________
296 Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber,
298 Int_t& rowNumber, Int_t& secNumber)
300 //Read a trailer of 40 bits in the backward reading mode
303 fEndingFillWords = 0;
305 temp = GetNextBackWord();
307 if (temp == -1) return kFALSE;
308 } while (temp == 0x2AA);
311 rowNumber = GetNextBackWord();
312 if (rowNumber == -1) return kFALSE;
313 padNumber = GetNextBackWord();
314 if (padNumber == -1) return kFALSE;
315 wordsNumber = GetNextBackWord();
316 if (wordsNumber == -1) return kFALSE;
321 //_____________________________________________________________________________
322 void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber,
324 Int_t nTimeBins, const Int_t* adcValues,
327 //Write all ADC values and the trailer of a channel
331 Int_t bunchLength = 0;
333 // loop over time bins
334 for (Int_t iTime = 0; iTime < nTimeBins; iTime++) {
335 if (adcValues[iTime] >= threshold) { // ADC value above threshold
336 FillBuffer(adcValues[iTime]);
341 } else if (timeBin >= 0) { // end of bunch
343 FillBuffer(bunchLength + 2);
350 if (timeBin >= 0) { // end of bunch
352 FillBuffer(bunchLength + 2);
357 WriteTrailer(nWords, padNumber, rowNumber, secNumber);
361 //_____________________________________________________________________________
362 void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
364 //Write a (dummy or real) DDL data header,
365 //set the compression bit if compressed
367 AliRawDataHeader header;
369 //if size=0 it means that this data header is a dummy data header
370 fDataHeaderPos = fFile->tellp();
371 fFile->write((char*)(&header), sizeof(header));
373 UInt_t currentFilePos = fFile->tellp();
374 fFile->seekp(fDataHeaderPos);
375 header.fSize = currentFilePos-fDataHeaderPos;
376 header.SetAttribute(0); // valid data
377 if (compressed) header.SetAttribute(1);
378 fFile->write((char*)(&header), sizeof(header));
379 fFile->seekp(currentFilePos);
383 //_____________________________________________________________________________
384 Bool_t AliAltroBuffer::ReadDataHeader()
386 //Read the DDL data header at the beginning of the file,
387 //returns true in case of valid data
389 AliRawDataHeader header;
390 UInt_t currentPos = fFile->tellp();
392 if (!fFile->read((char*)(&header), sizeof(header))) return kFALSE;
393 fDataHeaderPos = fFile->tellp();
394 fFile->seekp(currentPos);
395 return header.TestAttribute(0);