]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDrawStream.cxx
test Id (Ivana)
[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 //
19// and translation into ADC values //
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"
d60fe037 42
43#include "AliTRDrawStream.h"
44
45// temporary
46#include "AliRunLoader.h"
47
48ClassImp(AliTRDrawStream)
49
50// some static information
51const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
cc26f39c 52 8, 9, 10, 11,
53 4, 5, 6, 7,
54 0, 1, 2, 3};
d60fe037 55const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
56const Int_t AliTRDrawStream::fgkNlinks = 12;
57const Int_t AliTRDrawStream::fgkNstacks = 5;
58const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
59const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
60
92305359 61const char* AliTRDrawStream::fgkErrorMessages[] = {
d60fe037 62 "Unknown error",
63 "Link monitor active",
64 "Pretrigger counter mismatch",
65 "not a TRD equipment (1024-1041)",
66 "Invalid Stack header",
67 "Invalid detector number",
68 "No digits could be retrieved from the digitsmanager",
69 "HC header mismatch",
70 "HC check bits wrong",
71 "Unexpected position in readout stream",
72 "Invalid testpattern mode",
73 "Testpattern mismatch",
74 "Number of timebins changed",
75 "ADC mask inconsistent",
76 "ADC check bits invalid",
77 "Missing ADC data",
78 "Missing expected ADC channels",
79 "Missing MCM headers"
80};
81
92305359 82Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
92223bf6 83 0,
84 0,
85 2,
86 1,
87 0,
88 1,
89 1,
90 1,
91 1,
92 2,
93 1,
94 1,
95 1,
96 1,
97 2,
98 1,
99 1,
100 1
101};
102
103AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
104 AliTRDrawStream::kTolerate,
105 AliTRDrawStream::kDiscardHC,
106 AliTRDrawStream::kTolerate,
107 AliTRDrawStream::kAbort,
108 AliTRDrawStream::kAbort,
109 AliTRDrawStream::kAbort,
110 AliTRDrawStream::kAbort,
111 AliTRDrawStream::kDiscardHC,
112 AliTRDrawStream::kDiscardHC,
113 AliTRDrawStream::kTolerate,
114 AliTRDrawStream::kTolerate,
115 AliTRDrawStream::kTolerate,
116 AliTRDrawStream::kTolerate,
117 AliTRDrawStream::kTolerate,
118 AliTRDrawStream::kTolerate,
119 AliTRDrawStream::kTolerate,
120 AliTRDrawStream::kTolerate,
121 AliTRDrawStream::kTolerate
122};
123
d60fe037 124AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
cc26f39c 125 fStats(),
f0a345a7 126 fStoreError(&AliTRDrawStream::ForgetError),
d60fe037 127 fRawReader(rawReader),
128 fDigitsManager(0x0),
129 fDigitsParam(0x0),
130 fErrors(0x0),
131 fLastError(),
92223bf6 132 fErrorFlags(0),
d60fe037 133 fPayloadStart(0x0),
134 fPayloadCurr(0x0),
135 fPayloadSize(0),
136 fNtimebins(-1),
137 fLastEvId(-1),
138 fCurrSlot(-1),
139 fCurrLink(-1),
140 fCurrRobPos(-1),
141 fCurrMcmPos(-1),
142 fCurrEquipmentId(0),
143 fCurrSmuIndexHeaderSize(0),
144 fCurrSmuIndexHeaderVersion(0),
145 fCurrTrackEnable(0),
146 fCurrTrackletEnable(0),
147 fCurrStackMask(0),
148 fCurrStackIndexWord(0x0),
149 fCurrStackHeaderSize(0x0),
150 fCurrStackHeaderVersion(0x0),
151 fCurrLinkMask(0x0),
152 fCurrCleanCheckout(0x0),
153 fCurrBoardId(0x0),
154 fCurrHwRev(0x0),
155 fCurrLinkMonitorFlags(0x0),
156 fCurrLinkDataTypeFlags(0x0),
157 fCurrLinkDebugFlags(0x0),
158 fCurrSpecial(-1),
159 fCurrMajor(-1),
160 fCurrMinor(-1),
161 fCurrAddHcWords(-1),
162 fCurrSm(-1),
163 fCurrStack(-1),
164 fCurrLayer(-1),
165 fCurrSide(-1),
166 fCurrHC(-1),
167 fCurrCheck(-1),
168 fCurrNtimebins(-1),
169 fCurrBC(-1),
170 fCurrPtrgCnt(-1),
171 fCurrPtrgPhase(-1),
cc26f39c 172 fNDumpMCMs(0),
d60fe037 173 fTrackletArray(0x0),
174 fAdcArray(0x0),
175 fSignalIndex(0x0),
5fdfc9e4 176 fTrackletTree(0x0),
177 fTracklets(0x0),
178 fTracks(0x0),
179 fMarkers(0x0)
d60fe037 180{
181 // default constructor
182
183 fCurrStackIndexWord = new UInt_t[fgkNstacks];
184 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
185 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
186 fCurrLinkMask = new UInt_t[fgkNstacks];
187 fCurrCleanCheckout = new UInt_t[fgkNstacks];
188 fCurrBoardId = new UInt_t[fgkNstacks];
189 fCurrHwRev = new UInt_t[fgkNstacks];
190 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
191 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
192 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
5fdfc9e4 193 for (Int_t i = 0; i < 100; i++)
194 fDumpMCM[i] = 0;
d60fe037 195
196 // preparing TClonesArray
197 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
198
199 // setting up the error tree
200 fErrors = new TTree("errorStats", "Error statistics");
201 fErrors->SetDirectory(0x0);
5fdfc9e4 202 fErrors->Branch("error", &fLastError);
d60fe037 203 fErrors->SetCircular(1000);
2f9bdd85 204 for (Int_t i = 0; i < 100; i++) {
205 fErrorBuffer[i] = 0;
206 }
207
d60fe037 208}
209
210AliTRDrawStream::~AliTRDrawStream()
211{
212 // destructor
213
214 delete fErrors;
215
216 delete [] fCurrStackIndexWord;
217 delete [] fCurrStackHeaderSize;
218 delete [] fCurrStackHeaderVersion;
219 delete [] fCurrLinkMask;
220 delete [] fCurrCleanCheckout;
221 delete [] fCurrBoardId;
222 delete [] fCurrHwRev;
223 delete [] fCurrLinkMonitorFlags;
224 delete [] fCurrLinkDataTypeFlags;
225 delete [] fCurrLinkDebugFlags;
226}
227
228Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
229{
230 // read the current event from the raw reader and fill it to the digits manager
231
232 if (!fRawReader) {
233 AliError("No raw reader available");
234 return kFALSE;
235 }
236
237 // tracklet output
67271412 238 ConnectTracklets(trackletTree);
d60fe037 239
240 // some preparations
241 fDigitsParam = 0x0;
242
243 // loop over all DDLs
244 // data starts with GTU payload, i.e. SMU index word
245 UChar_t *buffer = 0x0;
246
247 while (fRawReader->ReadNextData(buffer)) {
248
249 fCurrEquipmentId = fRawReader->GetEquipmentId();
250 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
251
252 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
92223bf6 253 EquipmentError(kNonTrdEq, "Skipping");
d60fe037 254 continue;
255 }
256
257 // setting the pointer to data and current reading position
258 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
259 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
cc26f39c 260 fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
d60fe037 261 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
262
263 // read SMU index header
264 if (ReadSmHeader() < 0) {
265 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
266 continue;
267 }
268
269 // read stack index header
270 for (Int_t iStack = 0; iStack < 5; iStack++) {
67271412 271 if ((fCurrStackMask & (1 << iStack)) != 0)
d60fe037 272 ReadStackIndexHeader(iStack);
273 }
274
275 for (Int_t iStack = 0; iStack < 5; iStack++) {
276 fCurrSlot = iStack;
67271412 277 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
d60fe037 278 continue;
279
280 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
281 for (Int_t iLink = 0; iLink < 12; iLink++) {
282 fCurrLink = iLink;
9e07aeda 283 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + iLink;
d60fe037 284 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
285 continue;
286
92223bf6 287 fErrorFlags = 0;
288 // check for link monitor error flag
d60fe037 289 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
290 LinkError(kLinkMonitor);
d60fe037 291
292 // read the data from one HC
293 ReadLinkData();
294
295 // read all data endmarkers
92223bf6 296 SeekNextLink();
d60fe037 297 }
298 }
299 }
300 return kTRUE;
301}
302
303
304Bool_t AliTRDrawStream::NextDDL()
305{
0508ca31 306 // continue reading with the next equipment
307
d60fe037 308 if (!fRawReader)
309 return kFALSE;
310
311 fCurrEquipmentId = 0;
312 fCurrSlot = 0;
313 fCurrLink = 0;
314
315 UChar_t *buffer = 0x0;
316
317 while (fRawReader->ReadNextData(buffer)) {
318
319 fCurrEquipmentId = fRawReader->GetEquipmentId();
320 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
321
322 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
92223bf6 323 EquipmentError(kNonTrdEq, "Skipping");
d60fe037 324 continue;
325 }
326
327 // setting the pointer to data and current reading position
328 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
329 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
330 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
331
332 // read SMU index header
333 if (ReadSmHeader() < 0) {
334 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
335 continue;
336 }
337
338 // read stack index header
339 for (Int_t iStack = 0; iStack < 5; iStack++) {
67271412 340 if ((fCurrStackMask & (1 << iStack)) != 0) {
d60fe037 341 ReadStackIndexHeader(iStack);
342 }
343 }
344 return kTRUE;
345 }
346
347 return kFALSE;
348}
349
350
351Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
352{
0508ca31 353 // read the data for the next chamber
354 // in case you only want to read the data of a single chamber
355 // to read all data ReadEvent(...) is recommended
356
d60fe037 357 fDigitsManager = digMgr;
358 fDigitsParam = 0x0;
359
92223bf6 360 fErrorFlags = 0;
361
d60fe037 362 // tracklet output preparation
67271412 363 TTree *trklTree = 0x0;
364 AliRunLoader *rl = AliRunLoader::Instance();
44ac5cbf 365 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
366 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
367 if (trklLoader) {
cc26f39c 368 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
369 if (trklTreeLoader)
370 trklTree = trklTreeLoader->Tree();
371 else
372 trklTree = trklLoader->Tree();
67271412 373 }
374
375 if (fTrackletTree != trklTree)
376 ConnectTracklets(trklTree);
d60fe037 377
378 if (!fRawReader) {
379 AliError("No raw reader available");
380 return -1;
381 }
382
9e07aeda 383 while (fCurrSlot < 0 || fCurrSlot >= 5) {
d60fe037 384 if (!NextDDL()) {
385 fCurrSlot = -1;
386 return -1;
387 }
9e07aeda 388 while ((fCurrSlot < 5) &&
389 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
390 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
391 fCurrLink++;
392 if (fCurrLink > 11) {
393 fCurrLink = 0;
394 fCurrSlot++;
395 }
396 }
d60fe037 397 }
398
399 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
400 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
401
402 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
403 LinkError(kLinkMonitor);
404
405 // read the data from one HC
406 ReadLinkData();
407
408 // read all data endmarkers
92223bf6 409 SeekNextLink();
d60fe037 410
411 if (fCurrLink % 2 == 0) {
412 // if we just read the A-side HC then also check the B-side
413 fCurrLink++;
1e7466b5 414 fCurrHC++;
d60fe037 415 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
416 ReadLinkData();
92223bf6 417 SeekNextLink();
d60fe037 418 }
419 }
420
421 //??? to check
422 do {
423 fCurrLink++;
424 if (fCurrLink > 11) {
425 fCurrLink = 0;
426 fCurrSlot++;
427 }
428 } while ((fCurrSlot < 5) &&
67271412 429 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
430 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
d60fe037 431
25671e69 432 // return chamber information from HC if it is valid
433 // otherwise return information from link position
434 if (fCurrSm < 0 || fCurrSm > 17 || fCurrStack < 0 || fCurrStack > 4 || fCurrLayer < 0 || fCurrLayer > 5)
435 return ((fCurrEquipmentId-1024) + fCurrSlot * 6 + fCurrLink/2);
436 else
437 return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
d60fe037 438}
439
440
441Int_t AliTRDrawStream::ReadSmHeader()
442{
443 // read the SMU index header at the current reading position
444 // and store the information in the corresponding variables
445
446 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
92223bf6 447 EquipmentError(kUnknown, "SM Header incomplete");
d60fe037 448 return -1;
449 }
450
451 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
452 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
5fdfc9e4 453 // fCurrSmuIndexHeaderTrgAvail = ((*fPayloadCurr) >> 9) & 0x1;
454 // fCurrSmuIndexHeaderEvType = ((*fPayloadCurr) >> 7) & 0x3;
d60fe037 455 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
456 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
457 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
458
459 AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
460 fCurrSmuIndexHeaderSize,
461 fCurrSmuIndexHeaderVersion,
462 fCurrTrackEnable,
463 fCurrTrackletEnable,
464 fCurrStackMask));
5fdfc9e4 465
466 // decode GTU track words
8d8be166 467 UInt_t trackWord[2] = { 0, 0 };
5fdfc9e4 468 Int_t stack = 0;
469 Int_t idx = 0;
470 for (UInt_t iWord = 4; iWord < fCurrSmuIndexHeaderSize; iWord++) {
471 if (fPayloadCurr[iWord] == 0x10000000) {
472 stack++;
473 idx = 0;
474 }
475 else {
476 if ((idx == 0) &&
477 ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
478 AliDebug(1,Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
479 continue;
480 }
481 else if ((idx & 0x1)==0x1) {
482 trackWord[idx&0x1] = fPayloadCurr[iWord];
483 AliDebug(1,Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
484// if (fTracks)
485// new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-1024);
486 }
487 else {
488 trackWord[idx&0x1] = fPayloadCurr[iWord];
489 }
490 idx++;
491 }
492 }
493
d60fe037 494 fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
495
496 return fCurrSmuIndexHeaderSize + 1;
497}
498
499Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
500{
501 // read the stack index header
502 // and store the information in the corresponding variables
503
504 fCurrStackIndexWord[stack] = *fPayloadCurr;
505 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
506 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
507 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
508
67271412 509 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
92223bf6 510 StackError(kStackHeaderInvalid, "Stack index header aborted");
d60fe037 511 return -1;
512 }
513
514 switch (fCurrStackHeaderVersion[stack]) {
515 case 0xa:
516 if (fCurrStackHeaderSize[stack] < 8) {
92223bf6 517 StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
d60fe037 518 return -1;
519 }
520
521 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
522 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
523 fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
524
525 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
526 // A side
527 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
528 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
529 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
530 // B side
531 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
532 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
533 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
534 }
535 break;
536
537 default:
92223bf6 538 StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
d60fe037 539 }
540
541 fPayloadCurr += fCurrStackHeaderSize[stack];
542
543 return fCurrStackHeaderSize[stack];
544}
545
546Int_t AliTRDrawStream::ReadLinkData()
547{
548 // read the data in one link (one HC) until the data endmarker is reached
cc26f39c 549 // returns the number of words read!
d60fe037 550
551 Int_t count = 0;
cc26f39c 552 UInt_t* startPosLink = fPayloadCurr;
553
554// printf("----- HC: %i -----\n", fCurrHC);
555// for (Int_t i = 0; i < 3; i++) {
556// printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
557// fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
558// }
d60fe037 559
5fdfc9e4 560 if (fMarkers)
561 new ((*fMarkers)[fMarkers->GetEntriesFast()])
562 AliTRDrawStreamError(-kHCactive, fCurrSm, fCurrStack, fCurrLink);
563
92223bf6 564 if (fErrorFlags & kDiscardHC)
565 return count;
566
d60fe037 567 count += ReadTracklets();
92223bf6 568 if (fErrorFlags & kDiscardHC)
569 return count;
d60fe037 570
571 count += ReadHcHeader();
92223bf6 572 if (fErrorFlags & kDiscardHC)
573 return count;
d60fe037 574
575 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
576
577 if (det > -1 && det < 540) {
578
579 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
580 //fAdcArray->Expand();
581 if (fAdcArray->GetNtime() != fCurrNtimebins)
582 fAdcArray->Allocate(16, 144, fCurrNtimebins);
583 }
584 else {
92223bf6 585 LinkError(kNoDigits);
d60fe037 586 }
587
588 if (!fDigitsParam) {
589 fDigitsParam = fDigitsManager->GetDigitsParam();
590 }
591 if (fDigitsParam) {
592 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
593 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
594 fDigitsParam->SetADCbaseline(det, 10);
595 }
596
597 if (fDigitsManager->UsesDictionaries()) {
598 fDigitsManager->GetDictionary(det, 0)->Reset();
599 fDigitsManager->GetDictionary(det, 1)->Reset();
600 fDigitsManager->GetDictionary(det, 2)->Reset();
601 }
602
603 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
604 fSignalIndex->SetSM(fCurrSm);
605 fSignalIndex->SetStack(fCurrStack);
606 fSignalIndex->SetLayer(fCurrLayer);
607 fSignalIndex->SetDetNumber(det);
608 if (!fSignalIndex->IsAllocated())
609 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
610 }
611
612 // ----- check which kind of data -----
613 if (fCurrMajor & 0x40) {
614 if ((fCurrMajor & 0x7) == 0x7) {
615 AliDebug(1, "This is a config event");
616 UInt_t *startPos = fPayloadCurr;
617 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
618 *fPayloadCurr != fgkDataEndmarker)
619 fPayloadCurr++;
620 count += fPayloadCurr - startPos;
621
622 // feeding TRAP config
623 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
0508ca31 624 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
d60fe037 625 }
626 else {
627 Int_t tpmode = fCurrMajor & 0x7;
628 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
629 ReadTPData(tpmode);
630 }
631 }
632 else if (fCurrMajor & 0x20) {
633 AliDebug(1, "This is a zs event");
634 count += ReadZSData();
635 }
636 else {
637 AliDebug(1, "This is a nozs event");
638 count += ReadNonZSData();
639 }
640 }
641 else {
92223bf6 642 LinkError(kInvalidDetector, "%i", det);
d60fe037 643 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
644 *fPayloadCurr != fgkDataEndmarker)
645 fPayloadCurr++;
d60fe037 646 }
637666cd 647
648 if (fCurrSm > -1 && fCurrSm < 18) {
649 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
650 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
651 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
652 fStats.fBytesRead += count * sizeof(UInt_t);
653 }
cc26f39c 654
d60fe037 655 return count;
656}
657
658Int_t AliTRDrawStream::ReadTracklets()
659{
660 // read the tracklets from one HC
661
662 fTrackletArray->Clear();
663
664 UInt_t *start = fPayloadCurr;
665 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
666 fPayloadCurr - fPayloadStart < fPayloadSize) {
667
5fdfc9e4 668 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
d60fe037 669
670 fPayloadCurr++;
671 }
672
673 if (fTrackletArray->GetEntriesFast() > 0) {
674 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
9e07aeda 675 (fCurrEquipmentId-1024), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
5fdfc9e4 676 if (fCurrSm > -1 && fCurrSm < 18) {
677 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
678 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
679 }
d60fe037 680 if (fTrackletTree)
681 fTrackletTree->Fill();
5fdfc9e4 682 if (fTracklets)
683 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
684 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
685 }
d60fe037 686 }
687
688 // loop over remaining tracklet endmarkers
689 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
690 fPayloadCurr - fPayloadStart < fPayloadSize))
691 fPayloadCurr++;
692
cc26f39c 693 return fPayloadCurr - start;
d60fe037 694}
695
696Int_t AliTRDrawStream::ReadHcHeader()
697{
698 // read and parse the HC header of one HC
699 // and store the information in the corresponding variables
700
701 UInt_t *start = fPayloadCurr;
702 // check not to be at the data endmarker
703 if (*fPayloadCurr == fgkDataEndmarker)
704 return 0;
705
706 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
707 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
708 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
709 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
710 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
711 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
712 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
713 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
714 fCurrCheck = (*fPayloadCurr) & 0x3;
715
0508ca31 716 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
d60fe037 717 fCurrStack != fCurrSlot ||
718 fCurrLayer != fCurrLink / 2 ||
719 fCurrSide != fCurrLink % 2) {
92223bf6 720 LinkError(kHCmismatch,
721 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
722 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
723 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);;
d60fe037 724 }
725 if (fCurrCheck != 0x1) {
92223bf6 726 LinkError(kHCcheckFailed);
d60fe037 727 }
728
729 if (fCurrAddHcWords > 0) {
730 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
731 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
732 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
733 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
734 }
735
736 fPayloadCurr += 1 + fCurrAddHcWords;
737
5fdfc9e4 738 return (fPayloadCurr - start);
d60fe037 739}
740
741Int_t AliTRDrawStream::ReadTPData(Int_t mode)
742{
743 // testing of testpattern 1 to 3 (hardcoded), 0 missing
744 // evcnt checking missing
745 Int_t cpu = 0;
746 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
747 Int_t evcnt = 0;
748 Int_t count = 0;
749 Int_t mcmcount = -1;
750 Int_t wordcount = 0;
751 Int_t channelcount = 0;
752 UInt_t expword = 0;
753 UInt_t expadcval = 0;
754 UInt_t diff = 0;
755 Int_t lastmcmpos = -1;
756 Int_t lastrobpos = -1;
757
758 UInt_t* start = fPayloadCurr;
759
760 while (*(fPayloadCurr) != fgkDataEndmarker &&
761 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
762
763 // ----- Checking MCM Header -----
764 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
765 mcmcount++;
766
767 // ----- checking for proper readout order - ROB -----
768 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
769 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
770 }
771 else {
92223bf6 772 ROBError(kPosUnexp);
d60fe037 773 }
774 fCurrRobPos = ROB(*fPayloadCurr);
775
776 // ----- checking for proper readout order - MCM -----
777 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
778 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
779 }
780 else {
92223bf6 781 MCMError(kPosUnexp);
d60fe037 782 }
783 fCurrMcmPos = MCM(*fPayloadCurr);
784
785
786 fPayloadCurr++;
787
788 evcnt = 0x3f & *fPayloadCurr >> 26;
789 cpu = -1;
790 channelcount = 0;
791 while (channelcount < 21) {
792 count = 0;
793 if (cpu != cpufromchannel[channelcount]) {
794 cpu = cpufromchannel[channelcount];
795 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
796 wordcount = 0;
797 }
798
799 while (count < 10) {
800 if (channelcount % 2 == 0)
801 expword = 0x3;
802 else
803 expword = 0x2;
804
805 if (mode == 1) {
806 // ----- TP 1 -----
807 expword |= expadcval << 2;
808 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
809 expword |= expadcval << 12;
810 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
811 expword |= expadcval << 22;
812 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
813 }
814 else if (mode == 2) {
815 // ----- TP 2 ------
816 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
817 ((fCurrStack + 1) << 15) |
818 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
819 }
820 else if (mode == 3) {
821 // ----- TP 3 -----
822 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
823 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
824 }
825 else {
826 expword = 0;
92223bf6 827 LinkError(kTPmodeInvalid, "Just reading");
d60fe037 828 }
829
830 diff = *fPayloadCurr ^ expword;
831 if (diff != 0) {
92223bf6 832 MCMError(kTPmismatch,
833 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
834 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
d60fe037 835 }
836 fPayloadCurr++;
837 count++;
838 wordcount++;
839 }
840 channelcount++;
841 }
842 // continue with next MCM
843 }
844 return fPayloadCurr - start;
845}
846
847
848Int_t AliTRDrawStream::ReadZSData()
849{
850 // read the zs data from one link from the current reading position
851
852 UInt_t *start = fPayloadCurr;
853
854 Int_t mcmcount = 0;
0508ca31 855 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 856 Int_t channelcount = 0;
0508ca31 857 Int_t channelcountExp = 0;
858 Int_t channelcountMax = 0;
d60fe037 859 Int_t timebins;
860 Int_t currentTimebin = 0;
861 Int_t adcwc = 0;
862 Int_t evno = -1;
863 Int_t lastmcmpos = -1;
864 Int_t lastrobpos = -1;
865
866 if (fCurrNtimebins != fNtimebins) {
867 if (fNtimebins > 0)
92223bf6 868 LinkError(kNtimebinsChanged,
869 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 870 fNtimebins = fCurrNtimebins;
871 }
872
873 timebins = fNtimebins;
874
875 while (*(fPayloadCurr) != fgkDataEndmarker &&
876 fPayloadCurr - fPayloadStart < fPayloadSize) {
877
878 // ----- Checking MCM Header -----
879 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
cc26f39c 880 UInt_t *startPosMCM = fPayloadCurr;
d60fe037 881
882 // ----- checking for proper readout order - ROB -----
883 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
884 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
885 }
886 else {
92223bf6 887 ROBError(kPosUnexp);
d60fe037 888 }
889 fCurrRobPos = ROB(*fPayloadCurr);
890
891 // ----- checking for proper readout order - MCM -----
892 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
893 lastmcmpos = GetMCMReadoutPos(lastmcmpos);
894 }
895 else {
92223bf6 896 MCMError(kPosUnexp);
d60fe037 897 }
898 fCurrMcmPos = MCM(*fPayloadCurr);
899
900 if (EvNo(*fPayloadCurr) != evno) {
901 if (evno == -1)
902 evno = EvNo(*fPayloadCurr);
903 else {
92223bf6 904 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
d60fe037 905 }
906 }
907 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
908 Int_t padcoloff = PadColOffset(*fPayloadCurr);
909 Int_t row = Row(*fPayloadCurr);
910 fPayloadCurr++;
911
912 // ----- Reading ADC channels -----
913 AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
914
915 // ----- analysing the ADC mask -----
916 channelcount = 0;
0508ca31 917 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
918 channelcountMax = GetNActiveChannels(*fPayloadCurr);
d60fe037 919 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
920 Int_t channelno = -1;
921 fPayloadCurr++;
922
0508ca31 923 if (channelcountExp != channelcountMax) {
924 if (channelcountExp > channelcountMax) {
925 Int_t temp = channelcountExp;
926 channelcountExp = channelcountMax;
927 channelcountMax = temp;
d60fe037 928 }
0508ca31 929 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
930 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
92223bf6 931 MCMError(kAdcMaskInconsistent,
932 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
933 *(fPayloadCurr + 10 * channelcountExp),
934 *(fPayloadCurr + 10 * channelcountExp + 1) );
0508ca31 935 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
936 channelcountExp++;
d60fe037 937 else {
938 break;
939 }
940 }
92223bf6 941 MCMError(kAdcMaskInconsistent,
942 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
943 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
d60fe037 944 }
0508ca31 945 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
d60fe037 946
947 // ----- reading marked ADC channels -----
0508ca31 948 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 949 if (channelno < 20)
d60fe037 950 channelno++;
e29e514c 951 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
d60fe037 952 channelno++;
953
954 if (fCurrNtimebins > 30) {
955 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
956 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
957 }
958 else {
959 currentTimebin = 0;
960 }
961
962 adcwc = 0;
963 AliDebug(2, Form("Now looking %i words", timebins / 3));
964 Int_t adccol = adccoloff - channelno;
965 Int_t padcol = padcoloff - channelno;
cc26f39c 966// if (adccol < 3 || adccol > 165)
967// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
968// channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
969
d60fe037 970 while (adcwc < timebins / 3 &&
971 *(fPayloadCurr) != fgkDataEndmarker &&
972 fPayloadCurr - fPayloadStart < fPayloadSize) {
973 int check = 0x3 & *fPayloadCurr;
974 if (channelno % 2 != 0) { // odd channel
975 if (check != 0x2 && channelno < 21) {
92223bf6 976 MCMError(kAdcCheckInvalid,
977 "%i for %2i. ADC word in odd channel %i",
978 check, adcwc+1, channelno);
d60fe037 979 }
980 }
981 else { // even channel
982 if (check != 0x3 && channelno < 21) {
92223bf6 983 MCMError(kAdcCheckInvalid,
984 "%i for %2i. ADC word in even channel %i",
985 check, adcwc+1, channelno);
d60fe037 986 }
987 }
988
989 // filling the actual timebin data
990 int tb2 = 0x3ff & *fPayloadCurr >> 22;
991 int tb1 = 0x3ff & *fPayloadCurr >> 12;
992 int tb0 = 0x3ff & *fPayloadCurr >> 2;
993 if (adcwc != 0 || fCurrNtimebins <= 30)
994 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
995 else
996 tb0 = -1;
997 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
998 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
999
1000 adcwc++;
1001 fPayloadCurr++;
1002 }
1003
1004 if (adcwc != timebins / 3)
92223bf6 1005 MCMError(kAdcDataAbort);
d60fe037 1006
1007 // adding index
1008 if (padcol > 0 && padcol < 144) {
1009 fSignalIndex->AddIndexRC(row, padcol);
1010 }
1011
1012 channelcount++;
1013 }
cc26f39c 1014
637666cd 1015 if (fCurrSm > -1 && fCurrSm < 18) {
1016 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1017 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1018 }
0508ca31 1019 if (channelcount != channelcountExp)
92223bf6 1020 MCMError(kAdcChannelsMiss);
d60fe037 1021
1022 mcmcount++;
637666cd 1023 if (fCurrSm > -1 && fCurrSm < 18) {
1024 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1025 fStats.fStatsSector[fCurrSm].fNMCMs++;
1026 }
cc26f39c 1027
1028 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
92223bf6 1029 DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
cc26f39c 1030 startPosMCM, fPayloadCurr - startPosMCM);
1031 }
1032
d60fe037 1033 // continue with next MCM
1034 }
1035
1036 // check for missing MCMs (if header suppression is inactive)
67271412 1037 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
92223bf6 1038 LinkError(kMissMcmHeaders,
1039 "No. of MCM headers %i not as expected: %i",
1040 mcmcount, mcmcountExp);
d60fe037 1041 }
1042
1043 return (fPayloadCurr - start);
1044}
1045
1046Int_t AliTRDrawStream::ReadNonZSData()
1047{
1048 // read the non-zs data from one link from the current reading position
1049
1050 UInt_t *start = fPayloadCurr;
1051
1052 Int_t mcmcount = 0;
0508ca31 1053 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 1054 Int_t channelcount = 0;
0508ca31 1055 Int_t channelcountExp = 0;
d60fe037 1056 Int_t timebins;
1057 Int_t currentTimebin = 0;
1058 Int_t adcwc = 0;
1059 Int_t evno = -1;
1060 Int_t lastmcmpos = -1;
1061 Int_t lastrobpos = -1;
1062
1063 if (fCurrNtimebins != fNtimebins) {
1064 if (fNtimebins > 0)
92223bf6 1065 LinkError(kNtimebinsChanged,
1066 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
d60fe037 1067 fNtimebins = fCurrNtimebins;
1068 }
1069
1070 timebins = fNtimebins;
1071
1072 while (*(fPayloadCurr) != fgkDataEndmarker &&
1073 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1074
1075 // ----- Checking MCM Header -----
1076 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1077
1078 // ----- checking for proper readout order - ROB -----
1079 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1080 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1081 }
1082 else {
92223bf6 1083 ROBError(kPosUnexp);
d60fe037 1084 }
1085 fCurrRobPos = ROB(*fPayloadCurr);
1086
1087 // ----- checking for proper readout order - MCM -----
1088 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1089 lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
1090 }
1091 else {
92223bf6 1092 MCMError(kPosUnexp);
d60fe037 1093 }
1094 fCurrMcmPos = MCM(*fPayloadCurr);
1095
1096 if (EvNo(*fPayloadCurr) != evno) {
1097 if (evno == -1)
1098 evno = EvNo(*fPayloadCurr);
1099 else {
92223bf6 1100 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
d60fe037 1101 }
1102 }
1103
1104 channelcount = 0;
0508ca31 1105 channelcountExp = 21;
d60fe037 1106 int channelno = -1;
1107
1108 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1109 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1110 Int_t row = Row(*fPayloadCurr);
1111
1112 fPayloadCurr++;
1113
1114 // ----- reading marked ADC channels -----
0508ca31 1115 while (channelcount < channelcountExp &&
d60fe037 1116 *(fPayloadCurr) != fgkDataEndmarker) {
e29e514c 1117 if (channelno < 20)
d60fe037 1118 channelno++;
1119
1120 currentTimebin = 0;
1121
1122 adcwc = 0;
1123 AliDebug(2, Form("Now looking %i words", timebins / 3));
1124 Int_t adccol = adccoloff - channelno;
1125 Int_t padcol = padcoloff - channelno;
1126 while (adcwc < timebins / 3 &&
1127 *(fPayloadCurr) != fgkDataEndmarker &&
1128 fPayloadCurr - fPayloadStart < fPayloadSize) {
1129 int check = 0x3 & *fPayloadCurr;
1130 if (channelno % 2 != 0) { // odd channel
1131 if (check != 0x2 && channelno < 21) {
92223bf6 1132 MCMError(kAdcCheckInvalid,
1133 "%i for %2i. ADC word in odd channel %i",
1134 check, adcwc+1, channelno);
d60fe037 1135 }
1136 }
1137 else { // even channel
1138 if (check != 0x3 && channelno < 21) {
92223bf6 1139 MCMError(kAdcCheckInvalid,
1140 "%i for %2i. ADC word in even channel %i",
1141 check, adcwc+1, channelno);
d60fe037 1142 }
1143 }
1144
1145 // filling the actual timebin data
1146 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1147 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1148 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1149 if (adcwc != 0 || fCurrNtimebins <= 30)
1150 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1151 else
1152 tb0 = -1;
1153 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1154 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1155
1156 adcwc++;
1157 fPayloadCurr++;
1158 }
1159
1160 if (adcwc != timebins / 3)
92223bf6 1161 MCMError(kAdcDataAbort);
d60fe037 1162
1163 // adding index
1164 if (padcol > 0 && padcol < 144) {
1165 fSignalIndex->AddIndexRC(row, padcol);
1166 }
1167
1168 channelcount++;
1169 }
1170
0508ca31 1171 if (channelcount != channelcountExp)
92223bf6 1172 MCMError(kAdcChannelsMiss);
d60fe037 1173 mcmcount++;
1174 // continue with next MCM
1175 }
1176
1177 // check for missing MCMs (if header suppression is inactive)
0508ca31 1178 if (mcmcount != mcmcountExp) {
92223bf6 1179 LinkError(kMissMcmHeaders,
1180 "%i not as expected: %i", mcmcount, mcmcountExp);
d60fe037 1181 }
1182
1183 return (fPayloadCurr - start);
1184}
1185
92223bf6 1186Int_t AliTRDrawStream::SeekNextLink()
1187{
92305359 1188 // proceed in raw data stream till the next link
1189
92223bf6 1190 UInt_t *start = fPayloadCurr;
1191
1192 // read until data endmarkers
1193 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1194 *fPayloadCurr != fgkDataEndmarker)
1195 fPayloadCurr++;
1196
1197 // read all data endmarkers
1198 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1199 *fPayloadCurr == fgkDataEndmarker)
1200 fPayloadCurr++;
1201
1202 return (fPayloadCurr - start);
1203}
1204
67271412 1205Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1206{
92305359 1207 // connect the tracklet tree used to store the tracklet output
1208
67271412 1209 fTrackletTree = trklTree;
1210 if (!fTrackletTree)
1211 return kTRUE;
1212
cc26f39c 1213 if (!fTrackletTree->GetBranch("hc"))
67271412 1214 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
cc26f39c 1215 else
67271412 1216 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
cc26f39c 1217
1218 if (!fTrackletTree->GetBranch("trkl"))
1219 fTrackletTree->Branch("trkl", &fTrackletArray);
1220 else
67271412 1221 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
cc26f39c 1222
67271412 1223 return kTRUE;
1224}
1225
1226
1d62be37 1227void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
d60fe037 1228{
0508ca31 1229 // register error according to error code on equipment level
1230 // and return the corresponding error message
1231
d60fe037 1232 fLastError.fSector = fCurrEquipmentId - 1024;
1233 fLastError.fStack = -1;
1234 fLastError.fLink = -1;
1235 fLastError.fRob = -1;
1236 fLastError.fMcm = -1;
1237 fLastError.fError = err;
f4b3235e 1238 (this->*fStoreError)();
d60fe037 1239
92223bf6 1240 va_list ap;
1241 if (fgErrorDebugLevel[err] > 10)
1242 AliDebug(fgErrorDebugLevel[err],
1243 Form("Event %6i: Eq. %2d - %s : %s",
92305359 1244 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 1245 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1246 else
1247 AliError(Form("Event %6i: Eq. %2d - %s : %s",
92305359 1248 fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
1d62be37 1249 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1250 fErrorFlags |= fgErrorBehav[err];
d60fe037 1251}
1252
1253
1d62be37 1254void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
d60fe037 1255{
0508ca31 1256 // register error according to error code on stack level
1257 // and return the corresponding error message
1258
d60fe037 1259 fLastError.fSector = fCurrEquipmentId - 1024;
1260 fLastError.fStack = fCurrSlot;
1261 fLastError.fLink = -1;
1262 fLastError.fRob = -1;
1263 fLastError.fMcm = -1;
1264 fLastError.fError = err;
f4b3235e 1265 (this->*fStoreError)();
d60fe037 1266
92223bf6 1267 va_list ap;
e29e514c 1268 if (fgErrorDebugLevel[err] > 0)
92223bf6 1269 AliDebug(fgErrorDebugLevel[err],
1270 Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 1271 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 1272 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1273 else
1274 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
92305359 1275 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
1d62be37 1276 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1277 fErrorFlags |= fgErrorBehav[err];
d60fe037 1278}
1279
1280
1d62be37 1281void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
d60fe037 1282{
0508ca31 1283 // register error according to error code on link level
1284 // and return the corresponding error message
1285
d60fe037 1286 fLastError.fSector = fCurrEquipmentId - 1024;
1287 fLastError.fStack = fCurrSlot;
1288 fLastError.fLink = fCurrLink;
1289 fLastError.fRob = -1;
1290 fLastError.fMcm = -1;
1291 fLastError.fError = err;
f4b3235e 1292 (this->*fStoreError)();
d60fe037 1293
92223bf6 1294 va_list ap;
e29e514c 1295 if (fgErrorDebugLevel[err] > 0)
92223bf6 1296 AliDebug(fgErrorDebugLevel[err],
1297 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 1298 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 1299 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1300 else
1301 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
92305359 1302 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
1d62be37 1303 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1304 fErrorFlags |= fgErrorBehav[err];
d60fe037 1305}
1306
1307
1d62be37 1308void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
d60fe037 1309{
0508ca31 1310 // register error according to error code on ROB level
1311 // and return the corresponding error message
1312
d60fe037 1313 fLastError.fSector = fCurrEquipmentId - 1024;
1314 fLastError.fStack = fCurrSlot;
1315 fLastError.fLink = fCurrLink;
1316 fLastError.fRob = fCurrRobPos;
1317 fLastError.fMcm = -1;
1318 fLastError.fError = err;
f4b3235e 1319 (this->*fStoreError)();
d60fe037 1320
92223bf6 1321 va_list ap;
e29e514c 1322 if (fgErrorDebugLevel[err] > 0)
92223bf6 1323 AliDebug(fgErrorDebugLevel[err],
1324 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
92305359 1325 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 1326 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1327 else
1328 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
92305359 1329 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
1d62be37 1330 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1331 fErrorFlags |= fgErrorBehav[err];
d60fe037 1332}
1333
1334
1d62be37 1335void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
d60fe037 1336{
0508ca31 1337 // register error according to error code on MCM level
1338 // and return the corresponding error message
1339
d60fe037 1340 fLastError.fSector = fCurrEquipmentId - 1024;
1341 fLastError.fStack = fCurrSlot;
1342 fLastError.fLink = fCurrLink;
1343 fLastError.fRob = fCurrRobPos;
1344 fLastError.fMcm = fCurrMcmPos;
1345 fLastError.fError = err;
f4b3235e 1346 (this->*fStoreError)();
d60fe037 1347
92223bf6 1348 va_list ap;
e29e514c 1349 if (fgErrorDebugLevel[err] > 0)
92223bf6 1350 AliDebug(fgErrorDebugLevel[err],
1351 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
92305359 1352 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 1353 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1354 else
1355 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
92305359 1356 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
1d62be37 1357 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
92223bf6 1358 fErrorFlags |= fgErrorBehav[err];
d60fe037 1359}
1360
1361const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1362{
0508ca31 1363 // return the error message for the given error code
1364
d60fe037 1365 if (errCode > 0 && errCode < kLastErrorCode)
92305359 1366 return fgkErrorMessages[errCode];
d60fe037 1367 else
1368 return "";
1369}
cc26f39c 1370
1371void AliTRDrawStream::AliTRDrawStats::ClearStats()
1372{
1373 // clear statistics (includes clearing sector-wise statistics)
1374
1375 fBytesRead = 0;
1376 for (Int_t iSector = 0; iSector < 18; iSector++) {
1377 fStatsSector[iSector].ClearStats();
1378 }
1379
1380}
1381
1382void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1383{
1384 // clear statistics (includes clearing HC-wise statistics)
1385
1386 fBytes = 0;
1387 fBytesRead = 0;
1388 fNTracklets = 0;
1389 fNMCMs = 0;
1390 fNChannels = 0;
1391
1392 for (Int_t iHC = 0; iHC < 60; iHC++) {
1393 fStatsHC[iHC].ClearStats();
1394 }
1395}
1396
1397void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1398{
1399 // clear statistics
1400
1401 fBytes = 0;
1402 fBytesRead = 0;
1403 fNTracklets = 0;
1404 fNMCMs = 0;
1405 fNChannels = 0;
1406}
1407
1408void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1409{
1410 // mark MCM for dumping of raw data
1411
1412 if (dump) {
1413 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
1414 }
1415 else {
1416 Int_t iMCM;
1417 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1418 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1419 fNDumpMCMs--;
1420 break;
1421 }
1422 }
1423 for ( ; iMCM < fNDumpMCMs; iMCM++) {
1424 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1425 }
1426 }
1427}
1428
92305359 1429Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
cc26f39c 1430{
1431 // check if MCM data should be dumped
1432
1433 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1434 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1435 return kTRUE;
1436 }
1437 }
1438 return kFALSE;
1439}
1440
1441void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
1442{
1443 // dump raw data
1444
1445 title += "\n";
1446 Int_t pos = 0;
1447 for ( ; pos+3 < length; pos += 4) {
1448 title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n",
1449 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1450 }
1451 for ( ; pos < length; pos++) {
1452 title += Form("0x%08x ", start[pos]);
1453 }
1454 AliInfo(title);
1455}
f4b3235e 1456
1457AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
1458 fError(error),
1459 fSector(sector),
1460 fStack(stack),
1461 fLink(link),
1462 fRob(rob),
1463 fMcm(mcm)
1464{
1465 // ctor
1466
1467}