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