rugnux: the model is parsed by the caller and handed in as RugnuxModel
The analysis read the --model file itself, four to five times per run (the model kind, every validation, molecular replacement, the stills reference intensities) and located the PAE sidecar from the file name. The library is to do no file I/O, so the model now arrives in memory: - RugnuxModel (image_analysis/structure_refinement/RugnuxModel.h): the gemmi structure as read, whether it is ModelCIF, the PAE matrix where a prediction came with one, and the name the report gives it. - ParseRugnuxModel / ReadRugnuxModelFile (writer/RugnuxModelFile.h, in JFJochRugnuxFiles): bytes in, gzip by magic, PDB/mmCIF by content, _ma_qa_metric detection as before; the file reader takes the PAE JSON from the same place PaePathFor named. - ProcessConfig::model replaces model_path; PrepareSearchModel, RunMolecularReplacement, ValidateAgainstModel and ModelReferenceIntensities take the model; result fields name it by model_name. - rugnux reads the model before the run starts and stops with an error where the file holds no model (it used to run and report the model as not validated). The viewer reads it when the job is set up. - The broker parses an uploaded model at once and answers 400 where it is not one; it keeps the parsed model in memory, with no temporary directory or file. It takes no PAE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f215300a07
commit
4bf41983ed
32 files changed
+352
-242
No files matched your search
@@ -7,6 +7,7 @@
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
#include <gemmi/dencalc.hpp>
|
||||
#include <gemmi/it92.hpp>
|
||||
@@ -15,6 +16,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"
|
||||
@@ -322,7 +324,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);
|
||||
@@ -331,7 +333,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);
|
||||
@@ -375,19 +377,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);
|
||||
@@ -395,7 +398,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
|
||||
|
||||
Reference in new issue
Block a user