Skill Tracer
Skills › Scientific Agent Skills › molecular-dynamics › system_preparation.md

system_preparation.md

86 lines · skills/molecular-dynamics/references/system_preparation.md at 5f2bc03

Open on GitHub
1# System preparation and force-field provenance
2
3Reviewed 2026-10-01. OpenMM 8.6.1 is the executed simulation release. PDBFixer
41.12.0 was exercised on a water/ion fixture. OpenFF Toolkit 0.18.0 APIs below
5were reviewed in official documentation; OpenFF parameterization is illustrative
6and was not executed in this audit.
7

System preparation and force-field provenance

Reviewed 2026-10-01. OpenMM 8.6.1 is the executed simulation release. PDBFixer 1.12.0 was exercised on a water/ion fixture. OpenFF Toolkit 0.18.0 APIs below were reviewed in official documentation; OpenFF parameterization is illustrative and was not executed in this audit.

Raw lines 1 to 7
8## PDBFixer: preserve scientific decisions
9
10PDBFixer can propose missing residues from SEQRES and replace modified residues,
11but neither operation establishes the correct experimental construct. Its
12`removeHeterogens(True)` keeps water and removes ligands, ions and cofactors; do
13not use it as general protein-ligand preparation. This conservative example adds
14missing atoms/hydrogens without silently rebuilding entire loops or deleting
15heterogens. Inspect retained nonstandard residues and parameterize them separately.
16Use `conda install -c conda-forge pdbfixer` in a separate environment if needed.
18```python
19from pdbfixer import PDBFixer
20from openmm.app import PDBFile
22def fix_pdb(input_pdb, output_pdb, ph=7.0):
23 fixer = PDBFixer(filename=input_pdb)
24 fixer.findMissingResidues()
25 print("Missing residue proposals:", fixer.missingResidues)
26 fixer.missingResidues = {} # Explicit policy: do not invent absent loops/termini.
27 fixer.findNonstandardResidues()
28 print("Nonstandard residues retained:", fixer.nonstandardResidues)
29 # Review before opting into replaceNonstandardResidues or heterogen deletion.
30 fixer.findMissingAtoms()
31 fixer.addMissingAtoms()
32 fixer.addMissingHydrogens(ph)
33 with open(output_pdb, "w") as handle:
34 PDBFile.writeFile(fixer.topology, fixer.positions, handle, keepIds=True)
35 return output_pdb
36```
38Hydrogens assigned at a pH are a model choice, not a pKa calculation. Inspect
39histidines, catalytic groups, metal binding, disulfides and termini manually.
40Run `Modeller.addHydrogens(..., pH=...)` using the intended force field and consistent
41pH afterward; retained unknown ligands still need explicit chemical preparation.

PDBFixer: preserve scientific decisions

PDBFixer can propose missing residues from SEQRES and replace modified residues, but neither operation establishes the correct experimental construct. Its removeHeterogens(True) keeps water and removes ligands, ions and cofactors; do not use it as general protein-ligand preparation. This conservative example adds missing atoms/hydrogens without silently rebuilding entire loops or deleting heterogens. Inspect retained nonstandard residues and parameterize them separately. Use conda install -c conda-forge pdbfixer in a separate environment if needed.

from pdbfixer import PDBFixer
from openmm.app import PDBFile

def fix_pdb(input_pdb, output_pdb, ph=7.0):
    fixer = PDBFixer(filename=input_pdb)
    fixer.findMissingResidues()
    print("Missing residue proposals:", fixer.missingResidues)
    fixer.missingResidues = {}  # Explicit policy: do not invent absent loops/termini.
    fixer.findNonstandardResidues()
    print("Nonstandard residues retained:", fixer.nonstandardResidues)
    # Review before opting into replaceNonstandardResidues or heterogen deletion.
    fixer.findMissingAtoms()
    fixer.addMissingAtoms()
    fixer.addMissingHydrogens(ph)
    with open(output_pdb, "w") as handle:
        PDBFile.writeFile(fixer.topology, fixer.positions, handle, keepIds=True)
    return output_pdb

Hydrogens assigned at a pH are a model choice, not a pKa calculation. Inspect histidines, catalytic groups, metal binding, disulfides and termini manually. Run Modeller.addHydrogens(..., pH=...) using the intended force field and consistent pH afterward; retained unknown ligands still need explicit chemical preparation.

Raw lines 8 to 42
43## OpenFF ligand parameters
45The official Toolkit installation route uses conda-forge/Mamba and chemistry
46backends. Although Toolkit 0.18.0 and Interchange 0.5.1 are on PyPI, their metadata does
47not declare the complete dependency stack; a bare pip install is insufficient.
48For example, `mamba create -n md-openff -c conda-forge openff-toolkit openff-interchange`
49is an illustrative environment command; check the solved force-field/charge
50backend dependencies before running it.
52Sage 2.3.0 (`openff-2.3.0.offxml`) is the stable small-molecule release reviewed
53here; OpenFF 3.0 alpha force fields are research prereleases. Sage 2.3 uses AshGC
54charges and needs the corresponding OpenFF NAGL implementation and model. Record
55and validate those versions; do not silently substitute older AM1-BCC charges.
56Installing/resolving these optional models was outside this small smoke audit.
58```python
59from openff.toolkit import Molecule, ForceField as OFFForceField
61def parameterize_ligand(smiles, ff_name="openff-2.3.0.offxml"):
62 """Illustrative ligand-only parameterization; requires the charge backend/model."""
63 mol = Molecule.from_smiles(smiles) # Undefined stereochemistry raises by default.
64 mol.generate_conformers(n_conformers=1)
65 off_ff = OFFForceField(ff_name)
66 return off_ff.create_interchange(mol.to_topology())
67```
69The SMILES must encode the intended stereoisomer, tautomer and formal charge.
70A generated conformer is not the bound pose. Map every ligand atom back to the
71complex before merging through a supported template/system construction route.
72Preserve nonbonded conventions, water/ion parameters, exceptions and charge totals;
73do not concatenate independent OpenMM Systems or confuse OpenFF with GAFF2.

OpenFF ligand parameters

The official Toolkit installation route uses conda-forge/Mamba and chemistry backends. Although Toolkit 0.18.0 and Interchange 0.5.1 are on PyPI, their metadata does not declare the complete dependency stack; a bare pip install is insufficient. For example, mamba create -n md-openff -c conda-forge openff-toolkit openff-interchange is an illustrative environment command; check the solved force-field/charge backend dependencies before running it.

Sage 2.3.0 (openff-2.3.0.offxml) is the stable small-molecule release reviewed here; OpenFF 3.0 alpha force fields are research prereleases. Sage 2.3 uses AshGC charges and needs the corresponding OpenFF NAGL implementation and model. Record and validate those versions; do not silently substitute older AM1-BCC charges. Installing/resolving these optional models was outside this small smoke audit.

from openff.toolkit import Molecule, ForceField as OFFForceField

def parameterize_ligand(smiles, ff_name="openff-2.3.0.offxml"):
    """Illustrative ligand-only parameterization; requires the charge backend/model."""
    mol = Molecule.from_smiles(smiles)  # Undefined stereochemistry raises by default.
    mol.generate_conformers(n_conformers=1)
    off_ff = OFFForceField(ff_name)
    return off_ff.create_interchange(mol.to_topology())

The SMILES must encode the intended stereoisomer, tautomer and formal charge. A generated conformer is not the bound pose. Map every ligand atom back to the complex before merging through a supported template/system construction route. Preserve nonbonded conventions, water/ion parameters, exceptions and charge totals; do not concatenate independent OpenMM Systems or confuse OpenFF with GAFF2.

Raw lines 43 to 74
75## Official sources
77- [OpenMM running simulations and force-field inventory](https://docs.openmm.org/latest/userguide/application/02_running_sims.html)
78- [Modeller and solvent semantics](https://docs.openmm.org/latest/api-python/generated/openmm.app.modeller.Modeller.html)
79- [Simulation and restart APIs](https://docs.openmm.org/latest/api-python/generated/openmm.app.simulation.Simulation.html)
80- [Barostat Context parameters](https://docs.openmm.org/latest/api-python/generated/openmm.openmm.MonteCarloBarostat.html)
81- [PDBFixer 1.12 release](https://github.com/openmm/pdbfixer/releases/tag/v1.12)
82- [PDBFixer manual](https://github.com/openmm/pdbfixer/blob/v1.12/Manual.html)
83- [OpenFF installation](https://docs.openforcefield.org/projects/toolkit/en/stable/installation.html)
84- [OpenFF ForceField API](https://docs.openforcefield.org/projects/toolkit/en/stable/api/generated/openff.toolkit.typing.engines.smirnoff.ForceField.html)
85- [OpenFF force-field releases](https://github.com/openforcefield/openff-forcefields/releases)
86- [NAGL installation](https://docs.openforcefield.org/projects/nagl/en/stable/installation.html)