Skip to content

amber #

Utilities for working with Amber files and objects.

Functions:

convert_parm_to_xml #

convert_parm_to_xml(path: Path) -> str

Convert an Amber parameter file to OpenMM XML format.

Notes
  • This function requires that ParmEd is installed.
  • Doing any kind of interconversion of force fields is inherently dangerous. This should only be used as a last resort when you have no other option.

Parameters:

  • path (Path) –

    The path to the Amber parameter file (.parm7, .prmtop, .parm).

Returns:

  • str

    The OpenMM XML representation of the Amber parameter file.

Source code in femto/md/utils/amber.py
def convert_parm_to_xml(path: pathlib.Path) -> str:
    """Convert an Amber parameter file to OpenMM XML format.

    Notes:
        * This function requires that ParmEd is installed.
        * Doing any kind of interconversion of force fields is inherently dangerous.
          This should only be used as a last resort when you have no other option.

    Args:
        path: The path to the Amber parameter file (.parm7, .prmtop, .parm).

    Returns:
        The OpenMM XML representation of the Amber parameter file.
    """
    import parmed

    if path.suffix.lower() not in {".prmtop", ".parm7", ".parm"}:
        raise ValueError(f"Unsupported Amber file format: {path}")

    warnings.warn(
        f"Converting {path.name} from {path.suffix} to OpenMM FFXML. It is assumed "
        f"that the parameter was generated by an Amber based FF, e.g. GAFF, and treats "
        f"any improper torsions as such. Such conversion is inherently dangerous, and "
        f"support to do so will be removed in the future.",
        DeprecationWarning,
        stacklevel=2,
    )

    structure = parmed.amber.AmberParm(str(path))

    mock_atoms = [
        _MockAtom(
            index=atom.idx,
            name=atom.name,
            symbol=openmm.app.Element.getByAtomicNumber(atom.element).symbol,
            typename=atom.type,
            mass=atom.mass,
            neighbours=[neigh.idx for neigh in atom.bond_partners],
        )
        for atom in structure.atoms
    ]
    mock_bonds = [
        _MockBond(
            atom1=mock_atoms[bond.atom1.idx],
            atom2=mock_atoms[bond.atom2.idx],
        )
        for bond in structure.bonds
    ]
    mock_mol = _MockMolecule(atoms=mock_atoms, bonds=mock_bonds)

    system = structure.createSystem(removeCMMotion=False)
    _reorder_torsions(system, mock_mol)

    mixin = openmmforcefields.generators.template_generators.OpenMMSystemMixin()

    ffxml = mixin.convert_system_to_ffxml(mock_mol, system, "amber")
    ffxml = ffxml.replace('ordering="smirnoff"', 'ordering="amber"')

    return ffxml