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