]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDrawStream.cxx
Fix out of bounds error
[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;
5b6cd9b6 1702 if (currentTimebin >= fCurrNtimebins)
1703 break;
d60fe037 1704 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
5b6cd9b6 1705 if (currentTimebin >= fCurrNtimebins)
1706 break;
d60fe037 1707 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
5f006bd7 1708
d60fe037 1709 adcwc++;
1710 fPayloadCurr++;
1711 }
5f006bd7 1712
cb8b99ee 1713 if (adcwc != nADCwords)
92223bf6 1714 MCMError(kAdcDataAbort);
5f006bd7 1715
1716 // adding index
d60fe037 1717 if (padcol > 0 && padcol < 144) {
1718 fSignalIndex->AddIndexRC(row, padcol);
1719 }
5f006bd7 1720
d60fe037 1721 channelcount++;
1722 }
cc26f39c 1723
637666cd 1724 if (fCurrSm > -1 && fCurrSm < 18) {
1725 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1726 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1727 }
0508ca31 1728 if (channelcount != channelcountExp)
92223bf6 1729 MCMError(kAdcChannelsMiss);
5f006bd7 1730
d60fe037 1731 mcmcount++;
637666cd 1732 if (fCurrSm > -1 && fCurrSm < 18) {
1733 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1734 fStats.fStatsSector[fCurrSm].fNMCMs++;
1735 }
cc26f39c 1736
1737 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
9cb9c409 1738 AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1739 startPosMCM, fPayloadCurr - startPosMCM));
cc26f39c 1740 }
1741
d60fe037 1742 // continue with next MCM
1743 }
1744
1745 // check for missing MCMs (if header suppression is inactive)
67271412 1746 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
92223bf6 1747 LinkError(kMissMcmHeaders,
5f006bd7 1748 "No. of MCM headers %i not as expected: %i",
92223bf6 1749 mcmcount, mcmcountExp);
d60fe037 1750 }
1751
1752 return (fPayloadCurr - start);
1753}
1754
1755Int_t AliTRDrawStream::ReadNonZSData()
1756{
1757 // read the non-zs data from one link from the current reading position
5f006bd7 1758
d60fe037 1759 UInt_t *start = fPayloadCurr;
5f006bd7 1760
d60fe037 1761 Int_t mcmcount = 0;
0508ca31 1762 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1763 Int_t channelcount = 0;
0508ca31 1764 Int_t channelcountExp = 0;
d60fe037 1765 Int_t timebins;
1766 Int_t currentTimebin = 0;
1767 Int_t adcwc = 0;
1768 Int_t evno = -1;
1769 Int_t lastmcmpos = -1;
1770 Int_t lastrobpos = -1;
1771
1772 if (fCurrNtimebins != fNtimebins) {
5f006bd7 1773 if (fNtimebins > 0)
92223bf6 1774 LinkError(kNtimebinsChanged,
1775 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1776 fNtimebins = fCurrNtimebins;
1777 }
5f006bd7 1778
d60fe037 1779 timebins = fNtimebins;
5f006bd7 1780
1781 while (*(fPayloadCurr) != fgkDataEndmarker &&
d60fe037 1782 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
5f006bd7 1783
d60fe037 1784 // ----- Checking MCM Header -----
1785 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
5f006bd7 1786
d60fe037 1787 // ----- checking for proper readout order - ROB -----
52a2b6c0 1788 fCurrRobPos = ROB(*fPayloadCurr);
d60fe037 1789 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
52a2b6c0 1790 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
1791 lastmcmpos = -1;
d60fe037 1792 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1793 }
1794 else {
9cb9c409 1795 ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
d60fe037 1796 }
5f006bd7 1797
d60fe037 1798 // ----- checking for proper readout order - MCM -----
52a2b6c0 1799 fCurrMcmPos = MCM(*fPayloadCurr);
1800 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
9cb9c409 1801 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
d60fe037 1802 }
1803 else {
9cb9c409 1804 MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
d60fe037 1805 }
5f006bd7 1806
5fedeee9 1807 if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
1808 if (evno == -1) {
d60fe037 1809 evno = EvNo(*fPayloadCurr);
5fedeee9 1810 }
d60fe037 1811 else {
52a2b6c0 1812 MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
d60fe037 1813 }
1814 }
5f006bd7 1815
d60fe037 1816 channelcount = 0;
0508ca31 1817 channelcountExp = 21;
d60fe037 1818 int channelno = -1;
1819
1820 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1821 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1822 Int_t row = Row(*fPayloadCurr);
1823
1824 fPayloadCurr++;
1825
1826 // ----- reading marked ADC channels -----
5f006bd7 1827 while (channelcount < channelcountExp &&
d60fe037 1828 *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1829 if (channelno < 20)
d60fe037 1830 channelno++;
5f006bd7 1831
d60fe037 1832 currentTimebin = 0;
5f006bd7 1833
d60fe037 1834 adcwc = 0;
cb8b99ee 1835 Int_t nADCwords = (timebins + 2) / 3;
1836 AliDebug(2, Form("Now looking %i words", nADCwords));
d60fe037 1837 Int_t adccol = adccoloff - channelno;
1838 Int_t padcol = padcoloff - channelno;
cb8b99ee 1839 while ((adcwc < nADCwords) &&
1840 (*(fPayloadCurr) != fgkDataEndmarker) &&
1841 (fPayloadCurr - fPayloadStart < fPayloadSize)) {
d60fe037 1842 int check = 0x3 & *fPayloadCurr;
1843 if (channelno % 2 != 0) { // odd channel
1844 if (check != 0x2 && channelno < 21) {
92223bf6 1845 MCMError(kAdcCheckInvalid,
5f006bd7 1846 "%i for %2i. ADC word in odd channel %i",
92223bf6 1847 check, adcwc+1, channelno);
d60fe037 1848 }
1849 }
1850 else { // even channel
1851 if (check != 0x3 && channelno < 21) {
92223bf6 1852 MCMError(kAdcCheckInvalid,
5f006bd7 1853 "%i for %2i. ADC word in even channel %i",
92223bf6 1854 check, adcwc+1, channelno);
d60fe037 1855 }
1856 }
5f006bd7 1857
d60fe037 1858 // filling the actual timebin data
1859 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1860 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1861 int tb0 = 0x3ff & *fPayloadCurr >> 2;
5f006bd7 1862 if (adcwc != 0 || fCurrNtimebins <= 30)
d60fe037 1863 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1864 else
1865 tb0 = -1;
5b6cd9b6 1866 if (currentTimebin >= fCurrNtimebins)
1867 break;
d60fe037 1868 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
5b6cd9b6 1869 if (currentTimebin >= fCurrNtimebins)
1870 break;
d60fe037 1871 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1872
1873 adcwc++;
1874 fPayloadCurr++;
1875 }
1876
cb8b99ee 1877 if (adcwc != nADCwords)
92223bf6 1878 MCMError(kAdcDataAbort);
5f006bd7 1879
1880 // adding index
d60fe037 1881 if (padcol > 0 && padcol < 144) {
1882 fSignalIndex->AddIndexRC(row, padcol);
1883 }
1884
1885 channelcount++;
1886 }
1887
0508ca31 1888 if (channelcount != channelcountExp)
92223bf6 1889 MCMError(kAdcChannelsMiss);
d60fe037 1890 mcmcount++;
1891 // continue with next MCM
1892 }
1893
1894 // check for missing MCMs (if header suppression is inactive)
0508ca31 1895 if (mcmcount != mcmcountExp) {
92223bf6 1896 LinkError(kMissMcmHeaders,
1897 "%i not as expected: %i", mcmcount, mcmcountExp);
d60fe037 1898 }
1899
1900 return (fPayloadCurr - start);
1901}
1902
52a2b6c0 1903Int_t AliTRDrawStream::SeekNextStack()
1904{
1905 // proceed in raw data stream till the next stack
1906
1907 if (!fCurrStackEndmarkerAvail)
1908 return 0;
1909
1910 UInt_t *start = fPayloadCurr;
1911
1912 // read until data endmarkers
1913 while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
1914 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1915 (fPayloadCurr[1] != fgkStackEndmarker[1])))
1916 fPayloadCurr++;
1917
1918 if ((fPayloadCurr - start) != 0)
1919 StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
1920
1921 AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
1922
1923 // goto next stack
1924 fPayloadCurr++;
1925 fPayloadCurr++;
1926
1927 return (fPayloadCurr-start);
1928}
1929
92223bf6 1930Int_t AliTRDrawStream::SeekNextLink()
1931{
92305359 1932 // proceed in raw data stream till the next link
1933
92223bf6 1934 UInt_t *start = fPayloadCurr;
1935
1936 // read until data endmarkers
1937 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
ec3b8338 1938 ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
1939 (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
92223bf6 1940 *fPayloadCurr != fgkDataEndmarker)
1941 fPayloadCurr++;
1942
1943 // read all data endmarkers
1944 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1945 *fPayloadCurr == fgkDataEndmarker)
1946 fPayloadCurr++;
1947
1948 return (fPayloadCurr - start);
1949}
1950
5f006bd7 1951Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
67271412 1952{
92305359 1953 // connect the tracklet tree used to store the tracklet output
1954
67271412 1955 fTrackletTree = trklTree;
5f006bd7 1956 if (!fTrackletTree)
67271412 1957 return kTRUE;
1958
5f006bd7 1959 if (!fTrackletTree->GetBranch("hc"))
67271412 1960 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
5f006bd7 1961 else
67271412 1962 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
cc26f39c 1963
5f006bd7 1964 if (!fTrackletTree->GetBranch("trkl"))
cc26f39c 1965 fTrackletTree->Branch("trkl", &fTrackletArray);
5f006bd7 1966 else
67271412 1967 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
cc26f39c 1968
67271412 1969 return kTRUE;
1970}
1971
1972
1d62be37 1973void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 1974{
1975 // register error according to error code on equipment level
0508ca31 1976 // and return the corresponding error message
1977
9cb9c409 1978 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 1979 fLastError.fStack = -1;
1980 fLastError.fLink = -1;
1981 fLastError.fRob = -1;
1982 fLastError.fMcm = -1;
1983 fLastError.fError = err;
f4b3235e 1984 (this->*fStoreError)();
d60fe037 1985
92223bf6 1986 va_list ap;
5f006bd7 1987 if (fgErrorDebugLevel[err] > 10)
92223bf6 1988 AliDebug(fgErrorDebugLevel[err],
5f006bd7 1989 Form("Event %6i: Eq. %2d - %s : %s",
92305359 1990 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 1991 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 1992 else
1993 AliError(Form("Event %6i: Eq. %2d - %s : %s",
92305359 1994 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 1995 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1996 fErrorFlags |= fgErrorBehav[err];
5f006bd7 1997}
d60fe037 1998
1999
1d62be37 2000void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2001{
2002 // register error according to error code on stack level
0508ca31 2003 // and return the corresponding error message
2004
9cb9c409 2005 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2006 fLastError.fStack = fCurrSlot;
2007 fLastError.fLink = -1;
2008 fLastError.fRob = -1;
2009 fLastError.fMcm = -1;
2010 fLastError.fError = err;
f4b3235e 2011 (this->*fStoreError)();
d60fe037 2012
92223bf6 2013 va_list ap;
5f006bd7 2014 if (fgErrorDebugLevel[err] > 0)
2015 AliDebug(fgErrorDebugLevel[err],
2016 Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2017 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2018 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2019 else
2020 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 2021 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 2022 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2023 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2024}
d60fe037 2025
2026
1d62be37 2027void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2028{
2029 // register error according to error code on link level
0508ca31 2030 // and return the corresponding error message
2031
9cb9c409 2032 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2033 fLastError.fStack = fCurrSlot;
2034 fLastError.fLink = fCurrLink;
2035 fLastError.fRob = -1;
2036 fLastError.fMcm = -1;
2037 fLastError.fError = err;
f4b3235e 2038 (this->*fStoreError)();
d60fe037 2039
92223bf6 2040 va_list ap;
e29e514c 2041 if (fgErrorDebugLevel[err] > 0)
5f006bd7 2042 AliDebug(fgErrorDebugLevel[err],
2043 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2044 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2045 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2046 else
2047 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 2048 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 2049 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2050 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2051}
d60fe037 2052
2053
1d62be37 2054void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2055{
2056 // register error according to error code on ROB level
0508ca31 2057 // and return the corresponding error message
2058
9cb9c409 2059 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2060 fLastError.fStack = fCurrSlot;
2061 fLastError.fLink = fCurrLink;
2062 fLastError.fRob = fCurrRobPos;
2063 fLastError.fMcm = -1;
2064 fLastError.fError = err;
f4b3235e 2065 (this->*fStoreError)();
d60fe037 2066
92223bf6 2067 va_list ap;
5f006bd7 2068 if (fgErrorDebugLevel[err] > 0)
2069 AliDebug(fgErrorDebugLevel[err],
2070 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
92305359 2071 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 2072 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2073 else
2074 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
2075 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 2076 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2077 fErrorFlags |= fgErrorBehav[err];
5f006bd7 2078}
d60fe037 2079
2080
1d62be37 2081void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
5f006bd7 2082{
2083 // register error according to error code on MCM level
0508ca31 2084 // and return the corresponding error message
2085
9cb9c409 2086 fLastError.fSector = fCurrEquipmentId - kDDLOffset;
d60fe037 2087 fLastError.fStack = fCurrSlot;
2088 fLastError.fLink = fCurrLink;
2089 fLastError.fRob = fCurrRobPos;
2090 fLastError.fMcm = fCurrMcmPos;
2091 fLastError.fError = err;
f4b3235e 2092 (this->*fStoreError)();
d60fe037 2093
92223bf6 2094 va_list ap;
5f006bd7 2095 if (fgErrorDebugLevel[err] > 0)
2096 AliDebug(fgErrorDebugLevel[err],
92223bf6 2097 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2098 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2099 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
5f006bd7 2100 else
92223bf6 2101 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
5f006bd7 2102 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 2103 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 2104 fErrorFlags |= fgErrorBehav[err];
d60fe037 2105}
2106
2107const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
5f006bd7 2108{
0508ca31 2109 // return the error message for the given error code
2110
5f006bd7 2111 if (errCode > 0 && errCode < kLastErrorCode)
92305359 2112 return fgkErrorMessages[errCode];
5f006bd7 2113 else
2114 return "";
2115}
cc26f39c 2116
2117void AliTRDrawStream::AliTRDrawStats::ClearStats()
2118{
2119 // clear statistics (includes clearing sector-wise statistics)
2120
2121 fBytesRead = 0;
2122 for (Int_t iSector = 0; iSector < 18; iSector++) {
2123 fStatsSector[iSector].ClearStats();
2124 }
2125
2126}
2127
2128void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
2129{
2130 // clear statistics (includes clearing HC-wise statistics)
2131
2132 fBytes = 0;
2133 fBytesRead = 0;
2134 fNTracklets = 0;
2135 fNMCMs = 0;
2136 fNChannels = 0;
2137
2138 for (Int_t iHC = 0; iHC < 60; iHC++) {
2139 fStatsHC[iHC].ClearStats();
2140 }
2141}
2142
2143void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
2144{
2145 // clear statistics
2146
2147 fBytes = 0;
2148 fBytesRead = 0;
2149 fNTracklets = 0;
2150 fNMCMs = 0;
2151 fNChannels = 0;
2152}
2153
2154void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
5f006bd7 2155{
cc26f39c 2156 // mark MCM for dumping of raw data
2157
2158 if (dump) {
5f006bd7 2159 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
cc26f39c 2160 }
2161 else {
2162 Int_t iMCM;
2163 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2164 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2165 fNDumpMCMs--;
2166 break;
2167 }
2168 }
2169 for ( ; iMCM < fNDumpMCMs; iMCM++) {
2170 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
2171 }
2172 }
2173}
2174
92305359 2175Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
cc26f39c 2176{
2177 // check if MCM data should be dumped
2178
2179 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
2180 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
2181 return kTRUE;
2182 }
2183 }
2184 return kFALSE;
2185}
2186
6419bebb 2187TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
cc26f39c 2188{
2189 // dump raw data
2190
2191 title += "\n";
9cb9c409 2192 for (Int_t pos = 0; pos < length; pos += 4) {
2193 if ((start[pos+0] != endmarker) && pos+0 < length)
2194 if ((start[pos+1] != endmarker && pos+1 < length))
2195 if ((start[pos+2] != endmarker && pos+2 < length))
2196 if ((start[pos+3] != endmarker && pos+3 < length))
5f006bd7 2197 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2198 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2199 else {
5f006bd7 2200 title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2201 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
2202 return title;
2203 }
2204 else {
5f006bd7 2205 title += Form(" 0x%08x 0x%08x 0x%08x\n",
9cb9c409 2206 start[pos+0], start[pos+1], start[pos+2]);
2207 return title;
2208 }
2209 else {
5f006bd7 2210 title += Form(" 0x%08x 0x%08x\n",
9cb9c409 2211 start[pos+0], start[pos+1]);
2212 return title;
2213 }
2214 else {
5f006bd7 2215 title += Form(" 0x%08x\n",
9cb9c409 2216 start[pos+0]);
2217 return title;
2218 }
cc26f39c 2219 }
9cb9c409 2220 return title;
2221}
2222
2223TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
2224{
2225 title += Form("0x%08x -> ROB: %i, MCM: %2i",
2226 word, ROB(word), MCM(word));
2227 return title;
2228}
2229
2230TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
2231{
2232 title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
2233 word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
2234 return title;
cc26f39c 2235}
f4b3235e 2236
5f006bd7 2237AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
f4b3235e 2238 fError(error),
2239 fSector(sector),
2240 fStack(stack),
5f006bd7 2241 fLink(link),
f4b3235e 2242 fRob(rob),
2243 fMcm(mcm)
2244{
2245 // ctor
2246
2247}
52a2b6c0 2248
2249void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
2250{
2251 // sort tracklets for referencing from GTU tracks
2252
5fedeee9 2253 if (!trklArray)
2254 return;
2255
52a2b6c0 2256 Int_t nTracklets = trklArray->GetEntriesFast();
2257
2258 Int_t lastHC = -1;
2259 for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
2260 AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
2261 Int_t hc = trkl->GetHCId();
2262 if ((hc < 0) || (hc >= 1080)) {
2263 AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
2264 continue;
2265 }
2266 AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
2267 if (hc != lastHC) {
2268 AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
2269 indices[hc] = iTracklet + 1;
2270 lastHC = hc;
2271 }
2272 }
2273
2274 for (Int_t iDet = 0; iDet < 540; iDet++) {
2275 Int_t trklIndexA = indices[2*iDet + 0] - 1;
2276 Int_t trklIndexB = indices[2*iDet + 1] - 1;
2277 Int_t trklIndex = sortedTracklets.GetEntries();
2278 AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2279 AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2280 AliTRDtrackletBase *trklNext = 0x0;
2281 while (trklA != 0x0 || trklB != 0x0) {
2282 AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
2283 iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
2284 if (trklA == 0x0) {
2285 trklNext = trklB;
2286 trklIndexB++;
2287 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2288 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2289 trklB = 0x0;
2290 }
2291 else if (trklB == 0x0) {
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 {
5fedeee9 2299 if (trklA->GetZbin() <= trklB->GetZbin()) {
52a2b6c0 2300 trklNext = trklA;
2301 trklIndexA++;
2302 trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
2303 if (trklA && trklA->GetHCId() != 2*iDet)
2304 trklA = 0x0;
2305 }
2306 else {
2307 trklNext = trklB;
2308 trklIndexB++;
2309 trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
2310 if (trklB && trklB->GetHCId() != 2*iDet + 1)
2311 trklB = 0x0;
2312 }
2313 }
2314 if (trklNext) {
03e2f460 2315 sortedTracklets.Add(trklNext);
2316
52a2b6c0 2317 }
ec3b8338 2318 }
52a2b6c0 2319
ec3b8338 2320 // updating tracklet indices as in output
2321 if (sortedTracklets.GetEntries() != trklIndex) {
03e2f460 2322 indices[2*iDet + 0] = trklIndex;
2323 indices[2*iDet + 1] = sortedTracklets.GetEntries();
ec3b8338 2324 } else {
2325 indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
52a2b6c0 2326 }
2327 }
2328}
03e2f460 2329
2330void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
2331{
2332 UInt_t mask = trdTrack->GetLayerMask();
2333 UInt_t stack = trdTrack->GetStack();
2334
2335 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
2336 refIndex[iLayer] = -1;
2337
2338 if (mask & (1 << iLayer)) {
2339
2340 Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
2341 Int_t idx = trdTrack->GetTrackletIndex(iLayer);
2342
2343 if ((det < 0) || (det > 539)) {
2344 AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
2345 continue;
2346 }
2347 if (trackletIndex[2*det] >= 0) {
2348 if ((trackletIndex[2*det] + idx > -1) &&
2349 (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
2350 refIndex[iLayer] = trackletIndex[2*det] + idx;
2351 } else {
2352 AliErrorClass(Form("Requested tracklet index %i out of range", idx));
2353 }
2354 } else {
2355 AliErrorClass(Form("Non-existing tracklets requested in det %i", det));
2356 }
2357 }
2358 }
2359}