Line data Source code
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 : ///////////////////////////////////////////////////////////////////////////////
19 : ///
20 : /// This class provides access to Altro digits in raw data.
21 : ///
22 : /// It loops over all Altro digits in the raw data given by the AliRawReader.
23 : /// The Next method goes to the next digit. If there are no digits left
24 : /// it returns kFALSE.
25 : /// Several getters provide information about the current digit.
26 : ///
27 : ///////////////////////////////////////////////////////////////////////////////
28 :
29 : #include "AliAltroRawStream.h"
30 : #include "AliRawReader.h"
31 : #include "AliLog.h"
32 : #include "AliRawEventHeaderBase.h"
33 :
34 128 : ClassImp(AliAltroRawStream)
35 :
36 :
37 : //_____________________________________________________________________________
38 12 : AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
39 12 : fIsShortDataHeader(kFALSE),
40 12 : fDDLNumber(-1),
41 12 : fPrevDDLNumber(-1),
42 12 : fRCUId(-1),
43 12 : fPrevRCUId(-1),
44 12 : fHWAddress(-1),
45 12 : fPrevHWAddress(-1),
46 12 : fTime(-1),
47 12 : fPrevTime(-1),
48 12 : fSignal(-1),
49 12 : fTimeBunch(-1),
50 12 : fRawReader(rawReader),
51 12 : fData(NULL),
52 12 : fPosition(0),
53 12 : fCount(0),
54 12 : fChannelPayloadSize(-1),
55 12 : fBunchLength(0),
56 12 : fRCUTrailerData(NULL),
57 12 : fRCUTrailerSize(0),
58 12 : fFECERRA(0),
59 12 : fFECERRB(0),
60 12 : fERRREG2(0),
61 12 : fERRREG3(0),
62 12 : fERRREG4(0),
63 12 : fActiveFECsA(0),
64 12 : fActiveFECsB(0),
65 12 : fAltroCFG1(0),
66 12 : fAltroCFG2(0)
67 60 : {
68 : // create an object to read Altro raw digits
69 24 : }
70 :
71 : //_____________________________________________________________________________
72 : AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
73 0 : TObject(stream),
74 0 : fIsShortDataHeader(stream.fIsShortDataHeader),
75 0 : fDDLNumber(stream.fDDLNumber),
76 0 : fPrevDDLNumber(stream.fPrevDDLNumber),
77 0 : fRCUId(stream.fRCUId),
78 0 : fPrevRCUId(stream.fPrevRCUId),
79 0 : fHWAddress(stream.fHWAddress),
80 0 : fPrevHWAddress(stream.fPrevHWAddress),
81 0 : fTime(stream.fTime),
82 0 : fPrevTime(stream.fPrevTime),
83 0 : fSignal(stream.fSignal),
84 0 : fTimeBunch(stream.fTimeBunch),
85 0 : fRawReader(stream.fRawReader),
86 0 : fData(stream.fData),
87 0 : fPosition(stream.fPosition),
88 0 : fCount(stream.fCount),
89 0 : fChannelPayloadSize(stream.fChannelPayloadSize),
90 0 : fBunchLength(stream.fBunchLength),
91 0 : fRCUTrailerData(stream.fRCUTrailerData),
92 0 : fRCUTrailerSize(stream.fRCUTrailerSize),
93 0 : fFECERRA(stream.fFECERRA),
94 0 : fFECERRB(stream.fFECERRB),
95 0 : fERRREG2(stream.fERRREG2),
96 0 : fERRREG3(stream.fERRREG3),
97 0 : fERRREG4(stream.fERRREG4),
98 0 : fActiveFECsA(stream.fActiveFECsA),
99 0 : fActiveFECsB(stream.fActiveFECsB),
100 0 : fAltroCFG1(stream.fAltroCFG1),
101 0 : fAltroCFG2(stream.fAltroCFG2)
102 0 : {
103 0 : }
104 :
105 : //_____________________________________________________________________________
106 : AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& stream)
107 : {
108 0 : if(&stream == this) return *this;
109 :
110 0 : fIsShortDataHeader = stream.fIsShortDataHeader;
111 0 : fDDLNumber = stream.fDDLNumber;
112 0 : fPrevDDLNumber = stream.fPrevDDLNumber;
113 0 : fRCUId = stream.fRCUId;
114 0 : fPrevRCUId = stream.fPrevRCUId;
115 0 : fHWAddress = stream.fHWAddress;
116 0 : fPrevHWAddress = stream.fPrevHWAddress;
117 0 : fTime = stream.fTime;
118 0 : fPrevTime = stream.fPrevTime;
119 0 : fSignal = stream.fSignal;
120 0 : fTimeBunch = stream.fTimeBunch;
121 0 : fRawReader = stream.fRawReader;
122 0 : fData = stream.fData;
123 0 : fPosition = stream.fPosition;
124 0 : fCount = stream.fCount;
125 0 : fChannelPayloadSize= stream.fChannelPayloadSize;
126 0 : fBunchLength = stream.fBunchLength;
127 0 : fRCUTrailerData = stream.fRCUTrailerData;
128 0 : fRCUTrailerSize = stream.fRCUTrailerSize;
129 0 : fFECERRA = stream.fFECERRA;
130 0 : fFECERRB = stream.fFECERRB;
131 0 : fERRREG2 = stream.fERRREG2;
132 0 : fERRREG3 = stream.fERRREG3;
133 0 : fERRREG4 = stream.fERRREG4;
134 0 : fActiveFECsA = stream.fActiveFECsA;
135 0 : fActiveFECsB = stream.fActiveFECsB;
136 0 : fAltroCFG1 = stream.fAltroCFG1;
137 0 : fAltroCFG2 = stream.fAltroCFG2;
138 :
139 0 : return *this;
140 0 : }
141 :
142 : //_____________________________________________________________________________
143 : AliAltroRawStream::~AliAltroRawStream()
144 48 : {
145 : // clean up
146 :
147 48 : }
148 :
149 : //_____________________________________________________________________________
150 : void AliAltroRawStream::Reset()
151 : {
152 : // reset altro raw stream params
153 :
154 0 : fPosition = fCount = fBunchLength = 0;
155 0 : fChannelPayloadSize = -1;
156 :
157 0 : fRCUTrailerData = NULL;
158 0 : fRCUTrailerSize = 0;
159 :
160 0 : fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fERRREG4 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
161 :
162 0 : fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
163 :
164 0 : if (fRawReader) fRawReader->Reset();
165 0 : }
166 :
167 : //_____________________________________________________________________________
168 : Bool_t AliAltroRawStream::Next()
169 : {
170 : // read the next raw digit
171 : // returns kFALSE if there is no digit left
172 :
173 0 : fPrevDDLNumber = fDDLNumber;
174 0 : fPrevRCUId = fRCUId;
175 0 : fPrevHWAddress = fHWAddress;
176 0 : fPrevTime = fTime;
177 :
178 0 : while (fCount == 0) { // next trailer
179 0 : while (fPosition <= 0) { // next payload
180 : do {
181 0 : if (!fRawReader->ReadNextData(fData)) return kFALSE;
182 0 : } while (fRawReader->GetDataSize() == 0);
183 :
184 0 : fDDLNumber = fRawReader->GetDDLID();
185 :
186 0 : fPosition = GetPosition();
187 : }
188 :
189 0 : ReadTrailer();
190 :
191 0 : fBunchLength = 0;
192 : }
193 :
194 0 : if (fBunchLength == 0) ReadBunch();
195 0 : else fTime--;
196 :
197 0 : ReadAmplitude();
198 :
199 0 : return kTRUE;
200 0 : }
201 :
202 : //_____________________________________________________________________________
203 : Bool_t AliAltroRawStream::NextDDL(UChar_t *data)
204 : {
205 148 : if (!data) {
206 : do {
207 0 : if (!fRawReader->ReadNextData(fData)) return kFALSE;
208 0 : } while (fRawReader->GetDataSize() == 0);
209 : }
210 : else {
211 74 : fData = data;
212 : }
213 :
214 74 : fDDLNumber = fRawReader->GetDDLID();
215 74 : fChannelPayloadSize = -1;
216 74 : fPosition = GetPosition();
217 :
218 74 : return kTRUE;
219 74 : }
220 :
221 : //_____________________________________________________________________________
222 : Bool_t AliAltroRawStream::NextChannel()
223 : {
224 1012 : if (fPosition <= 0) return kFALSE;
225 :
226 395 : ReadTrailer();
227 :
228 395 : return kTRUE;
229 469 : }
230 :
231 : //_____________________________________________________________________________
232 : Bool_t AliAltroRawStream::NextBunch(UShort_t *bunchData,
233 : Int_t &bunchLength,
234 : Int_t &startTimeBin)
235 : {
236 1060 : if (fCount == 0) return kFALSE;
237 :
238 212 : ReadBunch();
239 212 : bunchLength = fTimeBunch;
240 212 : startTimeBin = fTime;
241 :
242 18534 : while (fBunchLength > 0) {
243 9055 : ReadAmplitude();
244 9055 : bunchData[bunchLength-fBunchLength-1] = fSignal;
245 : }
246 :
247 212 : return kTRUE;
248 424 : }
249 :
250 : //_____________________________________________________________________________
251 : void AliAltroRawStream::SelectRawData(Int_t detId)
252 : {
253 : // Select the raw data for specific
254 : // detector id
255 0 : AliDebug(1,Form("Selecting raw data for detector %d",detId));
256 0 : fRawReader->Select(detId);
257 0 : }
258 :
259 : //_____________________________________________________________________________
260 : void AliAltroRawStream::SelectRawData(const char *detName)
261 : {
262 : // Select the raw data for specific
263 : // detector name
264 0 : AliDebug(1,Form("Selecting raw data for detector %s",detName));
265 0 : fRawReader->Select(detName);
266 0 : }
267 :
268 : //_____________________________________________________________________________
269 : UShort_t AliAltroRawStream::GetNextWord()
270 : {
271 : // Read the next 10 bit word in backward direction
272 : // The input stream access is given by fData and fPosition
273 :
274 40364 : fPosition--;
275 :
276 20182 : Int_t iBit = fPosition * 10;
277 20182 : Int_t iByte = iBit / 8;
278 20182 : Int_t shift = iBit % 8;
279 :
280 : // the raw data is written as integers where the low bits are filled first
281 : // -> little endian is assumed here !
282 : Int_t iByteLow = iByte;
283 20182 : iByte++;
284 : Int_t iByteHigh = iByte;
285 20182 : return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
286 : }
287 :
288 : //_____________________________________________________________________________
289 : Bool_t AliAltroRawStream::ReadTrailer()
290 : {
291 : //Read a trailer of 40 bits in the backward reading mode
292 : //First reading filling words
293 : UShort_t temp;
294 : Int_t nFillWords = 0;
295 2615 : while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
296 395 : if (nFillWords == 0) {
297 156 : fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0x2AA");
298 : // PrintDebug();
299 156 : AliWarning(Form("Incorrect trailer found ! Expected 0x2AA not found (0x%x != 0x2AA) ! Current position %d, DDL=%d",
300 : temp,fPosition,fDDLNumber));
301 : // trying to recover and find the next bunch
302 26625 : while ((fPosition > 2) && (temp != 0x2AA)) temp = GetNextWord();
303 156 : if (temp != 0x2AA) {
304 27 : fCount = fPosition = 0;
305 27 : return kFALSE;
306 : }
307 129 : temp = GetNextWord();
308 129 : }
309 :
310 : //Then read the trailer
311 368 : if (fPosition < 2) {
312 0 : fRawReader->AddMajorErrorLog(kAltroTrailerErr,Form("size %d < 5",
313 : fPosition));
314 : // PrintDebug();
315 0 : AliWarning(Form("Incorrect raw data size ! Expected at least 5 words but found %d !",fPosition));
316 0 : fCount = fPosition = 0;
317 0 : return kFALSE;
318 : }
319 :
320 368 : fCount = (temp << 4) & 0x3FF;
321 368 : if ((temp >> 6) != 0xA) {
322 0 : fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0xA");
323 : // PrintDebug();
324 0 : AliWarning(Form("Incorrect trailer found ! Expecting 0xA but found 0x%x !",temp >> 6));
325 0 : fCount = 0;
326 0 : return kFALSE;
327 : }
328 :
329 368 : temp = GetNextWord();
330 368 : fHWAddress = (temp & 0x3) << 10;
331 368 : if (((temp >> 2) & 0xF) != 0xA) {
332 0 : fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no second 0xA");
333 : // PrintDebug();
334 0 : AliWarning(Form("Incorrect trailer found ! Expecting second 0xA but found 0x%x !",(temp >> 2) & 0xF));
335 0 : fCount = 0;
336 0 : return kFALSE;
337 : }
338 368 : fCount |= ((temp & 0x3FF) >> 6);
339 368 : fChannelPayloadSize = fCount;
340 :
341 368 : if (fCount >= fPosition) {
342 0 : fRawReader->AddMajorErrorLog(kAltroTrailerErr,"invalid size");
343 : // PrintDebug();
344 0 : AliWarning(Form("Incorrect trailer found ! The altro payload size is invalid (%d >= %d) !",fCount,fPosition));
345 0 : fCount = 0;
346 0 : return kFALSE;
347 : }
348 368 : temp = GetNextWord();
349 368 : fHWAddress |= temp;
350 :
351 368 : fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
352 :
353 368 : return kTRUE;
354 395 : }
355 :
356 : //_____________________________________________________________________________
357 : void AliAltroRawStream::ReadBunch()
358 : {
359 : // Read altro payload in
360 : // backward direction
361 424 : if (fCount <= 2) {
362 0 : fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
363 : // PrintDebug();
364 0 : AliWarning(Form("Could not read bunch length and time bin ! Only %d 10-bit words are left !",fCount));
365 0 : fBunchLength = fTimeBunch = fCount = 0;
366 0 : return;
367 : }
368 :
369 212 : fBunchLength = GetNextWord() - 2;
370 212 : if (fBunchLength > fCount) {
371 0 : fRawReader->AddMinorErrorLog(kBunchLengthReadErr,Form("bl=%d",fBunchLength));
372 : // PrintDebug();
373 0 : AliWarning(Form("Could not read bunch length ! Bunch length = %d (>%d)",fBunchLength,fCount));
374 0 : fBunchLength = fTimeBunch = fCount = 0;
375 0 : return;
376 : }
377 212 : fTimeBunch = fBunchLength;
378 212 : fCount--;
379 :
380 212 : fTime = GetNextWord();
381 212 : fCount--;
382 :
383 212 : return;
384 212 : }
385 :
386 : //_____________________________________________________________________________
387 : void AliAltroRawStream::ReadAmplitude()
388 : {
389 : // Read next time bin amplitude
390 18110 : if (fCount <= 0) {
391 0 : fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
392 : // PrintDebug();
393 0 : AliWarning("Could not read sample amplitude !");
394 0 : fCount = fSignal = fBunchLength = 0;
395 0 : return;
396 : }
397 :
398 9055 : fSignal = GetNextWord();
399 :
400 9055 : fCount--;
401 9055 : fBunchLength--;
402 :
403 9055 : return;
404 9055 : }
405 :
406 : //_____________________________________________________________________________
407 : Int_t AliAltroRawStream::GetPosition()
408 : {
409 : // Sets the position in the
410 : // input stream
411 : // Read the RCU trailer
412 : // This includes the trailer size,
413 : // RCU identifier and raw data payload.
414 : // The RCU trailer format is described
415 : // in details in the RCU manual.
416 :
417 : // We use the last word of the payload
418 : // in order to decide which RCU firmware
419 : // was used during the data taking.
420 : // The firmware v2 adds 0xAAAA as 16
421 : // most significant bits and since the
422 : // payload size (firmware v1) can not be
423 : // that big, we use this as a unique
424 : // label of the firmware version.
425 :
426 148 : Int_t index = fRawReader->GetDataSize();
427 74 : UInt_t word = Get32bitWord(index);
428 74 : if (((word >> 16) == 0xaaaa) || (word == 2)) {
429 : // This is RCU formware v2
430 : // The statement word==2 is needed only temporary
431 : // in order to be able to read previously generated
432 : // aliroot raw data
433 :
434 : Int_t trailerSize = 0;
435 74 : if (word == 2) {
436 0 : AliInfo("Old simulated raw data is assumed!");
437 : trailerSize = 2;
438 0 : fRCUId = 0;
439 0 : }
440 : else {
441 : // First read 32-bit word with the
442 : // trailer size (7 bits), RCU ID (9 bits) and
443 : // 0xAAA (the rest - 16 bits)
444 74 : fRCUId = (Int_t)((word >> 7) & 0x1ff);
445 74 : trailerSize = (word & 0x7F);
446 : }
447 :
448 : // Now read the beginning of the trailer
449 : // where the payload size is written
450 74 : if (trailerSize < 2) {
451 0 : fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
452 0 : trailerSize*4));
453 0 : AliWarning(Form("Invalid trailer size found (%d bytes) !",
454 : trailerSize*4));
455 0 : }
456 :
457 74 : Int_t position = ReadRCUTrailer(index,trailerSize);
458 74 : if (fRawReader->GetType() != AliRawEventHeaderBase::kStartOfData) {
459 : // The size is specified in a number of 40bits
460 : // Therefore we need to transform it to number of bytes
461 74 : position *= 5;
462 :
463 : // Check the consistency of the header and trailer
464 148 : if (((fRawReader->GetDataSize() - trailerSize*4) < position) ||
465 74 : ((fRawReader->GetDataSize() - trailerSize*4) >= (position + 4))) {
466 0 : fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
467 0 : fRawReader->GetDataSize(),
468 : trailerSize*4,
469 : position));
470 0 : AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
471 : fRawReader->GetDataSize(),
472 : trailerSize*4,
473 : position));
474 0 : position = fRawReader->GetDataSize() - trailerSize*4;
475 0 : }
476 :
477 74 : return position * 8 / 10;
478 : }
479 : else {
480 : // Special RCU payload in case of SOD events
481 : // The decoding is left to the user code
482 : // Here we just retrieve the payload size
483 0 : return position;
484 : }
485 : }
486 : else {
487 : // In case of the Old RCU trailer format
488 : // we have to read just the size of altro payload
489 : // in units of 40-bit words
490 : Int_t position = (Int_t)word;
491 :
492 0 : fRCUId = -1;
493 0 : fRCUTrailerSize = 0;
494 0 : fRCUTrailerData = NULL;
495 :
496 : // The size is specified in a number of 40bits
497 : // Therefore we need to transform it to number of bytes
498 0 : position *= 5;
499 :
500 0 : if (!fIsShortDataHeader) {
501 :
502 : // Check the consistency of the header and trailer
503 0 : if (((fRawReader->GetDataSize() - 4) < position) ||
504 0 : ((fRawReader->GetDataSize() - 4) >= (position + 4))) {
505 0 : fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
506 0 : fRawReader->GetDataSize()-4,
507 : position));
508 : // PrintDebug();
509 0 : AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
510 : fRawReader->GetDataSize()-4,
511 : position));
512 0 : position = fRawReader->GetDataSize()-4;
513 0 : }
514 : }
515 : else {
516 : // Check the consistency of the header and trailer
517 : // In this case the header is shorter by 4 bytes
518 0 : if ((fRawReader->GetDataSize() < position) ||
519 0 : (fRawReader->GetDataSize() >= (position + 4))) {
520 0 : fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
521 0 : fRawReader->GetDataSize(),
522 : position));
523 : // PrintDebug();
524 0 : AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
525 : fRawReader->GetDataSize(),
526 : position));
527 0 : position = fRawReader->GetDataSize();
528 0 : }
529 :
530 : // 7 32-bit words Common Data Header
531 : // therefore we have to shift back by 4 bytes
532 : // the pointer to the raw data payload
533 0 : fData -= 4;
534 : }
535 :
536 : // Return the position in units of 10-bit words
537 0 : return position*8/10;
538 : }
539 74 : }
540 :
541 : //_____________________________________________________________________________
542 : UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
543 : {
544 : // This method returns the 32 bit word at a given
545 : // position inside the raw data payload.
546 : // The 'index' points to the beginning of the next word.
547 : // The method is supposed to be endian (platform)
548 : // independent.
549 296 : if (!fData) {
550 0 : PrintDebug();
551 0 : AliFatal("Raw data paylod buffer is not yet initialized !");
552 0 : }
553 :
554 148 : if (index < 4) {
555 0 : fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
556 : // PrintDebug();
557 0 : AliWarning(Form("Invalid raw data payload position (%d) !",index));
558 0 : }
559 :
560 : UInt_t word = 0;
561 148 : word = fData[--index] << 24;
562 148 : word |= fData[--index] << 16;
563 148 : word |= fData[--index] << 8;
564 148 : word |= fData[--index];
565 :
566 148 : return word;
567 : }
568 :
569 : //_____________________________________________________________________________
570 : Int_t AliAltroRawStream::ReadRCUTrailer(Int_t &index, Int_t trailerSize)
571 : {
572 : // The method decodes the RCU trailer data
573 : // according to the RCU fw ver.2 specs
574 :
575 148 : fRCUTrailerSize = trailerSize*4;
576 :
577 148 : for (trailerSize -= 2; trailerSize > 0; trailerSize--) {
578 0 : Int_t word = Get32bitWord(index);
579 0 : Int_t parCode = word >> 26;
580 0 : Int_t parData = word & 0x3FFFFFF;
581 0 : switch (parCode) {
582 : case 1:
583 : // ERR_REG1
584 0 : fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
585 0 : fFECERRB = ((parData & 0x1FFF)) << 7;
586 0 : break;
587 : case 2:
588 : // ERR_REG2
589 0 : fERRREG2 = parData & 0x1FF;
590 0 : break;
591 : case 3:
592 : // ERR_REG3
593 0 : fERRREG3 = parData & 0xFFF;
594 0 : break;
595 : case 4:
596 : // ERR_REG4
597 0 : fERRREG4 = parData & 0xFFF;
598 0 : break;
599 : case 5:
600 : // FEC_RO_A
601 0 : fActiveFECsA = parData & 0xFFFF;
602 0 : break;
603 : case 6:
604 : // FEC_RO_B
605 0 : fActiveFECsB = parData & 0xFFFF;
606 0 : break;
607 : case 7:
608 : // RDO_CFG1
609 0 : fAltroCFG1 = parData & 0xFFFFF;
610 0 : break;
611 : case 8:
612 : // RDO_CFG2
613 0 : fAltroCFG2 = parData & 0x1FFFFFF;
614 0 : break;
615 : default:
616 0 : fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
617 0 : AliWarning(Form("Undefined parameter code %d, ignore it !",
618 : parCode));
619 0 : break;
620 : }
621 : }
622 :
623 74 : if (index < 4) {
624 0 : fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
625 0 : fRCUTrailerSize,
626 0 : fRawReader->GetDataSize()));
627 0 : AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
628 : fRCUTrailerSize,
629 : fRawReader->GetDataSize()));
630 0 : }
631 74 : fRCUTrailerData = fData + index;
632 :
633 74 : Int_t position = Get32bitWord(index);
634 :
635 :
636 74 : return position;
637 : }
638 :
639 : //_____________________________________________________________________________
640 : Double_t AliAltroRawStream::GetTSample() const
641 : {
642 : // Returns the sampling time
643 : // in seconds. In case the rcu trailer
644 : // was note read, return an invalid number (0)
645 :
646 0 : if (!fRCUTrailerData) return 0.;
647 :
648 : const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
649 0 : UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
650 : Double_t tSample;
651 0 : switch (fq) {
652 : case 0:
653 : // 20 MHz
654 : tSample = 2.0*kLHCTimeSample;
655 0 : break;
656 : case 1:
657 : // 10 Mhz
658 : tSample = 4.0*kLHCTimeSample;
659 0 : break;
660 : case 2:
661 : // 5 MHz
662 : tSample = 8.0*kLHCTimeSample;
663 0 : break;
664 : default:
665 0 : AliWarning(Form("Invalid sampling frequency value %d !",
666 : fq));
667 : tSample = 0.;
668 0 : break;
669 : }
670 :
671 : return tSample;
672 0 : }
673 :
674 : //_____________________________________________________________________________
675 : Double_t AliAltroRawStream::GetL1Phase() const
676 : {
677 : // Returns the L1 phase w.r.t to the
678 : // LHC clock
679 0 : if (!fRCUTrailerData) return 0.;
680 :
681 : const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
682 0 : Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
683 :
684 0 : Double_t tSample = GetTSample();
685 0 : if (phase >= tSample) {
686 0 : AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
687 : phase,tSample));
688 : phase = 0.;
689 0 : }
690 :
691 : return phase;
692 0 : }
693 :
694 : //_____________________________________________________________________________
695 : void AliAltroRawStream::PrintRCUTrailer() const
696 : {
697 : // Prints the contents of
698 : // the RCU trailer data
699 0 : printf("RCU trailer:\n===========\n");
700 0 : printf("FECERRA: 0x%x\nFECERRB: 0x%x\n",fFECERRA,fFECERRB);
701 0 : printf("ERRREG2: 0x%x\n",fERRREG2);
702 0 : printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
703 0 : printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
704 0 : printf("Active FECs (branch A): 0x%x\nActive FECs (branch B): 0x%x\n",fActiveFECsA,fActiveFECsB);
705 0 : printf("Baseline corr: 0x%x\n",GetBaselineCorr());
706 0 : printf("Number of presamples: %d\nNumber of postsamples: %d\n",GetNPresamples(),GetNPostsamples());
707 0 : printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
708 0 : printf("GlitchFilter: %d\n",GetGlitchFilter());
709 0 : printf("Number of non-ZS postsamples: %d\nNumber of non-ZS presamples: %d\n",GetNNonZSPostsamples(),GetNNonZSPresamples());
710 0 : printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
711 0 : printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
712 0 : printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
713 0 : printf("Sparse readout: %d\n",GetSparseRO());
714 0 : printf("Sampling time: %e s\n",GetTSample());
715 0 : printf("L1 Phase: %e s\n",GetL1Phase());
716 0 : printf("AltroCFG1: 0x%x\nAltroCFG2: 0x%x\n",GetAltroCFG1(),GetAltroCFG2());
717 0 : printf("===========\n");
718 0 : }
719 :
720 : //_____________________________________________________________________________
721 : Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
722 : {
723 : // Return a pointer to the RCU trailer
724 : // data. Should be called always after
725 : // the RCU trailer was already processed
726 : // in the GetPosition() method
727 222 : if (!fRCUTrailerSize || !fRCUTrailerData) {
728 0 : AliError("No valid RCU trailer data is found !");
729 0 : data = NULL;
730 0 : return kFALSE;
731 : }
732 :
733 74 : data = fRCUTrailerData;
734 :
735 74 : return kTRUE;
736 74 : }
737 :
738 : //_____________________________________________________________________________
739 : void AliAltroRawStream::PrintDebug() const
740 : {
741 : // The method prints all the available
742 : // debug information.
743 : // Its is used in case of decoding errors.
744 :
745 0 : AliError("Start of debug printout\n--------------------");
746 :
747 0 : Dump();
748 0 : if (fRawReader) fRawReader->Dump();
749 :
750 0 : AliError("End of debug printout\n--------------------");
751 0 : }
752 :
753 : //_____________________________________________________________________________
754 : Int_t AliAltroRawStream::GetBranch() const
755 : {
756 : // The method provides the RCU branch index (0 or 1)
757 : // for the current hardware address.
758 : // In case the hardware address has not been yet
759 : // initialized, the method returns -1
760 0 : if (fHWAddress == -1) return -1;
761 :
762 0 : return ((fHWAddress >> 11) & 0x1);
763 0 : }
764 :
765 : //_____________________________________________________________________________
766 : Int_t AliAltroRawStream::GetFEC() const
767 : {
768 : // The method provides the front-end card index
769 : // for the current hardware address.
770 : // In case the hardware address has not been yet
771 : // initialized, the method returns -1
772 0 : if (fHWAddress == -1) return -1;
773 :
774 0 : return ((fHWAddress >> 7) & 0xF);
775 0 : }
776 :
777 : //_____________________________________________________________________________
778 : Int_t AliAltroRawStream::GetAltro() const
779 : {
780 : // The method provides the altro chip index
781 : // for the current hardware address.
782 : // In case the hardware address has not been yet
783 : // initialized, the method returns -1
784 0 : if (fHWAddress == -1) return -1;
785 :
786 0 : return ((fHWAddress >> 4) & 0x7);
787 0 : }
788 :
789 : //_____________________________________________________________________________
790 : Int_t AliAltroRawStream::GetChannel() const
791 : {
792 : // The method provides the channel index
793 : // for the current hardware address.
794 : // In case the hardware address has not been yet
795 : // initialized, the method returns -1
796 0 : if (fHWAddress == -1) return -1;
797 :
798 0 : return (fHWAddress & 0xF);
799 0 : }
800 :
801 : //_____________________________________________________________________________
802 : void AliAltroRawStream::AddMappingErrorLog(const char *message)
803 : {
804 : // Signal a mapping error
805 : // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
806 : // classes in order to log an error related to bad altro mapping
807 :
808 0 : if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
809 0 : }
810 :
811 : //_____________________________________________________________________________
812 : Int_t AliAltroRawStream::GetRCUPayloadSizeInSOD() const
813 : {
814 : // Get the size of the RCU data in case
815 : // of SOD events
816 0 : if (fRawReader) {
817 0 : if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
818 0 : return fPosition;
819 : }
820 : }
821 0 : return -1;
822 0 : }
|