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

resid

1-indexed

Residue number (matches PDB/PyMOL)

resid 77

resname

-

Residue name

resname SER

name

-

Atom name

name OG

index

0-indexed

OpenMM atom index

index 2739

pdbindex

1-indexed

PDB atom serial (matches PyMOL)

pdbindex 2740

chain

-

Chain ID

chain A

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

resid

77

PyMOL shows atom serial 2740

pdbindex

2740

OpenMM internal index 2739

index

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:

  1. Protein - atoms numbered as in original PDB

  2. Ligand/Substrate - atoms numbered sequentially after protein

  3. Polymers (if enabled) - added after ligand

  4. 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 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

  1. Click on the atom you want to restrain

  2. Right-click the atom in the viewer

  3. 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:

  1. Residue numbering doesn’t match (check PDB)

  2. Atom name is different (check PDB atom names)

  3. 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

  1. Check enabled: true is set

  2. Verify distance units (should be Angstroms)

  3. Check force constant is reasonable (not too small)

  4. 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.