]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TRD/AliTRDrawStream.cxx
- add decoding of GTU tracks
[u/mrichter/AliRoot.git] / TRD / AliTRDrawStream.cxx
... / ...
CommitLineData
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
25#include <cstdio>
26#include <cstdarg>
27
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"
40#include "AliESDTrdTrack.h"
41#include "AliTreeLoader.h"
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,
52 8, 9, 10, 11,
53 4, 5, 6, 7,
54 0, 1, 2, 3};
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
61const char* AliTRDrawStream::fgErrorMessages[] = {
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
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
124AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
125 fStats(),
126 fStoreError(&AliTRDrawStream::StoreErrorTree),
127 fRawReader(rawReader),
128 fDigitsManager(0x0),
129 fDigitsParam(0x0),
130 fErrors(0x0),
131 fLastError(),
132 fErrorFlags(0),
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),
172 fNDumpMCMs(0),
173 fTrackletArray(0x0),
174 fAdcArray(0x0),
175 fSignalIndex(0x0),
176 fTrackletTree(0x0),
177 fTracklets(0x0),
178 fTracks(0x0),
179 fMarkers(0x0)
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];
193 for (Int_t i = 0; i < 100; i++)
194 fDumpMCM[i] = 0;
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);
202 fErrors->Branch("error", &fLastError);
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
234 ConnectTracklets(trackletTree);
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) {
249 EquipmentError(kNonTrdEq, "Skipping");
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);
256 fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
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++) {
267 if ((fCurrStackMask & (1 << iStack)) != 0)
268 ReadStackIndexHeader(iStack);
269 }
270
271 for (Int_t iStack = 0; iStack < 5; iStack++) {
272 fCurrSlot = iStack;
273 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
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
283 fErrorFlags = 0;
284 // check for link monitor error flag
285 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
286 LinkError(kLinkMonitor);
287
288 // read the data from one HC
289 ReadLinkData();
290
291 // read all data endmarkers
292 SeekNextLink();
293 }
294 }
295 }
296 return kTRUE;
297}
298
299
300Bool_t AliTRDrawStream::NextDDL()
301{
302 // continue reading with the next equipment
303
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) {
319 EquipmentError(kNonTrdEq, "Skipping");
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++) {
336 if ((fCurrStackMask & (1 << iStack)) != 0) {
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{
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
353 fDigitsManager = digMgr;
354 fDigitsParam = 0x0;
355
356 fErrorFlags = 0;
357
358 // tracklet output preparation
359 TTree *trklTree = 0x0;
360 AliRunLoader *rl = AliRunLoader::Instance();
361 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
362 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
363 if (trklLoader) {
364 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
365 if (trklTreeLoader)
366 trklTree = trklTreeLoader->Tree();
367 else
368 trklTree = trklLoader->Tree();
369 }
370
371 if (fTrackletTree != trklTree)
372 ConnectTracklets(trklTree);
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
396 SeekNextLink();
397
398 if (fCurrLink % 2 == 0) {
399 // if we just read the A-side HC then also check the B-side
400 fCurrLink++;
401 fCurrHC++;
402 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
403 ReadLinkData();
404 SeekNextLink();
405 }
406 }
407
408 //??? to check
409 do {
410 fCurrLink++;
411 if (fCurrLink > 11) {
412 fCurrLink = 0;
413 fCurrSlot++;
414 }
415 } while ((fCurrSlot < 5) &&
416 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
417 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
418
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);
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) {
434 EquipmentError(kUnknown, "SM Header incomplete");
435 return -1;
436 }
437
438 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
439 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
440 // fCurrSmuIndexHeaderTrgAvail = ((*fPayloadCurr) >> 9) & 0x1;
441 // fCurrSmuIndexHeaderEvType = ((*fPayloadCurr) >> 7) & 0x3;
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));
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
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
496 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
497 StackError(kStackHeaderInvalid, "Stack index header aborted");
498 return -1;
499 }
500
501 switch (fCurrStackHeaderVersion[stack]) {
502 case 0xa:
503 if (fCurrStackHeaderSize[stack] < 8) {
504 StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
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:
525 StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
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
536 // returns the number of words read!
537
538 Int_t count = 0;
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// }
546
547 if (fMarkers)
548 new ((*fMarkers)[fMarkers->GetEntriesFast()])
549 AliTRDrawStreamError(-kHCactive, fCurrSm, fCurrStack, fCurrLink);
550
551 if (fErrorFlags & kDiscardHC)
552 return count;
553
554 count += ReadTracklets();
555 if (fErrorFlags & kDiscardHC)
556 return count;
557
558 count += ReadHcHeader();
559 if (fErrorFlags & kDiscardHC)
560 return count;
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 {
572 LinkError(kNoDigits);
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();
611 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
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 {
629 LinkError(kInvalidDetector, "%i", det);
630 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
631 *fPayloadCurr != fgkDataEndmarker)
632 fPayloadCurr++;
633 }
634
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
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
653 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
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()));
661 if (fCurrSm > -1 && fCurrSm < 18) {
662 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
663 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
664 }
665 if (fTrackletTree)
666 fTrackletTree->Fill();
667 if (fTracklets)
668 for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
669 new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
670 }
671 }
672
673 // loop over remaining tracklet endmarkers
674 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
675 fPayloadCurr - fPayloadStart < fPayloadSize))
676 fPayloadCurr++;
677
678 return fPayloadCurr - start;
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
701 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
702 fCurrStack != fCurrSlot ||
703 fCurrLayer != fCurrLink / 2 ||
704 fCurrSide != fCurrLink % 2) {
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]);;
709 }
710 if (fCurrCheck != 0x1) {
711 LinkError(kHCcheckFailed);
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
723 return (fPayloadCurr - start);
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 {
757 ROBError(kPosUnexp);
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 {
766 MCMError(kPosUnexp);
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;
812 LinkError(kTPmodeInvalid, "Just reading");
813 }
814
815 diff = *fPayloadCurr ^ expword;
816 if (diff != 0) {
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));;
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;
840 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
841 Int_t channelcount = 0;
842 Int_t channelcountExp = 0;
843 Int_t channelcountMax = 0;
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)
853 LinkError(kNtimebinsChanged,
854 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
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));
865 UInt_t *startPosMCM = fPayloadCurr;
866
867 // ----- checking for proper readout order - ROB -----
868 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
869 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
870 }
871 else {
872 ROBError(kPosUnexp);
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 {
881 MCMError(kPosUnexp);
882 }
883 fCurrMcmPos = MCM(*fPayloadCurr);
884
885 if (EvNo(*fPayloadCurr) != evno) {
886 if (evno == -1)
887 evno = EvNo(*fPayloadCurr);
888 else {
889 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
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;
902 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
903 channelcountMax = GetNActiveChannels(*fPayloadCurr);
904 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
905 Int_t channelno = -1;
906 fPayloadCurr++;
907
908 if (channelcountExp != channelcountMax) {
909 if (channelcountExp > channelcountMax) {
910 Int_t temp = channelcountExp;
911 channelcountExp = channelcountMax;
912 channelcountMax = temp;
913 }
914 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
915 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
916 MCMError(kAdcMaskInconsistent,
917 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
918 *(fPayloadCurr + 10 * channelcountExp),
919 *(fPayloadCurr + 10 * channelcountExp + 1) );
920 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
921 channelcountExp++;
922 else {
923 break;
924 }
925 }
926 MCMError(kAdcMaskInconsistent,
927 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
928 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
929 }
930 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
931
932 // ----- reading marked ADC channels -----
933 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
934 if (channelno < 20)
935 channelno++;
936 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
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;
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
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) {
961 MCMError(kAdcCheckInvalid,
962 "%i for %2i. ADC word in odd channel %i",
963 check, adcwc+1, channelno);
964 }
965 }
966 else { // even channel
967 if (check != 0x3 && channelno < 21) {
968 MCMError(kAdcCheckInvalid,
969 "%i for %2i. ADC word in even channel %i",
970 check, adcwc+1, channelno);
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)
990 MCMError(kAdcDataAbort);
991
992 // adding index
993 if (padcol > 0 && padcol < 144) {
994 fSignalIndex->AddIndexRC(row, padcol);
995 }
996
997 channelcount++;
998 }
999
1000 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
1001 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
1002 if (channelcount != channelcountExp)
1003 MCMError(kAdcChannelsMiss);
1004
1005 mcmcount++;
1006 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
1007 fStats.fStatsSector[fCurrSm].fNMCMs++;
1008
1009 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
1010 DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
1011 startPosMCM, fPayloadCurr - startPosMCM);
1012 }
1013
1014 // continue with next MCM
1015 }
1016
1017 // check for missing MCMs (if header suppression is inactive)
1018 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
1019 LinkError(kMissMcmHeaders,
1020 "No. of MCM headers %i not as expected: %i",
1021 mcmcount, mcmcountExp);
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;
1034 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
1035 Int_t channelcount = 0;
1036 Int_t channelcountExp = 0;
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)
1046 LinkError(kNtimebinsChanged,
1047 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
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 {
1064 ROBError(kPosUnexp);
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 {
1073 MCMError(kPosUnexp);
1074 }
1075 fCurrMcmPos = MCM(*fPayloadCurr);
1076
1077 if (EvNo(*fPayloadCurr) != evno) {
1078 if (evno == -1)
1079 evno = EvNo(*fPayloadCurr);
1080 else {
1081 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1082 }
1083 }
1084
1085 channelcount = 0;
1086 channelcountExp = 21;
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 -----
1096 while (channelcount < channelcountExp &&
1097 *(fPayloadCurr) != fgkDataEndmarker) {
1098 if (channelno < 20)
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) {
1113 MCMError(kAdcCheckInvalid,
1114 "%i for %2i. ADC word in odd channel %i",
1115 check, adcwc+1, channelno);
1116 }
1117 }
1118 else { // even channel
1119 if (check != 0x3 && channelno < 21) {
1120 MCMError(kAdcCheckInvalid,
1121 "%i for %2i. ADC word in even channel %i",
1122 check, adcwc+1, channelno);
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)
1142 MCMError(kAdcDataAbort);
1143
1144 // adding index
1145 if (padcol > 0 && padcol < 144) {
1146 fSignalIndex->AddIndexRC(row, padcol);
1147 }
1148
1149 channelcount++;
1150 }
1151
1152 if (channelcount != channelcountExp)
1153 MCMError(kAdcChannelsMiss);
1154 mcmcount++;
1155 // continue with next MCM
1156 }
1157
1158 // check for missing MCMs (if header suppression is inactive)
1159 if (mcmcount != mcmcountExp) {
1160 LinkError(kMissMcmHeaders,
1161 "%i not as expected: %i", mcmcount, mcmcountExp);
1162 }
1163
1164 return (fPayloadCurr - start);
1165}
1166
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
1184Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1185{
1186 fTrackletTree = trklTree;
1187 if (!fTrackletTree)
1188 return kTRUE;
1189
1190 if (!fTrackletTree->GetBranch("hc"))
1191 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1192 else
1193 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1194
1195 if (!fTrackletTree->GetBranch("trkl"))
1196 fTrackletTree->Branch("trkl", &fTrackletArray);
1197 else
1198 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1199
1200 return kTRUE;
1201}
1202
1203
1204void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
1205{
1206 // register error according to error code on equipment level
1207 // and return the corresponding error message
1208
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;
1215 (this->*fStoreError)();
1216
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],
1222 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1223 else
1224 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1225 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1226 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1227 fErrorFlags |= fgErrorBehav[err];
1228}
1229
1230
1231void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
1232{
1233 // register error according to error code on stack level
1234 // and return the corresponding error message
1235
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;
1242 (this->*fStoreError)();
1243
1244 va_list ap;
1245 if (fgErrorDebugLevel[err] > 0)
1246 AliDebug(fgErrorDebugLevel[err],
1247 Form("Event %6i: Eq. %2d S %i - %s : %s",
1248 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1249 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1250 else
1251 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1252 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1253 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1254 fErrorFlags |= fgErrorBehav[err];
1255}
1256
1257
1258void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
1259{
1260 // register error according to error code on link level
1261 // and return the corresponding error message
1262
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;
1269 (this->*fStoreError)();
1270
1271 va_list ap;
1272 if (fgErrorDebugLevel[err] > 0)
1273 AliDebug(fgErrorDebugLevel[err],
1274 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1275 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1276 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1277 else
1278 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1279 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1280 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1281 fErrorFlags |= fgErrorBehav[err];
1282}
1283
1284
1285void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
1286{
1287 // register error according to error code on ROB level
1288 // and return the corresponding error message
1289
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;
1296 (this->*fStoreError)();
1297
1298 va_list ap;
1299 if (fgErrorDebugLevel[err] > 0)
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],
1303 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
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],
1307 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1308 fErrorFlags |= fgErrorBehav[err];
1309}
1310
1311
1312void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
1313{
1314 // register error according to error code on MCM level
1315 // and return the corresponding error message
1316
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;
1323 (this->*fStoreError)();
1324
1325 va_list ap;
1326 if (fgErrorDebugLevel[err] > 0)
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],
1330 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
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],
1334 (va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
1335 fErrorFlags |= fgErrorBehav[err];
1336}
1337
1338const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1339{
1340 // return the error message for the given error code
1341
1342 if (errCode > 0 && errCode < kLastErrorCode)
1343 return fgErrorMessages[errCode];
1344 else
1345 return "";
1346}
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}
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}