msm
#
Functionality for applying the modified Seminario method.
Originally written by Alice E. A. Allen, TCM, University of Cambridge Modified by Joshua T. Horton and rewritten by Chris Ringrose, Newcastle University Further adapted for presto.
Reference: AEA Allen, MC Payne, DJ Cole, J. Chem. Theory Comput. (2018), doi:10.1021/acs.jctc.7b00785
Classes:
-
BondParams–Parameters for a harmonic bond potential with explicit units.
-
AngleParams–Parameters for a harmonic angle potential with explicit units.
-
AngleScalingCalculator–Calculator for Modified Seminario Method scaling factors.
-
HessianDecomposer–Decomposes a molecular Hessian matrix into atom-pair contributions.
Functions:
-
unit_vector_along_bond–Calculate unit vector along a bond from atom_a to atom_b.
-
unit_vector_normal_to_plane–Calculate unit vector normal to the plane defined by two vectors.
-
compute_perpendicular_vector_in_plane–Compute vector in angle plane and perpendicular to the first bond.
-
calculate_bond_force_constant–Calculate force constant for a bond using the Seminario method.
-
calculate_angle_force_constant–Calculate force constant and equilibrium angle using Modified Seminario Method.
-
calculate_bond_params–Calculate bond parameters using the Modified Seminario Method.
-
calculate_angle_params–Calculate angle parameters using the Modified Seminario Method.
-
apply_msm_to_molecule–Apply Modified Seminario Method to calculate bond and angle parameters.
-
apply_msm_to_molecules–Apply Modified Seminario Method to molecules and update force field.
BondParams
dataclass
#
Parameters for a harmonic bond potential with explicit units.
Force constant is in kcal/mol/nm² and length is in nm. Both are stored as OpenFF Quantity objects with explicit units.
Methods:
-
from_values–Create BondParams from raw float values (assumed kcal/mol/nm² and nm).
from_values
classmethod
#
from_values(
force_constant: float, length: float
) -> BondParams
Create BondParams from raw float values (assumed kcal/mol/nm² and nm).
Source code in presto/msm.py
AngleParams
dataclass
#
Parameters for a harmonic angle potential with explicit units.
Force constant is in kcal/mol/rad² and angle is in radians. Both are stored as OpenFF Quantity objects with explicit units.
Methods:
-
from_values–Create AngleParams from raw float values (assumed kcal/mol/rad² and radians).
from_values
classmethod
#
from_values(
force_constant: float, angle: float
) -> AngleParams
Create AngleParams from raw float values (assumed kcal/mol/rad² and radians).
Source code in presto/msm.py
AngleScalingCalculator
#
AngleScalingCalculator(
angles: list[tuple[int, int, int]],
coords: NDArray[floating],
n_atoms: int,
)
Calculator for Modified Seminario Method scaling factors.
The scaling factors account for the contribution of other angles sharing the same central atom and bond.
Args: angles: List of angle tuples (atom_a, atom_b, atom_c). coords: Atomic coordinates. n_atoms: Number of atoms in the molecule.
Methods:
-
compute_scaling_factors–Compute scaling factors for all angles.
Source code in presto/msm.py
_build_central_atom_lookup
#
Build lookup structure for angles organized by central atom.
Source code in presto/msm.py
_compute_perpendicular_vectors
#
Compute perpendicular vectors for all angle contributions.
Source code in presto/msm.py
compute_scaling_factors
#
Compute scaling factors for all angles.
Returns: List of (scale_ab, scale_cb) tuples for each angle.
Source code in presto/msm.py
HessianDecomposer
#
Decomposes a molecular Hessian matrix into atom-pair contributions.
Args: hessian: Full Hessian matrix of shape (3n_atoms, 3n_atoms). coords: Atomic coordinates of shape (n_atoms, 3).
Source code in presto/msm.py
_decompose
#
Compute eigendecomposition of partial Hessian matrices.
Source code in presto/msm.py
unit_vector_along_bond
#
Calculate unit vector along a bond from atom_a to atom_b.
Args: coords: Atomic coordinates array of shape (n_atoms, 3). atom_a: Index of first atom. atom_b: Index of second atom.
Returns: Unit vector from atom_a to atom_b.
Source code in presto/msm.py
unit_vector_normal_to_plane
#
unit_vector_normal_to_plane(
u_bc: NDArray[floating], u_ab: NDArray[floating]
) -> NDArray[floating]
Calculate unit vector normal to the plane defined by two vectors.
Args: u_bc: First unit vector. u_ab: Second unit vector.
Returns: Unit vector normal to the plane defined by u_bc and u_ab.
Source code in presto/msm.py
_get_arbitrary_perpendicular
#
Get an arbitrary unit vector perpendicular to the given vector.
Args: u: Input unit vector.
Returns: Unit vector perpendicular to u.
Source code in presto/msm.py
compute_perpendicular_vector_in_plane
#
compute_perpendicular_vector_in_plane(
coords: NDArray[floating], angle: tuple[int, int, int]
) -> NDArray[floating]
Compute vector in angle plane and perpendicular to the first bond.
For angle a-b-c, computes the vector in plane abc that is perpendicular to the bond a-b.
Args: coords: Atomic coordinates array. angle: Tuple of (atom_a, atom_b, atom_c) indices.
Returns: Unit vector in the plane perpendicular to bond a-b.
Source code in presto/msm.py
calculate_bond_force_constant
#
calculate_bond_force_constant(
bond: tuple[int, int],
eigenvals: NDArray[complexfloating],
eigenvecs: NDArray[complexfloating],
coords: NDArray[floating],
) -> float
Calculate force constant for a bond using the Seminario method.
Implements Equation 10 from the Seminario paper.
Args: bond: Tuple of (atom_a, atom_b) indices. eigenvals: Eigenvalues array of shape (n_atoms, n_atoms, 3). eigenvecs: Eigenvectors array of shape (3, 3, n_atoms, n_atoms). coords: Atomic coordinates in Angstroms.
Returns: Force constant in kcal/mol/Å^2.
Source code in presto/msm.py
calculate_angle_force_constant
#
calculate_angle_force_constant(
angle: tuple[int, int, int],
bond_lengths: NDArray[floating],
eigenvals: NDArray[complexfloating],
eigenvecs: NDArray[complexfloating],
coords: NDArray[floating],
scalings: tuple[float, float],
) -> tuple[float, float]
Calculate force constant and equilibrium angle using Modified Seminario Method.
Implements Equation 14 from the Seminario paper with modifications for additional angle contributions.
Args: angle: Tuple of (atom_a, atom_b, atom_c) indices. bond_lengths: Matrix of bond lengths. eigenvals: Eigenvalues array. eigenvecs: Eigenvectors array. coords: Atomic coordinates in Angstroms. scalings: Scaling factors (scale_ab, scale_cb) for Modified Seminario.
Returns: Tuple of (force_constant, equilibrium_angle) where force constant is in kcal/mol/rad^2 and angle is in degrees.
Source code in presto/msm.py
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | |
_calculate_linear_angle_force_constant
#
_calculate_linear_angle_force_constant(
u_ab: NDArray[floating],
u_cb: NDArray[floating],
bond_lens: tuple[float, float],
eigenvals: tuple[
NDArray[complexfloating], NDArray[complexfloating]
],
eigenvecs: tuple[
NDArray[complexfloating], NDArray[complexfloating]
],
n_samples: int = 200,
) -> tuple[float, float]
Calculate force constant for a linear or near-linear angle.
For linear angles (e.g., nitrile groups), the perpendicular vector is not uniquely defined. We sample different perpendicular directions and average.
Args: u_ab: Unit vector along bond a-b. u_cb: Unit vector along bond c-b. bond_lens: Tuple of (bond_len_ab, bond_len_bc). eigenvals: Tuple of eigenvalue arrays for (a-b, c-b). eigenvecs: Tuple of eigenvector arrays for (a-b, c-b). n_samples: Number of samples around the bond direction.
Returns: Tuple of (force_constant, equilibrium_angle).
Source code in presto/msm.py
_dot_product
#
_dot_product(
u_pa: NDArray[floating[Any]],
eig_vec: NDArray[complexfloating[Any, Any]],
) -> complex
Compute dot product handling complex eigenvectors.
Source code in presto/msm.py
calculate_bond_params
#
calculate_bond_params(
bond_indices: list[tuple[int, int]],
hessian_decomposer: HessianDecomposer,
vib_scaling: float,
) -> dict[tuple[int, int], BondParams]
Calculate bond parameters using the Modified Seminario Method.
Args: bond_indices: List of bond tuples (atom_i, atom_j). hessian_decomposer: Decomposed Hessian data (in internal units: kcal/mol/nm²). vib_scaling: Vibrational scaling factor.
Returns: Dictionary mapping bond indices to BondParams.
Source code in presto/msm.py
calculate_angle_params
#
calculate_angle_params(
angle_indices: list[tuple[int, int, int]],
hessian_decomposer: HessianDecomposer,
vib_scaling: float,
) -> dict[tuple[int, int, int], AngleParams]
Calculate angle parameters using the Modified Seminario Method.
Args: angle_indices: List of angle tuples (atom_i, atom_j, atom_k). hessian_decomposer: Decomposed Hessian data (in internal units: kcal/mol/nm²). vib_scaling: Vibrational scaling factor.
Returns: Dictionary mapping angle indices to AngleParams.
Source code in presto/msm.py
apply_msm_to_molecule
#
apply_msm_to_molecule(
mol: Molecule,
bond_indices: list[tuple[int, int]],
angle_indices: list[tuple[int, int, int]],
settings: MSMSettings,
) -> tuple[
dict[tuple[int, int], BondParams],
dict[tuple[int, int, int], AngleParams],
]
Apply Modified Seminario Method to calculate bond and angle parameters.
Sets up an ML potential simulation, minimizes the structure, computes the Hessian, and calculates force field parameters. If settings.n_conformers > 1, parameters are calculated for each conformer and averaged.
Args: mol: OpenFF Molecule to parameterize. bond_indices: List of bond indices to calculate parameters for. angle_indices: List of angle indices to calculate parameters for. settings: MSM settings including ML potential, scaling factors, and n_conformers.
Returns: Tuple of (bond_params_dict, angle_params_dict). If multiple conformers are used, the parameters are averaged over all conformers.
Source code in presto/msm.py
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 | |
_mean_bond_params
#
_mean_bond_params(
params_list: list[BondParams],
) -> BondParams
Calculate mean bond parameters from a list.
Source code in presto/msm.py
_mean_angle_params
#
_mean_angle_params(
params_list: list[AngleParams],
) -> AngleParams
Calculate mean angle parameters from a list.
Source code in presto/msm.py
apply_msm_to_molecules
#
apply_msm_to_molecules(
mols: list[Molecule],
off_ff: ForceField,
settings: MSMSettings,
) -> ForceField
Apply Modified Seminario Method to molecules and update force field.
Calculates bond and angle parameters for all molecules, averages parameters that share the same SMIRKS pattern, and updates the force field accordingly.
Args: mols: List of molecules to parameterize. off_ff: OpenFF ForceField to modify. settings: MSM settings.
Returns: Modified ForceField with MSM-derived parameters.
Reference: AEA Allen, MC Payne, DJ Cole, J. Chem. Theory Comput. (2018), doi:10.1021/acs.jctc.7b00785
Source code in presto/msm.py
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | |