Restraints Guide
This guide covers how to define and apply distance restraints in PolyzyMD simulations.
Overview
Restraints are commonly used to:
Keep a substrate near the enzyme active site
Maintain specific protein-ligand contacts
Prevent dissociation during equilibration
PolyzyMD supports several restraint types with flexible atom selection.
Restraint Types
Flat-Bottom Restraint
The most common restraint type. No force is applied when atoms are within the threshold distance; a harmonic force kicks in beyond it.
U(r) = 0 if r < r₀
U(r) = ½k(r - r₀)² if r ≥ r₀
restraints:
- type: "flat_bottom"
name: "substrate_active_site"
atom1:
selection: "resid 77 and name OG"
atom2:
selection: "resname LIG and name C1"
distance: 3.3 # Angstroms - threshold
force_constant: 10000.0 # kJ/mol/nm²
enabled: true
Harmonic Restraint
Standard harmonic potential - always applies force to maintain target distance.
U(r) = ½k(r - r₀)²
restraints:
- type: "harmonic"
name: "distance_restraint"
atom1:
selection: "resid 50 and name CA"
atom2:
selection: "resid 100 and name CA"
distance: 10.0 # Angstroms - target distance
force_constant: 1000.0
enabled: true
Upper Wall
Prevents distance from exceeding threshold (same as flat-bottom).
- type: "upper_wall"
Lower Wall
Prevents distance from going below threshold.
U(r) = ½k(r₀ - r)² if r < r₀
U(r) = 0 if r ≥ r₀
- type: "lower_wall"
Atom Selection Syntax
PolyzyMD uses an MDAnalysis-inspired selection syntax.
Available Keywords
Keyword |
Indexing |
Description |
Example |
|---|---|---|---|
|
1-indexed |
Residue number (matches PDB/PyMOL) |
|
|
- |
Residue name |
|
|
- |
Atom name |
|
|
0-indexed |
OpenMM atom index |
|
|
1-indexed |
PDB atom serial (matches PyMOL) |
|
|
- |
Chain ID |
|
Combining Selections
Use and / or to combine:
# Both conditions must be true
selection: "resid 77 and name OG"
# Either condition
selection: "resname SER or resname THR"
# Complex combinations
selection: "(resid 77 and name OG) or (resid 110 and name NE2)"
Index Conventions
Important
Understanding indexing is critical for correct restraints!
What you see |
Keyword to use |
Value to use |
|---|---|---|
PyMOL shows residue 77 |
|
77 |
PyMOL shows atom serial 2740 |
|
2740 |
OpenMM internal index 2739 |
|
2739 |
Rule of thumb: Use resid and pdbindex - they match what you see in PyMOL.
Understanding Atom Ordering in PolyzyMD
PolyzyMD builds systems in a consistent, predictable order:
Protein - atoms numbered as in original PDB
Ligand/Substrate - atoms numbered sequentially after protein
Polymers (if enabled) - added after ligand
Solvent and ions - added last
This means if your protein PDB has atoms 1-2722, your ligand atoms will start at 2723.
Important
The solvated_system.pdb file generated by PolyzyMD is your reference for atom indices.
Always use this file (not your input structures) when determining pdbindex values.
Workflow: Finding Atom Indices with PyMOL
Step 1: Run Your Simulation Build
First, build your system to generate solvated_system.pdb:
polyzymd run -c config.yaml --replicate 1
# Or just build without running:
polyzymd build -c config.yaml
Step 2: Open the Solvated PDB in PyMOL
pymol /path/to/scratch/dir/solvated_system.pdb
Step 3: Select and Label Your Target Atom
Click on the atom you want to restrain
Right-click the atom in the viewer
Navigate to: Label → atom identifiers → ID
This displays the atom’s ID number directly on the structure - this is the pdbindex value you need.
Tip
You can also see the atom ID in the PyMOL console when you click on an atom:
You clicked /solvated_system//RBY`1/C13x pk1: … id 2739
Step 4: Write Your Selection
Use the displayed ID with pdbindex:
atom2:
selection: "resname RBY and pdbindex 2739"
description: "Substrate ester carbonyl carbon"
Real Example: Restraining a Docked Ligand
Here’s a real example from a LipA enzyme simulation with a Resorufin Butyrate substrate.
The Solvated PDB Structure
After building the system, the solvated_system.pdb shows the ligand atoms following the protein:
TER 2722 ASN A 181
HETATM 2723 C1x RBY B 1 72.639 64.759 41.006 1.00 0.00 C
HETATM 2724 C2x RBY B 1 73.757 65.093 40.238 1.00 0.00 C
HETATM 2725 C3x RBY B 1 74.974 65.339 40.886 1.00 0.00 C
HETATM 2726 C4x RBY B 1 75.074 65.248 42.284 1.00 0.00 C
HETATM 2727 C5x RBY B 1 73.950 64.894 43.027 1.00 0.00 C
HETATM 2728 C6x RBY B 1 72.739 64.634 42.394 1.00 0.00 C
HETATM 2729 N1x RBY B 1 76.267 65.488 42.979 1.00 0.00 N
HETATM 2730 C7x RBY B 1 77.297 65.796 42.258 1.00 0.00 C
HETATM 2731 C8x RBY B 1 78.582 66.067 42.936 1.00 0.00 C
HETATM 2732 C9x RBY B 1 79.679 66.376 42.240 1.00 0.00 C
HETATM 2733 C10x RBY B 1 79.654 66.462 40.768 1.00 0.00 C
HETATM 2734 O1x RBY B 1 80.663 66.736 40.132 1.00 0.00 O
HETATM 2735 C11x RBY B 1 78.374 66.201 40.088 1.00 0.00 C
HETATM 2736 C12x RBY B 1 77.264 65.893 40.770 1.00 0.00 C
HETATM 2737 O2x RBY B 1 76.065 65.659 40.104 1.00 0.00 O
HETATM 2738 O3x RBY B 1 71.447 64.422 40.347 1.00 0.00 O
HETATM 2739 C13x RBY B 1 70.808 63.259 40.777 1.00 0.00 C <- Ester carbonyl
HETATM 2740 O4x RBY B 1 69.599 63.071 40.828 1.00 0.00 O
HETATM 2741 C14x RBY B 1 71.835 62.259 41.248 1.00 0.00 C
...
TER 2757 RBY B 1
HETATM 2758 C1x SBM C 1 80.069 63.041 53.056 1.00 0.00 C <- Polymers start
The Configuration
To restrain atom C13x (the ester carbonyl carbon, pdbindex 2739) near the catalytic serine:
restraints:
- type: "flat_bottom"
name: "substrate_active_site"
atom1:
selection: "resid 77 and name OG"
description: "Catalytic serine oxygen"
atom2:
selection: "resname RBY and pdbindex 2739"
description: "Substrate ester carbonyl carbon"
distance: 10.0 # Angstroms - no force applied within this distance
force_constant: 10000.0
enabled: true
What You’ll See When Running
When the simulation runs, you’ll see confirmation that the restraint was applied:
Applying 1 restraint(s)...
- substrate_active_site: atom 1192 <-> atom 2738 (type=flat_bottom, d=10.0 Å, k=10000.0 kJ/mol/nm²)
Successfully applied 1 restraint(s)
Running energy minimization...
Note
The logged atom indices are 0-indexed (OpenMM internal). They will be one less than the pdbindex values.
Common Restraint Patterns
Substrate in Active Site
Keep substrate within bonding distance of catalytic residue:
restraints:
- type: "flat_bottom"
name: "substrate_catalytic"
atom1:
selection: "resid 77 and name OG"
description: "Catalytic serine"
atom2:
selection: "resname LIG and name C1"
description: "Substrate carbonyl carbon"
distance: 3.5
force_constant: 10000.0
enabled: true
Multiple Active Site Contacts
restraints:
- type: "flat_bottom"
name: "contact_1"
atom1:
selection: "resid 77 and name OG"
atom2:
selection: "resname LIG and name C1"
distance: 3.5
force_constant: 10000.0
enabled: true
- type: "flat_bottom"
name: "contact_2"
atom1:
selection: "resid 110 and name NE2"
atom2:
selection: "resname LIG and name O2"
distance: 3.5
force_constant: 5000.0
enabled: true
- type: "flat_bottom"
name: "contact_3"
atom1:
selection: "resid 12 and name N"
atom2:
selection: "resname LIG and name O1"
distance: 4.0
force_constant: 5000.0
enabled: false # Disabled for now
Protein-Protein Distance
Monitor or restrain distance between protein regions:
restraints:
- type: "harmonic"
name: "domain_distance"
atom1:
selection: "resid 50 and name CA"
atom2:
selection: "resid 150 and name CA"
distance: 25.0
force_constant: 100.0 # Weak restraint
enabled: true
Force Constant Guidelines
Use Case |
Force Constant (kJ/mol/nm²) |
|---|---|
Strong restraint (prevent dissociation) |
10000 - 50000 |
Moderate restraint |
1000 - 5000 |
Weak/guiding restraint |
100 - 500 |
Very weak (biasing) |
10 - 50 |
Note
Start with stronger restraints during equilibration, then reduce or disable for production if desired.
Troubleshooting
“No atoms match selection”
ValueError: No atoms match selection: 'resid 77 and name OG'
Causes:
Residue numbering doesn’t match (check PDB)
Atom name is different (check PDB atom names)
Typo in selection string
Solution: Open PDB in PyMOL and verify exact residue numbers and atom names.
“Requires exactly one atom per selection”
ValueError: Restraint 'my_restraint' requires exactly one atom per selection.
Got 5 for atom1, 1 for atom2
Cause: Selection matches multiple atoms.
Solution: Make selection more specific:
# Too broad - matches all atoms in residue
selection: "resid 77"
# Better - matches specific atom
selection: "resid 77 and name OG"
# Most specific - use atom index
selection: "resid 77 and pdbindex 1193"
Restraint Not Taking Effect
Check
enabled: trueis setVerify distance units (should be Angstroms)
Check force constant is reasonable (not too small)
Verify atom selections resolve correctly
Disabling Restraints
In Configuration
restraints:
- type: "flat_bottom"
name: "my_restraint"
# ... other settings ...
enabled: false # Disabled
No Restraints at All
restraints: []
Or simply omit the restraints section entirely.