Source code for MDAnalysis.converters.OpenMMParser

# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# MDAnalysis --- https://www.mdanalysis.org
# Copyright (c) 2006-2017 The MDAnalysis Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the GNU Public Licence, v2 or any higher version
#
# Please cite your use of MDAnalysis in published work:
#
# R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N. Melo, S. L. Seyler,
# D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney, and O. Beckstein.
# MDAnalysis: A Python package for the rapid analysis of molecular dynamics
# simulations. In S. Benthall and S. Rostrup editors, Proceedings of the 15th
# Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy.
# doi: 10.25080/majora-629e541a-00e
#
# N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein.
# MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations.
# J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787
#

"""OpenMM topology parser :mod:`MDAnalysis.converters.OpenMMParser`
===================================================================

.. versionadded:: 2.0.0


Converts an
`OpenMM topology <http://docs.openmm.org/latest/api-python/generated/openmm.app.topology.Topology.html#openmm.app.topology.Topology>`_
:class:`openmm.app.topology.Topology` into a :class:`MDAnalysis.core.Topology`.

Also converts some objects within the
`OpenMM Application layer <http://docs.openmm.org/latest/api-python/app.html>`_

    - `openmm.app.pdbfile.PDBFile <http://docs.openmm.org/latest/api-python/generated/openmm.app.pdbfile.PDBFile.html#openmm.app.pdbfile.PDBFile>`_
    - `openmm.app.simulation.Simulation <http://docs.openmm.org/latest/api-python/generated/openmm.app.simulation.Simulation.html#openmm.app.simulation.Simulation>`_
    - `openmm.app.modeller.Modeller <http://docs.openmm.org/latest/api-python/generated/openmm.app.modeller.Modeller.html#openmm.app.modeller.Modeller>`_
    - `openmm.app.pdbxfile.PDBxFile <http://docs.openmm.org/latest/api-python/generated/openmm.app.pdbxfile.PDBxFile.html#openmm.app.pdbxfile.PDBxFile>`_

The :class:`OpenMMTopologyParser` generates a topology from an OpenMM Topology object.


Classes
-------

.. autoclass:: OpenMMTopologyParser
   :members:
   :inherited-members:

.. autoclass:: OpenMMAppTopologyParser
   :members:
   :inherited-members:

"""

import numpy as np

from ..topology.base import TopologyReaderBase
from ..core.topology import Topology
from ..core.topologyattrs import (
    Atomids,
    Atomnames,
    Atomtypes,
    Bonds,
    ChainIDs,
    Elements,
    Masses,
    Resids,
    Resnums,
    Resnames,
    Segids,
)


[docs]class OpenMMTopologyParser(TopologyReaderBase): format = "OPENMMTOPOLOGY" @staticmethod def _format_hint(thing): """Can this Parser read object *thing*? """ try: from openmm import app except ImportError: try: # pragma: no cover from simtk.openmm import app except ImportError: return False else: return isinstance(thing, app.Topology) def _mda_topology_from_omm_topology(self, omm_topology): """ Construct mda topology from omm topology Can be used for any openmm object that contains a topology object Parameters ---------- omm_topology: openmm.Topology Returns ------- top : MDAnalysis.core.topology.Topology """ atom_resindex = [a.residue.index for a in omm_topology.atoms()] residue_segindex = [r.chain.index for r in omm_topology.residues()] atomids = [a.id for a in omm_topology.atoms()] atomnames = [a.name for a in omm_topology.atoms()] chainids = [a.residue.chain.id for a in omm_topology.atoms()] elements = [a.element.symbol for a in omm_topology.atoms()] atomtypes = [a.element.symbol for a in omm_topology.atoms()] masses = [a.element.mass._value for a in omm_topology.atoms()] resnames = [r.name for r in omm_topology.residues()] resids = [r.index + 1 for r in omm_topology.residues()] resnums = resids.copy() segids = [str(c.index) for c in omm_topology.chains()] bonds = [(b.atom1.index, b.atom2.index) for b in omm_topology.bonds()] bond_orders = [b.order for b in omm_topology.bonds()] bond_types = [b.type for b in omm_topology.bonds()] n_atoms = len(atomids) n_residues = len(resids) n_segments = len(segids) attrs = [ Atomids(np.array(atomids, dtype=np.int32)), Atomnames(np.array(atomnames, dtype=object)), Atomtypes(np.array(atomtypes, dtype=object)), Bonds(bonds, types=bond_types, order=bond_orders, guessed=False), ChainIDs(np.array(chainids, dtype=object)), Elements(np.array(elements, dtype=object)), Masses(np.array(masses, dtype=np.float32)), Resids(resids), Resnums(resnums), Resnames(resnames), Segids(segids), ] top = Topology( n_atoms, n_residues, n_segments, attrs=attrs, atom_resindex=atom_resindex, residue_segindex=residue_segindex, ) return top def parse(self, **kwargs): omm_topology = self.filename top = self._mda_topology_from_omm_topology(omm_topology) return top
[docs]class OpenMMAppTopologyParser(OpenMMTopologyParser): format = "OPENMMAPP" @staticmethod def _format_hint(thing): """Can this Parser read object *thing*? """ try: from openmm import app except ImportError: try: # pragma: no cover from simtk.openmm import app except ImportError: return False else: return isinstance( thing, ( app.PDBFile, app.Modeller, app.Simulation, app.PDBxFile ) ) def parse(self, **kwargs): try: omm_topology = self.filename.getTopology() except AttributeError: omm_topology = self.filename.topology top = self._mda_topology_from_omm_topology(omm_topology) return top