From 794db0ca345f1362105c307f2d139007af853573 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Mon, 26 Oct 2026 00:40:00 +0100 Subject: [PATCH] Refinement cut by the run's cancel; the hero shows the refined R-work / R-free The refinement of a placed model gets the run's cancel flag (RefinementSettings::cancel, through CancelFlag::RunFlag), so the broker's deadline or a cancel - and Ctrl+C in rugnux - cuts a running refinement short with what its finished trials found. RefinementResult::cancelled goes to the live status as rugnux_live_refinement.cancelled (API, regenerated clients) and to the step's note. Hero: once refined, the model card's headline is "R-work / R-free, refined" (e.g. 0.32 / 0.35), its green/red still the placement verdict, the placement and fit in the context line. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 395016a30c2bc2aa26fdf2cec2ced9cebe6fad80) --- broker/OpenAPIConvert.cpp | 1 + broker/gen/model/Rugnux_live_refinement.cpp | 16 +++++++++++++++- broker/gen/model/Rugnux_live_refinement.h | 9 ++++++++- broker/jfjoch_api.yaml | 8 +++++++- broker/redoc-static.html | 4 ++-- docs/JFJOCH_BROKER.md | 4 ++-- .../docs/RugnuxLiveRefinement.md | 3 ++- frontend/src/client/types.gen.ts | 8 +++++++- frontend/src/client/zod.gen.ts | 1 + frontend/src/components/RugnuxHero.tsx | 14 ++++++++------ frontend/src/components/RugnuxParts.tsx | 3 ++- receiver/JFJochReceiverRugnux.cpp | 1 + receiver/RugnuxLiveStatus.h | 1 + rugnux/Rugnux.h | 2 ++ rugnux/RugnuxScaleMerge.cpp | 7 +++++-- tests/RugnuxLiveStatusTest.cpp | 19 +++++++++++++++++++ 16 files changed, 83 insertions(+), 18 deletions(-) diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index a49a9afb6..e708150df 100644 --- a/broker/OpenAPIConvert.cpp +++ b/broker/OpenAPIConvert.cpp @@ -1314,6 +1314,7 @@ org::openapitools::server::model::Rugnux_live_status Convert(const RugnuxLiveSna const RugnuxLiveRefinement &r = m.refinement.value(); org::openapitools::server::model::Rugnux_live_refinement refinement; refinement.setPerformed(r.performed); + refinement.setCancelled(r.cancelled); refinement.setReason(r.reason); refinement.setOnGpu(r.on_gpu); refinement.setSeconds(r.seconds); diff --git a/broker/gen/model/Rugnux_live_refinement.cpp b/broker/gen/model/Rugnux_live_refinement.cpp index 570b258a6..952cc5821 100644 --- a/broker/gen/model/Rugnux_live_refinement.cpp +++ b/broker/gen/model/Rugnux_live_refinement.cpp @@ -22,6 +22,7 @@ namespace org::openapitools::server::model Rugnux_live_refinement::Rugnux_live_refinement() { m_Performed = false; + m_Cancelled = false; m_Reason = ""; m_On_gpu = false; m_Seconds = 0.0; @@ -56,7 +57,7 @@ bool Rugnux_live_refinement::validate(std::stringstream& msg, const std::string& bool success = true; const std::string _pathPrefix = pathPrefix.empty() ? "Rugnux_live_refinement" : pathPrefix; - + /* Blobs */ { const std::vector& value = m_Blobs; @@ -89,6 +90,9 @@ bool Rugnux_live_refinement::operator==(const Rugnux_live_refinement& rhs) const (isPerformed() == rhs.isPerformed()) && + (isCancelled() == rhs.isCancelled()) + && + (getReason() == rhs.getReason()) && @@ -128,6 +132,7 @@ void to_json(nlohmann::json& j, const Rugnux_live_refinement& o) { j = nlohmann::json::object(); j["performed"] = o.m_Performed; + j["cancelled"] = o.m_Cancelled; j["reason"] = o.m_Reason; j["on_gpu"] = o.m_On_gpu; j["seconds"] = o.m_Seconds; @@ -147,6 +152,7 @@ void to_json(nlohmann::json& j, const Rugnux_live_refinement& o) void from_json(const nlohmann::json& j, Rugnux_live_refinement& o) { j.at("performed").get_to(o.m_Performed); + j.at("cancelled").get_to(o.m_Cancelled); j.at("reason").get_to(o.m_Reason); j.at("on_gpu").get_to(o.m_On_gpu); j.at("seconds").get_to(o.m_Seconds); @@ -183,6 +189,14 @@ void Rugnux_live_refinement::setPerformed(bool const value) { m_Performed = value; } +bool Rugnux_live_refinement::isCancelled() const +{ + return m_Cancelled; +} +void Rugnux_live_refinement::setCancelled(bool const value) +{ + m_Cancelled = value; +} std::string Rugnux_live_refinement::getReason() const { return m_Reason; diff --git a/broker/gen/model/Rugnux_live_refinement.h b/broker/gen/model/Rugnux_live_refinement.h index 620141804..146be0110 100644 --- a/broker/gen/model/Rugnux_live_refinement.h +++ b/broker/gen/model/Rugnux_live_refinement.h @@ -61,11 +61,16 @@ public: /// Rugnux_live_refinement members /// - /// Refinement ran to the end; false with `reason` where it failed + /// Refinement ran; false with `reason` where it failed /// bool isPerformed() const; void setPerformed(bool const value); /// + /// The deadline or a cancel cut the refinement short: the weight trials that ran were chosen among, the rest left out (cut before the first, the model is the placement's) + /// + bool isCancelled() const; + void setCancelled(bool const value); + /// /// Why refinement did not run to the end; empty otherwise /// std::string getReason() const; @@ -124,6 +129,8 @@ public: protected: bool m_Performed; + bool m_Cancelled; + std::string m_Reason; bool m_On_gpu; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index b04579a05..f67835095 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -2861,6 +2861,7 @@ components: refinement is off (it runs only with a GPU in live mode). required: - performed + - cancelled - reason - on_gpu - seconds @@ -2869,7 +2870,12 @@ components: properties: performed: type: boolean - description: Refinement ran to the end; false with `reason` where it failed + description: Refinement ran; false with `reason` where it failed + cancelled: + type: boolean + description: | + The deadline or a cancel cut the refinement short: the weight trials that ran were chosen among, the + rest left out (cut before the first, the model is the placement's) reason: type: string description: Why refinement did not run to the end; empty otherwise diff --git a/broker/redoc-static.html b/broker/redoc-static.html index 2037f0bb2..a1b6a6b5d 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -864,7 +864,7 @@ and validation of every following rugnux live collection, until it is removed wi
Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "placed_model": true,
  • "refined_model": true,
  • "anomalous_map": true,
  • "anomalous_signal": true,
  • "model": {
    },
  • "space_group": "string",
  • "d_min": 0.1,
  • "isa": 0.1,
  • "probe": "string",
  • "probe_s": 0.1,
  • "start_to_first_image_s": 0.1,
  • "message": "string",
  • "images_expected": 0,
  • "expected_collection_s": 0.1,
  • "images_received": 0,
  • "elapsed_s": 0.1,
  • "step_progress": 1,
  • "steps": [
    ],
  • "last_image_s": 0.1,
  • "cut": "string",
  • "cut_s": 0.1,
  • "last_image_to_written_s": 0.1,
  • "verdict": "string",
  • "verdict_text": "string",
  • "summary": [
    ],
  • "warnings": [
    ]
}

Get the model as placed by the last rugnux live run

The model placed against the data by molecular replacement or validation, as mmCIF - the same text as the +

http://localhost:5232/rugnux/status

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "placed_model": true,
  • "refined_model": true,
  • "anomalous_map": true,
  • "anomalous_signal": true,
  • "model": {
    },
  • "space_group": "string",
  • "d_min": 0.1,
  • "isa": 0.1,
  • "probe": "string",
  • "probe_s": 0.1,
  • "start_to_first_image_s": 0.1,
  • "message": "string",
  • "images_expected": 0,
  • "expected_collection_s": 0.1,
  • "images_received": 0,
  • "elapsed_s": 0.1,
  • "step_progress": 1,
  • "steps": [
    ],
  • "last_image_s": 0.1,
  • "cut": "string",
  • "cut_s": 0.1,
  • "last_image_to_written_s": 0.1,
  • "verdict": "string",
  • "verdict_text": "string",
  • "summary": [
    ],
  • "warnings": [
    ]
}

Get the model as placed by the last rugnux live run

The model placed against the data by molecular replacement or validation, as mmCIF - the same text as the _model.cif file written beside the data: the data's cell and space group, with the input model's own metadata (entities, sequences, references, authors, software) kept. Kept as long as /rugnux/status. Where the run refined the model, the refined model unless asked for stage=placed.

@@ -1123,7 +1123,7 @@ then image might be replaced in the buffer between calling /images and /image.cb