Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions DataFormats/Detectors/TRD/include/DataFormatsTRD/RawData.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,6 @@ uint32_t getlinkerrorflag(const HalfCRUHeader& cruhead, const uint32_t link);
uint32_t getlinkdatasize(const HalfCRUHeader& cruhead, const uint32_t link);
uint32_t getlinkerrorflags(const HalfCRUHeader& cruheader, std::array<uint32_t, 15>& linkerrorflags);
uint32_t getlinkdatasizes(const HalfCRUHeader& cruheader, std::array<uint32_t, 15>& linksizes);
std::ostream& operator<<(std::ostream& stream, const TrackletHCHeader& halfchamberheader);
std::ostream& operator<<(std::ostream& stream, const TrackletMCMHeader& mcmhead);
std::ostream& operator<<(std::ostream& stream, const TrackletMCMData& tracklet);
void dumpHalfChamber(o2::trd::TrackletHCHeader& halfchamber);
std::ostream& operator<<(std::ostream& stream, const HalfCRUHeader& halfcru);
bool trackletMCMHeaderSanityCheck(o2::trd::TrackletMCMHeader& header);
bool trackletHCHeaderSanityCheck(o2::trd::TrackletHCHeader& header);
bool digitMCMHeaderSanityCheck(o2::trd::DigitMCMHeader* header);
bool digitMCMADCMaskSanityCheck(o2::trd::DigitMCMADCMask& mask, int numberofbitsset);
bool digitMCMWordSanityCheck(o2::trd::DigitMCMData* word, int adcchannel);
bool halfCRUHeaderSanityCheck(const o2::trd::HalfCRUHeader& header);
void printDigitHCHeader(o2::trd::DigitHCHeader& header, uint32_t headers[3]);

Expand Down Expand Up @@ -480,6 +470,7 @@ void printDigitMCMADCMask(const o2::trd::DigitMCMADCMask& digitmcmadcmask);

void printHalfCRUHeader(const o2::trd::HalfCRUHeader& halfcru);
void clearHalfCRUHeader(o2::trd::HalfCRUHeader& halfcru);
bool sanityCheckTrackletHCHeader(const o2::trd::TrackletHCHeader& header);
bool sanityCheckTrackletMCMHeader(const o2::trd::TrackletMCMHeader& header);
bool sanityCheckDigitMCMHeader(const o2::trd::DigitMCMHeader& header);
bool sanityCheckDigitMCMADCMask(const o2::trd::DigitMCMADCMask& mask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ enum ParsingErrors {
TrackletDataWrongOrdering, // the tracklet data is not arriving in increasing MCM order
TrackletDataDuplicateMCM, // we see more than one TrackletMCMHeader for the same MCM
TrackletNoTrackletEndMarker, // got to the end of the buffer with out finding a tracklet end marker.
TrackletNoSecondEndMarker, // we expected to see a second tracklet end marker, but found something else instead
TrackletMCMDataFailure, // invalid word for TrackletMCMData detected
TrackletDataMissing, // we expected tracklet data but got an endmarker instead
TrackletExitingNoTrackletEndMarker, // got to the end of the buffer exiting tracklet parsing with no tracklet end marker
UnparsedTrackletDataRemaining, // the tracklet parsing has finished correctly, but there is still data left on the link (CRU puts incorrect link size or corrupt data?)
UnparsedDigitDataRemaining, // the digit parsing has finished correctly, but there is still data left on the link (CRU puts incorrect link size or corrupt data? RDH > 8kByte before?)
Expand Down Expand Up @@ -84,6 +87,9 @@ static const std::unordered_map<int, std::string> ParsingErrorsString = {
{TrackletDataWrongOrdering, "TrackletDataWrongOrdering"},
{TrackletDataDuplicateMCM, "TrackletDataDuplicateMCM"},
{TrackletNoTrackletEndMarker, "TrackletNoTrackletEndMarker"},
{TrackletNoSecondEndMarker, "TrackletNoSecondEndMarker"},
{TrackletMCMDataFailure, "TrackletMCMDataFailure"},
{TrackletDataMissing, "TrackletDataMissing"},
{TrackletExitingNoTrackletEndMarker, "TrackletExitingNoTrackletEndMarker"},
{UnparsedTrackletDataRemaining, "UnparsedTrackletDataRemaining"},
{UnparsedDigitDataRemaining, "UnparsedDigitDataRemaining"},
Expand Down
20 changes: 18 additions & 2 deletions DataFormats/Detectors/TRD/src/RawData.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,23 @@ bool halfCRUHeaderSanityCheck(const o2::trd::HalfCRUHeader& header)
return true;
}

bool sanityCheckTrackletHCHeader(const o2::trd::TrackletHCHeader& header)
{
if (header.one != 1) {
return false;
}
if (((~header.supermodule) & 0x1f) >= NSECTOR) {
return false;
}
if (((~header.stack) & 0x7) >= NSTACK) {
return false;
}
if (((~header.layer) & 0x7) >= NLAYER) {
return false;
}
return true;
}

bool sanityCheckTrackletMCMHeader(const o2::trd::TrackletMCMHeader& header)
{
// a bit limited to what we can check.
Expand Down Expand Up @@ -298,7 +315,7 @@ bool sanityCheckDigitMCMADCMask(const o2::trd::DigitMCMADCMask& mask)
if (mask.j != 0xc) {
return false;
}
int counter = (~mask.c) & 0x1f;
unsigned int counter = (~mask.c) & 0x1f;
std::bitset<NADCMCM> headerMask(mask.adcmask);
return (counter == headerMask.count());
}
Expand Down Expand Up @@ -376,7 +393,6 @@ void printDigitHCHeaders(o2::trd::DigitHCHeader& header, uint32_t headers[3], in
void printDigitHCHeader(o2::trd::DigitHCHeader& header, uint32_t headers[3])
{
printDigitHCHeaders(header, headers, -1, 0, true);
int countheaderwords = header.numberHCW;
int index;
//for the currently 3 implemented other header words, they can come in any order, and are identified by their reserved portion
for (int countheaderwords = 0; countheaderwords < header.numberHCW; ++countheaderwords) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class CruRawReader

HalfCRUHeader mCurrentHalfCRUHeader; // are we waiting for new header or currently parsing the payload of on
HalfCRUHeader mPreviousHalfCRUHeader; // are we waiting for new header or currently parsing the payload of on
bool mPreviousHalfCRUHeaderSet; // flag, whether we can use mPreviousHalfCRUHeader for additional sanity checks
DigitHCHeader mDigitHCHeader; // Digit HalfChamber header we are currently on.
uint16_t mTimeBins{constants::TIMEBINS}; // the number of time bins to be read out (default 30, can be overwritten from digit HC header)
bool mHaveSeenDigitHCHeader3{false}; // flag, whether we can compare an incoming DigitHCHeader3 with a header we have seen before
Expand Down
19 changes: 11 additions & 8 deletions Detectors/TRD/reconstruction/macros/CompareDigitsAndTracklets.C
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,20 @@ void CompareDigitsAndTracklets(bool ignoreTrkltPid = false,
trackletTreereco->GetEvent(iev);

// compare trigger records
bool compareTriggerRecords = true;
if (trigRecs->size() != trigRecsReco->size()) {
LOG(warn) << "Number of trigger records does not match for entry " << iev;
continue;
compareTriggerRecords = false;
}
for (size_t iTrig = 0; iTrig < trigRecs->size(); ++iTrig) {
const auto& trig = trigRecs->at(iTrig);
const auto& trigReco = trigRecsReco->at(iTrig);
if (!(trig == trigReco)) {
LOGF(error, "Trigger records don't match at trigger %lu. Reference orbit/bc (%u/%u), orbit/bc (%u/%u)",
iTrig, trig.getBCData().orbit, trig.getBCData().bc, trigReco.getBCData().orbit, trigReco.getBCData().bc);
break;
if (compareTriggerRecords) {
for (size_t iTrig = 0; iTrig < trigRecs->size(); ++iTrig) {
const auto& trig = trigRecs->at(iTrig);
const auto& trigReco = trigRecsReco->at(iTrig);
if (!(trig == trigReco)) {
LOGF(error, "Trigger records don't match at trigger %lu. Reference orbit/bc (%u/%u), orbit/bc (%u/%u)",
iTrig, trig.getBCData().orbit, trig.getBCData().bc, trigReco.getBCData().orbit, trigReco.getBCData().bc);
break;
}
}
}

Expand Down
68 changes: 28 additions & 40 deletions Detectors/TRD/reconstruction/src/CruRawReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ int CruRawReader::processHBFs()
// at this point the entire HBF data payload is sitting in mHBFPayload and the total data count is mTotalHBFPayLoad
int iteration = 0;
mHBFoffset32 = 0;
mPreviousHalfCRUHeaderSet = false;
while (mHBFoffset32 < (mTotalHBFPayLoad / 4)) {
if (mOptions[TRDVerboseBit]) {
LOGP(info, "Current half-CRU iteration {}, current offset in the HBF payload {}, total payload in number of 32-bit words {}", iteration, mHBFoffset32, mTotalHBFPayLoad / 4);
Expand Down Expand Up @@ -305,8 +306,10 @@ bool CruRawReader::parseDigitHCHeaders(int hcid)
}
incrementErrors(DigitHCHeader2Problem, hcid);
}
/* Currently we don't do anything with the information stored in DigitHCHeader2
DigitHCHeader2 header2;
header2.word = headers[headerwordcount];
*/
headersfound.set(1);
break;

Expand Down Expand Up @@ -407,7 +410,7 @@ bool CruRawReader::processHalfCRU(int iteration)
return true;
}

if (iteration > 0) {
if (mPreviousHalfCRUHeaderSet) {
// for the second trigger (and thus second HalfCRUHeader we see) we can do some more sanity checks
// in case one check fails, we try to go to the next HalfCRUHeader
if (mCurrentHalfCRUHeader.EndPoint != mPreviousHalfCRUHeader.EndPoint) {
Expand All @@ -432,6 +435,7 @@ bool CruRawReader::processHalfCRU(int iteration)
}
}
mPreviousHalfCRUHeader = mCurrentHalfCRUHeader;
mPreviousHalfCRUHeaderSet = true;

//can this half cru length fit into the available space of the rdh accumulated payload
if (totalHalfCRUDataLength32 > (mTotalHBFPayLoad / 4) - mHBFoffset32) {
Expand Down Expand Up @@ -466,19 +470,17 @@ bool CruRawReader::processHalfCRU(int iteration)
int cruIdx = mFEEID.supermodule * 2 + mFEEID.side; // 2 CRUs per SM, side defining A/C-side CRU
int halfCruIdx = cruIdx * 2 + mFEEID.endpoint; // endpoint (0 or 1) defines half-CRU
int linkIdxGlobal = halfCruIdx * NLINKSPERHALFCRU + currentlinkindex; // global link ID [0..1079]
int halfChamberId = HelperMethods::getHCIDFromLinkID(linkIdxGlobal);
// int halfChamberId = mLinkMap->getHCID(linkIdxGlobal); FIXME: uncomment, when object available in CCDB
// TODO we keep detector, stack, layer, sector, side for now to be compatible to the current code state,
int halfChamberId = mLinkMap->getHCID(linkIdxGlobal);
// TODO we keep detector, stack, layer, side for now to be compatible to the current code state,
// but halfChamberId contains everything we need to know... More cleanup to be done in second step
int detectorId = halfChamberId / 2;
int stack = HelperMethods::getStack(detectorId);
int layer = HelperMethods::getLayer(detectorId);
int sector = HelperMethods::getSector(detectorId);
int side = halfChamberId % 2;
int stack_layer = stack * NLAYER + layer; // similarly this is also only for graphing so just use the rdh ones for now.
mEventRecords.incLinkErrorFlags(mFEEID.supermodule, side, stack_layer, mCurrentHalfCRULinkErrorFlags[currentlinkindex]);
int currentlinksize32 = mCurrentHalfCRULinkLengths[currentlinkindex] * 8; // x8 to go from 256 bits to 32 bit;
int endOfCurrentLink = mHBFoffset32 + currentlinksize32;
uint32_t currentlinksize32 = mCurrentHalfCRULinkLengths[currentlinkindex] * 8; // x8 to go from 256 bits to 32 bit;
uint32_t endOfCurrentLink = mHBFoffset32 + currentlinksize32;

linksizeAccum32 += currentlinksize32;
if (currentlinksize32 == 0) {
Expand All @@ -500,27 +502,25 @@ bool CruRawReader::processHalfCRU(int iteration)
LOGF(info, "Tracklet parser starting at offset %u and processing up to %u words", mHBFoffset32, currentlinksize32);
}
int trackletWordsRejected = 0;
// LOGF(warn, "Starting tracklet parsing for HCID %i", halfChamberId);
int trackletWordsRead = parseTrackletLinkData(currentlinksize32, halfChamberId, trackletWordsRejected);
std::chrono::duration<double, std::micro> trackletparsingtime = std::chrono::high_resolution_clock::now() - trackletparsingstart;
if (trackletWordsRead == -1) {
//something went wrong bailout of here.
if (mMaxWarnPrinted > 0) {
LOG(warn) << "Tracklet parser returned -1 for link " << currentlinkindex;
checkNoWarn();
}
// something went wrong bailout of here.
mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
incrementErrors(TrackletsReturnedMinusOne, halfChamberId);
continue; // move to next link of this half-CRU
}
mHBFoffset32 += trackletWordsRead;
if (mCurrentHalfCRUHeader.EventType == ETYPEPHYSICSTRIGGER &&
endOfCurrentLink - mHBFoffset32 >= 8) {
/*
// disabled for the same reason as for the warning after the digits parsing below
if (mMaxWarnPrinted > 0) {
LOGF(warn, "After successfully parsing the tracklet data for link %i there are %i words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
LOGF(warn, "After successfully parsing the tracklet data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
checkNoWarn();
}
incrementErrors(UnparsedTrackletDataRemaining, halfChamberId, fmt::format("On link {} there are {} words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32));
*/
}
mEventRecords.getCurrentEventRecord().incTrackletTime((double)std::chrono::duration_cast<std::chrono::microseconds>(trackletparsingtime).count());
if (mOptions[TRDVerboseBit]) {
Expand Down Expand Up @@ -581,10 +581,14 @@ bool CruRawReader::processHalfCRU(int iteration)
if (endOfCurrentLink - mHBFoffset32 >= 8) {
// check if some data is lost (probably due to bug in CRU user logic)
// we should have max 7 padding words to align the link to 256 bits
/*
// due to the current CRU bug this is almost always the case
// TODO enable warning again when CRU UL is fixed
if (mMaxWarnPrinted > 0) {
LOGF(warn, "After successfully parsing the digit data for link %i there are %i words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
LOGF(warn, "After successfully parsing the digit data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
checkNoWarn();
}
*/
incrementErrors(UnparsedDigitDataRemaining, halfChamberId, fmt::format("On link {} there are {} words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32));
}
mEventRecords.getCurrentEventRecord().incDigitTime((double)std::chrono::duration_cast<std::chrono::microseconds>(digitsparsingtime).count());
Expand Down Expand Up @@ -630,7 +634,7 @@ bool CruRawReader::processHalfCRU(int iteration)

bool CruRawReader::isTrackletHCHeaderOK(const TrackletHCHeader& header, int& hcid)
{
if (header.one != 1) {
if (!sanityCheckTrackletHCHeader(header)) {
return false;
}
int detHeader = HelperMethods::getDetector(((~header.supermodule) & 0x1f), ((~header.stack) & 0x7), ((~header.layer) & 0x7));
Expand All @@ -644,12 +648,10 @@ bool CruRawReader::isTrackletHCHeaderOK(const TrackletHCHeader& header, int& hci
}

if (hcid != hcidHeader) {
/* FIXME currently would be flooded by these messages, as long as CCDB object not available
if (mMaxWarnPrinted > 0) {
LOGF(alarm, "RDH HCID %i, TrackletHCHeader HCID %i. Taking the TrackletHCHedaer as authority", hcid, hcidHeader);
checkNoWarn();
}
*/
hcid = hcidHeader;
}
return (hcid == hcidHeader);
Expand All @@ -658,7 +660,6 @@ bool CruRawReader::isTrackletHCHeaderOK(const TrackletHCHeader& header, int& hci
int CruRawReader::parseDigitLinkData(int maxWords32, int hcid, int& wordsRejected)
{
int wordsRead = 0;
int numberOfDigitsFound = 0;
int state = StateDigitMCMHeader;
DigitMCMHeader mcmHeader;
DigitMCMADCMask adcMask;
Expand Down Expand Up @@ -806,11 +807,7 @@ int CruRawReader::parseDigitLinkData(int maxWords32, int hcid, int& wordsRejecte
else if (state == StateSecondEndmarker) {
++wordsRead;
if (currWord != DIGITENDMARKER) {
if (mMaxWarnPrinted > 0) {
LOGF(warn, "Expected second digit end marker, but found 0x%08x instead", currWord);
checkNoWarn();
}
incrementErrors(DigitParsingNoSecondEndmarker, hcid, "No second digit end marker found");
incrementErrors(DigitParsingNoSecondEndmarker, hcid, fmt::format("Expected second digit end marker, but found {:#010x} instead", currWord));
return -1;
}
state = StateFinished;
Expand All @@ -825,11 +822,7 @@ int CruRawReader::parseDigitLinkData(int maxWords32, int hcid, int& wordsRejecte
// not good, something went wrong with digit parsing
// e.g. we tried to move to the end marker but reached the link size
// without finding one.
if (mMaxWarnPrinted > 0) {
LOGF(warn, "We exited the digit parser state machine in the state %i and not in the proper finished state", state);
checkNoWarn();
}
incrementErrors(DigitParsingExitInWrongState, hcid, "Done with digit parsing but state is not StateFinished");
incrementErrors(DigitParsingExitInWrongState, hcid, fmt::format("Done with digit parsing but state is not StateFinished but in state {}", state));
return -1;
}
}
Expand Down Expand Up @@ -919,16 +912,14 @@ int CruRawReader::parseTrackletLinkData(int linkSize32, int& hcid, int& wordsRej
if (currWord == TRACKLETENDMARKER) {
if ((hcHeader.format & 0x2) == 0x2) {
// format indicates no empty MCM headers are sent, so we should not see an end marker here
// TODO add error message/counter for QC
LOGF(warn, "For the MCM Header 0x%08x we expected a tracklet from CPU %i, but got an endmarker instead", mcmHeader.word, iCpu);
incrementErrors(TrackletDataMissing, hcid, fmt::format("For the MCM Header {:#010x} we expected a tracklet from CPU {}, but got an endmarker instead", mcmHeader.word, iCpu));
}
state = StateSecondEndmarker; // we expect a second tracklet end marker to follow
break;
}
if ((currWord & 0x1) == 0x1) {
// the reserved bit of the trackler MCM data is set
// TODO add error message/counter for QC
LOGF(warn, "Invalid word 0x%08x for the expected TrackletMCMData", currWord);
incrementErrors(TrackletMCMDataFailure, hcid, fmt::format("Invalid word {:#010x} for the expected TrackletMCMData", currWord));
++wordsRejected;
}
TrackletMCMData mcmData;
Expand Down Expand Up @@ -971,10 +962,7 @@ int CruRawReader::parseTrackletLinkData(int linkSize32, int& hcid, int& wordsRej
else if (state == StateSecondEndmarker) {
++wordsRead;
if (currWord != TRACKLETENDMARKER) {
if (mMaxWarnPrinted > 0) {
LOGF(warn, "Expected second tracklet end marker, but found 0x%08x instead", currWord);
checkNoWarn();
}
incrementErrors(TrackletNoSecondEndMarker, hcid, fmt::format("Expected second tracklet end marker, but found {:#010x} instead", currWord));
return -1;
}
state = StateFinished;
Expand Down Expand Up @@ -1028,7 +1016,9 @@ Tracklet64 CruRawReader::assembleTracklet64(int format, TrackletMCMHeader& mcmHe
slope ^= 0x80;
uint32_t hpid = (mcmHeader.word >> (1 + cpu * 8)) & 0xff;
uint32_t lpid = mcmData.pid;
uint32_t pid = (hpid << 12) | lpid;
// The combined 20 bit PID information from the MCM header and the tracklet word
// is given by ((hpid << 12) | lpid).
// hpid holds the upper 8 bit and lpid the lower 12 bit.
int q0, q1, q2;
if (format & 0x1) {
// DQR enabled
Expand Down Expand Up @@ -1060,12 +1050,10 @@ void CruRawReader::dumpInputPayload() const

void CruRawReader::run()
{
/* FIXME: uncomment, when object available in CCDB
if (!mLinkMap) {
LOG(error) << "No mapping for Link ID to HCID provided from CCDB";
return;
}
*/
if (mOptions[TRDVerboseBit]) {
dumpInputPayload();
}
Expand Down
Loading