]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliAltroBuffer.cxx
Adding support for raw data events without subevent header
[u/mrichter/AliRoot.git] / RAW / AliAltroBuffer.cxx
CommitLineData
3ea47630 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
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
22// Author: D.Favretto
23
24#include "AliAltroBuffer.h"
25#include "AliRawDataHeader.h"
26#include <Riostream.h>
27#include <stdlib.h>
28
29
30ClassImp(AliAltroBuffer)
31
32
33//_____________________________________________________________________________
34AliAltroBuffer::AliAltroBuffer(const char* fileName, Int_t flag):
35 fShift(0),
36 fCurrentCell(0),
37 fFreeCellBuffer(0),
38 fFlag(flag),
39 fVerbose(0),
40 fFile(NULL),
41 fMaskBackward(0xFF),
42 fFilePosition(0),
43 fFileEnd(0),
44 fDataHeaderPos(0),
45 fEndingFillWords(0)
46{
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
49
50 //the buffer is cleaned
51 for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0;
52
53 if (flag) {
54 fFreeCellBuffer = 16;
55 fShift = 32;
56 //open the output file
57#ifndef __DECCXX
58 fFile = new fstream(fileName, ios::binary|ios::out);
59#else
60 fFile = new fstream(fileName, ios::out);
61#endif
62 } else {
63 //open the input file
64#ifndef __DECCXX
65 fFile = new fstream(fileName, ios::binary|ios::in);
66#else
67 fFile = new fstream(fileName, ios::in);
68#endif
69 if (!fFile) {
70 Error("AliAltroBuffer", "File doesn't exist: %s", fileName);
71 return;
72 }
73 fShift = 0;
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;
78 fFile->seekg(0);
79 }
80}
81
82//_____________________________________________________________________________
83AliAltroBuffer::~AliAltroBuffer()
84{
85// destructor
86
87 if (fFlag) {
88 //Flush out the Buffer content at the end only if Buffer wasn't completely filled
89 Flush();
90 if (fVerbose) Info("~AliAltroBuffer", "File Created");
91 }//end if
92 fFile->close();
93 delete fFile;
94}
95
96//_____________________________________________________________________________
97AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source):
98 TObject(source),
99 fShift(source.fShift),
100 fCurrentCell(source.fCurrentCell),
101 fFreeCellBuffer(source.fFreeCellBuffer),
102 fFlag(source.fFlag),
103 fVerbose(source.fVerbose),
104 fFile(NULL),
105 fMaskBackward(source.fMaskBackward),
106 fFilePosition(source.fFilePosition),
107 fFileEnd(source.fFileEnd),
108 fDataHeaderPos(source.fDataHeaderPos),
109 fEndingFillWords(source.fEndingFillWords)
110{
111// Copy Constructor
112
113 Fatal("AliAltroBuffer", "copy constructor not implemented");
114}
115
116//_____________________________________________________________________________
117AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/)
118{
119//Assigment operator
120
121 Fatal("operator =", "assignment operator not implemented");
122 return *this;
123}
124
125
126//_____________________________________________________________________________
127Int_t AliAltroBuffer::GetNext()
128{
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
133
134 UInt_t mask = 0xFFC00000;
135 UInt_t temp;
136 UInt_t value;
137 if (!fShift) {
138 if (fFile->tellg() >= (Int_t)fFileEnd) return -1;
139 if (fFile->read((char*)fBuffer, sizeof(UInt_t)*5)) {
140 fCurrentCell = 0;
141 fShift = 22;
142 value = fBuffer[fCurrentCell] & mask;
143 value = value >> 22;
144 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10;
145 return value;
146 } else {
147 return -1;
148 }
149 } else {
150 if (fShift >= 10) {
151 value = fBuffer[fCurrentCell] & mask;
152 value = value >> 22;
153 fShift -= 10;
154 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10;
155 } else {
156 value = fBuffer[fCurrentCell] & mask;
157 fCurrentCell++;
158 temp = fBuffer[fCurrentCell];
159 temp = temp >> fShift;
160 temp = temp & mask;
161 value = value | temp;
162 value = value >> 22;
163 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << (10-fShift);
164 fShift += 22;
165 }
166 return value;
167 }//end else
168}
169
170//_____________________________________________________________________________
171Int_t AliAltroBuffer::GetNextBackWord()
172{
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
177
178 UInt_t mask = 0x3FF;
179 UInt_t temp;
180 UInt_t value;
181 if (!fShift) {
182 if (fFilePosition > fDataHeaderPos){
183 fFilePosition -= sizeof(UInt_t)*5;
184 fFile->seekg(fFilePosition);
185 fFile->read((char*)fBuffer, sizeof(UInt_t)*5);
186
187 fCurrentCell = 4;
188 fShift = 22;
189 fMaskBackward = 0xFF;
190 value = fBuffer[fCurrentCell] & mask;
191 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10;
192 return value;
193 } else {
194 fFile->seekg(fDataHeaderPos);
195 return -1;
196 }
197 } else {
198 if (fShift >= 10) {
199 value = fBuffer[fCurrentCell] & mask;
200 fShift -= 10;
201 fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10;
202 } else {
203 value = fBuffer[fCurrentCell];
204 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;
212 }
213 return value;
214 }//end else
215}
216
217//_____________________________________________________________________________
218void AliAltroBuffer::Flush()
219{
220// Flushes the Buffer content
221 if (fFreeCellBuffer != 16) {
222 Int_t temp = fFreeCellBuffer;
223 for (Int_t i = 0; i < temp; i++){
224 FillBuffer(0x2AA);
225 }//end for
226 }//end if
227}
228
229//_____________________________________________________________________________
230void AliAltroBuffer::FillBuffer(Int_t val)
231{
232//Fills the Buffer with 16 ten bits words and write into a file
233
23b19451 234 if ((val > 0x3FF) || (val < 0)) {
235 Error("FillBuffer", "Value out of range (10 bits): %d", val);
236 val = 0x3FF;
237 }
3ea47630 238 fFreeCellBuffer--;
239 if (fShift < 10) {
240 Int_t temp = val;
241 val = val >> (10-fShift);
242 fBuffer[fCurrentCell] |= val;
243 fCurrentCell++;
244 fShift += 32;
245 val = temp;
246 }
247 fShift -= 10;
248 val = val << fShift;
249 fBuffer[fCurrentCell] |= val;
250 if (!fShift) {
251 //Buffer is written into a file
252 fFile->write((char*)fBuffer, sizeof(UInt_t)*5);
253 //Buffer is empty
254 for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0;
255 fShift = 32;
256 fCurrentCell = 0;
257 fFreeCellBuffer = 16;
258 }
259}
260
261
262//_____________________________________________________________________________
263void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber,
264 Int_t rowNumber, Int_t secNumber)
265{
266//Writes a trailer of 40 bits
267
268 Int_t num = fFreeCellBuffer % 4;
269 for(Int_t i = 0; i < num; i++) {
270 FillBuffer(0x2AA);
271 }//end for
272 FillBuffer(wordsNumber);
273 FillBuffer(padNumber);
274 FillBuffer(rowNumber);
275 FillBuffer(secNumber);
276}
277
278//_____________________________________________________________________________
279Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Int_t& padNumber,
280 Int_t& rowNumber, Int_t& secNumber)
281{
282//Read a trailer of 40 bits in the forward reading mode
283
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;
292 return kTRUE;
293}
294
295//_____________________________________________________________________________
296Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber,
297 Int_t& padNumber,
298 Int_t& rowNumber, Int_t& secNumber)
299{
300//Read a trailer of 40 bits in the backward reading mode
301
302 Int_t temp;
303 fEndingFillWords = 0;
304 do {
305 temp = GetNextBackWord();
306 fEndingFillWords++;
307 if (temp == -1) return kFALSE;
308 } while (temp == 0x2AA);
309 fEndingFillWords--;
310 secNumber = temp;
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;
317 return kTRUE;
318}
319
320
321//_____________________________________________________________________________
322void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber,
323 Int_t secNumber,
324 Int_t nTimeBins, const Int_t* adcValues,
325 Int_t threshold)
326{
327//Write all ADC values and the trailer of a channel
328
329 Int_t nWords = 0;
330 Int_t timeBin = -1;
331 Int_t bunchLength = 0;
332
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]);
337 nWords++;
338 timeBin = iTime;
339 bunchLength++;
340
341 } else if (timeBin >= 0) { // end of bunch
342 FillBuffer(timeBin);
343 FillBuffer(bunchLength + 2);
344 nWords += 2;
345 timeBin = -1;
346 bunchLength = 0;
347 }
348 }
349
350 if (timeBin >= 0) { // end of bunch
351 FillBuffer(timeBin);
352 FillBuffer(bunchLength + 2);
353 nWords += 2;
354 }
355
356 // write the trailer
357 WriteTrailer(nWords, padNumber, rowNumber, secNumber);
358}
359
360
361//_____________________________________________________________________________
362void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed)
363{
364//Write a (dummy or real) DDL data header,
365//set the compression bit if compressed
366
367 AliRawDataHeader header;
368 if (dummy) {
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));
372 } else {
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);
380 }
381}
b0aef454 382
383//_____________________________________________________________________________
384Bool_t AliAltroBuffer::ReadDataHeader()
385{
386//Read the DDL data header at the beginning of the file,
387//returns true in case of valid data
388
389 AliRawDataHeader header;
390 UInt_t currentPos = fFile->tellp();
391 fFile->seekp(0);
392 if (!fFile->read((char*)(&header), sizeof(header))) return kFALSE;
393 fDataHeaderPos = fFile->tellp();
394 fFile->seekp(currentPos);
395 return header.TestAttribute(0);
396}