// Decoding data from the TRD raw stream //
// and translation into ADC values, on-line tracklets and tracks //
// //
+// CRC checks rely on boost, and are enabled only when TRD_RAW_CRC //
+// is defined //
+// //
+// Additional debug features can be enabled by defining TRD_RAW_DEBUG //
+// //
// Author: J. Klein (jochen.klein@cern.ch) //
// //
////////////////////////////////////////////////////////////////////////////
#include <cstdio>
#include <cstdarg>
+#if defined(TRD_RAW_CRC)
+#include <boost/crc.hpp>
+#endif
+
#include "TClonesArray.h"
#include "TTree.h"
#include "AliTRDtrackletWord.h"
#include "AliTRDtrackletMCM.h"
#include "AliESDTrdTrack.h"
-#include "AliTreeLoader.h"
-#include "AliLoader.h"
#include "AliTRDrawStream.h"
-// temporary
-#include "AliRunLoader.h"
-
ClassImp(AliTRDrawStream)
// some static information
"not a TRD equipment (1024-1041)",
"Invalid Stack header",
"Invalid detector number",
+ "Invalid pad row",
"No digits could be retrieved from the digitsmanager",
"HC header mismatch",
"HC check bits wrong",
1,
0,
1,
+ 0,
1,
0,
1,
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
+ AliTRDrawStream::kDiscardMCM,
AliTRDrawStream::kAbort,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kDiscardHC,
fCurrTrackEnable(0),
fCurrTrackletEnable(0),
fCurrStackMask(0),
+#ifdef TRD_RAW_DEBUG
+ fCurrL0Count(),
+ fCurrL1aCount(),
+ fCurrL1rCount(),
+ fCurrL2aCount(),
+ fCurrL2rCount(),
+ fCurrL0offset(),
+#endif
fCurrTrkHeaderIndexWord(0x0),
fCurrTrkHeaderSize(0x0),
fCurrTrkFlags(0x0),
fCurrLinkMonitorFlags(0x0),
fCurrLinkDataTypeFlags(0x0),
fCurrLinkDebugFlags(0x0),
- fCurrMatchFlagsSRAM(0),
- fCurrMatchFlagsPostBP(0),
+ fCurrMatchFlagsSRAM(),
+ fCurrMatchFlagsPostBP(),
fCurrChecksumStack(),
fCurrChecksumSIU(0),
fCurrSpecial(-1),
fCurrHC(-1),
fCurrCheck(-1),
fCurrNtimebins(-1),
- fCurrBC(-1),
fCurrPtrgCnt(-1),
fCurrPtrgPhase(-1),
+#ifdef TRD_RAW_DEBUG
+ fCurrBC(),
+#endif
fNDumpMCMs(0),
- fTrackletArray(0x0),
fAdcArray(0x0),
fSignalIndex(0x0),
- fTrackletTree(0x0),
fTracklets(0x0),
fTracks(0x0),
fMarkers(0x0)
fCurrTrgHeaderIndexWord = new UInt_t[fgkNtriggers];
fCurrTrgHeaderSize = new UInt_t[fgkNtriggers];
fCurrTrgFlags = new UInt_t[fgkNsectors];
+#ifdef TRD_RAW_DEBUG
+ fCurrL0Count = new UInt_t[fgkNsectors];
+ fCurrL1aCount = new UInt_t[fgkNsectors];
+ fCurrL1rCount = new UInt_t[fgkNsectors];
+ fCurrL2aCount = new UInt_t[fgkNsectors];
+ fCurrL2rCount = new UInt_t[fgkNsectors];
+#endif
fCurrStackIndexWord = new UInt_t[fgkNstacks];
fCurrStackHeaderSize = new UInt_t[fgkNstacks];
fCurrStackHeaderVersion = new UInt_t[fgkNstacks];
fCurrCleanCheckout = new UInt_t[fgkNstacks];
fCurrBoardId = new UInt_t[fgkNstacks];
fCurrHwRevTMU = new UInt_t[fgkNstacks];
- fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
+ fCurrLinkMonitorFlags = new UInt_t[fgkNsectors * fgkNstacks * fgkNlinks];
fCurrLinkDataTypeFlags = new UInt_t[fgkNstacks * fgkNlinks];
fCurrLinkDebugFlags = new UInt_t[fgkNstacks * fgkNlinks];
for (Int_t iSector = 0; iSector < fgkNsectors; iSector++)
for (Int_t i = 0; i < 100; i++)
fDumpMCM[i] = 0;
- // preparing TClonesArray
- fTrackletArray = new TClonesArray("AliTRDtrackletWord", 256);
-
// setting up the error tree
fErrors = new TTree("errorStats", "Error statistics");
fErrors->SetDirectory(0x0);
delete [] fCurrLinkDebugFlags;
}
-Bool_t AliTRDrawStream::ReadEvent(TTree *trackletTree)
+Bool_t AliTRDrawStream::ReadEvent()
{
// read the current event from the raw reader and fill it to the digits manager
return kFALSE;
}
- // tracklet output
- ConnectTracklets(trackletTree);
-
// some preparations
fDigitsParam = 0x0;
if (fCurrTrailerReadout)
ReadGTUTrailer();
+#ifdef TRD_RAW_CRC
+ boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumStack[5];
+ boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> checksumSIU;
+ checksumSIU.reset();
+
+ // process CDH, replace size with 0xffffffff
+ UInt_t temp = 0xffffffff;
+ checksumSIU.process_bytes(&temp, sizeof(UInt_t));
+ UInt_t *data = (UInt_t*) fRawReader->GetDataHeader();
+ checksumSIU.process_bytes(&data[1], 7*sizeof(UInt_t));
+ // process payload including everything but the SIU checksum
+ checksumSIU.process_bytes(buffer, fRawReader->GetDataSize()-4);
+
+ if (checksumSIU() != fCurrChecksumSIU) {
+ EquipmentError(kCRCmismatch, "SIU data - recalc: 0x%08x - 0x%08x", fCurrChecksumSIU, checksumSIU());
+ }
+#endif
+
// loop over all active links
AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
fCurrSlot = iStack;
+#ifdef TRD_RAW_CRC
+ checksumStack[iStack].reset();
+#endif
+
if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
continue;
if ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) == 0)
continue;
+#ifdef TRD_RAW_CRC
+ UInt_t *start = fPayloadCurr;
+#endif
Int_t size = 0;
fErrorFlags = 0;
// check for link monitor error flag
- if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
+ if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
size += ReadLinkData();
// read all data endmarkers
size += SeekNextLink();
+
+#ifdef TRD_RAW_CRC
+ // always use data for CRC calculation
+ // (even if link monitor active)
+ UShort_t crc = CalcLinkChecksum(start, size);
+ checksumStack[iStack].process_bytes(&crc, sizeof(UShort_t));
+#endif
+ }
+#ifdef TRD_RAW_CRC
+ if (fDigitsManager && (checksumStack[iStack]() != fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack])) {
+ StackError(kCRCmismatch, "data - recalc: 0x%04x - 0x%04x", fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][iStack], checksumStack[iStack]());
}
+#endif
// continue with next stack
SeekNextStack();
fErrorFlags = 0;
- // tracklet output preparation
- TTree *trklTree = 0x0;
- AliRunLoader *rl = AliRunLoader::Instance();
- AliLoader* trdLoader = rl ? rl->GetLoader("TRDLoader") : NULL;
- AliDataLoader *trklLoader = trdLoader ? trdLoader->GetDataLoader("tracklets") : NULL;
- if (trklLoader) {
- AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw");
- if (trklTreeLoader)
- trklTree = trklTreeLoader->Tree();
- else
- trklTree = trklLoader->Tree();
- }
-
- if (fTrackletTree != trklTree)
- ConnectTracklets(trklTree);
-
if (!fRawReader) {
AliError("No raw reader available");
return -1;
fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNlinks * fgkNstacks +
fCurrSlot * fgkNlinks + fCurrLink;
- if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
+ if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
ReadLinkData();
fCurrLink++;
fCurrHC++;
if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
- if (fCurrLinkMonitorFlags[fCurrSlot*fgkNlinks + fCurrLink] != 0) {
+ if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
LinkError(kLinkMonitor);
if (fgErrorBehav[kLinkMonitor] == kTolerate)
ReadLinkData();
fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
fCurrStackEndmarkerAvail = 1;
+#ifdef TRD_RAW_DEBUG
+ if (fCurrSmHeaderSize > 7) {
+ fCurrL0Count[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[3];
+ fCurrL1aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[4];
+ fCurrL1rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[5];
+ fCurrL2aCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[6];
+ fCurrL2rCount[fCurrEquipmentId-kDDLOffset] = fPayloadCurr[7];
+ }
+#endif
break;
default:
AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
trk->SetFlags((trackWord >> 52) & 0x7ff);
- trk->SetReserved((trackWord >> 49) & 0x7);
+ trk->SetFlagsTiming((trackWord >> 51) & 0x1);
+ trk->SetReserved((trackWord >> 49) & 0x3);
trk->SetY((trackWord >> 36) & 0x1fff);
trk->SetTrackletIndex((trackWord >> 0) & 0x3f, 0);
trk->SetTrackletIndex((trackWord >> 6) & 0x3f, 1);
trk->SetTrackletIndex((trackWord >> 24) & 0x3f, 4);
trk->SetTrackletIndex((trackWord >> 30) & 0x3f, 5);
+ if (trk->GetFlagsTiming() == 0) {
+ AliError(Form("*** track not in time: 0x%016llx", trk->GetExtendedTrackWord(0)));
+ }
+
if (trackWord != trk->GetExtendedTrackWord(0)) {
AliError(Form("extended track word 0x%016llx does not match the read one 0x%016llx",
trk->GetExtendedTrackWord(0), trackWord));
switch (fCurrStackHeaderVersion[stack]) {
case 0xa:
+ case 0xb:
if (fCurrStackHeaderSize[stack] < 8) {
LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
return -1;
for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
// A side
- fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
- fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
- fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
+ fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2] = fPayloadCurr[iLayer+2] & 0xf;
+ fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 4) & 0x3;
+ fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2] = (fPayloadCurr[iLayer+2] >> 12) & 0xf;
// B side
- fCurrLinkMonitorFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
- fCurrLinkDataTypeFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
- fCurrLinkDebugFlags [stack*fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
+ fCurrLinkMonitorFlags [((fCurrEquipmentId - kDDLOffset) * fgkNstacks + stack) *fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 16) & 0xf;
+ fCurrLinkDataTypeFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 20) & 0x3;
+ fCurrLinkDebugFlags [stack * fgkNlinks + iLayer*2 + 1] = (fPayloadCurr[iLayer+2] >> 28) & 0xf;
}
break;
default:
- LinkError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
+ EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
}
fPayloadCurr += fCurrStackHeaderSize[stack];
UInt_t* trailer = fPayloadStart + fPayloadSize -1;
// look for the trailer index word from the end
- for (Int_t iWord = 0; iWord < fPayloadSize; iWord++) {
- if ((fPayloadStart[fPayloadSize-1-iWord] & 0xffff) == 0x1f51) {
+ for (Int_t iWord = 0; iWord < fPayloadSize-2; iWord++) {
+ if ((fPayloadStart[fPayloadSize-3-iWord] == fgkStackEndmarker[0]) &&
+ (fPayloadStart[fPayloadSize-2-iWord] == fgkStackEndmarker[1]) &&
+ ((fPayloadStart[fPayloadSize-1-iWord] & 0xfff) == 0xf51)) {
trailer = fPayloadStart + fPayloadSize - 1 - iWord;
break;
}
}
- if (((*trailer) & 0xffff) == 0x1f51) {
+ if (((*trailer) & 0xfff) == 0xf51) {
UInt_t trailerIndexWord = (*trailer);
Int_t trailerSize = (trailerIndexWord >> 16) & 0xffff;
+ // Int_t trailerVersion = (trailerIndexWord >> 12) & 0xf;
AliDebug(2, DumpRaw("GTU trailer", trailer, trailerSize+1));
// parse the trailer
if (trailerSize >= 4) {
// match flags from GTU
- fCurrMatchFlagsSRAM = (trailer[1] >> 0) & 0x1f;
- fCurrMatchFlagsPostBP = (trailer[1] >> 5) & 0x1f;
+ fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
+ fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
// individual checksums
- fCurrChecksumStack[0] = (trailer[1] >> 16) & 0xffff;
- fCurrChecksumStack[1] = (trailer[2] >> 0) & 0xffff;
- fCurrChecksumStack[2] = (trailer[2] >> 16) & 0xffff;
- fCurrChecksumStack[3] = (trailer[3] >> 0) & 0xffff;
- fCurrChecksumStack[4] = (trailer[3] >> 16) & 0xffff;
- fCurrChecksumSIU = trailer[4];
-
- if ((fCurrMatchFlagsSRAM & fCurrStackMask) != fCurrStackMask)
- EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM);
- if ((fCurrMatchFlagsPostBP & fCurrStackMask) != fCurrStackMask)
- EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP);
+ fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][0] = (trailer[1] >> 16) & 0xffff;
+ fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][1] = (trailer[2] >> 0) & 0xffff;
+ fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][2] = (trailer[2] >> 16) & 0xffff;
+ fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][3] = (trailer[3] >> 0) & 0xffff;
+ fCurrChecksumStack[fCurrEquipmentId - kDDLOffset][4] = (trailer[3] >> 16) & 0xffff;
+ fCurrChecksumSIU = trailer[trailerSize];
+
+ if ((fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
+ EquipmentError(kCRCmismatch, "CRC mismatch SRAM: 0x%02x", fCurrMatchFlagsSRAM[fCurrEquipmentId-kDDLOffset]);
+ if ((fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] & fCurrStackMask) != fCurrStackMask)
+ EquipmentError(kCRCmismatch, "CRC mismatch BP: 0x%02x", fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset]);
}
else {
{
// read the tracklets from one HC
- fTrackletArray->Clear();
+ Int_t nTracklets = 0;
UInt_t *start = fPayloadCurr;
while (*(fPayloadCurr) != fgkTrackletEndmarker &&
*(fPayloadCurr) != fgkStackEndmarker[0] &&
*(fPayloadCurr) != fgkStackEndmarker[1] &&
fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
- new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
+ ++nTracklets;
+ if (fTracklets)
+ new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
fPayloadCurr++;
}
- if (fTrackletArray->GetEntriesFast() > 0) {
- AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", fTrackletArray->GetEntriesFast(),
+ if (nTracklets > 0) {
+ AliDebug(1, Form("Found %i tracklets in %i %i %i (ev. %i)", nTracklets,
(fCurrEquipmentId-kDDLOffset), fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
if (fCurrSm > -1 && fCurrSm < 18) {
- fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += fTrackletArray->GetEntriesFast();
- fStats.fStatsSector[fCurrSm].fNTracklets += fTrackletArray->GetEntriesFast();
+ fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNTracklets += nTracklets;
+ fStats.fStatsSector[fCurrSm].fNTracklets += nTracklets;
}
- if (fTrackletTree)
- fTrackletTree->Fill();
- if (fTracklets)
- for (Int_t iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
- new ((*fTracklets)[fTracklets->GetEntriesFast()]) AliTRDtrackletWord(*((AliTRDtrackletWord*)(*fTrackletArray)[iTracklet]));
- }
}
// loop over remaining tracklet endmarkers
if (fCurrAddHcWords > 0) {
fCurrNtimebins = (fPayloadCurr[1] >> 26) & 0x3f;
- fCurrBC = (fPayloadCurr[1] >> 10) & 0xffff;
+#ifdef TRD_RAW_DEBUG
+ fCurrBC[fCurrHC] = (fPayloadCurr[1] >> 10) & 0xffff;
+#endif
fCurrPtrgCnt = (fPayloadCurr[1] >> 6) & 0xf;
fCurrPtrgPhase = (fPayloadCurr[1] >> 2) & 0xf;
}
}
else {
MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+#ifdef TRD_RAW_DEBUG
+ if (fCurrL0offset[fCurrHC/2] != 0)
+ LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
+ fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
+ EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
+ EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
+ fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
+ evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
+#endif
}
}
GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
}
+#ifdef TRD_RAW_DEBUG
+ if (fCurrL0Count[fCurrEquipmentId-kDDLOffset] > 0) {
+ evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
+ }
+ fCurrEvCount[fCurrEquipmentId-kDDLOffset] = EvNo(*fPayloadCurr);
+#endif
+
if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
if (evno == -1) {
evno = EvNo(*fPayloadCurr);
}
else {
- MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+ MCMError(kEvCntMismatch, "exp <-> SM: %i <-> %i", evno & 0xfffff, EvNo(*fPayloadCurr));
+#ifdef TRD_RAW_DEBUG
+ Int_t prevOffset = fCurrL0offset[fCurrHC/2];
+ fCurrL0offset[fCurrHC/2] = (- fCurrL0Count[fCurrEquipmentId-kDDLOffset] + EvNo(*fPayloadCurr)) % (1 << 20);
+ if (fCurrL0offset[fCurrHC/2] < 0)
+ fCurrL0offset[fCurrHC/2] += 0xfffff;
+ evno = (fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2]) & 0xfffff;
+ if (prevOffset != 0)
+ LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
+ fCurrEquipmentId, fCurrSlot, fCurrLink/2,
+ prevOffset,
+ fCurrL0offset[fCurrHC/2],
+ fCurrL0Count[fCurrEquipmentId-kDDLOffset],
+ EvNo(*fPayloadCurr));
+#endif
}
}
Int_t adccoloff = AdcColOffset(*fPayloadCurr);
fPayloadCurr++;
if ((row > 11) && (fCurrStack == 2)) {
- MCMError(kUnknown, "Data in padrow > 11 for stack 2");
+ MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
}
- if (fErrorFlags & (kDiscardMCM | kDiscardHC | kDiscardDDL))
- break; //???
+ if (fErrorFlags & (kDiscardHC | kDiscardDDL))
+ break;
// ----- Reading ADC channels -----
AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
}
}
- // filling the actual timebin data
- int tb2 = 0x3ff & *fPayloadCurr >> 22;
- int tb1 = 0x3ff & *fPayloadCurr >> 12;
- int tb0 = 0x3ff & *fPayloadCurr >> 2;
- if (adcwc != 0 || fCurrNtimebins <= 30)
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
- else
- tb0 = -1;
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
+ if ((fErrorFlags & kDiscardMCM) == 0) {
+ // filling the actual timebin data
+ int tb2 = 0x3ff & (*fPayloadCurr >> 22);
+ int tb1 = 0x3ff & (*fPayloadCurr >> 12);
+ int tb0 = 0x3ff & (*fPayloadCurr >> 2);
+ if (adcwc != 0 || fCurrNtimebins <= 30)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
+ else
+ tb0 = -1;
+ if (currentTimebin < fCurrNtimebins)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
+ if (currentTimebin < fCurrNtimebins)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
+ }
adcwc++;
fPayloadCurr++;
}
else {
MCMError(kEvCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+#ifdef TRD_RAW_DEBUG
+ if (fCurrL0offset[fCurrHC/2] != 0)
+ LinkError(kEvCntMismatch, "offset for %i %i %i changed from %i to %i = %i - %i",
+ fCurrEquipmentId, fCurrSlot, fCurrLink/2, fCurrL0offset[fCurrHC/2],
+ EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset],
+ EvNo(*fPayloadCurr), fCurrL0Count[fCurrEquipmentId-kDDLOffset]);
+ fCurrL0offset[fCurrHC/2] = EvNo(*fPayloadCurr) - fCurrL0Count[fCurrEquipmentId-kDDLOffset];
+ evno = fCurrL0Count[fCurrEquipmentId-kDDLOffset] + fCurrL0offset[fCurrHC/2];
+#endif
}
}
Int_t adccoloff = AdcColOffset(*fPayloadCurr);
Int_t padcoloff = PadColOffset(*fPayloadCurr);
Int_t row = Row(*fPayloadCurr);
-
fPayloadCurr++;
+ if ((row > 11) && (fCurrStack == 2)) {
+ MCMError(kInvalidPadRow, "Data in padrow > 11 for stack 2");
+ }
+
+ if (fErrorFlags & (kDiscardHC | kDiscardDDL))
+ break;
+
// ----- reading marked ADC channels -----
while (channelcount < channelcountExp &&
*(fPayloadCurr) != fgkDataEndmarker) {
}
}
- // filling the actual timebin data
- int tb2 = 0x3ff & *fPayloadCurr >> 22;
- int tb1 = 0x3ff & *fPayloadCurr >> 12;
- int tb0 = 0x3ff & *fPayloadCurr >> 2;
- if (adcwc != 0 || fCurrNtimebins <= 30)
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
- else
- tb0 = -1;
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
- fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
+ if ((fErrorFlags & kDiscardMCM) == 0) {
+ // filling the actual timebin data
+ int tb2 = 0x3ff & (*fPayloadCurr >> 22);
+ int tb1 = 0x3ff & (*fPayloadCurr >> 12);
+ int tb0 = 0x3ff & (*fPayloadCurr >> 2);
+ if (adcwc != 0 || fCurrNtimebins <= 30)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb0);
+ else
+ tb0 = -1;
+ if (currentTimebin < fCurrNtimebins)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb1);
+ if (currentTimebin < fCurrNtimebins)
+ fAdcArray->SetDataByAdcCol(row, adccol, currentTimebin++, tb2);
+ }
adcwc++;
fPayloadCurr++;
return (fPayloadCurr - start);
}
+#ifdef TRD_RAW_CRC
+UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t *data, Int_t size)
+{
+ // calculate the CRC for the data from this link
+ // must not change the pointers to the data
+
+ // always count two endmarkers
+ Int_t nEndmarkers = 0;
+ for (Int_t i = 0; i < size; i++) {
+ if (data[size-1 - i] != fgkDataEndmarker)
+ break;
+ nEndmarkers++;
+ }
+
+ size = size - (nEndmarkers-2);
+
+ boost::crc_optimal<16, 0x8005, 0, 0, false, false> checksumLink;
+
+ checksumLink.reset();
+ checksumLink.process_bytes(data, size*sizeof(UInt_t));
+ return checksumLink();
+}
+#else
+UShort_t AliTRDrawStream::CalcLinkChecksum(UInt_t * /* data */, Int_t /* size */)
+{
+ // checksum calculation relies on boost,
+ // we return 0 if we cannot calculate it
+
+ AliError("Checksum calculation relies on boost CRC implementation!");
+
+ return 0;
+}
+#endif
+
Int_t AliTRDrawStream::SeekNextStack()
{
// proceed in raw data stream till the next stack
return (fPayloadCurr - start);
}
-Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
-{
- // connect the tracklet tree used to store the tracklet output
-
- fTrackletTree = trklTree;
- if (!fTrackletTree)
- return kTRUE;
-
- if (!fTrackletTree->GetBranch("hc"))
- fTrackletTree->Branch("hc", &fCurrHC, "hc/I");
- else
- fTrackletTree->SetBranchAddress("hc", &fCurrHC);
-
- if (!fTrackletTree->GetBranch("trkl"))
- fTrackletTree->Branch("trkl", &fTrackletArray);
- else
- fTrackletTree->SetBranchAddress("trkl", &fTrackletArray);
-
- return kTRUE;
-}
-
void AliTRDrawStream::EquipmentError(ErrorCode_t err, const char *const msg, ...)
{
}
}
if (trklNext) {
- Int_t label = -2; // mark raw tracklets with label -2
- if (AliTRDtrackletMCM *trklMCM = dynamic_cast<AliTRDtrackletMCM*> (trklNext))
- label = trklMCM->GetLabel();
- AliESDTrdTracklet *esdTracklet = new AliESDTrdTracklet(trklNext->GetTrackletWord(), trklNext->GetHCId(), label);
- sortedTracklets.Add(esdTracklet);
+ sortedTracklets.Add(trklNext);
+
}
}
// updating tracklet indices as in output
if (sortedTracklets.GetEntries() != trklIndex) {
- indices[2*iDet + 0] = indices[2*iDet + 1] = trklIndex;
+ indices[2*iDet + 0] = trklIndex;
+ indices[2*iDet + 1] = sortedTracklets.GetEntries();
} else {
indices[2*iDet + 0] = indices[2*iDet + 1] = -1;
}
}
}
+
+void AliTRDrawStream::AssignTracklets(AliESDTrdTrack *trdTrack, Int_t *trackletIndex, Int_t refIndex[6])
+{
+ UInt_t mask = trdTrack->GetLayerMask();
+ UInt_t stack = trdTrack->GetStack();
+
+ for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
+ refIndex[iLayer] = -1;
+
+ if (mask & (1 << iLayer)) {
+
+ Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
+ Int_t idx = trdTrack->GetTrackletIndex(iLayer);
+
+ if ((det < 0) || (det > 539)) {
+ AliErrorClass(Form("Invalid detector no. from track: %i", 2*det));
+ continue;
+ }
+ if (trackletIndex[2*det] >= 0) {
+ if ((trackletIndex[2*det] + idx > -1) &&
+ (trackletIndex[2*det] + idx < trackletIndex[2*det+1])) {
+ refIndex[iLayer] = trackletIndex[2*det] + idx;
+ } else {
+ AliErrorClass(Form("Requested tracklet index %i out of range", idx));
+ }
+ } else {
+ AliErrorClass(Form("Non-existing tracklets requested in det %i", det));
+ }
+ }
+ }
+}