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