diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 40d116e1d..2152a0135 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -1469,6 +1469,7 @@ class Detector { private: std::vector getPortNumbers(int start_port); + void updateRxRateCorrections(); }; } // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 10d7d7592..46aa5d925 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -771,6 +771,7 @@ Result Detector::getRxHostname(Positions pos) const { void Detector::setRxHostname(const std::string &receiver, Positions pos) { pimpl->Parallel(&Module::setReceiverHostname, pos, receiver); + updateRxRateCorrections(); } void Detector::setRxHostname(const std::vector &name) { @@ -788,6 +789,7 @@ void Detector::setRxHostname(const std::vector &name) { pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]); } } + updateRxRateCorrections(); } Result Detector::getRxPort(Positions pos) const { @@ -1109,6 +1111,20 @@ void Detector::setDefaultRateCorrection(Positions pos) { void Detector::setRateCorrection(ns dead_time, Positions pos) { pimpl->Parallel(&Module::setRateCorrection, pos, dead_time.count()); + updateRxRateCorrections(); +} + +void Detector::updateRxRateCorrections() { + // get tau from all modules and send to Rx index 0 + if (getUseReceiverFlag().squash(false)) { + // convert Result to std::vector + auto retval = getRateCorrection(); + std::vector t(retval.size()); + for (int i = 0; i < (int)retval.size(); ++i) { + t[i] = retval[i].count(); + } + pimpl->Parallel(&Module::sendReceiverRateCorrections, {0}, t); + } } Result Detector::getPartialReadout(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index f44e34f48..e613a961d 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1163,6 +1163,21 @@ void Module::setRateCorrection(int64_t t) { sendToDetector(F_SET_RATE_CORRECT, t, nullptr); } +void Module::sendReceiverRateCorrections(const std::vector &t) { + LOG(logDEBUG) << "Sending to detector [rate corrections: " << ToString(t) + << ']'; + auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); + receiver.Send(F_SET_RECEIVER_RATE_CORRECT); + // TODO: use overload for vector + int size = t.size(); + receiver.Send(size); + receiver.Send(t.data(), t.size() * sizeof(t[0])); + if (receiver.Receive() == FAIL) { + throw RuntimeError("Receiver " + std::to_string(moduleId) + + " returned error: " + receiver.readErrorMessage()); + } +} + int Module::getReadNLines() const { return sendToDetector(F_GET_READ_N_LINES); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index fecb590cd..d1c9cc93a 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -312,6 +312,7 @@ class Module : public virtual slsDetectorDefs { int64_t getRateCorrection() const; void setDefaultRateCorrection(); void setRateCorrection(int64_t t = 0); + void sendReceiverRateCorrections(const std::vector &t); int getReadNLines() const; void setReadNLines(const int value); bool getInterruptSubframe() const; @@ -371,8 +372,9 @@ class Module : public virtual slsDetectorDefs { void setBurstPeriod(int64_t value); std::array getInjectChannel() const; void setInjectChannel(const int offsetChannel, const int incrementChannel); - void sendVetoPhoton(const int chipIndex, const std::vector& gainIndices, - const std::vector& values); + void sendVetoPhoton(const int chipIndex, + const std::vector &gainIndices, + const std::vector &values); void getVetoPhoton(const int chipIndex, const std::string &fname) const; void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string &fname); diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 64857950d..dc20985d1 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -201,6 +201,7 @@ int ClientInterface::functionTable(){ flist[F_GET_RECEIVER_THREAD_IDS] = &ClientInterface::get_thread_ids; flist[F_GET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::get_streaming_start_fnum; flist[F_SET_RECEIVER_STREAMING_START_FNUM] = &ClientInterface::set_streaming_start_fnum; + flist[F_SET_RECEIVER_RATE_CORRECT] = &ClientInterface::set_rate_correct; for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << @@ -906,7 +907,8 @@ int ClientInterface::get_missing_packets(Interface &socket) { auto size = static_cast(missing_packets.size()); socket.Send(OK); socket.Send(size); - socket.Send(missing_packets.data(), sizeof(missing_packets[0])* missing_packets.size()); + socket.Send(missing_packets.data(), + sizeof(missing_packets[0]) * missing_packets.size()); return OK; } @@ -1204,7 +1206,7 @@ int ClientInterface::set_additional_json_header(Interface &socket) { socket.Receive(&buff[0], buff.size()); std::istringstream iss(buff); std::string key, value; - while(iss >> key){ + while (iss >> key) { iss >> value; json[key] = value; } @@ -1219,7 +1221,7 @@ int ClientInterface::get_additional_json_header(Interface &socket) { std::map json = impl()->getAdditionalJsonHeader(); LOG(logDEBUG1) << "additional json header:" << sls::ToString(json); std::ostringstream oss; - for (auto & it : json){ + for (auto &it : json) { oss << it.first << ' ' << it.second << ' '; } auto buff = oss.str(); @@ -1735,3 +1737,18 @@ int ClientInterface::set_streaming_start_fnum(Interface &socket) { validate(index, retval, "set streaming start fnum", DEC); return socket.Send(OK); } + +int ClientInterface::set_rate_correct(Interface &socket) { + auto index = socket.Receive(); + if (index <= 0) { + throw RuntimeError("Invalid number of rate correction values: " + + std::to_string(index)); + } + LOG(logDEBUG) << "Number of detectors for rate correction: " << index; + std::vector t(index); + socket.Receive(t.data(), t.size() * sizeof(t[0])); + verifyIdle(socket); + LOG(logINFOBLUE) << "Setting rate corrections[" << index << ']'; + impl()->setRateCorrections(t); + return socket.Send(OK); +} \ No newline at end of file diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index dc54a86dd..effd11dbb 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -157,6 +157,7 @@ class ClientInterface : private virtual slsDetectorDefs { int get_thread_ids(sls::ServerInterface &socket); int get_streaming_start_fnum(sls::ServerInterface &socket); int set_streaming_start_fnum(sls::ServerInterface &socket); + int set_rate_correct(sls::ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 0ba8e2528..0e4ea412d 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -47,6 +47,7 @@ void Implementation::DeleteMembers() { fifo.clear(); eth.clear(); udpPortNum.clear(); + rateCorrections.clear(); ctbDbitList.clear(); } @@ -946,6 +947,7 @@ void Implementation::SetupWriter() { masterAttributes->subExptime = std::chrono::nanoseconds(subExpTime); masterAttributes->subPeriod = std::chrono::nanoseconds(subPeriod); masterAttributes->quad = quadEnable; + masterAttributes->ratecorr = rateCorrections; masterAttributes->adcmask = tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga; masterAttributes->analog = @@ -1798,6 +1800,11 @@ void Implementation::setReadNLines(const int value) { LOG(logINFO) << "Number of Lines to readout: " << numLinesReadout; } +void Implementation::setRateCorrections(const std::vector &t) { + rateCorrections = t; + LOG(logINFO) << "Rate Corrections: " << sls::ToString(rateCorrections); +} + slsDetectorDefs::readoutMode Implementation::getReadoutMode() const { LOG(logDEBUG3) << __SHORT_AT__ << " called"; return readoutType; diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index f2001ac14..a669a0820 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -211,6 +211,8 @@ class Implementation : private virtual slsDetectorDefs { int getReadNLines() const; /* [Eiger] */ void setReadNLines(const int value); + /* [Eiger] */ + void setRateCorrections(const std::vector &t); readoutMode getReadoutMode() const; /* [Ctb] */ void setReadoutMode(const readoutMode f); @@ -336,6 +338,7 @@ class Implementation : private virtual slsDetectorDefs { bool activated; bool deactivatedPaddingEnable; int numLinesReadout; + std::vector rateCorrections; readoutMode readoutType; uint32_t adcEnableMaskOneGiga; uint32_t adcEnableMaskTenGiga; diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 3a7f84b89..4fe1fef92 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -34,6 +34,7 @@ class MasterAttributes { ns subExptime{0}; ns subPeriod{0}; uint32_t quad{0}; + std::vector ratecorr; uint32_t adcmask{0}; uint32_t analog{0}; uint32_t digital{0}; @@ -292,7 +293,9 @@ class EigerMasterAttributes : public MasterAttributes { << '\n' << "SubPeriod : " << sls::ToString(subPeriod) << '\n' - << "Quad : " << quad << '\n'; + << "Quad : " << quad << '\n' + << "Rate Corrections : " << sls::ToString(ratecorr) + << '\n'; std::string message = oss.str(); MasterAttributes::WriteBinaryAttributes(fd, message); }; @@ -339,6 +342,14 @@ class EigerMasterAttributes : public MasterAttributes { group->createDataSet("quad", PredType::NATIVE_INT, dataspace); dataset.write(&quad, PredType::NATIVE_INT); } + // Rate corrections + { + DataSpace dataspace = DataSpace(H5S_SCALAR); + StrType strdatatype(PredType::C_S1, 256); + DataSet dataset = group->createDataSet("rate corrections", + strdatatype, dataspace); + dataset.write(sls::ToString(ratecorr), strdatatype); + } }; #endif }; diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index a739b0ac2..8d83fbdc5 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -309,6 +309,7 @@ enum detFuncs { F_GET_RECEIVER_THREAD_IDS, F_GET_RECEIVER_STREAMING_START_FNUM, F_SET_RECEIVER_STREAMING_START_FNUM, + F_SET_RECEIVER_RATE_CORRECT, NUM_REC_FUNCTIONS }; @@ -617,9 +618,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_RECEIVER_NUM_GATES: return "F_SET_RECEIVER_NUM_GATES"; case F_SET_RECEIVER_GATE_DELAY: return "F_SET_RECEIVER_GATE_DELAY"; case F_GET_RECEIVER_THREAD_IDS: return "F_GET_RECEIVER_THREAD_IDS"; - case F_GET_RECEIVER_STREAMING_START_FNUM: return "F_GET_RECEIVER_STREAMING_START_FNUM"; case F_SET_RECEIVER_STREAMING_START_FNUM: return "F_SET_RECEIVER_STREAMING_START_FNUM"; + case F_SET_RECEIVER_RATE_CORRECT: return "F_SET_RECEIVER_RATE_CORRECT"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function";