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