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 ////////////////////////////////////////////////////////////////////////////
28 #include "TClonesArray.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 "AliTreeLoader.h"
42 #include "AliTRDrawStream.h"
45 #include "AliRunLoader.h"
47 ClassImp(AliTRDrawStream)
49 // some static information
50 const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
54 const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
55 const Int_t AliTRDrawStream::fgkNlinks = 12;
56 const Int_t AliTRDrawStream::fgkNstacks = 5;
57 const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
58 const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
60 const char* AliTRDrawStream::fgErrorMessages[] = {
62 "Link monitor active",
63 "Pretrigger counter mismatch",
64 "not a TRD equipment (1024-1041)",
65 "Invalid Stack header",
66 "Invalid detector number",
67 "No digits could be retrieved from the digitsmanager",
69 "HC check bits wrong",
70 "Unexpected position in readout stream",
71 "Invalid testpattern mode",
72 "Testpattern mismatch",
73 "Number of timebins changed",
74 "ADC mask inconsistent",
75 "ADC check bits invalid",
77 "Missing expected ADC channels",
81 const Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
102 AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
103 AliTRDrawStream::kTolerate,
104 AliTRDrawStream::kDiscardHC,
105 AliTRDrawStream::kTolerate,
106 AliTRDrawStream::kAbort,
107 AliTRDrawStream::kAbort,
108 AliTRDrawStream::kAbort,
109 AliTRDrawStream::kAbort,
110 AliTRDrawStream::kDiscardHC,
111 AliTRDrawStream::kDiscardHC,
112 AliTRDrawStream::kTolerate,
113 AliTRDrawStream::kTolerate,
114 AliTRDrawStream::kTolerate,
115 AliTRDrawStream::kTolerate,
116 AliTRDrawStream::kTolerate,
117 AliTRDrawStream::kTolerate,
118 AliTRDrawStream::kTolerate,
119 AliTRDrawStream::kTolerate,
120 AliTRDrawStream::kTolerate
123 AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
125 fRawReader(rawReader),
141 fCurrSmuIndexHeaderSize(0),
142 fCurrSmuIndexHeaderVersion(0),
144 fCurrTrackletEnable(0),
146 fCurrStackIndexWord(0x0),
147 fCurrStackHeaderSize(0x0),
148 fCurrStackHeaderVersion(0x0),
150 fCurrCleanCheckout(0x0),
153 fCurrLinkMonitorFlags(0x0),
154 fCurrLinkDataTypeFlags(0x0),
155 fCurrLinkDebugFlags(0x0),
176 // default constructor
178 fCurrStackIndexWord = new UInt_t[fgkNstacks];
179 fCurrStackHeaderSize = new UInt_t[fgkNstacks];
180 fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
181 fCurrLinkMask = new UInt_t[fgkNstacks];
182 fCurrCleanCheckout = new UInt_t[fgkNstacks];
183 fCurrBoardId = new UInt_t[fgkNstacks];
184 fCurrHwRev = new UInt_t[fgkNstacks];
185 fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
186 fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
187 fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
189 // preparing TClonesArray
190 fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
192 // setting up the error tree
193 fErrors = new TTree("errorStats", "Error statistics");
194 fErrors->SetDirectory(0x0);
195 fErrors->Branch("error", &fLastError, "sector/I:stack:link:error:rob:mcm");
196 fErrors->SetCircular(1000);
199 AliTRDrawStream::~AliTRDrawStream()
205 delete [] fCurrStackIndexWord;
206 delete [] fCurrStackHeaderSize;
207 delete [] fCurrStackHeaderVersion;
208 delete [] fCurrLinkMask;
209 delete [] fCurrCleanCheckout;
210 delete [] fCurrBoardId;
211 delete [] fCurrHwRev;
212 delete [] fCurrLinkMonitorFlags;
213 delete [] fCurrLinkDataTypeFlags;
214 delete [] fCurrLinkDebugFlags;
217 Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
219 // read the current event from the raw reader and fill it to the digits manager
222 AliError("No raw reader available");
227 ConnectTracklets(trackletTree);
232 // loop over all DDLs
233 // data starts with GTU payload, i.e. SMU index word
234 UChar_t *buffer = 0x0;
236 while (fRawReader->ReadNextData(buffer)) {
238 fCurrEquipmentId = fRawReader->GetEquipmentId();
239 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
241 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
242 EquipmentError(kNonTrdEq, "Skipping");
246 // setting the pointer to data and current reading position
247 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
248 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
249 fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
250 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
252 // read SMU index header
253 if (ReadSmHeader() < 0) {
254 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
258 // read stack index header
259 for (Int_t iStack = 0; iStack < 5; iStack++) {
260 if ((fCurrStackMask & (1 << iStack)) != 0)
261 ReadStackIndexHeader(iStack);
264 for (Int_t iStack = 0; iStack < 5; iStack++) {
266 if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
269 AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
270 for (Int_t iLink = 0; iLink < 12; iLink++) {
272 fCurrHC = fCurrSm * 60 + fCurrSlot * 12 + iLink;
273 if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
277 // check for link monitor error flag
278 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
279 LinkError(kLinkMonitor);
281 // read the data from one HC
284 // read all data endmarkers
293 Bool_t AliTRDrawStream::NextDDL()
295 // continue reading with the next equipment
300 fCurrEquipmentId = 0;
304 UChar_t *buffer = 0x0;
306 while (fRawReader->ReadNextData(buffer)) {
308 fCurrEquipmentId = fRawReader->GetEquipmentId();
309 AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
311 if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
312 EquipmentError(kNonTrdEq, "Skipping");
316 // setting the pointer to data and current reading position
317 fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
318 fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
319 AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
321 // read SMU index header
322 if (ReadSmHeader() < 0) {
323 AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
327 // read stack index header
328 for (Int_t iStack = 0; iStack < 5; iStack++) {
329 if ((fCurrStackMask & (1 << iStack)) != 0) {
330 ReadStackIndexHeader(iStack);
340 Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
342 // read the data for the next chamber
343 // in case you only want to read the data of a single chamber
344 // to read all data ReadEvent(...) is recommended
346 fDigitsManager = digMgr;
351 // tracklet output preparation
352 TTree *trklTree = 0x0;
353 AliRunLoader *rl = AliRunLoader::Instance();
354 AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
355 AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
357 AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
359 trklTree = trklTreeLoader->Tree();
361 trklTree = trklLoader->Tree();
364 if (fTrackletTree != trklTree)
365 ConnectTracklets(trklTree);
368 AliError("No raw reader available");
372 if (fCurrSlot < 0 || fCurrSlot >= 5) {
379 AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
380 fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
382 if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0)
383 LinkError(kLinkMonitor);
385 // read the data from one HC
388 // read all data endmarkers
391 if (fCurrLink % 2 == 0) {
392 // if we just read the A-side HC then also check the B-side
395 if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
404 if (fCurrLink > 11) {
408 } while ((fCurrSlot < 5) &&
409 (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
410 ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
412 return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
416 Int_t AliTRDrawStream::ReadSmHeader()
418 // read the SMU index header at the current reading position
419 // and store the information in the corresponding variables
421 if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
422 EquipmentError(kUnknown, "SM Header incomplete");
426 fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
427 fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
428 fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
429 fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
430 fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
432 AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
433 fCurrSmuIndexHeaderSize,
434 fCurrSmuIndexHeaderVersion,
439 fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
441 return fCurrSmuIndexHeaderSize + 1;
444 Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
446 // read the stack index header
447 // and store the information in the corresponding variables
449 fCurrStackIndexWord[stack] = *fPayloadCurr;
450 fCurrStackHeaderSize[stack] = (((*fPayloadCurr) >> 16) & 0xffff) + 1;
451 fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
452 fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
454 if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
455 StackError(kStackHeaderInvalid, "Stack index header aborted");
459 switch (fCurrStackHeaderVersion[stack]) {
461 if (fCurrStackHeaderSize[stack] < 8) {
462 StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
466 fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
467 fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
468 fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
470 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
472 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
473 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
474 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
476 fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
477 fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
478 fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
483 StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
486 fPayloadCurr += fCurrStackHeaderSize[stack];
488 return fCurrStackHeaderSize[stack];
491 Int_t AliTRDrawStream::ReadLinkData()
493 // read the data in one link (one HC) until the data endmarker is reached
494 // returns the number of words read!
497 UInt_t* startPosLink = fPayloadCurr;
499 // printf("----- HC: %i -----\n", fCurrHC);
500 // for (Int_t i = 0; i < 3; i++) {
501 // printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
502 // fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
505 if (fErrorFlags & kDiscardHC)
508 count += ReadTracklets();
509 if (fErrorFlags & kDiscardHC)
512 count += ReadHcHeader();
513 if (fErrorFlags & kDiscardHC)
516 Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
518 if (det > -1 && det < 540) {
520 if ((fAdcArray = fDigitsManager->GetDigits(det))) {
521 //fAdcArray->Expand();
522 if (fAdcArray->GetNtime() != fCurrNtimebins)
523 fAdcArray->Allocate(16, 144, fCurrNtimebins);
526 LinkError(kNoDigits);
530 fDigitsParam = fDigitsManager->GetDigitsParam();
533 fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
534 fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
535 fDigitsParam->SetADCbaseline(det, 10);
538 if (fDigitsManager->UsesDictionaries()) {
539 fDigitsManager->GetDictionary(det, 0)->Reset();
540 fDigitsManager->GetDictionary(det, 1)->Reset();
541 fDigitsManager->GetDictionary(det, 2)->Reset();
544 if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
545 fSignalIndex->SetSM(fCurrSm);
546 fSignalIndex->SetStack(fCurrStack);
547 fSignalIndex->SetLayer(fCurrLayer);
548 fSignalIndex->SetDetNumber(det);
549 if (!fSignalIndex->IsAllocated())
550 fSignalIndex->Allocate(16, 144, fCurrNtimebins);
553 // ----- check which kind of data -----
554 if (fCurrMajor & 0x40) {
555 if ((fCurrMajor & 0x7) == 0x7) {
556 AliDebug(1, "This is a config event");
557 UInt_t *startPos = fPayloadCurr;
558 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
559 *fPayloadCurr != fgkDataEndmarker)
561 count += fPayloadCurr - startPos;
563 // feeding TRAP config
564 AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
565 trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
568 Int_t tpmode = fCurrMajor & 0x7;
569 AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
573 else if (fCurrMajor & 0x20) {
574 AliDebug(1, "This is a zs event");
575 count += ReadZSData();
578 AliDebug(1, "This is a nozs event");
579 count += ReadNonZSData();
583 LinkError(kInvalidDetector, "%i", det);
584 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
585 *fPayloadCurr != fgkDataEndmarker)
589 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytes += (fPayloadCurr - startPosLink) * sizeof(UInt_t);
590 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fBytesRead += count * sizeof(UInt_t);
591 fStats.fStatsSector[fCurrSm].fBytesRead += count * sizeof(UInt_t);
592 fStats.fBytesRead += count * sizeof(UInt_t);
597 Int_t AliTRDrawStream::ReadTracklets()
599 // read the tracklets from one HC
601 fTrackletArray->Clear();
603 UInt_t *start = fPayloadCurr;
604 while (*(fPayloadCurr) != fgkTrackletEndmarker &&
605 fPayloadCurr - fPayloadStart < fPayloadSize) {
607 new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr));
612 if (fTrackletArray->GetEntriesFast() > 0) {
613 AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
614 fCurrSm, fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
615 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
616 fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
618 fTrackletTree->Fill();
621 // loop over remaining tracklet endmarkers
622 while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
623 fPayloadCurr - fPayloadStart < fPayloadSize))
626 return fPayloadCurr - start;
629 Int_t AliTRDrawStream::ReadHcHeader()
631 // read and parse the HC header of one HC
632 // and store the information in the corresponding variables
634 UInt_t *start = fPayloadCurr;
635 // check not to be at the data endmarker
636 if (*fPayloadCurr == fgkDataEndmarker)
639 fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
640 fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
641 fCurrMinor = (*fPayloadCurr >> 17) & 0x7f;
642 fCurrAddHcWords = (*fPayloadCurr >> 14) & 0x7;
643 fCurrSm = (*fPayloadCurr >> 9) & 0x1f;
644 fCurrLayer = (*fPayloadCurr >> 6) & 0x7;
645 fCurrStack = (*fPayloadCurr >> 3) & 0x7;
646 fCurrSide = (*fPayloadCurr >> 2) & 0x1;
647 fCurrCheck = (*fPayloadCurr) & 0x3;
649 if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
650 fCurrStack != fCurrSlot ||
651 fCurrLayer != fCurrLink / 2 ||
652 fCurrSide != fCurrLink % 2) {
653 LinkError(kHCmismatch,
654 "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
655 fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
656 fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);;
658 if (fCurrCheck != 0x1) {
659 LinkError(kHCcheckFailed);
662 if (fCurrAddHcWords > 0) {
663 fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
664 fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
665 fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
666 fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
669 fPayloadCurr += 1 + fCurrAddHcWords;
671 return (fPayloadCurr - start) / sizeof(UInt_t);
674 Int_t AliTRDrawStream::ReadTPData(Int_t mode)
676 // testing of testpattern 1 to 3 (hardcoded), 0 missing
677 // evcnt checking missing
679 Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
684 Int_t channelcount = 0;
686 UInt_t expadcval = 0;
688 Int_t lastmcmpos = -1;
689 Int_t lastrobpos = -1;
691 UInt_t* start = fPayloadCurr;
693 while (*(fPayloadCurr) != fgkDataEndmarker &&
694 fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
696 // ----- Checking MCM Header -----
697 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
700 // ----- checking for proper readout order - ROB -----
701 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
702 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
707 fCurrRobPos = ROB(*fPayloadCurr);
709 // ----- checking for proper readout order - MCM -----
710 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
711 lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
716 fCurrMcmPos = MCM(*fPayloadCurr);
721 evcnt = 0x3f & *fPayloadCurr >> 26;
724 while (channelcount < 21) {
726 if (cpu != cpufromchannel[channelcount]) {
727 cpu = cpufromchannel[channelcount];
728 expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
733 if (channelcount % 2 == 0)
740 expword |= expadcval << 2;
741 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
742 expword |= expadcval << 12;
743 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
744 expword |= expadcval << 22;
745 expadcval = ( (expadcval << 1) | ( ( (expadcval >> 9) ^ (expadcval >> 6) ) & 1) ) & 0x3FF;
747 else if (mode == 2) {
749 expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
750 ((fCurrStack + 1) << 15) |
751 (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
753 else if (mode == 3) {
755 expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
756 (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
760 LinkError(kTPmodeInvalid, "Just reading");
763 diff = *fPayloadCurr ^ expword;
765 MCMError(kTPmismatch,
766 "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
767 *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
775 // continue with next MCM
777 return fPayloadCurr - start;
781 Int_t AliTRDrawStream::ReadZSData()
783 // read the zs data from one link from the current reading position
785 UInt_t *start = fPayloadCurr;
788 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
789 Int_t channelcount = 0;
790 Int_t channelcountExp = 0;
791 Int_t channelcountMax = 0;
793 Int_t currentTimebin = 0;
796 Int_t lastmcmpos = -1;
797 Int_t lastrobpos = -1;
799 if (fCurrNtimebins != fNtimebins) {
801 LinkError(kNtimebinsChanged,
802 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
803 fNtimebins = fCurrNtimebins;
806 timebins = fNtimebins;
808 while (*(fPayloadCurr) != fgkDataEndmarker &&
809 fPayloadCurr - fPayloadStart < fPayloadSize) {
811 // ----- Checking MCM Header -----
812 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
813 UInt_t *startPosMCM = fPayloadCurr;
815 // ----- checking for proper readout order - ROB -----
816 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
817 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
822 fCurrRobPos = ROB(*fPayloadCurr);
824 // ----- checking for proper readout order - MCM -----
825 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
826 lastmcmpos = GetMCMReadoutPos(lastmcmpos);
831 fCurrMcmPos = MCM(*fPayloadCurr);
833 if (EvNo(*fPayloadCurr) != evno) {
835 evno = EvNo(*fPayloadCurr);
837 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
840 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
841 Int_t padcoloff = PadColOffset(*fPayloadCurr);
842 Int_t row = Row(*fPayloadCurr);
845 // ----- Reading ADC channels -----
846 AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
848 // ----- analysing the ADC mask -----
850 channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
851 channelcountMax = GetNActiveChannels(*fPayloadCurr);
852 Int_t channelmask = GetActiveChannels(*fPayloadCurr);
853 Int_t channelno = -1;
856 if (channelcountExp != channelcountMax) {
857 if (channelcountExp > channelcountMax) {
858 Int_t temp = channelcountExp;
859 channelcountExp = channelcountMax;
860 channelcountMax = temp;
862 while (channelcountExp < channelcountMax && channelcountExp < 21 &&
863 fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
864 MCMError(kAdcMaskInconsistent,
865 "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
866 *(fPayloadCurr + 10 * channelcountExp),
867 *(fPayloadCurr + 10 * channelcountExp + 1) );
868 if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
874 MCMError(kAdcMaskInconsistent,
875 "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
876 GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
878 AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
880 // ----- reading marked ADC channels -----
881 while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
884 while (channelno < 20 && (channelmask & 1 << channelno) == 0)
887 if (fCurrNtimebins > 30) {
888 currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
889 timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
896 AliDebug(2, Form("Now looking %i words", timebins / 3));
897 Int_t adccol = adccoloff - channelno;
898 Int_t padcol = padcoloff - channelno;
899 // if (adccol < 3 || adccol > 165)
900 // AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
901 // channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
903 while (adcwc < timebins / 3 &&
904 *(fPayloadCurr) != fgkDataEndmarker &&
905 fPayloadCurr - fPayloadStart < fPayloadSize) {
906 int check = 0x3 & *fPayloadCurr;
907 if (channelno % 2 != 0) { // odd channel
908 if (check != 0x2 && channelno < 21) {
909 MCMError(kAdcCheckInvalid,
910 "%i for %2i. ADC word in odd channel %i",
911 check, adcwc+1, channelno);
914 else { // even channel
915 if (check != 0x3 && channelno < 21) {
916 MCMError(kAdcCheckInvalid,
917 "%i for %2i. ADC word in even channel %i",
918 check, adcwc+1, channelno);
922 // filling the actual timebin data
923 int tb2 = 0x3ff & *fPayloadCurr >> 22;
924 int tb1 = 0x3ff & *fPayloadCurr >> 12;
925 int tb0 = 0x3ff & *fPayloadCurr >> 2;
926 if (adcwc != 0 || fCurrNtimebins <= 30)
927 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
930 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
931 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
937 if (adcwc != timebins / 3)
938 MCMError(kAdcDataAbort);
941 if (padcol > 0 && padcol < 144) {
942 fSignalIndex->AddIndexRC(row, padcol);
948 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNChannels += channelcount;
949 fStats.fStatsSector[fCurrSm].fNChannels += channelcount;
950 if (channelcount != channelcountExp)
951 MCMError(kAdcChannelsMiss);
954 fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
955 fStats.fStatsSector[fCurrSm].fNMCMs++;
957 if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
958 DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
959 startPosMCM, fPayloadCurr - startPosMCM);
962 // continue with next MCM
965 // check for missing MCMs (if header suppression is inactive)
966 if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
967 LinkError(kMissMcmHeaders,
968 "No. of MCM headers %i not as expected: %i",
969 mcmcount, mcmcountExp);
972 return (fPayloadCurr - start);
975 Int_t AliTRDrawStream::ReadNonZSData()
977 // read the non-zs data from one link from the current reading position
979 UInt_t *start = fPayloadCurr;
982 Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
983 Int_t channelcount = 0;
984 Int_t channelcountExp = 0;
986 Int_t currentTimebin = 0;
989 Int_t lastmcmpos = -1;
990 Int_t lastrobpos = -1;
992 if (fCurrNtimebins != fNtimebins) {
994 LinkError(kNtimebinsChanged,
995 "No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
996 fNtimebins = fCurrNtimebins;
999 timebins = fNtimebins;
1001 while (*(fPayloadCurr) != fgkDataEndmarker &&
1002 fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
1004 // ----- Checking MCM Header -----
1005 AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
1007 // ----- checking for proper readout order - ROB -----
1008 if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
1009 lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
1012 ROBError(kPosUnexp);
1014 fCurrRobPos = ROB(*fPayloadCurr);
1016 // ----- checking for proper readout order - MCM -----
1017 if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
1018 lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
1021 MCMError(kPosUnexp);
1023 fCurrMcmPos = MCM(*fPayloadCurr);
1025 if (EvNo(*fPayloadCurr) != evno) {
1027 evno = EvNo(*fPayloadCurr);
1029 MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
1034 channelcountExp = 21;
1037 Int_t adccoloff = AdcColOffset(*fPayloadCurr);
1038 Int_t padcoloff = PadColOffset(*fPayloadCurr);
1039 Int_t row = Row(*fPayloadCurr);
1043 // ----- reading marked ADC channels -----
1044 while (channelcount < channelcountExp &&
1045 *(fPayloadCurr) != fgkDataEndmarker) {
1052 AliDebug(2, Form("Now looking %i words", timebins / 3));
1053 Int_t adccol = adccoloff - channelno;
1054 Int_t padcol = padcoloff - channelno;
1055 while (adcwc < timebins / 3 &&
1056 *(fPayloadCurr) != fgkDataEndmarker &&
1057 fPayloadCurr - fPayloadStart < fPayloadSize) {
1058 int check = 0x3 & *fPayloadCurr;
1059 if (channelno % 2 != 0) { // odd channel
1060 if (check != 0x2 && channelno < 21) {
1061 MCMError(kAdcCheckInvalid,
1062 "%i for %2i. ADC word in odd channel %i",
1063 check, adcwc+1, channelno);
1066 else { // even channel
1067 if (check != 0x3 && channelno < 21) {
1068 MCMError(kAdcCheckInvalid,
1069 "%i for %2i. ADC word in even channel %i",
1070 check, adcwc+1, channelno);
1074 // filling the actual timebin data
1075 int tb2 = 0x3ff & *fPayloadCurr >> 22;
1076 int tb1 = 0x3ff & *fPayloadCurr >> 12;
1077 int tb0 = 0x3ff & *fPayloadCurr >> 2;
1078 if (adcwc != 0 || fCurrNtimebins <= 30)
1079 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
1082 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
1083 fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
1089 if (adcwc != timebins / 3)
1090 MCMError(kAdcDataAbort);
1093 if (padcol > 0 && padcol < 144) {
1094 fSignalIndex->AddIndexRC(row, padcol);
1100 if (channelcount != channelcountExp)
1101 MCMError(kAdcChannelsMiss);
1103 // continue with next MCM
1106 // check for missing MCMs (if header suppression is inactive)
1107 if (mcmcount != mcmcountExp) {
1108 LinkError(kMissMcmHeaders,
1109 "%i not as expected: %i", mcmcount, mcmcountExp);
1112 return (fPayloadCurr - start);
1115 Int_t AliTRDrawStream::SeekNextLink()
1117 UInt_t *start = fPayloadCurr;
1119 // read until data endmarkers
1120 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1121 *fPayloadCurr != fgkDataEndmarker)
1124 // read all data endmarkers
1125 while (fPayloadCurr - fPayloadStart < fPayloadSize &&
1126 *fPayloadCurr == fgkDataEndmarker)
1129 return (fPayloadCurr - start);
1132 Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
1134 fTrackletTree = trklTree;
1138 if (!fTrackletTree->GetBranch("hc"))
1139 fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
1141 fTrackletTree->SetBranchAddress("hc", &fCurrHC);
1143 if (!fTrackletTree->GetBranch("trkl"))
1144 fTrackletTree->Branch("trkl", &fTrackletArray);
1146 fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
1152 TString AliTRDrawStream::EquipmentError(ErrorCode_t err, TString msg, ...)
1154 // register error according to error code on equipment level
1155 // and return the corresponding error message
1157 fLastError.fSector = fCurrEquipmentId - 1024;
1158 fLastError.fStack = -1;
1159 fLastError.fLink = -1;
1160 fLastError.fRob = -1;
1161 fLastError.fMcm = -1;
1162 fLastError.fError = err;
1166 if (fgErrorDebugLevel[err] > 10)
1167 AliDebug(fgErrorDebugLevel[err],
1168 Form("Event %6i: Eq. %2d - %s : %s",
1169 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1170 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1172 AliError(Form("Event %6i: Eq. %2d - %s : %s",
1173 fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
1174 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1175 fErrorFlags |= fgErrorBehav[err];
1180 TString AliTRDrawStream::StackError(ErrorCode_t err, TString msg, ...)
1182 // register error according to error code on stack level
1183 // and return the corresponding error message
1185 fLastError.fSector = fCurrEquipmentId - 1024;
1186 fLastError.fStack = fCurrSlot;
1187 fLastError.fLink = -1;
1188 fLastError.fRob = -1;
1189 fLastError.fMcm = -1;
1190 fLastError.fError = err;
1194 if (fgErrorDebugLevel[err] > 0)
1195 AliDebug(fgErrorDebugLevel[err],
1196 Form("Event %6i: Eq. %2d S %i - %s : %s",
1197 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1198 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1200 AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
1201 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
1202 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1203 fErrorFlags |= fgErrorBehav[err];
1208 TString AliTRDrawStream::LinkError(ErrorCode_t err, TString msg, ...)
1210 // register error according to error code on link level
1211 // and return the corresponding error message
1213 fLastError.fSector = fCurrEquipmentId - 1024;
1214 fLastError.fStack = fCurrSlot;
1215 fLastError.fLink = fCurrLink;
1216 fLastError.fRob = -1;
1217 fLastError.fMcm = -1;
1218 fLastError.fError = err;
1222 if (fgErrorDebugLevel[err] > 0)
1223 AliDebug(fgErrorDebugLevel[err],
1224 Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1225 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1226 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1228 AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
1229 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
1230 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1231 fErrorFlags |= fgErrorBehav[err];
1236 TString AliTRDrawStream::ROBError(ErrorCode_t err, TString msg, ...)
1238 // register error according to error code on ROB level
1239 // and return the corresponding error message
1241 fLastError.fSector = fCurrEquipmentId - 1024;
1242 fLastError.fStack = fCurrSlot;
1243 fLastError.fLink = fCurrLink;
1244 fLastError.fRob = fCurrRobPos;
1245 fLastError.fMcm = -1;
1246 fLastError.fError = err;
1250 if (fgErrorDebugLevel[err] > 0)
1251 AliDebug(fgErrorDebugLevel[err],
1252 Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1253 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
1254 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1256 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
1257 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
1258 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1259 fErrorFlags |= fgErrorBehav[err];
1264 TString AliTRDrawStream::MCMError(ErrorCode_t err, TString msg, ...)
1266 // register error according to error code on MCM level
1267 // and return the corresponding error message
1269 fLastError.fSector = fCurrEquipmentId - 1024;
1270 fLastError.fStack = fCurrSlot;
1271 fLastError.fLink = fCurrLink;
1272 fLastError.fRob = fCurrRobPos;
1273 fLastError.fMcm = fCurrMcmPos;
1274 fLastError.fError = err;
1278 if (fgErrorDebugLevel[err] > 0)
1279 AliDebug(fgErrorDebugLevel[err],
1280 Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1281 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
1282 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1284 AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
1285 fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
1286 (va_start(ap, msg), vsprintf(fErrorBuffer, msg.Data(), ap), va_end(ap), fErrorBuffer) ));
1287 fErrorFlags |= fgErrorBehav[err];
1291 const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
1293 // return the error message for the given error code
1295 if (errCode > 0 && errCode < kLastErrorCode)
1296 return fgErrorMessages[errCode];
1301 void AliTRDrawStream::AliTRDrawStats::ClearStats()
1303 // clear statistics (includes clearing sector-wise statistics)
1306 for (Int_t iSector = 0; iSector < 18; iSector++) {
1307 fStatsSector[iSector].ClearStats();
1312 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::ClearStats()
1314 // clear statistics (includes clearing HC-wise statistics)
1322 for (Int_t iHC = 0; iHC < 60; iHC++) {
1323 fStatsHC[iHC].ClearStats();
1327 void AliTRDrawStream::AliTRDrawStats::AliTRDrawStatsSector::AliTRDrawStatsHC::ClearStats()
1338 void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
1340 // mark MCM for dumping of raw data
1343 fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
1347 for (iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1348 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1353 for ( ; iMCM < fNDumpMCMs; iMCM++) {
1354 fDumpMCM[iMCM] = fDumpMCM[iMCM+1];
1359 Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm)
1361 // check if MCM data should be dumped
1363 for (Int_t iMCM = 0; iMCM < fNDumpMCMs; iMCM++) {
1364 if (fDumpMCM[iMCM] == ((det << 7) | (rob << 4) | mcm)) {
1371 void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
1377 for ( ; pos+3 < length; pos += 4) {
1378 title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n",
1379 start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
1381 for ( ; pos < length; pos++) {
1382 title += Form("0x%08x ", start[pos]);