////////////////////////////////////////////////////////////////////////////
// //
// Decoding data from the TRD raw stream //
-// and translation into ADC values //
+// 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 "AliLog.h"
#include "AliRawReader.h"
+#include "AliTRDcalibDB.h"
#include "AliTRDdigitsManager.h"
#include "AliTRDdigitsParam.h"
+#include "AliTRDcalibDB.h"
+#include "AliTRDmcmSim.h"
#include "AliTRDtrapConfig.h"
#include "AliTRDarrayADC.h"
#include "AliTRDarrayDictionary.h"
#include "AliTRDSignalIndex.h"
#include "AliTRDtrackletWord.h"
+#include "AliTRDtrackletMCM.h"
#include "AliESDTrdTrack.h"
-#include "AliTreeLoader.h"
#include "AliTRDrawStream.h"
-// temporary
-#include "AliRunLoader.h"
-
ClassImp(AliTRDrawStream)
-// some static information
-const Int_t AliTRDrawStream::fgkMcmOrder[] = {12, 13, 14, 15,
- 8, 9, 10, 11,
- 4, 5, 6, 7,
- 0, 1, 2, 3};
-const Int_t AliTRDrawStream::fgkRobOrder [] = {0, 1, 2, 3};
+// some static information
+Int_t AliTRDrawStream::fgMcmOrder[] = {12, 13, 14, 15,
+ 8, 9, 10, 11,
+ 4, 5, 6, 7,
+ 0, 1, 2, 3};
+Int_t AliTRDrawStream::fgRobOrder [] = {0, 1, 2, 3};
const Int_t AliTRDrawStream::fgkNlinks = 12;
const Int_t AliTRDrawStream::fgkNstacks = 5;
+const Int_t AliTRDrawStream::fgkNsectors = 18;
+const Int_t AliTRDrawStream::fgkNtriggers = 12;
const UInt_t AliTRDrawStream::fgkDataEndmarker = 0x00000000;
const UInt_t AliTRDrawStream::fgkTrackletEndmarker = 0x10001000;
+const UInt_t AliTRDrawStream::fgkStackEndmarker[] = { 0xe0d01000, 0xe0d10000 };
-const char* AliTRDrawStream::fgErrorMessages[] = {
+const char* AliTRDrawStream::fgkErrorMessages[] = {
"Unknown error",
"Link monitor active",
- "Pretrigger counter mismatch",
+ "Event counter mismatch",
"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 header mismatch",
"HC check bits wrong",
"Unexpected position in readout stream",
"Invalid testpattern mode",
"Testpattern mismatch",
"Number of timebins changed",
- "ADC mask inconsistent",
- "ADC check bits invalid",
+ "ADC mask inconsistent",
+ "ADC check bits invalid",
"Missing ADC data",
"Missing expected ADC channels",
- "Missing MCM headers"
+ "Missing MCM headers",
+ "Missing TP data",
+ "CRC mismatch"
};
-const Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
+Int_t AliTRDrawStream::fgErrorDebugLevel[] = {
0,
0,
- 2,
- 1,
- 0,
- 1,
- 1,
+ 2,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
1,
- 1,
2,
1,
+ 0,
+ 1,
+ 1,
+ 2,
1,
1,
- 1,
- 2,
- 1,
- 1,
- 1
+ 1,
+ 0,
+ 0
};
AliTRDrawStream::ErrorBehav_t AliTRDrawStream::fgErrorBehav[] = {
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
AliTRDrawStream::kAbort,
+ AliTRDrawStream::kDiscardMCM,
AliTRDrawStream::kAbort,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kDiscardHC,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate,
+ AliTRDrawStream::kTolerate,
+ AliTRDrawStream::kTolerate,
AliTRDrawStream::kTolerate
};
AliTRDrawStream::AliTRDrawStream(AliRawReader *rawReader) :
- fStats(),
- fStoreError(&AliTRDrawStream::StoreErrorTree),
+ fStoreError(&AliTRDrawStream::ForgetError),
fRawReader(rawReader),
fDigitsManager(0x0),
fDigitsParam(0x0),
fErrors(0x0),
fLastError(),
fErrorFlags(0),
+ fStats(),
fPayloadStart(0x0),
fPayloadCurr(0x0),
fPayloadSize(0),
fCurrRobPos(-1),
fCurrMcmPos(-1),
fCurrEquipmentId(0),
- fCurrSmuIndexHeaderSize(0),
- fCurrSmuIndexHeaderVersion(0),
+ fCurrSmHeaderSize(0),
+ fCurrSmHeaderVersion(0),
+ fCurrTrailerReadout(0),
+ fCurrTrgHeaderAvail(0),
+ fCurrTrgHeaderReadout(0),
+ fCurrTrkHeaderAvail(0),
+ fCurrStackEndmarkerAvail(0),
+ fCurrEvType(0),
+ fCurrTriggerEnable(0),
+ fCurrTriggerFired(0),
fCurrTrackEnable(0),
fCurrTrackletEnable(0),
fCurrStackMask(0),
+#ifdef TRD_RAW_DEBUG
+ fCurrL0Count(),
+ fCurrL1aCount(),
+ fCurrL1rCount(),
+ fCurrL2aCount(),
+ fCurrL2rCount(),
+ fCurrL0offset(),
+#endif
+ fCurrTrkHeaderIndexWord(0x0),
+ fCurrTrkHeaderSize(0x0),
+ fCurrTrkFlags(0x0),
+ fCurrTrgHeaderIndexWord(0x0),
+ fCurrTrgHeaderSize(0x0),
+ fCurrTrgFlags(0x0),
fCurrStackIndexWord(0x0),
fCurrStackHeaderSize(0x0),
fCurrStackHeaderVersion(0x0),
fCurrLinkMask(0x0),
fCurrCleanCheckout(0x0),
fCurrBoardId(0x0),
- fCurrHwRev(0x0),
+ fCurrHwRev(-1),
+ fCurrHwRevTMU(0x0),
fCurrLinkMonitorFlags(0x0),
fCurrLinkDataTypeFlags(0x0),
fCurrLinkDebugFlags(0x0),
+ fCurrMatchFlagsSRAM(),
+ fCurrMatchFlagsPostBP(),
+ fCurrChecksumStack(),
+ fCurrChecksumSIU(0),
fCurrSpecial(-1),
fCurrMajor(-1),
fCurrMinor(-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)
{
// default constructor
- fCurrStackIndexWord = new UInt_t[fgkNstacks];
- fCurrStackHeaderSize = new UInt_t[fgkNstacks];
+ fCurrTrkHeaderIndexWord = new UInt_t[fgkNstacks];
+ fCurrTrkHeaderSize = new UInt_t[fgkNstacks];
+ fCurrTrkFlags = new ULong64_t[fgkNsectors*fgkNstacks];
+ 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];
- fCurrLinkMask = new UInt_t[fgkNstacks];
- fCurrCleanCheckout = new UInt_t[fgkNstacks];
- fCurrBoardId = new UInt_t[fgkNstacks];
- fCurrHwRev = new UInt_t[fgkNstacks];
- fCurrLinkMonitorFlags = new UInt_t[fgkNstacks * fgkNlinks];
+ fCurrLinkMask = new UInt_t[fgkNstacks];
+ fCurrCleanCheckout = new UInt_t[fgkNstacks];
+ fCurrBoardId = new UInt_t[fgkNstacks];
+ fCurrHwRevTMU = new UInt_t[fgkNstacks];
+ 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++)
+ fCurrTrgFlags[iSector] = 0;
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 fErrors;
+ delete [] fCurrTrkHeaderIndexWord;
+ delete [] fCurrTrkHeaderSize;
+ delete [] fCurrTrkFlags;
+ delete [] fCurrTrgHeaderIndexWord;
+ delete [] fCurrTrgHeaderSize;
+ delete [] fCurrTrgFlags;
delete [] fCurrStackIndexWord;
delete [] fCurrStackHeaderSize;
delete [] fCurrStackHeaderVersion;
delete [] fCurrLinkMask;
delete [] fCurrCleanCheckout;
delete [] fCurrBoardId;
- delete [] fCurrHwRev;
+ delete [] fCurrHwRevTMU;
delete [] fCurrLinkMonitorFlags;
delete [] fCurrLinkDataTypeFlags;
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;
// loop over all DDLs
- // data starts with GTU payload, i.e. SMU index word
+ // data starts with GTU payload, i.e. SM index word
UChar_t *buffer = 0x0;
while (fRawReader->ReadNextData(buffer)) {
fCurrEquipmentId = fRawReader->GetEquipmentId();
AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
- if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
+ if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
EquipmentError(kNonTrdEq, "Skipping");
continue;
}
- // setting the pointer to data and current reading position
- fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
- fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
- fStats.fStatsSector[fCurrEquipmentId - 1024].fBytes = fRawReader->GetDataSize();
- AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
+ if (fMarkers)
+ new ((*fMarkers)[fMarkers->GetEntriesFast()])
+ AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
- // read SMU index header
- if (ReadSmHeader() < 0) {
- AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
- continue;
- }
+ ReadGTUHeaders((UInt_t*) buffer);
+
+ 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();
- // read stack index header
- for (Int_t iStack = 0; iStack < 5; iStack++) {
- if ((fCurrStackMask & (1 << iStack)) != 0)
- ReadStackIndexHeader(iStack);
+ // 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
- for (Int_t iStack = 0; iStack < 5; iStack++) {
+ // loop over all active links
+ AliDebug(2, Form("Stack mask 0x%02x", fCurrStackMask));
+ for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
fCurrSlot = iStack;
- if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
+#ifdef TRD_RAW_CRC
+ checksumStack[iStack].reset();
+#endif
+
+ if ((fCurrStackMask & (1 << fCurrSlot)) == 0)
continue;
AliDebug(2, Form("Stack %i, Link mask: 0x%02x", fCurrSlot, fCurrLinkMask[fCurrSlot]));
- for (Int_t iLink = 0; iLink < 12; iLink++) {
+ for (Int_t iLink = 0; iLink < fgkNlinks; iLink++) {
fCurrLink = iLink;
- fCurrHC = fCurrSm * 60 + fCurrSlot * 12 + iLink;
+ fCurrHC = (fCurrEquipmentId - kDDLOffset) * fgkNstacks * fgkNlinks +
+ fCurrSlot * fgkNlinks + iLink;
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);
-
- // read the data from one HC
- ReadLinkData();
+ if (fgErrorBehav[kLinkMonitor] == kTolerate)
+ size += ReadLinkData();
+ }
+ else
+ // read the data from one HC
+ size += ReadLinkData();
// read all data endmarkers
- SeekNextLink();
+ 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();
}
}
+
return kTRUE;
}
fCurrEquipmentId = fRawReader->GetEquipmentId();
AliDebug(2, Form("equipment: %i", fCurrEquipmentId));
-
- if (fCurrEquipmentId < 1024 || fCurrEquipmentId > 1041) {
+
+ if (fCurrEquipmentId < kDDLOffset || fCurrEquipmentId > kDDLMax) {
EquipmentError(kNonTrdEq, "Skipping");
continue;
}
- // setting the pointer to data and current reading position
- fPayloadCurr = fPayloadStart = (UInt_t*) (buffer);
- fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
- AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
+ if (fMarkers)
+ new ((*fMarkers)[fMarkers->GetEntriesFast()])
+ AliTRDrawStreamError(-kSecactive, fCurrEquipmentId - kDDLOffset);
+
+ ReadGTUHeaders((UInt_t*) buffer);
+
+ if (fCurrTrailerReadout)
+ ReadGTUTrailer();
- // read SMU index header
- if (ReadSmHeader() < 0) {
- AliError(Form("Reading SMU header failed, skipping this DDL %i", fCurrEquipmentId));
- continue;
- }
-
- // read stack index header
- for (Int_t iStack = 0; iStack < 5; iStack++) {
- if ((fCurrStackMask & (1 << iStack)) != 0) {
- ReadStackIndexHeader(iStack);
- }
- }
return kTRUE;
}
}
-Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr, UInt_t ** /* trackletContainer */, UShort_t ** /* errorContainer */)
+Int_t AliTRDrawStream::NextChamber(AliTRDdigitsManager *digMgr)
{
// read the data for the next chamber
// in case you only want to read the data of a single chamber
// to read all data ReadEvent(...) is recommended
- fDigitsManager = digMgr;
+ fDigitsManager = digMgr;
fDigitsParam = 0x0;
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;
}
- if (fCurrSlot < 0 || fCurrSlot >= 5) {
+ while (fCurrSlot < 0 || fCurrSlot >= fgkNstacks) {
if (!NextDDL()) {
fCurrSlot = -1;
return -1;
}
+ while ((fCurrSlot < fgkNstacks) &&
+ (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
+ ((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0)) {
+ if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
+ ++fCurrSlot;
+ fCurrSlot = 0;
+ continue;
+ }
+ fCurrLink++;
+ if (fCurrLink >= fgkNlinks) {
+ SeekNextStack();
+ fCurrLink = 0;
+ fCurrSlot++;
+ }
+ }
}
AliDebug(2, Form("Stack %i, Link %i, mask: 0x%02x", fCurrSlot, fCurrLink, fCurrLinkMask[fCurrSlot]));
- fCurrHC = (fCurrEquipmentId - 1024) * 60 + fCurrSlot * 12 + fCurrLink;
+ 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();
+ }
+ else
+ // read the data from one HC
+ ReadLinkData();
- // read the data from one HC
- ReadLinkData();
-
// read all data endmarkers
SeekNextLink();
fCurrLink++;
fCurrHC++;
if (fCurrLinkMask[fCurrSlot] & (1 << fCurrLink)) {
- ReadLinkData();
+ if (fCurrLinkMonitorFlags[(((fCurrEquipmentId - kDDLOffset) * fgkNstacks) + fCurrSlot) * fgkNlinks + fCurrLink] != 0) {
+ LinkError(kLinkMonitor);
+ if (fgErrorBehav[kLinkMonitor] == kTolerate)
+ ReadLinkData();
+ }
+ else {
+ ReadLinkData();
+ }
SeekNextLink();
}
}
- //??? to check
do {
- fCurrLink++;
- if (fCurrLink > 11) {
+ if ((fCurrStackMask & (1 << fCurrSlot)) == 0) {
fCurrLink = 0;
fCurrSlot++;
}
- } while ((fCurrSlot < 5) &&
- (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
+ else {
+ fCurrLink++;
+ if (fCurrLink >= fgkNlinks) {
+ SeekNextStack();
+ fCurrLink = 0;
+ fCurrSlot++;
+ }
+ }
+ } while ((fCurrSlot < fgkNstacks) &&
+ (((fCurrStackMask & (1 << fCurrSlot)) == 0) ||
((fCurrLinkMask[fCurrSlot] & (1 << fCurrLink))) == 0));
// return chamber information from HC if it is valid
// otherwise return information from link position
- if (fCurrSm < 0 || fCurrSm > 17 || fCurrStack < 0 || fCurrStack > 4 || fCurrLayer < 0 || fCurrLayer > 5)
- return ((fCurrEquipmentId-1024) + fCurrSlot * 6 + fCurrLink/2);
+ if (fCurrSm < 0 || fCurrSm >= fgkNsectors || fCurrStack < 0 || fCurrStack >= fgkNstacks || fCurrLayer < 0 || fCurrLayer >= fgkNlinks/2)
+ return ((fCurrEquipmentId-kDDLOffset) + fCurrSlot * fgkNlinks/2 + fCurrLink/2);
else
- return (fCurrSm * 30 + fCurrStack * 6 + fCurrLayer);
+ return (fCurrSm * fgkNstacks*fgkNlinks/2 + fCurrStack * fgkNlinks/2 + fCurrLayer);
}
+Int_t AliTRDrawStream::ReadGTUHeaders(UInt_t *buffer)
+{
+ // check the data source and read the headers
+
+ if (fCurrEquipmentId >= kDDLOffset && fCurrEquipmentId <= kDDLMax) {
+ // this is ROC data
+
+ // setting the pointer to data and current reading position
+ fPayloadCurr = fPayloadStart = buffer;
+ fPayloadSize = fRawReader->GetDataSize() / sizeof(UInt_t);
+ fStats.fStatsSector[fCurrEquipmentId - kDDLOffset].fBytes = fRawReader->GetDataSize();
+ AliDebug(2, Form("Read buffer of size: %i", fRawReader->GetDataSize()));
+
+ AliDebug(1, DumpRaw("raw data", fPayloadCurr, TMath::Min(fPayloadSize, 1000)));
+
+ // read SM header
+ if (ReadSmHeader() < 0) {
+ AliError(Form("Reading SM header failed, skipping this DDL %i", fCurrEquipmentId));
+ return -1;
+ }
+
+ // read tracking headers (if available)
+ if (fCurrTrkHeaderAvail) {
+ for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
+ if ((fCurrStackMask & (1 << iStack)) != 0)
+ ReadTrackingHeader(iStack);
+ }
+ }
+
+ // read trigger header(s) (if available)
+ if (fCurrTrgHeaderAvail)
+ ReadTriggerHeaders();
+
+ // read stack header
+ for (Int_t iStack = 0; iStack < fgkNstacks; iStack++) {
+ if ((fCurrStackMask & (1 << iStack)) != 0)
+ ReadStackHeader(iStack);
+ }
+
+ return 0;
+ }
+ else
+ return -1;
+}
+
Int_t AliTRDrawStream::ReadSmHeader()
{
- // read the SMU index header at the current reading position
+ // read the SMU index header at the current reading position
// and store the information in the corresponding variables
if (fPayloadCurr - fPayloadStart >= fPayloadSize - 1) {
return -1;
}
- fCurrSmuIndexHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
- fCurrSmuIndexHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
- // fCurrSmuIndexHeaderTrgAvail = ((*fPayloadCurr) >> 9) & 0x1;
- // fCurrSmuIndexHeaderEvType = ((*fPayloadCurr) >> 7) & 0x3;
+ fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = 0;
+
+ fCurrSmHeaderSize = ((*fPayloadCurr) >> 16) & 0xffff;
+ fCurrSmHeaderVersion = ((*fPayloadCurr) >> 12) & 0xf;
fCurrTrackEnable = ((*fPayloadCurr) >> 6) & 0x1;
fCurrTrackletEnable = ((*fPayloadCurr) >> 5) & 0x1;
fCurrStackMask = ((*fPayloadCurr) ) & 0x1f;
+ fCurrHwRev = (fPayloadCurr[1] >> 12) & 0xffff;
+ fCurrStackEndmarkerAvail = 0;
+
+ switch (fCurrSmHeaderVersion) {
+ case 0xb:
+ fCurrTrailerReadout = 0;
+ fCurrTrgHeaderAvail = 0;
+ fCurrEvType = 0;
+ fCurrTrkHeaderAvail = 0;
+
+ DecodeGTUtracks();
+ break;
+
+ case 0xc:
+ fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
+ fCurrTrgHeaderAvail = 1;
+ fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
+ fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
+ fCurrTrkHeaderAvail = fCurrTrackEnable;
+ fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
+ fCurrTriggerFired = (fPayloadCurr[2] >> 20) & 0xfff;
+ fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] = fCurrTriggerFired;
+ break;
+
+ case 0xd:
+ fCurrTrailerReadout = ((*fPayloadCurr) >> 10) & 0x1;
+ fCurrTrgHeaderAvail = 1;
+ fCurrTrgHeaderReadout = ((*fPayloadCurr) >> 9) & 0x1;
+ fCurrEvType = ((*fPayloadCurr) >> 7) & 0x3;
+ fCurrTrkHeaderAvail = fCurrTrackEnable;
+ fCurrTriggerEnable = (fPayloadCurr[2] >> 8) & 0xfff;
+ 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;
- AliDebug(5, Form("SMU header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x",
- fCurrSmuIndexHeaderSize,
- fCurrSmuIndexHeaderVersion,
- fCurrTrackEnable,
+ default:
+ AliError(Form("unknown SM header version: 0x%x", fCurrSmHeaderVersion));
+ }
+
+ AliDebug(5, Form("SM header: size: %i, version: %i, track enable: %i, tracklet enable: %i, stack mask: %2x, trailer: %i, trgheader: %i, trkheader: %i",
+ fCurrSmHeaderSize,
+ fCurrSmHeaderVersion,
+ fCurrTrackEnable,
fCurrTrackletEnable,
- fCurrStackMask));
+ fCurrStackMask,
+ fCurrTrailerReadout,
+ fCurrTrgHeaderAvail,
+ fCurrTrkHeaderAvail ));
+
+ // jump to the first word after the SM header
+ fPayloadCurr += fCurrSmHeaderSize + 1;
+ return fCurrSmHeaderSize + 1;
+}
+
+Int_t AliTRDrawStream::DecodeGTUtracks()
+{
// decode GTU track words
- UInt_t trackWord[2] = { 0, 0 };
- Int_t stack = 0;
+ // this depends on the hardware revision of the SMU
+
+ Int_t sector = fCurrEquipmentId-kDDLOffset;
+
+ if ((sector < 0) || (sector > 17)) {
+ AliError(Form("Invalid sector %i for GTU tracks", sector));
+ return -1;
+ }
+
+ AliDebug(1, DumpRaw(Form("GTU tracks in sector %2i (hw rev %i)", sector, fCurrHwRev),
+ fPayloadCurr + 4, 10, 0xffe0ffff));
+
+ fCurrTrgFlags[sector] = 0;
+
+ if (fCurrHwRev < 1772) {
+ UInt_t fastWord; // fast trigger word
+ ULong64_t trackWord = 0; // extended track word
+ Int_t stack = 0;
+ Int_t idx = 0;
+ for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+ if (fPayloadCurr[iWord] == 0x10000000) { // stack boundary marker
+ stack++;
+ idx = 0;
+ }
+ else {
+ if ((idx == 0) &&
+ ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
+ fastWord = fPayloadCurr[iWord];
+ fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
+ AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
+ continue;
+ }
+ else if ((idx & 0x1) == 0x1) {
+ trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+ AliDebug(1,Form("track debug word: 0x%016llx", trackWord));
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+
+ trk->SetSector(sector);
+ trk->SetStack((trackWord >> 60) & 0x7);
+ trk->SetA(0);
+ trk->SetB(0);
+ trk->SetPID(0);
+ trk->SetLayerMask((trackWord >> 16) & 0x3f);
+ trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+ trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+ trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+ trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+ trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+ trk->SetFlags(0);
+ trk->SetReserved(0);
+ trk->SetLabel(-3);
+
+ Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+ if (TMath::Abs(pt) > 0.1) {
+ trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+ }
+ }
+ }
+ else {
+ trackWord = fPayloadCurr[iWord];
+ }
+ idx++;
+ }
+ }
+ }
+ else if (fCurrHwRev < 1804) {
+ UInt_t fastWord; // fast trigger word
+ ULong64_t trackWord = 0; // extended track word
+ Int_t stack = 0;
+ Int_t idx = 0;
+ for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+ if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
+ stack++;
+ idx = 0;
+ }
+ else {
+ if ((idx == 0) &&
+ ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
+ fastWord = fPayloadCurr[iWord];
+ fCurrTrgFlags[sector] |= 1 << (stack+11); // assume tracking done if fast word sent
+ AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
+ continue;
+ }
+ else if ((idx & 0x1) == 0x1) {
+ trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+ AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+
+ trk->SetSector(fCurrEquipmentId-kDDLOffset);
+ trk->SetStack((trackWord >> 60) & 0x7);
+ trk->SetA(0);
+ trk->SetB(0);
+ trk->SetPID(0);
+ trk->SetLayerMask((trackWord >> 16) & 0x3f);
+ trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+ trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+ trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+ trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+ trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+ trk->SetFlags(0);
+ trk->SetReserved(0);
+ trk->SetLabel(-3);
+
+ Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+ if (TMath::Abs(pt) > 0.1) {
+ trk->SetA((Int_t) (-0.15*51625./100./pt / 160e-4 * 2));
+ }
+ }
+ }
+ else {
+ trackWord = fPayloadCurr[iWord];
+ }
+ idx++;
+ }
+ }
+ }
+ else if (fCurrHwRev < 1819) {
+ UInt_t fastWord; // fast trigger word
+ ULong64_t trackWord = 0; // extended track word
+ Int_t stack = 0;
+ Int_t idx = 0;
+ for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+ if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
+ stack++;
+ idx = 0;
+ }
+ else {
+ if ((idx == 0) &&
+ ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
+ fastWord = fPayloadCurr[iWord];
+ if (fastWord & (1 << 13))
+ fCurrTrgFlags[sector] |= 1 << (stack+11);
+ AliDebug(1, Form("stack %i: fast trigger word: 0x%08x", stack, fastWord));
+ continue;
+ }
+ else if ((idx & 0x1) == 0x1) {
+ trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+ AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+
+ trk->SetSector(fCurrEquipmentId-kDDLOffset);
+ trk->SetStack((trackWord >> 60) & 0x7);
+ trk->SetA(0);
+ trk->SetB(0);
+ // trk->SetPt(((trackWord & 0xffff) ^ 0x8000) - 0x8000);
+ trk->SetPID(0);
+ trk->SetLayerMask((trackWord >> 16) & 0x3f);
+ trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+ trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+ trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+ trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+ trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+ trk->SetFlags(0);
+ trk->SetReserved(0);
+ trk->SetLabel(-3);
+
+ Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+ if (TMath::Abs(pt) > 0.1) {
+ trk->SetA((Int_t) (0.15*51625./100./trk->Pt() / 160e-4 * 2));
+ }
+ }
+ }
+ else {
+ trackWord = fPayloadCurr[iWord];
+ }
+ idx++;
+ }
+ }
+ }
+ else if (fCurrHwRev < 1860) {
+ UInt_t fastWord; // fast trigger word
+ ULong64_t trackWord = 0; // extended track word
+ Int_t stack = 0;
+ Int_t idx = 0;
+ Bool_t upperWord = kFALSE;
+ Int_t word = 0;
+ for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+ if (fPayloadCurr[iWord] == 0xffe0ffff) { // stack boundary marker
+ stack++;
+ idx = 0;
+ upperWord = kFALSE;
+ }
+ else {
+ // assemble the 32-bit words out of 16-bit blocks
+ if (upperWord) {
+ word |= (fPayloadCurr[iWord] & 0xffff0000);
+ upperWord = kFALSE;
+ }
+ else {
+ // lower word is read first
+ word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
+ upperWord = kTRUE;
+ continue;
+ }
+
+ if ((word & 0xffff0008) == 0x13370008) {
+ fastWord = word;
+ AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, fastWord));
+ if (fastWord & (1 << 13))
+ fCurrTrgFlags[sector] |= 1 << (stack+11);
+ continue;
+ }
+ else if ((idx & 0x1) == 0x1) {
+ trackWord |= ((ULong64_t) word) << 32;
+ AliDebug(1, Form("track debug word: 0x%016llx", trackWord));
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+
+ trk->SetSector(fCurrEquipmentId-kDDLOffset);
+ trk->SetStack((trackWord >> 60) & 0x7);
+ trk->SetA(0);
+ trk->SetB(0);
+ trk->SetPID(0);
+ trk->SetLayerMask((trackWord >> 16) & 0x3f);
+ trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+ trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+ trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+ trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+ trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+ trk->SetFlags(0);
+ trk->SetReserved(0);
+ trk->SetLabel(-3);
+
+ Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+ if (TMath::Abs(pt) > 0.1) {
+ trk->SetA((Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+ }
+ }
+ }
+ else {
+ trackWord = word;
+ }
+ idx++;
+ }
+ }
+
+ }
+ else {
+ ULong64_t trackWord = 0; // this is the debug word
+ Int_t stack = 0;
+ Int_t idx = 0;
+ Bool_t upperWord = kFALSE;
+ Int_t word = 0;
+ for (UInt_t iWord = 4; iWord < fCurrSmHeaderSize; iWord++) {
+ if (fPayloadCurr[iWord] == 0xffe0ffff) {
+ stack++;
+ idx = 0;
+ upperWord = kFALSE;
+ }
+ else {
+ // assemble the 32-bit words out of 16-bit blocks
+ if (upperWord) {
+ word |= (fPayloadCurr[iWord] & 0xffff0000);
+ upperWord = kFALSE;
+ }
+ else {
+ // lower word is read first
+ word = (fPayloadCurr[iWord] & 0xffff0000) >> 16;
+ upperWord = kTRUE;
+ continue;
+ }
+
+ if ((word & 0xffff0008) == 0x13370008) {
+ AliDebug(1, Form("stack %i: fast track word: 0x%08x", stack, word));
+ continue;
+ }
+ else if ((word & 0xffff0010) == 0x13370010) {
+ AliDebug(1, Form("stack %i: tracking done word: 0x%08x", stack, word));
+ fCurrTrgFlags[sector] |= 1 << (stack+11);
+ continue;
+ }
+ else if ((idx & 0x1) == 0x1) {
+ trackWord |= ((ULong64_t) word) << 32;
+ AliDebug(1, Form("track debug word: 0x%16llx", trackWord));
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+ trk->SetSector(fCurrEquipmentId-kDDLOffset);
+ trk->SetStack((trackWord >> 60) & 0x7);
+ trk->SetA(0);
+ trk->SetB(0);
+ trk->SetPID(0);
+ trk->SetLayerMask((trackWord >> 16) & 0x3f);
+ trk->SetTrackletIndex((trackWord >> 22) & 0x3f, 0);
+ trk->SetTrackletIndex((trackWord >> 28) & 0x3f, 1);
+ trk->SetTrackletIndex((trackWord >> 34) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 40) & 0x3f, 3);
+ trk->SetTrackletIndex((trackWord >> 46) & 0x3f, 4);
+ trk->SetTrackletIndex((trackWord >> 52) & 0x3f, 5);
+
+ trk->SetFlags(0);
+ trk->SetReserved(0);
+ trk->SetLabel(-3);
+
+ Float_t pt = (((Int_t) (trackWord & 0xffff) ^ 0x8000) - 0x8000)/128.;
+ if (TMath::Abs(pt) > 0.1) {
+ trk->SetA(-(Int_t) (0.15*51625./100./pt / 160e-4 * 2));
+ }
+ }
+ }
+ else {
+ trackWord = word;
+ }
+ idx++;
+ }
+ }
+ }
+ return 0;
+}
+
+Int_t AliTRDrawStream::ReadTrackingHeader(Int_t stack)
+{
+ // read the tracking information and store it for the given stack
+
+ // index word
+
+ fCurrTrkHeaderIndexWord[stack] = *fPayloadCurr;
+ fCurrTrkHeaderSize[stack] = ((*fPayloadCurr) >> 16) & 0x3ff;
+
+ AliDebug(1, Form("tracking header index word: 0x%08x, size: %i (hw rev: %i)",
+ fCurrTrkHeaderIndexWord[stack], fCurrTrkHeaderSize[stack], fCurrHwRev));
+ Int_t trackingTime = *fPayloadCurr & 0x3ff;
+
+ fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= ((fCurrTrkHeaderIndexWord[stack] >> 10) & 0x1) << (22 + stack);
+ fPayloadCurr++;
+
+ // data words
+ ULong64_t trackWord = 0;
Int_t idx = 0;
- for (UInt_t iWord = 4; iWord < fCurrSmuIndexHeaderSize; iWord++) {
- if (fPayloadCurr[iWord] == 0x10000000) {
- stack++;
- idx = 0;
+ Int_t trackIndex = fTracks ? fTracks->GetEntriesFast() : -1;
+
+ for (UInt_t iWord = 0; iWord < fCurrTrkHeaderSize[stack]; iWord++) {
+
+ if (!(idx & 0x1)) {
+ // first part of 64-bit word
+ trackWord = fPayloadCurr[iWord];
}
else {
- if ((idx == 0) &&
- ((fPayloadCurr[iWord] & 0xfffff0f0) == 0x13370000)) {
- AliDebug(1,Form("stack %i: fast trigger word: 0x%08x", stack, fPayloadCurr[iWord]));
- continue;
- }
- else if ((idx & 0x1)==0x1) {
- trackWord[idx&0x1] = fPayloadCurr[iWord];
- AliDebug(1,Form("track debug word: 0x%08x%08x", trackWord[1], trackWord[0]));
-// if (fTracks)
-// new ((*fTracks)[fTracks->GetEntriesFast()]) AliESDTrdTrack(0, 0, trackWord[0], trackWord[1], fCurrEquipmentId-1024);
+ trackWord |= ((ULong64_t) fPayloadCurr[iWord]) << 32;
+
+ if (trackWord & (1ul << 63)) {
+ if ((trackWord & (0x3ful << 56)) != 0) {
+ // track word
+ AliDebug(2, Form("track word: 0x%016llx", trackWord));
+
+ if (fTracks) {
+ AliESDTrdTrack *trk = new ((*fTracks)[fTracks->GetEntriesFast()])
+ AliESDTrdTrack();
+
+ trk->SetSector(fCurrEquipmentId-kDDLOffset);
+ trk->SetLayerMask((trackWord >> 56) & 0x3f);
+ trk->SetA( (((trackWord >> 38) & 0x3ffff) ^ 0x20000) - 0x20000);
+ trk->SetB( (((trackWord >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
+ trk->SetC( (((trackWord >> 8) & 0xffff) ^ 0x8000) - 0x8000);
+ trk->SetPID((trackWord >> 0) & 0xff);
+ trk->SetStack(stack);
+ trk->SetLabel(-3);
+
+ // now compare the track word with the one generated from the ESD information
+ if (trackWord != trk->GetTrackWord(0)) {
+ AliError(Form("track word 0x%016llx does not match the read one 0x%016llx",
+ trk->GetTrackWord(0), trackWord));
+ }
+ }
+ }
+ else {
+ // done marker (so far only used to set trigger flag)
+ fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= 1 << (27 + stack);
+ fCurrTrkFlags[(fCurrEquipmentId-kDDLOffset)*fgkNstacks + stack] = trackWord;
+
+ AliDebug(2, Form("tracking done marker: 0x%016llx, trigger flags: 0x%08x",
+ trackWord, fCurrTrgFlags[fCurrEquipmentId-kDDLOffset]));
+ AliDebug(2, Form("seg / stack / first / last / done / index : %i %i %lli %lli %lli %i",
+ fCurrEquipmentId - kDDLOffset, stack,
+ (trackWord >> 20) & 0x3ff,
+ (trackWord >> 10) & 0x3ff,
+ (trackWord >> 0) & 0x3ff,
+ trackingTime));
+ }
}
else {
- trackWord[idx&0x1] = fPayloadCurr[iWord];
+ // extended track word
+ AliDebug(2, Form("extended track word: 0x%016llx", trackWord));
+
+ if (fTracks) {
+ AliESDTrdTrack *trk = (AliESDTrdTrack*) (*fTracks)[trackIndex];
+
+ trk->SetFlags((trackWord >> 52) & 0x7ff);
+ 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 >> 12) & 0x3f, 2);
+ trk->SetTrackletIndex((trackWord >> 18) & 0x3f, 3);
+ 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));
+ }
+
+ trackIndex++;
+ }
}
- idx++;
}
+ idx++;
}
- fPayloadCurr += fCurrSmuIndexHeaderSize + 1;
+ fPayloadCurr += fCurrTrkHeaderSize[stack];
+
+ return fCurrTrkHeaderSize[stack];
+}
+
+Int_t AliTRDrawStream::ReadTriggerHeaders()
+{
+ // read all trigger headers present
+
+ AliDebug(1, Form("trigger mask: 0x%03x, fired: 0x%03x\n",
+ fCurrTriggerEnable, fCurrTriggerFired));
+ // loop over potential trigger blocks
+ for (Int_t iTrigger = 0; iTrigger < fgkNtriggers; iTrigger++) {
+ // check for trigger enable
+ if (fCurrTriggerEnable & (1 << iTrigger)) {
+ // check for readout mode and trigger fired
+ if ((fCurrTrgHeaderReadout == 0) || (fCurrTriggerFired & (1 << iTrigger))) {
+ // index word
+ AliDebug(1, Form("trigger index word %i: 0x%08x\n", iTrigger, *fPayloadCurr));
+ fCurrTrgHeaderIndexWord[iTrigger] = *fPayloadCurr;
+ fCurrTrgHeaderSize[iTrigger] = ((*fPayloadCurr) >> 16) & 0x3ff;
+ if (iTrigger == 7) {
+ // timeout trigger, use to extract tracking time
+ fCurrTrgFlags[fCurrEquipmentId-kDDLOffset] |= (*fPayloadCurr & 0x3ff) << 12;
+ }
+
+ fPayloadCurr++;
+ // data words
+ fPayloadCurr += fCurrTrgHeaderSize[iTrigger];
+ }
+ }
+ }
- return fCurrSmuIndexHeaderSize + 1;
+ return 0;
}
-Int_t AliTRDrawStream::ReadStackIndexHeader(Int_t stack)
+Int_t AliTRDrawStream::ReadStackHeader(Int_t stack)
{
- // read the stack index header
+ // read the stack header
// and store the information in the corresponding variables
fCurrStackIndexWord[stack] = *fPayloadCurr;
fCurrStackHeaderVersion[stack] = ((*fPayloadCurr) >> 12) & 0xf;
fCurrLinkMask[stack] = (*fPayloadCurr) & 0xfff;
+ // dumping stack header
+ AliDebug(1, DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
+
if (fPayloadCurr - fPayloadStart >= fPayloadSize - (Int_t) fCurrStackHeaderSize[stack]) {
- StackError(kStackHeaderInvalid, "Stack index header aborted");
+ EquipmentError(kStackHeaderInvalid, "Stack index header %i incomplete", stack);
+ // dumping stack header
+ AliError(DumpRaw(Form("stack %i header", stack), fPayloadCurr, fCurrStackHeaderSize[stack]));
+
return -1;
}
switch (fCurrStackHeaderVersion[stack]) {
- case 0xa:
+ case 0xa:
+ case 0xb:
if (fCurrStackHeaderSize[stack] < 8) {
- StackError(kStackHeaderInvalid, "Stack header smaller than expected!");
+ LinkError(kStackHeaderInvalid, "Stack header smaller than expected!");
return -1;
}
-
+
fCurrCleanCheckout[stack] = fPayloadCurr[1] & 0x1;
fCurrBoardId[stack] = (fPayloadCurr[1] >> 8) & 0xff;
- fCurrHwRev[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
-
+ fCurrHwRevTMU[stack] = (fPayloadCurr[1] >> 16) & 0xffff;
+
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:
- StackError(kStackHeaderInvalid, "Invalid Stack Index Header version %x", fCurrStackHeaderVersion[stack]);
+ EquipmentError(kStackHeaderInvalid, "Invalid Stack Header version %x", fCurrStackHeaderVersion[stack]);
}
-
+
fPayloadCurr += fCurrStackHeaderSize[stack];
return fCurrStackHeaderSize[stack];
}
+Int_t AliTRDrawStream::ReadGTUTrailer()
+{
+ // read the SM trailer containing CRCs from various stages
+
+ UInt_t* trailer = fPayloadStart + fPayloadSize -1;
+
+ // look for the trailer index word from the end
+ 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) & 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[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 0) & 0x1f;
+ fCurrMatchFlagsPostBP[fCurrEquipmentId-kDDLOffset] = (trailer[1] >> 5) & 0x1f;
+ // individual checksums
+ 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 {
+ LinkError(kUnknown, "Invalid GTU trailer");
+ }
+ }
+ else
+ EquipmentError(kUnknown, "trailer index marker mismatch");
+
+ return 0;
+}
+
Int_t AliTRDrawStream::ReadLinkData()
{
// read the data in one link (one HC) until the data endmarker is reached
Int_t count = 0;
UInt_t* startPosLink = fPayloadCurr;
-// printf("----- HC: %i -----\n", fCurrHC);
-// for (Int_t i = 0; i < 3; i++) {
-// printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
-// fPayloadCurr[i*4+0], fPayloadCurr[i*4+1], fPayloadCurr[i*4+2], fPayloadCurr[i*4+3]);
-// }
+ AliDebug(1, DumpRaw(Form("link data from seg %2i slot %i link %2i", fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink),
+ fPayloadCurr, TMath::Min((Int_t) (fPayloadSize - (fPayloadCurr-fPayloadStart)), 100), 0x00000000));
if (fMarkers)
new ((*fMarkers)[fMarkers->GetEntriesFast()])
- AliTRDrawStreamError(-kHCactive, fCurrSm, fCurrStack, fCurrLink);
+ AliTRDrawStreamError(-kHCactive, fCurrEquipmentId-kDDLOffset, fCurrSlot, fCurrLink);
if (fErrorFlags & kDiscardHC)
return count;
- count += ReadTracklets();
- if (fErrorFlags & kDiscardHC)
- return count;
+ if (fCurrTrackletEnable) {
+ count += ReadTracklets();
+ if (fErrorFlags & kDiscardHC)
+ return count;
+ }
+ AliDebug(1, DumpRaw("HC header", fPayloadCurr, 4, 0x00000000));
count += ReadHcHeader();
if (fErrorFlags & kDiscardHC)
return count;
Int_t det = fCurrSm * 30 + fCurrStack * 6 + fCurrLayer;
if (det > -1 && det < 540) {
-
- if ((fAdcArray = fDigitsManager->GetDigits(det))) {
- //fAdcArray->Expand();
- if (fAdcArray->GetNtime() != fCurrNtimebins)
- fAdcArray->Allocate(16, 144, fCurrNtimebins);
- }
- else {
- LinkError(kNoDigits);
- }
-
- if (!fDigitsParam) {
- fDigitsParam = fDigitsManager->GetDigitsParam();
- }
- if (fDigitsParam) {
- fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
- fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
- fDigitsParam->SetADCbaseline(det, 10);
- }
-
- if (fDigitsManager->UsesDictionaries()) {
- fDigitsManager->GetDictionary(det, 0)->Reset();
- fDigitsManager->GetDictionary(det, 1)->Reset();
- fDigitsManager->GetDictionary(det, 2)->Reset();
- }
- if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
- fSignalIndex->SetSM(fCurrSm);
- fSignalIndex->SetStack(fCurrStack);
- fSignalIndex->SetLayer(fCurrLayer);
- fSignalIndex->SetDetNumber(det);
- if (!fSignalIndex->IsAllocated())
- fSignalIndex->Allocate(16, 144, fCurrNtimebins);
- }
-
// ----- check which kind of data -----
if (fCurrMajor & 0x40) {
if ((fCurrMajor & 0x7) == 0x7) {
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
count += fPayloadCurr - startPos;
-
+
// feeding TRAP config
- AliTRDtrapConfig *trapcfg = AliTRDtrapConfig::Instance();
- trapcfg->ReadPackedConfig(fCurrHC, startPos, fPayloadCurr - startPos);
+ AliTRDtrapConfig *trapcfg = AliTRDcalibDB::Instance()->GetTrapConfig();
+ AliTRDmcmSim::ReadPackedConfig(trapcfg, fCurrHC, startPos, fPayloadCurr - startPos);
}
else {
Int_t tpmode = fCurrMajor & 0x7;
AliDebug(1, Form("Checking testpattern (mode %i) data", tpmode));
- ReadTPData(tpmode);
+ count += ReadTPData(tpmode);
}
}
- else if (fCurrMajor & 0x20) {
- AliDebug(1, "This is a zs event");
- count += ReadZSData();
- }
else {
- AliDebug(1, "This is a nozs event");
- count += ReadNonZSData();
+ // reading real data
+ if (fDigitsManager) {
+ if ((fAdcArray = fDigitsManager->GetDigits(det))) {
+ //fAdcArray->Expand();
+ if (fAdcArray->GetNtime() != fCurrNtimebins)
+ fAdcArray->Allocate(16, 144, fCurrNtimebins);
+ }
+ else {
+ LinkError(kNoDigits);
+ }
+
+ if (!fDigitsParam) {
+ fDigitsParam = fDigitsManager->GetDigitsParam();
+ }
+ if (fDigitsParam) {
+ fDigitsParam->SetPretriggerPhase(det, fCurrPtrgPhase);
+ fDigitsParam->SetNTimeBins(det, fCurrNtimebins);
+ fDigitsParam->SetADCbaseline(det, 10);
+ }
+
+ if (fDigitsManager->UsesDictionaries()) {
+ fDigitsManager->GetDictionary(det, 0)->Reset();
+ fDigitsManager->GetDictionary(det, 1)->Reset();
+ fDigitsManager->GetDictionary(det, 2)->Reset();
+ }
+
+ if ((fSignalIndex = fDigitsManager->GetIndexes(det))) {
+ fSignalIndex->SetSM(fCurrSm);
+ fSignalIndex->SetStack(fCurrStack);
+ fSignalIndex->SetLayer(fCurrLayer);
+ fSignalIndex->SetDetNumber(det);
+ if (!fSignalIndex->IsAllocated())
+ fSignalIndex->Allocate(16, 144, fCurrNtimebins);
+ }
+
+ if (fCurrMajor & 0x20) {
+ AliDebug(1, "This is a zs event");
+ count += ReadZSData();
+ }
+ else {
+ AliDebug(1, "This is a nozs event");
+ count += ReadNonZSData();
+ }
+ }
+ else {
+ // just read until data endmarkers
+ while (fPayloadCurr - fPayloadStart < fPayloadSize &&
+ *fPayloadCurr != fgkDataEndmarker)
+ fPayloadCurr++;
+ }
}
}
else {
fStats.fBytesRead += count * sizeof(UInt_t);
}
+ if ((fErrorFlags & kDiscardHC) && fAdcArray)
+ fAdcArray->SetDataInvalid(); // invalidate the data
+
return count;
}
{
// read the tracklets from one HC
- fTrackletArray->Clear();
+ Int_t nTracklets = 0;
UInt_t *start = fPayloadCurr;
- while (*(fPayloadCurr) != fgkTrackletEndmarker &&
- fPayloadCurr - fPayloadStart < fPayloadSize) {
-
- new ((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(*(fPayloadCurr), fCurrHC);
+ while (*(fPayloadCurr) != fgkTrackletEndmarker &&
+ *(fPayloadCurr) != fgkStackEndmarker[0] &&
+ *(fPayloadCurr) != fgkStackEndmarker[1] &&
+ fPayloadCurr - fPayloadStart < (fPayloadSize - 1)) {
+ ++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(),
- fCurrSm, fCurrSlot, fCurrLink, fRawReader->GetEventIndex()));
+ 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
- while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
- fPayloadCurr - fPayloadStart < fPayloadSize))
+ while ((*(fPayloadCurr) == fgkTrackletEndmarker &&
+ fPayloadCurr - fPayloadStart < fPayloadSize))
fPayloadCurr++;
-
+
return fPayloadCurr - start;
}
// read and parse the HC header of one HC
// and store the information in the corresponding variables
+ AliDebug(1, Form("HC header: 0x%08x", *fPayloadCurr));
UInt_t *start = fPayloadCurr;
// check not to be at the data endmarker
- if (*fPayloadCurr == fgkDataEndmarker)
+ if (*fPayloadCurr == fgkDataEndmarker ||
+ *(fPayloadCurr) == fgkStackEndmarker[0] ||
+ *(fPayloadCurr) == fgkStackEndmarker[1]) {
+ LinkError(kHCmismatch, "found endmarker where HC header should be");
return 0;
+ }
fCurrSpecial = (*fPayloadCurr >> 31) & 0x1;
fCurrMajor = (*fPayloadCurr >> 24) & 0x7f;
fCurrSide = (*fPayloadCurr >> 2) & 0x1;
fCurrCheck = (*fPayloadCurr) & 0x3;
- if (fCurrSm != (((Int_t) fCurrEquipmentId) - 1024) ||
- fCurrStack != fCurrSlot ||
- fCurrLayer != fCurrLink / 2 ||
- fCurrSide != fCurrLink % 2) {
+ if ((fCurrSm != (((Int_t) fCurrEquipmentId) - kDDLOffset)) ||
+ (fCurrStack != fCurrSlot) ||
+ (fCurrLayer != fCurrLink / 2) ||
+ (fCurrSide != fCurrLink % 2)) {
LinkError(kHCmismatch,
- "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
+ "HC: %i, %i, %i, %i\n 0x%08x 0x%08x 0x%08x 0x%08x",
fCurrSm, fCurrStack, fCurrLayer, fCurrSide,
- fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);;
+ fPayloadCurr[0], fPayloadCurr[1], fPayloadCurr[2], fPayloadCurr[3]);
}
if (fCurrCheck != 0x1) {
LinkError(kHCcheckFailed);
}
-
+
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;
}
-
+
fPayloadCurr += 1 + fCurrAddHcWords;
-
+
return (fPayloadCurr - start);
}
// evcnt checking missing
Int_t cpu = 0;
Int_t cpufromchannel[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
+ Int_t evno = -1;
Int_t evcnt = 0;
Int_t count = 0;
Int_t mcmcount = -1;
UInt_t* start = fPayloadCurr;
- while (*(fPayloadCurr) != fgkDataEndmarker &&
+ while (*(fPayloadCurr) != fgkDataEndmarker &&
fPayloadCurr - fPayloadStart < fPayloadSize - 1) {
// ----- Checking MCM Header -----
- AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
+ AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
+ UInt_t *startPosMCM = fPayloadCurr;
mcmcount++;
-
+
// ----- checking for proper readout order - ROB -----
+ fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
+ if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
+ lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
- ROBError(kPosUnexp);
+ ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
}
- fCurrRobPos = ROB(*fPayloadCurr);
-
+
// ----- checking for proper readout order - MCM -----
- if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
+ fCurrMcmPos = MCM(*fPayloadCurr);
+ if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
- MCMError(kPosUnexp);
+ MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
+ }
+
+ if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
+ if (evno == -1) {
+ evno = EvNo(*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
+ }
}
- fCurrMcmPos = MCM(*fPayloadCurr);
-
fPayloadCurr++;
-
+
evcnt = 0x3f & *fPayloadCurr >> 26;
cpu = -1;
channelcount = 0;
expadcval = (1 << 9) | (fCurrRobPos << 6) | (fCurrMcmPos << 2) | cpu;
wordcount = 0;
}
-
+
while (count < 10) {
+ if (*fPayloadCurr == fgkDataEndmarker) {
+ MCMError(kMissTpData);
+ return (fPayloadCurr - start);
+ }
+
if (channelcount % 2 == 0)
expword = 0x3;
- else
+ else
expword = 0x2;
-
+
if (mode == 1) {
// ----- TP 1 -----
expword |= expadcval << 2;
}
else if (mode == 2) {
// ----- TP 2 ------
- expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
- ((fCurrStack + 1) << 15) |
- (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
+ expword = ((0x3f & evcnt) << 26) | ((fCurrSm + 1) << 21) | ((fCurrLayer + 1) << 18) |
+ ((fCurrStack + 1) << 15) |
+ (fCurrRobPos << 12) | (fCurrMcmPos << 8) | (cpu << 6) | (wordcount + 1);
}
else if (mode == 3) {
// ----- TP 3 -----
- expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
- (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
+ expword = ((0xfff & evcnt) << 20) | (fCurrSm << 15) | (fCurrLink/2 << 12) | (fCurrStack << 9) |
+ (fCurrRobPos << 6) | (fCurrMcmPos << 2) | (cpu << 0);
}
else {
expword = 0;
}
diff = *fPayloadCurr ^ expword;
+ AliDebug(11, Form("Comparing ch %2i, word %2i (cpu %i): 0x%08x <-> 0x%08x",
+ channelcount, wordcount, cpu, *fPayloadCurr, expword));
+
if (diff != 0) {
MCMError(kTPmismatch,
- "Seen 0x%08x, expected 0x%08x, diff: 0x%08x (0x%02x)",
- *fPayloadCurr, expword, diff, 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24));;
+ "Seen 0x%08x, expected 0x%08x, diff: 0x%08x, 0x%04x, 0x%02x - word %2i (cpu %i, ch %i)",
+ *fPayloadCurr, expword, diff,
+ 0xffff & (diff | diff >> 16),
+ 0xff & (diff | diff >> 8 | diff >> 16 | diff >> 24),
+ wordcount, cpu, channelcount);;
}
fPayloadCurr++;
count++;
wordcount++;
+ if (*fPayloadCurr == fgkDataEndmarker)
+ return (fPayloadCurr - start);
}
channelcount++;
}
// continue with next MCM
+
+ if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
+ AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
+ startPosMCM, fPayloadCurr - startPosMCM));
+ }
+
}
- return fPayloadCurr - start;
+ return fPayloadCurr - start;
}
Int_t AliTRDrawStream::ReadZSData()
{
// read the zs data from one link from the current reading position
-
+
UInt_t *start = fPayloadCurr;
-
+
Int_t mcmcount = 0;
Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
Int_t channelcount = 0;
Int_t lastrobpos = -1;
if (fCurrNtimebins != fNtimebins) {
- if (fNtimebins > 0)
+ if (fNtimebins > 0)
LinkError(kNtimebinsChanged,
"No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
fNtimebins = fCurrNtimebins;
}
-
+
timebins = fNtimebins;
-
- while (*(fPayloadCurr) != fgkDataEndmarker &&
+
+ while (*(fPayloadCurr) != fgkDataEndmarker &&
+ *(fPayloadCurr) != fgkStackEndmarker[0] &&
+ *(fPayloadCurr) != fgkStackEndmarker[1] &&
fPayloadCurr - fPayloadStart < fPayloadSize) {
-
+
// ----- Checking MCM Header -----
- AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
+ AliDebug(2, DumpMcmHeader("MCM header: ", *fPayloadCurr));
UInt_t *startPosMCM = fPayloadCurr;
-
+
// ----- checking for proper readout order - ROB -----
+ fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
+ if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
+ lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
- ROBError(kPosUnexp);
+ ROBError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
+ GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos, GetROBReadoutPos(fCurrRobPos)));
}
- fCurrRobPos = ROB(*fPayloadCurr);
-
+
// ----- checking for proper readout order - MCM -----
+ fCurrMcmPos = MCM(*fPayloadCurr);
if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
- lastmcmpos = GetMCMReadoutPos(lastmcmpos);
+ lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
- MCMError(kPosUnexp);
+ MCMError(kPosUnexp, Form("#%i after #%i and #%i in readout order",
+ GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos, GetMCMReadoutPos(fCurrMcmPos)));
}
- fCurrMcmPos = MCM(*fPayloadCurr);
-
- if (EvNo(*fPayloadCurr) != evno) {
- if (evno == -1)
+
+#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(kPtrgCntMismatch, "%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);
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 ADC channels -----
- AliDebug(2, Form("ADC mask: 0x%08x", *fPayloadCurr));
-
+ AliDebug(2, DumpAdcMask("ADC mask: ", *fPayloadCurr));
+
// ----- analysing the ADC mask -----
channelcount = 0;
channelcountExp = GetNActiveChannelsFromMask(*fPayloadCurr);
channelcountMax = GetNActiveChannels(*fPayloadCurr);
Int_t channelmask = GetActiveChannels(*fPayloadCurr);
Int_t channelno = -1;
- fPayloadCurr++;
+ fPayloadCurr++;
if (channelcountExp != channelcountMax) {
if (channelcountExp > channelcountMax) {
channelcountExp = channelcountMax;
channelcountMax = temp;
}
- while (channelcountExp < channelcountMax && channelcountExp < 21 &&
+ while (channelcountExp < channelcountMax && channelcountExp < 21 &&
fPayloadCurr - fPayloadStart < fPayloadSize - 10 * channelcountExp - 1) {
MCMError(kAdcMaskInconsistent,
- "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
- *(fPayloadCurr + 10 * channelcountExp),
+ "Possible MCM-H: 0x%08x, possible ADC-mask: 0x%08x",
+ *(fPayloadCurr + 10 * channelcountExp),
*(fPayloadCurr + 10 * channelcountExp + 1) );
- if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
+ if (!CouldBeMCMhdr( *(fPayloadCurr + 10 * channelcountExp)) && !CouldBeADCmask( *(fPayloadCurr + 10 * channelcountExp + 1)))
channelcountExp++;
else {
break;
}
}
MCMError(kAdcMaskInconsistent,
- "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
+ "Inconsistency in no. of active channels: Counter: %i, Mask: %i, chosen: %i!",
GetNActiveChannels(fPayloadCurr[-1]), GetNActiveChannelsFromMask(fPayloadCurr[-1]), channelcountExp);
}
- AliDebug(2, Form("expecting %i active channels, timebins: %i", channelcountExp, fCurrNtimebins));
-
+ AliDebug(2, Form("expecting %i active channels, %i timebins", channelcountExp, fCurrNtimebins));
+
// ----- reading marked ADC channels -----
while (channelcount < channelcountExp && *(fPayloadCurr) != fgkDataEndmarker) {
if (channelno < 20)
channelno++;
while (channelno < 20 && (channelmask & 1 << channelno) == 0)
channelno++;
-
+
if (fCurrNtimebins > 30) {
currentTimebin = ((*fPayloadCurr >> 2) & 0x3f);
timebins = ((*fPayloadCurr >> 8) & 0xf) * 3;
- }
+ }
else {
currentTimebin = 0;
}
-
+
adcwc = 0;
- AliDebug(2, Form("Now looking %i words", timebins / 3));
+ Int_t nADCwords = (timebins + 2) / 3;
+ AliDebug(3, Form("Now reading %i words for channel %2i", nADCwords, channelno));
Int_t adccol = adccoloff - channelno;
Int_t padcol = padcoloff - channelno;
-// if (adccol < 3 || adccol > 165)
-// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
+// if (adccol < 3 || adccol > 165)
+// AliInfo(Form("writing channel %i of det %3i %i:%2i to adcrow/-col: %i/%i padcol: %i",
// channelno, fCurrHC/2, fCurrRobPos, fCurrMcmPos, row, adccol, padcol));
- while (adcwc < timebins / 3 &&
- *(fPayloadCurr) != fgkDataEndmarker &&
- fPayloadCurr - fPayloadStart < fPayloadSize) {
+ while ((adcwc < nADCwords) &&
+ (*(fPayloadCurr) != fgkDataEndmarker) &&
+ (fPayloadCurr - fPayloadStart < fPayloadSize)) {
int check = 0x3 & *fPayloadCurr;
if (channelno % 2 != 0) { // odd channel
if (check != 0x2 && channelno < 21) {
MCMError(kAdcCheckInvalid,
- "%i for %2i. ADC word in odd channel %i",
+ "%i for %2i. ADC word in odd channel %i",
check, adcwc+1, channelno);
}
}
else { // even channel
if (check != 0x3 && channelno < 21) {
MCMError(kAdcCheckInvalid,
- "%i for %2i. ADC word in even channel %i",
+ "%i for %2i. ADC word in even channel %i",
check, adcwc+1, channelno);
}
}
-
- // 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++;
}
-
- if (adcwc != timebins / 3)
+
+ if (adcwc != nADCwords)
MCMError(kAdcDataAbort);
-
- // adding index
+
+ // adding index
if (padcol > 0 && padcol < 144) {
fSignalIndex->AddIndexRC(row, padcol);
}
-
+
channelcount++;
}
}
if (channelcount != channelcountExp)
MCMError(kAdcChannelsMiss);
-
+
mcmcount++;
if (fCurrSm > -1 && fCurrSm < 18) {
fStats.fStatsSector[fCurrSm].fStatsHC[fCurrHC%60].fNMCMs++;
}
if (IsDumping() && DumpingMCM(fCurrHC/2, fCurrRobPos, fCurrMcmPos)) {
- DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
- startPosMCM, fPayloadCurr - startPosMCM);
+ AliInfo(DumpRaw(Form("Event %i: Det %3i ROB %i MCM %2i", fRawReader->GetEventIndex(), fCurrHC/2, fCurrRobPos, fCurrMcmPos),
+ startPosMCM, fPayloadCurr - startPosMCM));
}
// continue with next MCM
// check for missing MCMs (if header suppression is inactive)
if (((fCurrMajor & 0x1) == 0) && (mcmcount != mcmcountExp)) {
LinkError(kMissMcmHeaders,
- "No. of MCM headers %i not as expected: %i",
+ "No. of MCM headers %i not as expected: %i",
mcmcount, mcmcountExp);
}
Int_t AliTRDrawStream::ReadNonZSData()
{
// read the non-zs data from one link from the current reading position
-
+
UInt_t *start = fPayloadCurr;
-
+
Int_t mcmcount = 0;
Int_t mcmcountExp = fCurrStack == 2 ? 48 : 64;
Int_t channelcount = 0;
Int_t lastrobpos = -1;
if (fCurrNtimebins != fNtimebins) {
- if (fNtimebins > 0)
+ if (fNtimebins > 0)
LinkError(kNtimebinsChanged,
"No. of timebins changed from %i to %i", fNtimebins, fCurrNtimebins);
fNtimebins = fCurrNtimebins;
}
-
+
timebins = fNtimebins;
-
- while (*(fPayloadCurr) != fgkDataEndmarker &&
+
+ while (*(fPayloadCurr) != fgkDataEndmarker &&
fPayloadCurr - fPayloadStart < fPayloadSize - 2) {
-
+
// ----- Checking MCM Header -----
AliDebug(2, Form("MCM header: 0x%08x", *fPayloadCurr));
-
+
// ----- checking for proper readout order - ROB -----
+ fCurrRobPos = ROB(*fPayloadCurr);
if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) >= lastrobpos) {
+ if (GetROBReadoutPos(ROB(*fPayloadCurr) / 2) > lastrobpos)
+ lastmcmpos = -1;
lastrobpos = GetROBReadoutPos(ROB(*fPayloadCurr) / 2);
}
else {
- ROBError(kPosUnexp);
+ ROBError(kPosUnexp, Form("#%i after #%i in readout order", GetROBReadoutPos(ROB(*fPayloadCurr) / 2), lastrobpos));
}
- fCurrRobPos = ROB(*fPayloadCurr);
-
+
// ----- checking for proper readout order - MCM -----
- if (GetMCMReadoutPos(MCM(*fPayloadCurr)) >= (lastmcmpos + 1) % 16) {
- lastmcmpos = GetMCMReadoutPos(*fPayloadCurr);
+ fCurrMcmPos = MCM(*fPayloadCurr);
+ if (GetMCMReadoutPos(MCM(*fPayloadCurr)) > lastmcmpos) {
+ lastmcmpos = GetMCMReadoutPos(MCM(*fPayloadCurr));
}
else {
- MCMError(kPosUnexp);
+ MCMError(kPosUnexp, Form("#%i after #%i in readout order", GetMCMReadoutPos(MCM(*fPayloadCurr)), lastmcmpos));
}
- fCurrMcmPos = MCM(*fPayloadCurr);
-
- if (EvNo(*fPayloadCurr) != evno) {
- if (evno == -1)
+
+ if (EvNo(*fPayloadCurr) != (evno & 0xfffff)) {
+ if (evno == -1) {
evno = EvNo(*fPayloadCurr);
+ }
else {
- MCMError(kPtrgCntMismatch, "%i <-> %i", evno, EvNo(*fPayloadCurr));
+ 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
}
}
-
+
channelcount = 0;
channelcountExp = 21;
int channelno = -1;
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 &&
+ while (channelcount < channelcountExp &&
*(fPayloadCurr) != fgkDataEndmarker) {
if (channelno < 20)
channelno++;
-
+
currentTimebin = 0;
-
+
adcwc = 0;
- AliDebug(2, Form("Now looking %i words", timebins / 3));
+ Int_t nADCwords = (timebins + 2) / 3;
+ AliDebug(2, Form("Now looking %i words", nADCwords));
Int_t adccol = adccoloff - channelno;
Int_t padcol = padcoloff - channelno;
- while (adcwc < timebins / 3 &&
- *(fPayloadCurr) != fgkDataEndmarker &&
- fPayloadCurr - fPayloadStart < fPayloadSize) {
+ while ((adcwc < nADCwords) &&
+ (*(fPayloadCurr) != fgkDataEndmarker) &&
+ (fPayloadCurr - fPayloadStart < fPayloadSize)) {
int check = 0x3 & *fPayloadCurr;
if (channelno % 2 != 0) { // odd channel
if (check != 0x2 && channelno < 21) {
MCMError(kAdcCheckInvalid,
- "%i for %2i. ADC word in odd channel %i",
+ "%i for %2i. ADC word in odd channel %i",
check, adcwc+1, channelno);
}
}
else { // even channel
if (check != 0x3 && channelno < 21) {
MCMError(kAdcCheckInvalid,
- "%i for %2i. ADC word in even channel %i",
+ "%i for %2i. ADC word in even channel %i",
check, adcwc+1, channelno);
}
}
-
- // 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++;
}
- if (adcwc != timebins / 3)
+ if (adcwc != nADCwords)
MCMError(kAdcDataAbort);
-
- // adding index
+
+ // adding index
if (padcol > 0 && padcol < 144) {
fSignalIndex->AddIndexRC(row, padcol);
}
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
+
+ if (!fCurrStackEndmarkerAvail)
+ return 0;
+
+ UInt_t *start = fPayloadCurr;
+
+ // read until data endmarkers
+ while ((fPayloadCurr - fPayloadStart < fPayloadSize-1) &&
+ ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
+ (fPayloadCurr[1] != fgkStackEndmarker[1])))
+ fPayloadCurr++;
+
+ if ((fPayloadCurr - start) != 0)
+ StackError(kUnknown, "skipped %i words to reach stack endmarker", fPayloadCurr - start);
+
+ AliDebug(2, Form("stack endmarker: 0x%08x 0x%08x", fPayloadCurr[0], fPayloadCurr[1]));
+
+ // goto next stack
+ fPayloadCurr++;
+ fPayloadCurr++;
+
+ return (fPayloadCurr-start);
+}
+
Int_t AliTRDrawStream::SeekNextLink()
{
+ // proceed in raw data stream till the next link
+
UInt_t *start = fPayloadCurr;
// read until data endmarkers
while (fPayloadCurr - fPayloadStart < fPayloadSize &&
+ ((fPayloadCurr[0] != fgkStackEndmarker[0]) ||
+ (fPayloadCurr[1] != fgkStackEndmarker[1])) &&
*fPayloadCurr != fgkDataEndmarker)
fPayloadCurr++;
return (fPayloadCurr - start);
}
-Bool_t AliTRDrawStream::ConnectTracklets(TTree *trklTree)
-{
- 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, ...)
-{
- // register error according to error code on equipment level
+{
+ // register error according to error code on equipment level
// and return the corresponding error message
- fLastError.fSector = fCurrEquipmentId - 1024;
+ fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = -1;
fLastError.fLink = -1;
fLastError.fRob = -1;
(this->*fStoreError)();
va_list ap;
- if (fgErrorDebugLevel[err] > 10)
+ if (fgErrorDebugLevel[err] > 10)
AliDebug(fgErrorDebugLevel[err],
- Form("Event %6i: Eq. %2d - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
+ Form("Event %6i: Eq. %2d - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
- else
- AliError(Form("Event %6i: Eq. %2d - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fgErrorMessages[err],
+ else
+ AliError(Form("Event %6i: Eq. %2d - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
-}
+}
void AliTRDrawStream::StackError(ErrorCode_t err, const char *const msg, ...)
-{
- // register error according to error code on stack level
+{
+ // register error according to error code on stack level
// and return the corresponding error message
- fLastError.fSector = fCurrEquipmentId - 1024;
+ fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = -1;
fLastError.fRob = -1;
(this->*fStoreError)();
va_list ap;
- if (fgErrorDebugLevel[err] > 0)
- AliDebug(fgErrorDebugLevel[err],
- Form("Event %6i: Eq. %2d S %i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
+ if (fgErrorDebugLevel[err] > 0)
+ AliDebug(fgErrorDebugLevel[err],
+ Form("Event %6i: Eq. %2d S %i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
- else
- AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgErrorMessages[err],
+ else
+ AliError(Form("Event %6i: Eq. %2d S %i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
-}
+}
void AliTRDrawStream::LinkError(ErrorCode_t err, const char *const msg, ...)
-{
- // register error according to error code on link level
+{
+ // register error according to error code on link level
// and return the corresponding error message
- fLastError.fSector = fCurrEquipmentId - 1024;
+ fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = -1;
va_list ap;
if (fgErrorDebugLevel[err] > 0)
- AliDebug(fgErrorDebugLevel[err],
- Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
+ AliDebug(fgErrorDebugLevel[err],
+ Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
- else
- AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgErrorMessages[err],
+ else
+ AliError(Form("Event %6i: Eq. %2d S %i l %2i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
-}
+}
void AliTRDrawStream::ROBError(ErrorCode_t err, const char *const msg, ...)
-{
- // register error according to error code on ROB level
+{
+ // register error according to error code on ROB level
// and return the corresponding error message
- fLastError.fSector = fCurrEquipmentId - 1024;
+ fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = fCurrRobPos;
(this->*fStoreError)();
va_list ap;
- if (fgErrorDebugLevel[err] > 0)
- AliDebug(fgErrorDebugLevel[err],
- Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
+ if (fgErrorDebugLevel[err] > 0)
+ AliDebug(fgErrorDebugLevel[err],
+ Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
- else
- AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgErrorMessages[err],
+ else
+ AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i - %s : %s",
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
-}
+}
void AliTRDrawStream::MCMError(ErrorCode_t err, const char *const msg, ...)
-{
- // register error according to error code on MCM level
+{
+ // register error according to error code on MCM level
// and return the corresponding error message
- fLastError.fSector = fCurrEquipmentId - 1024;
+ fLastError.fSector = fCurrEquipmentId - kDDLOffset;
fLastError.fStack = fCurrSlot;
fLastError.fLink = fCurrLink;
fLastError.fRob = fCurrRobPos;
(this->*fStoreError)();
va_list ap;
- if (fgErrorDebugLevel[err] > 0)
- AliDebug(fgErrorDebugLevel[err],
+ if (fgErrorDebugLevel[err] > 0)
+ AliDebug(fgErrorDebugLevel[err],
Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
- else
+ else
AliError(Form("Event %6i: Eq. %2d S %i l %2i ROB %i MCM %2i - %s : %s",
- fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgErrorMessages[err],
+ fRawReader->GetEventIndex(), fCurrEquipmentId, fCurrSlot, fCurrLink, fCurrRobPos, fCurrMcmPos, fgkErrorMessages[err],
(va_start(ap, msg), vsprintf(fErrorBuffer, msg, ap), va_end(ap), fErrorBuffer) ));
fErrorFlags |= fgErrorBehav[err];
}
const char* AliTRDrawStream::GetErrorMessage(ErrorCode_t errCode)
-{
+{
// return the error message for the given error code
- if (errCode > 0 && errCode < kLastErrorCode)
- return fgErrorMessages[errCode];
- else
- return "";
-}
+ if (errCode > 0 && errCode < kLastErrorCode)
+ return fgkErrorMessages[errCode];
+ else
+ return "";
+}
void AliTRDrawStream::AliTRDrawStats::ClearStats()
{
}
void AliTRDrawStream::SetDumpMCM(Int_t det, Int_t rob, Int_t mcm, Bool_t dump)
-{
+{
// mark MCM for dumping of raw data
if (dump) {
- fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
+ fDumpMCM[fNDumpMCMs++] = (det << 7) | (rob << 4) | mcm;
}
else {
Int_t iMCM;
}
}
-Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm)
+Bool_t AliTRDrawStream::DumpingMCM(Int_t det, Int_t rob, Int_t mcm) const
{
// check if MCM data should be dumped
return kFALSE;
}
-void AliTRDrawStream::DumpRaw(TString title, UInt_t *start, Int_t length)
+TString AliTRDrawStream::DumpRaw(TString title, const UInt_t *start, Int_t length, UInt_t endmarker)
{
// dump raw data
title += "\n";
- Int_t pos = 0;
- for ( ; pos+3 < length; pos += 4) {
- title += Form("0x%08x 0x%08x 0x%08x 0x%08x\n",
- start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
- }
- for ( ; pos < length; pos++) {
- title += Form("0x%08x ", start[pos]);
+ for (Int_t pos = 0; pos < length; pos += 4) {
+ if ((start[pos+0] != endmarker) && pos+0 < length)
+ if ((start[pos+1] != endmarker && pos+1 < length))
+ if ((start[pos+2] != endmarker && pos+2 < length))
+ if ((start[pos+3] != endmarker && pos+3 < length))
+ title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
+ else {
+ title += Form(" 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ start[pos+0], start[pos+1], start[pos+2], start[pos+3]);
+ return title;
+ }
+ else {
+ title += Form(" 0x%08x 0x%08x 0x%08x\n",
+ start[pos+0], start[pos+1], start[pos+2]);
+ return title;
+ }
+ else {
+ title += Form(" 0x%08x 0x%08x\n",
+ start[pos+0], start[pos+1]);
+ return title;
+ }
+ else {
+ title += Form(" 0x%08x\n",
+ start[pos+0]);
+ return title;
+ }
}
- AliInfo(title);
+ return title;
}
-AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
+TString AliTRDrawStream::DumpMcmHeader(TString title, UInt_t word)
+{
+ title += Form("0x%08x -> ROB: %i, MCM: %2i",
+ word, ROB(word), MCM(word));
+ return title;
+}
+
+TString AliTRDrawStream::DumpAdcMask(TString title, UInt_t word)
+{
+ title += Form("0x%08x -> #ch : %2i, 0x%06x (%2i ch)",
+ word, GetNActiveChannels(word), GetActiveChannels(word), GetNActiveChannelsFromMask(word));
+ return title;
+}
+
+AliTRDrawStream::AliTRDrawStreamError::AliTRDrawStreamError(Int_t error, Int_t sector, Int_t stack, Int_t link, Int_t rob, Int_t mcm) :
fError(error),
fSector(sector),
fStack(stack),
- fLink(link),
+ fLink(link),
fRob(rob),
fMcm(mcm)
{
// ctor
}
+
+void AliTRDrawStream::SortTracklets(TClonesArray *trklArray, TList &sortedTracklets, Int_t *indices)
+{
+ // sort tracklets for referencing from GTU tracks
+
+ if (!trklArray)
+ return;
+
+ Int_t nTracklets = trklArray->GetEntriesFast();
+
+ Int_t lastHC = -1;
+ for (Int_t iTracklet = 0; iTracklet < nTracklets; iTracklet++) {
+ AliTRDtrackletBase *trkl = (AliTRDtrackletBase*) ((*trklArray)[iTracklet]);
+ Int_t hc = trkl->GetHCId();
+ if ((hc < 0) || (hc >= 1080)) {
+ AliErrorClass(Form("HC for tracklet: 0x%08x out of range: %i", trkl->GetTrackletWord(), trkl->GetHCId()));
+ continue;
+ }
+ AliDebugClass(5, Form("hc: %4i : 0x%08x z: %2i", hc, trkl->GetTrackletWord(), trkl->GetZbin()));
+ if (hc != lastHC) {
+ AliDebugClass(2, Form("set tracklet index for HC %i to %i", hc, iTracklet));
+ indices[hc] = iTracklet + 1;
+ lastHC = hc;
+ }
+ }
+
+ for (Int_t iDet = 0; iDet < 540; iDet++) {
+ Int_t trklIndexA = indices[2*iDet + 0] - 1;
+ Int_t trklIndexB = indices[2*iDet + 1] - 1;
+ Int_t trklIndex = sortedTracklets.GetEntries();
+ AliTRDtrackletBase *trklA = trklIndexA > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+ AliTRDtrackletBase *trklB = trklIndexB > -1 ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+ AliTRDtrackletBase *trklNext = 0x0;
+ while (trklA != 0x0 || trklB != 0x0) {
+ AliDebugClass(5, Form("det %i - A: %i/%i -> %p, B: %i/%i -> %p",
+ iDet, trklIndexA, nTracklets, trklA, trklIndexB, nTracklets, trklB));
+ if (trklA == 0x0) {
+ trklNext = trklB;
+ trklIndexB++;
+ trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+ if (trklB && trklB->GetHCId() != 2*iDet + 1)
+ trklB = 0x0;
+ }
+ else if (trklB == 0x0) {
+ trklNext = trklA;
+ trklIndexA++;
+ trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+ if (trklA && trklA->GetHCId() != 2*iDet)
+ trklA = 0x0;
+ }
+ else {
+ if (trklA->GetZbin() <= trklB->GetZbin()) {
+ trklNext = trklA;
+ trklIndexA++;
+ trklA = trklIndexA < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexA]) : 0x0;
+ if (trklA && trklA->GetHCId() != 2*iDet)
+ trklA = 0x0;
+ }
+ else {
+ trklNext = trklB;
+ trklIndexB++;
+ trklB = trklIndexB < nTracklets ? (AliTRDtrackletBase*) ((*trklArray)[trklIndexB]) : 0x0;
+ if (trklB && trklB->GetHCId() != 2*iDet + 1)
+ trklB = 0x0;
+ }
+ }
+ if (trklNext) {
+ sortedTracklets.Add(trklNext);
+
+ }
+ }
+
+ // updating tracklet indices as in output
+ if (sortedTracklets.GetEntries() != 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));
+ }
+ }
+ }
+}