]>
Commit | Line | Data |
---|---|---|
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 | |
3ea47630 | 22 | |
23 | #include "AliAltroBuffer.h" | |
5802cf2d | 24 | #include "AliAltroMapping.h" |
3ea47630 | 25 | #include "AliRawDataHeader.h" |
5802cf2d | 26 | #include "AliLog.h" |
3ea47630 | 27 | #include <Riostream.h> |
28 | #include <stdlib.h> | |
29 | ||
30 | ||
31 | ClassImp(AliAltroBuffer) | |
32 | ||
3ea47630 | 33 | //_____________________________________________________________________________ |
5802cf2d | 34 | AliAltroBuffer::AliAltroBuffer(const char* fileName, Int_t flag, const AliAltroMapping *mapping): |
3ea47630 | 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), | |
5802cf2d | 45 | fEndingFillWords(0), |
46 | fMapping(mapping) | |
3ea47630 | 47 | { |
48 | //if flag = 1 the actual object is used in the write mode | |
49 | //if flag = 0 the actual object is used in the read mode | |
50 | ||
51 | //the buffer is cleaned | |
52 | for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0; | |
53 | ||
54 | if (flag) { | |
55 | fFreeCellBuffer = 16; | |
56 | fShift = 32; | |
57 | //open the output file | |
58 | #ifndef __DECCXX | |
59 | fFile = new fstream(fileName, ios::binary|ios::out); | |
60 | #else | |
61 | fFile = new fstream(fileName, ios::out); | |
62 | #endif | |
63 | } else { | |
64 | //open the input file | |
65 | #ifndef __DECCXX | |
66 | fFile = new fstream(fileName, ios::binary|ios::in); | |
67 | #else | |
68 | fFile = new fstream(fileName, ios::in); | |
69 | #endif | |
70 | if (!fFile) { | |
71 | Error("AliAltroBuffer", "File doesn't exist: %s", fileName); | |
72 | return; | |
73 | } | |
74 | fShift = 0; | |
75 | //To get the file dimension (position of the last element in term of bytes) | |
76 | fFile->seekg(0, ios::end); | |
77 | fFilePosition = fFile->tellg(); | |
78 | fFileEnd = fFilePosition; | |
79 | fFile->seekg(0); | |
80 | } | |
5802cf2d | 81 | |
3ea47630 | 82 | } |
83 | ||
84 | //_____________________________________________________________________________ | |
85 | AliAltroBuffer::~AliAltroBuffer() | |
86 | { | |
87 | // destructor | |
88 | ||
89 | if (fFlag) { | |
90 | //Flush out the Buffer content at the end only if Buffer wasn't completely filled | |
91 | Flush(); | |
92 | if (fVerbose) Info("~AliAltroBuffer", "File Created"); | |
93 | }//end if | |
94 | fFile->close(); | |
95 | delete fFile; | |
5802cf2d | 96 | |
3ea47630 | 97 | } |
98 | ||
99 | //_____________________________________________________________________________ | |
100 | AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source): | |
101 | TObject(source), | |
102 | fShift(source.fShift), | |
103 | fCurrentCell(source.fCurrentCell), | |
104 | fFreeCellBuffer(source.fFreeCellBuffer), | |
105 | fFlag(source.fFlag), | |
106 | fVerbose(source.fVerbose), | |
107 | fFile(NULL), | |
108 | fMaskBackward(source.fMaskBackward), | |
109 | fFilePosition(source.fFilePosition), | |
110 | fFileEnd(source.fFileEnd), | |
111 | fDataHeaderPos(source.fDataHeaderPos), | |
5802cf2d | 112 | fEndingFillWords(source.fEndingFillWords), |
113 | fMapping(source.fMapping) | |
3ea47630 | 114 | { |
115 | // Copy Constructor | |
116 | ||
117 | Fatal("AliAltroBuffer", "copy constructor not implemented"); | |
118 | } | |
119 | ||
120 | //_____________________________________________________________________________ | |
121 | AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/) | |
122 | { | |
123 | //Assigment operator | |
124 | ||
125 | Fatal("operator =", "assignment operator not implemented"); | |
126 | return *this; | |
127 | } | |
128 | ||
129 | ||
130 | //_____________________________________________________________________________ | |
131 | Int_t AliAltroBuffer::GetNext() | |
132 | { | |
133 | //It reads a 10 bits word in forward dicection from the Buffer. | |
134 | //A new Buffer is read from the file only when Buffer is empty. | |
135 | //If there aren't elements anymore -1 is returned otherwise | |
136 | //the next element is returned | |
137 | ||
138 | UInt_t mask = 0xFFC00000; | |
139 | UInt_t temp; | |
140 | UInt_t value; | |
141 | if (!fShift) { | |
142 | if (fFile->tellg() >= (Int_t)fFileEnd) return -1; | |
143 | if (fFile->read((char*)fBuffer, sizeof(UInt_t)*5)) { | |
144 | fCurrentCell = 0; | |
145 | fShift = 22; | |
146 | value = fBuffer[fCurrentCell] & mask; | |
147 | value = value >> 22; | |
148 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; | |
149 | return value; | |
150 | } else { | |
151 | return -1; | |
152 | } | |
153 | } else { | |
154 | if (fShift >= 10) { | |
155 | value = fBuffer[fCurrentCell] & mask; | |
156 | value = value >> 22; | |
157 | fShift -= 10; | |
158 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; | |
159 | } else { | |
160 | value = fBuffer[fCurrentCell] & mask; | |
161 | fCurrentCell++; | |
162 | temp = fBuffer[fCurrentCell]; | |
163 | temp = temp >> fShift; | |
164 | temp = temp & mask; | |
165 | value = value | temp; | |
166 | value = value >> 22; | |
167 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << (10-fShift); | |
168 | fShift += 22; | |
169 | } | |
170 | return value; | |
171 | }//end else | |
172 | } | |
173 | ||
174 | //_____________________________________________________________________________ | |
175 | Int_t AliAltroBuffer::GetNextBackWord() | |
176 | { | |
177 | //It reads a 10 bits word in backward dicection from the Buffer. | |
178 | //A new Buffer is read from the file only when Buffer is empty. | |
179 | //If there aren't elements anymore -1 is returned otherwise | |
180 | //the next element is returned | |
181 | ||
182 | UInt_t mask = 0x3FF; | |
183 | UInt_t temp; | |
184 | UInt_t value; | |
185 | if (!fShift) { | |
186 | if (fFilePosition > fDataHeaderPos){ | |
187 | fFilePosition -= sizeof(UInt_t)*5; | |
188 | fFile->seekg(fFilePosition); | |
189 | fFile->read((char*)fBuffer, sizeof(UInt_t)*5); | |
190 | ||
191 | fCurrentCell = 4; | |
192 | fShift = 22; | |
193 | fMaskBackward = 0xFF; | |
194 | value = fBuffer[fCurrentCell] & mask; | |
195 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; | |
196 | return value; | |
197 | } else { | |
198 | fFile->seekg(fDataHeaderPos); | |
199 | return -1; | |
200 | } | |
201 | } else { | |
202 | if (fShift >= 10) { | |
203 | value = fBuffer[fCurrentCell] & mask; | |
204 | fShift -= 10; | |
205 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; | |
206 | } else { | |
207 | value = fBuffer[fCurrentCell]; | |
208 | fCurrentCell--; | |
209 | temp = fBuffer[fCurrentCell] & mask; | |
210 | temp = temp & fMaskBackward; | |
211 | fMaskBackward = fMaskBackward >> 2; | |
212 | temp = temp << fShift; | |
213 | value = value | temp; | |
214 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> (10-fShift); | |
215 | fShift = 22 + fShift; | |
216 | } | |
217 | return value; | |
218 | }//end else | |
219 | } | |
220 | ||
221 | //_____________________________________________________________________________ | |
222 | void AliAltroBuffer::Flush() | |
223 | { | |
224 | // Flushes the Buffer content | |
225 | if (fFreeCellBuffer != 16) { | |
226 | Int_t temp = fFreeCellBuffer; | |
227 | for (Int_t i = 0; i < temp; i++){ | |
228 | FillBuffer(0x2AA); | |
229 | }//end for | |
230 | }//end if | |
231 | } | |
232 | ||
233 | //_____________________________________________________________________________ | |
234 | void AliAltroBuffer::FillBuffer(Int_t val) | |
235 | { | |
236 | //Fills the Buffer with 16 ten bits words and write into a file | |
237 | ||
23b19451 | 238 | if ((val > 0x3FF) || (val < 0)) { |
239 | Error("FillBuffer", "Value out of range (10 bits): %d", val); | |
240 | val = 0x3FF; | |
241 | } | |
3ea47630 | 242 | fFreeCellBuffer--; |
243 | if (fShift < 10) { | |
244 | Int_t temp = val; | |
245 | val = val >> (10-fShift); | |
246 | fBuffer[fCurrentCell] |= val; | |
247 | fCurrentCell++; | |
248 | fShift += 32; | |
249 | val = temp; | |
250 | } | |
251 | fShift -= 10; | |
252 | val = val << fShift; | |
253 | fBuffer[fCurrentCell] |= val; | |
254 | if (!fShift) { | |
255 | //Buffer is written into a file | |
256 | fFile->write((char*)fBuffer, sizeof(UInt_t)*5); | |
257 | //Buffer is empty | |
258 | for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0; | |
259 | fShift = 32; | |
260 | fCurrentCell = 0; | |
261 | fFreeCellBuffer = 16; | |
262 | } | |
263 | } | |
264 | ||
265 | ||
5802cf2d | 266 | //_____________________________________________________________________________ |
267 | void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber, | |
268 | Int_t rowNumber, Int_t secNumber) | |
269 | { | |
270 | //Writes a trailer of 40 bits | |
271 | ||
272 | Int_t num = fFreeCellBuffer % 4; | |
273 | for(Int_t i = 0; i < num; i++) { | |
274 | FillBuffer(0x2AA); | |
275 | }//end for | |
276 | FillBuffer(wordsNumber); | |
277 | FillBuffer(padNumber); | |
278 | FillBuffer(rowNumber); | |
279 | FillBuffer(secNumber); | |
280 | } | |
281 | ||
3ea47630 | 282 | //_____________________________________________________________________________ |
283 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber, | |
284 | Int_t rowNumber, Int_t secNumber) | |
285 | { | |
286 | //Writes a trailer of 40 bits | |
287 | ||
5802cf2d | 288 | if (!fMapping) { |
289 | AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!"); | |
290 | return WriteDummyTrailer(wordsNumber,padNumber, | |
291 | rowNumber,secNumber); | |
292 | } | |
293 | ||
cc934096 | 294 | Short_t hwAddress = fMapping->GetHWAddress(rowNumber,padNumber,secNumber); |
295 | if (hwAddress == -1) | |
20daa34d | 296 | AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber)); |
cc934096 | 297 | WriteTrailer(wordsNumber,hwAddress); |
20daa34d | 298 | } |
299 | ||
300 | //_____________________________________________________________________________ | |
cc934096 | 301 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAddress) |
20daa34d | 302 | { |
303 | //Writes a trailer of 40 bits using | |
304 | //a given hardware adress | |
3ea47630 | 305 | Int_t num = fFreeCellBuffer % 4; |
306 | for(Int_t i = 0; i < num; i++) { | |
307 | FillBuffer(0x2AA); | |
308 | }//end for | |
5802cf2d | 309 | Int_t temp; |
cc934096 | 310 | temp = hwAddress & 0x3FF; |
5802cf2d | 311 | FillBuffer(temp); |
cc934096 | 312 | |
5802cf2d | 313 | temp = (wordsNumber << 6) & 0x3FF; |
314 | temp |= (0xA << 2); | |
cc934096 | 315 | temp |= ((hwAddress >> 10) & 0x3); |
316 | FillBuffer(temp); | |
5802cf2d | 317 | |
cc934096 | 318 | temp = 0xA << 6; |
319 | temp |= ((wordsNumber & 0x3FF) >> 4); | |
5802cf2d | 320 | FillBuffer(temp); |
cc934096 | 321 | |
322 | temp = 0x2AA; | |
5802cf2d | 323 | FillBuffer(temp); |
3ea47630 | 324 | } |
325 | ||
326 | //_____________________________________________________________________________ | |
16e29964 | 327 | Bool_t AliAltroBuffer::ReadDummyTrailer(Int_t& wordsNumber, Int_t& padNumber, |
328 | Int_t& rowNumber, Int_t& secNumber) | |
3ea47630 | 329 | { |
16e29964 | 330 | //Read a dummy trailer of 40 bits in the forward reading mode |
3ea47630 | 331 | |
332 | wordsNumber = GetNext(); | |
333 | if (wordsNumber == -1) return kFALSE; | |
334 | padNumber = GetNext(); | |
335 | if (padNumber == -1) return kFALSE; | |
336 | rowNumber = GetNext(); | |
337 | if (rowNumber == -1) return kFALSE; | |
338 | secNumber = GetNext(); | |
339 | if (secNumber == -1) return kFALSE; | |
340 | return kTRUE; | |
341 | } | |
342 | ||
16e29964 | 343 | //_____________________________________________________________________________ |
344 | Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Int_t& padNumber, | |
345 | Int_t& rowNumber, Int_t& secNumber) | |
346 | { | |
347 | //Read a trailer of 40 bits in the forward reading mode | |
348 | if (!fMapping) { | |
349 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); | |
350 | return ReadDummyTrailer(wordsNumber,padNumber, | |
351 | rowNumber,secNumber); | |
352 | } | |
353 | ||
cc934096 | 354 | Short_t hwAddress; |
355 | if (!ReadTrailer(wordsNumber,hwAddress)) return kFALSE; | |
356 | rowNumber = fMapping->GetPadRow(hwAddress); | |
357 | padNumber = fMapping->GetPad(hwAddress); | |
358 | secNumber = fMapping->GetSector(hwAddress); | |
20daa34d | 359 | |
360 | return kTRUE; | |
361 | } | |
362 | ||
363 | //_____________________________________________________________________________ | |
cc934096 | 364 | Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Short_t& hwAddress) |
20daa34d | 365 | { |
366 | //Read a trailer of 40 bits in the forward reading mode | |
367 | ||
16e29964 | 368 | Int_t temp = GetNext(); |
cc934096 | 369 | hwAddress = temp; |
16e29964 | 370 | |
371 | temp = GetNext(); | |
cc934096 | 372 | wordsNumber = ((temp & 0x3FF) >> 6); |
20daa34d | 373 | if (((temp >> 2) & 0xF) != 0xA) |
16e29964 | 374 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",temp >> 6)); |
cc934096 | 375 | hwAddress |= (temp & 0x3) << 10; |
376 | ||
377 | temp = GetNext(); | |
378 | if ((temp >> 6) != 0xA) | |
379 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); | |
380 | wordsNumber |= (temp << 4) & 0x3FF; | |
16e29964 | 381 | |
382 | temp = GetNext(); | |
cc934096 | 383 | if (temp != 0x2AA) |
384 | AliFatal(Form("Incorrect trailer found ! Expecting 0x2AA but found %x !",temp)); | |
16e29964 | 385 | |
16e29964 | 386 | return kTRUE; |
387 | } | |
388 | ||
3ea47630 | 389 | //_____________________________________________________________________________ |
20daa34d | 390 | Bool_t AliAltroBuffer::ReadDummyTrailerBackward(Int_t& wordsNumber, Int_t& padNumber, |
391 | Int_t& rowNumber, Int_t& secNumber) | |
3ea47630 | 392 | { |
393 | //Read a trailer of 40 bits in the backward reading mode | |
394 | ||
395 | Int_t temp; | |
396 | fEndingFillWords = 0; | |
397 | do { | |
398 | temp = GetNextBackWord(); | |
399 | fEndingFillWords++; | |
400 | if (temp == -1) return kFALSE; | |
401 | } while (temp == 0x2AA); | |
402 | fEndingFillWords--; | |
403 | secNumber = temp; | |
404 | rowNumber = GetNextBackWord(); | |
405 | if (rowNumber == -1) return kFALSE; | |
406 | padNumber = GetNextBackWord(); | |
407 | if (padNumber == -1) return kFALSE; | |
408 | wordsNumber = GetNextBackWord(); | |
409 | if (wordsNumber == -1) return kFALSE; | |
410 | return kTRUE; | |
411 | } | |
412 | ||
20daa34d | 413 | //_____________________________________________________________________________ |
414 | Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber, Int_t& padNumber, | |
415 | Int_t& rowNumber, Int_t& secNumber) | |
416 | { | |
417 | //Read a trailer of 40 bits in the backward reading mode | |
418 | if (!fMapping) { | |
419 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); | |
420 | return ReadDummyTrailerBackward(wordsNumber,padNumber, | |
421 | rowNumber,secNumber); | |
422 | } | |
423 | ||
cc934096 | 424 | Short_t hwAddress; |
425 | if (!ReadTrailerBackward(wordsNumber,hwAddress)) return kFALSE; | |
426 | rowNumber = fMapping->GetPadRow(hwAddress); | |
427 | padNumber = fMapping->GetPad(hwAddress); | |
428 | secNumber = fMapping->GetSector(hwAddress); | |
20daa34d | 429 | |
430 | return kTRUE; | |
431 | } | |
432 | ||
433 | //_____________________________________________________________________________ | |
cc934096 | 434 | Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber, Short_t& hwAddress) |
20daa34d | 435 | { |
436 | //Read a trailer of 40 bits in the backward reading mode | |
437 | ||
438 | Int_t temp; | |
439 | fEndingFillWords = 0; | |
cc934096 | 440 | while ((temp = GetNextBackWord()) == 0x2AA) { |
20daa34d | 441 | fEndingFillWords++; |
442 | if (temp == -1) return kFALSE; | |
cc934096 | 443 | }; |
444 | if (fEndingFillWords == 0) | |
445 | AliFatal("Incorrect trailer found ! Expected 0x2AA not found !"); | |
20daa34d | 446 | fEndingFillWords--; |
447 | ||
cc934096 | 448 | wordsNumber = (temp << 4) & 0x3FF; |
449 | if ((temp >> 6) != 0xA) | |
450 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); | |
20daa34d | 451 | |
452 | temp = GetNextBackWord(); | |
cc934096 | 453 | hwAddress = (temp & 0x3) << 10; |
20daa34d | 454 | if (((temp >> 2) & 0xF) != 0xA) |
cc934096 | 455 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF)); |
456 | wordsNumber |= ((temp & 0x3FF) >> 6); | |
20daa34d | 457 | |
458 | temp = GetNextBackWord(); | |
cc934096 | 459 | hwAddress |= temp; |
20daa34d | 460 | |
461 | return kTRUE; | |
462 | } | |
3ea47630 | 463 | |
464 | //_____________________________________________________________________________ | |
465 | void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, | |
466 | Int_t secNumber, | |
467 | Int_t nTimeBins, const Int_t* adcValues, | |
468 | Int_t threshold) | |
469 | { | |
cc934096 | 470 | //Write all ADC values and the trailer of a channel |
471 | Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); | |
472 | // write the trailer | |
473 | WriteTrailer(nWords, padNumber, rowNumber, secNumber); | |
474 | } | |
475 | ||
476 | //_____________________________________________________________________________ | |
477 | void AliAltroBuffer::WriteChannel(Short_t hwAddress, | |
478 | Int_t nTimeBins, const Int_t* adcValues, | |
479 | Int_t threshold) | |
480 | { | |
481 | //Write all ADC values and the trailer of a channel | |
482 | Int_t nWords = WriteBunch(nTimeBins,adcValues,threshold); | |
483 | // write the trailer | |
484 | WriteTrailer(nWords, hwAddress); | |
485 | } | |
486 | ||
487 | //_____________________________________________________________________________ | |
488 | Int_t AliAltroBuffer::WriteBunch(Int_t nTimeBins, const Int_t* adcValues, | |
489 | Int_t threshold) | |
490 | { | |
491 | //Write all ADC values | |
492 | //Return number of words written | |
3ea47630 | 493 | |
494 | Int_t nWords = 0; | |
495 | Int_t timeBin = -1; | |
496 | Int_t bunchLength = 0; | |
497 | ||
498 | // loop over time bins | |
499 | for (Int_t iTime = 0; iTime < nTimeBins; iTime++) { | |
500 | if (adcValues[iTime] >= threshold) { // ADC value above threshold | |
501 | FillBuffer(adcValues[iTime]); | |
502 | nWords++; | |
503 | timeBin = iTime; | |
504 | bunchLength++; | |
505 | ||
506 | } else if (timeBin >= 0) { // end of bunch | |
507 | FillBuffer(timeBin); | |
508 | FillBuffer(bunchLength + 2); | |
509 | nWords += 2; | |
510 | timeBin = -1; | |
511 | bunchLength = 0; | |
512 | } | |
513 | } | |
514 | ||
515 | if (timeBin >= 0) { // end of bunch | |
516 | FillBuffer(timeBin); | |
517 | FillBuffer(bunchLength + 2); | |
518 | nWords += 2; | |
519 | } | |
520 | ||
cc934096 | 521 | return nWords; |
3ea47630 | 522 | } |
523 | ||
20daa34d | 524 | //_____________________________________________________________________________ |
cc934096 | 525 | void AliAltroBuffer::ReadChannelBackward(Int_t& padNumber, Int_t& rowNumber, |
526 | Int_t& secNumber, | |
527 | Int_t& nTimeBins, Int_t* adcValues) | |
20daa34d | 528 | { |
cc934096 | 529 | //Read all ADC values and the trailer of a channel (in backward order) |
20daa34d | 530 | |
531 | Int_t wordsNumber; | |
cc934096 | 532 | if (!ReadTrailerBackward(wordsNumber,padNumber, |
533 | rowNumber,secNumber)) return; | |
534 | return ReadBunchBackward(wordsNumber,nTimeBins,adcValues); | |
535 | } | |
20daa34d | 536 | |
cc934096 | 537 | //_____________________________________________________________________________ |
538 | void AliAltroBuffer::ReadChannelBackward(Short_t& hwAddress, | |
539 | Int_t& nTimeBins, Int_t* adcValues) | |
540 | { | |
541 | //Read all ADC values and the trailer of a channel (in backward order) | |
542 | ||
543 | Int_t wordsNumber; | |
544 | if (!ReadTrailerBackward(wordsNumber, | |
545 | hwAddress)) return; | |
546 | return ReadBunchBackward(wordsNumber,nTimeBins,adcValues); | |
547 | } | |
548 | ||
549 | //_____________________________________________________________________________ | |
550 | void AliAltroBuffer::ReadBunchBackward(Int_t wordsNumber, | |
551 | Int_t& nTimeBins, Int_t* adcValues) | |
552 | { | |
20daa34d | 553 | if (wordsNumber < 0) return; |
554 | // Number of fill words | |
555 | Int_t nFillWords; | |
556 | if ((wordsNumber % 4) == 0) | |
557 | nFillWords = 0; | |
558 | else | |
559 | nFillWords = 4 - wordsNumber % 4; | |
560 | // Read the fill words | |
561 | for (Int_t i = 0; i < nFillWords; i++) { | |
cc934096 | 562 | Int_t temp = GetNextBackWord(); |
20daa34d | 563 | if (temp != 0x2AA) |
564 | AliFatal(Form("Invalid fill word, expected 0x2AA, but got %X", temp)); | |
565 | } | |
566 | ||
567 | // Decoding | |
568 | Int_t lastWord = wordsNumber; | |
569 | nTimeBins = -1; | |
570 | while (lastWord > 0) { | |
cc934096 | 571 | Int_t l = GetNextBackWord(); |
20daa34d | 572 | if (l < 0) AliFatal(Form("Bad bunch length (%d) !", l)); |
cc934096 | 573 | Int_t t = GetNextBackWord(); |
20daa34d | 574 | if (t < 0) AliFatal(Form("Bad bunch time (%d) !", t)); |
575 | lastWord -= 2; | |
576 | if (nTimeBins == -1) nTimeBins = t + 1; | |
577 | for (Int_t i = 2; i < l; i++) { | |
cc934096 | 578 | Int_t amp = GetNextBackWord(); |
20daa34d | 579 | if (amp < 0) AliFatal(Form("Bad adc value (%X) !", amp)); |
580 | adcValues[t - (i-2)] = amp; | |
581 | lastWord--; | |
582 | } | |
583 | } | |
584 | ||
585 | } | |
3ea47630 | 586 | |
587 | //_____________________________________________________________________________ | |
588 | void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed) | |
589 | { | |
590 | //Write a (dummy or real) DDL data header, | |
591 | //set the compression bit if compressed | |
592 | ||
593 | AliRawDataHeader header; | |
594 | if (dummy) { | |
595 | //if size=0 it means that this data header is a dummy data header | |
596 | fDataHeaderPos = fFile->tellp(); | |
597 | fFile->write((char*)(&header), sizeof(header)); | |
598 | } else { | |
599 | UInt_t currentFilePos = fFile->tellp(); | |
600 | fFile->seekp(fDataHeaderPos); | |
601 | header.fSize = currentFilePos-fDataHeaderPos; | |
602 | header.SetAttribute(0); // valid data | |
603 | if (compressed) header.SetAttribute(1); | |
604 | fFile->write((char*)(&header), sizeof(header)); | |
605 | fFile->seekp(currentFilePos); | |
606 | } | |
607 | } | |
b0aef454 | 608 | |
609 | //_____________________________________________________________________________ | |
610 | Bool_t AliAltroBuffer::ReadDataHeader() | |
611 | { | |
612 | //Read the DDL data header at the beginning of the file, | |
613 | //returns true in case of valid data | |
614 | ||
615 | AliRawDataHeader header; | |
616 | UInt_t currentPos = fFile->tellp(); | |
617 | fFile->seekp(0); | |
618 | if (!fFile->read((char*)(&header), sizeof(header))) return kFALSE; | |
619 | fDataHeaderPos = fFile->tellp(); | |
620 | fFile->seekp(currentPos); | |
621 | return header.TestAttribute(0); | |
622 | } | |
5802cf2d | 623 |