]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDrawStream.cxx
Bug fix: AliHLTComponent::ConfigureFromArgumentString
[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
d60fe037 1363 return count;
1364}
1365
1366Int_t AliTRDrawStream::ReadTracklets()
1367{
1368 // read the tracklets from one HC
1369
f77d6f54 1370 Int_t nTracklets = 0;
d60fe037 1371
1372 UInt_t *start = fPayloadCurr;
5f006bd7 1373 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
ec3b8338 1374 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1375 *(fPayloadCurr) != fgkStackEndmarker[1] &&
1376 fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
f77d6f54 1377 ++nTracklets;
1378 if (fTracklets)
1379 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
d60fe037 1380
1381 fPayloadCurr++;
1382 }
1383
f77d6f54 1384 if (nTracklets > 0) {
1385 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
9cb9c409 1386 (fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
5fdfc9e4 1387 if (fCurrSm > -1 && fCurrSm < 18) {
f77d6f54 1388 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
1389 fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
5fdfc9e4 1390 }
d60fe037 1391 }
1392
1393 // loop over remaining tracklet endmarkers
5f006bd7 1394 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
1395 fPayloadCurr - fPayloadStart < fPayloadSize))
d60fe037 1396 fPayloadCurr++;
5f006bd7 1397
cc26f39c 1398 return fPayloadCurr - start;
d60fe037 1399}
1400
1401Int_t AliTRDrawStream::ReadHcHeader()
1402{
1403 // read and parse the HC header of one HC
1404 // and store the information in the corresponding variables
1405
9cb9c409 1406 AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
d60fe037 1407 UInt_t *start = fPayloadCurr;
1408 // check not to be at the data endmarker
ec3b8338 1409 if (*fPayloadCurr == fgkDataEndmarker ||
1410 *(fPayloadCurr) == fgkStackEndmarker[0] ||
1411 *(fPayloadCurr) == fgkStackEndmarker[1]) {
1412 LinkError(kHCmismatch, "found endmarker where HC header should be");
d60fe037 1413 return 0;
ec3b8338 1414 }
d60fe037 1415
1416 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
1417 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
1418 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
1419 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
1420 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
1421 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
1422 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
1423 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
1424 fCurrCheck = (*fPayloadCurr) & 0x3;
1425
5f006bd7 1426 if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
1427 (fCurrStack != fCurrSlot) ||
1428 (fCurrLayer != fCurrLink / 2) ||
9cb9c409 1429 (fCurrSide != fCurrLink % 2)) {
92223bf6 1430 LinkError(kHCmismatch,
5f006bd7 1431 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
92223bf6 1432 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
9cb9c409 1433 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
d60fe037 1434 }
1435 if (fCurrCheck != 0x1) {
92223bf6 1436 LinkError(kHCcheckFailed);
d60fe037 1437 }
5f006bd7 1438
d60fe037 1439 if (fCurrAddHcWords > 0) {
1440 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
f77d6f54 1441#ifdef TRD_RAW_DEBUG
1442 fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
1443#endif
d60fe037 1444 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
1445 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
1446 }
5f006bd7 1447
d60fe037 1448 fPayloadCurr += 1 + fCurrAddHcWords;
5f006bd7 1449
5fdfc9e4 1450 return (fPayloadCurr - start);
d60fe037 1451}
1452
1453Int_t AliTRDrawStream::ReadTPData(Int_t mode)
1454{
1455 // testing of testpattern 1 to 3 (hardcoded), 0 missing
1456 // evcnt checking missing
1457 Int_t cpu = 0;
1458 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 1459 Int_t evno = -1;
d60fe037 1460 Int_t evcnt = 0;
1461 Int_t count = 0;
1462 Int_t mcmcount = -1;
1463 Int_t wordcount = 0;
1464 Int_t channelcount = 0;
1465 UInt_t expword = 0;
1466 UInt_t expadcval = 0;
1467 UInt_t diff = 0;
1468 Int_t lastmcmpos = -1;
1469 Int_t lastrobpos = -1;
1470
1471 UInt_t* start = fPayloadCurr;
1472
5f006bd7 1473 while (*(fPayloadCurr) != fgkDataEndmarker &&
d60fe037 1474 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
1475
1476 // ----- Checking MCM Header -----
2519cca4 1477 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
1478 UInt_t *startPosMCM = fPayloadCurr;
d60fe037 1479 mcmcount++;
5f006bd7 1480
d60fe037 1481 // ----- checking for proper readout order - ROB -----
52a2b6c0 1482 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1483 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
52a2b6c0 1484 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1485 lastmcmpos = -1;
d60fe037 1486 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1487 }
1488 else {
9cb9c409 1489 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
d60fe037 1490 }
5f006bd7 1491
d60fe037 1492 // ----- checking for proper readout order - MCM -----
52a2b6c0 1493 fCurrMcmPos = MCM(*fPayloadCurr);
1494 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
d60fe037 1495 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
1496 }
1497 else {
9cb9c409 1498 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
d60fe037 1499 }
5f006bd7 1500
5fedeee9 1501 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
52a2b6c0 1502 if (evno == -1) {
1503 evno = EvNo(*fPayloadCurr);
1504 }
1505 else {
1506 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
f77d6f54 1507#ifdef TRD_RAW_DEBUG
1508 if (fCurrL0offset[fCurrHC/2] != 0)
1509 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1510 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1511 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1512 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1513 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1514 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1515#endif
52a2b6c0 1516 }
1517 }
d60fe037 1518
1519 fPayloadCurr++;
5f006bd7 1520
d60fe037 1521 evcnt = 0x3f & *fPayloadCurr >> 26;
1522 cpu = -1;
1523 channelcount = 0;
1524 while (channelcount < 21) {
1525 count = 0;
1526 if (cpu != cpufromchannel[channelcount]) {
1527 cpu = cpufromchannel[channelcount];
1528 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
1529 wordcount = 0;
1530 }
5f006bd7 1531
d60fe037 1532 while (count < 10) {
2519cca4 1533 if (*fPayloadCurr == fgkDataEndmarker) {
1534 MCMError(kMissTpData);
1535 return (fPayloadCurr - start);
1536 }
1537
d60fe037 1538 if (channelcount % 2 == 0)
1539 expword = 0x3;
5f006bd7 1540 else
d60fe037 1541 expword = 0x2;
5f006bd7 1542
d60fe037 1543 if (mode == 1) {
1544 // ----- TP 1 -----
1545 expword |= expadcval << 2;
1546 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1547 expword |= expadcval << 12;
1548 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1549 expword |= expadcval << 22;
1550 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
1551 }
1552 else if (mode == 2) {
1553 // ----- TP 2 ------
5f006bd7 1554 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
1555 ((fCurrStack + 1) << 15) |
1556 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
d60fe037 1557 }
1558 else if (mode == 3) {
1559 // ----- TP 3 -----
5f006bd7 1560 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
1561 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
d60fe037 1562 }
1563 else {
1564 expword = 0;
92223bf6 1565 LinkError(kTPmodeInvalid, "Just reading");
d60fe037 1566 }
1567
1568 diff = *fPayloadCurr ^ expword;
2519cca4 1569 AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
1570 channelcount, wordcount, cpu, *fPayloadCurr, expword));
1571
d60fe037 1572 if (diff != 0) {
92223bf6 1573 MCMError(kTPmismatch,
52a2b6c0 1574 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
c4daee41 1575 *fPayloadCurr, expword, diff,
c4daee41 1576 0xffff & (diff | diff >> 16),
52a2b6c0 1577 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
2519cca4 1578 wordcount, cpu, channelcount);;
d60fe037 1579 }
1580 fPayloadCurr++;
1581 count++;
1582 wordcount++;
52a2b6c0 1583 if (*fPayloadCurr == fgkDataEndmarker)
1584 return (fPayloadCurr - start);
d60fe037 1585 }
1586 channelcount++;
1587 }
1588 // continue with next MCM
2519cca4 1589
1590 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1591 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1592 startPosMCM, fPayloadCurr - startPosMCM));
1593 }
1594
d60fe037 1595 }
5f006bd7 1596 return fPayloadCurr - start;
d60fe037 1597}
1598
1599
1600Int_t AliTRDrawStream::ReadZSData()
1601{
1602 // read the zs data from one link from the current reading position
5f006bd7 1603
d60fe037 1604 UInt_t *start = fPayloadCurr;
5f006bd7 1605
d60fe037 1606 Int_t mcmcount = 0;
0508ca31 1607 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1608 Int_t channelcount = 0;
0508ca31 1609 Int_t channelcountExp = 0;
1610 Int_t channelcountMax = 0;
d60fe037 1611 Int_t timebins;
1612 Int_t currentTimebin = 0;
1613 Int_t adcwc = 0;
1614 Int_t evno = -1;
1615 Int_t lastmcmpos = -1;
1616 Int_t lastrobpos = -1;
1617
1618 if (fCurrNtimebins != fNtimebins) {
5f006bd7 1619 if (fNtimebins > 0)
92223bf6 1620 LinkError(kNtimebinsChanged,
1621 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1622 fNtimebins = fCurrNtimebins;
1623 }
5f006bd7 1624
d60fe037 1625 timebins = fNtimebins;
5f006bd7 1626
1627 while (*(fPayloadCurr) != fgkDataEndmarker &&
ec3b8338 1628 *(fPayloadCurr) != fgkStackEndmarker[0] &&
1629 *(fPayloadCurr) != fgkStackEndmarker[1] &&
d60fe037 1630 fPayloadCurr - fPayloadStart < fPayloadSize) {
5f006bd7 1631
d60fe037 1632 // ----- Checking MCM Header -----
9cb9c409 1633 AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
cc26f39c 1634 UInt_t *startPosMCM = fPayloadCurr;
5f006bd7 1635
d60fe037 1636 // ----- checking for proper readout order - ROB -----
52a2b6c0 1637 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1638 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
9cb9c409 1639 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1640 lastmcmpos = -1;
d60fe037 1641 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1642 }
1643 else {
9cb9c409 1644 ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1645 GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
d60fe037 1646 }
5f006bd7 1647
d60fe037 1648 // ----- checking for proper readout order - MCM -----
52a2b6c0 1649 fCurrMcmPos = MCM(*fPayloadCurr);
d60fe037 1650 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
9cb9c409 1651 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
d60fe037 1652 }
1653 else {
9cb9c409 1654 MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
1655 GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
d60fe037 1656 }
5f006bd7 1657
f77d6f54 1658#ifdef TRD_RAW_DEBUG
1659 if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
1660 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1661 }
1662 fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
1663#endif
1664
5fedeee9 1665 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1666 if (evno == -1) {
d60fe037 1667 evno = EvNo(*fPayloadCurr);
5fedeee9 1668 }
d60fe037 1669 else {
f77d6f54 1670 MCMError(kEvCntMismatch, "exp <-> SM: %i <-> %i", evno & 0xfffff, EvNo(*fPayloadCurr));
1671#ifdef TRD_RAW_DEBUG
1672 Int_t prevOffset = fCurrL0offset[fCurrHC/2];
1673 fCurrL0offset[fCurrHC/2] = (- fCurrL0Count[fCurrEquipmentId-kDDLOffset] + EvNo(*fPayloadCurr)) % (1 << 20);
1674 if (fCurrL0offset[fCurrHC/2] < 0)
1675 fCurrL0offset[fCurrHC/2] += 0xfffff;
1676 evno = (fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2]) & 0xfffff;
1677 if (prevOffset != 0)
1678 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1679 fCurrEquipmentId, fCurrSlot, fCurrLink/2,
1680 prevOffset,
1681 fCurrL0offset[fCurrHC/2],
1682 fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1683 EvNo(*fPayloadCurr));
1684#endif
d60fe037 1685 }
1686 }
1687 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1688 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1689 Int_t row = Row(*fPayloadCurr);
1690 fPayloadCurr++;
5f006bd7 1691
52a2b6c0 1692 if ((row > 11) && (fCurrStack == 2)) {
789a8b20 1693 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
52a2b6c0 1694 }
1695
789a8b20 1696 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1697 break;
5fedeee9 1698
d60fe037 1699 // ----- Reading ADC channels -----
9cb9c409 1700 AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
5f006bd7 1701
d60fe037 1702 // ----- analysing the ADC mask -----
1703 channelcount = 0;
0508ca31 1704 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
1705 channelcountMax = GetNActiveChannels(*fPayloadCurr);
d60fe037 1706 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
1707 Int_t channelno = -1;
5f006bd7 1708 fPayloadCurr++;
d60fe037 1709
0508ca31 1710 if (channelcountExp != channelcountMax) {
1711 if (channelcountExp > channelcountMax) {
1712 Int_t temp = channelcountExp;
1713 channelcountExp = channelcountMax;
1714 channelcountMax = temp;
d60fe037 1715 }
5f006bd7 1716 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
0508ca31 1717 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
92223bf6 1718 MCMError(kAdcMaskInconsistent,
5f006bd7 1719 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
1720 *(fPayloadCurr + 10 * channelcountExp),
92223bf6 1721 *(fPayloadCurr + 10 * channelcountExp + 1) );
5f006bd7 1722 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
0508ca31 1723 channelcountExp++;
d60fe037 1724 else {
1725 break;
1726 }
1727 }
92223bf6 1728 MCMError(kAdcMaskInconsistent,
5f006bd7 1729 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
92223bf6 1730 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
d60fe037 1731 }
9cb9c409 1732 AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
5f006bd7 1733
d60fe037 1734 // ----- reading marked ADC channels -----
0508ca31 1735 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1736 if (channelno < 20)
d60fe037 1737 channelno++;
e29e514c 1738 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
d60fe037 1739 channelno++;
5f006bd7 1740
d60fe037 1741 if (fCurrNtimebins > 30) {
1742 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
1743 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
5f006bd7 1744 }
d60fe037 1745 else {
1746 currentTimebin = 0;
1747 }
5f006bd7 1748
d60fe037 1749 adcwc = 0;
cb8b99ee 1750 Int_t nADCwords = (timebins + 2) / 3;
1751 AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
d60fe037 1752 Int_t adccol = adccoloff - channelno;
1753 Int_t padcol = padcoloff - channelno;
5f006bd7 1754// if (adccol < 3 || adccol > 165)
1755// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
cc26f39c 1756// channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
1757
cb8b99ee 1758 while ((adcwc < nADCwords) &&
1759 (*(fPayloadCurr) != fgkDataEndmarker) &&
1760 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
d60fe037 1761 int check = 0x3 & *fPayloadCurr;
1762 if (channelno % 2 != 0) { // odd channel
1763 if (check != 0x2 && channelno < 21) {
92223bf6 1764 MCMError(kAdcCheckInvalid,
5f006bd7 1765 "%i for %2i. ADC word in odd channel %i",
92223bf6 1766 check, adcwc+1, channelno);
d60fe037 1767 }
1768 }
1769 else { // even channel
1770 if (check != 0x3 && channelno < 21) {
92223bf6 1771 MCMError(kAdcCheckInvalid,
5f006bd7 1772 "%i for %2i. ADC word in even channel %i",
92223bf6 1773 check, adcwc+1, channelno);
d60fe037 1774 }
1775 }
5f006bd7 1776
789a8b20 1777 if ((fErrorFlags & kDiscardMCM) == 0) {
1778 // filling the actual timebin data
1779 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1780 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1781 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1782 if (adcwc != 0 || fCurrNtimebins <= 30)
1783 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1784 else
1785 tb0 = -1;
1786 if (currentTimebin < fCurrNtimebins)
1787 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1788 if (currentTimebin < fCurrNtimebins)
1789 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1790 }
5f006bd7 1791
d60fe037 1792 adcwc++;
1793 fPayloadCurr++;
1794 }
5f006bd7 1795
cb8b99ee 1796 if (adcwc != nADCwords)
92223bf6 1797 MCMError(kAdcDataAbort);
5f006bd7 1798
1799 // adding index
d60fe037 1800 if (padcol > 0 && padcol < 144) {
1801 fSignalIndex->AddIndexRC(row, padcol);
1802 }
5f006bd7 1803
d60fe037 1804 channelcount++;
1805 }
cc26f39c 1806
637666cd 1807 if (fCurrSm > -1 && fCurrSm < 18) {
1808 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1809 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1810 }
0508ca31 1811 if (channelcount != channelcountExp)
92223bf6 1812 MCMError(kAdcChannelsMiss);
5f006bd7 1813
d60fe037 1814 mcmcount++;
637666cd 1815 if (fCurrSm > -1 && fCurrSm < 18) {
1816 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1817 fStats.fStatsSector[fCurrSm].fNMCMs++;
1818 }
cc26f39c 1819
1820 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
9cb9c409 1821 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1822 startPosMCM, fPayloadCurr - startPosMCM));
cc26f39c 1823 }
1824
d60fe037 1825 // continue with next MCM
1826 }
1827
1828 // check for missing MCMs (if header suppression is inactive)
67271412 1829 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
92223bf6 1830 LinkError(kMissMcmHeaders,
5f006bd7 1831 "No. of MCM headers %i not as expected: %i",
92223bf6 1832 mcmcount, mcmcountExp);
d60fe037 1833 }
1834
1835 return (fPayloadCurr - start);
1836}
1837
1838Int_t AliTRDrawStream::ReadNonZSData()
1839{
1840 // read the non-zs data from one link from the current reading position
5f006bd7 1841
d60fe037 1842 UInt_t *start = fPayloadCurr;
5f006bd7 1843
d60fe037 1844 Int_t mcmcount = 0;
0508ca31 1845 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1846 Int_t channelcount = 0;
0508ca31 1847 Int_t channelcountExp = 0;
d60fe037 1848 Int_t timebins;
1849 Int_t currentTimebin = 0;
1850 Int_t adcwc = 0;
1851 Int_t evno = -1;
1852 Int_t lastmcmpos = -1;
1853 Int_t lastrobpos = -1;
1854
1855 if (fCurrNtimebins != fNtimebins) {
5f006bd7 1856 if (fNtimebins > 0)
92223bf6 1857 LinkError(kNtimebinsChanged,
1858 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1859 fNtimebins = fCurrNtimebins;
1860 }
5f006bd7 1861
d60fe037 1862 timebins = fNtimebins;
5f006bd7 1863
1864 while (*(fPayloadCurr) != fgkDataEndmarker &&
d60fe037 1865 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
5f006bd7 1866
d60fe037 1867 // ----- Checking MCM Header -----
1868 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
5f006bd7 1869
d60fe037 1870 // ----- checking for proper readout order - ROB -----
52a2b6c0 1871 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1872 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
52a2b6c0 1873 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1874 lastmcmpos = -1;
d60fe037 1875 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1876 }
1877 else {
9cb9c409 1878 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
d60fe037 1879 }
5f006bd7 1880
d60fe037 1881 // ----- checking for proper readout order - MCM -----
52a2b6c0 1882 fCurrMcmPos = MCM(*fPayloadCurr);
1883 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
9cb9c409 1884 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
d60fe037 1885 }
1886 else {
9cb9c409 1887 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
d60fe037 1888 }
5f006bd7 1889
5fedeee9 1890 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1891 if (evno == -1) {
d60fe037 1892 evno = EvNo(*fPayloadCurr);
5fedeee9 1893 }
d60fe037 1894 else {
52a2b6c0 1895 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
f77d6f54 1896#ifdef TRD_RAW_DEBUG
1897 if (fCurrL0offset[fCurrHC/2] != 0)
1898 LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
1899 fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
1900 EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
1901 EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
1902 fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
1903 evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
1904#endif
d60fe037 1905 }
1906 }
5f006bd7 1907
d60fe037 1908 channelcount = 0;
0508ca31 1909 channelcountExp = 21;
d60fe037 1910 int channelno = -1;
1911
1912 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1913 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1914 Int_t row = Row(*fPayloadCurr);
d60fe037 1915 fPayloadCurr++;
1916
789a8b20 1917 if ((row > 11) && (fCurrStack == 2)) {
1918 MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
1919 }
1920
1921 if (fErrorFlags & (kDiscardHC | kDiscardDDL))
1922 break;
1923
d60fe037 1924 // ----- reading marked ADC channels -----
5f006bd7 1925 while (channelcount < channelcountExp &&
d60fe037 1926 *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1927 if (channelno < 20)
d60fe037 1928 channelno++;
5f006bd7 1929
d60fe037 1930 currentTimebin = 0;
5f006bd7 1931
d60fe037 1932 adcwc = 0;
cb8b99ee 1933 Int_t nADCwords = (timebins + 2) / 3;
1934 AliDebug(2, Form("Now looking %i words", nADCwords));
d60fe037 1935 Int_t adccol = adccoloff - channelno;
1936 Int_t padcol = padcoloff - channelno;
cb8b99ee 1937 while ((adcwc < nADCwords) &&
1938 (*(fPayloadCurr) != fgkDataEndmarker) &&
1939 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
d60fe037 1940 int check = 0x3 & *fPayloadCurr;
1941 if (channelno % 2 != 0) { // odd channel
1942 if (check != 0x2 && channelno < 21) {
92223bf6 1943 MCMError(kAdcCheckInvalid,
5f006bd7 1944 "%i for %2i. ADC word in odd channel %i",
92223bf6 1945 check, adcwc+1, channelno);
d60fe037 1946 }
1947 }
1948 else { // even channel
1949 if (check != 0x3 && channelno < 21) {
92223bf6 1950 MCMError(kAdcCheckInvalid,
5f006bd7 1951 "%i for %2i. ADC word in even channel %i",
92223bf6 1952 check, adcwc+1, channelno);
d60fe037 1953 }
1954 }
5f006bd7 1955
789a8b20 1956 if ((fErrorFlags & kDiscardMCM) == 0) {
1957 // filling the actual timebin data
1958 int tb2 = 0x3ff & (*fPayloadCurr >> 22);
1959 int tb1 = 0x3ff & (*fPayloadCurr >> 12);
1960 int tb0 = 0x3ff & (*fPayloadCurr >> 2);
1961 if (adcwc != 0 || fCurrNtimebins <= 30)
1962 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1963 else
1964 tb0 = -1;
1965 if (currentTimebin < fCurrNtimebins)
1966 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1967 if (currentTimebin < fCurrNtimebins)
1968 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1969 }
d60fe037 1970
1971 adcwc++;
1972 fPayloadCurr++;
1973 }
1974
cb8b99ee 1975 if (adcwc != nADCwords)
92223bf6 1976 MCMError(kAdcDataAbort);
5f006bd7 1977
1978 // adding index
d60fe037 1979 if (padcol > 0 && padcol < 144) {
1980 fSignalIndex->AddIndexRC(row, padcol);
1981 }
1982
1983 channelcount++;
1984 }
1985
0508ca31 1986 if (channelcount != channelcountExp)
92223bf6 1987 MCMError(kAdcChannelsMiss);
d60fe037 1988 mcmcount++;
1989 // continue with next MCM
1990 }
1991
1992 // check for missing MCMs (if header suppression is inactive)
0508ca31 1993 if (mcmcount != mcmcountExp) {
92223bf6 1994 LinkError(kMissMcmHeaders,
1995 "%i not as expected: %i", mcmcount, mcmcountExp);
d60fe037 1996 }
1997
1998 return (fPayloadCurr - start);
1999}
2000
f77d6f54 2001#ifdef TRD_RAW_CRC
2002UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
2003{
2004 // calculate the CRC for the data from this link
2005 // must not change the pointers to the data
2006
2007 // always count two endmarkers
2008 Int_t nEndmarkers = 0;
2009 for (Int_t i = 0; i < size; i++) {
2010 if (data[size-1 - i] != fgkDataEndmarker)
2011 break;
2012 nEndmarkers++;
2013 }
2014
2015 size = size - (nEndmarkers-2);
2016
2017 boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
2018
2019 checksumLink.reset();
2020 checksumLink.process_bytes(data, size*sizeof(UInt_t));
2021 return checksumLink();
2022}
2023#else
2024UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * /* data */, Int_t /* size */)
2025{
2026 // checksum calculation relies on boost,
2027 // we return 0 if we cannot calculate it
2028
2029 AliError("Checksum calculation relies on boost CRC implementation!");
2030
2031 return 0;
2032}
2033#endif
2034
52a2b6c0 2035Int_t AliTRDrawStream::SeekNextStack()
2036{
2037 // proceed in raw data stream till the next stack
2038
2039 if (!fCurrStackEndmarkerAvail)
2040 return 0;
2041
2042 UInt_t *start = fPayloadCurr;
2043
2044 // read until data endmarkers
2045 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
2046 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2047 (fPayloadCurr[1] != fgkStackEndmarker[1])))
2048 fPayloadCurr++;
2049
2050 if ((fPayloadCurr - start) != 0)
2051 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
2052
2053 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
2054
2055 // goto next stack
2056 fPayloadCurr++;
2057 fPayloadCurr++;
2058
2059 return (fPayloadCurr-start);
2060}
2061
92223bf6 2062Int_t AliTRDrawStream::SeekNextLink()
2063{
92305359 2064 // proceed in raw data stream till the next link
2065
92223bf6 2066 UInt_t *start = fPayloadCurr;
2067
2068 // read until data endmarkers
2069 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
ec3b8338 2070 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
2071 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
92223bf6 2072 *fPayloadCurr != fgkDataEndmarker)
2073 fPayloadCurr++;
2074
2075 // read all data endmarkers
2076 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
2077 *fPayloadCurr == fgkDataEndmarker)
2078 fPayloadCurr++;
2079
2080 return (fPayloadCurr - start);
2081}
67271412 2082
2083
1d62be37 2084void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2085{
2086 // register error according to error code on equipment level
0508ca31 2087 // and return the corresponding error message
2088
9cb9c409 2089 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2090 fLastError.fStack = -1;
2091 fLastError.fLink = -1;
2092 fLastError.fRob = -1;
2093 fLastError.fMcm = -1;
2094 fLastError.fError = err;
f4b3235e 2095 (this->*fStoreError)();
d60fe037 2096
92223bf6 2097 va_list ap;
5f006bd7 2098 if (fgErrorDebugLevel[err] > 10)
92223bf6 2099 AliDebug(fgErrorDebugLevel[err],
5f006bd7 2100 Form("Event %6i: Eq. %2d - %s : %s",
92305359 2101 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 2102 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2103 else
2104 AliError(Form("Event %6i: Eq. %2d - %s : %s",
92305359 2105 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 2106 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2107 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2108}
d60fe037 2109
2110
1d62be37 2111void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2112{
2113 // register error according to error code on stack level
0508ca31 2114 // and return the corresponding error message
2115
9cb9c409 2116 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2117 fLastError.fStack = fCurrSlot;
2118 fLastError.fLink = -1;
2119 fLastError.fRob = -1;
2120 fLastError.fMcm = -1;
2121 fLastError.fError = err;
f4b3235e 2122 (this->*fStoreError)();
d60fe037 2123
92223bf6 2124 va_list ap;
5f006bd7 2125 if (fgErrorDebugLevel[err] > 0)
2126 AliDebug(fgErrorDebugLevel[err],
2127 Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2128 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2129 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2130 else
2131 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2132 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2133 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2134 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2135}
d60fe037 2136
2137
1d62be37 2138void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2139{
2140 // register error according to error code on link level
0508ca31 2141 // and return the corresponding error message
2142
9cb9c409 2143 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2144 fLastError.fStack = fCurrSlot;
2145 fLastError.fLink = fCurrLink;
2146 fLastError.fRob = -1;
2147 fLastError.fMcm = -1;
2148 fLastError.fError = err;
f4b3235e 2149 (this->*fStoreError)();
d60fe037 2150
92223bf6 2151 va_list ap;
e29e514c 2152 if (fgErrorDebugLevel[err] > 0)
5f006bd7 2153 AliDebug(fgErrorDebugLevel[err],
2154 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2155 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2156 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2157 else
2158 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2159 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2160 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2161 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2162}
d60fe037 2163
2164
1d62be37 2165void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2166{
2167 // register error according to error code on ROB level
0508ca31 2168 // and return the corresponding error message
2169
9cb9c409 2170 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2171 fLastError.fStack = fCurrSlot;
2172 fLastError.fLink = fCurrLink;
2173 fLastError.fRob = fCurrRobPos;
2174 fLastError.fMcm = -1;
2175 fLastError.fError = err;
f4b3235e 2176 (this->*fStoreError)();
d60fe037 2177
92223bf6 2178 va_list ap;
5f006bd7 2179 if (fgErrorDebugLevel[err] > 0)
2180 AliDebug(fgErrorDebugLevel[err],
2181 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
92305359 2182 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 2183 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2184 else
2185 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2186 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 2187 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2188 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2189}
d60fe037 2190
2191
1d62be37 2192void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2193{
2194 // register error according to error code on MCM level
0508ca31 2195 // and return the corresponding error message
2196
9cb9c409 2197 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2198 fLastError.fStack = fCurrSlot;
2199 fLastError.fLink = fCurrLink;
2200 fLastError.fRob = fCurrRobPos;
2201 fLastError.fMcm = fCurrMcmPos;
2202 fLastError.fError = err;
f4b3235e 2203 (this->*fStoreError)();
d60fe037 2204
92223bf6 2205 va_list ap;
5f006bd7 2206 if (fgErrorDebugLevel[err] > 0)
2207 AliDebug(fgErrorDebugLevel[err],
92223bf6 2208 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2209 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2210 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2211 else
92223bf6 2212 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2213 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2214 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2215 fErrorFlags |= fgErrorBehav[err];
d60fe037 2216}
2217
2218const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
5f006bd7 2219{
0508ca31 2220 // return the error message for the given error code
2221
5f006bd7 2222 if (errCode > 0 && errCode < kLastErrorCode)
92305359 2223 return fgkErrorMessages[errCode];
5f006bd7 2224 else
2225 return "";
2226}
cc26f39c 2227
2228void AliTRDrawStream::AliTRDrawStats::ClearStats()
2229{
2230 // clear statistics (includes clearing sector-wise statistics)
2231
2232 fBytesRead = 0;
2233 for (Int_t iSector = 0; iSector < 18; iSector++) {
2234 fStatsSector[iSector].ClearStats();
2235 }
2236
2237}
2238
2239void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2240{
2241 // clear statistics (includes clearing HC-wise statistics)
2242
2243 fBytes = 0;
2244 fBytesRead = 0;
2245 fNTracklets = 0;
2246 fNMCMs = 0;
2247 fNChannels = 0;
2248
2249 for (Int_t iHC = 0; iHC < 60; iHC++) {
2250 fStatsHC[iHC].ClearStats();
2251 }
2252}
2253
2254void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2255{
2256 // clear statistics
2257
2258 fBytes = 0;
2259 fBytesRead = 0;
2260 fNTracklets = 0;
2261 fNMCMs = 0;
2262 fNChannels = 0;
2263}
2264
2265void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
5f006bd7 2266{
cc26f39c 2267 // mark MCM for dumping of raw data
2268
2269 if (dump) {
5f006bd7 2270 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
cc26f39c 2271 }
2272 else {
2273 Int_t iMCM;
2274 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2275 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2276 fNDumpMCMs--;
2277 break;
2278 }
2279 }
2280 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2281 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2282 }
2283 }
2284}
2285
92305359 2286Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
cc26f39c 2287{
2288 // check if MCM data should be dumped
2289
2290 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2291 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2292 return kTRUE;
2293 }
2294 }
2295 return kFALSE;
2296}
2297
6419bebb 2298TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
cc26f39c 2299{
2300 // dump raw data
2301
2302 title += "\n";
9cb9c409 2303 for (Int_t pos = 0; pos < length; pos += 4) {
2304 if ((start[pos+0] != endmarker) && pos+0 < length)
2305 if ((start[pos+1] != endmarker && pos+1 < length))
2306 if ((start[pos+2] != endmarker && pos+2 < length))
2307 if ((start[pos+3] != endmarker && pos+3 < length))
5f006bd7 2308 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2309 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2310 else {
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 return title;
2314 }
2315 else {
5f006bd7 2316 title += Form(" 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2317 start[pos+0], start[pos+1], start[pos+2]);
2318 return title;
2319 }
2320 else {
5f006bd7 2321 title += Form(" 0x%08x 0x%08x\n",
9cb9c409 2322 start[pos+0], start[pos+1]);
2323 return title;
2324 }
2325 else {
5f006bd7 2326 title += Form(" 0x%08x\n",
9cb9c409 2327 start[pos+0]);
2328 return title;
2329 }
cc26f39c 2330 }
9cb9c409 2331 return title;
2332}
2333
2334TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2335{
2336 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2337 word, ROB(word), MCM(word));
2338 return title;
2339}
2340
2341TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2342{
2343 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2344 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2345 return title;
cc26f39c 2346}
f4b3235e 2347
5f006bd7 2348AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
f4b3235e 2349 fError(error),
2350 fSector(sector),
2351 fStack(stack),
5f006bd7 2352 fLink(link),
f4b3235e 2353 fRob(rob),
2354 fMcm(mcm)
2355{
2356 // ctor
2357
2358}
52a2b6c0 2359
2360void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2361{
2362 // sort tracklets for referencing from GTU tracks
2363
5fedeee9 2364 if (!trklArray)
2365 return;
2366
52a2b6c0 2367 Int_t nTracklets = trklArray->GetEntriesFast();
2368
2369 Int_t lastHC = -1;
2370 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2371 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2372 Int_t hc = trkl->GetHCId();
2373 if ((hc < 0) || (hc >= 1080)) {
2374 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2375 continue;
2376 }
2377 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2378 if (hc != lastHC) {
2379 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2380 indices[hc] = iTracklet + 1;
2381 lastHC = hc;
2382 }
2383 }
2384
2385 for (Int_t iDet = 0; iDet < 540; iDet++) {
2386 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2387 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2388 Int_t trklIndex = sortedTracklets.GetEntries();
2389 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2390 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2391 AliTRDtrackletBase *trklNext = 0x0;
2392 while (trklA != 0x0 || trklB != 0x0) {
2393 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2394 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2395 if (trklA == 0x0) {
2396 trklNext = trklB;
2397 trklIndexB++;
2398 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2399 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2400 trklB = 0x0;
2401 }
2402 else if (trklB == 0x0) {
2403 trklNext = trklA;
2404 trklIndexA++;
2405 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2406 if (trklA && trklA->GetHCId() != 2*iDet)
2407 trklA = 0x0;
2408 }
2409 else {
5fedeee9 2410 if (trklA->GetZbin() <= trklB->GetZbin()) {
52a2b6c0 2411 trklNext = trklA;
2412 trklIndexA++;
2413 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2414 if (trklA && trklA->GetHCId() != 2*iDet)
2415 trklA = 0x0;
2416 }
2417 else {
2418 trklNext = trklB;
2419 trklIndexB++;
2420 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2421 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2422 trklB = 0x0;
2423 }
2424 }
2425 if (trklNext) {
03e2f460 2426 sortedTracklets.Add(trklNext);
2427
52a2b6c0 2428 }
ec3b8338 2429 }
52a2b6c0 2430
ec3b8338 2431 // updating tracklet indices as in output
2432 if (sortedTracklets.GetEntries() != trklIndex) {
03e2f460 2433 indices[2*iDet + 0] = trklIndex;
2434 indices[2*iDet + 1] = sortedTracklets.GetEntries();
ec3b8338 2435 } else {
2436 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
52a2b6c0 2437 }
2438 }
2439}
03e2f460 2440
2441void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2442{
2443 UInt_t mask = trdTrack->GetLayerMask();
2444 UInt_t stack = trdTrack->GetStack();
2445
2446 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2447 refIndex[iLayer] = -1;
2448
2449 if (mask & (1 << iLayer)) {
2450
2451 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2452 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2453
2454 if ((det < 0) || (det > 539)) {
2455 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2456 continue;
2457 }
2458 if (trackletIndex[2*det] >= 0) {
2459 if ((trackletIndex[2*det] + idx > -1) &&
2460 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2461 refIndex[iLayer] = trackletIndex[2*det] + idx;
2462 } else {
2463 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2464 }
2465 } else {
2466 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));
2467 }
2468 }
2469 }
2470}