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