diff --git a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/RawEventData.h b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/RawEventData.h index 5d856f55c1d65..622f3116b7868 100644 --- a/DataFormats/Detectors/ZDC/include/DataFormatsZDC/RawEventData.h +++ b/DataFormats/Detectors/ZDC/include/DataFormatsZDC/RawEventData.h @@ -33,7 +33,9 @@ constexpr unsigned short Id_w0 = 0x0; constexpr unsigned short Id_w1 = 0x1; constexpr unsigned short Id_w2 = 0x2; constexpr unsigned short Id_wn = 0x3; -constexpr int NWPerGBTW = 4; +constexpr int NWPerGBTW = 4; // 4*32bit=128 bit per GBTW +constexpr int NBPerGBTW = 4 * NWPerGBTW; // 16B=128 bit per GBTW +constexpr int PayloadPerGBTW = 10; // 80 bit per GBTW struct __attribute__((__packed__)) ChannelDataV0 { // First GBT word diff --git a/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDC.h b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDC.h index 482c4c4c38b6d..b27f7e34353c0 100644 --- a/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDC.h +++ b/Detectors/ZDC/raw/include/ZDCRaw/RawReaderZDC.h @@ -70,7 +70,7 @@ class RawReaderZDC void clear(); // decoding binary data into data blocks - void processBinaryData(gsl::span payload, int linkID); // processing data blocks into digits + int processBinaryData(gsl::span payload, int linkID, uint8_t dataFormat); // processing data blocks into digits int processWord(const uint32_t* word); void process(const EventChData& ch); diff --git a/Detectors/ZDC/raw/src/DumpRaw.cxx b/Detectors/ZDC/raw/src/DumpRaw.cxx index c1dc48169cf40..3a6cec3cba6f8 100644 --- a/Detectors/ZDC/raw/src/DumpRaw.cxx +++ b/Detectors/ZDC/raw/src/DumpRaw.cxx @@ -78,9 +78,9 @@ void DumpRaw::init() { gROOT->SetBatch(); auto& sopt = ZDCSimParam::Instance(); - int nbx = (sopt.nBCAheadTrig + 1) * NTimeBinsPerBC; double xmin = -sopt.nBCAheadTrig * NTimeBinsPerBC - 0.5; double xmax = 2 * NTimeBinsPerBC - 0.5; + int nbx = std::round(xmax - xmin); if (mTransmitted == nullptr) { mTransmitted = std::make_unique("ht", "Transmitted channels", NModules, -0.5, NModules - 0.5, NChPerModule, -0.5, NChPerModule - 0.5); } @@ -226,36 +226,37 @@ int DumpRaw::processWord(const uint32_t* word) printf("NULL\n"); return 1; } + // LOGF(info, "GBT word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3); if ((word[0] & 0x3) == Id_w0) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[0][iw] = word[iw]; - } + mCh.w[0][NWPerGBTW - 1] = 0; + mCh.w[0][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[0][0], (const void*)word, PayloadPerGBTW); } else if ((word[0] & 0x3) == Id_w1) { if (mCh.f.fixed_0 == Id_w0) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[1][iw] = word[iw]; - } + mCh.w[1][NWPerGBTW - 1] = 0; + mCh.w[1][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[1][0], (const void*)word, PayloadPerGBTW); } else { - LOG(error) << "Wrong word sequence"; + LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, word[0] & 0x3); mCh.f.fixed_0 = Id_wn; mCh.f.fixed_1 = Id_wn; mCh.f.fixed_2 = Id_wn; } } else if ((word[0] & 0x3) == Id_w2) { if (mCh.f.fixed_0 == Id_w0 && mCh.f.fixed_1 == Id_w1) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[2][iw] = word[iw]; - } + mCh.w[2][NWPerGBTW - 1] = 0; + mCh.w[2][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[2][0], (const void*)word, PayloadPerGBTW); process(mCh); } else { - LOG(error) << "Wrong word sequence"; + LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u %u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, mCh.f.fixed_1, word[0] & 0x3); } mCh.f.fixed_0 = Id_wn; mCh.f.fixed_1 = Id_wn; mCh.f.fixed_2 = Id_wn; } else { - // Word not present in payload - LOG(fatal) << "Event format error"; + // Word id not foreseen in payload + LOGF(error, "Event format error on word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3); return 1; } return 0; diff --git a/Detectors/ZDC/raw/src/RawReaderZDC.cxx b/Detectors/ZDC/raw/src/RawReaderZDC.cxx index 34b18f1af1f7c..f9e40b28abc24 100644 --- a/Detectors/ZDC/raw/src/RawReaderZDC.cxx +++ b/Detectors/ZDC/raw/src/RawReaderZDC.cxx @@ -32,25 +32,48 @@ void RawReaderZDC::clear() mOrbitData.clear(); } -void RawReaderZDC::processBinaryData(gsl::span payload, int linkID) +int RawReaderZDC::processBinaryData(gsl::span payload, int linkID, uint8_t dataFormat) { if (0 <= linkID && linkID < 16) { size_t payloadSize = payload.size(); - for (int32_t ip = 0; ip < payloadSize; ip += 16) { + if (dataFormat == 2) { + for (int32_t ip = 0; (ip + PayloadPerGBTW) <= payloadSize; ip += PayloadPerGBTW) { #ifndef O2_ZDC_DEBUG - if (mVerbosity >= DbgExtra) { + if (mVerbosity >= DbgExtra) { + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + } +#else o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); +#endif + const uint32_t* gbtw = (const uint32_t*)&payload[ip]; + if (gbtw[0] != 0xffffffff && gbtw[1] != 0xffffffff && (*((const uint16_t*)&gbtw[2])) != 0xffff) { + if (processWord(gbtw)) { + return 1; + } + } } + } else if (dataFormat == 0) { + for (int32_t ip = 0; ip < payloadSize; ip += NBPerGBTW) { +#ifndef O2_ZDC_DEBUG + if (mVerbosity >= DbgExtra) { + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + } #else - o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); #endif - processWord((const uint32_t*)&payload[ip]); + if (processWord((const uint32_t*)&payload[ip])) { + return 1; + } + } + } else { + LOG(fatal) << "RawReaderZDC::processBinaryData - Unsupported DataFormat " << dataFormat; } } else { // put here code in case of bad rdh.linkID value LOG(info) << "WARNING! WRONG LINK ID! " << linkID; - return; + return 1; } + return 0; } int RawReaderZDC::processWord(const uint32_t* word) @@ -59,36 +82,37 @@ int RawReaderZDC::processWord(const uint32_t* word) LOG(error) << "NULL pointer"; return 1; } + // LOGF(info, "GBT word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3); if ((word[0] & 0x3) == Id_w0) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[0][iw] = word[iw]; - } + mCh.w[0][NWPerGBTW - 1] = 0; + mCh.w[0][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[0][0], (const void*)word, PayloadPerGBTW); } else if ((word[0] & 0x3) == Id_w1) { if (mCh.f.fixed_0 == Id_w0) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[1][iw] = word[iw]; - } + mCh.w[1][NWPerGBTW - 1] = 0; + mCh.w[1][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[1][0], (const void*)word, PayloadPerGBTW); } else { - LOG(error) << "Wrong word sequence"; + LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, word[0] & 0x3); mCh.f.fixed_0 = Id_wn; mCh.f.fixed_1 = Id_wn; mCh.f.fixed_2 = Id_wn; } } else if ((word[0] & 0x3) == Id_w2) { if (mCh.f.fixed_0 == Id_w0 && mCh.f.fixed_1 == Id_w1) { - for (int32_t iw = 0; iw < NWPerGBTW; iw++) { - mCh.w[2][iw] = word[iw]; - } + mCh.w[2][NWPerGBTW - 1] = 0; + mCh.w[2][NWPerGBTW - 2] = 0; + memcpy((void*)&mCh.w[2][0], (const void*)word, PayloadPerGBTW); process(mCh); } else { - LOG(error) << "Wrong word sequence"; + LOGF(error, "Wrong word sequence: %04x %08x %08x id=%u %u *%u*", *((uint16_t*)&word[2]), word[1], word[0], mCh.f.fixed_0, mCh.f.fixed_1, word[0] & 0x3); } mCh.f.fixed_0 = Id_wn; mCh.f.fixed_1 = Id_wn; mCh.f.fixed_2 = Id_wn; } else { - // Word not present in payload - LOG(fatal) << "Event format error"; + // Word id not foreseen in payload + LOGF(error, "Event format error on word %04x %08x %08x id=%u", *((uint16_t*)&word[2]), word[1], word[0], word[0] & 0x3); return 1; } return 0; diff --git a/Detectors/ZDC/raw/src/ZDCRawParserDPLSpec.cxx b/Detectors/ZDC/raw/src/ZDCRawParserDPLSpec.cxx index d9d5aa8a6aec9..857b1b5400e4c 100644 --- a/Detectors/ZDC/raw/src/ZDCRawParserDPLSpec.cxx +++ b/Detectors/ZDC/raw/src/ZDCRawParserDPLSpec.cxx @@ -33,12 +33,14 @@ #include "DataFormatsZDC/ChannelData.h" #include "DataFormatsZDC/OrbitData.h" #include "DataFormatsZDC/RecEvent.h" +#include "DataFormatsZDC/RawEventData.h" #include "CommonUtils/NameConf.h" #include "CommonUtils/MemFileHelper.h" #include "CCDB/BasicCCDBManager.h" #include "CCDB/CCDBTimeStampUtils.h" #include "ZDCBase/ModuleConfig.h" #include "ZDCRaw/ZDCRawParserDPLSpec.h" +#include "ZDCSimulation/Digits2Raw.h" using namespace o2::framework; @@ -104,12 +106,30 @@ void ZDCRawParserDPLSpec::run(ProcessingContext& pc) size_t payloadSize = it.size(); // offset of payload in the raw page size_t offset = it.offset(); + int dataFormat = o2::raw::RDHUtils::getDataFormat(rdhPtr); #ifdef O2_ZDC_DEBUG - LOG(info) << count << " processBinaryData: size=" << it.size() << " link=" << o2::raw::RDHUtils::getLinkID(rdhPtr); + int linkID = o2::raw::RDHUtils::getLinkID(rdhPtr); + LOG(info) << count << " ZDCRawParserDPLSpec::run: fmt=" << dataFormat << " size=" << it.size() << " link=" << linkID; #endif - for (int32_t ip = 0; ip < payloadSize; ip += 16) { - // o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); - mWorker.processWord((const uint32_t*)&payload[ip]); + if (dataFormat == 2) { + for (int32_t ip = 0; (ip + PayloadPerGBTW) <= payloadSize; ip += PayloadPerGBTW) { + // Assign only the actual payload + uint32_t gbtw[4] = {0x0, 0x0, 0x0, 0x0}; + memcpy((void*)gbtw, (const void*)&payload[ip], PayloadPerGBTW); +#ifdef O2_ZDC_DEBUG + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)gbtw); +#endif + if (gbtw[0] != 0xffffffff && gbtw[1] != 0xffffffff && (gbtw[2] & 0xffff) != 0xffff) { + mWorker.processWord(gbtw); + } + } + } else if (dataFormat == 0) { + for (int32_t ip = 0; ip < payloadSize; ip += NBPerGBTW) { + // o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&payload[ip]); + mWorker.processWord((const uint32_t*)&payload[ip]); + } + } else { + LOG(error) << "ZDCDataReaderDPLSpec::run - Unsupported DataFormat " << dataFormat; } } } diff --git a/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h b/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h index a7e8d5f13c3b9..869b00911a1e5 100644 --- a/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h +++ b/Detectors/ZDC/simulation/include/ZDCSimulation/Digits2Raw.h @@ -19,6 +19,7 @@ #include #include #include "Headers/RAWDataHeader.h" +#include "Framework/Logger.h" #include "CommonDataFormat/InteractionRecord.h" #include "DetectorsRaw/RawFileWriter.h" #include "DetectorsRaw/HBFUtils.h" @@ -58,6 +59,13 @@ class Digits2Raw // void setContinuous(bool v = true) { mIsContinuous = v; } bool isContinuous() const { return mIsContinuous; } + + void setEnablePadding(bool v) + { + mEnablePadding = v; + } + bool getEnablePadding() const { return mEnablePadding; } + static void print_gbt_word(const uint32_t* word, const ModuleConfig* moduleConfig = nullptr); private: @@ -77,6 +85,7 @@ class Digits2Raw EventData mZDC; /// Output structure bool mIsContinuous = true; /// Continuous (self-triggered) or externally-triggered readout bool mOutputPerLink = false; /// Split output + int mEnablePadding = 0; /// Enable padding to 128 bit const ModuleConfig* mModuleConfig = nullptr; /// Trigger/readout configuration object const SimCondition* mSimCondition = nullptr; /// Pedestal/noise configuration object uint16_t mScalers[NModules][NChPerModule] = {0}; /// ZDC orbit scalers diff --git a/Detectors/ZDC/simulation/src/Digits2Raw.cxx b/Detectors/ZDC/simulation/src/Digits2Raw.cxx index ea083f4943760..bd865fc63c1d4 100644 --- a/Detectors/ZDC/simulation/src/Digits2Raw.cxx +++ b/Detectors/ZDC/simulation/src/Digits2Raw.cxx @@ -61,6 +61,8 @@ void Digits2Raw::processDigits(const std::string& outDir, const std::string& fil mFLPID = uint16_t(0); mEndPointID = uint32_t(0); // TODO: assign FeeID from configuration object + // N.B. Now the electronics has the possibility to reconfigure FEE ID in order to match + // what is expected from simulation. The FEE ID should never change in the future for (int ilink = 0; ilink < NLinks; ilink++) { uint64_t FeeID = uint64_t(ilink); std::string outFileLink = o2::utils::Str::concat_string(outDir, "/", "ZDC"); @@ -237,14 +239,7 @@ inline void Digits2Raw::updatePedestalReference(int bc) for (int32_t ic = 0; ic < NChPerModule; ic++) { // Identify connected channel auto id = mModuleConfig->modules[im].channelID[ic]; - double myped = mzdcPedData[io].data[id] + 32768.; - if (myped < 0) { - myped = 0; - } - if (myped > 65535) { - myped = 65535; - } - mPed[im][ic] = myped; + mPed[im][ic] = *((uint16_t*)&mzdcPedData[io].data[id]); } } } else if (mEmpty[bc] > 0 && mEmpty[bc] != mLastNEmpty) { @@ -495,8 +490,14 @@ void Digits2Raw::writeDigits() uint64_t FeeID = 2 * im + ic / 2; if (mModuleConfig->modules[im].readChannel[ic]) { for (int32_t iw = 0; iw < o2::zdc::NWPerBc; iw++) { - gsl::span payload{reinterpret_cast(&mZDC.data[im][ic].w[iw][0]), data_size}; - mWriter.addData(FeeID, mCruID, mLinkID, mEndPointID, ir, payload); + if (mEnablePadding) { + gsl::span payload{reinterpret_cast(&mZDC.data[im][ic].w[iw][0]), data_size}; + mWriter.addData(FeeID, mCruID, mLinkID, mEndPointID, ir, payload); + } else { + gsl::span payload{reinterpret_cast(&mZDC.data[im][ic].w[iw][0]), PayloadPerGBTW}; + o2::zdc::Digits2Raw::print_gbt_word((const uint32_t*)&mZDC.data[im][ic].w[iw][0]); + mWriter.addData(FeeID, mCruID, mLinkID, mEndPointID, ir, payload); + } } addedChData[ic] = true; } @@ -560,10 +561,8 @@ void Digits2Raw::print_gbt_word(const uint32_t* word, const ModuleConfig* module ULong64_t msb = val >> 64; uint32_t a = word[0]; uint32_t b = word[1]; - uint32_t c = word[2]; - // uint32_t d=(msb>>32)&0xffffffff; - // printf("\n%llx %llx ",lsb,msb); - // printf("\n%8x %8x %8x %8x ",d,c,b,a); + uint16_t c = *((uint16_t*)&word[2]); + // printf("\nGBTW: %04x %08x %08x\n",c,b,a); if ((a & 0x3) == 0) { uint32_t myorbit = (val >> 48) & 0xffffffff; uint32_t mybc = (val >> 36) & 0xfff; diff --git a/Detectors/ZDC/simulation/src/digi2raw.cxx b/Detectors/ZDC/simulation/src/digi2raw.cxx index b4c6cdc2e254c..61d778092f29c 100644 --- a/Detectors/ZDC/simulation/src/digi2raw.cxx +++ b/Detectors/ZDC/simulation/src/digi2raw.cxx @@ -38,7 +38,7 @@ namespace bpo = boost::program_options; -void digi2raw(const std::string& inpName, const std::string& outDir, int verbosity, const std::string& fileFor, uint32_t rdhV = 4, +void digi2raw(const std::string& inpName, const std::string& outDir, int verbosity, const std::string& fileFor, uint32_t rdhV = 7, bool enablePadding = false, const std::string& ccdbHost = "", int superPageSizeInB = 1024 * 1024); int main(int argc, char** argv) @@ -60,6 +60,7 @@ int main(int argc, char** argv) add_option("output-dir,o", bpo::value()->default_value("./"), "output directory for raw data"); uint32_t defRDH = o2::raw::RDHUtils::getVersion(); add_option("rdh-version,r", bpo::value()->default_value(defRDH), "RDH version to use"); + add_option("enable-padding", bpo::value()->default_value(false)->implicit_value(true), "enable GBT word padding to 128 bits even for RDH V7"); add_option("hbfutils-config,u", bpo::value()->default_value(std::string(o2::base::NameConf::DIGITIZATIONCONFIGFILE)), "config file for HBFUtils (or none)"); add_option("configKeyValues", bpo::value()->default_value(""), "comma-separated configKeyValues"); @@ -94,6 +95,7 @@ int main(int argc, char** argv) vm["verbosity"].as(), vm["file-for"].as(), vm["rdh-version"].as(), + vm["enable-padding"].as(), ccdbHost); o2::raw::HBFUtils::Instance().print(); @@ -101,8 +103,12 @@ int main(int argc, char** argv) return 0; } -void digi2raw(const std::string& inpName, const std::string& outDir, int verbosity, const std::string& fileFor, uint32_t rdhV, const std::string& ccdbHost, int superPageSizeInB) +void digi2raw(const std::string& inpName, const std::string& outDir, int verbosity, const std::string& fileFor, uint32_t rdhV, bool enablePadding, const std::string& ccdbHost, int superPageSizeInB) { + if (rdhV < 7 && !enablePadding) { + enablePadding = true; + LOG(info) << "padding is always ON for RDH version " << rdhV; + } //std::string ccdbHost = "http://ccdb-test.cern.ch:8080"; auto& mgr = o2::ccdb::BasicCCDBManager::instance(); mgr.setURL(ccdbHost); @@ -126,6 +132,8 @@ void digi2raw(const std::string& inpName, const std::string& outDir, int verbosi LOG(info) << "Loaded simulation configuration for timestamp " << mgr.getTimestamp(); simCondition->print(); + LOG(info) << "RDHVersion " << rdhV << " padding: " << enablePadding; + const auto* ctx = o2::steer::DigitizationContext::loadFromFile("collisioncontext.root"); const auto& bcfill = ctx->getBunchFilling(); auto bf = ctx->getBunchFilling(); @@ -139,6 +147,7 @@ void digi2raw(const std::string& inpName, const std::string& outDir, int verbosi o2::zdc::Digits2Raw d2r; d2r.setFileFor(fileFor); + d2r.setEnablePadding(enablePadding); d2r.setVerbosity(verbosity); auto& wr = d2r.getWriter(); std::string inputGRP = o2::base::NameConf::getGRPFileName(); @@ -146,7 +155,11 @@ void digi2raw(const std::string& inpName, const std::string& outDir, int verbosi wr.setContinuousReadout(grp->isDetContinuousReadOut(o2::detectors::DetID::ZDC)); // must be set explicitly wr.setSuperPageSize(superPageSizeInB); wr.useRDHVersion(rdhV); - + wr.useRDHDataFormat(enablePadding ? 0 : 2); + if (!enablePadding) { // CRU page alignment padding is used only if no GBT word padding is used + wr.setAlignmentSize(16); + wr.setAlignmentPaddingFiller(0xff); + } o2::raw::assertOutputDirectory(outDir); std::string outDirName(outDir); diff --git a/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx b/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx index cb5e5e4dd0ab0..7caf605d8ef38 100644 --- a/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx +++ b/Detectors/ZDC/workflow/src/ZDCDataReaderDPLSpec.cxx @@ -86,7 +86,7 @@ void ZDCDataReaderDPLSpec::run(ProcessingContext& pc) DPLRawParser parser(pc.inputs(), o2::framework::select("zdc:ZDC/RAWDATA")); uint64_t count = 0; - static uint64_t nErr[3] = {0}; + static uint64_t nErr[4] = {0}; for (auto it = parser.begin(), end = parser.end(); it != end; ++it) { // Processing each page auto rdhPtr = reinterpret_cast(it.raw()); @@ -105,10 +105,14 @@ void ZDCDataReaderDPLSpec::run(ProcessingContext& pc) } else { gsl::span payload(it.data(), it.size()); auto lid = o2::raw::RDHUtils::getLinkID(rdhPtr); + auto dataFormat = o2::raw::RDHUtils::getDataFormat(rdhPtr); #ifdef O2_ZDC_DEBUG LOG(info) << count << " processBinaryData: size=" << it.size() << " link=" << lid; #endif - mRawReader.processBinaryData(payload, lid); + if (mRawReader.processBinaryData(payload, lid, dataFormat)) { + nErr[3]++; + break; + } } } count++; @@ -123,10 +127,10 @@ void ZDCDataReaderDPLSpec::run(ProcessingContext& pc) if (nErr[2] > 0) { LOG(warning) << "ZDCDataReaderDPLSpec::run - No payload occurrences " << nErr[2]; } - if (nErr[0] == 0) { + if (nErr[0] == 0 && nErr[3] == 0) { mRawReader.accumulateDigits(); } else { - LOG(warning) << "Not sending output "; + LOG(warning) << "Not sending output"; } mRawReader.makeSnapshot(pc); }