]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TRD/AliTRDrawStream.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStream.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// Decoding data from the TRD raw stream //
19// and translation into ADC values, on-line tracklets and tracks //
20// //
21// CRC checks rely on boost, and are enabled only when TRD_RAW_CRC //
22// is defined //
23// //
24// Additional debug features can be enabled by defining TRD_RAW_DEBUG //
25// //
26// Author: J. Klein (jochen.klein@cern.ch) //
27// //
28////////////////////////////////////////////////////////////////////////////
29
30#include <cstdio>
31#include <cstdarg>
32
33#if defined(TRD_RAW_CRC)
34#include <boost/crc.hpp>
35#endif
36
37#include "TClonesArray.h"
38#include "TTree.h"
39
40#include "AliLog.h"
41#include "AliRawReader.h"
42#include "AliTRDcalibDB.h"
43#include "AliTRDdigitsManager.h"
44#include "AliTRDdigitsParam.h"
45#include "AliTRDcalibDB.h"
46#include "AliTRDmcmSim.h"
47#include "AliTRDtrapConfig.h"
48#include "AliTRDarrayADC.h"
49#include "AliTRDarrayDictionary.h"
50#include "AliTRDSignalIndex.h"
51#include "AliTRDtrackletWord.h"
52#include "AliTRDtrackletMCM.h"
53#include "AliESDTrdTrack.h"
54
55#include "AliTRDrawStream.h"
56
57ClassImp(AliTRDrawStream)
58
59// some static information
60Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
61 8, 9, 10, 11,
62 4, 5, 6, 7,
63 0, 1, 2, 3};
64Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
65const Int_t AliTRDrawStream::fgkNlinks = 12;
66const Int_t AliTRDrawStream::fgkNstacks = 5;
67const Int_t AliTRDrawStream::fgkNsectors = 18;
68const Int_t AliTRDrawStream::fgkNtriggers = 12;
69const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
70const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
71const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
72
73const char* AliTRDrawStream::fgkErrorMessages[] = {
74 "Unknown error",
75 "Link monitor active",
76 "Event counter mismatch",
77 "not a TRD equipment (1024-1041)",
78 "Invalid Stack header",
79 "Invalid detector number",
80 "Invalid pad row",
81 "No digits could be retrieved from the digitsmanager",
82 "HC header mismatch",
83 "HC check bits wrong",
84 "Unexpected position in readout stream",
85 "Invalid testpattern mode",
86 "Testpattern mismatch",
87 "Number of timebins changed",
88 "ADC mask inconsistent",
89 "ADC check bits invalid",
90 "Missing ADC data",
91 "Missing expected ADC channels",
92 "Missing MCM headers",
93 "Missing TP data",
94 "CRC mismatch"
95};
96
97Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
98 0,
99 0,
100 2,
101 1,
102 0,
103 1,
104 0,
105 1,
106 0,
107 1,
108 2,
109 1,
110 0,
111 1,
112 1,
113 2,
114 1,
115 1,
116 1,
117 0,
118 0
119};
120
121AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
122 AliTRDrawStream::kTolerate,
123 AliTRDrawStream::kDiscardHC,
124 AliTRDrawStream::kTolerate,
125 AliTRDrawStream::kAbort,
126 AliTRDrawStream::kAbort,
127 AliTRDrawStream::kAbort,
128 AliTRDrawStream::kDiscardMCM,
129 AliTRDrawStream::kAbort,
130 AliTRDrawStream::kDiscardHC,
131 AliTRDrawStream::kDiscardHC,
132 AliTRDrawStream::kTolerate,
133 AliTRDrawStream::kTolerate,
134 AliTRDrawStream::kTolerate,
135 AliTRDrawStream::kTolerate,
136 AliTRDrawStream::kTolerate,
137 AliTRDrawStream::kTolerate,
138 AliTRDrawStream::kTolerate,
139 AliTRDrawStream::kTolerate,
140 AliTRDrawStream::kTolerate,
141 AliTRDrawStream::kTolerate,
142 AliTRDrawStream::kTolerate
143};
144
145AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
146 fStoreError(&AliTRDrawStream::ForgetError),
147 fRawReader(rawReader),
148 fDigitsManager(0x0),
149 fDigitsParam(0x0),
150 fErrors(0x0),
151 fLastError(),
152 fErrorFlags(0),
153 fStats(),
154 fPayloadStart(0x0),
155 fPayloadCurr(0x0),
156 fPayloadSize(0),
157 fNtimebins(-1),
158 fLastEvId(-1),
159 fCurrSlot(-1),
160 fCurrLink(-1),
161 fCurrRobPos(-1),
162 fCurrMcmPos(-1),
163 fCurrEquipmentId(0),
164 fCurrSmHeaderSize(0),
165 fCurrSmHeaderVersion(0),
166 fCurrTrailerReadout(0),
167 fCurrTrgHeaderAvail(0),
168 fCurrTrgHeaderReadout(0),
169 fCurrTrkHeaderAvail(0),
170 fCurrStackEndmarkerAvail(0),
171 fCurrEvType(0),
172 fCurrTriggerEnable(0),
173 fCurrTriggerFired(0),
174 fCurrTrackEnable(0),
175 fCurrTrackletEnable(0),
176 fCurrStackMask(0),
177#ifdef TRD_RAW_DEBUG
178 fCurrL0Count(),
179 fCurrL1aCount(),
180 fCurrL1rCount(),
181 fCurrL2aCount(),
182 fCurrL2rCount(),
183 fCurrL0offset(),
184#endif
185 fCurrTrkHeaderIndexWord(0x0),
186 fCurrTrkHeaderSize(0x0),
187 fCurrTrkFlags(0x0),
188 fCurrTrgHeaderIndexWord(0x0),
189 fCurrTrgHeaderSize(0x0),
190 fCurrTrgFlags(0x0),
191 fCurrStackIndexWord(0x0),
192 fCurrStackHeaderSize(0x0),
193 fCurrStackHeaderVersion(0x0),
194 fCurrLinkMask(0x0),
195 fCurrCleanCheckout(0x0),
196 fCurrBoardId(0x0),
197 fCurrHwRev(-1),
198 fCurrHwRevTMU(0x0),
199 fCurrLinkMonitorFlags(0x0),
200 fCurrLinkDataTypeFlags(0x0),
201 fCurrLinkDebugFlags(0x0),
202 fCurrMatchFlagsSRAM(),
203 fCurrMatchFlagsPostBP(),
204 fCurrChecksumStack(),
205 fCurrChecksumSIU(0),
206 fCurrSpecial(-1),
207 fCurrMajor(-1),
208 fCurrMinor(-1),
209 fCurrAddHcWords(-1),
210 fCurrSm(-1),
211 fCurrStack(-1),
212 fCurrLayer(-1),
213 fCurrSide(-1),
214 fCurrHC(-1),
215 fCurrCheck(-1),
216 fCurrNtimebins(-1),
217 fCurrPtrgCnt(-1),
218 fCurrPtrgPhase(-1),
219#ifdef TRD_RAW_DEBUG
220 fCurrBC(),
221#endif
222 fNDumpMCMs(0),
223 fAdcArray(0x0),
224 fSignalIndex(0x0),
225 fTracklets(0x0),
226 fTracks(0x0),
227 fMarkers(0x0)
228{
229 // default constructor
230
231 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
232 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
233 fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
234 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
235 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
236 fCurrTrgFlags = new UInt_t[fgkNsectors];
237#ifdef TRD_RAW_DEBUG
238 fCurrL0Count = new UInt_t[fgkNsectors];
239 fCurrL1aCount = new UInt_t[fgkNsectors];
240 fCurrL1rCount = new UInt_t[fgkNsectors];
241 fCurrL2aCount = new UInt_t[fgkNsectors];
242 fCurrL2rCount = new UInt_t[fgkNsectors];
243#endif
244 fCurrStackIndexWord = new UInt_t[fgkNstacks];
245 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
246 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
247 fCurrLinkMask = new UInt_t[fgkNstacks];
248 fCurrCleanCheckout = new UInt_t[fgkNstacks];
249 fCurrBoardId = new UInt_t[fgkNstacks];
250 fCurrHwRevTMU = new UInt_t[fgkNstacks];
251 fCurrLinkMonitorFlags = new UInt_t[fgkNsectors * fgkNstacks * fgkNlinks];
252 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
253 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
254 for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
255 fCurrTrgFlags[iSector] = 0;
256 for (Int_t i = 0; i < 100; i++)
257 fDumpMCM[i] = 0;
258
259 // setting up the error tree
260 fErrors = new TTree("errorStats", "Error statistics");
261 fErrors->SetDirectory(0x0);
262 fErrors->Branch("error", &fLastError);
263 fErrors->SetCircular(1000);
264 for (Int_t i = 0; i < 100; i++) {
265 fErrorBuffer[i] = 0;
266 }
267
268}
269
270AliTRDrawStream::~AliTRDrawStream()
271{
272 // destructor
273
274 delete fErrors;
275
276 delete [] fCurrTrkHeaderIndexWord;
277 delete [] fCurrTrkHeaderSize;
278 delete [] fCurrTrkFlags;
279 delete [] fCurrTrgHeaderIndexWord;
280 delete [] fCurrTrgHeaderSize;
281 delete [] fCurrTrgFlags;
282 delete [] fCurrStackIndexWord;
283 delete [] fCurrStackHeaderSize;
284 delete [] fCurrStackHeaderVersion;
285 delete [] fCurrLinkMask;
286 delete [] fCurrCleanCheckout;
287 delete [] fCurrBoardId;
288 delete [] fCurrHwRevTMU;
289 delete [] fCurrLinkMonitorFlags;
290 delete [] fCurrLinkDataTypeFlags;
291 delete [] fCurrLinkDebugFlags;
292}
293
294Bool_t AliTRDrawStream::ReadEvent()
295{
296 // read the current event from the raw reader and fill it to the digits manager
297
298 if (!fRawReader) {
299 AliError("No raw reader available");
300 return kFALSE;
301 }
302
303 // some preparations
304 fDigitsParam = 0x0;
305
306 // loop over all DDLs
307 // data starts with GTU payload, i.e. SM index word
308 UChar_t *buffer = 0x0;
309
310 while (fRawReader->ReadNextData(buffer)) {
311
312 fCurrEquipmentId = fRawReader->GetEquipmentId();
313 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
314
315 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
316 EquipmentError(kNonTrdEq, "Skipping");
317 continue;
318 }
319
320 if (fMarkers)
321 new ((*fMarkers)[fMarkers->GetEntriesFast()])
322 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
323
324 ReadGTUHeaders((UInt_t*) buffer);
325
326 if (fCurrTrailerReadout)
327 ReadGTUTrailer();
328
329#ifdef TRD_RAW_CRC
330 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumStack[5];
331 boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> checksumSIU;
332 checksumSIU.reset();
333
334 // process CDH, replace size with 0xffffffff
335 UInt_t temp = 0xffffffff;
336 checksumSIU.process_bytes(&temp, sizeof(UInt_t));
337 UInt_t *data = (UInt_t*) fRawReader->GetDataHeader();
338 checksumSIU.process_bytes(&data[1], 7*sizeof(UInt_t));
339 // process payload including everything but the SIU checksum
340 checksumSIU.process_bytes(buffer, fRawReader->GetDataSize()-4);
341
342 if (checksumSIU() != fCurrChecksumSIU) {
343 EquipmentError(kCRCmismatch, "SIU data - recalc: 0x%08x - 0x%08x", fCurrChecksumSIU, checksumSIU());
344 }
345#endif
346
347 // loop over all active links
348 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
349 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
350 fCurrSlot = iStack;
351#ifdef TRD_RAW_CRC
352 checksumStack[iStack].reset();
353#endif
354
355 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
356 continue;
357
358 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
359 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
360 fCurrLink = iLink;
361 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
362 fCurrSlot * fgkNlinks + iLink;
363 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
364 continue;
365
366#ifdef TRD_RAW_CRC
367 UInt_t *start = fPayloadCurr;
368#endif
369 Int_t size = 0;
370
371 fErrorFlags = 0;
372 // check for link monitor error flag
373 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
374 LinkError(kLinkMonitor);
375 if (fgErrorBehav[kLinkMonitor] == kTolerate)
376 size += ReadLinkData();
377 }
378 else
379 // read the data from one HC
380 size += ReadLinkData();
381
382 // read all data endmarkers
383 size += SeekNextLink();
384
385#ifdef TRD_RAW_CRC
386 // always use data for CRC calculation
387 // (even if link monitor active)
388 UShort_t crc = CalcLinkChecksum(start, size);
389 checksumStack[iStack].process_bytes(&crc, sizeof(UShort_t));
390#endif
391 }
392#ifdef TRD_RAW_CRC
393 if (fDigitsManager && (checksumStack[iStack]() != fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack])) {
394 StackError(kCRCmismatch, "data - recalc: 0x%04x - 0x%04x", fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack], checksumStack[iStack]());
395 }
396#endif
397
398 // continue with next stack
399 SeekNextStack();
400 }
401 }
402
403 return kTRUE;
404}
405
406
407Bool_t AliTRDrawStream::NextDDL()
408{
409 // continue reading with the next equipment
410
411 if (!fRawReader)
412 return kFALSE;
413
414 fCurrEquipmentId = 0;
415 fCurrSlot = 0;
416 fCurrLink = 0;
417
418 UChar_t *buffer = 0x0;
419
420 while (fRawReader->ReadNextData(buffer)) {
421
422 fCurrEquipmentId = fRawReader->GetEquipmentId();
423 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
424
425 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
426 EquipmentError(kNonTrdEq, "Skipping");
427 continue;
428 }
429
430 if (fMarkers)
431 new ((*fMarkers)[fMarkers->GetEntriesFast()])
432 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
433
434 ReadGTUHeaders((UInt_t*) buffer);
435
436 if (fCurrTrailerReadout)
437 ReadGTUTrailer();
438
439 return kTRUE;
440 }
441
442 return kFALSE;
443}
444
445
446Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
447{
448 // read the data for the next chamber
449 // in case you only want to read the data of a single chamber
450 // to read all data ReadEvent(...) is recommended
451
452 fDigitsManager = digMgr;
453 fDigitsParam = 0x0;
454
455 fErrorFlags = 0;
456
457 if (!fRawReader) {
458 AliError("No raw reader available");
459 return -1;
460 }
461
462 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
463 if (!NextDDL()) {
464 fCurrSlot = -1;
465 return -1;
466 }
467 while ((fCurrSlot < fgkNstacks) &&
468 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
469 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
470 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
471 ++fCurrSlot;
472 fCurrSlot = 0;
473 continue;
474 }
475 fCurrLink++;
476 if (fCurrLink >= fgkNlinks) {
477 SeekNextStack();
478 fCurrLink = 0;
479 fCurrSlot++;
480 }
481 }
482 }
483
484 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
485 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
486 fCurrSlot * fgkNlinks + fCurrLink;
487
488 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
489 LinkError(kLinkMonitor);
490 if (fgErrorBehav[kLinkMonitor] == kTolerate)
491 ReadLinkData();
492 }
493 else
494 // read the data from one HC
495 ReadLinkData();
496
497 // read all data endmarkers
498 SeekNextLink();
499
500 if (fCurrLink % 2 == 0) {
501 // if we just read the A-side HC then also check the B-side
502 fCurrLink++;
503 fCurrHC++;
504 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
505 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
506 LinkError(kLinkMonitor);
507 if (fgErrorBehav[kLinkMonitor] == kTolerate)
508 ReadLinkData();
509 }
510 else {
511 ReadLinkData();
512 }
513 SeekNextLink();
514 }
515 }
516
517 do {
518 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
519 fCurrLink = 0;
520 fCurrSlot++;
521 }
522 else {
523 fCurrLink++;
524 if (fCurrLink >= fgkNlinks) {
525 SeekNextStack();
526 fCurrLink = 0;
527 fCurrSlot++;
528 }
529 }
530 } while ((fCurrSlot < fgkNstacks) &&
531 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
532 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
533
534 // return chamber information from HC if it is valid
535 // otherwise return information from link position
536 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
537 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
538 else
539 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
540}
541
542
543Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
544{
545 // check the data source and read the headers
546
547 if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
548 // this is ROC data
549
550 // setting the pointer to data and current reading position
551 fPayloadCurr = fPayloadStart = buffer;
552 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
553 fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
554 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
555
556 AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
557
558 // read SM header
559 if (ReadSmHeader() < 0) {
560 AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
561 return -1;
562 }
563
564 // read tracking headers (if available)
565 if (fCurrTrkHeaderAvail) {
566 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
567 if ((fCurrStackMask & (1 << iStack)) != 0)
568 ReadTrackingHeader(iStack);
569 }
570 }
571
572 // read trigger header(s) (if available)
573 if (fCurrTrgHeaderAvail)
574 ReadTriggerHeaders();
575
576 // read stack header
577 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
578 if ((fCurrStackMask & (1 << iStack)) != 0)
579 ReadStackHeader(iStack);
580 }
581
582 return 0;
583 }
584 else
585 return -1;
586}
587
588Int_t AliTRDrawStream::ReadSmHeader()
589{
590 // read the SMU index header at the current reading position
591 // and store the information in the corresponding variables
592
593 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
594 EquipmentError(kUnknown, "SM Header incomplete");
595 return -1;
596 }
597
598 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
599
600 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
601 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
602 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
603 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
604 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
605 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
606 fCurrStackEndmarkerAvail = 0;
607
608 switch (fCurrSmHeaderVersion) {
609 case 0xb:
610 fCurrTrailerReadout = 0;
611 fCurrTrgHeaderAvail = 0;
612 fCurrEvType = 0;
613 fCurrTrkHeaderAvail = 0;
614
615 DecodeGTUtracks();
616 break;
617
618 case 0xc:
619 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
620 fCurrTrgHeaderAvail = 1;
621 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
622 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
623 fCurrTrkHeaderAvail = fCurrTrackEnable;
624 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
625 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
626 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
627 break;
628
629 case 0xd:
630 fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
631 fCurrTrgHeaderAvail = 1;
632 fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
633 fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
634 fCurrTrkHeaderAvail = fCurrTrackEnable;
635 fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
636 fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
637 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
638 fCurrStackEndmarkerAvail = 1;
639#ifdef TRD_RAW_DEBUG
640 if (fCurrSmHeaderSize > 7) {
641 fCurrL0Count[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[3];
642 fCurrL1aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[4];
643 fCurrL1rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[5];
644 fCurrL2aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[6];
645 fCurrL2rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[7];
646 }
647#endif
648 break;
649
650 default:
651 AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
652 }
653
654 AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
655 fCurrSmHeaderSize,
656 fCurrSmHeaderVersion,
657 fCurrTrackEnable,
658 fCurrTrackletEnable,
659 fCurrStackMask,
660 fCurrTrailerReadout,
661 fCurrTrgHeaderAvail,
662 fCurrTrkHeaderAvail ));
663
664 // jump to the first word after the SM header
665 fPayloadCurr += fCurrSmHeaderSize + 1;
666
667 return fCurrSmHeaderSize + 1;
668}
669
670Int_t AliTRDrawStream::DecodeGTUtracks()
671{
672 // decode GTU track words
673 // this depends on the hardware revision of the SMU
674
675 Int_t sector = fCurrEquipmentId-kDDLOffset;
676
677 if ((sector < 0) || (sector > 17)) {
678 AliError(Form("Invalid sector %i for GTU tracks", sector));
679 return -1;
680 }
681
682 AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
683 fPayloadCurr + 4, 10, 0xffe0ffff));
684
685 fCurrTrgFlags[sector] = 0;
686
687 if (fCurrHwRev < 1772) {
688 UInt_t fastWord; // fast trigger word
689 ULong64_t trackWord = 0; // extended track word
690 Int_t stack = 0;
691 Int_t idx = 0;
692 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
693 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
694 stack++;
695 idx = 0;
696 }
697 else {
698 if ((idx == 0) &&
699 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
700 fastWord = fPayloadCurr[iWord];
701 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
702 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
703 continue;
704 }
705 else if ((idx & 0x1) == 0x1) {
706 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
707 AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
708 if (fTracks) {
709 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
710 AliESDTrdTrack();
711
712 trk->SetSector(sector);
713 trk->SetStack((trackWord >> 60) & 0x7);
714 trk->SetA(0);
715 trk->SetB(0);
716 trk->SetPID(0);
717 trk->SetLayerMask((trackWord >> 16) & 0x3f);
718 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
719 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
720 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
721 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
722 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
723 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
724
725 trk->SetFlags(0);
726 trk->SetReserved(0);
727 trk->SetLabel(-3);
728
729 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
730 if (TMath::Abs(pt) > 0.1) {
731 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
732 }
733 }
734 }
735 else {
736 trackWord = fPayloadCurr[iWord];
737 }
738 idx++;
739 }
740 }
741 }
742 else if (fCurrHwRev < 1804) {
743 UInt_t fastWord; // fast trigger word
744 ULong64_t trackWord = 0; // extended track word
745 Int_t stack = 0;
746 Int_t idx = 0;
747 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
748 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
749 stack++;
750 idx = 0;
751 }
752 else {
753 if ((idx == 0) &&
754 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
755 fastWord = fPayloadCurr[iWord];
756 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
757 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
758 continue;
759 }
760 else if ((idx & 0x1) == 0x1) {
761 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
762 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
763 if (fTracks) {
764 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
765 AliESDTrdTrack();
766
767 trk->SetSector(fCurrEquipmentId-kDDLOffset);
768 trk->SetStack((trackWord >> 60) & 0x7);
769 trk->SetA(0);
770 trk->SetB(0);
771 trk->SetPID(0);
772 trk->SetLayerMask((trackWord >> 16) & 0x3f);
773 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
774 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
775 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
776 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
777 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
778 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
779
780 trk->SetFlags(0);
781 trk->SetReserved(0);
782 trk->SetLabel(-3);
783
784 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
785 if (TMath::Abs(pt) > 0.1) {
786 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
787 }
788 }
789 }
790 else {
791 trackWord = fPayloadCurr[iWord];
792 }
793 idx++;
794 }
795 }
796 }
797 else if (fCurrHwRev < 1819) {
798 UInt_t fastWord; // fast trigger word
799 ULong64_t trackWord = 0; // extended track word
800 Int_t stack = 0;
801 Int_t idx = 0;
802 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
803 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
804 stack++;
805 idx = 0;
806 }
807 else {
808 if ((idx == 0) &&
809 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
810 fastWord = fPayloadCurr[iWord];
811 if (fastWord & (1 << 13))
812 fCurrTrgFlags[sector] |= 1 << (stack+11);
813 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
814 continue;
815 }
816 else if ((idx & 0x1) == 0x1) {
817 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
818 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
819
820 if (fTracks) {
821 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
822 AliESDTrdTrack();
823
824 trk->SetSector(fCurrEquipmentId-kDDLOffset);
825 trk->SetStack((trackWord >> 60) & 0x7);
826 trk->SetA(0);
827 trk->SetB(0);
828 // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
829 trk->SetPID(0);
830 trk->SetLayerMask((trackWord >> 16) & 0x3f);
831 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
832 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
833 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
834 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
835 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
836 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
837
838 trk->SetFlags(0);
839 trk->SetReserved(0);
840 trk->SetLabel(-3);
841
842 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
843 if (TMath::Abs(pt) > 0.1) {
844 trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
845 }
846 }
847 }
848 else {
849 trackWord = fPayloadCurr[iWord];
850 }
851 idx++;
852 }
853 }
854 }
855 else if (fCurrHwRev < 1860) {
856 UInt_t fastWord; // fast trigger word
857 ULong64_t trackWord = 0; // extended track word
858 Int_t stack = 0;
859 Int_t idx = 0;
860 Bool_t upperWord = kFALSE;
861 Int_t word = 0;
862 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
863 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
864 stack++;
865 idx = 0;
866 upperWord = kFALSE;
867 }
868 else {
869 // assemble the 32-bit words out of 16-bit blocks
870 if (upperWord) {
871 word |= (fPayloadCurr[iWord] & 0xffff0000);
872 upperWord = kFALSE;
873 }
874 else {
875 // lower word is read first
876 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
877 upperWord = kTRUE;
878 continue;
879 }
880
881 if ((word & 0xffff0008) == 0x13370008) {
882 fastWord = word;
883 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
884 if (fastWord & (1 << 13))
885 fCurrTrgFlags[sector] |= 1 << (stack+11);
886 continue;
887 }
888 else if ((idx & 0x1) == 0x1) {
889 trackWord |= ((ULong64_t) word) << 32;
890 AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
891 if (fTracks) {
892 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
893 AliESDTrdTrack();
894
895 trk->SetSector(fCurrEquipmentId-kDDLOffset);
896 trk->SetStack((trackWord >> 60) & 0x7);
897 trk->SetA(0);
898 trk->SetB(0);
899 trk->SetPID(0);
900 trk->SetLayerMask((trackWord >> 16) & 0x3f);
901 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
902 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
903 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
904 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
905 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
906 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
907
908 trk->SetFlags(0);
909 trk->SetReserved(0);
910 trk->SetLabel(-3);
911
912 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
913 if (TMath::Abs(pt) > 0.1) {
914 trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
915 }
916 }
917 }
918 else {
919 trackWord = word;
920 }
921 idx++;
922 }
923 }
924
925 }
926 else {
927 ULong64_t trackWord = 0; // this is the debug word
928 Int_t stack = 0;
929 Int_t idx = 0;
930 Bool_t upperWord = kFALSE;
931 Int_t word = 0;
932 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
933 if (fPayloadCurr[iWord] == 0xffe0ffff) {
934 stack++;
935 idx = 0;
936 upperWord = kFALSE;
937 }
938 else {
939 // assemble the 32-bit words out of 16-bit blocks
940 if (upperWord) {
941 word |= (fPayloadCurr[iWord] & 0xffff0000);
942 upperWord = kFALSE;
943 }
944 else {
945 // lower word is read first
946 word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
947 upperWord = kTRUE;
948 continue;
949 }
950
951 if ((word & 0xffff0008) == 0x13370008) {
952 AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
953 continue;
954 }
955 else if ((word & 0xffff0010) == 0x13370010) {
956 AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
957 fCurrTrgFlags[sector] |= 1 << (stack+11);
958 continue;
959 }
960 else if ((idx & 0x1) == 0x1) {
961 trackWord |= ((ULong64_t) word) << 32;
962 AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
963 if (fTracks) {
964 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
965 AliESDTrdTrack();
966 trk->SetSector(fCurrEquipmentId-kDDLOffset);
967 trk->SetStack((trackWord >> 60) & 0x7);
968 trk->SetA(0);
969 trk->SetB(0);
970 trk->SetPID(0);
971 trk->SetLayerMask((trackWord >> 16) & 0x3f);
972 trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
973 trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
974 trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
975 trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
976 trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
977 trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
978
979 trk->SetFlags(0);
980 trk->SetReserved(0);
981 trk->SetLabel(-3);
982
983 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
984 if (TMath::Abs(pt) > 0.1) {
985 trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
986 }
987 }
988 }
989 else {
990 trackWord = word;
991 }
992 idx++;
993 }
994 }
995 }
996 return 0;
997}
998
999Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
1000{
1001 // read the tracking information and store it for the given stack
1002
1003 // index word
1004
1005 fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
1006 fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
1007
1008 AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
1009 fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
1010 Int_t trackingTime = *fPayloadCurr & 0x3ff;
1011
1012 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
1013 fPayloadCurr++;
1014
1015 // data words
1016 ULong64_t trackWord = 0;
1017 Int_t idx = 0;
1018 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
1019
1020 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
1021
1022 if (!(idx & 0x1)) {
1023 // first part of 64-bit word
1024 trackWord = fPayloadCurr[iWord];
1025 }
1026 else {
1027 trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
1028
1029 if (trackWord & (1ul << 63)) {
1030 if ((trackWord & (0x3ful << 56)) != 0) {
1031 // track word
1032 AliDebug(2, Form("track word: 0x%016llx", trackWord));
1033
1034 if (fTracks) {
1035 AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
1036 AliESDTrdTrack();
1037
1038 trk->SetSector(fCurrEquipmentId-kDDLOffset);
1039 trk->SetLayerMask((trackWord >> 56) & 0x3f);
1040 trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
1041 trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
1042 trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
1043 trk->SetPID((trackWord >> 0) & 0xff);
1044 trk->SetStack(stack);
1045 trk->SetLabel(-3);
1046
1047 // now compare the track word with the one generated from the ESD information
1048 if (trackWord != trk->GetTrackWord(0)) {
1049 AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
1050 trk->GetTrackWord(0), trackWord));
1051 }
1052 }
1053 }
1054 else {
1055 // done marker (so far only used to set trigger flag)
1056 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
1057 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
1058
1059 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1060 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
1061 AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
1062 fCurrEquipmentId - kDDLOffset, stack,
1063 (trackWord >> 20) & 0x3ff,
1064 (trackWord >> 10) & 0x3ff,
1065 (trackWord >> 0) & 0x3ff,
1066 trackingTime));
1067 }
1068 }
1069 else {
1070 // extended track word
1071 AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
1072
1073 if (fTracks) {
1074 AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
1075
1076 trk->SetFlags((trackWord >> 52) & 0x7ff);
1077 trk->SetFlagsTiming((trackWord >> 51) & 0x1);
1078 trk->SetReserved((trackWord >> 49) & 0x3);
1079 trk->SetY((trackWord >> 36) & 0x1fff);
1080 trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
1081 trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
1082 trk->SetTrackletIndex((trackWord >> 12) & 0x3f, 2);
1083 trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
1084 trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
1085 trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
1086
1087 if (trk->GetFlagsTiming() == 0) {
1088 AliError(Form("*** track not in time: 0x%016llx", trk->GetExtendedTrackWord(0)));
1089 }
1090
1091 if (trackWord != trk->GetExtendedTrackWord(0)) {
1092 AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
1093 trk->GetExtendedTrackWord(0), trackWord));
1094 }
1095
1096 trackIndex++;
1097 }
1098 }
1099 }
1100 idx++;
1101 }
1102
1103 fPayloadCurr += fCurrTrkHeaderSize[stack];
1104
1105 return fCurrTrkHeaderSize[stack];
1106}
1107
1108Int_t AliTRDrawStream::ReadTriggerHeaders()
1109{
1110 // read all trigger headers present
1111
1112 AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
1113 fCurrTriggerEnable, fCurrTriggerFired));
1114 // loop over potential trigger blocks
1115 for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
1116 // check for trigger enable
1117 if (fCurrTriggerEnable & (1 << iTrigger)) {
1118 // check for readout mode and trigger fired
1119 if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
1120 // index word
1121 AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
1122 fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
1123 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
1124 if (iTrigger == 7) {
1125 // timeout trigger, use to extract tracking time
1126 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1127 }
1128
1129 fPayloadCurr++;
1130 // data words
1131 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1132 }
1133 }
1134 }
1135
1136 return 0;
1137}
1138
1139Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
1140{
1141 // read the stack header
1142 // and store the information in the corresponding variables
1143
1144 fCurrStackIndexWord[stack] = *fPayloadCurr;
1145 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
1146 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
1147 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
1148
1149 // dumping stack header
1150 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1151
1152 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
1153 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
1154 // dumping stack header
1155 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1156
1157 return -1;
1158 }
1159
1160 switch (fCurrStackHeaderVersion[stack]) {
1161 case 0xa:
1162 case 0xb:
1163 if (fCurrStackHeaderSize[stack] < 8) {
1164 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
1165 return -1;
1166 }
1167
1168 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1169 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
1170 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1171
1172 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1173 // A side
1174 fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
1175 fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
1176 fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
1177 // B side
1178 fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
1179 fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
1180 fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
1181 }
1182 break;
1183
1184 default:
1185 EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
1186 }
1187
1188 fPayloadCurr += fCurrStackHeaderSize[stack];
1189
1190 return fCurrStackHeaderSize[stack];
1191}
1192
1193Int_t AliTRDrawStream::ReadGTUTrailer()
1194{
1195 // read the SM trailer containing CRCs from various stages
1196
1197 UInt_t* trailer = fPayloadStart + fPayloadSize -1;
1198
1199 // look for the trailer index word from the end
1200 for (Int_t iWord = 0; iWord < fPayloadSize-2; iWord++) {
1201 if ((fPayloadStart[fPayloadSize-3-iWord] == fgkStackEndmarker[0]) &&
1202 (fPayloadStart[fPayloadSize-2-iWord] == fgkStackEndmarker[1]) &&
1203 ((fPayloadStart[fPayloadSize-1-iWord] & 0xfff) == 0xf51)) {
1204 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1205 break;
1206 }
1207 }
1208
1209 if (((*trailer) & 0xfff) == 0xf51) {
1210 UInt_t trailerIndexWord = (*trailer);
1211 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
1212 // Int_t trailerVersion = (trailerIndexWord >> 12) & 0xf;
1213 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1214 // parse the trailer
1215 if (trailerSize >= 4) {
1216 // match flags from GTU
1217 fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
1218 fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
1219 // individual checksums
1220 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][0] = (trailer[1] >> 16) & 0xffff;
1221 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][1] = (trailer[2] >> 0) & 0xffff;
1222 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][2] = (trailer[2] >> 16) & 0xffff;
1223 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][3] = (trailer[3] >> 0) & 0xffff;
1224 fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][4] = (trailer[3] >> 16) & 0xffff;
1225 fCurrChecksumSIU = trailer[trailerSize];
1226
1227 if ((fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
1228 EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset]);
1229 if ((fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
1230 EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset]);
1231
1232 }
1233 else {
1234 LinkError(kUnknown, "Invalid GTU trailer");
1235 }
1236 }
1237 else
1238 EquipmentError(kUnknown, "trailer index marker mismatch");
1239
1240 return 0;
1241}
1242
1243Int_t AliTRDrawStream::ReadLinkData()
1244{
1245 // read the data in one link (one HC) until the data endmarker is reached
1246 // returns the number of words read!
1247
1248 Int_t count = 0;
1249 UInt_t* startPosLink = fPayloadCurr;
1250
1251 AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
1252 fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
1253
1254 if (fMarkers)
1255 new ((*fMarkers)[fMarkers->GetEntriesFast()])
1256 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
1257
1258 if (fErrorFlags & kDiscardHC)
1259 return count;
1260
1261 if (fCurrTrackletEnable) {
1262 count += ReadTracklets();
1263 if (fErrorFlags & kDiscardHC)
1264 return count;
1265 }
1266
1267 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
1268 count += ReadHcHeader();
1269 if (fErrorFlags & kDiscardHC)
1270 return count;
1271
1272 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
1273
1274 if (det > -1 && det < 540) {
1275
1276 // ----- check which kind of data -----
1277 if (fCurrMajor & 0x40) {
1278 if ((fCurrMajor & 0x7) == 0x7) {
1279 AliDebug(1, "This is a config event");
1280 UInt_t *startPos = fPayloadCurr;
1281 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1282 *fPayloadCurr != fgkDataEndmarker)
1283 fPayloadCurr++;
1284 count += fPayloadCurr - startPos;
1285
1286 // feeding TRAP config
1287 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1288 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
1289 }
1290 else {
1291 Int_t tpmode = fCurrMajor & 0x7;
1292 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
1293 count += ReadTPData(tpmode);
1294 }
1295 }
1296 else {
1297 // reading real data
1298 if (fDigitsManager) {
1299 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
1300 //fAdcArray->Expand();
1301 if (fAdcArray->GetNtime() != fCurrNtimebins)
1302 fAdcArray->Allocate(16, 144, fCurrNtimebins);
1303 }
1304 else {
1305 LinkError(kNoDigits);
1306 }
1307
1308 if (!fDigitsParam) {
1309 fDigitsParam = fDigitsManager->GetDigitsParam();
1310 }
1311 if (fDigitsParam) {
1312 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
1313 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
1314 fDigitsParam->SetADCbaseline(det, 10);
1315 }
1316
1317 if (fDigitsManager->UsesDictionaries()) {
1318 fDigitsManager->GetDictionary(det, 0)->Reset();
1319 fDigitsManager->GetDictionary(det, 1)->Reset();
1320 fDigitsManager->GetDictionary(det, 2)->Reset();
1321 }
1322
1323 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
1324 fSignalIndex->SetSM(fCurrSm);
1325 fSignalIndex->SetStack(fCurrStack);
1326 fSignalIndex->SetLayer(fCurrLayer);
1327 fSignalIndex->SetDetNumber(det);
1328 if (!fSignalIndex->IsAllocated())
1329 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
1330 }
1331
1332 if (fCurrMajor & 0x20) {
1333 AliDebug(1, "This is a zs event");
1334 count += ReadZSData();
1335 }
1336 else {
1337 AliDebug(1, "This is a nozs event");
1338 count += ReadNonZSData();
1339 }
1340 }
1341 else {
1342 // just read until data endmarkers
1343 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1344 *fPayloadCurr != fgkDataEndmarker)
1345 fPayloadCurr++;
1346 }
1347 }
1348 }
1349 else {
1350 LinkError(kInvalidDetector, "%i", det);
1351 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1352 *fPayloadCurr != fgkDataEndmarker)
1353 fPayloadCurr++;
1354 }
1355
1356 if (fCurrSm > -1 && fCurrSm < 18) {
1357 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
1358 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
1359 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
1360 fStats.fBytesRead += count * sizeof(UInt_t);
1361 }
1362
1363 if ((fErrorFlags & kDiscardHC) && fAdcArray)
1364 fAdcArray->SetDataInvalid(); // invalidate the data
1365
1366 return count;
1367}
1368
1369Int_t AliTRDrawStream::ReadTracklets()
1370{
1371 // read the tracklets from one HC
1372
1373 Int_t nTracklets = 0;
1374
1375 UInt_t *start = fPayloadCurr;
1376 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
1377 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1378 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1379 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
1380 ++nTracklets;
1381 if (fTracklets)
1382 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
1383
1384 fPayloadCurr++;
1385 }
1386
1387 if (nTracklets > 0) {
1388 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
1389 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
1390 if (fCurrSm > -1 && fCurrSm < 18) {
1391 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
1392 fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
1393 }
1394 }
1395
1396 // loop over remaining tracklet endmarkers
1397 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1398 fPayloadCurr - fPayloadStart < fPayloadSize))
1399 fPayloadCurr++;
1400
1401 return fPayloadCurr - start;
1402}
1403
1404Int_t AliTRDrawStream::ReadHcHeader()
1405{
1406 // read and parse the HC header of one HC
1407 // and store the information in the corresponding variables
1408
1409 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
1410 UInt_t *start = fPayloadCurr;
1411 // check not to be at the data endmarker
1412 if (*fPayloadCurr == fgkDataEndmarker ||
1413 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1414 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1415 LinkError(kHCmismatch, "found endmarker where HC header should be");
1416 return 0;
1417 }
1418
1419 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1420 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1421 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1422 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1423 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1424 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1425 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1426 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1427 fCurrCheck = (*fPayloadCurr) & 0x3;
1428
1429 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1430 (fCurrStack != fCurrSlot) ||
1431 (fCurrLayer != fCurrLink / 2) ||
1432 (fCurrSide != fCurrLink % 2)) {
1433 LinkError(kHCmismatch,
1434 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
1435 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
1436 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
1437 }
1438 if (fCurrCheck != 0x1) {
1439 LinkError(kHCcheckFailed);
1440 }
1441
1442 if (fCurrAddHcWords > 0) {
1443 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
1444#ifdef TRD_RAW_DEBUG
1445 fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
1446#endif
1447 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1448 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1449 }
1450
1451 fPayloadCurr += 1 + fCurrAddHcWords;
1452
1453 return (fPayloadCurr - start);
1454}
1455
1456Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1457{
1458 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1459 // evcnt checking missing
1460 Int_t cpu = 0;
1461 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
1462 Int_t evno = -1;
1463 Int_t evcnt = 0;
1464 Int_t count = 0;
1465 Int_t mcmcount = -1;
1466 Int_t wordcount = 0;
1467 Int_t channelcount = 0;
1468 UInt_t expword = 0;
1469 UInt_t expadcval = 0;
1470 UInt_t diff = 0;
1471 Int_t lastmcmpos = -1;
1472 Int_t lastrobpos = -1;
1473
1474 UInt_t* start = fPayloadCurr;
1475
1476 while (*(fPayloadCurr) != fgkDataEndmarker &&
1477 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1478
1479 // ----- Checking MCM Header -----
1480 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1481 UInt_t *startPosMCM = fPayloadCurr;
1482 mcmcount++;
1483
1484 // ----- checking for proper readout order - ROB -----
1485 fCurrRobPos = ROB(*fPayloadCurr);
1486 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1487 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1488 lastmcmpos = -1;
1489 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1490 }
1491 else {
1492 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1493 }
1494
1495 // ----- checking for proper readout order - MCM -----
1496 fCurrMcmPos = MCM(*fPayloadCurr);
1497 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1498 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1499 }
1500 else {
1501 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1502 }
1503
1504 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1505 if (evno == -1) {
1506 evno = EvNo(*fPayloadCurr);
1507 }
1508 else {
1509 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1510#ifdef TRD_RAW_DEBUG
1511 if (fCurrL0offset[fCurrHC/2] != 0)
1512 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1513 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1514 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1515 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1516 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1517 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1518#endif
1519 }
1520 }
1521
1522 fPayloadCurr++;
1523
1524 evcnt = 0x3f & *fPayloadCurr >> 26;
1525 cpu = -1;
1526 channelcount = 0;
1527 while (channelcount < 21) {
1528 count = 0;
1529 if (cpu != cpufromchannel[channelcount]) {
1530 cpu = cpufromchannel[channelcount];
1531 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1532 wordcount = 0;
1533 }
1534
1535 while (count < 10) {
1536 if (*fPayloadCurr == fgkDataEndmarker) {
1537 MCMError(kMissTpData);
1538 return (fPayloadCurr - start);
1539 }
1540
1541 if (channelcount % 2 == 0)
1542 expword = 0x3;
1543 else
1544 expword = 0x2;
1545
1546 if (mode == 1) {
1547 // ----- TP 1 -----
1548 expword |= expadcval << 2;
1549 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1550 expword |= expadcval << 12;
1551 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1552 expword |= expadcval << 22;
1553 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1554 }
1555 else if (mode == 2) {
1556 // ----- TP 2 ------
1557 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1558 ((fCurrStack + 1) << 15) |
1559 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
1560 }
1561 else if (mode == 3) {
1562 // ----- TP 3 -----
1563 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1564 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
1565 }
1566 else {
1567 expword = 0;
1568 LinkError(kTPmodeInvalid, "Just reading");
1569 }
1570
1571 diff = *fPayloadCurr ^ expword;
1572 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1573 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1574
1575 if (diff != 0) {
1576 MCMError(kTPmismatch,
1577 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
1578 *fPayloadCurr, expword, diff,
1579 0xffff & (diff | diff >> 16),
1580 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
1581 wordcount, cpu, channelcount);;
1582 }
1583 fPayloadCurr++;
1584 count++;
1585 wordcount++;
1586 if (*fPayloadCurr == fgkDataEndmarker)
1587 return (fPayloadCurr - start);
1588 }
1589 channelcount++;
1590 }
1591 // continue with next MCM
1592
1593 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1594 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1595 startPosMCM, fPayloadCurr - startPosMCM));
1596 }
1597
1598 }
1599 return fPayloadCurr - start;
1600}
1601
1602
1603Int_t AliTRDrawStream::ReadZSData()
1604{
1605 // read the zs data from one link from the current reading position
1606
1607 UInt_t *start = fPayloadCurr;
1608
1609 Int_t mcmcount = 0;
1610 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1611 Int_t channelcount = 0;
1612 Int_t channelcountExp = 0;
1613 Int_t channelcountMax = 0;
1614 Int_t timebins;
1615 Int_t currentTimebin = 0;
1616 Int_t adcwc = 0;
1617 Int_t evno = -1;
1618 Int_t lastmcmpos = -1;
1619 Int_t lastrobpos = -1;
1620
1621 if (fCurrNtimebins != fNtimebins) {
1622 if (fNtimebins > 0)
1623 LinkError(kNtimebinsChanged,
1624 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1625 fNtimebins = fCurrNtimebins;
1626 }
1627
1628 timebins = fNtimebins;
1629
1630 while (*(fPayloadCurr) != fgkDataEndmarker &&
1631 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1632 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1633 fPayloadCurr - fPayloadStart < fPayloadSize) {
1634
1635 // ----- Checking MCM Header -----
1636 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1637 UInt_t *startPosMCM = fPayloadCurr;
1638
1639 // ----- checking for proper readout order - ROB -----
1640 fCurrRobPos = ROB(*fPayloadCurr);
1641 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1642 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1643 lastmcmpos = -1;
1644 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1645 }
1646 else {
1647 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1648 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
1649 }
1650
1651 // ----- checking for proper readout order - MCM -----
1652 fCurrMcmPos = MCM(*fPayloadCurr);
1653 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1654 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1655 }
1656 else {
1657 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1658 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
1659 }
1660
1661#ifdef TRD_RAW_DEBUG
1662 if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
1663 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1664 }
1665 fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
1666#endif
1667
1668 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1669 if (evno == -1) {
1670 evno = EvNo(*fPayloadCurr);
1671 }
1672 else {
1673 MCMError(kEvCntMismatch, "exp <-> SM: %i <-> %i", evno & 0xfffff, EvNo(*fPayloadCurr));
1674#ifdef TRD_RAW_DEBUG
1675 Int_t prevOffset = fCurrL0offset[fCurrHC/2];
1676 fCurrL0offset[fCurrHC/2] = (- fCurrL0Count[fCurrEquipmentId-kDDLOffset] + EvNo(*fPayloadCurr)) % (1 << 20);
1677 if (fCurrL0offset[fCurrHC/2] < 0)
1678 fCurrL0offset[fCurrHC/2] += 0xfffff;
1679 evno = (fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2]) & 0xfffff;
1680 if (prevOffset != 0)
1681 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1682 fCurrEquipmentId, fCurrSlot, fCurrLink/2,
1683 prevOffset,
1684 fCurrL0offset[fCurrHC/2],
1685 fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1686 EvNo(*fPayloadCurr));
1687#endif
1688 }
1689 }
1690 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1691 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1692 Int_t row = Row(*fPayloadCurr);
1693 fPayloadCurr++;
1694
1695 if ((row > 11) && (fCurrStack == 2)) {
1696 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1697 }
1698
1699 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1700 break;
1701
1702 // ----- Reading ADC channels -----
1703 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
1704
1705 // ----- analysing the ADC mask -----
1706 channelcount = 0;
1707 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1708 channelcountMax = GetNActiveChannels(*fPayloadCurr);
1709 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1710 Int_t channelno = -1;
1711 fPayloadCurr++;
1712
1713 if (channelcountExp != channelcountMax) {
1714 if (channelcountExp > channelcountMax) {
1715 Int_t temp = channelcountExp;
1716 channelcountExp = channelcountMax;
1717 channelcountMax = temp;
1718 }
1719 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
1720 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
1721 MCMError(kAdcMaskInconsistent,
1722 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1723 *(fPayloadCurr + 10 * channelcountExp),
1724 *(fPayloadCurr + 10 * channelcountExp + 1) );
1725 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
1726 channelcountExp++;
1727 else {
1728 break;
1729 }
1730 }
1731 MCMError(kAdcMaskInconsistent,
1732 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
1733 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
1734 }
1735 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
1736
1737 // ----- reading marked ADC channels -----
1738 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
1739 if (channelno < 20)
1740 channelno++;
1741 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
1742 channelno++;
1743
1744 if (fCurrNtimebins > 30) {
1745 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1746 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
1747 }
1748 else {
1749 currentTimebin = 0;
1750 }
1751
1752 adcwc = 0;
1753 Int_t nADCwords = (timebins + 2) / 3;
1754 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
1755 Int_t adccol = adccoloff - channelno;
1756 Int_t padcol = padcoloff - channelno;
1757// if (adccol < 3 || adccol > 165)
1758// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
1759// channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1760
1761 while ((adcwc < nADCwords) &&
1762 (*(fPayloadCurr) != fgkDataEndmarker) &&
1763 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1764 int check = 0x3 & *fPayloadCurr;
1765 if (channelno % 2 != 0) { // odd channel
1766 if (check != 0x2 && channelno < 21) {
1767 MCMError(kAdcCheckInvalid,
1768 "%i for %2i. ADC word in odd channel %i",
1769 check, adcwc+1, channelno);
1770 }
1771 }
1772 else { // even channel
1773 if (check != 0x3 && channelno < 21) {
1774 MCMError(kAdcCheckInvalid,
1775 "%i for %2i. ADC word in even channel %i",
1776 check, adcwc+1, channelno);
1777 }
1778 }
1779
1780 if ((fErrorFlags & kDiscardMCM) == 0) {
1781 // filling the actual timebin data
1782 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1783 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1784 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1785 if (adcwc != 0 || fCurrNtimebins <= 30)
1786 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1787 else
1788 tb0 = -1;
1789 if (currentTimebin < fCurrNtimebins)
1790 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1791 if (currentTimebin < fCurrNtimebins)
1792 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1793 }
1794
1795 adcwc++;
1796 fPayloadCurr++;
1797 }
1798
1799 if (adcwc != nADCwords)
1800 MCMError(kAdcDataAbort);
1801
1802 // adding index
1803 if (padcol > 0 && padcol < 144) {
1804 fSignalIndex->AddIndexRC(row, padcol);
1805 }
1806
1807 channelcount++;
1808 }
1809
1810 if (fCurrSm > -1 && fCurrSm < 18) {
1811 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1812 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1813 }
1814 if (channelcount != channelcountExp)
1815 MCMError(kAdcChannelsMiss);
1816
1817 mcmcount++;
1818 if (fCurrSm > -1 && fCurrSm < 18) {
1819 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1820 fStats.fStatsSector[fCurrSm].fNMCMs++;
1821 }
1822
1823 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1824 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1825 startPosMCM, fPayloadCurr - startPosMCM));
1826 }
1827
1828 // continue with next MCM
1829 }
1830
1831 // check for missing MCMs (if header suppression is inactive)
1832 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1833 LinkError(kMissMcmHeaders,
1834 "No. of MCM headers %i not as expected: %i",
1835 mcmcount, mcmcountExp);
1836 }
1837
1838 return (fPayloadCurr - start);
1839}
1840
1841Int_t AliTRDrawStream::ReadNonZSData()
1842{
1843 // read the non-zs data from one link from the current reading position
1844
1845 UInt_t *start = fPayloadCurr;
1846
1847 Int_t mcmcount = 0;
1848 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1849 Int_t channelcount = 0;
1850 Int_t channelcountExp = 0;
1851 Int_t timebins;
1852 Int_t currentTimebin = 0;
1853 Int_t adcwc = 0;
1854 Int_t evno = -1;
1855 Int_t lastmcmpos = -1;
1856 Int_t lastrobpos = -1;
1857
1858 if (fCurrNtimebins != fNtimebins) {
1859 if (fNtimebins > 0)
1860 LinkError(kNtimebinsChanged,
1861 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
1862 fNtimebins = fCurrNtimebins;
1863 }
1864
1865 timebins = fNtimebins;
1866
1867 while (*(fPayloadCurr) != fgkDataEndmarker &&
1868 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1869
1870 // ----- Checking MCM Header -----
1871 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1872
1873 // ----- checking for proper readout order - ROB -----
1874 fCurrRobPos = ROB(*fPayloadCurr);
1875 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1876 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1877 lastmcmpos = -1;
1878 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1879 }
1880 else {
1881 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
1882 }
1883
1884 // ----- checking for proper readout order - MCM -----
1885 fCurrMcmPos = MCM(*fPayloadCurr);
1886 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
1887 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1888 }
1889 else {
1890 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
1891 }
1892
1893 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1894 if (evno == -1) {
1895 evno = EvNo(*fPayloadCurr);
1896 }
1897 else {
1898 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1899#ifdef TRD_RAW_DEBUG
1900 if (fCurrL0offset[fCurrHC/2] != 0)
1901 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1902 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1903 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1904 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1905 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1906 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1907#endif
1908 }
1909 }
1910
1911 channelcount = 0;
1912 channelcountExp = 21;
1913 int channelno = -1;
1914
1915 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1916 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1917 Int_t row = Row(*fPayloadCurr);
1918 fPayloadCurr++;
1919
1920 if ((row > 11) && (fCurrStack == 2)) {
1921 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1922 }
1923
1924 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1925 break;
1926
1927 // ----- reading marked ADC channels -----
1928 while (channelcount < channelcountExp &&
1929 *(fPayloadCurr) != fgkDataEndmarker) {
1930 if (channelno < 20)
1931 channelno++;
1932
1933 currentTimebin = 0;
1934
1935 adcwc = 0;
1936 Int_t nADCwords = (timebins + 2) / 3;
1937 AliDebug(2, Form("Now looking %i words", nADCwords));
1938 Int_t adccol = adccoloff - channelno;
1939 Int_t padcol = padcoloff - channelno;
1940 while ((adcwc < nADCwords) &&
1941 (*(fPayloadCurr) != fgkDataEndmarker) &&
1942 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
1943 int check = 0x3 & *fPayloadCurr;
1944 if (channelno % 2 != 0) { // odd channel
1945 if (check != 0x2 && channelno < 21) {
1946 MCMError(kAdcCheckInvalid,
1947 "%i for %2i. ADC word in odd channel %i",
1948 check, adcwc+1, channelno);
1949 }
1950 }
1951 else { // even channel
1952 if (check != 0x3 && channelno < 21) {
1953 MCMError(kAdcCheckInvalid,
1954 "%i for %2i. ADC word in even channel %i",
1955 check, adcwc+1, channelno);
1956 }
1957 }
1958
1959 if ((fErrorFlags & kDiscardMCM) == 0) {
1960 // filling the actual timebin data
1961 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1962 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1963 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1964 if (adcwc != 0 || fCurrNtimebins <= 30)
1965 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1966 else
1967 tb0 = -1;
1968 if (currentTimebin < fCurrNtimebins)
1969 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1970 if (currentTimebin < fCurrNtimebins)
1971 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1972 }
1973
1974 adcwc++;
1975 fPayloadCurr++;
1976 }
1977
1978 if (adcwc != nADCwords)
1979 MCMError(kAdcDataAbort);
1980
1981 // adding index
1982 if (padcol > 0 && padcol < 144) {
1983 fSignalIndex->AddIndexRC(row, padcol);
1984 }
1985
1986 channelcount++;
1987 }
1988
1989 if (channelcount != channelcountExp)
1990 MCMError(kAdcChannelsMiss);
1991 mcmcount++;
1992 // continue with next MCM
1993 }
1994
1995 // check for missing MCMs (if header suppression is inactive)
1996 if (mcmcount != mcmcountExp) {
1997 LinkError(kMissMcmHeaders,
1998 "%i not as expected: %i", mcmcount, mcmcountExp);
1999 }
2000
2001 return (fPayloadCurr - start);
2002}
2003
2004#ifdef TRD_RAW_CRC
2005UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
2006{
2007 // calculate the CRC for the data from this link
2008 // must not change the pointers to the data
2009
2010 // always count two endmarkers
2011 Int_t nEndmarkers = 0;
2012 for (Int_t i = 0; i < size; i++) {
2013 if (data[size-1 - i] != fgkDataEndmarker)
2014 break;
2015 nEndmarkers++;
2016 }
2017
2018 size = size - (nEndmarkers-2);
2019
2020 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
2021
2022 checksumLink.reset();
2023 checksumLink.process_bytes(data, size*sizeof(UInt_t));
2024 return checksumLink();
2025}
2026#else
2027UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * /* data */, Int_t /* size */)
2028{
2029 // checksum calculation relies on boost,
2030 // we return 0 if we cannot calculate it
2031
2032 AliError("Checksum calculation relies on boost CRC implementation!");
2033
2034 return 0;
2035}
2036#endif
2037
2038Int_t AliTRDrawStream::SeekNextStack()
2039{
2040 // proceed in raw data stream till the next stack
2041
2042 if (!fCurrStackEndmarkerAvail)
2043 return 0;
2044
2045 UInt_t *start = fPayloadCurr;
2046
2047 // read until data endmarkers
2048 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
2049 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2050 (fPayloadCurr[1] != fgkStackEndmarker[1])))
2051 fPayloadCurr++;
2052
2053 if ((fPayloadCurr - start) != 0)
2054 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
2055
2056 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
2057
2058 // goto next stack
2059 fPayloadCurr++;
2060 fPayloadCurr++;
2061
2062 return (fPayloadCurr-start);
2063}
2064
2065Int_t AliTRDrawStream::SeekNextLink()
2066{
2067 // proceed in raw data stream till the next link
2068
2069 UInt_t *start = fPayloadCurr;
2070
2071 // read until data endmarkers
2072 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2073 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2074 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
2075 *fPayloadCurr != fgkDataEndmarker)
2076 fPayloadCurr++;
2077
2078 // read all data endmarkers
2079 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2080 *fPayloadCurr == fgkDataEndmarker)
2081 fPayloadCurr++;
2082
2083 return (fPayloadCurr - start);
2084}
2085
2086
2087void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
2088{
2089 // register error according to error code on equipment level
2090 // and return the corresponding error message
2091
2092 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2093 fLastError.fStack = -1;
2094 fLastError.fLink = -1;
2095 fLastError.fRob = -1;
2096 fLastError.fMcm = -1;
2097 fLastError.fError = err;
2098 (this->*fStoreError)();
2099
2100 va_list ap;
2101 if (fgErrorDebugLevel[err] > 10)
2102 AliDebug(fgErrorDebugLevel[err],
2103 Form("Event %6i: Eq. %2d - %s : %s",
2104 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
2105 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2106 else
2107 AliError(Form("Event %6i: Eq. %2d - %s : %s",
2108 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
2109 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2110 fErrorFlags |= fgErrorBehav[err];
2111}
2112
2113
2114void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
2115{
2116 // register error according to error code on stack level
2117 // and return the corresponding error message
2118
2119 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2120 fLastError.fStack = fCurrSlot;
2121 fLastError.fLink = -1;
2122 fLastError.fRob = -1;
2123 fLastError.fMcm = -1;
2124 fLastError.fError = err;
2125 (this->*fStoreError)();
2126
2127 va_list ap;
2128 if (fgErrorDebugLevel[err] > 0)
2129 AliDebug(fgErrorDebugLevel[err],
2130 Form("Event %6i: Eq. %2d S %i - %s : %s",
2131 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2132 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2133 else
2134 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
2135 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
2136 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2137 fErrorFlags |= fgErrorBehav[err];
2138}
2139
2140
2141void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
2142{
2143 // register error according to error code on link level
2144 // and return the corresponding error message
2145
2146 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2147 fLastError.fStack = fCurrSlot;
2148 fLastError.fLink = fCurrLink;
2149 fLastError.fRob = -1;
2150 fLastError.fMcm = -1;
2151 fLastError.fError = err;
2152 (this->*fStoreError)();
2153
2154 va_list ap;
2155 if (fgErrorDebugLevel[err] > 0)
2156 AliDebug(fgErrorDebugLevel[err],
2157 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2158 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2159 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2160 else
2161 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
2162 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
2163 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2164 fErrorFlags |= fgErrorBehav[err];
2165}
2166
2167
2168void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
2169{
2170 // register error according to error code on ROB level
2171 // and return the corresponding error message
2172
2173 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2174 fLastError.fStack = fCurrSlot;
2175 fLastError.fLink = fCurrLink;
2176 fLastError.fRob = fCurrRobPos;
2177 fLastError.fMcm = -1;
2178 fLastError.fError = err;
2179 (this->*fStoreError)();
2180
2181 va_list ap;
2182 if (fgErrorDebugLevel[err] > 0)
2183 AliDebug(fgErrorDebugLevel[err],
2184 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2185 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2186 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2187 else
2188 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2189 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
2190 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2191 fErrorFlags |= fgErrorBehav[err];
2192}
2193
2194
2195void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
2196{
2197 // register error according to error code on MCM level
2198 // and return the corresponding error message
2199
2200 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
2201 fLastError.fStack = fCurrSlot;
2202 fLastError.fLink = fCurrLink;
2203 fLastError.fRob = fCurrRobPos;
2204 fLastError.fMcm = fCurrMcmPos;
2205 fLastError.fError = err;
2206 (this->*fStoreError)();
2207
2208 va_list ap;
2209 if (fgErrorDebugLevel[err] > 0)
2210 AliDebug(fgErrorDebugLevel[err],
2211 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2212 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2213 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2214 else
2215 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
2216 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
2217 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
2218 fErrorFlags |= fgErrorBehav[err];
2219}
2220
2221const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
2222{
2223 // return the error message for the given error code
2224
2225 if (errCode > 0 && errCode < kLastErrorCode)
2226 return fgkErrorMessages[errCode];
2227 else
2228 return "";
2229}
2230
2231void AliTRDrawStream::AliTRDrawStats::ClearStats()
2232{
2233 // clear statistics (includes clearing sector-wise statistics)
2234
2235 fBytesRead = 0;
2236 for (Int_t iSector = 0; iSector < 18; iSector++) {
2237 fStatsSector[iSector].ClearStats();
2238 }
2239
2240}
2241
2242void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2243{
2244 // clear statistics (includes clearing HC-wise statistics)
2245
2246 fBytes = 0;
2247 fBytesRead = 0;
2248 fNTracklets = 0;
2249 fNMCMs = 0;
2250 fNChannels = 0;
2251
2252 for (Int_t iHC = 0; iHC < 60; iHC++) {
2253 fStatsHC[iHC].ClearStats();
2254 }
2255}
2256
2257void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2258{
2259 // clear statistics
2260
2261 fBytes = 0;
2262 fBytesRead = 0;
2263 fNTracklets = 0;
2264 fNMCMs = 0;
2265 fNChannels = 0;
2266}
2267
2268void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
2269{
2270 // mark MCM for dumping of raw data
2271
2272 if (dump) {
2273 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
2274 }
2275 else {
2276 Int_t iMCM;
2277 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2278 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2279 fNDumpMCMs--;
2280 break;
2281 }
2282 }
2283 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2284 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2285 }
2286 }
2287}
2288
2289Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
2290{
2291 // check if MCM data should be dumped
2292
2293 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2294 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2295 return kTRUE;
2296 }
2297 }
2298 return kFALSE;
2299}
2300
2301TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
2302{
2303 // dump raw data
2304
2305 title += "\n";
2306 for (Int_t pos = 0; pos < length; pos += 4) {
2307 if ((start[pos+0] != endmarker) && pos+0 < length)
2308 if ((start[pos+1] != endmarker && pos+1 < length))
2309 if ((start[pos+2] != endmarker && pos+2 < length))
2310 if ((start[pos+3] != endmarker && pos+3 < length))
2311 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2312 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2313 else {
2314 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
2315 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2316 return title;
2317 }
2318 else {
2319 title += Form(" 0x%08x 0x%08x 0x%08x\n",
2320 start[pos+0], start[pos+1], start[pos+2]);
2321 return title;
2322 }
2323 else {
2324 title += Form(" 0x%08x 0x%08x\n",
2325 start[pos+0], start[pos+1]);
2326 return title;
2327 }
2328 else {
2329 title += Form(" 0x%08x\n",
2330 start[pos+0]);
2331 return title;
2332 }
2333 }
2334 return title;
2335}
2336
2337TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2338{
2339 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2340 word, ROB(word), MCM(word));
2341 return title;
2342}
2343
2344TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2345{
2346 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2347 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2348 return title;
2349}
2350
2351AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
2352 fError(error),
2353 fSector(sector),
2354 fStack(stack),
2355 fLink(link),
2356 fRob(rob),
2357 fMcm(mcm)
2358{
2359 // ctor
2360
2361}
2362
2363void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2364{
2365 // sort tracklets for referencing from GTU tracks
2366
2367 if (!trklArray)
2368 return;
2369
2370 Int_t nTracklets = trklArray->GetEntriesFast();
2371
2372 Int_t lastHC = -1;
2373 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2374 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2375 Int_t hc = trkl->GetHCId();
2376 if ((hc < 0) || (hc >= 1080)) {
2377 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2378 continue;
2379 }
2380 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2381 if (hc != lastHC) {
2382 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2383 indices[hc] = iTracklet + 1;
2384 lastHC = hc;
2385 }
2386 }
2387
2388 for (Int_t iDet = 0; iDet < 540; iDet++) {
2389 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2390 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2391 Int_t trklIndex = sortedTracklets.GetEntries();
2392 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2393 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2394 AliTRDtrackletBase *trklNext = 0x0;
2395 while (trklA != 0x0 || trklB != 0x0) {
2396 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2397 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2398 if (trklA == 0x0) {
2399 trklNext = trklB;
2400 trklIndexB++;
2401 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2402 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2403 trklB = 0x0;
2404 }
2405 else if (trklB == 0x0) {
2406 trklNext = trklA;
2407 trklIndexA++;
2408 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2409 if (trklA && trklA->GetHCId() != 2*iDet)
2410 trklA = 0x0;
2411 }
2412 else {
2413 if (trklA->GetZbin() <= trklB->GetZbin()) {
2414 trklNext = trklA;
2415 trklIndexA++;
2416 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2417 if (trklA && trklA->GetHCId() != 2*iDet)
2418 trklA = 0x0;
2419 }
2420 else {
2421 trklNext = trklB;
2422 trklIndexB++;
2423 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2424 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2425 trklB = 0x0;
2426 }
2427 }
2428 if (trklNext) {
2429 sortedTracklets.Add(trklNext);
2430
2431 }
2432 }
2433
2434 // updating tracklet indices as in output
2435 if (sortedTracklets.GetEntries() != trklIndex) {
2436 indices[2*iDet + 0] = trklIndex;
2437 indices[2*iDet + 1] = sortedTracklets.GetEntries();
2438 } else {
2439 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
2440 }
2441 }
2442}
2443
2444void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2445{
2446 UInt_t mask = trdTrack->GetLayerMask();
2447 UInt_t stack = trdTrack->GetStack();
2448
2449 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2450 refIndex[iLayer] = -1;
2451
2452 if (mask & (1 << iLayer)) {
2453
2454 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2455 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2456
2457 if ((det < 0) || (det > 539)) {
2458 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2459 continue;
2460 }
2461 if (trackletIndex[2*det] >= 0) {
2462 if ((trackletIndex[2*det] + idx > -1) &&
2463 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2464 refIndex[iLayer] = trackletIndex[2*det] + idx;
2465 } else {
2466 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2467 }
2468 } else {
2469 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));
2470 }
2471 }
2472 }
2473}