Model validation expands strict NCS; the written cell follows the model's indexing
- ModelValidation reads the model and, where it carries non-given NCS operators (_struct_ncs_oper 'generate' / MTRIX without the given flag), expands them (gemmi expand_ncs, vendored assembly.cpp from GEMMI 0.7.5, MPL-2.0 as the rest of gemmi_gph). Same in the battery's model_check.py and depdata_check.py. An icosahedral-virus entry deposited as 3 of the 45 chains of its ASU was scored against a fifteenth of its atoms: R-free 0.545 -> 0.297. - The indexing the model chooses (AdoptModelFrame) now moves the cell with the indices (reseat_integrated in the main path; CellInBasis in the forecast, twin-file and stills/scale paths). A near-symmetry law (b within 2% of c, beta a degree off 90, a~b in P1) relabelled the reflections only, so the files were written with two axes swapped or beta flipped relative to the indices. Where the law moved the cell, the validation is remade on the moved cell. Measured on 18 open/in-house sets with models: p.hkl and MTZ reflection data bit-identical on all; cell and model R unchanged where the law is exact; the cell now matches the deposited one on the 6 pseudo-merohedral cases (orthorhombic a/c swap, three monoclinic beta flips, a P1 alpha/beta swap), R-free within +-0.001 there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EizBKhTqrAYago9KJG3dA3
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <gemmi/mmread_gz.hpp> // read_structure_gz
|
||||
#include <gemmi/assembly.hpp> // expand_ncs
|
||||
#include <gemmi/gz.hpp> // MaybeGzipped
|
||||
#include <gemmi/it92.hpp> // IT92 x-ray form factors
|
||||
#include <gemmi/dencalc.hpp> // DensityCalculator
|
||||
@@ -212,6 +213,15 @@ void reorient_about_centroid(gemmi::Model &model, const gemmi::Mat33 &rot) {
|
||||
SetModelPositions(model, pos);
|
||||
}
|
||||
|
||||
// A deposition can hold only part of the asymmetric unit, with the strict-NCS operators that generate
|
||||
// the rest (mmCIF _struct_ncs_oper code 'generate', PDB MTRIX without the given flag): an icosahedral
|
||||
// virus deposits a few chains of the dozens in the crystal's ASU. Read as it is, the model is that
|
||||
// fraction of the crystal, and every R and map made from it describes the fraction.
|
||||
void expand_strict_ncs(gemmi::Structure &st) {
|
||||
if (std::any_of(st.ncs.begin(), st.ncs.end(), [](const gemmi::NcsOp &op) { return !op.given; }))
|
||||
gemmi::expand_ncs(st, gemmi::HowToNameCopiedChain::Short);
|
||||
}
|
||||
|
||||
// Move a model into another cell by keeping its fractional coordinates. Correct only when the two
|
||||
// cells describe the same axes in the same order, which is what the probe below is there to arrange.
|
||||
void refractionalize_into(gemmi::Structure &st, const gemmi::UnitCell &target) {
|
||||
@@ -436,6 +446,7 @@ ModelValidationResult Validate(const std::vector<MergedReflection> &merged,
|
||||
// falls back to the content when it does not recognise one. A model arrives named however
|
||||
// whoever produced it named it, so the file itself is the better authority.
|
||||
st = gemmi::read_structure_gz(model_path, gemmi::CoorFormat::Detect);
|
||||
expand_strict_ncs(st);
|
||||
} catch (const std::exception &e) {
|
||||
result.failure_reason = fmt::format("cannot read model {}: {}", model_path, e.what());
|
||||
logger.Error("Model validation: {}", result.failure_reason);
|
||||
@@ -1817,6 +1828,7 @@ std::vector<MergedReflection> ModelReferenceIntensities(const std::string &model
|
||||
// falls back to the content when it does not recognise one. A model arrives named however
|
||||
// whoever produced it named it, so the file itself is the better authority.
|
||||
st = gemmi::read_structure_gz(model_path, gemmi::CoorFormat::Detect);
|
||||
expand_strict_ncs(st);
|
||||
} catch (const std::exception &e) {
|
||||
logger.Error("Model reference: cannot read model {}: {}", model_path, e.what());
|
||||
return out;
|
||||
|
||||
Reference in New Issue
Block a user