]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - RAW/AliAltroRawStreamV3.cxx
Merge branch 'master' into TPCdev
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStreamV3.cxx
... / ...
CommitLineData
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///////////////////////////////////////////////////////////////////////////////
17///
18/// This is a base class for reading raw data digits in Altro format.
19/// The class is able to read the RCU v3 and above formats.
20/// The main difference between the format V3 and older ones is in
21/// the coding of the 10-bit Altro payload words. In V3 3 10-bit words
22/// are coded in one 32-bit word. The bits 30 and 31 are used to identify
23/// the payload, altro header and RCU trailer contents.
24///
25///
26/// cvetan.cheshkov@cern.ch 1/04/2009
27///////////////////////////////////////////////////////////////////////////////
28
29#include "AliAltroRawStreamV3.h"
30#include "AliRawReader.h"
31#include "AliLog.h"
32#include "AliAltroRawStream.h"
33#include "AliRawEventHeaderBase.h"
34
35ClassImp(AliAltroRawStreamV3)
36
37
38//_____________________________________________________________________________
39AliAltroRawStreamV3::AliAltroRawStreamV3(AliRawReader* rawReader) :
40 fIsShortDataHeader(kFALSE),
41 fDDLNumber(-1),
42 fRCUId(-1),
43 fHWAddress(-1),
44 fRawReader(rawReader),
45 fData(NULL),
46 fChannelStartPos(-1),
47 fPosition(-1),
48 fCount(-1),
49 fStartTimeBin(-1),
50 fBunchLength(-1),
51 fBadChannel(kFALSE),
52 fPayloadSize(-1),
53 fChannelPayloadSize(-1),
54 fBunchDataPointer(NULL),
55 fBunchDataIndex(-1),
56 fRCUTrailerData(NULL),
57 fRCUTrailerSize(0),
58 fFECERRA(0),
59 fFECERRB(0),
60 fERRREG2(0),
61 fERRREG3(0),
62 fActiveFECsA(0),
63 fActiveFECsB(0),
64 fAltroCFG1(0),
65 fAltroCFG2(0),
66 fOldStream(NULL),
67 fCheckAltroPayload(kTRUE),
68 fFormatVersion(0)
69{
70 // Constructor
71 // Create an object to read Altro raw digits in
72 // RCU version 3 and beyond format
73 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = 0;
74}
75
76//_____________________________________________________________________________
77AliAltroRawStreamV3::~AliAltroRawStreamV3()
78{
79// destructor
80// delete old stream object if one exists
81 if (fOldStream) delete fOldStream;
82}
83
84//_____________________________________________________________________________
85AliAltroRawStreamV3::AliAltroRawStreamV3(const AliAltroRawStreamV3& stream) :
86 TObject(stream),
87 fIsShortDataHeader(stream.fIsShortDataHeader),
88 fDDLNumber(stream.fDDLNumber),
89 fRCUId(stream.fRCUId),
90 fHWAddress(stream.fHWAddress),
91 fRawReader(stream.fRawReader),
92 fData(stream.fData),
93 fChannelStartPos(stream.fChannelStartPos),
94 fPosition(stream.fPosition),
95 fCount(stream.fCount),
96 fStartTimeBin(stream.fStartTimeBin),
97 fBunchLength(stream.fBunchLength),
98 fBadChannel(stream.fBadChannel),
99 fPayloadSize(stream.fPayloadSize),
100 fChannelPayloadSize(stream.fChannelPayloadSize),
101 fBunchDataPointer(stream.fBunchDataPointer),
102 fBunchDataIndex(stream.fBunchDataIndex),
103 fRCUTrailerData(stream.fRCUTrailerData),
104 fRCUTrailerSize(stream.fRCUTrailerSize),
105 fFECERRA(stream.fFECERRA),
106 fFECERRB(stream.fFECERRB),
107 fERRREG2(stream.fERRREG2),
108 fERRREG3(stream.fERRREG3),
109 fActiveFECsA(stream.fActiveFECsA),
110 fActiveFECsB(stream.fActiveFECsB),
111 fAltroCFG1(stream.fAltroCFG1),
112 fAltroCFG2(stream.fAltroCFG2),
113 fOldStream(NULL),
114 fCheckAltroPayload(stream.fCheckAltroPayload),
115 fFormatVersion(0)
116{
117 // Copy constructor
118 // Copy the bunch data array
119 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
120
121 if (stream.fOldStream)
122 fOldStream = new AliAltroRawStream(*stream.fOldStream);
123}
124
125//_____________________________________________________________________________
126AliAltroRawStreamV3& AliAltroRawStreamV3::operator = (const AliAltroRawStreamV3& stream)
127{
128 // assignment operator
129 // ...
130 if(&stream == this) return *this;
131
132 fIsShortDataHeader = stream.fIsShortDataHeader;
133 fDDLNumber = stream.fDDLNumber;
134 fRCUId = stream.fRCUId;
135 fHWAddress = stream.fHWAddress;
136 fRawReader = stream.fRawReader;
137 fData = stream.fData;
138 fChannelStartPos = stream.fChannelStartPos;
139 fPosition = stream.fPosition;
140 fCount = stream.fCount;
141 fStartTimeBin = stream.fStartTimeBin;
142 fBunchLength = stream.fBunchLength;
143 fBadChannel = stream.fBadChannel;
144 fPayloadSize = stream.fPayloadSize;
145 fChannelPayloadSize= stream.fChannelPayloadSize;
146 fBunchDataPointer = stream.fBunchDataPointer;
147 fBunchDataIndex = stream.fBunchDataIndex;
148 fRCUTrailerData = stream.fRCUTrailerData;
149 fRCUTrailerSize = stream.fRCUTrailerSize;
150 fFECERRA = stream.fFECERRA;
151 fFECERRB = stream.fFECERRB;
152 fERRREG2 = stream.fERRREG2;
153 fERRREG3 = stream.fERRREG3;
154 fActiveFECsA = stream.fActiveFECsA;
155 fActiveFECsB = stream.fActiveFECsB;
156 fAltroCFG1 = stream.fAltroCFG1;
157 fAltroCFG2 = stream.fAltroCFG2;
158 fFormatVersion = stream.fFormatVersion;
159
160 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
161
162 if (stream.fOldStream) {
163 if (fOldStream) delete fOldStream;
164 fOldStream = new AliAltroRawStream(stream.fRawReader);
165 *fOldStream = *stream.fOldStream;
166 }
167
168 fCheckAltroPayload = stream.fCheckAltroPayload;
169
170 return *this;
171}
172
173//_____________________________________________________________________________
174void AliAltroRawStreamV3::Reset()
175{
176// Complete reset of raw stream params
177// Reset of the raw-reader as well
178
179 fDDLNumber = fRCUId = fHWAddress = -1;
180 fChannelStartPos = -1;
181 fPosition = fCount = -1;
182 fBunchLength = fStartTimeBin = -1;
183 fBadChannel = kFALSE;
184 fPayloadSize = -1;
185 fChannelPayloadSize = -1;
186 fBunchDataPointer = NULL;
187 fBunchDataIndex = -1;
188
189 fRCUTrailerData = NULL;
190 fRCUTrailerSize = 0;
191
192 fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
193
194 if (fRawReader) fRawReader->Reset();
195
196 if (fOldStream) fOldStream->Reset();
197}
198
199//_____________________________________________________________________________
200Bool_t AliAltroRawStreamV3::NextDDL()
201{
202// Read the next DDL payload (CDH + RCU trailer)
203// Updates the information which is coming from these
204// two sources
205 fFormatVersion = 0;
206 fPosition = 0;
207 // Get next DDL payload
208 // return wtih false in case no more data payloads
209 // are found
210 do {
211 if (!fRawReader->ReadNextData(fData)) return kFALSE;
212 } while (fRawReader->GetDataSize() == 0);
213
214 fDDLNumber = fRawReader->GetDDLID();
215 fChannelPayloadSize = -1;
216 fChannelStartPos = -1;
217
218 fFormatVersion = (fRawReader->GetBlockAttributes() & 0xF);
219
220 if (fFormatVersion < 2) {
221 // old altro format data
222 if (!fOldStream) {
223 fOldStream = new AliAltroRawStream(fRawReader);
224 AliInfo(Form("RCU firmware verion %d detected. Using AliAltroRawStream to decode the data.",
225 fFormatVersion));
226 }
227 Bool_t status = fOldStream->NextDDL(fData);
228 if (status) {
229 fRCUId = fOldStream->GetRCUId();
230 fRCUTrailerSize = fOldStream->GetRCUTrailerSize();
231 fOldStream->GetRCUTrailerData(fRCUTrailerData);
232 fFECERRA = fOldStream->GetFECERRA();
233 fFECERRB = fOldStream->GetFECERRB();
234 fERRREG2 = fOldStream->GetERRREG2();
235 fERRREG3 = ((UInt_t)fOldStream->GetNChAddrMismatch()) |
236 (((UInt_t)fOldStream->GetNChLengthMismatch()) << 12);
237 fActiveFECsA = fOldStream->GetActiveFECsA();
238 fActiveFECsB = fOldStream->GetActiveFECsB();
239 fAltroCFG1 = fOldStream->GetAltroCFG1();
240 fAltroCFG2 = fOldStream->GetAltroCFG2();
241 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData)
242 fPayloadSize = fOldStream->GetRCUPayloadSizeInSOD();
243 }
244 return status;
245 }
246
247 return ReadRCUTrailer(fFormatVersion);
248}
249
250//_____________________________________________________________________________
251Bool_t AliAltroRawStreamV3::NextChannel()
252{
253 // Read the next Altro channel from the
254 // raw-data stream
255 // Updates the channel hardware address member and
256 // channel data size. Sets the error flag in case
257 // RCU signals readout error in this channel
258 if (fOldStream) {
259 Bool_t status = fOldStream->NextChannel();
260 if (status) {
261 fHWAddress = fOldStream->GetHWAddress();
262 fChannelPayloadSize = fOldStream->GetChannelPayloadSize();
263 }
264 return status;
265 }
266
267 Int_t channelStartPos=fPosition;
268 fChannelStartPos = -1;
269 fCount = -1;
270 fBadChannel = kFALSE;
271 fBunchDataIndex = 0;
272 fBunchLength = -1;
273
274 UInt_t word = 0;
275 do {
276 word = Get32bitWord(fPosition++);
277 if (fPosition > fPayloadSize) return kFALSE;
278 }
279 while ((word >> 30) != 1);
280
281 // check for readout errors
282 fBadChannel = (word >> 29) & 0x1;
283
284 // extract channel payload and hw address
285 fCount = (word >> 16) & 0x3FF;
286 fChannelPayloadSize = fCount;
287 fHWAddress = word & 0xFFF;
288
289 // Now unpack the altro data
290 // Revert the order of the samples
291 // inside the bunch so that the
292 // first time is first in the samples
293 // array
294 Int_t isample = 0;
295 Int_t nwords = (fCount+2)/3;
296 for (Int_t iword = 0; iword < nwords; iword++) {
297 word = Get32bitWord(fPosition++);
298 if ((word >> 30) != 0) {
299 // Unexpected end of altro channel payload
300 AliWarning(Form("Unexpected end of payload in altro channel payload! DDL=%03d, Address=0x%x, word=0x%x",
301 fDDLNumber,fHWAddress,word));
302 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
303 if (AliDebugLevel() > 0) HexDumpChannel();
304 fCount = -1;
305 fPosition--;
306 return kFALSE;
307 }
308 fBunchData[isample++] = (word >> 20) & 0x3FF;
309 fBunchData[isample++] = (word >> 10) & 0x3FF;
310 fBunchData[isample++] = word & 0x3FF;
311 }
312
313 fChannelStartPos=channelStartPos;
314 return kTRUE;
315}
316
317//_____________________________________________________________________________
318Bool_t AliAltroRawStreamV3::NextBunch()
319{
320 // Read next altro bunch from the
321 // raw-data stream.
322 // Updates the start/end time-bins
323 // and the array with altro samples
324 if (fOldStream) {
325 Bool_t status = fOldStream->NextBunch(fBunchData,fBunchLength,fStartTimeBin);
326 if (status) fBunchDataPointer = &fBunchData[0];
327 else fBunchDataPointer = NULL;
328 return status;
329 }
330
331 Int_t prevTimeBin = (fBunchLength > 0) ? fStartTimeBin-fBunchLength+1 : 1024;
332 fBunchLength = fStartTimeBin = -1;
333 fBunchDataPointer = NULL;
334
335 if ((fBunchDataIndex >= fCount) || fBadChannel) return kFALSE;
336
337 fBunchLength = fBunchData[fBunchDataIndex];
338 if (fBunchLength <= 2) {
339 // Invalid bunch size
340 AliDebug(1,Form("Too short bunch length (%d) @ %d in Address=0x%x (DDL=%03d)!",
341 fBunchLength,fBunchDataIndex,fHWAddress,fDDLNumber));
342 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
343 if (AliDebugLevel() > 0) HexDumpChannel();
344 fCount = fBunchLength = -1;
345 return kFALSE;
346 }
347 if ((fBunchDataIndex + fBunchLength) > fCount) {
348 // Too long bunch detected
349 AliDebug(1,Form("Too long bunch detected @ %d in Address=0x%x (DDL=%03d) ! Expected <= %d 10-bit words, found %d !", fBunchDataIndex,
350 fHWAddress,fDDLNumber,fCount-fBunchDataIndex,fBunchLength));
351 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
352 if (AliDebugLevel() > 0) HexDumpChannel();
353 fCount = fBunchLength = -1;
354 return kFALSE;
355 }
356 fBunchDataIndex++;
357 fBunchLength -= 2;
358
359 fStartTimeBin = fBunchData[fBunchDataIndex++];
360 if (fCheckAltroPayload) {
361 if ((fStartTimeBin-fBunchLength+1) < 0) {
362 AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d-%d+1) < 0", fBunchDataIndex-1,
363 fHWAddress,fDDLNumber,fStartTimeBin,fBunchLength));
364 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
365 if (AliDebugLevel() > 0) HexDumpChannel();
366 fCount = fBunchLength = -1;
367 return kFALSE;
368 }
369 if (fStartTimeBin >= prevTimeBin) {
370 AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d>=%d)", fBunchDataIndex-1,
371 fHWAddress,fDDLNumber,fStartTimeBin,prevTimeBin));
372 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
373 if (AliDebugLevel() > 0) HexDumpChannel();
374 fCount = fBunchLength = -1;
375 return kFALSE;
376 }
377 }
378
379 fBunchDataPointer = &fBunchData[fBunchDataIndex];
380
381 fBunchDataIndex += fBunchLength;
382
383 return kTRUE;
384}
385
386//_____________________________________________________________________________
387const UChar_t *AliAltroRawStreamV3::GetChannelPayload() const
388{
389 //returns raw channel data, length 4+(fChannelPayloadSize+2)/3*4
390 if (fChannelStartPos<0 || fChannelPayloadSize<0) return NULL;
391 Int_t channelSize=1+(fChannelPayloadSize+2)/3; // nof 32bit words
392 if (fPosition<fChannelStartPos+channelSize) return NULL;
393 return fData+(fChannelStartPos<<2);
394}
395
396//_____________________________________________________________________________
397UInt_t AliAltroRawStreamV3::Get32bitWord(Int_t index) const
398{
399 // This method returns the 32 bit word at a given
400 // position inside the raw data payload.
401 // The 'index' points to the beginning of the word.
402 // The method is supposed to be endian (platform)
403 // independent.
404
405 index = (index << 2);
406 UInt_t word = 0;
407 word |= fData[index++];
408 word |= fData[index++] << 8;
409 word |= fData[index++] << 16;
410 word |= fData[index++] << 24;
411
412 return word;
413}
414
415///_____________________________________________________________________________
416Bool_t AliAltroRawStreamV3::ReadRCUTrailer(UChar_t rcuVer)
417{
418 // Read the RCU trailer according
419 // to the RCU formware version
420 // specified in CDH
421 // Cross-check with version found in the
422 // trailer
423
424 fRCUTrailerData = NULL;
425 fRCUTrailerSize = 0;
426 fPayloadSize = -1;
427
428 Int_t index = fRawReader->GetDataSize()/4;
429
430 // First read 32-bit word with the
431 // trailer size (7 bits), RCU ID (9 bits) and
432 // RCU firmware version (8 bits?)
433 // The two major bit should be 11 (identifies
434 // the end of the trailer)
435 UInt_t word = Get32bitWord(--index);
436
437 if ((word >> 30) != 3) {
438 fRawReader->AddFatalErrorLog(kRCUTrailerErr,"");
439 AliError("Last RCU trailer word not found!");
440 return kFALSE;
441 }
442
443 UChar_t ver = (word >> 16) & 0xFF;
444 if (ver != rcuVer) {
445 // Wrong RCU firmware version detected
446 fRawReader->AddMajorErrorLog(kRCUVerErr,Form("%d!=%d",
447 ver,rcuVer));
448 AliDebug(1,Form("Wrong RCU firmware version detected: %d != %d",
449 ver,rcuVer));
450 }
451
452 fRCUId = (Int_t)((word >> 7) & 0x1FF);
453 Int_t trailerSize = (word & 0x7F);
454
455 // Now read the beginning of the trailer
456 // where the payload size is written
457 if (trailerSize < 2) {
458 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
459 trailerSize*4));
460 AliWarning(Form("Invalid trailer size found (%d bytes) !",
461 trailerSize*4));
462 return kFALSE;
463 }
464
465 trailerSize -= 2;
466 fRCUTrailerSize = trailerSize*4;
467
468 for (; trailerSize > 0; trailerSize--) {
469 word = Get32bitWord(--index);
470 if ((word >> 30) != 2) {
471 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"missing 10");
472 AliWarning("Missing RCU trailer identifier pattern!");
473 continue;
474 }
475 Int_t parCode = (word >> 26) & 0xF;
476 Int_t parData = word & 0x3FFFFFF;
477 switch (parCode) {
478 case 1:
479 // ERR_REG1
480 fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
481 fFECERRB = ((parData & 0x1FFF)) << 7;
482 break;
483 case 2:
484 // ERR_REG2
485 fERRREG2 = parData & 0x1FF;
486 break;
487 case 3:
488 // ERR_REG3
489 fERRREG3 = parData & 0x1FFFFFF;
490 break;
491 case 4:
492 // FEC_RO_A
493 fActiveFECsA = parData & 0xFFFF;
494 break;
495 case 5:
496 // FEC_RO_B
497 fActiveFECsB = parData & 0xFFFF;
498 break;
499 case 6:
500 // RDO_CFG1
501 fAltroCFG1 = parData & 0xFFFFF;
502 break;
503 case 7:
504 // RDO_CFG2
505 fAltroCFG2 = parData & 0x1FFFFFF;
506 break;
507 default:
508 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
509 AliWarning(Form("Undefined parameter code %d, ignore it !",
510 parCode));
511 break;
512 }
513 }
514
515 if (index < 1) {
516 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
517 fRCUTrailerSize+8,
518 fRawReader->GetDataSize()));
519 AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
520 fRCUTrailerSize,
521 fRawReader->GetDataSize()));
522 }
523
524 fRCUTrailerData = fData + index*4;
525
526 // Now read the payload size
527 // (First word in the RCU trailer)
528 fPayloadSize = Get32bitWord(--index) & 0x3FFFFFF;
529
530 if ((fRawReader->GetDataSize() - fRCUTrailerSize - 8) != (fPayloadSize*4)) {
531 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
532 fRawReader->GetDataSize(),
533 fRCUTrailerSize+8,
534 fPayloadSize*4));
535 AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
536 fRawReader->GetDataSize(),
537 fRCUTrailerSize+8,
538 fPayloadSize*4));
539 }
540
541 return kTRUE;
542}
543
544//_____________________________________________________________________________
545Int_t AliAltroRawStreamV3::GetBranch() const
546{
547 // The method provides the RCU branch index (0 or 1)
548 // for the current hardware address.
549 // In case the hardware address has not been yet
550 // initialized, the method returns -1
551 if (fHWAddress == -1) return -1;
552
553 return ((fHWAddress >> 11) & 0x1);
554}
555
556//_____________________________________________________________________________
557Int_t AliAltroRawStreamV3::GetFEC() const
558{
559 // The method provides the front-end card index
560 // for the current hardware address.
561 // In case the hardware address has not been yet
562 // initialized, the method returns -1
563 if (fHWAddress == -1) return -1;
564
565 return ((fHWAddress >> 7) & 0xF);
566}
567
568//_____________________________________________________________________________
569Int_t AliAltroRawStreamV3::GetAltro() const
570{
571 // The method provides the altro chip index
572 // for the current hardware address.
573 // In case the hardware address has not been yet
574 // initialized, the method returns -1
575 if (fHWAddress == -1) return -1;
576
577 return ((fHWAddress >> 4) & 0x7);
578}
579
580//_____________________________________________________________________________
581Int_t AliAltroRawStreamV3::GetChannel() const
582{
583 // The method provides the channel index
584 // for the current hardware address.
585 // In case the hardware address has not been yet
586 // initialized, the method returns -1
587 if (fHWAddress == -1) return -1;
588
589 return (fHWAddress & 0xF);
590}
591
592//_____________________________________________________________________________
593Bool_t AliAltroRawStreamV3::GetRCUTrailerData(UChar_t*& data) const
594{
595 // Return a pointer to the RCU trailer
596 // data. Should be called always after
597 // the RCU trailer was already processed
598 // in the GetPosition() method
599 if (!fRCUTrailerSize || !fRCUTrailerData) {
600 AliError("No valid RCU trailer data is found !");
601 data = NULL;
602 return kFALSE;
603 }
604
605 data = fRCUTrailerData;
606
607 return kTRUE;
608}
609
610//_____________________________________________________________________________
611void AliAltroRawStreamV3::PrintRCUTrailer() const
612{
613 // Prints the contents of
614 // the RCU trailer data
615 printf("RCU trailer (Format version %d):\n"
616 "==================================================\n", GetFormatVersion());
617 printf("FECERRA: 0x%x\n", fFECERRA);
618 printf("FECERRB: 0x%x\n", fFECERRB);
619 printf("ERRREG2: 0x%x\n", fERRREG2);
620 printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
621 printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
622 printf("Active FECs (branch A): 0x%x\n", fActiveFECsA);
623 printf("Active FECs (branch B): 0x%x\n", fActiveFECsB);
624 printf("Baseline corr: 0x%x\n",GetBaselineCorr());
625 printf("Number of presamples: %d\n", GetNPresamples());
626 printf("Number of postsamples: %d\n",GetNPostsamples());
627 printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
628 printf("GlitchFilter: %d\n",GetGlitchFilter());
629 printf("Number of non-ZS postsamples: %d\n",GetNNonZSPostsamples());
630 printf("Number of non-ZS presamples: %d\n",GetNNonZSPresamples());
631 printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
632 printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
633 printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
634 printf("Sparse readout: %d\n",GetSparseRO());
635 printf("Sampling time: %e s\n",GetTSample());
636 printf("L1 Phase: %e s\n",GetL1Phase());
637 printf("AltroCFG1: 0x%x\n",GetAltroCFG1());
638 printf("AltroCFG2: 0x%x\n",GetAltroCFG2());
639 printf("==================================================\n");
640}
641
642//_____________________________________________________________________________
643void AliAltroRawStreamV3::SelectRawData(Int_t detId)
644{
645 // Select the raw data for specific
646 // detector id
647 AliDebug(1,Form("Selecting raw data for detector %d",detId));
648 fRawReader->Select(detId);
649}
650
651//_____________________________________________________________________________
652void AliAltroRawStreamV3::SelectRawData(const char *detName)
653{
654 // Select the raw data for specific
655 // detector name
656 AliDebug(1,Form("Selecting raw data for detector %s",detName));
657 fRawReader->Select(detName);
658}
659
660//_____________________________________________________________________________
661Double_t AliAltroRawStreamV3::GetTSample() const
662{
663 // Returns the sampling time
664 // in seconds. In case the rcu trailer
665 // was note read, return an invalid number (0)
666
667 if (!fRCUTrailerData) return 0.;
668
669 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
670 UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
671 Double_t tSample;
672 switch (fq) {
673 case 0:
674 // 20 MHz
675 tSample = 2.0*kLHCTimeSample;
676 break;
677 case 1:
678 // 10 Mhz
679 tSample = 4.0*kLHCTimeSample;
680 break;
681 case 2:
682 // 5 MHz
683 tSample = 8.0*kLHCTimeSample;
684 break;
685 default:
686 AliWarning(Form("Invalid sampling frequency value %d !",
687 fq));
688 tSample = 0.;
689 break;
690 }
691
692 return tSample;
693}
694
695//_____________________________________________________________________________
696Double_t AliAltroRawStreamV3::GetL1Phase() const
697{
698 // Returns the L1 phase w.r.t to the
699 // LHC clock
700 if (!fRCUTrailerData) return 0.;
701
702 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
703 Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
704
705 Double_t tSample = GetTSample();
706 if (phase >= tSample) {
707 AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
708 phase,tSample));
709 phase = 0.;
710 }
711
712 return phase;
713}
714
715//_____________________________________________________________________________
716void AliAltroRawStreamV3::AddMappingErrorLog(const char *message)
717{
718 // Signal a mapping error
719 // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
720 // classes in order to log an error related to bad altro mapping
721
722 if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
723}
724
725//_____________________________________________________________________________
726UChar_t *AliAltroRawStreamV3::GetRCUPayloadInSOD() const
727{
728 // Get a pointer to the data in case
729 // of SOD events
730 if (fRawReader) {
731 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
732 return fData;
733 }
734 }
735 return NULL;
736}
737
738//_____________________________________________________________________________
739Int_t AliAltroRawStreamV3::GetRCUPayloadSizeInSOD() const
740{
741 // Get the size of the RCU data in case
742 // of SOD events
743 if (fRawReader) {
744 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
745 return fPayloadSize;
746 }
747 }
748 return -1;
749}
750
751//_____________________________________________________________________________
752
753void AliAltroRawStreamV3::HexDumpChannel() const
754{
755 // Print of the Hex Data of the current channel
756 // to decipher read-out warnings and errors
757 if (fCount>0 && fPosition>0) {
758 printf("Hex-Dump of DDL: %3d, RCU ID: %d, HWADDR: 0x%03x\n",
759 fDDLNumber,fRCUId,fHWAddress);
760 printf("32-bit - 2bit 10bit 10bit 10bit - ");
761 printf("Index 10bit 10bit 10bit\n");
762 printf("********** **** ***** ***** ***** - ");
763 printf("***** ****** ****** ******\n");
764 Int_t nwords = (fCount+2)/3+1;
765 for (Int_t iword = 0; iword < nwords; iword++) {
766 UInt_t word32 = Get32bitWord(fPosition-nwords+iword);
767 UInt_t marker = word32 >> 30 & 0x3;
768 UInt_t word101 = word32 >> 20 & 0x3FF;
769 UInt_t word102 = word32 >> 10 & 0x3FF;
770 UInt_t word103 = word32 >> 00 & 0x3FF; // nice octal number
771 printf("0x%08x - 0b%1d%1d 0x%03x 0x%03x 0x%03x",
772 word32,marker>>1,marker&0x1,word101,word102,word103);
773 if (iword == 0) { printf(" - Channel Header\n"); continue; }
774 Int_t base = 3*(iword-1);
775 printf(" - %5d 0x%03x%c 0x%03x%c 0x%03x%c\n", base,
776 fBunchData[base], (fBunchDataIndex == base ? '*' : ' '),
777 fBunchData[base+1], (fBunchDataIndex == base+1 ? '*' : ' '),
778 fBunchData[base+2], (fBunchDataIndex == base+2 ? '*' : ' '));
779 }
780 }
781}