Skip to content

rest #

Prepare a system for REST sampling.

Functions:

  • apply_rest

    Modifies an OpenMM system in-place such that the valence, vdW and electrostatic

Attributes:

  • REST_CTX_PARAM

    The global parameter used to scale interactions by beta_m / beta_0 according to

  • REST_CTX_PARAM_SQRT

    The global parameter used to scale interactions by sqrt(beta_m / beta_0) according

REST_CTX_PARAM module-attribute #

REST_CTX_PARAM = 'bm_b0'

The global parameter used to scale interactions by beta_m / beta_0 according to REST2.

REST_CTX_PARAM_SQRT module-attribute #

REST_CTX_PARAM_SQRT = 'sqrt<bm_b0>'

The global parameter used to scale interactions by sqrt(beta_m / beta_0) according to REST2.

apply_rest #

apply_rest(
    system: System, solute_idxs: set[int], config: REST
)

Modifies an OpenMM system in-place such that the valence, vdW and electrostatic interactions are scaled according to the REST2 scheme.

Namely, torsion barrier heights are scaled by beta_m / beta_0, electrostatic charges are scaled by sqrt(beta_m / beta_0), and LJ epsilons are scaled by beta_m / beta_0.

Notes
  • REST should be applied after any alchemical modifications.

Parameters:

  • system (System) –

    The system to modify in-place.

  • solute_idxs (set[int]) –

    The indices of the 'solute'. Usually this will be the indices of the ligand atoms, but may also include protein atoms or only a subet of ligand atoms.

  • config (REST) –

    Configuration for REST2.

Source code in femto/md/rest.py
def apply_rest(
    system: openmm.System, solute_idxs: set[int], config: femto.md.config.REST
):
    """Modifies an OpenMM system *in-place* such that the valence, vdW and electrostatic
    interactions are scaled according to the REST2 scheme.

    Namely, torsion barrier heights are scaled by ``beta_m / beta_0``, electrostatic
    charges are scaled by ``sqrt(beta_m / beta_0)``, and LJ epsilons are scaled by
    ``beta_m / beta_0``.

    Notes:
        * REST should be applied after any alchemical modifications.

    Args:
        system: The system to modify in-place.
        solute_idxs: The indices of the 'solute'. Usually this will be the indices of
            the ligand atoms, but may also include protein atoms or only a subet of
            ligand atoms.
        config: Configuration for REST2.
    """

    forces_by_type = collections.defaultdict(dict)

    for i, force in enumerate(system.getForces()):
        if type(force) not in _SUPPORTED_FORCES:
            raise ValueError(f"Force type {type(force)} is not supported for REST.")

        forces_by_type[type(force)][i] = force

    rest_forces = {}

    for force_type, forces in forces_by_type.items():
        for i, force in forces.items():
            if force_type == openmm.HarmonicBondForce and config.scale_bonds:
                raise NotImplementedError("Scaling of bonds is not yet supported.")
            elif force_type == openmm.HarmonicAngleForce and config.scale_angles:
                raise NotImplementedError("Scaling of angles is not yet supported.")
            elif force_type == openmm.PeriodicTorsionForce and config.scale_torsions:
                force = _create_torsion_force(force, solute_idxs)
            elif (
                force_type in (openmm.NonbondedForce, openmm.CustomNonbondedForce)
                and config.scale_nonbonded
            ):
                force = _create_nonbonded_force(force, solute_idxs)
            else:
                force = copy.deepcopy(force)

            rest_forces[i] = force

    for i in reversed(range(system.getNumForces())):
        system.removeForce(i)
    for i in range(len(rest_forces)):
        system.addForce(rest_forces[i])