From 4f6153b2f3338257d7a04b292a478de40a4d267e Mon Sep 17 00:00:00 2001 From: Jose Borreguero Date: Mon, 29 Sep 2025 13:55:11 -0400 Subject: [PATCH 1/4] Refactor SNSLiveEventDataListener and ADARAParser for improved clarity and functionality Signed-off-by: Jose Borreguero --- .../MantidLiveData/SNSLiveEventDataListener.h | 29 +++++------ Framework/LiveData/src/ADARA/ADARAParser.cpp | 48 +++++++++---------- .../LiveData/src/SNSLiveEventDataListener.cpp | 36 ++++++-------- .../PythonInterface/mantid/utils/logging.py | 18 ++++--- .../Framework/LiveData/New_features/39186.rst | 1 - 5 files changed, 64 insertions(+), 68 deletions(-) delete mode 100644 docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h index f2f2154c606d..066e15f59104 100644 --- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h @@ -21,9 +21,8 @@ namespace Mantid { namespace LiveData { -/** An implementation of ILiveListener for use at SNS. Connects to the Stream - Management - Service and receives events from it. +/** An implementation of ILiveListener for use at SNS. + * Connects to the Stream Management Service and receives events from it. */ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable, public ADARA::Parser { public: @@ -53,18 +52,17 @@ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable protected: using ADARA::Parser::rxPacket; // virtual bool rxPacket( const ADARA::Packet &pkt); - // virtual bool rxPacket( const ADARA::RawDataPkt &pkt); + bool rxPacket(const ADARA::AnnotationPkt &pkt) override; bool rxPacket(const ADARA::BankedEventPkt &pkt) override; + bool rxPacket(const ADARA::BeamlineInfoPkt &pkt) override; bool rxPacket(const ADARA::BeamMonitorPkt &pkt) override; + bool rxPacket(const ADARA::DeviceDescriptorPkt &pkt) override; bool rxPacket(const ADARA::GeometryPkt &pkt) override; - bool rxPacket(const ADARA::BeamlineInfoPkt &pkt) override; + bool rxPacket(const ADARA::RunInfoPkt &pkt) override; bool rxPacket(const ADARA::RunStatusPkt &pkt) override; bool rxPacket(const ADARA::VariableU32Pkt &pkt) override; bool rxPacket(const ADARA::VariableDoublePkt &pkt) override; bool rxPacket(const ADARA::VariableStringPkt &pkt) override; - bool rxPacket(const ADARA::DeviceDescriptorPkt &pkt) override; - bool rxPacket(const ADARA::AnnotationPkt &pkt) override; - bool rxPacket(const ADARA::RunInfoPkt &pkt) override; private: // Workspace initialization needs to happen in 2 steps. Part 1 must happen @@ -117,11 +115,11 @@ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable detid2index_map m_indexMap; // maps pixel id's to workspace indexes detid2index_map m_monitorIndexMap; // Same as above for the monitor workspace - // We need these 2 strings to initialize m_buffer + // We need these 2 strings to initialize m_eventBuffer std::string m_instrumentName; std::string m_instrumentXML; - // Names of log values that we need before we can initialize m_buffer. + // Names of log values that we need before we can initialize m_eventBuffer. // We get the names by parsing m_instrumentXML; std::vector m_requiredLogs; @@ -133,7 +131,7 @@ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable bool m_isConnected{false}; Poco::Thread m_thread; - std::mutex m_mutex; // protects m_buffer & m_status + std::mutex m_mutex; // protects m_eventBuffer & m_status bool m_pauseNetRead{false}; bool m_stopThread{false}; // background thread checks this periodically. // If true, the thread exits @@ -161,7 +159,7 @@ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable // --- Data structures necessary for handling all the process variable info // --- - // maps to variable name + // maps a pair to its Processing Variable's name // (variable names are unique, so we don't need to worry about device names.) using NameMapType = std::map, std::string>; NameMapType m_nameMap; @@ -176,12 +174,15 @@ class SNSLiveEventDataListener : public API::LiveListener, public Poco::Runnable // need to parse whatever variable value packets we have in order to set the // state of the system properly. - // Maps the device ID / variable ID pair to the actual packet. Using a map + // Maps the pair to the actual packet. Using a map // means we will only keep one packet (the most recent one) for each variable using VariableMapType = std::map, std::shared_ptr>; VariableMapType m_variableMap; - // Process all the variable value packets stored in m_variableMap + /// Process all the variable value packets stored in m_variableMap and then clear this cache + /// + /// The method is triggered through the packet processing chain: + /// - rxPacket() → ignorePacket() → replayVariableCache() void replayVariableCache(); // --------------------------------------------------------------------------- diff --git a/Framework/LiveData/src/ADARA/ADARAParser.cpp b/Framework/LiveData/src/ADARA/ADARAParser.cpp index 79532b945f3a..a3d2af8592a5 100644 --- a/Framework/LiveData/src/ADARA/ADARAParser.cpp +++ b/Framework/LiveData/src/ADARA/ADARAParser.cpp @@ -63,7 +63,7 @@ void Parser::reset() { m_len = 0; m_oversize_len = 0; m_restart_offset = 0; - + m_oversize_offset = 0; m_discarded_packets.clear(); } @@ -314,38 +314,38 @@ bool Parser::rxOversizePkt(const PacketHeader *hdr, const uint8_t * /*unused*/, return false; \ } -EXPAND_HANDLER(RawDataPkt) -EXPAND_HANDLER(MappedDataPkt) -EXPAND_HANDLER(RTDLPkt) -EXPAND_HANDLER(SourceListPkt) +EXPAND_HANDLER(AnnotationPkt) EXPAND_HANDLER(BankedEventPkt) EXPAND_HANDLER(BankedEventStatePkt) -EXPAND_HANDLER(BeamMonitorPkt) -EXPAND_HANDLER(PixelMappingPkt) -EXPAND_HANDLER(PixelMappingAltPkt) -EXPAND_HANDLER(RunStatusPkt) -EXPAND_HANDLER(RunInfoPkt) -EXPAND_HANDLER(TransCompletePkt) -EXPAND_HANDLER(ClientHelloPkt) -EXPAND_HANDLER(AnnotationPkt) -EXPAND_HANDLER(SyncPkt) -EXPAND_HANDLER(HeartbeatPkt) -EXPAND_HANDLER(GeometryPkt) EXPAND_HANDLER(BeamlineInfoPkt) EXPAND_HANDLER(BeamMonitorConfigPkt) -EXPAND_HANDLER(DetectorBankSetsPkt) +EXPAND_HANDLER(BeamMonitorPkt) +EXPAND_HANDLER(ClientHelloPkt) EXPAND_HANDLER(DataDonePkt) +EXPAND_HANDLER(DetectorBankSetsPkt) EXPAND_HANDLER(DeviceDescriptorPkt) -EXPAND_HANDLER(VariableU32Pkt) -EXPAND_HANDLER(VariableDoublePkt) -EXPAND_HANDLER(VariableStringPkt) -EXPAND_HANDLER(VariableU32ArrayPkt) -EXPAND_HANDLER(VariableDoubleArrayPkt) -EXPAND_HANDLER(MultVariableU32Pkt) +EXPAND_HANDLER(GeometryPkt) +EXPAND_HANDLER(HeartbeatPkt) +EXPAND_HANDLER(MappedDataPkt) EXPAND_HANDLER(MultVariableDoublePkt) +EXPAND_HANDLER(MultVariableDoubleArrayPkt) EXPAND_HANDLER(MultVariableStringPkt) EXPAND_HANDLER(MultVariableU32ArrayPkt) -EXPAND_HANDLER(MultVariableDoubleArrayPkt) +EXPAND_HANDLER(MultVariableU32Pkt) +EXPAND_HANDLER(PixelMappingAltPkt) +EXPAND_HANDLER(PixelMappingPkt) +EXPAND_HANDLER(RawDataPkt) +EXPAND_HANDLER(RTDLPkt) +EXPAND_HANDLER(RunInfoPkt) +EXPAND_HANDLER(RunStatusPkt) +EXPAND_HANDLER(SourceListPkt) +EXPAND_HANDLER(SyncPkt) +EXPAND_HANDLER(TransCompletePkt) +EXPAND_HANDLER(VariableDoublePkt) +EXPAND_HANDLER(VariableDoubleArrayPkt) +EXPAND_HANDLER(VariableStringPkt) +EXPAND_HANDLER(VariableU32ArrayPkt) +EXPAND_HANDLER(VariableU32Pkt) void Parser::getDiscardedPacketsLogString(std::string &log_info) { log_info = "Discarded ADARA Packet/Counts: "; diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp index afeef5ab98b4..a81f8e241e0c 100644 --- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -442,13 +442,12 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::BankedEventPkt &pkt) { /// Parse a beam monitor event packet /** Overrides the default function defined in ADARA::Parser and processes data from ADARA::BeamMonitorPkt packets. - * Parsed events are counted and the counts are accumulated in the temporary workspace until the forground thread + * Parsed events are counted and the counts are accumulated in the temporary workspace until the foreground thread * retrieves them. * * @see extractData() * @param pkt The packet to be parsed - * @return Returns false if there were no problems. Returns true if there was an error and packet parsing should be - * interrupted + * @return false if no problems, true if error occurred and packet parsing should be interrupted */ bool SNSLiveEventDataListener::rxPacket(const ADARA::BeamMonitorPkt &pkt) { // Check to see if we should process this packet (depending on what the user selected for start up options, the SMS @@ -1517,20 +1516,16 @@ ILiveListener::RunStatus SNSLiveEventDataListener::runStatus() { return rv; } -// Called by the rxPacket() functions to determine if the packet should be -// processed -// (Depending on when it last indexed its data, SMS might send us packets that -// are -// older than we requested.) -// Returns false if the packet should be processed, true if is should be ignored +// Called by the rxPacket() functions to determine if the packet should be processed +// (Depending on when it last indexed its data, SNS might send us packets that are older than we requested) +// Returns false if the packet should be processed, true if it should be ignored bool SNSLiveEventDataListener::ignorePacket(const ADARA::PacketHeader &hdr, const ADARA::RunStatus::Enum status) { - // Since we're filtering based on time (either the absolute timestamp or - // nothing - // before the start of the most recent run), once we've determined a given - // packet should be processed, we know all packets after that should also be - // processed. Thus, we can reduce most calls to this function to a simple - // boolean test... - if (!m_ignorePackets) + // Since we're filtering based on time (either the absolute timestamp or nothing + // before the start of the most recent run), + // once we've determined a given packet should be processed, + // we know all packets after that should also be processed. + // Thus, we can reduce most calls to this function to a simple boolean test + if (!m_ignorePackets) // don't ignore return false; // Are we looking for the start of the run? @@ -1548,7 +1543,7 @@ bool SNSLiveEventDataListener::ignorePacket(const ADARA::PacketHeader &hdr, cons // If we've just hit our start-up condition, then process // all the variable value packets we've been hanging on to. - if (!m_ignorePackets) { + if (!m_ignorePackets) { // don't ignore replayVariableCache(); } @@ -1557,12 +1552,9 @@ bool SNSLiveEventDataListener::ignorePacket(const ADARA::PacketHeader &hdr, cons // Process all the variable value packets stored in m_variableMap void SNSLiveEventDataListener::replayVariableCache() { - auto it = m_variableMap.begin(); - while (it != m_variableMap.end()) { - rxPacket(*(*it).second); // call rxPacket() on the stored packet - it++; + for (const auto &varPacketPair : m_variableMap) { + rxPacket(*varPacketPair.second); // call rxPacket() on the stored packet } - m_variableMap.clear(); // empty the map to save a little ram } diff --git a/Framework/PythonInterface/mantid/utils/logging.py b/Framework/PythonInterface/mantid/utils/logging.py index 46d33b5407d5..a987d5e6a632 100644 --- a/Framework/PythonInterface/mantid/utils/logging.py +++ b/Framework/PythonInterface/mantid/utils/logging.py @@ -60,7 +60,7 @@ def capture_logs(level=None) -> io.StringIO: sys.stdout = backup["stdout"] -def log_to_python(level="debug"): +def log_to_python(level=None, pattern=None) -> None: r""" Modify Mantid's logger to forward messages to Python's logging framework instead of outputting them itself. This allows users to configure the logger from Python @@ -70,14 +70,18 @@ def log_to_python(level="debug"): @param str level: Logging level for the *Mantid* logger. Should be set to a low value to forward all potentially relevant messages to Python and let *Python's* logger - filter out undesired messages. Possible values: 'trace', 'debug' (default), + filter out undesired messages. Possible values: 'trace', 'debug', 'information', 'notice', 'warning', 'error', 'critical', 'fatal'. + @param str pattern: A logging pattern to format messages before forwarding them (example: %t) + See https://github.com/pocoproject/poco/wiki/Poco::Util::Application-Logging-Configuration#logging-format-placeholders """ config = ConfigService.Instance() - config["logging.loggers.root.level"] = level - config["logging.channels.consoleChannel.formatter"] = "f1" - # Output only the message text and let Python take care of formatting. - config["logging.formatters.f1.class"] = "PatternFormatter" - config["logging.formatters.f1.pattern"] = "%t" + if level is not None: + config["logging.loggers.root.level"] = level + if pattern is not None: + config["logging.channels.consoleChannel.formatter"] = "f1" + # Output only the message text and let Python take care of formatting. + config["logging.formatters.f1.class"] = "PatternFormatter" + config["logging.formatters.f1.pattern"] = pattern # Important: Do this one last because it triggers re-init of logging system! config["logging.channels.consoleChannel.class"] = "PythonLoggingChannel" diff --git a/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst b/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst deleted file mode 100644 index a17ff4d64994..000000000000 --- a/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst +++ /dev/null @@ -1 +0,0 @@ -- updated header and source files for ADARA packets from v1.5.1 to v1.10.3 From 380428e7a3ebed25418a76c62b2b43e952083005 Mon Sep 17 00:00:00 2001 From: Jose Borreguero Date: Mon, 29 Sep 2025 14:54:04 -0400 Subject: [PATCH 2/4] emsure we only log the test message Signed-off-by: Jose Borreguero --- Framework/PythonInterface/mantid/utils/logging.py | 3 +-- .../PythonInterface/test/python/mantid/utils/loggingTest.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Framework/PythonInterface/mantid/utils/logging.py b/Framework/PythonInterface/mantid/utils/logging.py index a987d5e6a632..be8ccfa49fa7 100644 --- a/Framework/PythonInterface/mantid/utils/logging.py +++ b/Framework/PythonInterface/mantid/utils/logging.py @@ -72,7 +72,7 @@ def log_to_python(level=None, pattern=None) -> None: to forward all potentially relevant messages to Python and let *Python's* logger filter out undesired messages. Possible values: 'trace', 'debug', 'information', 'notice', 'warning', 'error', 'critical', 'fatal'. - @param str pattern: A logging pattern to format messages before forwarding them (example: %t) + @param str pattern: A logging pattern to format messages before forwarding them (example: '[%s] %t') See https://github.com/pocoproject/poco/wiki/Poco::Util::Application-Logging-Configuration#logging-format-placeholders """ config = ConfigService.Instance() @@ -80,7 +80,6 @@ def log_to_python(level=None, pattern=None) -> None: config["logging.loggers.root.level"] = level if pattern is not None: config["logging.channels.consoleChannel.formatter"] = "f1" - # Output only the message text and let Python take care of formatting. config["logging.formatters.f1.class"] = "PatternFormatter" config["logging.formatters.f1.pattern"] = pattern # Important: Do this one last because it triggers re-init of logging system! diff --git a/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py b/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py index d757bdddf0e6..428d3bb310a9 100644 --- a/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py +++ b/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py @@ -51,7 +51,7 @@ def test_log_to_python(self): py_logger.addHandler(handler) with temporary_config(): - log_to_python() + log_to_python(level="%t") logger.information("[[info]]") logger.warning("[[warning]]") logger.error("[[error]]") From 6814aa3cb97f5a70c9cf37d2153b9a4352b1e4cd Mon Sep 17 00:00:00 2001 From: Jose Borreguero Date: Mon, 29 Sep 2025 15:13:28 -0400 Subject: [PATCH 3/4] Update loggingTest.py to use 'information' level in log_to_python Signed-off-by: Jose Borreguero --- .../PythonInterface/test/python/mantid/utils/loggingTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py b/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py index 428d3bb310a9..801d25e6ce6f 100644 --- a/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py +++ b/Framework/PythonInterface/test/python/mantid/utils/loggingTest.py @@ -51,7 +51,7 @@ def test_log_to_python(self): py_logger.addHandler(handler) with temporary_config(): - log_to_python(level="%t") + log_to_python(level="information", pattern="%t") logger.information("[[info]]") logger.warning("[[warning]]") logger.error("[[error]]") From d311da4569780965dd4ddd8bf4971c9ae134099d Mon Sep 17 00:00:00 2001 From: Jose Borreguero Date: Mon, 29 Sep 2025 15:18:15 -0400 Subject: [PATCH 4/4] restore unadvertenly removed file Signed-off-by: Jose Borreguero --- .../release/v6.14.0/Framework/LiveData/New_features/39186.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst diff --git a/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst b/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst new file mode 100644 index 000000000000..a17ff4d64994 --- /dev/null +++ b/docs/source/release/v6.14.0/Framework/LiveData/New_features/39186.rst @@ -0,0 +1 @@ +- updated header and source files for ADARA packets from v1.5.1 to v1.10.3