]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDrawStream.cxx
Fix coding rule violations
[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
d60fe037 25#include "TClonesArray.h"
26#include "TTree.h"
27
28#include "AliLog.h"
29#include "AliRawReader.h"
30#include "AliTRDdigitsManager.h"
31#include "AliTRDdigitsParam.h"
32#include "AliTRDtrapConfig.h"
33#include "AliTRDarrayADC.h"
34#include "AliTRDarrayDictionary.h"
35#include "AliTRDSignalIndex.h"
36#include "AliTRDtrackletWord.h"
37
38#include "AliTRDrawStream.h"
39
40// temporary
41#include "AliRunLoader.h"
42
43ClassImp(AliTRDrawStream)
44
45// some static information
46const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
47 8, 9, 10, 11,
48 4, 5, 6, 7,
49 0, 1, 2, 3};
50const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
51const Int_t AliTRDrawStream::fgkNlinks = 12;
52const Int_t AliTRDrawStream::fgkNstacks = 5;
53const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
54const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
55
56char* AliTRDrawStream::fgErrorMessages[] = {
57 "Unknown error",
58 "Link monitor active",
59 "Pretrigger counter mismatch",
60 "not a TRD equipment (1024-1041)",
61 "Invalid Stack header",
62 "Invalid detector number",
63 "No digits could be retrieved from the digitsmanager",
64 "HC header mismatch",
65 "HC check bits wrong",
66 "Unexpected position in readout stream",
67 "Invalid testpattern mode",
68 "Testpattern mismatch",
69 "Number of timebins changed",
70 "ADC mask inconsistent",
71 "ADC check bits invalid",
72 "Missing ADC data",
73 "Missing expected ADC channels",
74 "Missing MCM headers"
75};
76
77AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
78 fRawReader(rawReader),
79 fDigitsManager(0x0),
80 fDigitsParam(0x0),
81 fErrors(0x0),
82 fLastError(),
83 fPayloadStart(0x0),
84 fPayloadCurr(0x0),
85 fPayloadSize(0),
86 fNtimebins(-1),
87 fLastEvId(-1),
88 fCurrSlot(-1),
89 fCurrLink(-1),
90 fCurrRobPos(-1),
91 fCurrMcmPos(-1),
92 fCurrEquipmentId(0),
93 fCurrSmuIndexHeaderSize(0),
94 fCurrSmuIndexHeaderVersion(0),
95 fCurrTrackEnable(0),
96 fCurrTrackletEnable(0),
97 fCurrStackMask(0),
98 fCurrStackIndexWord(0x0),
99 fCurrStackHeaderSize(0x0),
100 fCurrStackHeaderVersion(0x0),
101 fCurrLinkMask(0x0),
102 fCurrCleanCheckout(0x0),
103 fCurrBoardId(0x0),
104 fCurrHwRev(0x0),
105 fCurrLinkMonitorFlags(0x0),
106 fCurrLinkDataTypeFlags(0x0),
107 fCurrLinkDebugFlags(0x0),
108 fCurrSpecial(-1),
109 fCurrMajor(-1),
110 fCurrMinor(-1),
111 fCurrAddHcWords(-1),
112 fCurrSm(-1),
113 fCurrStack(-1),
114 fCurrLayer(-1),
115 fCurrSide(-1),
116 fCurrHC(-1),
117 fCurrCheck(-1),
118 fCurrNtimebins(-1),
119 fCurrBC(-1),
120 fCurrPtrgCnt(-1),
121 fCurrPtrgPhase(-1),
122 fTrackletArray(0x0),
123 fAdcArray(0x0),
124 fSignalIndex(0x0),
125 fTrackletTree(0x0)
126{
127 // default constructor
128
129 fCurrStackIndexWord = new UInt_t[fgkNstacks];
130 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
131 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
132 fCurrLinkMask = new UInt_t[fgkNstacks];
133 fCurrCleanCheckout = new UInt_t[fgkNstacks];
134 fCurrBoardId = new UInt_t[fgkNstacks];
135 fCurrHwRev = new UInt_t[fgkNstacks];
136 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
137 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
138 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
139
140 // preparing TClonesArray
141 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
142
143 // setting up the error tree
144 fErrors = new TTree("errorStats", "Error statistics");
145 fErrors->SetDirectory(0x0);
146 fErrors->Branch("error", &fLastError, "sector/I:stack:link:error:rob:mcm");
147 fErrors->SetCircular(1000);
148}
149
150AliTRDrawStream::~AliTRDrawStream()
151{
152 // destructor
153
154 delete fErrors;
155
156 delete [] fCurrStackIndexWord;
157 delete [] fCurrStackHeaderSize;
158 delete [] fCurrStackHeaderVersion;
159 delete [] fCurrLinkMask;
160 delete [] fCurrCleanCheckout;
161 delete [] fCurrBoardId;
162 delete [] fCurrHwRev;
163 delete [] fCurrLinkMonitorFlags;
164 delete [] fCurrLinkDataTypeFlags;
165 delete [] fCurrLinkDebugFlags;
166}
167
168Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
169{
170 // read the current event from the raw reader and fill it to the digits manager
171
172 if (!fRawReader) {
173 AliError("No raw reader available");
174 return kFALSE;
175 }
176
177 // tracklet output
178 fTrackletTree = trackletTree;
179 if (fTrackletTree) {
180 if (!fTrackletTree->GetBranch("trkl")) {
181 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
182 fTrackletTree->Branch("trkl", &fTrackletArray);
183 }
184 else {
185 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
186 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
187 }
188 }
189
190 // some preparations
191 fDigitsParam = 0x0;
192
193 // loop over all DDLs
194 // data starts with GTU payload, i.e. SMU index word
195 UChar_t *buffer = 0x0;
196
197 while (fRawReader->ReadNextData(buffer)) {
198
199 fCurrEquipmentId = fRawReader->GetEquipmentId();
200 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
201
202 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
203 AliError(EquipmentError(kNonTrdEq, "Skipping"));
204 continue;
205 }
206
207 // setting the pointer to data and current reading position
208 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
209 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
210 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
211
212 // read SMU index header
213 if (ReadSmHeader() < 0) {
214 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
215 continue;
216 }
217
218 // read stack index header
219 for (Int_t iStack = 0; iStack < 5; iStack++) {
220 if (fCurrStackMask & (1 << iStack) != 0)
221 ReadStackIndexHeader(iStack);
222 }
223
224 for (Int_t iStack = 0; iStack < 5; iStack++) {
225 fCurrSlot = iStack;
226 if (fCurrStackMask & (1 << fCurrSlot) == 0)
227 continue;
228
229 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
230 for (Int_t iLink = 0; iLink < 12; iLink++) {
231 fCurrLink = iLink;
232 fCurrHC = fCurrSm * 60 + fCurrSlot * 12 + iLink;
233 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
234 continue;
235
236 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
237 LinkError(kLinkMonitor);
238 AliDebug(2, Form("Payload for S%il%i", fCurrSlot, fCurrLink));
239 for (Int_t i = 0; i < 10; i++) //???
240 AliDebug(5, Form("%3i: 0x%08x 0x%08x 0x%08x 0x%08x", i*4,
241 fPayloadCurr[4*i], fPayloadCurr[4*i+1],
242 fPayloadCurr[4*i+2], fPayloadCurr[4*i+3]));
243
244 // read the data from one HC
245 ReadLinkData();
246
247 // read all data endmarkers
248 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
249 *fPayloadCurr == fgkDataEndmarker)
250 fPayloadCurr++;
251
252 }
253 }
254 }
255 return kTRUE;
256}
257
258
259Bool_t AliTRDrawStream::NextDDL()
260{
0508ca31 261 // continue reading with the next equipment
262
d60fe037 263 if (!fRawReader)
264 return kFALSE;
265
266 fCurrEquipmentId = 0;
267 fCurrSlot = 0;
268 fCurrLink = 0;
269
270 UChar_t *buffer = 0x0;
271
272 while (fRawReader->ReadNextData(buffer)) {
273
274 fCurrEquipmentId = fRawReader->GetEquipmentId();
275 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
276
277 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
278 AliError(EquipmentError(kNonTrdEq, "Skipping"));
279 continue;
280 }
281
282 // setting the pointer to data and current reading position
283 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
284 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
285 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
286
287 // read SMU index header
288 if (ReadSmHeader() < 0) {
289 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
290 continue;
291 }
292
293 // read stack index header
294 for (Int_t iStack = 0; iStack < 5; iStack++) {
295 if (fCurrStackMask & (1 << iStack) != 0) {
296 ReadStackIndexHeader(iStack);
297 }
298 }
299 return kTRUE;
300 }
301
302 return kFALSE;
303}
304
305
306Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
307{
0508ca31 308 // read the data for the next chamber
309 // in case you only want to read the data of a single chamber
310 // to read all data ReadEvent(...) is recommended
311
d60fe037 312 fDigitsManager = digMgr;
313 fDigitsParam = 0x0;
314
315 // tracklet output preparation
316 fTrackletTree = 0x0;
317 //AliDataLoader *trklLoader = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets");
318 //if (trklLoader)
319 // fTrackletTree = trklLoader->Tree();
320
321 if (!fRawReader) {
322 AliError("No raw reader available");
323 return -1;
324 }
325
326 if (fCurrSlot < 0 || fCurrSlot >= 5) {
327 if (!NextDDL()) {
328 fCurrSlot = -1;
329 return -1;
330 }
331 }
332
333 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
334 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
335
336 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
337 LinkError(kLinkMonitor);
338
339 // read the data from one HC
340 ReadLinkData();
341
342 // read all data endmarkers
343 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
344 *fPayloadCurr == fgkDataEndmarker)
345 fPayloadCurr++;
346
347 if (fCurrLink % 2 == 0) {
348 // if we just read the A-side HC then also check the B-side
349 fCurrLink++;
350 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
351 ReadLinkData();
352 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
353 *fPayloadCurr == fgkDataEndmarker)
354 fPayloadCurr++;
355 }
356 }
357
358 //??? to check
359 do {
360 fCurrLink++;
361 if (fCurrLink > 11) {
362 fCurrLink = 0;
363 fCurrSlot++;
364 }
365 } while ((fCurrSlot < 5) &&
366 ((fCurrStackMask & (1 << fCurrSlot) == 0) ||
367 (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0));
368
0508ca31 369 return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
d60fe037 370}
371
372
373Int_t AliTRDrawStream::ReadSmHeader()
374{
375 // read the SMU index header at the current reading position
376 // and store the information in the corresponding variables
377
378 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
0508ca31 379 AliError(EquipmentError(kUnknown, "SM Header incomplete"));
d60fe037 380 return -1;
381 }
382
383 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
384 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
385 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
386 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
387 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
388
389 AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
390 fCurrSmuIndexHeaderSize,
391 fCurrSmuIndexHeaderVersion,
392 fCurrTrackEnable,
393 fCurrTrackletEnable,
394 fCurrStackMask));
395
396 fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
397
398 return fCurrSmuIndexHeaderSize + 1;
399}
400
401Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
402{
403 // read the stack index header
404 // and store the information in the corresponding variables
405
406 fCurrStackIndexWord[stack] = *fPayloadCurr;
407 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
408 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
409 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
410
411 if (fPayloadCurr - fPayloadStart >= fPayloadSize - fCurrStackHeaderSize[stack]) {
412 AliError(StackError(kStackHeaderInvalid, "Stack index header aborted"));
413 return -1;
414 }
415
416 switch (fCurrStackHeaderVersion[stack]) {
417 case 0xa:
418 if (fCurrStackHeaderSize[stack] < 8) {
419 AliError(StackError(kStackHeaderInvalid, "Stack header smaller than expected!"));
420 return -1;
421 }
422
423 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
424 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
425 fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
426
427 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
428 // A side
429 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
430 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
431 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
432 // B side
433 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
434 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
435 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
436 }
437 break;
438
439 default:
440 AliError(StackError(kStackHeaderInvalid, Form("Invalid Stack Index Header version %x",
441 fCurrStackHeaderVersion[stack])));
442 }
443
444 fPayloadCurr += fCurrStackHeaderSize[stack];
445
446 return fCurrStackHeaderSize[stack];
447}
448
449Int_t AliTRDrawStream::ReadLinkData()
450{
451 // read the data in one link (one HC) until the data endmarker is reached
452
453 Int_t count = 0;
454
455 count += ReadTracklets();
456
457 count += ReadHcHeader();
458
459 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
460
461 if (det > -1 && det < 540) {
462
463 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
464 //fAdcArray->Expand();
465 if (fAdcArray->GetNtime() != fCurrNtimebins)
466 fAdcArray->Allocate(16, 144, fCurrNtimebins);
467 }
468 else {
469 AliError(LinkError(kNoDigits));
470 }
471
472 if (!fDigitsParam) {
473 fDigitsParam = fDigitsManager->GetDigitsParam();
474 }
475 if (fDigitsParam) {
476 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
477 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
478 fDigitsParam->SetADCbaseline(det, 10);
479 }
480
481 if (fDigitsManager->UsesDictionaries()) {
482 fDigitsManager->GetDictionary(det, 0)->Reset();
483 fDigitsManager->GetDictionary(det, 1)->Reset();
484 fDigitsManager->GetDictionary(det, 2)->Reset();
485 }
486
487 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
488 fSignalIndex->SetSM(fCurrSm);
489 fSignalIndex->SetStack(fCurrStack);
490 fSignalIndex->SetLayer(fCurrLayer);
491 fSignalIndex->SetDetNumber(det);
492 if (!fSignalIndex->IsAllocated())
493 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
494 }
495
496 // ----- check which kind of data -----
497 if (fCurrMajor & 0x40) {
498 if ((fCurrMajor & 0x7) == 0x7) {
499 AliDebug(1, "This is a config event");
500 UInt_t *startPos = fPayloadCurr;
501 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
502 *fPayloadCurr != fgkDataEndmarker)
503 fPayloadCurr++;
504 count += fPayloadCurr - startPos;
505
506 // feeding TRAP config
507 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
0508ca31 508 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
d60fe037 509 }
510 else {
511 Int_t tpmode = fCurrMajor & 0x7;
512 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
513 ReadTPData(tpmode);
514 }
515 }
516 else if (fCurrMajor & 0x20) {
517 AliDebug(1, "This is a zs event");
518 count += ReadZSData();
519 }
520 else {
521 AliDebug(1, "This is a nozs event");
522 count += ReadNonZSData();
523 }
524 }
525 else {
526 AliError(LinkError(kInvalidDetector, Form("%i", det)));
527 UInt_t *startPos = fPayloadCurr;
528 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
529 *fPayloadCurr != fgkDataEndmarker)
530 fPayloadCurr++;
531 count += fPayloadCurr - startPos;
532 }
533
534 return count;
535}
536
537Int_t AliTRDrawStream::ReadTracklets()
538{
539 // read the tracklets from one HC
540
541 fTrackletArray->Clear();
542
543 UInt_t *start = fPayloadCurr;
544 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
545 fPayloadCurr - fPayloadStart < fPayloadSize) {
546
547 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr));
548
549 fPayloadCurr++;
550 }
551
552 if (fTrackletArray->GetEntriesFast() > 0) {
553 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
554 fCurrSm, fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
555 if (fTrackletTree)
556 fTrackletTree->Fill();
557 }
558
559 // loop over remaining tracklet endmarkers
560 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
561 fPayloadCurr - fPayloadStart < fPayloadSize))
562 fPayloadCurr++;
563
564 return (fPayloadCurr - start) / sizeof(UInt_t);
565}
566
567Int_t AliTRDrawStream::ReadHcHeader()
568{
569 // read and parse the HC header of one HC
570 // and store the information in the corresponding variables
571
572 UInt_t *start = fPayloadCurr;
573 // check not to be at the data endmarker
574 if (*fPayloadCurr == fgkDataEndmarker)
575 return 0;
576
577 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
578 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
579 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
580 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
581 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
582 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
583 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
584 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
585 fCurrCheck = (*fPayloadCurr) & 0x3;
586
0508ca31 587 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
d60fe037 588 fCurrStack != fCurrSlot ||
589 fCurrLayer != fCurrLink / 2 ||
590 fCurrSide != fCurrLink % 2) {
591 AliError(LinkError(kHCmismatch,
592 Form("HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
593 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
594 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]) ));
595 }
596 if (fCurrCheck != 0x1) {
597 AliError(LinkError(kHCcheckFailed));
598 }
599
600 if (fCurrAddHcWords > 0) {
601 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
602 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
603 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
604 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
605 }
606
607 fPayloadCurr += 1 + fCurrAddHcWords;
608
609 return (fPayloadCurr - start) / sizeof(UInt_t);
610}
611
612Int_t AliTRDrawStream::ReadTPData(Int_t mode)
613{
614 // testing of testpattern 1 to 3 (hardcoded), 0 missing
615 // evcnt checking missing
616 Int_t cpu = 0;
617 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
618 Int_t evcnt = 0;
619 Int_t count = 0;
620 Int_t mcmcount = -1;
621 Int_t wordcount = 0;
622 Int_t channelcount = 0;
623 UInt_t expword = 0;
624 UInt_t expadcval = 0;
625 UInt_t diff = 0;
626 Int_t lastmcmpos = -1;
627 Int_t lastrobpos = -1;
628
629 UInt_t* start = fPayloadCurr;
630
631 while (*(fPayloadCurr) != fgkDataEndmarker &&
632 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
633
634 // ----- Checking MCM Header -----
635 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
636 mcmcount++;
637
638 // ----- checking for proper readout order - ROB -----
639 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
640 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
641 }
642 else {
643 AliError(ROBError(kPosUnexp));
644 }
645 fCurrRobPos = ROB(*fPayloadCurr);
646
647 // ----- checking for proper readout order - MCM -----
648 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
649 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
650 }
651 else {
652 AliError(MCMError(kPosUnexp));
653 }
654 fCurrMcmPos = MCM(*fPayloadCurr);
655
656
657 fPayloadCurr++;
658
659 evcnt = 0x3f & *fPayloadCurr >> 26;
660 cpu = -1;
661 channelcount = 0;
662 while (channelcount < 21) {
663 count = 0;
664 if (cpu != cpufromchannel[channelcount]) {
665 cpu = cpufromchannel[channelcount];
666 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
667 wordcount = 0;
668 }
669
670 while (count < 10) {
671 if (channelcount % 2 == 0)
672 expword = 0x3;
673 else
674 expword = 0x2;
675
676 if (mode == 1) {
677 // ----- TP 1 -----
678 expword |= expadcval << 2;
679 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
680 expword |= expadcval << 12;
681 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
682 expword |= expadcval << 22;
683 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
684 }
685 else if (mode == 2) {
686 // ----- TP 2 ------
687 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
688 ((fCurrStack + 1) << 15) |
689 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
690 }
691 else if (mode == 3) {
692 // ----- TP 3 -----
693 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
694 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
695 }
696 else {
697 expword = 0;
698 AliError(LinkError(kTPmodeInvalid, "Just reading"));
699 }
700
701 diff = *fPayloadCurr ^ expword;
702 if (diff != 0) {
703 AliError(MCMError(kTPmismatch,
704 Form("Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
705 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24)) ));
706 }
707 fPayloadCurr++;
708 count++;
709 wordcount++;
710 }
711 channelcount++;
712 }
713 // continue with next MCM
714 }
715 return fPayloadCurr - start;
716}
717
718
719Int_t AliTRDrawStream::ReadZSData()
720{
721 // read the zs data from one link from the current reading position
722
723 UInt_t *start = fPayloadCurr;
724
725 Int_t mcmcount = 0;
0508ca31 726 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 727 Int_t channelcount = 0;
0508ca31 728 Int_t channelcountExp = 0;
729 Int_t channelcountMax = 0;
d60fe037 730 Int_t timebins;
731 Int_t currentTimebin = 0;
732 Int_t adcwc = 0;
733 Int_t evno = -1;
734 Int_t lastmcmpos = -1;
735 Int_t lastrobpos = -1;
736
737 if (fCurrNtimebins != fNtimebins) {
738 if (fNtimebins > 0)
739 AliError(LinkError(kNtimebinsChanged,
740 Form("No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins) ));
741 fNtimebins = fCurrNtimebins;
742 }
743
744 timebins = fNtimebins;
745
746 while (*(fPayloadCurr) != fgkDataEndmarker &&
747 fPayloadCurr - fPayloadStart < fPayloadSize) {
748
749 // ----- Checking MCM Header -----
750 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
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 AliError(ROBError(kPosUnexp));
758 }
759 fCurrRobPos = ROB(*fPayloadCurr);
760
761 // ----- checking for proper readout order - MCM -----
762 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
763 lastmcmpos = GetMCMReadoutPos(lastmcmpos);
764 }
765 else {
766 AliError(MCMError(kPosUnexp));
767 }
768 fCurrMcmPos = MCM(*fPayloadCurr);
769
770 if (EvNo(*fPayloadCurr) != evno) {
771 if (evno == -1)
772 evno = EvNo(*fPayloadCurr);
773 else {
774 AliError(MCMError(kPtrgCntMismatch,
775 Form("%i <-> %i", evno, EvNo(*fPayloadCurr)) ));
776 }
777 }
778 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
779 Int_t padcoloff = PadColOffset(*fPayloadCurr);
780 Int_t row = Row(*fPayloadCurr);
781 fPayloadCurr++;
782
783 // ----- Reading ADC channels -----
784 AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
785
786 // ----- analysing the ADC mask -----
787 channelcount = 0;
0508ca31 788 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
789 channelcountMax = GetNActiveChannels(*fPayloadCurr);
d60fe037 790 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
791 Int_t channelno = -1;
792 fPayloadCurr++;
793
0508ca31 794 if (channelcountExp != channelcountMax) {
795 if (channelcountExp > channelcountMax) {
796 Int_t temp = channelcountExp;
797 channelcountExp = channelcountMax;
798 channelcountMax = temp;
d60fe037 799 }
0508ca31 800 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
801 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
d60fe037 802 AliError(MCMError(kAdcMaskInconsistent,
803 Form("Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
0508ca31 804 *(fPayloadCurr + 10 * channelcountExp),
805 *(fPayloadCurr + 10 * channelcountExp + 1) ) ));
806 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
807 channelcountExp++;
d60fe037 808 else {
809 break;
810 }
811 }
812 AliError(MCMError(kAdcMaskInconsistent,
813 Form("Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
0508ca31 814 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp) ));
d60fe037 815 }
0508ca31 816 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
d60fe037 817
818 // ----- reading marked ADC channels -----
0508ca31 819 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
d60fe037 820 if (channelno < 21)
821 channelno++;
822 while (channelno < 21 && (channelmask & 1 << channelno) == 0)
823 channelno++;
824
825 if (fCurrNtimebins > 30) {
826 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
827 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
828 }
829 else {
830 currentTimebin = 0;
831 }
832
833 adcwc = 0;
834 AliDebug(2, Form("Now looking %i words", timebins / 3));
835 Int_t adccol = adccoloff - channelno;
836 Int_t padcol = padcoloff - channelno;
837 while (adcwc < timebins / 3 &&
838 *(fPayloadCurr) != fgkDataEndmarker &&
839 fPayloadCurr - fPayloadStart < fPayloadSize) {
840 int check = 0x3 & *fPayloadCurr;
841 if (channelno % 2 != 0) { // odd channel
842 if (check != 0x2 && channelno < 21) {
843 AliError(MCMError(kAdcCheckInvalid,
844 Form("Invalid check bits: %i for %2i. ADC word in odd channel: %i",
845 check, adcwc+1, channelno) ));
846 }
847 }
848 else { // even channel
849 if (check != 0x3 && channelno < 21) {
850 AliError(MCMError(kAdcCheckInvalid,
851 Form("Invalid check bits: %i for %2i. ADC word in even channel: %i",
852 check, adcwc+1, channelno) ));
853 }
854 }
855
856 // filling the actual timebin data
857 int tb2 = 0x3ff & *fPayloadCurr >> 22;
858 int tb1 = 0x3ff & *fPayloadCurr >> 12;
859 int tb0 = 0x3ff & *fPayloadCurr >> 2;
860 if (adcwc != 0 || fCurrNtimebins <= 30)
861 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
862 else
863 tb0 = -1;
864 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
865 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
866
867 adcwc++;
868 fPayloadCurr++;
869 }
870
871 if (adcwc != timebins / 3)
872 AliError(MCMError(kAdcDataAbort));
873
874 // adding index
875 if (padcol > 0 && padcol < 144) {
876 fSignalIndex->AddIndexRC(row, padcol);
877 }
878
879 channelcount++;
880 }
881
0508ca31 882 if (channelcount != channelcountExp)
d60fe037 883 AliError(MCMError(kAdcChannelsMiss));
884
885 mcmcount++;
886 // continue with next MCM
887 }
888
889 // check for missing MCMs (if header suppression is inactive)
0508ca31 890 if (fCurrMajor & 0x1 == 0 && mcmcount != mcmcountExp) {
d60fe037 891 AliError(LinkError(kMissMcmHeaders,
892 Form("No. of MCM headers %i not as expected: %i",
0508ca31 893 mcmcount, mcmcountExp) ));
d60fe037 894 }
895
896 return (fPayloadCurr - start);
897}
898
899Int_t AliTRDrawStream::ReadNonZSData()
900{
901 // read the non-zs data from one link from the current reading position
902
903 UInt_t *start = fPayloadCurr;
904
905 Int_t mcmcount = 0;
0508ca31 906 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
d60fe037 907 Int_t channelcount = 0;
0508ca31 908 Int_t channelcountExp = 0;
d60fe037 909 Int_t timebins;
910 Int_t currentTimebin = 0;
911 Int_t adcwc = 0;
912 Int_t evno = -1;
913 Int_t lastmcmpos = -1;
914 Int_t lastrobpos = -1;
915
916 if (fCurrNtimebins != fNtimebins) {
917 if (fNtimebins > 0)
918 AliError(LinkError(kNtimebinsChanged,
919 Form("No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins) ));
920 fNtimebins = fCurrNtimebins;
921 }
922
923 timebins = fNtimebins;
924
925 while (*(fPayloadCurr) != fgkDataEndmarker &&
926 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
927
928 // ----- Checking MCM Header -----
929 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
930
931 // ----- checking for proper readout order - ROB -----
932 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
933 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
934 }
935 else {
936 AliError(ROBError(kPosUnexp));
937 }
938 fCurrRobPos = ROB(*fPayloadCurr);
939
940 // ----- checking for proper readout order - MCM -----
941 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
942 lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
943 }
944 else {
945 AliError(MCMError(kPosUnexp));
946 }
947 fCurrMcmPos = MCM(*fPayloadCurr);
948
949 if (EvNo(*fPayloadCurr) != evno) {
950 if (evno == -1)
951 evno = EvNo(*fPayloadCurr);
952 else {
953 AliError(MCMError(kPtrgCntMismatch,
954 Form("%i <-> %i", evno, EvNo(*fPayloadCurr)) ));
955 }
956 }
957
958 channelcount = 0;
0508ca31 959 channelcountExp = 21;
d60fe037 960 int channelno = -1;
961
962 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
963 Int_t padcoloff = PadColOffset(*fPayloadCurr);
964 Int_t row = Row(*fPayloadCurr);
965
966 fPayloadCurr++;
967
968 // ----- reading marked ADC channels -----
0508ca31 969 while (channelcount < channelcountExp &&
d60fe037 970 *(fPayloadCurr) != fgkDataEndmarker) {
971 if (channelno < 21)
972 channelno++;
973
974 currentTimebin = 0;
975
976 adcwc = 0;
977 AliDebug(2, Form("Now looking %i words", timebins / 3));
978 Int_t adccol = adccoloff - channelno;
979 Int_t padcol = padcoloff - channelno;
980 while (adcwc < timebins / 3 &&
981 *(fPayloadCurr) != fgkDataEndmarker &&
982 fPayloadCurr - fPayloadStart < fPayloadSize) {
983 int check = 0x3 & *fPayloadCurr;
984 if (channelno % 2 != 0) { // odd channel
985 if (check != 0x2 && channelno < 21) {
986 AliError(MCMError(kAdcCheckInvalid,
987 Form("Invalid check bits: %i for %2i. ADC word in odd channel: %i",
988 check, adcwc+1, channelno) ));
989 }
990 }
991 else { // even channel
992 if (check != 0x3 && channelno < 21) {
993 AliError(MCMError(kAdcCheckInvalid,
994 Form("Invalid check bits: %i for %2i. ADC word in even channel: %i",
995 check, adcwc+1, channelno) ));
996 }
997 }
998
999 // filling the actual timebin data
1000 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1001 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1002 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1003 if (adcwc != 0 || fCurrNtimebins <= 30)
1004 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1005 else
1006 tb0 = -1;
1007 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1008 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1009
1010 adcwc++;
1011 fPayloadCurr++;
1012 }
1013
1014 if (adcwc != timebins / 3)
1015 AliError(MCMError(kAdcDataAbort));
1016
1017 // adding index
1018 if (padcol > 0 && padcol < 144) {
1019 fSignalIndex->AddIndexRC(row, padcol);
1020 }
1021
1022 channelcount++;
1023 }
1024
0508ca31 1025 if (channelcount != channelcountExp)
d60fe037 1026 AliError(MCMError(kAdcChannelsMiss));
1027 mcmcount++;
1028 // continue with next MCM
1029 }
1030
1031 // check for missing MCMs (if header suppression is inactive)
0508ca31 1032 if (mcmcount != mcmcountExp) {
d60fe037 1033 AliError(LinkError(kMissMcmHeaders,
0508ca31 1034 Form("%i not as expected: %i", mcmcount, mcmcountExp) ));
d60fe037 1035 }
1036
1037 return (fPayloadCurr - start);
1038}
1039
1040
0508ca31 1041Int_t AliTRDrawStream::GetNActiveChannelsFromMask(UInt_t adcmask) const
d60fe037 1042{
0508ca31 1043 // return number of active bits in the ADC mask
1044
d60fe037 1045 adcmask = GetActiveChannels(adcmask);
1046 adcmask = adcmask - ((adcmask >> 1) & 0x55555555);
1047 adcmask = (adcmask & 0x33333333) + ((adcmask >> 2) & 0x33333333);
1048 return (((adcmask + (adcmask >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
1049}
1050
1051
1052TString AliTRDrawStream::EquipmentError(ErrorCode_t err, TString msg)
1053{
0508ca31 1054 // register error according to error code on equipment level
1055 // and return the corresponding error message
1056
d60fe037 1057 fLastError.fSector = fCurrEquipmentId - 1024;
1058 fLastError.fStack = -1;
1059 fLastError.fLink = -1;
1060 fLastError.fRob = -1;
1061 fLastError.fMcm = -1;
1062 fLastError.fError = err;
1063 fErrors->Fill();
1064
1065 return (Form("Event %6i: Eq. %2d - %s : ",
1066 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err]) + msg);
1067}
1068
1069
1070TString AliTRDrawStream::StackError(ErrorCode_t err, TString msg)
1071{
0508ca31 1072 // register error according to error code on stack level
1073 // and return the corresponding error message
1074
d60fe037 1075 fLastError.fSector = fCurrEquipmentId - 1024;
1076 fLastError.fStack = fCurrSlot;
1077 fLastError.fLink = -1;
1078 fLastError.fRob = -1;
1079 fLastError.fMcm = -1;
1080 fLastError.fError = err;
1081 fErrors->Fill();
1082
1083 return (Form("Event %6i: Eq. %2d S %i - %s : ",
1084 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err]) + msg);
1085}
1086
1087
1088TString AliTRDrawStream::LinkError(ErrorCode_t err, TString msg)
1089{
0508ca31 1090 // register error according to error code on link level
1091 // and return the corresponding error message
1092
d60fe037 1093 fLastError.fSector = fCurrEquipmentId - 1024;
1094 fLastError.fStack = fCurrSlot;
1095 fLastError.fLink = fCurrLink;
1096 fLastError.fRob = -1;
1097 fLastError.fMcm = -1;
1098 fLastError.fError = err;
1099 fErrors->Fill();
1100
1101 return (Form("Event %6i: Eq. %2d S %i l %2i - %s : ",
1102 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err]) + msg);
1103}
1104
1105
1106TString AliTRDrawStream::ROBError(ErrorCode_t err, TString msg)
1107{
0508ca31 1108 // register error according to error code on ROB level
1109 // and return the corresponding error message
1110
d60fe037 1111 fLastError.fSector = fCurrEquipmentId - 1024;
1112 fLastError.fStack = fCurrSlot;
1113 fLastError.fLink = fCurrLink;
1114 fLastError.fRob = fCurrRobPos;
1115 fLastError.fMcm = -1;
1116 fLastError.fError = err;
1117 fErrors->Fill();
1118
1119 return (Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : ",
1120 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err]) + msg);
1121}
1122
1123
1124TString AliTRDrawStream::MCMError(ErrorCode_t err, TString msg)
1125{
0508ca31 1126 // register error according to error code on MCM level
1127 // and return the corresponding error message
1128
d60fe037 1129 fLastError.fSector = fCurrEquipmentId - 1024;
1130 fLastError.fStack = fCurrSlot;
1131 fLastError.fLink = fCurrLink;
1132 fLastError.fRob = fCurrRobPos;
1133 fLastError.fMcm = fCurrMcmPos;
1134 fLastError.fError = err;
1135 fErrors->Fill();
1136
1137 return (Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : ",
1138 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err]) + msg);
1139}
1140
1141const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1142{
0508ca31 1143 // return the error message for the given error code
1144
d60fe037 1145 if (errCode > 0 && errCode < kLastErrorCode)
1146 return fgErrorMessages[errCode];
1147 else
1148 return "";
1149}