]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDrawStream.cxx
Dump object functionality
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStream.cxx
CommitLineData
0508ca31 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 //
9cb9c409 19// and translation into ADC values, on-line tracklets and tracks //
0508ca31 20// //
f77d6f54 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// //
0508ca31 26// Author: J. Klein (jochen.klein@cern.ch) //
27// //
28////////////////////////////////////////////////////////////////////////////
29
92223bf6 30#include <cstdio>
31#include <cstdarg>
32
f77d6f54 33#if defined(TRD_RAW_CRC)
34#include <boost/crc.hpp>
35#endif
36
d60fe037 37#include "TClonesArray.h"
38#include "TTree.h"
39
40#include "AliLog.h"
41#include "AliRawReader.h"
5fedeee9 42#include "AliTRDcalibDB.h"
d60fe037 43#include "AliTRDdigitsManager.h"
44#include "AliTRDdigitsParam.h"
43573bcf 45#include "AliTRDcalibDB.h"
46#include "AliTRDmcmSim.h"
d60fe037 47#include "AliTRDtrapConfig.h"
48#include "AliTRDarrayADC.h"
49#include "AliTRDarrayDictionary.h"
50#include "AliTRDSignalIndex.h"
51#include "AliTRDtrackletWord.h"
52a2b6c0 52#include "AliTRDtrackletMCM.h"
5fdfc9e4 53#include "AliESDTrdTrack.h"
d60fe037 54
55#include "AliTRDrawStream.h"
56
d60fe037 57ClassImp(AliTRDrawStream)
58
9cb9c409 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};
d60fe037 65const Int_t AliTRDrawStream::fgkNlinks = 12;
66const Int_t AliTRDrawStream::fgkNstacks = 5;
9cb9c409 67const Int_t AliTRDrawStream::fgkNsectors = 18;
68const Int_t AliTRDrawStream::fgkNtriggers = 12;
d60fe037 69const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
70const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
52a2b6c0 71const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
d60fe037 72
92305359 73const char* AliTRDrawStream::fgkErrorMessages[] = {
d60fe037 74 "Unknown error",
75 "Link monitor active",
52a2b6c0 76 "Event counter mismatch",
d60fe037 77 "not a TRD equipment (1024-1041)",
78 "Invalid Stack header",
79 "Invalid detector number",
789a8b20 80 "Invalid pad row",
d60fe037 81 "No digits could be retrieved from the digitsmanager",
5f006bd7 82 "HC header mismatch",
d60fe037 83 "HC check bits wrong",
84 "Unexpected position in readout stream",
85 "Invalid testpattern mode",
86 "Testpattern mismatch",
87 "Number of timebins changed",
5f006bd7 88 "ADC mask inconsistent",
89 "ADC check bits invalid",
d60fe037 90 "Missing ADC data",
91 "Missing expected ADC channels",
2519cca4 92 "Missing MCM headers",
52a2b6c0 93 "Missing TP data",
94 "CRC mismatch"
d60fe037 95};
96
92305359 97Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
92223bf6 98 0,
99 0,
5f006bd7 100 2,
101 1,
102 0,
103 1,
789a8b20 104 0,
5f006bd7 105 1,
ec3b8338 106 0,
92223bf6 107 1,
92223bf6 108 2,
109 1,
2519cca4 110 0,
92223bf6 111 1,
5f006bd7 112 1,
113 2,
114 1,
115 1,
2519cca4 116 1,
52a2b6c0 117 0,
2519cca4 118 0
92223bf6 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,
789a8b20 128 AliTRDrawStream::kDiscardMCM,
92223bf6 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,
2519cca4 140 AliTRDrawStream::kTolerate,
52a2b6c0 141 AliTRDrawStream::kTolerate,
92223bf6 142 AliTRDrawStream::kTolerate
143};
144
d60fe037 145AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
f0a345a7 146 fStoreError(&AliTRDrawStream::ForgetError),
d60fe037 147 fRawReader(rawReader),
148 fDigitsManager(0x0),
149 fDigitsParam(0x0),
150 fErrors(0x0),
151 fLastError(),
92223bf6 152 fErrorFlags(0),
2519cca4 153 fStats(),
d60fe037 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),
9cb9c409 164 fCurrSmHeaderSize(0),
165 fCurrSmHeaderVersion(0),
166 fCurrTrailerReadout(0),
167 fCurrTrgHeaderAvail(0),
168 fCurrTrgHeaderReadout(0),
169 fCurrTrkHeaderAvail(0),
52a2b6c0 170 fCurrStackEndmarkerAvail(0),
9cb9c409 171 fCurrEvType(0),
172 fCurrTriggerEnable(0),
173 fCurrTriggerFired(0),
d60fe037 174 fCurrTrackEnable(0),
175 fCurrTrackletEnable(0),
176 fCurrStackMask(0),
f77d6f54 177#ifdef TRD_RAW_DEBUG
178 fCurrL0Count(),
179 fCurrL1aCount(),
180 fCurrL1rCount(),
181 fCurrL2aCount(),
182 fCurrL2rCount(),
183 fCurrL0offset(),
184#endif
9cb9c409 185 fCurrTrkHeaderIndexWord(0x0),
186 fCurrTrkHeaderSize(0x0),
2519cca4 187 fCurrTrkFlags(0x0),
9cb9c409 188 fCurrTrgHeaderIndexWord(0x0),
189 fCurrTrgHeaderSize(0x0),
2519cca4 190 fCurrTrgFlags(0x0),
d60fe037 191 fCurrStackIndexWord(0x0),
192 fCurrStackHeaderSize(0x0),
193 fCurrStackHeaderVersion(0x0),
194 fCurrLinkMask(0x0),
195 fCurrCleanCheckout(0x0),
196 fCurrBoardId(0x0),
9cb9c409 197 fCurrHwRev(-1),
198 fCurrHwRevTMU(0x0),
d60fe037 199 fCurrLinkMonitorFlags(0x0),
200 fCurrLinkDataTypeFlags(0x0),
201 fCurrLinkDebugFlags(0x0),
f77d6f54 202 fCurrMatchFlagsSRAM(),
203 fCurrMatchFlagsPostBP(),
52a2b6c0 204 fCurrChecksumStack(),
205 fCurrChecksumSIU(0),
d60fe037 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),
d60fe037 217 fCurrPtrgCnt(-1),
218 fCurrPtrgPhase(-1),
f77d6f54 219#ifdef TRD_RAW_DEBUG
220 fCurrBC(),
221#endif
cc26f39c 222 fNDumpMCMs(0),
d60fe037 223 fAdcArray(0x0),
224 fSignalIndex(0x0),
5fdfc9e4 225 fTracklets(0x0),
226 fTracks(0x0),
227 fMarkers(0x0)
d60fe037 228{
229 // default constructor
230
9cb9c409 231 fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
232 fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
2519cca4 233 fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
9cb9c409 234 fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
235 fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
2519cca4 236 fCurrTrgFlags = new UInt_t[fgkNsectors];
f77d6f54 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
5f006bd7 244 fCurrStackIndexWord = new UInt_t[fgkNstacks];
245 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
d60fe037 246 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
5f006bd7 247 fCurrLinkMask = new UInt_t[fgkNstacks];
248 fCurrCleanCheckout = new UInt_t[fgkNstacks];
249 fCurrBoardId = new UInt_t[fgkNstacks];
9cb9c409 250 fCurrHwRevTMU = new UInt_t[fgkNstacks];
f77d6f54 251 fCurrLinkMonitorFlags = new UInt_t[fgkNsectors * fgkNstacks * fgkNlinks];
d60fe037 252 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
253 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
2519cca4 254 for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
255 fCurrTrgFlags[iSector] = 0;
5fdfc9e4 256 for (Int_t i = 0; i < 100; i++)
257 fDumpMCM[i] = 0;
d60fe037 258
d60fe037 259 // setting up the error tree
260 fErrors = new TTree("errorStats", "Error statistics");
261 fErrors->SetDirectory(0x0);
5fdfc9e4 262 fErrors->Branch("error", &fLastError);
d60fe037 263 fErrors->SetCircular(1000);
2f9bdd85 264 for (Int_t i = 0; i < 100; i++) {
265 fErrorBuffer[i] = 0;
266 }
267
d60fe037 268}
269
270AliTRDrawStream::~AliTRDrawStream()
271{
272 // destructor
273
274 delete fErrors;
275
9cb9c409 276 delete [] fCurrTrkHeaderIndexWord;
277 delete [] fCurrTrkHeaderSize;
2519cca4 278 delete [] fCurrTrkFlags;
9cb9c409 279 delete [] fCurrTrgHeaderIndexWord;
280 delete [] fCurrTrgHeaderSize;
2519cca4 281 delete [] fCurrTrgFlags;
d60fe037 282 delete [] fCurrStackIndexWord;
283 delete [] fCurrStackHeaderSize;
284 delete [] fCurrStackHeaderVersion;
285 delete [] fCurrLinkMask;
286 delete [] fCurrCleanCheckout;
287 delete [] fCurrBoardId;
9cb9c409 288 delete [] fCurrHwRevTMU;
d60fe037 289 delete [] fCurrLinkMonitorFlags;
290 delete [] fCurrLinkDataTypeFlags;
291 delete [] fCurrLinkDebugFlags;
292}
293
f77d6f54 294Bool_t AliTRDrawStream::ReadEvent()
d60fe037 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
d60fe037 303 // some preparations
304 fDigitsParam = 0x0;
305
306 // loop over all DDLs
9cb9c409 307 // data starts with GTU payload, i.e. SM index word
d60fe037 308 UChar_t *buffer = 0x0;
309
310 while (fRawReader->ReadNextData(buffer)) {
311
312 fCurrEquipmentId = fRawReader->GetEquipmentId();
313 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
314
9cb9c409 315 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
92223bf6 316 EquipmentError(kNonTrdEq, "Skipping");
d60fe037 317 continue;
318 }
319
8df9496c 320 if (fMarkers)
321 new ((*fMarkers)[fMarkers->GetEntriesFast()])
9cb9c409 322 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
8df9496c 323
9cb9c409 324 ReadGTUHeaders((UInt_t*) buffer);
d60fe037 325
9cb9c409 326 if (fCurrTrailerReadout)
327 ReadGTUTrailer();
d60fe037 328
f77d6f54 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
9cb9c409 347 // loop over all active links
348 AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
349 for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
d60fe037 350 fCurrSlot = iStack;
f77d6f54 351#ifdef TRD_RAW_CRC
352 checksumStack[iStack].reset();
353#endif
354
9cb9c409 355 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
d60fe037 356 continue;
357
358 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
9cb9c409 359 for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
d60fe037 360 fCurrLink = iLink;
9cb9c409 361 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
362 fCurrSlot * fgkNlinks + iLink;
d60fe037 363 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
364 continue;
9cb9c409 365
f77d6f54 366#ifdef TRD_RAW_CRC
367 UInt_t *start = fPayloadCurr;
368#endif
52a2b6c0 369 Int_t size = 0;
370
92223bf6 371 fErrorFlags = 0;
372 // check for link monitor error flag
f77d6f54 373 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
d60fe037 374 LinkError(kLinkMonitor);
2519cca4 375 if (fgErrorBehav[kLinkMonitor] == kTolerate)
52a2b6c0 376 size += ReadLinkData();
2519cca4 377 }
7534e6db 378 else
379 // read the data from one HC
52a2b6c0 380 size += ReadLinkData();
d60fe037 381
382 // read all data endmarkers
52a2b6c0 383 size += SeekNextLink();
f77d6f54 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]());
d60fe037 395 }
f77d6f54 396#endif
52a2b6c0 397
398 // continue with next stack
399 SeekNextStack();
d60fe037 400 }
401 }
9cb9c409 402
d60fe037 403 return kTRUE;
404}
405
406
407Bool_t AliTRDrawStream::NextDDL()
408{
0508ca31 409 // continue reading with the next equipment
410
d60fe037 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));
5f006bd7 424
9cb9c409 425 if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
92223bf6 426 EquipmentError(kNonTrdEq, "Skipping");
d60fe037 427 continue;
428 }
429
8df9496c 430 if (fMarkers)
431 new ((*fMarkers)[fMarkers->GetEntriesFast()])
9cb9c409 432 AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
8df9496c 433
9cb9c409 434 ReadGTUHeaders((UInt_t*) buffer);
435
436 if (fCurrTrailerReadout)
437 ReadGTUTrailer();
d60fe037 438
d60fe037 439 return kTRUE;
440 }
441
442 return kFALSE;
443}
444
445
9cb9c409 446Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
d60fe037 447{
0508ca31 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
5f006bd7 452 fDigitsManager = digMgr;
d60fe037 453 fDigitsParam = 0x0;
454
92223bf6 455 fErrorFlags = 0;
456
d60fe037 457 if (!fRawReader) {
458 AliError("No raw reader available");
459 return -1;
460 }
461
9cb9c409 462 while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
d60fe037 463 if (!NextDDL()) {
464 fCurrSlot = -1;
465 return -1;
466 }
9cb9c409 467 while ((fCurrSlot < fgkNstacks) &&
9e07aeda 468 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
469 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
0ba57e68 470 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
471 ++fCurrSlot;
472 fCurrSlot = 0;
473 continue;
474 }
9e07aeda 475 fCurrLink++;
9cb9c409 476 if (fCurrLink >= fgkNlinks) {
0ba57e68 477 SeekNextStack();
9e07aeda 478 fCurrLink = 0;
479 fCurrSlot++;
480 }
481 }
d60fe037 482 }
483
484 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
9cb9c409 485 fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
486 fCurrSlot * fgkNlinks + fCurrLink;
d60fe037 487
f77d6f54 488 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
d60fe037 489 LinkError(kLinkMonitor);
2519cca4 490 if (fgErrorBehav[kLinkMonitor] == kTolerate)
491 ReadLinkData();
492 }
7534e6db 493 else
494 // read the data from one HC
495 ReadLinkData();
5f006bd7 496
d60fe037 497 // read all data endmarkers
92223bf6 498 SeekNextLink();
d60fe037 499
500 if (fCurrLink % 2 == 0) {
501 // if we just read the A-side HC then also check the B-side
502 fCurrLink++;
1e7466b5 503 fCurrHC++;
d60fe037 504 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
f77d6f54 505 if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
2519cca4 506 LinkError(kLinkMonitor);
507 if (fgErrorBehav[kLinkMonitor] == kTolerate)
508 ReadLinkData();
509 }
510 else {
511 ReadLinkData();
512 }
92223bf6 513 SeekNextLink();
d60fe037 514 }
515 }
516
d60fe037 517 do {
52a2b6c0 518 if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
d60fe037 519 fCurrLink = 0;
520 fCurrSlot++;
521 }
52a2b6c0 522 else {
523 fCurrLink++;
524 if (fCurrLink >= fgkNlinks) {
525 SeekNextStack();
526 fCurrLink = 0;
527 fCurrSlot++;
528 }
529 }
5f006bd7 530 } while ((fCurrSlot < fgkNstacks) &&
531 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
67271412 532 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
d60fe037 533
25671e69 534 // return chamber information from HC if it is valid
535 // otherwise return information from link position
9cb9c409 536 if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
537 return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
25671e69 538 else
9cb9c409 539 return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
d60fe037 540}
541
542
9cb9c409 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
d60fe037 588Int_t AliTRDrawStream::ReadSmHeader()
589{
5f006bd7 590 // read the SMU index header at the current reading position
d60fe037 591 // and store the information in the corresponding variables
592
593 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
92223bf6 594 EquipmentError(kUnknown, "SM Header incomplete");
d60fe037 595 return -1;
596 }
597
2519cca4 598 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
599
9cb9c409 600 fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
601 fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
d60fe037 602 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
603 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
604 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
9cb9c409 605 fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
52a2b6c0 606 fCurrStackEndmarkerAvail = 0;
9cb9c409 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;
2519cca4 626 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
9cb9c409 627 break;
d60fe037 628
52a2b6c0 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;
f77d6f54 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
52a2b6c0 648 break;
649
9cb9c409 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,
d60fe037 658 fCurrTrackletEnable,
9cb9c409 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}
5fdfc9e4 669
9cb9c409 670Int_t AliTRDrawStream::DecodeGTUtracks()
671{
5fdfc9e4 672 // decode GTU track words
9cb9c409 673 // this depends on the hardware revision of the SMU
674
cb8b99ee 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),
9cb9c409 683 fPayloadCurr + 4, 10, 0xffe0ffff));
684
2519cca4 685 fCurrTrgFlags[sector] = 0;
686
9cb9c409 687 if (fCurrHwRev < 1772) {
cb8b99ee 688 UInt_t fastWord; // fast trigger word
689 ULong64_t trackWord = 0; // extended track word
9cb9c409 690 Int_t stack = 0;
691 Int_t idx = 0;
692 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
cb8b99ee 693 if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
9cb9c409 694 stack++;
695 idx = 0;
696 }
697 else {
698 if ((idx == 0) &&
699 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
cb8b99ee 700 fastWord = fPayloadCurr[iWord];
2519cca4 701 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
cb8b99ee 702 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
9cb9c409 703 continue;
704 }
705 else if ((idx & 0x1) == 0x1) {
cb8b99ee 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);
52a2b6c0 727 trk->SetLabel(-3);
cb8b99ee 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 }
9cb9c409 735 else {
cb8b99ee 736 trackWord = fPayloadCurr[iWord];
9cb9c409 737 }
738 idx++;
739 }
5fdfc9e4 740 }
9cb9c409 741 }
742 else if (fCurrHwRev < 1804) {
cb8b99ee 743 UInt_t fastWord; // fast trigger word
744 ULong64_t trackWord = 0; // extended track word
9cb9c409 745 Int_t stack = 0;
746 Int_t idx = 0;
747 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
cb8b99ee 748 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
9cb9c409 749 stack++;
750 idx = 0;
751 }
752 else {
753 if ((idx == 0) &&
754 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
cb8b99ee 755 fastWord = fPayloadCurr[iWord];
2519cca4 756 fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
cb8b99ee 757 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
9cb9c409 758 continue;
759 }
760 else if ((idx & 0x1) == 0x1) {
cb8b99ee 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);
52a2b6c0 782 trk->SetLabel(-3);
cb8b99ee 783
784 Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
785 if (TMath::Abs(pt) > 0.1) {
c4daee41 786 trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
cb8b99ee 787 }
788 }
9cb9c409 789 }
790 else {
cb8b99ee 791 trackWord = fPayloadCurr[iWord];
9cb9c409 792 }
793 idx++;
794 }
795 }
796 }
797 else if (fCurrHwRev < 1819) {
cb8b99ee 798 UInt_t fastWord; // fast trigger word
799 ULong64_t trackWord = 0; // extended track word
9cb9c409 800 Int_t stack = 0;
801 Int_t idx = 0;
802 for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
cb8b99ee 803 if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
9cb9c409 804 stack++;
805 idx = 0;
806 }
807 else {
808 if ((idx == 0) &&
809 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
cb8b99ee 810 fastWord = fPayloadCurr[iWord];
c4daee41 811 if (fastWord & (1 << 13))
812 fCurrTrgFlags[sector] |= 1 << (stack+11);
cb8b99ee 813 AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
9cb9c409 814 continue;
815 }
816 else if ((idx & 0x1) == 0x1) {
cb8b99ee 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);
52a2b6c0 840 trk->SetLabel(-3);
cb8b99ee 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 }
9cb9c409 847 }
848 else {
cb8b99ee 849 trackWord = fPayloadCurr[iWord];
9cb9c409 850 }
851 idx++;
5fdfc9e4 852 }
9cb9c409 853 }
854 }
855 else if (fCurrHwRev < 1860) {
cb8b99ee 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));
2519cca4 884 if (fastWord & (1 << 13))
885 fCurrTrgFlags[sector] |= 1 << (stack+11);
cb8b99ee 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);
52a2b6c0 910 trk->SetLabel(-3);
cb8b99ee 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
9cb9c409 925 }
926 else {
cb8b99ee 927 ULong64_t trackWord = 0; // this is the debug word
9cb9c409 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;
5fdfc9e4 937 }
938 else {
9cb9c409 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));
2519cca4 957 fCurrTrgFlags[sector] |= 1 << (stack+11);
9cb9c409 958 continue;
959 }
960 else if ((idx & 0x1) == 0x1) {
cb8b99ee 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);
52a2b6c0 981 trk->SetLabel(-3);
cb8b99ee 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 }
9cb9c409 988 }
989 else {
cb8b99ee 990 trackWord = word;
9cb9c409 991 }
992 idx++;
5fdfc9e4 993 }
5fdfc9e4 994 }
995 }
9cb9c409 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;
9cb9c409 1007
cb8b99ee 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
2519cca4 1012 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
cb8b99ee 1013 fPayloadCurr++;
9cb9c409 1014
1015 // data words
cb8b99ee 1016 ULong64_t trackWord = 0;
9cb9c409 1017 Int_t idx = 0;
cb8b99ee 1018 Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
1019
9cb9c409 1020 for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
5f006bd7 1021
cb8b99ee 1022 if (!(idx & 0x1)) {
1023 // first part of 64-bit word
1024 trackWord = fPayloadCurr[iWord];
9cb9c409 1025 }
1026 else {
cb8b99ee 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);
52a2b6c0 1045 trk->SetLabel(-3);
cb8b99ee 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)
2519cca4 1056 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
bc425b5d 1057 fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
cb8b99ee 1058
2519cca4 1059 AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
1060 trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
cb8b99ee 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);
8c8af79a 1077 trk->SetFlagsTiming((trackWord >> 51) & 0x1);
1078 trk->SetReserved((trackWord >> 49) & 0x3);
cb8b99ee 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
f77d6f54 1087 if (trk->GetFlagsTiming() == 0) {
1088 AliError(Form("*** track not in time: 0x%016llx", trk->GetExtendedTrackWord(0)));
1089 }
1090
cb8b99ee 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 }
9cb9c409 1099 }
1100 idx++;
1101 }
1102
1103 fPayloadCurr += fCurrTrkHeaderSize[stack];
1104
1105 return fCurrTrkHeaderSize[stack];
1106}
5fdfc9e4 1107
9cb9c409 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;
a11bb3f3 1123 fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
2519cca4 1124 if (iTrigger == 7) {
1125 // timeout trigger, use to extract tracking time
1126 fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
1127 }
1128
9cb9c409 1129 fPayloadCurr++;
1130 // data words
1131 fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
1132 }
1133 }
1134 }
d60fe037 1135
9cb9c409 1136 return 0;
d60fe037 1137}
1138
9cb9c409 1139Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
d60fe037 1140{
9cb9c409 1141 // read the stack header
d60fe037 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
9cb9c409 1149 // dumping stack header
1150 AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1151
67271412 1152 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
6419bebb 1153 EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
52a2b6c0 1154 // dumping stack header
1155 AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
1156
d60fe037 1157 return -1;
1158 }
1159
1160 switch (fCurrStackHeaderVersion[stack]) {
9cb9c409 1161 case 0xa:
002576f7 1162 case 0xb:
d60fe037 1163 if (fCurrStackHeaderSize[stack] < 8) {
9cb9c409 1164 LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
d60fe037 1165 return -1;
1166 }
9cb9c409 1167
d60fe037 1168 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
1169 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
9cb9c409 1170 fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
1171
d60fe037 1172 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
1173 // A side
f77d6f54 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;
d60fe037 1177 // B side
f77d6f54 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;
d60fe037 1181 }
1182 break;
9cb9c409 1183
d60fe037 1184 default:
f77d6f54 1185 EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
d60fe037 1186 }
9cb9c409 1187
d60fe037 1188 fPayloadCurr += fCurrStackHeaderSize[stack];
1189
1190 return fCurrStackHeaderSize[stack];
1191}
1192
9cb9c409 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
002576f7 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)) {
9cb9c409 1204 trailer = fPayloadStart + fPayloadSize - 1 - iWord;
1205 break;
1206 }
1207 }
1208
f77d6f54 1209 if (((*trailer) & 0xfff) == 0xf51) {
9cb9c409 1210 UInt_t trailerIndexWord = (*trailer);
1211 Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
f77d6f54 1212 // Int_t trailerVersion = (trailerIndexWord >> 12) & 0xf;
9cb9c409 1213 AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
1214 // parse the trailer
52a2b6c0 1215 if (trailerSize >= 4) {
1216 // match flags from GTU
f77d6f54 1217 fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
1218 fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
52a2b6c0 1219 // individual checksums
f77d6f54 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]);
52a2b6c0 1231
1232 }
1233 else {
1234 LinkError(kUnknown, "Invalid GTU trailer");
1235 }
9cb9c409 1236 }
1237 else
1238 EquipmentError(kUnknown, "trailer index marker mismatch");
1239
1240 return 0;
1241}
1242
d60fe037 1243Int_t AliTRDrawStream::ReadLinkData()
1244{
1245 // read the data in one link (one HC) until the data endmarker is reached
cc26f39c 1246 // returns the number of words read!
d60fe037 1247
1248 Int_t count = 0;
cc26f39c 1249 UInt_t* startPosLink = fPayloadCurr;
1250
9cb9c409 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));
d60fe037 1253
5fdfc9e4 1254 if (fMarkers)
1255 new ((*fMarkers)[fMarkers->GetEntriesFast()])
0d0618dd 1256 AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
5fdfc9e4 1257
92223bf6 1258 if (fErrorFlags & kDiscardHC)
1259 return count;
1260
52a2b6c0 1261 if (fCurrTrackletEnable) {
1262 count += ReadTracklets();
1263 if (fErrorFlags & kDiscardHC)
1264 return count;
1265 }
d60fe037 1266
9cb9c409 1267 AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
d60fe037 1268 count += ReadHcHeader();
92223bf6 1269 if (fErrorFlags & kDiscardHC)
1270 return count;
d60fe037 1271
1272 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
d5a821ac 1273
d60fe037 1274 if (det > -1 && det < 540) {
d5a821ac 1275
d60fe037 1276 // ----- check which kind of data -----
1277 if (fCurrMajor & 0x40) {
1278 if ((fCurrMajor & 0x7) == 0x7) {
d5a821ac 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
43573bcf 1287 AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
1288 AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
d5a821ac 1289 }
1290 else {
1291 Int_t tpmode = fCurrMajor & 0x7;
1292 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
52a2b6c0 1293 count += ReadTPData(tpmode);
d60fe037 1294 }
d5a821ac 1295 }
1296 else {
2519cca4 1297 // reading real data
1298 if (fDigitsManager) {
d5a821ac 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 }
2519cca4 1307
d5a821ac 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 }
2519cca4 1316
d5a821ac 1317 if (fDigitsManager->UsesDictionaries()) {
1318 fDigitsManager->GetDictionary(det, 0)->Reset();
1319 fDigitsManager->GetDictionary(det, 1)->Reset();
1320 fDigitsManager->GetDictionary(det, 2)->Reset();
1321 }
2519cca4 1322
d5a821ac 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++;
2519cca4 1346 }
d60fe037 1347 }
d5a821ac 1348 }
1349 else {
92223bf6 1350 LinkError(kInvalidDetector, "%i", det);
d60fe037 1351 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
d5a821ac 1352 *fPayloadCurr != fgkDataEndmarker)
1353 fPayloadCurr++;
d60fe037 1354 }
637666cd 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 }
cc26f39c 1362
6e66b7e8 1363 if ((fErrorFlags & kDiscardHC) && fAdcArray)
1364 fAdcArray->SetDataInvalid(); // invalidate the data
1365
d60fe037 1366 return count;
1367}
1368
1369Int_t AliTRDrawStream::ReadTracklets()
1370{
1371 // read the tracklets from one HC
1372
f77d6f54 1373 Int_t nTracklets = 0;
d60fe037 1374
1375 UInt_t *start = fPayloadCurr;
5f006bd7 1376 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
ec3b8338 1377 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1378 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1379 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
f77d6f54 1380 ++nTracklets;
1381 if (fTracklets)
1382 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
d60fe037 1383
1384 fPayloadCurr++;
1385 }
1386
f77d6f54 1387 if (nTracklets > 0) {
1388 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
9cb9c409 1389 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
5fdfc9e4 1390 if (fCurrSm > -1 && fCurrSm < 18) {
f77d6f54 1391 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
1392 fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
5fdfc9e4 1393 }
d60fe037 1394 }
1395
1396 // loop over remaining tracklet endmarkers
5f006bd7 1397 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1398 fPayloadCurr - fPayloadStart < fPayloadSize))
d60fe037 1399 fPayloadCurr++;
5f006bd7 1400
cc26f39c 1401 return fPayloadCurr - start;
d60fe037 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
9cb9c409 1409 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
d60fe037 1410 UInt_t *start = fPayloadCurr;
1411 // check not to be at the data endmarker
ec3b8338 1412 if (*fPayloadCurr == fgkDataEndmarker ||
1413 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1414 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1415 LinkError(kHCmismatch, "found endmarker where HC header should be");
d60fe037 1416 return 0;
ec3b8338 1417 }
d60fe037 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
5f006bd7 1429 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1430 (fCurrStack != fCurrSlot) ||
1431 (fCurrLayer != fCurrLink / 2) ||
9cb9c409 1432 (fCurrSide != fCurrLink % 2)) {
92223bf6 1433 LinkError(kHCmismatch,
5f006bd7 1434 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
92223bf6 1435 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
9cb9c409 1436 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
d60fe037 1437 }
1438 if (fCurrCheck != 0x1) {
92223bf6 1439 LinkError(kHCcheckFailed);
d60fe037 1440 }
5f006bd7 1441
d60fe037 1442 if (fCurrAddHcWords > 0) {
1443 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
f77d6f54 1444#ifdef TRD_RAW_DEBUG
1445 fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
1446#endif
d60fe037 1447 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1448 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1449 }
5f006bd7 1450
d60fe037 1451 fPayloadCurr += 1 + fCurrAddHcWords;
5f006bd7 1452
5fdfc9e4 1453 return (fPayloadCurr - start);
d60fe037 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};
52a2b6c0 1462 Int_t evno = -1;
d60fe037 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
5f006bd7 1476 while (*(fPayloadCurr) != fgkDataEndmarker &&
d60fe037 1477 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1478
1479 // ----- Checking MCM Header -----
2519cca4 1480 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1481 UInt_t *startPosMCM = fPayloadCurr;
d60fe037 1482 mcmcount++;
5f006bd7 1483
d60fe037 1484 // ----- checking for proper readout order - ROB -----
52a2b6c0 1485 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1486 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
52a2b6c0 1487 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1488 lastmcmpos = -1;
d60fe037 1489 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1490 }
1491 else {
9cb9c409 1492 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
d60fe037 1493 }
5f006bd7 1494
d60fe037 1495 // ----- checking for proper readout order - MCM -----
52a2b6c0 1496 fCurrMcmPos = MCM(*fPayloadCurr);
1497 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
d60fe037 1498 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1499 }
1500 else {
9cb9c409 1501 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
d60fe037 1502 }
5f006bd7 1503
5fedeee9 1504 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
52a2b6c0 1505 if (evno == -1) {
1506 evno = EvNo(*fPayloadCurr);
1507 }
1508 else {
1509 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
f77d6f54 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
52a2b6c0 1519 }
1520 }
d60fe037 1521
1522 fPayloadCurr++;
5f006bd7 1523
d60fe037 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 }
5f006bd7 1534
d60fe037 1535 while (count < 10) {
2519cca4 1536 if (*fPayloadCurr == fgkDataEndmarker) {
1537 MCMError(kMissTpData);
1538 return (fPayloadCurr - start);
1539 }
1540
d60fe037 1541 if (channelcount % 2 == 0)
1542 expword = 0x3;
5f006bd7 1543 else
d60fe037 1544 expword = 0x2;
5f006bd7 1545
d60fe037 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 ------
5f006bd7 1557 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1558 ((fCurrStack + 1) << 15) |
1559 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
d60fe037 1560 }
1561 else if (mode == 3) {
1562 // ----- TP 3 -----
5f006bd7 1563 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1564 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
d60fe037 1565 }
1566 else {
1567 expword = 0;
92223bf6 1568 LinkError(kTPmodeInvalid, "Just reading");
d60fe037 1569 }
1570
1571 diff = *fPayloadCurr ^ expword;
2519cca4 1572 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1573 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1574
d60fe037 1575 if (diff != 0) {
92223bf6 1576 MCMError(kTPmismatch,
52a2b6c0 1577 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
c4daee41 1578 *fPayloadCurr, expword, diff,
c4daee41 1579 0xffff & (diff | diff >> 16),
52a2b6c0 1580 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
2519cca4 1581 wordcount, cpu, channelcount);;
d60fe037 1582 }
1583 fPayloadCurr++;
1584 count++;
1585 wordcount++;
52a2b6c0 1586 if (*fPayloadCurr == fgkDataEndmarker)
1587 return (fPayloadCurr - start);
d60fe037 1588 }
1589 channelcount++;
1590 }
1591 // continue with next MCM
2519cca4 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
d60fe037 1598 }
5f006bd7 1599 return fPayloadCurr - start;
d60fe037 1600}
1601
1602
1603Int_t AliTRDrawStream::ReadZSData()
1604{
1605 // read the zs data from one link from the current reading position
5f006bd7 1606
d60fe037 1607 UInt_t *start = fPayloadCurr;
5f006bd7 1608
d60fe037 1609 Int_t mcmcount = 0;
0508ca31 1610 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1611 Int_t channelcount = 0;
0508ca31 1612 Int_t channelcountExp = 0;
1613 Int_t channelcountMax = 0;
d60fe037 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) {
5f006bd7 1622 if (fNtimebins > 0)
92223bf6 1623 LinkError(kNtimebinsChanged,
1624 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1625 fNtimebins = fCurrNtimebins;
1626 }
5f006bd7 1627
d60fe037 1628 timebins = fNtimebins;
5f006bd7 1629
1630 while (*(fPayloadCurr) != fgkDataEndmarker &&
ec3b8338 1631 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1632 *(fPayloadCurr) != fgkStackEndmarker[1] &&
d60fe037 1633 fPayloadCurr - fPayloadStart < fPayloadSize) {
5f006bd7 1634
d60fe037 1635 // ----- Checking MCM Header -----
9cb9c409 1636 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
cc26f39c 1637 UInt_t *startPosMCM = fPayloadCurr;
5f006bd7 1638
d60fe037 1639 // ----- checking for proper readout order - ROB -----
52a2b6c0 1640 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1641 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
9cb9c409 1642 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1643 lastmcmpos = -1;
d60fe037 1644 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1645 }
1646 else {
9cb9c409 1647 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1648 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
d60fe037 1649 }
5f006bd7 1650
d60fe037 1651 // ----- checking for proper readout order - MCM -----
52a2b6c0 1652 fCurrMcmPos = MCM(*fPayloadCurr);
d60fe037 1653 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
9cb9c409 1654 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
d60fe037 1655 }
1656 else {
9cb9c409 1657 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1658 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
d60fe037 1659 }
5f006bd7 1660
f77d6f54 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
5fedeee9 1668 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1669 if (evno == -1) {
d60fe037 1670 evno = EvNo(*fPayloadCurr);
5fedeee9 1671 }
d60fe037 1672 else {
f77d6f54 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
d60fe037 1688 }
1689 }
1690 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1691 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1692 Int_t row = Row(*fPayloadCurr);
1693 fPayloadCurr++;
5f006bd7 1694
52a2b6c0 1695 if ((row > 11) && (fCurrStack == 2)) {
789a8b20 1696 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
52a2b6c0 1697 }
1698
789a8b20 1699 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1700 break;
5fedeee9 1701
d60fe037 1702 // ----- Reading ADC channels -----
9cb9c409 1703 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
5f006bd7 1704
d60fe037 1705 // ----- analysing the ADC mask -----
1706 channelcount = 0;
0508ca31 1707 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1708 channelcountMax = GetNActiveChannels(*fPayloadCurr);
d60fe037 1709 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1710 Int_t channelno = -1;
5f006bd7 1711 fPayloadCurr++;
d60fe037 1712
0508ca31 1713 if (channelcountExp != channelcountMax) {
1714 if (channelcountExp > channelcountMax) {
1715 Int_t temp = channelcountExp;
1716 channelcountExp = channelcountMax;
1717 channelcountMax = temp;
d60fe037 1718 }
5f006bd7 1719 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
0508ca31 1720 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
92223bf6 1721 MCMError(kAdcMaskInconsistent,
5f006bd7 1722 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1723 *(fPayloadCurr + 10 * channelcountExp),
92223bf6 1724 *(fPayloadCurr + 10 * channelcountExp + 1) );
5f006bd7 1725 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
0508ca31 1726 channelcountExp++;
d60fe037 1727 else {
1728 break;
1729 }
1730 }
92223bf6 1731 MCMError(kAdcMaskInconsistent,
5f006bd7 1732 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
92223bf6 1733 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
d60fe037 1734 }
9cb9c409 1735 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
5f006bd7 1736
d60fe037 1737 // ----- reading marked ADC channels -----
0508ca31 1738 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1739 if (channelno < 20)
d60fe037 1740 channelno++;
e29e514c 1741 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
d60fe037 1742 channelno++;
5f006bd7 1743
d60fe037 1744 if (fCurrNtimebins > 30) {
1745 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1746 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
5f006bd7 1747 }
d60fe037 1748 else {
1749 currentTimebin = 0;
1750 }
5f006bd7 1751
d60fe037 1752 adcwc = 0;
cb8b99ee 1753 Int_t nADCwords = (timebins + 2) / 3;
1754 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
d60fe037 1755 Int_t adccol = adccoloff - channelno;
1756 Int_t padcol = padcoloff - channelno;
5f006bd7 1757// if (adccol < 3 || adccol > 165)
1758// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
cc26f39c 1759// channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1760
cb8b99ee 1761 while ((adcwc < nADCwords) &&
1762 (*(fPayloadCurr) != fgkDataEndmarker) &&
1763 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
d60fe037 1764 int check = 0x3 & *fPayloadCurr;
1765 if (channelno % 2 != 0) { // odd channel
1766 if (check != 0x2 && channelno < 21) {
92223bf6 1767 MCMError(kAdcCheckInvalid,
5f006bd7 1768 "%i for %2i. ADC word in odd channel %i",
92223bf6 1769 check, adcwc+1, channelno);
d60fe037 1770 }
1771 }
1772 else { // even channel
1773 if (check != 0x3 && channelno < 21) {
92223bf6 1774 MCMError(kAdcCheckInvalid,
5f006bd7 1775 "%i for %2i. ADC word in even channel %i",
92223bf6 1776 check, adcwc+1, channelno);
d60fe037 1777 }
1778 }
5f006bd7 1779
789a8b20 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 }
5f006bd7 1794
d60fe037 1795 adcwc++;
1796 fPayloadCurr++;
1797 }
5f006bd7 1798
cb8b99ee 1799 if (adcwc != nADCwords)
92223bf6 1800 MCMError(kAdcDataAbort);
5f006bd7 1801
1802 // adding index
d60fe037 1803 if (padcol > 0 && padcol < 144) {
1804 fSignalIndex->AddIndexRC(row, padcol);
1805 }
5f006bd7 1806
d60fe037 1807 channelcount++;
1808 }
cc26f39c 1809
637666cd 1810 if (fCurrSm > -1 && fCurrSm < 18) {
1811 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1812 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1813 }
0508ca31 1814 if (channelcount != channelcountExp)
92223bf6 1815 MCMError(kAdcChannelsMiss);
5f006bd7 1816
d60fe037 1817 mcmcount++;
637666cd 1818 if (fCurrSm > -1 && fCurrSm < 18) {
1819 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1820 fStats.fStatsSector[fCurrSm].fNMCMs++;
1821 }
cc26f39c 1822
1823 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
9cb9c409 1824 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1825 startPosMCM, fPayloadCurr - startPosMCM));
cc26f39c 1826 }
1827
d60fe037 1828 // continue with next MCM
1829 }
1830
1831 // check for missing MCMs (if header suppression is inactive)
67271412 1832 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
92223bf6 1833 LinkError(kMissMcmHeaders,
5f006bd7 1834 "No. of MCM headers %i not as expected: %i",
92223bf6 1835 mcmcount, mcmcountExp);
d60fe037 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
5f006bd7 1844
d60fe037 1845 UInt_t *start = fPayloadCurr;
5f006bd7 1846
d60fe037 1847 Int_t mcmcount = 0;
0508ca31 1848 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1849 Int_t channelcount = 0;
0508ca31 1850 Int_t channelcountExp = 0;
d60fe037 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) {
5f006bd7 1859 if (fNtimebins > 0)
92223bf6 1860 LinkError(kNtimebinsChanged,
1861 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1862 fNtimebins = fCurrNtimebins;
1863 }
5f006bd7 1864
d60fe037 1865 timebins = fNtimebins;
5f006bd7 1866
1867 while (*(fPayloadCurr) != fgkDataEndmarker &&
d60fe037 1868 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
5f006bd7 1869
d60fe037 1870 // ----- Checking MCM Header -----
1871 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
5f006bd7 1872
d60fe037 1873 // ----- checking for proper readout order - ROB -----
52a2b6c0 1874 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1875 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
52a2b6c0 1876 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1877 lastmcmpos = -1;
d60fe037 1878 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1879 }
1880 else {
9cb9c409 1881 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
d60fe037 1882 }
5f006bd7 1883
d60fe037 1884 // ----- checking for proper readout order - MCM -----
52a2b6c0 1885 fCurrMcmPos = MCM(*fPayloadCurr);
1886 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
9cb9c409 1887 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
d60fe037 1888 }
1889 else {
9cb9c409 1890 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
d60fe037 1891 }
5f006bd7 1892
5fedeee9 1893 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1894 if (evno == -1) {
d60fe037 1895 evno = EvNo(*fPayloadCurr);
5fedeee9 1896 }
d60fe037 1897 else {
52a2b6c0 1898 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
f77d6f54 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
d60fe037 1908 }
1909 }
5f006bd7 1910
d60fe037 1911 channelcount = 0;
0508ca31 1912 channelcountExp = 21;
d60fe037 1913 int channelno = -1;
1914
1915 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1916 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1917 Int_t row = Row(*fPayloadCurr);
d60fe037 1918 fPayloadCurr++;
1919
789a8b20 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
d60fe037 1927 // ----- reading marked ADC channels -----
5f006bd7 1928 while (channelcount < channelcountExp &&
d60fe037 1929 *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1930 if (channelno < 20)
d60fe037 1931 channelno++;
5f006bd7 1932
d60fe037 1933 currentTimebin = 0;
5f006bd7 1934
d60fe037 1935 adcwc = 0;
cb8b99ee 1936 Int_t nADCwords = (timebins + 2) / 3;
1937 AliDebug(2, Form("Now looking %i words", nADCwords));
d60fe037 1938 Int_t adccol = adccoloff - channelno;
1939 Int_t padcol = padcoloff - channelno;
cb8b99ee 1940 while ((adcwc < nADCwords) &&
1941 (*(fPayloadCurr) != fgkDataEndmarker) &&
1942 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
d60fe037 1943 int check = 0x3 & *fPayloadCurr;
1944 if (channelno % 2 != 0) { // odd channel
1945 if (check != 0x2 && channelno < 21) {
92223bf6 1946 MCMError(kAdcCheckInvalid,
5f006bd7 1947 "%i for %2i. ADC word in odd channel %i",
92223bf6 1948 check, adcwc+1, channelno);
d60fe037 1949 }
1950 }
1951 else { // even channel
1952 if (check != 0x3 && channelno < 21) {
92223bf6 1953 MCMError(kAdcCheckInvalid,
5f006bd7 1954 "%i for %2i. ADC word in even channel %i",
92223bf6 1955 check, adcwc+1, channelno);
d60fe037 1956 }
1957 }
5f006bd7 1958
789a8b20 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 }
d60fe037 1973
1974 adcwc++;
1975 fPayloadCurr++;
1976 }
1977
cb8b99ee 1978 if (adcwc != nADCwords)
92223bf6 1979 MCMError(kAdcDataAbort);
5f006bd7 1980
1981 // adding index
d60fe037 1982 if (padcol > 0 && padcol < 144) {
1983 fSignalIndex->AddIndexRC(row, padcol);
1984 }
1985
1986 channelcount++;
1987 }
1988
0508ca31 1989 if (channelcount != channelcountExp)
92223bf6 1990 MCMError(kAdcChannelsMiss);
d60fe037 1991 mcmcount++;
1992 // continue with next MCM
1993 }
1994
1995 // check for missing MCMs (if header suppression is inactive)
0508ca31 1996 if (mcmcount != mcmcountExp) {
92223bf6 1997 LinkError(kMissMcmHeaders,
1998 "%i not as expected: %i", mcmcount, mcmcountExp);
d60fe037 1999 }
2000
2001 return (fPayloadCurr - start);
2002}
2003
f77d6f54 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
52a2b6c0 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
92223bf6 2065Int_t AliTRDrawStream::SeekNextLink()
2066{
92305359 2067 // proceed in raw data stream till the next link
2068
92223bf6 2069 UInt_t *start = fPayloadCurr;
2070
2071 // read until data endmarkers
2072 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
ec3b8338 2073 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2074 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
92223bf6 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}
67271412 2085
2086
1d62be37 2087void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2088{
2089 // register error according to error code on equipment level
0508ca31 2090 // and return the corresponding error message
2091
9cb9c409 2092 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2093 fLastError.fStack = -1;
2094 fLastError.fLink = -1;
2095 fLastError.fRob = -1;
2096 fLastError.fMcm = -1;
2097 fLastError.fError = err;
f4b3235e 2098 (this->*fStoreError)();
d60fe037 2099
92223bf6 2100 va_list ap;
5f006bd7 2101 if (fgErrorDebugLevel[err] > 10)
92223bf6 2102 AliDebug(fgErrorDebugLevel[err],
5f006bd7 2103 Form("Event %6i: Eq. %2d - %s : %s",
92305359 2104 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 2105 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2106 else
2107 AliError(Form("Event %6i: Eq. %2d - %s : %s",
92305359 2108 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 2109 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2110 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2111}
d60fe037 2112
2113
1d62be37 2114void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2115{
2116 // register error according to error code on stack level
0508ca31 2117 // and return the corresponding error message
2118
9cb9c409 2119 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2120 fLastError.fStack = fCurrSlot;
2121 fLastError.fLink = -1;
2122 fLastError.fRob = -1;
2123 fLastError.fMcm = -1;
2124 fLastError.fError = err;
f4b3235e 2125 (this->*fStoreError)();
d60fe037 2126
92223bf6 2127 va_list ap;
5f006bd7 2128 if (fgErrorDebugLevel[err] > 0)
2129 AliDebug(fgErrorDebugLevel[err],
2130 Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2131 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2132 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2133 else
2134 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2135 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2136 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2137 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2138}
d60fe037 2139
2140
1d62be37 2141void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2142{
2143 // register error according to error code on link level
0508ca31 2144 // and return the corresponding error message
2145
9cb9c409 2146 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2147 fLastError.fStack = fCurrSlot;
2148 fLastError.fLink = fCurrLink;
2149 fLastError.fRob = -1;
2150 fLastError.fMcm = -1;
2151 fLastError.fError = err;
f4b3235e 2152 (this->*fStoreError)();
d60fe037 2153
92223bf6 2154 va_list ap;
e29e514c 2155 if (fgErrorDebugLevel[err] > 0)
5f006bd7 2156 AliDebug(fgErrorDebugLevel[err],
2157 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2158 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2159 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2160 else
2161 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2162 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2163 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2164 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2165}
d60fe037 2166
2167
1d62be37 2168void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2169{
2170 // register error according to error code on ROB level
0508ca31 2171 // and return the corresponding error message
2172
9cb9c409 2173 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2174 fLastError.fStack = fCurrSlot;
2175 fLastError.fLink = fCurrLink;
2176 fLastError.fRob = fCurrRobPos;
2177 fLastError.fMcm = -1;
2178 fLastError.fError = err;
f4b3235e 2179 (this->*fStoreError)();
d60fe037 2180
92223bf6 2181 va_list ap;
5f006bd7 2182 if (fgErrorDebugLevel[err] > 0)
2183 AliDebug(fgErrorDebugLevel[err],
2184 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
92305359 2185 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 2186 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 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],
1d62be37 2190 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2191 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2192}
d60fe037 2193
2194
1d62be37 2195void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2196{
2197 // register error according to error code on MCM level
0508ca31 2198 // and return the corresponding error message
2199
9cb9c409 2200 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2201 fLastError.fStack = fCurrSlot;
2202 fLastError.fLink = fCurrLink;
2203 fLastError.fRob = fCurrRobPos;
2204 fLastError.fMcm = fCurrMcmPos;
2205 fLastError.fError = err;
f4b3235e 2206 (this->*fStoreError)();
d60fe037 2207
92223bf6 2208 va_list ap;
5f006bd7 2209 if (fgErrorDebugLevel[err] > 0)
2210 AliDebug(fgErrorDebugLevel[err],
92223bf6 2211 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2212 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2213 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2214 else
92223bf6 2215 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2216 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2217 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2218 fErrorFlags |= fgErrorBehav[err];
d60fe037 2219}
2220
2221const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
5f006bd7 2222{
0508ca31 2223 // return the error message for the given error code
2224
5f006bd7 2225 if (errCode > 0 && errCode < kLastErrorCode)
92305359 2226 return fgkErrorMessages[errCode];
5f006bd7 2227 else
2228 return "";
2229}
cc26f39c 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)
5f006bd7 2269{
cc26f39c 2270 // mark MCM for dumping of raw data
2271
2272 if (dump) {
5f006bd7 2273 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
cc26f39c 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
92305359 2289Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
cc26f39c 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
6419bebb 2301TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
cc26f39c 2302{
2303 // dump raw data
2304
2305 title += "\n";
9cb9c409 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))
5f006bd7 2311 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2312 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2313 else {
5f006bd7 2314 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2315 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2316 return title;
2317 }
2318 else {
5f006bd7 2319 title += Form(" 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2320 start[pos+0], start[pos+1], start[pos+2]);
2321 return title;
2322 }
2323 else {
5f006bd7 2324 title += Form(" 0x%08x 0x%08x\n",
9cb9c409 2325 start[pos+0], start[pos+1]);
2326 return title;
2327 }
2328 else {
5f006bd7 2329 title += Form(" 0x%08x\n",
9cb9c409 2330 start[pos+0]);
2331 return title;
2332 }
cc26f39c 2333 }
9cb9c409 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;
cc26f39c 2349}
f4b3235e 2350
5f006bd7 2351AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
f4b3235e 2352 fError(error),
2353 fSector(sector),
2354 fStack(stack),
5f006bd7 2355 fLink(link),
f4b3235e 2356 fRob(rob),
2357 fMcm(mcm)
2358{
2359 // ctor
2360
2361}
52a2b6c0 2362
2363void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2364{
2365 // sort tracklets for referencing from GTU tracks
2366
5fedeee9 2367 if (!trklArray)
2368 return;
2369
52a2b6c0 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 {
5fedeee9 2413 if (trklA->GetZbin() <= trklB->GetZbin()) {
52a2b6c0 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) {
03e2f460 2429 sortedTracklets.Add(trklNext);
2430
52a2b6c0 2431 }
ec3b8338 2432 }
52a2b6c0 2433
ec3b8338 2434 // updating tracklet indices as in output
2435 if (sortedTracklets.GetEntries() != trklIndex) {
03e2f460 2436 indices[2*iDet + 0] = trklIndex;
2437 indices[2*iDet + 1] = sortedTracklets.GetEntries();
ec3b8338 2438 } else {
2439 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
52a2b6c0 2440 }
2441 }
2442}
03e2f460 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}