Refinement restraints: metal ions bound to their donors by the model's LINK records
Metal sites were held only by the 1.9 A metal contact of the repulsions; REFMAC restrains the metal LINKs of the coordinate file (its documentation), which was the one geometry term the 0-cycle comparison did not share (one 2.8 A set: bond rmsd 0.018 against REFMAC's 0.042). - monomers/metals.cif: the Monomer Library's own statistics of metal sites (metals.json, LGPL data as the rest of monomers/), cut by update_monomers.py to the metal ions of its compound list and O, N, S donors: mean distance, spread and number of sites per metal, donor element and coordination number. - AddMetalLinks (before prepare_topology): every LINK / struct_conn record between a metal ion and an O, N or S that no link of the dictionary describes (its ZN-CYS, ZN-HIS, FE-CYS, FE-HIS are taken as they are) gets a link of one bond at EmbeddedMetalDistance for the two elements and the ion's coordination - the number of its donor records, symmetry mates included - from the rows resting on at least 20 sites (the coordination's own row, else the neighbours interpolated), sigma their spread (>= 0.02 A); a His or Cys donor loses the proton the bond replaces (DEL-HD1 / DEL-HE2 / CYSmod1, as the library's links do). Records only, no distance search; records to a symmetry mate count for the coordination but are not restrained (bonds to symmetry mates are not, anywhere). - The metal bonds are a restraint set of their own (RefinementTopology::metal_bonds), evaluated with the geometry and reported apart (GeometryStatistics::rmsd_metal, REFINE_RMSD_METAL_BONDS, REFINE_SCORE_RMSD_METAL_BONDS / _BONDS_ALL): their sigma is the spread of real sites, so they sit further from ideal than covalent bonds, and the weight ladder's 0.02 A bound stays a bound on the covalent ones. refine_parity.py compares REFMAC's bond rmsd (links included) with the combined one, and takes --gpu. Score-only geometry against REFMAC 5.8 0-cycle, all bonds (count): 2.8 A Zn/Fe set 0.0402 (4934) vs 0.042 (4935), was 0.0178; a Zn-Cys set 0.0186 (7102) vs 0.019 (7102); a Ca set 0.0297 vs 0.026 (REFMAC also refines the sugars and uses one Ca-O distance); a Mg set 0.0114 vs 0.017 (REFMAC restrains 8 symmetry links and puts Mg-O at 1.99 A, the library's statistics at 2.07). R of the scored model unchanged (+0.0001 on the first from the removed His/Cys protons). Refined R-free with the links vs without: +0.0016, -0.0002, +0.0005, +0.0004. Test: RefinementRestraints_metal_links (Zn-Cys4 by the dictionary's link, Mg(H2O)6 by the new ones, both back at their distances). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 0fcffc5c71e03e184cff18f07524473462a57b68)
This commit is contained in:
1 parent
9da3851844
commit
bcb71136ab
13 files changed
+547
-29
No files matched your search
@@ -751,6 +751,7 @@ void PlaceRiders(Context &ctx, RefinementTopology &topo) {
|
||||
RestraintSet RestraintsNow(Context &ctx, const RefinementTopology &topo) {
|
||||
const RefinementStage stage("repulsions");
|
||||
RestraintSet set = topo.geometry;
|
||||
set.Append(topo.metal_bonds);
|
||||
set.Append(BuildRepulsions(topo, ctx.Model(), ctx.cell, *ctx.sg, REPULSION_MARGIN, ctx.nthreads));
|
||||
set.Finalize(ctx.atoms.size());
|
||||
return set;
|
||||
@@ -874,13 +875,16 @@ TrialOutcome RunTrial(TrialSlot slot, const std::vector<int> &refinable, const s
|
||||
{
|
||||
const RefinementStage s1("measure");
|
||||
t.geometry = MeasureGeometry(topo.geometry,
|
||||
BuildRepulsions(topo, ctx.Model(), ctx.cell, *ctx.sg, 0.0, ctx.nthreads), ctx.XyzB());
|
||||
BuildRepulsions(topo, ctx.Model(), ctx.cell, *ctx.sg, 0.0, ctx.nthreads), ctx.XyzB(),
|
||||
&topo.metal_bonds);
|
||||
}
|
||||
t.within_bounds = t.geometry.rmsd_bonds <= MAX_RMSD_BONDS && t.geometry.rmsd_angles <= MAX_RMSD_ANGLES;
|
||||
out.line = fmt::format("Refinement, X-ray weight {:.3g}, B {}: R-work {:.4f}, R-free {:.4f}, rmsd bonds {:.4f} A, "
|
||||
"angles {:.2f} deg{}",
|
||||
"angles {:.2f} deg{}{}",
|
||||
w, adp_w > 0 ? fmt::format("refined at weight {:.3g}", adp_w) : std::string("held"),
|
||||
rf.r_work, rf.r_free, t.geometry.rmsd_bonds, t.geometry.rmsd_angles,
|
||||
t.geometry.metal_bonds > 0 ? fmt::format(", metal bonds {:.3f} A", t.geometry.rmsd_metal)
|
||||
: std::string(),
|
||||
t.within_bounds ? "" : " (geometry out of bounds)");
|
||||
out.pos = ctx.Positions();
|
||||
out.b = ctx.B();
|
||||
@@ -1020,11 +1024,13 @@ RefinementResult RefineModel(const gemmi::Structure &placed, const std::vector<M
|
||||
result.fixed_residues = topo.fixed_residues;
|
||||
result.fixed_names = topo.fixed_names;
|
||||
result.geometry_start = MeasureGeometry(topo.geometry, BuildRepulsions(topo, ctx.Model(), cell, sg, 0.0),
|
||||
ctx.XyzB());
|
||||
ctx.XyzB(), &topo.metal_bonds);
|
||||
finish();
|
||||
logger.Info("Refinement: the model scored only; geometry rmsd bonds {:.4f} A (rmsZ {:.2f}), angles {:.2f} deg "
|
||||
"(rmsZ {:.2f})", result.geometry_start.rmsd_bonds, result.geometry_start.rmsz_bonds,
|
||||
result.geometry_start.rmsd_angles, result.geometry_start.rmsz_angles);
|
||||
const GeometryStatistics &g = result.geometry_start;
|
||||
logger.Info("Refinement: the model scored only; geometry rmsd bonds {:.4f} A (rmsZ {:.2f}, {} bonds), metal "
|
||||
"bonds {:.4f} A (rmsZ {:.2f}, {}; {} links made), both {:.4f} A; angles {:.2f} deg (rmsZ {:.2f})",
|
||||
g.rmsd_bonds, g.rmsz_bonds, g.bonds, g.rmsd_metal, g.rmsz_metal, g.metal_bonds, topo.metal_links,
|
||||
g.RmsdAllBonds(), g.rmsd_angles, g.rmsz_angles);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1047,18 +1053,18 @@ RefinementResult RefineModel(const gemmi::Structure &placed, const std::vector<M
|
||||
if (topo.refinable[i])
|
||||
refinable.push_back(static_cast<int>(i));
|
||||
result.refined_atoms = static_cast<int>(refinable.size());
|
||||
logger.Info("Refinement: {} residues restrained, {} held fixed{}; {} bonds, {} angles, {} torsions, {} chiral "
|
||||
"volumes, {} planes",
|
||||
logger.Info("Refinement: {} residues restrained, {} held fixed{}; {} bonds, {} metal bonds ({} links made), {} "
|
||||
"angles, {} torsions, {} chiral volumes, {} planes",
|
||||
topo.restrained_residues, topo.fixed_residues,
|
||||
topo.fixed_names.empty() ? std::string() : " (" + Joined(topo.fixed_names) + ")",
|
||||
topo.bonds, topo.angles, topo.torsions, topo.chirals, topo.planes);
|
||||
topo.bonds, topo.metal_bonds.records.size(), topo.metal_links, topo.angles, topo.torsions, topo.chirals, topo.planes);
|
||||
|
||||
ctx.engine->SetRestraints(1, topo.adp);
|
||||
{
|
||||
const RestraintSet set = RestraintsNow(ctx, topo);
|
||||
ctx.engine->SetRestraints(0, set);
|
||||
RestraintSet repulsions = BuildRepulsions(topo, ctx.Model(), cell, sg, 0.0, ctx.nthreads);
|
||||
result.geometry_start = MeasureGeometry(topo.geometry, repulsions, ctx.XyzB());
|
||||
result.geometry_start = MeasureGeometry(topo.geometry, repulsions, ctx.XyzB(), &topo.metal_bonds);
|
||||
}
|
||||
double w0 = 0;
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user