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