Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converter for OpenMM #2917

Merged
merged 70 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
b3a43c6
Topology from omm topology and simulation objects. Coordinates from o…
ahy3nz Aug 22, 2020
f103d91
Remove debug lines
ahy3nz Aug 22, 2020
caadfab
Move omm topology parsing code outside class for re-use in multiple o…
ahy3nz Aug 22, 2020
b109715
Change openmm trajectory reader into single frame reader
ahy3nz Aug 22, 2020
4665de1
Add coordinates conversions for openmm modeller and pdbfile classes
ahy3nz Aug 23, 2020
b5f4aab
Add topology parsing for openmm pdbfile and modeller objects
ahy3nz Aug 23, 2020
91829be
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Aug 23, 2020
ba759c1
Tests for openmmtopology parser
ahy3nz Aug 23, 2020
9f1723e
Revert init
ahy3nz Aug 23, 2020
9de805c
Test openmm topology parsing on pdb file with connections, add atomtypes
ahy3nz Aug 23, 2020
2c25a3d
Use guesser for guessing atomtypes from atomnames
ahy3nz Aug 23, 2020
4bab35c
Off by one errors for 1-indexed resids
ahy3nz Aug 24, 2020
7b7c931
Set frame to 0 for first timestep
ahy3nz Aug 24, 2020
660e88c
Unwrap simtk quantity for time
ahy3nz Aug 25, 2020
6feb097
Coordinates tests for openmm pdbfile, modeller, simulation objects
ahy3nz Aug 25, 2020
1725d18
update error messsage
ahy3nz Aug 25, 2020
d1e7cea
Update documentation
ahy3nz Aug 25, 2020
1bb0fd0
Try updating some yaml files
ahy3nz Aug 25, 2020
1f138bd
Include datafiles and tests for pdbx files
ahy3nz Aug 25, 2020
138ad65
More documentation for pdbx
ahy3nz Aug 25, 2020
4c11d06
Typo in format
ahy3nz Aug 25, 2020
15807fc
Blacken code
ahy3nz Aug 25, 2020
e26d170
Refactor so generic application objects share the same readers and fu…
ahy3nz Aug 25, 2020
24994c6
Adjust line length
ahy3nz Aug 26, 2020
4fb4aa5
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Aug 27, 2020
64e7f58
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Aug 31, 2020
23a8c84
Revert datafiles without black formatting
ahy3nz Sep 2, 2020
906da5e
Add pdbx file to datafiles, update changelog
ahy3nz Sep 2, 2020
1bbf543
Update docstring with proper versionadded tag
ahy3nz Sep 2, 2020
6c7756f
Missing comma in list
ahy3nz Sep 2, 2020
170304d
Add pytest importorskip for testing openmm topology c onversion
ahy3nz Sep 2, 2020
36e652e
Update changelog
ahy3nz Sep 19, 2020
7d117d0
Merge conflict
ahy3nz Sep 19, 2020
a7fe421
Merge branch 'develop' into issue-2863-openmmtop
orbeckst Sep 30, 2020
d65a641
Merge conflicts
ahy3nz Oct 7, 2020
6a4229c
Remove unnecessary imports, more documentation for openmm application…
ahy3nz Oct 7, 2020
b7347d9
Update changelog
ahy3nz Oct 7, 2020
1b4d0c2
Example usage in documentation
ahy3nz Oct 7, 2020
1d085a8
Convert simtk quanitties into default internal units
ahy3nz Oct 7, 2020
5e79e1f
Merge conflict with develop
ahy3nz Oct 29, 2020
3349ab5
Update travis with extra variables for openmm, installing only on py3…
ahy3nz Nov 4, 2020
b189f2f
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Nov 4, 2020
eec5d9d
Revert back to atomtype guessing
ahy3nz Nov 4, 2020
76c9053
Use proper openmm atom naming conventions for unit test
ahy3nz Nov 4, 2020
a255dc0
Modify appveyor config to specify openmm on py36 vs py38
ahy3nz Nov 5, 2020
cd637db
Correct syntax for appveyor env vars
ahy3nz Nov 5, 2020
292a52e
Change appveyor var syntax
ahy3nz Nov 5, 2020
3c2322d
Empty string for conda openmm var
ahy3nz Nov 5, 2020
d3b708f
Fix merge conflicts
ahy3nz Nov 9, 2020
6ab342e
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Nov 16, 2020
1dde5d4
Merge conflict
ahy3nz Dec 11, 2020
a48b7ba
Merge conflict
ahy3nz Dec 11, 2020
85d1352
Update GHA conda min dependencies for openmm on conda-forge
ahy3nz Dec 11, 2020
c682a07
Remove inplace flag for converting energies, not used anywhere in ope…
ahy3nz Dec 12, 2020
e1bc710
Update appveyor to pull openmm from conda-forge
ahy3nz Dec 12, 2020
e14b4a4
Merge conflict
ahy3nz Dec 26, 2020
f80652a
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Dec 31, 2020
93ffc7e
Merge conflict
ahy3nz Jan 7, 2021
b7c40fd
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Feb 2, 2021
d0cf629
Merge conflict
ahy3nz Feb 20, 2021
74f7197
Update gh ci from merge conflict
ahy3nz Mar 11, 2021
2b4e1d0
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz Mar 14, 2021
f64e18d
Merge conflict with develop
ahy3nz Apr 24, 2021
37f1a56
Use simtk syntax for unit conversions
ahy3nz Apr 24, 2021
a8c40af
- Sanitize box angles when converting from OpenMM unitcell to MDA uni…
ahy3nz Apr 27, 2021
50ad7d0
Merge with upstream
ahy3nz Apr 29, 2021
9919631
Merge remote-tracking branch 'upstream/develop' into issue-2863-openm…
ahy3nz May 5, 2021
28ab392
Make sure OpenMM appears in the documentation
jbarnoud May 5, 2021
a86a528
PEP8 fixes for OpenMM reader and parser
jbarnoud May 5, 2021
bede198
Merge pull request #1 from jbarnoud/openmm
ahy3nz May 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .disabled-travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ env:
- SETUP_CMD="${PYTEST_FLAGS}"
- BUILD_CMD="pip install -e package/ && (cd testsuite/ && python setup.py build)"
- CONDA_MIN_DEPENDENCIES="mmtf-python biopython networkx cython matplotlib scipy griddataformats hypothesis gsd codecov"
- CONDA_DEPENDENCIES="${CONDA_MIN_DEPENDENCIES} seaborn>=0.7.0 clustalw=2.1 netcdf4 scikit-learn joblib>=0.12 chemfiles tqdm>=4.43.0 tidynamics>=1.0.0 rdkit>=2020.03.1 h5py"
- CONDA_DEPENDENCIES="${CONDA_MIN_DEPENDENCIES} seaborn>=0.7.0 clustalw=2.1 netcdf4 scikit-learn joblib>=0.12 chemfiles tqdm>=4.43.0 tidynamics>=1.0.0 rdkit>=2020.03.1 h5py openmm"
- CONDA_CHANNELS='biobuilds conda-forge'
- CONDA_CHANNEL_PRIORITY=True
- PIP_DEPENDENCIES="duecredit parmed"
Expand All @@ -43,7 +43,7 @@ env:
matrix:
# Run a coverage test for most versions
- CODECOV="true" SETUP_CMD="${PYTEST_FLAGS} --cov=MDAnalysis"
- PYTHON_VERSION=3.8 CODECOV="true" SETUP_CMD="${PYTEST_FLAGS} --cov=MDAnalysis"
- PYTHON_VERSION=3.8 CODECOV="true" SETUP_CMD="${PYTEST_FLAGS} --cov=MDAnalysis"
- PYTHON_VERSION=3.7 CODECOV="true" SETUP_CMD="${PYTEST_FLAGS} --cov=MDAnalysis"
- NUMPY_VERSION=1.16.0
- NUMPY_VERSION=dev EVENT_TYPE="cron"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gh-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defaults:
shell: bash -l {0}

env:
MDA_CONDA_MIN_DEPS: "pip pytest==6.1.2 mmtf-python biopython networkx cython matplotlib-base scipy griddataformats hypothesis gsd codecov threadpoolctl"
MDA_CONDA_MIN_DEPS: "pip pytest==6.1.2 mmtf-python biopython networkx cython matplotlib-base scipy griddataformats hypothesis gsd codecov threadpoolctl openmm"
MDA_CONDA_EXTRA_DEPS: "seaborn>=0.7.0 clustalw=2.1 netcdf4 scikit-learn joblib>=0.12 chemfiles tqdm>=4.43.0 tidynamics>=1.0.0 rdkit>=2020.03.1 h5py"
MDA_PIP_MIN_DEPS: 'coveralls coverage<5 pytest-cov pytest-xdist'
MDA_PIP_EXTRA_DEPS: 'duecredit parmed'
Expand Down
1 change: 1 addition & 0 deletions package/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ Chronological list of authors
- Henry Kobin
- Kosuke Kudo
- Sulay Shah
- Alexander Yang

External code
-------------
Expand Down
3 changes: 2 additions & 1 deletion package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The rules for this file:
calcraven,xiki-tempula, mieczyslaw, manuel.nuno.melo, PicoCentauri,
hanatok, rmeli, aditya-kamath, tirkarthi, LeonardoBarneschi, hejamu,
biogen98, orioncohen, z3y50n, hp115, ojeda-e, thadanipaarth, HenryKobin,
1ut, sulays
1ut, sulays, ahy3nz

* 2.0.0

Expand Down Expand Up @@ -205,6 +205,7 @@ Changes
``analysis.helix_analysis`` (PR #2929)
* Move water bridge analysis from hbonds to hydrogenbonds (Issue #2739 PR #2913)
* `threadpoolctl` is required for installation (Issue #2860)
* Added OpenMM coordinate and topology converters (Issue #2863, PR #2917)

Deprecations

Expand Down
186 changes: 186 additions & 0 deletions package/MDAnalysis/coordinates/OpenMM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# -*- 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 structure I/O --- :mod:`MDAnalysis.coordinates.OpenMM`
================================================================


Read coordinates data from a
`OpenMM <http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.simulation.Simulation.html#simtk.openmm.app.simulation.Simulation>`_
:class:`simtk.openmm.app.simulation.Simulation` with :class:`OpenMMReader`
into a MDAnalysis Universe.

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

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

Example
-------
OpenMM can read various file formats into OpenMM objects.
MDAnalysis can then convert some of these OpenMM objects into MDAnalysis Universe objects.

>>> import simtk.openmm.app as app
>>> import MDAnalysis as mda
>>> from MDAnalysis.tests.datafiles import PDBX
>>> pdbxfile = app.PDBxFile(PDBX)
>>> mda.Universe(pdbxfile)
<Universe with 60 atoms>



Classes
-------

.. autoclass:: OpenMMSimulationReader
:members:

.. autoclass:: OpenMMAppReader
:members:


"""


import numpy as np

from . import base
from .. import units


class OpenMMSimulationReader(base.SingleFrameReaderBase):
"""Reader for OpenMM Simulation objects


.. versionadded:: 2.0.0
"""

format = "OPENMMSIMULATION"
units = {"time": "ps", "length": "nm", "velocity": "nm/ps",
"force": "kJ/(mol*nm)", "energy": "kJ/mol"}

@staticmethod
def _format_hint(thing):
"""Can this reader read *thing*?
"""
try:
from simtk.openmm.app import Simulation
except ImportError:
return False
else:
return isinstance(thing, Simulation)

def _read_first_frame(self):
self.n_atoms = self.filename.topology.getNumAtoms()

self.ts = self._mda_timestep_from_omm_context()

if self.convert_units:
self.convert_pos_from_native(self.ts._pos)
self.ts.triclinic_dimensions = self.convert_pos_from_native(
self.ts.triclinic_dimensions, inplace=False
)
self.convert_velocities_from_native(self.ts._velocities)
self.convert_forces_from_native(self.ts._forces)
self.convert_time_from_native(self.ts.dt)

def _mda_timestep_from_omm_context(self):
""" Construct Timestep object from OpenMM context """
import simtk.unit as u

state = self.filename.context.getState(-1, getVelocities=True,
getForces=True, getEnergy=True)

n_atoms = self.filename.context.getSystem().getNumParticles()

ts = self._Timestep(n_atoms, **self._ts_kwargs)
ts.frame = 0
ts.data["time"] = state.getTime()._value
ts.data["potential_energy"] = (
state.getPotentialEnergy().in_units_of(u.kilojoule/u.mole)
)
ts.data["kinetic_energy"] = (
state.getKineticEnergy().in_units_of(u.kilojoule/u.mole)
)
ts.triclinic_dimensions = state.getPeriodicBoxVectors(
asNumpy=True)._value
ts.positions = state.getPositions(asNumpy=True)._value
ts.velocities = state.getVelocities(asNumpy=True)._value
ts.forces = state.getForces(asNumpy=True)._value

return ts


class OpenMMAppReader(base.SingleFrameReaderBase):
"""Reader for OpenMM Application layer objects

See also `OpenMM Application layer <http://docs.openmm.org/latest/api-python/generated/simtk.openmm.app.simulation.Simulation.html#simtk.openmm.app.simulation.Simulation>`_

.. versionadded:: 2.0.0
"""

format = "OPENMMAPP"
units = {"time": "ps", "length": "nm"}

@staticmethod
def _format_hint(thing):
"""Can this reader read *thing*?
"""
try:
from simtk.openmm import app
except ImportError:
return False
else:
return isinstance(thing, (app.PDBFile, app.Modeller,
app.PDBxFile))

def _read_first_frame(self):
self.n_atoms = self.filename.topology.getNumAtoms()

self.ts = self._mda_timestep_from_omm_app()

if self.convert_units:
self.convert_pos_from_native(self.ts._pos)
self.ts.triclinic_dimensions = self.convert_pos_from_native(
self.ts.triclinic_dimensions, inplace=False
)

def _mda_timestep_from_omm_app(self):
""" Construct Timestep object from OpenMM Application object """

omm_object = self.filename
n_atoms = omm_object.topology.getNumAtoms()

ts = self._Timestep(n_atoms, **self._ts_kwargs)
ts.frame = 0
if omm_object.topology.getPeriodicBoxVectors() is not None:
ts.triclinic_dimensions = np.array(
omm_object.topology.getPeriodicBoxVectors()._value
)
ts.positions = np.array(omm_object.getPositions()._value)

return ts


1 change: 1 addition & 0 deletions package/MDAnalysis/coordinates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,7 @@ class can choose an appropriate reader automatically.
from . import INPCRD
from . import LAMMPS
from . import MOL2
from . import OpenMM
from . import ParmEd
from . import PDB
from . import PDBQT
Expand Down
Loading