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)
A restraint dictionary carried in the binary, so refinement reads nothing from disk and needs no
CLIBD_MON: the 20 amino acids and MSE, the DNA/RNA nucleotides, ATP/ADP/AMP/GTP/GDP/GMP, DMSO, PEG
fragments (PEG, PGE, PG4, 1PE), GOL, EDO, SO4, PO4, ACT, MPD, water and common ions - copied verbatim
from the CCP4 Monomer Library (LGPL-3.0) - plus links_and_mods.cif cut down to the links and
modifications those compounds can take (peptide, cis-peptide, proline, N-methyl, disulfide,
nucleic-acid backbone, termini, metal-Cys/His) and ener_lib.cif cut to its atom-type table.
monomers/update_monomers.py holds the compound list and regenerates the subset; CMake embeds every
.cif of the directory as string pieces under MSVC's literal limit; EmbeddedMonomerLibrary() parses
them from memory into a gemmi::MonLib once per process. About 0.7 MB of text in the binary.
gemmi v0.7.5's monlib.cpp, topo.cpp and riding_h.cpp vendored verbatim (prepare_topology). Licence
text in licenses/, rows and a note in THIRD_PARTY_NOTICES.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
(cherry picked from commit 38034718052c4a300691393b5b817f476c83dfc2)