Skip to main content
Mutation protocols control how sequences are perturbed at each step. This guide shows you how to create your own.

The MutationProtocol base class

All mutation protocols inherit from MutationProtocol, a dataclass with an abstract one_step() method. The base class provides:
  • mutation_bias — a dictionary mapping amino acid one-letter codes to sampling probabilities (default excludes cysteine to avoid disulfide complications)
  • n_mutations — number of mutations to attempt per step (default 1)
  • exclude_self — if True, the current amino acid is excluded from the sampling distribution (default True)

Implementing one_step()

The one_step() method receives a System and must return a tuple of (mutated_system, mutation_record):
Key rules:
  • Always copy the system with system.__copy__() before modifying it — the minimizer needs the original for energy comparison
  • Return a MutationRecord with all Mutation objects — this enables replay and logging
  • Mutations to a chain are automatically reflected in all states sharing that chain

Mutation and MutationRecord

Each Mutation is a frozen dataclass recording a single mutation operation:
A MutationRecord is simply a list of Mutation objects from a single one_step() call.

Using built-in utilities

The base class provides helper methods you can use in your protocol:
  • choose_chain(system) — selects a chain with probability proportional to its number of mutable residues. This ensures chains with more mutable positions are mutated more frequently.
  • mutate_random_residue(chain) — picks a random mutable residue on the chain and resamples its amino acid from mutation_bias (excluding the current AA if exclude_self=True). Returns a Mutation object.
  • replay(system, mutation_record) — replays a recorded mutation on a fresh system copy. Useful for deterministic reproduction of trajectories.

Example: a custom mutation protocol

Here is a mutation protocol that biases toward specific amino acids based on their position in the chain. Residues near the N-terminus are biased toward charged amino acids (for solubility), while residues near the C-terminus are biased toward hydrophobic amino acids (for core packing):
Usage: