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