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