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