1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////
18 // Decoding data from the TRD raw stream //
19 // and translation into ADC values //
21 // Author: J. Klein (jochen.klein@cern.ch) //
23 ////////////////////////////////////////////////////////////////////////////
25 #include "TClonesArray.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 #include "AliTreeLoader.h"
39 #include "AliTRDrawStream.h"
42 #include "AliRunLoader.h"
44 ClassImp(AliTRDrawStream)
46 // some static information
47 const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
51 const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
52 const Int_t AliTRDrawStream::fgkNlinks = 12;
53 const Int_t AliTRDrawStream::fgkNstacks = 5;
54 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
55 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
57 const char* AliTRDrawStream::fgErrorMessages[] = {
59 "Link monitor active",
60 "Pretrigger counter mismatch",
61 "not a TRD equipment (1024-1041)",
62 "Invalid Stack header",
63 "Invalid detector number",
64 "No digits could be retrieved from the digitsmanager",
66 "HC check bits wrong",
67 "Unexpected position in readout stream",
68 "Invalid testpattern mode",
69 "Testpattern mismatch",
70 "Number of timebins changed",
71 "ADC mask inconsistent",
72 "ADC check bits invalid",
74 "Missing expected ADC channels",
78 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
80 fRawReader(rawReader),
95 fCurrSmuIndexHeaderSize(0),
96 fCurrSmuIndexHeaderVersion(0),
98 fCurrTrackletEnable(0),
100 fCurrStackIndexWord(0x0),
101 fCurrStackHeaderSize(0x0),
102 fCurrStackHeaderVersion(0x0),
104 fCurrCleanCheckout(0x0),
107 fCurrLinkMonitorFlags(0x0),
108 fCurrLinkDataTypeFlags(0x0),
109 fCurrLinkDebugFlags(0x0),
130 // default constructor
132 fCurrStackIndexWord = new UInt_t[fgkNstacks];
133 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
134 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
135 fCurrLinkMask = new UInt_t[fgkNstacks];
136 fCurrCleanCheckout = new UInt_t[fgkNstacks];
137 fCurrBoardId = new UInt_t[fgkNstacks];
138 fCurrHwRev = new UInt_t[fgkNstacks];
139 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
140 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
141 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
143 // preparing TClonesArray
144 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
146 // setting up the error tree
147 fErrors = new TTree("errorStats", "Error statistics");
148 fErrors->SetDirectory(0x0);
149 fErrors->Branch("error", &fLastError, "sector/I:stack:link:error:rob:mcm");
150 fErrors->SetCircular(1000);
153 AliTRDrawStream::~AliTRDrawStream()
159 delete [] fCurrStackIndexWord;
160 delete [] fCurrStackHeaderSize;
161 delete [] fCurrStackHeaderVersion;
162 delete [] fCurrLinkMask;
163 delete [] fCurrCleanCheckout;
164 delete [] fCurrBoardId;
165 delete [] fCurrHwRev;
166 delete [] fCurrLinkMonitorFlags;
167 delete [] fCurrLinkDataTypeFlags;
168 delete [] fCurrLinkDebugFlags;
171 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
173 // read the current event from the raw reader and fill it to the digits manager
176 AliError("No raw reader available");
181 ConnectTracklets(trackletTree);
186 // loop over all DDLs
187 // data starts with GTU payload, i.e. SMU index word
188 UChar_t *buffer = 0x0;
190 while (fRawReader->ReadNextData(buffer)) {
192 fCurrEquipmentId = fRawReader->GetEquipmentId();
193 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
195 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
196 AliError(EquipmentError(kNonTrdEq, "Skipping"));
200 // setting the pointer to data and current reading position
201 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
202 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
203 fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
204 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
206 // read SMU index header
207 if (ReadSmHeader() < 0) {
208 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
212 // read stack index header
213 for (Int_t iStack = 0; iStack < 5; iStack++) {
214 if ((fCurrStackMask & (1 << iStack)) != 0)
215 ReadStackIndexHeader(iStack);
218 for (Int_t iStack = 0; iStack < 5; iStack++) {
220 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
223 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
224 for (Int_t iLink = 0; iLink < 12; iLink++) {
226 fCurrHC = fCurrSm * 60 + fCurrSlot * 12 + iLink;
227 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
230 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
231 LinkError(kLinkMonitor);
232 AliDebug(2, Form("Payload for S%il%i", fCurrSlot, fCurrLink));
233 for (Int_t i = 0; i < 10; i++) //???
234 AliDebug(5, Form("%3i: 0x%08x 0x%08x 0x%08x 0x%08x", i*4,
235 fPayloadCurr[4*i], fPayloadCurr[4*i+1],
236 fPayloadCurr[4*i+2], fPayloadCurr[4*i+3]));
238 // read the data from one HC
241 // read all data endmarkers
242 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
243 *fPayloadCurr == fgkDataEndmarker)
253 Bool_t AliTRDrawStream::NextDDL()
255 // continue reading with the next equipment
260 fCurrEquipmentId = 0;
264 UChar_t *buffer = 0x0;
266 while (fRawReader->ReadNextData(buffer)) {
268 fCurrEquipmentId = fRawReader->GetEquipmentId();
269 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
271 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
272 AliError(EquipmentError(kNonTrdEq, "Skipping"));
276 // setting the pointer to data and current reading position
277 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
278 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
279 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
281 // read SMU index header
282 if (ReadSmHeader() < 0) {
283 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
287 // read stack index header
288 for (Int_t iStack = 0; iStack < 5; iStack++) {
289 if ((fCurrStackMask & (1 << iStack)) != 0) {
290 ReadStackIndexHeader(iStack);
300 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
302 // read the data for the next chamber
303 // in case you only want to read the data of a single chamber
304 // to read all data ReadEvent(...) is recommended
306 fDigitsManager = digMgr;
309 // tracklet output preparation
310 TTree *trklTree = 0x0;
311 AliRunLoader *rl = AliRunLoader::Instance();
312 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
313 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
315 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
317 trklTree = trklTreeLoader->Tree();
319 trklTree = trklLoader->Tree();
322 if (fTrackletTree != trklTree)
323 ConnectTracklets(trklTree);
326 AliError("No raw reader available");
330 if (fCurrSlot < 0 || fCurrSlot >= 5) {
337 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
338 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
340 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
341 LinkError(kLinkMonitor);
343 // read the data from one HC
346 // read all data endmarkers
347 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
348 *fPayloadCurr == fgkDataEndmarker)
351 if (fCurrLink % 2 == 0) {
352 // if we just read the A-side HC then also check the B-side
355 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
357 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
358 *fPayloadCurr == fgkDataEndmarker)
366 if (fCurrLink > 11) {
370 } while ((fCurrSlot < 5) &&
371 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
372 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
374 return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
378 Int_t AliTRDrawStream::ReadSmHeader()
380 // read the SMU index header at the current reading position
381 // and store the information in the corresponding variables
383 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
384 AliError(EquipmentError(kUnknown, "SM Header incomplete"));
388 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
389 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
390 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
391 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
392 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
394 AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
395 fCurrSmuIndexHeaderSize,
396 fCurrSmuIndexHeaderVersion,
401 fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
403 return fCurrSmuIndexHeaderSize + 1;
406 Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
408 // read the stack index header
409 // and store the information in the corresponding variables
411 fCurrStackIndexWord[stack] = *fPayloadCurr;
412 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
413 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
414 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
416 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
417 AliError(StackError(kStackHeaderInvalid, "Stack index header aborted"));
421 switch (fCurrStackHeaderVersion[stack]) {
423 if (fCurrStackHeaderSize[stack] < 8) {
424 AliError(StackError(kStackHeaderInvalid, "Stack header smaller than expected!"));
428 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
429 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
430 fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
432 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
434 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
435 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
436 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
438 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
439 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
440 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
445 AliError(StackError(kStackHeaderInvalid, Form("Invalid Stack Index Header version %x",
446 fCurrStackHeaderVersion[stack])));
449 fPayloadCurr += fCurrStackHeaderSize[stack];
451 return fCurrStackHeaderSize[stack];
454 Int_t AliTRDrawStream::ReadLinkData()
456 // read the data in one link (one HC) until the data endmarker is reached
457 // returns the number of words read!
460 UInt_t* startPosLink = fPayloadCurr;
462 // printf("----- HC: %i -----\n", fCurrHC);
463 // for (Int_t i = 0; i < 3; i++) {
464 // printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
465 // fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
468 count += ReadTracklets();
470 count += ReadHcHeader();
472 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
474 if (det > -1 && det < 540) {
476 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
477 //fAdcArray->Expand();
478 if (fAdcArray->GetNtime() != fCurrNtimebins)
479 fAdcArray->Allocate(16, 144, fCurrNtimebins);
482 AliError(LinkError(kNoDigits));
486 fDigitsParam = fDigitsManager->GetDigitsParam();
489 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
490 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
491 fDigitsParam->SetADCbaseline(det, 10);
494 if (fDigitsManager->UsesDictionaries()) {
495 fDigitsManager->GetDictionary(det, 0)->Reset();
496 fDigitsManager->GetDictionary(det, 1)->Reset();
497 fDigitsManager->GetDictionary(det, 2)->Reset();
500 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
501 fSignalIndex->SetSM(fCurrSm);
502 fSignalIndex->SetStack(fCurrStack);
503 fSignalIndex->SetLayer(fCurrLayer);
504 fSignalIndex->SetDetNumber(det);
505 if (!fSignalIndex->IsAllocated())
506 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
509 // ----- check which kind of data -----
510 if (fCurrMajor & 0x40) {
511 if ((fCurrMajor & 0x7) == 0x7) {
512 AliDebug(1, "This is a config event");
513 UInt_t *startPos = fPayloadCurr;
514 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
515 *fPayloadCurr != fgkDataEndmarker)
517 count += fPayloadCurr - startPos;
519 // feeding TRAP config
520 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
521 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
524 Int_t tpmode = fCurrMajor & 0x7;
525 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
529 else if (fCurrMajor & 0x20) {
530 AliDebug(1, "This is a zs event");
531 count += ReadZSData();
534 AliDebug(1, "This is a nozs event");
535 count += ReadNonZSData();
539 AliError(LinkError(kInvalidDetector, Form("%i", det)));
540 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
541 *fPayloadCurr != fgkDataEndmarker)
545 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
546 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
547 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
548 fStats.fBytesRead += count * sizeof(UInt_t);
553 Int_t AliTRDrawStream::ReadTracklets()
555 // read the tracklets from one HC
557 fTrackletArray->Clear();
559 UInt_t *start = fPayloadCurr;
560 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
561 fPayloadCurr - fPayloadStart < fPayloadSize) {
563 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr));
568 if (fTrackletArray->GetEntriesFast() > 0) {
569 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
570 fCurrSm, fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
571 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
572 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
574 fTrackletTree->Fill();
577 // loop over remaining tracklet endmarkers
578 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
579 fPayloadCurr - fPayloadStart < fPayloadSize))
582 return fPayloadCurr - start;
585 Int_t AliTRDrawStream::ReadHcHeader()
587 // read and parse the HC header of one HC
588 // and store the information in the corresponding variables
590 UInt_t *start = fPayloadCurr;
591 // check not to be at the data endmarker
592 if (*fPayloadCurr == fgkDataEndmarker)
595 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
596 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
597 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
598 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
599 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
600 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
601 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
602 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
603 fCurrCheck = (*fPayloadCurr) & 0x3;
605 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
606 fCurrStack != fCurrSlot ||
607 fCurrLayer != fCurrLink / 2 ||
608 fCurrSide != fCurrLink % 2) {
609 AliError(LinkError(kHCmismatch,
610 Form("HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
611 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
612 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]) ));
614 if (fCurrCheck != 0x1) {
615 AliError(LinkError(kHCcheckFailed));
618 if (fCurrAddHcWords > 0) {
619 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
620 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
621 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
622 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
625 fPayloadCurr += 1 + fCurrAddHcWords;
627 return (fPayloadCurr - start) / sizeof(UInt_t);
630 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
632 // testing of testpattern 1 to 3 (hardcoded), 0 missing
633 // evcnt checking missing
635 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
640 Int_t channelcount = 0;
642 UInt_t expadcval = 0;
644 Int_t lastmcmpos = -1;
645 Int_t lastrobpos = -1;
647 UInt_t* start = fPayloadCurr;
649 while (*(fPayloadCurr) != fgkDataEndmarker &&
650 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
652 // ----- Checking MCM Header -----
653 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
656 // ----- checking for proper readout order - ROB -----
657 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
658 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
661 AliError(ROBError(kPosUnexp));
663 fCurrRobPos = ROB(*fPayloadCurr);
665 // ----- checking for proper readout order - MCM -----
666 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
667 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
670 AliError(MCMError(kPosUnexp));
672 fCurrMcmPos = MCM(*fPayloadCurr);
677 evcnt = 0x3f & *fPayloadCurr >> 26;
680 while (channelcount < 21) {
682 if (cpu != cpufromchannel[channelcount]) {
683 cpu = cpufromchannel[channelcount];
684 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
689 if (channelcount % 2 == 0)
696 expword |= expadcval << 2;
697 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
698 expword |= expadcval << 12;
699 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
700 expword |= expadcval << 22;
701 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
703 else if (mode == 2) {
705 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
706 ((fCurrStack + 1) << 15) |
707 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
709 else if (mode == 3) {
711 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
712 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
716 AliError(LinkError(kTPmodeInvalid, "Just reading"));
719 diff = *fPayloadCurr ^ expword;
721 AliError(MCMError(kTPmismatch,
722 Form("Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
723 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24)) ));
731 // continue with next MCM
733 return fPayloadCurr - start;
737 Int_t AliTRDrawStream::ReadZSData()
739 // read the zs data from one link from the current reading position
741 UInt_t *start = fPayloadCurr;
744 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
745 Int_t channelcount = 0;
746 Int_t channelcountExp = 0;
747 Int_t channelcountMax = 0;
749 Int_t currentTimebin = 0;
752 Int_t lastmcmpos = -1;
753 Int_t lastrobpos = -1;
755 if (fCurrNtimebins != fNtimebins) {
757 AliError(LinkError(kNtimebinsChanged,
758 Form("No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins) ));
759 fNtimebins = fCurrNtimebins;
762 timebins = fNtimebins;
764 while (*(fPayloadCurr) != fgkDataEndmarker &&
765 fPayloadCurr - fPayloadStart < fPayloadSize) {
767 // ----- Checking MCM Header -----
768 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
769 UInt_t *startPosMCM = fPayloadCurr;
771 // ----- checking for proper readout order - ROB -----
772 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
773 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
776 AliError(ROBError(kPosUnexp));
778 fCurrRobPos = ROB(*fPayloadCurr);
780 // ----- checking for proper readout order - MCM -----
781 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
782 lastmcmpos = GetMCMReadoutPos(lastmcmpos);
785 AliError(MCMError(kPosUnexp));
787 fCurrMcmPos = MCM(*fPayloadCurr);
789 if (EvNo(*fPayloadCurr) != evno) {
791 evno = EvNo(*fPayloadCurr);
793 AliDebug(1, MCMError(kPtrgCntMismatch,
794 Form("%i <-> %i", evno, EvNo(*fPayloadCurr)) ));
797 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
798 Int_t padcoloff = PadColOffset(*fPayloadCurr);
799 Int_t row = Row(*fPayloadCurr);
802 // ----- Reading ADC channels -----
803 AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
805 // ----- analysing the ADC mask -----
807 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
808 channelcountMax = GetNActiveChannels(*fPayloadCurr);
809 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
810 Int_t channelno = -1;
813 if (channelcountExp != channelcountMax) {
814 if (channelcountExp > channelcountMax) {
815 Int_t temp = channelcountExp;
816 channelcountExp = channelcountMax;
817 channelcountMax = temp;
819 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
820 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
821 AliDebug(1, MCMError(kAdcMaskInconsistent,
822 Form("Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
823 *(fPayloadCurr + 10 * channelcountExp),
824 *(fPayloadCurr + 10 * channelcountExp + 1) ) ));
825 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
831 AliDebug(1, MCMError(kAdcMaskInconsistent,
832 Form("Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
833 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp) ));
835 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
837 // ----- reading marked ADC channels -----
838 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
841 while (channelno < 21 && (channelmask & 1 << channelno) == 0)
844 if (fCurrNtimebins > 30) {
845 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
846 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
853 AliDebug(2, Form("Now looking %i words", timebins / 3));
854 Int_t adccol = adccoloff - channelno;
855 Int_t padcol = padcoloff - channelno;
856 // if (adccol < 3 || adccol > 165)
857 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
858 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
860 while (adcwc < timebins / 3 &&
861 *(fPayloadCurr) != fgkDataEndmarker &&
862 fPayloadCurr - fPayloadStart < fPayloadSize) {
863 int check = 0x3 & *fPayloadCurr;
864 if (channelno % 2 != 0) { // odd channel
865 if (check != 0x2 && channelno < 21) {
866 AliError(MCMError(kAdcCheckInvalid,
867 Form("%i for %2i. ADC word in odd channel %i",
868 check, adcwc+1, channelno) ));
871 else { // even channel
872 if (check != 0x3 && channelno < 21) {
873 AliError(MCMError(kAdcCheckInvalid,
874 Form("%i for %2i. ADC word in even channel %i",
875 check, adcwc+1, channelno) ));
879 // filling the actual timebin data
880 int tb2 = 0x3ff & *fPayloadCurr >> 22;
881 int tb1 = 0x3ff & *fPayloadCurr >> 12;
882 int tb0 = 0x3ff & *fPayloadCurr >> 2;
883 if (adcwc != 0 || fCurrNtimebins <= 30)
884 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
887 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
888 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
894 if (adcwc != timebins / 3)
895 AliError(MCMError(kAdcDataAbort));
898 if (padcol > 0 && padcol < 144) {
899 fSignalIndex->AddIndexRC(row, padcol);
905 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
906 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
907 if (channelcount != channelcountExp)
908 AliDebug(1, MCMError(kAdcChannelsMiss));
911 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
912 fStats.fStatsSector[fCurrSm].fNMCMs++;
914 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
915 DumpRaw(Form("Det %3i ROB %i MCM %2i", fCurrHC/2, fCurrRobPos, fCurrMcmPos),
916 startPosMCM, fPayloadCurr - startPosMCM);
919 // continue with next MCM
922 // check for missing MCMs (if header suppression is inactive)
923 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
924 AliError(LinkError(kMissMcmHeaders,
925 Form("No. of MCM headers %i not as expected: %i",
926 mcmcount, mcmcountExp) ));
929 return (fPayloadCurr - start);
932 Int_t AliTRDrawStream::ReadNonZSData()
934 // read the non-zs data from one link from the current reading position
936 UInt_t *start = fPayloadCurr;
939 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
940 Int_t channelcount = 0;
941 Int_t channelcountExp = 0;
943 Int_t currentTimebin = 0;
946 Int_t lastmcmpos = -1;
947 Int_t lastrobpos = -1;
949 if (fCurrNtimebins != fNtimebins) {
951 AliError(LinkError(kNtimebinsChanged,
952 Form("No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins) ));
953 fNtimebins = fCurrNtimebins;
956 timebins = fNtimebins;
958 while (*(fPayloadCurr) != fgkDataEndmarker &&
959 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
961 // ----- Checking MCM Header -----
962 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
964 // ----- checking for proper readout order - ROB -----
965 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
966 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
969 AliError(ROBError(kPosUnexp));
971 fCurrRobPos = ROB(*fPayloadCurr);
973 // ----- checking for proper readout order - MCM -----
974 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
975 lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
978 AliError(MCMError(kPosUnexp));
980 fCurrMcmPos = MCM(*fPayloadCurr);
982 if (EvNo(*fPayloadCurr) != evno) {
984 evno = EvNo(*fPayloadCurr);
986 AliDebug(1, MCMError(kPtrgCntMismatch,
987 Form("%i <-> %i", evno, EvNo(*fPayloadCurr)) ));
992 channelcountExp = 21;
995 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
996 Int_t padcoloff = PadColOffset(*fPayloadCurr);
997 Int_t row = Row(*fPayloadCurr);
1001 // ----- reading marked ADC channels -----
1002 while (channelcount < channelcountExp &&
1003 *(fPayloadCurr) != fgkDataEndmarker) {
1010 AliDebug(2, Form("Now looking %i words", timebins / 3));
1011 Int_t adccol = adccoloff - channelno;
1012 Int_t padcol = padcoloff - channelno;
1013 while (adcwc < timebins / 3 &&
1014 *(fPayloadCurr) != fgkDataEndmarker &&
1015 fPayloadCurr - fPayloadStart < fPayloadSize) {
1016 int check = 0x3 & *fPayloadCurr;
1017 if (channelno % 2 != 0) { // odd channel
1018 if (check != 0x2 && channelno < 21) {
1019 AliError(MCMError(kAdcCheckInvalid,
1020 Form("%i for %2i. ADC word in odd channel %i",
1021 check, adcwc+1, channelno) ));
1024 else { // even channel
1025 if (check != 0x3 && channelno < 21) {
1026 AliError(MCMError(kAdcCheckInvalid,
1027 Form("%i for %2i. ADC word in even channel %i",
1028 check, adcwc+1, channelno) ));
1032 // filling the actual timebin data
1033 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1034 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1035 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1036 if (adcwc != 0 || fCurrNtimebins <= 30)
1037 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1040 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1041 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1047 if (adcwc != timebins / 3)
1048 AliError(MCMError(kAdcDataAbort));
1051 if (padcol > 0 && padcol < 144) {
1052 fSignalIndex->AddIndexRC(row, padcol);
1058 if (channelcount != channelcountExp)
1059 AliDebug(1, MCMError(kAdcChannelsMiss));
1061 // continue with next MCM
1064 // check for missing MCMs (if header suppression is inactive)
1065 if (mcmcount != mcmcountExp) {
1066 AliError(LinkError(kMissMcmHeaders,
1067 Form("%i not as expected: %i", mcmcount, mcmcountExp) ));
1070 return (fPayloadCurr - start);
1073 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1075 fTrackletTree = trklTree;
1079 if (!fTrackletTree->GetBranch("hc"))
1080 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1082 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1084 if (!fTrackletTree->GetBranch("trkl"))
1085 fTrackletTree->Branch("trkl", &fTrackletArray);
1087 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1093 TString AliTRDrawStream::EquipmentError(ErrorCode_t err, TString msg)
1095 // register error according to error code on equipment level
1096 // and return the corresponding error message
1098 fLastError.fSector = fCurrEquipmentId - 1024;
1099 fLastError.fStack = -1;
1100 fLastError.fLink = -1;
1101 fLastError.fRob = -1;
1102 fLastError.fMcm = -1;
1103 fLastError.fError = err;
1106 return (Form("Event %6i: Eq. %2d - %s : ",
1107 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err]) + msg);
1111 TString AliTRDrawStream::StackError(ErrorCode_t err, TString msg)
1113 // register error according to error code on stack level
1114 // and return the corresponding error message
1116 fLastError.fSector = fCurrEquipmentId - 1024;
1117 fLastError.fStack = fCurrSlot;
1118 fLastError.fLink = -1;
1119 fLastError.fRob = -1;
1120 fLastError.fMcm = -1;
1121 fLastError.fError = err;
1124 return (Form("Event %6i: Eq. %2d S %i - %s : ",
1125 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err]) + msg);
1129 TString AliTRDrawStream::LinkError(ErrorCode_t err, TString msg)
1131 // register error according to error code on link level
1132 // and return the corresponding error message
1134 fLastError.fSector = fCurrEquipmentId - 1024;
1135 fLastError.fStack = fCurrSlot;
1136 fLastError.fLink = fCurrLink;
1137 fLastError.fRob = -1;
1138 fLastError.fMcm = -1;
1139 fLastError.fError = err;
1142 return (Form("Event %6i: Eq. %2d S %i l %2i - %s : ",
1143 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err]) + msg);
1147 TString AliTRDrawStream::ROBError(ErrorCode_t err, TString msg)
1149 // register error according to error code on ROB level
1150 // and return the corresponding error message
1152 fLastError.fSector = fCurrEquipmentId - 1024;
1153 fLastError.fStack = fCurrSlot;
1154 fLastError.fLink = fCurrLink;
1155 fLastError.fRob = fCurrRobPos;
1156 fLastError.fMcm = -1;
1157 fLastError.fError = err;
1160 return (Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : ",
1161 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err]) + msg);
1165 TString AliTRDrawStream::MCMError(ErrorCode_t err, TString msg)
1167 // register error according to error code on MCM level
1168 // and return the corresponding error message
1170 fLastError.fSector = fCurrEquipmentId - 1024;
1171 fLastError.fStack = fCurrSlot;
1172 fLastError.fLink = fCurrLink;
1173 fLastError.fRob = fCurrRobPos;
1174 fLastError.fMcm = fCurrMcmPos;
1175 fLastError.fError = err;
1178 return (Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : ",
1179 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err]) + msg);
1182 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1184 // return the error message for the given error code
1186 if (errCode > 0 && errCode < kLastErrorCode)
1187 return fgErrorMessages[errCode];
1192 void AliTRDrawStream::AliTRDrawStats::ClearStats()
1194 // clear statistics (includes clearing sector-wise statistics)
1197 for (Int_t iSector = 0; iSector < 18; iSector++) {
1198 fStatsSector[iSector].ClearStats();
1203 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1205 // clear statistics (includes clearing HC-wise statistics)
1213 for (Int_t iHC = 0; iHC < 60; iHC++) {
1214 fStatsHC[iHC].ClearStats();
1218 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1229 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1231 // mark MCM for dumping of raw data
1234 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
1238 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1239 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1244 for ( ; iMCM < fNDumpMCMs; iMCM++) {
1245 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1250 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm)
1252 // check if MCM data should be dumped
1254 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1255 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1262 void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
1268 for ( ; pos+3 < length; pos += 4) {
1269 title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n",
1270 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1272 for ( ; pos < length; pos++) {
1273 title += Form("0x%08x ", start[pos]);