Merge broker-rugnux-live into rc176: rugnux in jfjoch_broker as a live thread during a DECTRIS rotation collection (off by default), the rugnux library without file I/O (results in ProcessResult::outputs, the CLI writes them through JFJochRugnuxOutput), END carrying the merged table, map coefficients and placed model

Branch reviewed at e16db07ff (review: owner's decisions accepted - _maps.mtz instead of .ccp4 in the
viewer, -o "" computes everything incl. MR/validation, Ctrl+C/error paths may leave fewer files, the
writer links gemmi/zlib) and merged at 55184eb09 with its review fixes (END size guard, frame drop as
in Lite, outputs released before re-runs, pool priority, docs, frontend gating).

Conflicts: rugnux/Rugnux.h (kept rc176's host_memory_budget_bytes, output_prefix removed as on the
branch), rugnux/RugnuxPipeline.h (MtzTable future + rc176's GPUMerge pointer), MolecularReplacement.h/.cpp
(rc176's GPU cost model, packed transform and split functions with the branch's RugnuxModel signature;
search_model with rc176's other_budgets, result.model_name). tests/RugnuxLargeTest.cpp: rc176's
host-budget test writes its files through WriteRugnuxOutputs now that the library writes none.
Generated code (broker/gen, frontend client, Python client docs, Redoc) regenerated from the merged
jfjoch_api.yaml with update_version.sh (version unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-10-17 21:01:38 +02:00
commit 78c2a69267
130 files changed
+7612 -1010

No files matched your search

+17 -15
View File
@@ -9,6 +9,7 @@
#include <cstring>
#include <fstream>
#include <random>
#include <sstream>
#include <gemmi/dencalc.hpp>
#include <gemmi/it92.hpp>
@@ -17,6 +18,7 @@
#include "../image_analysis/structure_refinement/MolecularReplacement.h"
#include "../image_analysis/structure_refinement/RigidBodyRefine.h"
#include "../common/Logger.h"
#include "../writer/RugnuxModelFile.h"
#ifdef JFJOCH_USE_CUDA
#include "../common/CUDAWrapper.h"
#include "../image_analysis/structure_refinement/MolecularReplacementGPU.h"
@@ -448,7 +450,7 @@ TEST_CASE("MolecularReplacement_ModelKind", "[MolecularReplacement]") {
const float plddt[3] = {90, 85, 95};
write("MolecularReplacement_ModelKind_af.pdb", "CRYST1 1.000 1.000 1.000 90.00 90.00 90.00 P 1 1",
plddt, false, false);
const SearchModel af = PrepareSearchModel("MolecularReplacement_ModelKind_af.pdb");
const SearchModel af = PrepareSearchModel(ReadRugnuxModelFile("MolecularReplacement_ModelKind_af.pdb"));
CHECK(af.failure_reason.empty());
CHECK(af.predicted);
CHECK(af.residues_kept == 3);
@@ -457,7 +459,7 @@ TEST_CASE("MolecularReplacement_ModelKind", "[MolecularReplacement]") {
const float refined[3] = {25, 112, 40};
write("MolecularReplacement_ModelKind_xtal.pdb", "CRYST1 50.000 60.000 70.000 90.00 90.00 90.00 P 21 21 21 4",
refined, true, true);
const SearchModel x = PrepareSearchModel("MolecularReplacement_ModelKind_xtal.pdb");
const SearchModel x = PrepareSearchModel(ReadRugnuxModelFile("MolecularReplacement_ModelKind_xtal.pdb"));
CHECK(x.failure_reason.empty());
CHECK(!x.predicted);
CHECK(x.residues_kept == 3);
@@ -501,19 +503,20 @@ TEST_CASE("MolecularReplacement_PaeDomains", "[MolecularReplacement]") {
m.st.models.push_back(model);
m.residues_read = 120;
m.residues_kept = 110;
const std::string path = "MolecularReplacement_PaeDomains.json";
{
std::ofstream out(path);
out << "[{\"predicted_aligned_error\":[";
for (int i = 0; i < 120; i++) {
out << (i ? "," : "") << "[";
for (int j = 0; j < 120; j++)
out << (j ? "," : "") << ((i < 55) == (j < 55) ? 2 : 25);
out << "]";
}
out << "],\"max_predicted_aligned_error\":31.75}]";
std::ostringstream json;
json << "[{\"predicted_aligned_error\":[";
for (int i = 0; i < 120; i++) {
json << (i ? "," : "") << "[";
for (int j = 0; j < 120; j++)
json << (j ? "," : "") << ((i < 55) == (j < 55) ? 2 : 25);
json << "]";
}
const auto domains = PaeDomains(path, m);
json << "],\"max_predicted_aligned_error\":31.75}]";
const RugnuxModel parsed = ParseRugnuxModel(
"ATOM 1 CA ALA A 1 0.000 0.000 0.000 1.00 90.00 C\nEND\n",
"AF-P12345-F1-model_v6.pdb", json.str());
REQUIRE(parsed.pae);
const auto domains = PaeDomains(*parsed.pae, m);
REQUIRE(domains.size() == 2);
CHECK(domains[0].size() == 60);
CHECK(domains[0].front() == 60);
@@ -521,7 +524,6 @@ TEST_CASE("MolecularReplacement_PaeDomains", "[MolecularReplacement]") {
const SearchModel d = DomainModel(m, domains[1]);
CHECK(d.residues_kept == 50);
CHECK(d.description == "PAE domain of 50 residues (1-50)");
std::remove(path.c_str());
}
// A placement of a group carried into a subgroup's merge: in P 21 21 21 read as P 1 21 1 on the same cell each