From c9793129dbbb48c517f131bc3c97d109467d5637 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 11 May 2026 17:24:50 +0200 Subject: [PATCH] wip, master attributes --- slsDetectorSoftware/src/Module.cpp | 1 + slsReceiverSoftware/src/ClientInterface.cpp | 34 ++++++++++++++++ slsReceiverSoftware/src/ClientInterface.h | 1 + slsReceiverSoftware/src/Implementation.cpp | 8 ++++ slsReceiverSoftware/src/Implementation.h | 4 ++ slsReceiverSoftware/src/MasterAttributes.cpp | 42 ++++++++++++++++++++ slsReceiverSoftware/src/MasterAttributes.h | 9 ++++- 7 files changed, 98 insertions(+), 1 deletion(-) diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 32f3e42a4..21642e7a2 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1436,6 +1436,7 @@ void Module::setDataStream(const portPosition port, const bool enable) { void Module::updateRxUDPDatastreamMetadata( const std::array, 2> &res) { + if (!shm()->useReceiverFlag) { return; } diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 2b43c617f..c4b63c04f 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -222,6 +222,8 @@ int ClientInterface::functionTable(){ flist[F_RECEIVER_GET_ROI_METADATA] = &ClientInterface::get_roi_metadata; flist[F_SET_RECEIVER_READOUT_SPEED] = &ClientInterface::set_readout_speed; flist[F_RECEIVER_GET_UDP_DATASTREAM] = &ClientInterface::get_port_udp_datastream; + flist[F_RECEIVER_UDP_DATASTREAM_METADATA]= &ClientInterface::update_udp_datastream_metadata; + for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { LOG(logDEBUG1) << "function fnum: " << i << " (" << @@ -1916,4 +1918,36 @@ int ClientInterface::set_readout_speed(Interface &socket) { return socket.Send(OK); } +int ClientInterface::update_udp_datastream_metadata(Interface &socket) { + auto nports = socket.Receive(); + if (nports != 2) { + throw RuntimeError("Could not update udp datastream meatdata. " + "Expecting max number of ports to be 2. Received " + + std::to_string(nports)); + } + auto nmods = socket.Receive(); + if (nmods < 1) { + throw RuntimeError("Could not update udp datastream metadata. " + "Expecting at least 1 module. Received " + + std::to_string(nmods)); + } + std::array, 2> portEnables; + for (auto &v : portEnables) { + v.resize(nmods); + } + socket.Receive(portEnables[0]); + socket.Receive(portEnables[1]); + LOG(logDEBUG1) << "Update UDP Datastream Metadata"; + LOG(logDEBUG1) << "Port 1:" << ToString(portEnables[0]); + LOG(logDEBUG1) << "Port 2:" << ToString(portEnables[1]); + verifyIdle(socket); + try { + impl()->updateUDPDatastreamMetadata(portEnables); + } catch (const std::exception &e) { + throw RuntimeError("Could not update UDP datastream metadata [" + + std::string(e.what()) + ']'); + } + return socket.Send(OK); +} + } // namespace sls diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index feedebda2..f0dd0d90d 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -170,6 +170,7 @@ class ClientInterface : private virtual slsDetectorDefs { int set_dbit_reorder(ServerInterface &socket); int get_roi_metadata(ServerInterface &socket); int set_readout_speed(ServerInterface &socket); + int update_udp_datastream_metadata(ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 91e6c0d08..6441c1bed 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -994,6 +994,9 @@ void Implementation::StartMasterWriter() { masterAttributes.gates = numberOfGates; masterAttributes.additionalJsonHeader = additionalJsonHeader; masterAttributes.readoutSpeed = readoutSpeed; + masterAttributes.udpPortEnables = udpPortEnables; + masterAttributes.udpPortType[0] = ToString(udpDataStreamType[0]); + masterAttributes.udpPortType[1] = ToString(udpDataStreamType[1]); // create master file masterFileName = dataProcessor[0]->CreateMasterFile( @@ -1709,6 +1712,11 @@ void Implementation::setUDPDataStream(const portPosition port, listener[i]->SetUDPDatastream(udpDataStream[i]); } +void Implementation::updateUDPDatastreamMetadata( + const std::array, 2> &portEnables) { + udpPortEnables = portEnables; +} + int Implementation::getReadNRows() const { return readNRows; } void Implementation::setReadNRows(const int value) { diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 7e29c1e4e..72c3ea539 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -230,6 +230,8 @@ class Implementation : private virtual slsDetectorDefs { * [Eiger] deactivated at module level */ void setUDPDataStream(const portPosition port, const bool enable); + void updateUDPDatastreamMetadata( + const std::array, 2> &portEnables); int getReadNRows() const; /* [Eiger][Jungfrau][Moench] */ void setReadNRows(const int value); @@ -366,6 +368,8 @@ class Implementation : private virtual slsDetectorDefs { bool quadEnable{false}; bool activated{true}; std::array udpDataStream = {{true, true}}; + std::array, 2> udpPortEnables; + std::vector udpPort2Enable; std::array udpDataStreamType = {{LEFT, RIGHT}}; // only for Eiger to remember (10Gbe selectable) std::array udpDataStream10GbE = {{true, true}}; diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index 76907ea04..fbc74ff78 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -55,6 +55,8 @@ void MasterAttributes::GetJungfrauBinaryAttributes(writer *w) { WriteBinaryNumberOfUDPInterfaces(w); WriteBinaryNumberOfRows(w); WriteBinaryReadoutSpeed(w); + if (numUDPInterfaces == 2) + WriteBinaryUDPPortEnables(w); } #ifdef HDF5C @@ -65,6 +67,8 @@ void MasterAttributes::WriteJungfrauHDF5Attributes(H5::Group *group) { WriteHDF5NumberOfUDPInterfaces(group); WriteHDF5NumberOfRows(group); WriteHDF5ReadoutSpeed(group); + if (numUDPInterfaces == 2) + WriteHDF5UDPPortEnables(group); } #endif @@ -75,6 +79,8 @@ void MasterAttributes::GetMoenchBinaryAttributes(writer *w) { WriteBinaryNumberOfUDPInterfaces(w); WriteBinaryNumberOfRows(w); WriteBinaryReadoutSpeed(w); + if (numUDPInterfaces == 2) + WriteBinaryUDPPortEnables(w); } #ifdef HDF5C @@ -85,6 +91,8 @@ void MasterAttributes::WriteMoenchHDF5Attributes(H5::Group *group) { WriteHDF5NumberOfUDPInterfaces(group); WriteHDF5NumberOfRows(group); WriteHDF5ReadoutSpeed(group); + if (numUDPInterfaces == 2) + WriteHDF5UDPPortEnables(group); } #endif @@ -101,6 +109,7 @@ void MasterAttributes::GetEigerBinaryAttributes(writer *w) { WriteBinaryNumberOfRows(w); WriteBinaryRateCorrections(w); WriteBinaryReadoutSpeed(w); + WriteBinaryUDPPortEnables(w); } #ifdef HDF5C @@ -117,6 +126,7 @@ void MasterAttributes::WriteEigerHDF5Attributes(H5::Group *group) { WriteHDF5NumberOfRows(group); WriteHDF5RateCorrections(group); WriteHDF5ReadoutSpeed(group); + WriteHDF5UDPPortEnables(group); } #endif @@ -690,6 +700,38 @@ void MasterAttributes::WriteHDF5TransceiverSamples(H5::Group *group) { } #endif +void MasterAttributes::WriteBinaryUDPPortEnables(writer *w) { + for (size_t i = 0; i != udpPortType.size(); ++i) { + std::string key = udpPortType[i] + std::string(N_UDP_PORT_ENABLES); + w->Key(key.c_str()); + w->StartArray(); + for (const int u : udpPortEnables[i]) { + w->Int(u); + } + w->EndArray(); + } +} + +#ifdef HDF5C +void MasterAttributes::WriteHDF5UDPPortEnables(H5::Group *group) { + for (size_t i = 0; i != udpPortType.size(); ++i) { + // convert vector -> vector + std::vector vals(udpPortEnables[i].begin(), + udpPortEnables[i].end()); + + hsize_t dims[1] = {vals.size()}; + H5::DataSpace dataspace(1, dims); + + std::string key = udpPortType[i] + std::string(N_UDP_PORT_ENABLES); + + H5::DataSet dataset = + group->createDataSet(key, H5::PredType::NATIVE_UINT32, dataspace); + + dataset.write(vals.data(), H5::PredType::NATIVE_UINT32); + } +} +#endif + #ifdef HDF5C void MasterAttributes::WriteHDF5String(H5::Group *group, const std::string &name, diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index d8a188671..eb72b224d 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -68,6 +68,8 @@ class MasterAttributes { std::map additionalJsonHeader; uint64_t framesInFile{0}; slsDetectorDefs::speedLevel readoutSpeed{slsDetectorDefs::FULL_SPEED}; + std::array, 2> udpPortEnables; + std::array udpPortType; inline static const std::string_view N_DETECTOR_TYPE = "Detector Type"; inline static const std::string_view N_TIMING_MODE = "Timing Mode"; @@ -125,6 +127,8 @@ class MasterAttributes { inline static const std::string_view N_SCAN_PARAMETERS = "Scan Parameters"; inline static const std::string_view N_ADDITIONAL_JSON_HEADER = "Additional JSON Header"; + inline static const std::string_view N_UDP_PORT_ENABLES = + " UDP Port Enables"; MasterAttributes() = default; ~MasterAttributes() = default; @@ -334,7 +338,10 @@ class MasterAttributes { #ifdef HDF5C void WriteHDF5TransceiverSamples(H5::Group *group); #endif - + void WriteBinaryUDPPortEnables(writer *w); +#ifdef HDF5C + void WriteHDF5UDPPortEnables(H5::Group *group); +#endif /** writes according to type */ template void WriteBinaryValue(writer *w, const T &value) { if constexpr (std::is_same_v) {