diff --git a/Detectors/MUON/MCH/Raw/Encoder/Digit/DigitPayloadEncoder.cxx b/Detectors/MUON/MCH/Raw/Encoder/Digit/DigitPayloadEncoder.cxx index a5dec7c1f985b..c8c067003ced3 100644 --- a/Detectors/MUON/MCH/Raw/Encoder/Digit/DigitPayloadEncoder.cxx +++ b/Detectors/MUON/MCH/Raw/Encoder/Digit/DigitPayloadEncoder.cxx @@ -57,7 +57,7 @@ void DigitPayloadEncoder::encodeDigits(gsl::span digits, int dualSampaChannelId = optElecId.value().second; // FIXME : what to put as rel time ? uint10_t ts = 0; - auto firstIR = o2::raw::HBFUtils::Instance().getFirstIR(); + auto firstIR = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); uint20_t bxCount = sampaBunchCrossingCounter(orbit, bc, firstIR.orbit); auto clusters = {raw::SampaCluster(ts, bxCount, d.getADC(), d.getNofSamples())}; mEncoder.addChannelData(elecId, dualSampaChannelId, clusters); diff --git a/Detectors/MUON/MCH/Raw/Encoder/Digit/digits-to-raw.cxx b/Detectors/MUON/MCH/Raw/Encoder/Digit/digits-to-raw.cxx index 3efbf16b4f067..584976fbcd9a0 100644 --- a/Detectors/MUON/MCH/Raw/Encoder/Digit/digits-to-raw.cxx +++ b/Detectors/MUON/MCH/Raw/Encoder/Digit/digits-to-raw.cxx @@ -137,7 +137,8 @@ int main(int argc, char* argv[]) // here we implicitely assume that this digits-to-raw is only called for // one timeframe so it's easy to detect the TF start... - uint32_t firstOrbitOfRun = o2::raw::HBFUtils::Instance().orbitFirst; + // RS: why do you need such assumption? In general, it is not correct + uint32_t firstOrbitOfRun = o2::raw::HBFUtils::Instance().getFirstSampledTFIR().orbit; // RS note that this is not anymore 1st orbit of the run but of the 1st filled TF auto dsElecIds = opts.dummyElecMap ? getAllDs() : getAllDs(); dre.addHeartbeats(dsElecIds, firstOrbitOfRun); diff --git a/Detectors/MUON/MCH/Raw/Encoder/Payload/PayloadEncoderImpl.h b/Detectors/MUON/MCH/Raw/Encoder/Payload/PayloadEncoderImpl.h index 76a7c668f2577..2807fee8db471 100644 --- a/Detectors/MUON/MCH/Raw/Encoder/Payload/PayloadEncoderImpl.h +++ b/Detectors/MUON/MCH/Raw/Encoder/Payload/PayloadEncoderImpl.h @@ -170,8 +170,8 @@ void PayloadEncoderImpl::addHeartbeatHeaders(const s if (dsids.empty()) { return; } - // get first orbit of the run - auto firstIR = o2::raw::HBFUtils::Instance().getFirstIR(); + // get first orbit of the TF + auto firstIR = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); auto sampaBXCount = sampaBunchCrossingCounter(firstIR.orbit, firstIR.bc, firstIR.orbit); for (auto dsElecId : dsids) { auto solarId = dsElecId.solarId(); diff --git a/Detectors/MUON/MCH/Raw/test/testClosureCoDec.cxx b/Detectors/MUON/MCH/Raw/test/testClosureCoDec.cxx index 602a1c47d1bac..e545c15025d8e 100644 --- a/Detectors/MUON/MCH/Raw/test/testClosureCoDec.cxx +++ b/Detectors/MUON/MCH/Raw/test/testClosureCoDec.cxx @@ -169,7 +169,7 @@ std::vector createBuffer(gsl::span data, { const o2::raw::HBFUtils& hbfutils = o2::raw::HBFUtils::Instance(); o2::conf::ConfigurableParam::setValue("HBFUtils", "orbitFirst", orbit); - + o2::conf::ConfigurableParam::setValue("HBFUtils", "orbitFirstSampled", orbit); auto encoder = createPayloadEncoder(createSolar2FeeLinkMapper(), isUserLogicFormat::value, VERSION, diff --git a/Detectors/MUON/MID/Raw/src/Encoder.cxx b/Detectors/MUON/MID/Raw/src/Encoder.cxx index 2c92bf0135978..931350e268619 100644 --- a/Detectors/MUON/MID/Raw/src/Encoder.cxx +++ b/Detectors/MUON/MID/Raw/src/Encoder.cxx @@ -133,8 +133,7 @@ void Encoder::finalize(bool closeFile) { /// Writes remaining data and closes the file if (mLastIR.isDummy()) { - mLastIR.bc = 0; - mLastIR.orbit = mRawWriter.getHBFUtils().orbitFirst; + mLastIR = mRawWriter.getHBFUtils().getFirstSampledTFIR(); } auto ir = getOrbitIR(mLastIR.orbit); auto nextIr = getOrbitIR(mLastIR.orbit + 1); @@ -157,9 +156,11 @@ void Encoder::process(gsl::span data, InteractionRecord ir, Ev /// Encodes data // The CTP trigger arrives to the electronics with a delay - applyElectronicsDelay(ir.orbit, ir.bc, -mElectronicsDelay.localToBC); + if (ir.differenceInBC(mRawWriter.getHBFUtils().getFirstSampledTFIR()) > mElectronicsDelay.localToBC) { // RS: not sure this is correct. + applyElectronicsDelay(ir.orbit, ir.bc, -mElectronicsDelay.localToBC); + } - if (ir.orbit != mLastIR.orbit) { + if (ir.orbit != mLastIR.orbit && !mLastIR.isDummy()) { onOrbitChange(mLastIR.orbit); } diff --git a/Detectors/Raw/README.md b/Detectors/Raw/README.md index 9549ae9c5b272..5e19dc0d3fe22 100644 --- a/Detectors/Raw/README.md +++ b/Detectors/Raw/README.md @@ -194,6 +194,13 @@ The writer will create a new CRU page with provided payload equipping it with th For further details see ``ITSMFT/common/simulation/MC2RawEncoder`` class and the macro `Detectors/ITSMFT/ITS/macros/test/run_digi2rawVarPage_its.C` to steer the MC to raw data conversion. +* Update: Use flag HBFUtils.obligatorySOR to start raw data from TF with SOX. + +If the HBFUtils.obligatorySOR==false (default) the MC->Raw converted data will start from the 1st TF containing data (i.e. corresponding to HBFUtils.firstOrbitSampled), +the SOX in the RDH will be set only if this TF coincides with the 1st TF of the Run (defined by the HBFUtils.orbitFirst). +With HBFUtils.obligatorySOR==true old behaviour will be preserved: the raw data will start from TF with HBFUtils.orbitFirst with SOX always set and for CRU detectors all HBFs/TFs between HBFUtils.orbitFirst and 1st non-empty HBF will be +filled by dummy RDHs. + ## RawFileReader A class for parsing raw data file(s) with "variable-size" CRU format. diff --git a/Detectors/Raw/include/DetectorsRaw/HBFUtils.h b/Detectors/Raw/include/DetectorsRaw/HBFUtils.h index 6cc89d6fb0b61..1503118bbc04a 100644 --- a/Detectors/Raw/include/DetectorsRaw/HBFUtils.h +++ b/Detectors/Raw/include/DetectorsRaw/HBFUtils.h @@ -135,10 +135,9 @@ struct HBFUtils : public o2::conf::ConfigurableParamHelper { void checkConsistency() const; - int nHBFPerTF = 128; ///< number of orbits per BC - uint32_t orbitFirst = 0; ///< orbit of 1st TF of the run - - // used for MC + int nHBFPerTF = 128; ///< number of orbits per BC + bool obligatorySOR = false; ///< in mc->raw always start from run 1st TF to set the SOR + uint32_t orbitFirst = 0; ///< orbit of 1st TF of the run uint32_t runNumber = 0; ///< run number uint32_t orbitFirstSampled = 0; ///< 1st orbit sampled in the MC uint32_t maxNOrbits = 0xffffffff; ///< max number of orbits to accept, used in digit->raw conversion diff --git a/Detectors/Raw/include/DetectorsRaw/RawFileReader.h b/Detectors/Raw/include/DetectorsRaw/RawFileReader.h index fa3ba6e277996..d3563fbe3eb4d 100644 --- a/Detectors/Raw/include/DetectorsRaw/RawFileReader.h +++ b/Detectors/Raw/include/DetectorsRaw/RawFileReader.h @@ -120,7 +120,7 @@ class RawFileReader true, // ErrWrongNumberOfTF true, // ErrHBFJump false, // ErrNoSuperPageForTF - true, // ErrNoSOX + false, // ErrNoSOX true, // ErrMismatchTF }; //================================================================================ @@ -250,6 +250,7 @@ class RawFileReader void setCheckErrors(uint32_t m = 0xffffffff) { mCheckErrors = m & ((0x1 << NErrorsDefined) - 1); } int getVerbosity() const { return mVerbosity; } uint32_t getCheckErrors() const { return mCheckErrors; } + bool isProcessingStopped() const { return mStopProcessing; } void setNominalSPageSize(int n = 0x1 << 20) { mNominalSPageSize = n > (0x1 << 15) ? n : (0x1 << 15); } int getNominalSPageSize() const { return mNominalSPageSize; } @@ -315,6 +316,7 @@ class RawFileReader long int mPosInFile = 0; //! current position in the file bool mMultiLinkFile = false; //! was > than 1 link seen in the file? bool mCacheData = false; //! cache data to block after 1st scan (may require excessive memory, use with care) + bool mStopProcessing = false; //! stop processing after error uint32_t mCheckErrors = 0; //! mask for errors to check FirstTFDetection mFirstTFAutodetect = FirstTFDetection::Disabled; //! bool mPreferCalculatedTFStart = false; //! prefer TFstart calculated via HBFUtils diff --git a/Detectors/Raw/src/RawFileReader.cxx b/Detectors/Raw/src/RawFileReader.cxx index ce526a20931bd..700e7c7b375c5 100644 --- a/Detectors/Raw/src/RawFileReader.cxx +++ b/Detectors/Raw/src/RawFileReader.cxx @@ -590,7 +590,14 @@ bool RawFileReader::preprocessFile(int ifl) lID = getLinkLocalID(rdh, mCurrentFileID); } bool newSPage = lID != lIDPrev; - mLinksData[lID].preprocessCRUPage(rdh, newSPage); + try { + mLinksData[lID].preprocessCRUPage(rdh, newSPage); + } catch (...) { + LOG(error) << "Corrupted data, abandoning processing"; + mStopProcessing = true; + break; + } + if (mLinksData[lID].nTimeFrames && (mLinksData[lID].nTimeFrames - 1 > mMaxTFToRead)) { // limit reached, discard the last read mLinksData[lID].nTimeFrames--; mLinksData[lID].blocks.pop_back(); @@ -706,6 +713,10 @@ bool RawFileReader::init() mEmpty = false; } } + if (mStopProcessing) { + LOG(error) << "Abandoning processing due to corrupted data"; + return false; + } mOrderedIDs.resize(mLinksData.size()); for (int i = mLinksData.size(); i--;) { mOrderedIDs[i] = i; diff --git a/Detectors/Raw/src/RawFileReaderWorkflow.cxx b/Detectors/Raw/src/RawFileReaderWorkflow.cxx index 7e8ae6ab865ae..4fb7e4e338d3c 100644 --- a/Detectors/Raw/src/RawFileReaderWorkflow.cxx +++ b/Detectors/Raw/src/RawFileReaderWorkflow.cxx @@ -206,8 +206,8 @@ void RawReaderSpecs::run(o2f::ProcessingContext& ctx) auto tfID = mReader->getNextTFToRead(); int nlinks = mReader->getNLinks(); - if (tfID > mMaxTFID) { - if (!mReader->isEmpty() && --mLoop) { + if (tfID > mMaxTFID || mReader->isProcessingStopped()) { + if (!mReader->isProcessingStopped() && !mReader->isEmpty() && --mLoop) { mLoopsDone++; tfID = 0; LOG(info) << "Starting new loop " << mLoopsDone << " from the beginning of data"; diff --git a/Detectors/Raw/src/RawFileWriter.cxx b/Detectors/Raw/src/RawFileWriter.cxx index 4d2f039327e69..4b73e852a4e94 100644 --- a/Detectors/Raw/src/RawFileWriter.cxx +++ b/Detectors/Raw/src/RawFileWriter.cxx @@ -166,7 +166,7 @@ RawFileWriter::LinkData& RawFileWriter::registerLink(uint16_t fee, uint16_t cru, RDHUtils::setSourceID(linkData.rdhCopy, o2::header::DAQID::O2toDAQ(mOrigin)); } linkData.writer = this; - linkData.updateIR = mHBFUtils.getFirstIR(); + linkData.updateIR = mHBFUtils.obligatorySOR ? mHBFUtils.getFirstIR() : mHBFUtils.getFirstSampledTFIR(); linkData.buffer.reserve(mSuperPageSize); RDHUtils::printRDH(linkData.rdhCopy); LOGF(info, "Registered %s with output to %s", linkData.describe(), outFileName); @@ -186,8 +186,8 @@ void RawFileWriter::addData(uint16_t feeid, uint16_t cru, uint8_t lnk, uint8_t e LOG(error) << "provided payload size " << data.size() << " is not multiple of GBT word size"; throw std::runtime_error("payload size is not mutiple of GBT word size"); } - if (ir < mHBFUtils.getFirstIR()) { - LOG(warning) << "provided " << ir << " precedes first TF " << mHBFUtils.getFirstIR() << " | discarding data for " << link.describe(); + if (ir < mHBFUtils.getFirstSampledTFIR()) { + LOG(warning) << "provided " << ir << " precedes first sampled TF " << mHBFUtils.getFirstSampledTFIR() << " | discarding data for " << link.describe(); return; } if (link.discardData || ir.orbit - mHBFUtils.orbitFirst >= mHBFUtils.maxNOrbits) { @@ -318,6 +318,9 @@ void RawFileWriter::LinkData::addDataInternal(const IR& ir, const gsl::spanmHBFUtils.getFirstIRofTF(ir) > writer->mHBFUtils.getFirstIR()) && !writer->mHBFUtils.obligatorySOR)) { + startOfRun = false; + } if (startOfRun && writer->isRORCDetector()) { // in RORC mode we write separate RDH with SOX in the very beginning of the run writer->mHBFUtils.updateRDH(rdhCopy, writer->mHBFUtils.getFirstIR(), false); diff --git a/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx index 96f5729e46cd2..e90c8fb992c1f 100644 --- a/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/HMPIDDigitizerSpec.cxx @@ -145,7 +145,7 @@ class HMPIDDPLDigitizerTask : public o2::base::BaseDPLDigitizer std::vector mIntRecord; // RS: at the moment using hardcoded flag for continuous readout - o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::CONTINUOUS; // readout mode + o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::TRIGGERING; // readout mode }; o2::framework::DataProcessorSpec getHMPIDDigitizerSpec(int channel, bool mctruth) diff --git a/prodtests/full_system_test.sh b/prodtests/full_system_test.sh index f8b09cd6b248c..8c4943ecb8ec9 100755 --- a/prodtests/full_system_test.sh +++ b/prodtests/full_system_test.sh @@ -45,6 +45,7 @@ SPLITTRDDIGI=${SPLITTRDDIGI:-1} NHBPERTF=${NHBPERTF:-128} RUNFIRSTORBIT=${RUNFIRSTORBIT:-0} FIRSTSAMPLEDORBIT=${FIRSTSAMPLEDORBIT:-0} +OBLIGATORYSOR=${OBLIGATORYSOR:-false} if [ $BEAMTYPE == "PbPb" ]; then FST_GENERATOR=${FST_GENERATOR:-pythia8hi} FST_COLRATE=${FST_COLRATE:-50000} @@ -73,7 +74,7 @@ echo "versions,${TAG} alidist=\"${ALIDISTCOMMIT}\",O2=\"${O2COMMIT}\" " > ${METR GLOBALDPLOPT="-b" # --monitoring-backend no-op:// is currently removed due to https://alice.its.cern.ch/jira/browse/O2-1887 -HBFUTILPARAMS="HBFUtils.nHBFPerTF=${NHBPERTF};HBFUtils.orbitFirst=${RUNFIRSTORBIT};HBFUtils.orbitFirstSampled=${FIRSTSAMPLEDORBIT}" +HBFUTILPARAMS="HBFUtils.nHBFPerTF=${NHBPERTF};HBFUtils.orbitFirst=${RUNFIRSTORBIT};HBFUtils.orbitFirstSampled=${FIRSTSAMPLEDORBIT};HBFUtils.obligatorySOR=${OBLIGATORYSOR}" [ "0$ALLOW_MULTIPLE_TF" != "01" ] && HBFUTILPARAMS+=";HBFUtils.maxNOrbits=$((${FIRSTSAMPLEDORBIT} + ${NHBPERTF}));" ulimit -n 4096 # Make sure we can open sufficiently many files