Merge branch 'mv-ncs' into rc175: models expanded by their strict NCS operators; the written cell follows the model's indexing
Exact: p.hkl md5 and MTZ reflection data identical on 18 sets. 4nwv R-free 0.545 -> 0.297 and cell in the depositor's frame; written cells corrected on 9rcs, 9b22, 9qw8, myob_x06da_powder_1. 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
|
||||
@@ -213,6 +214,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) {
|
||||
@@ -437,6 +447,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);
|
||||
@@ -1819,6 +1830,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