Skip to content

Commit

Permalink
gmxapi-30 Tutorial / working Jupyter notebook examples
Browse files Browse the repository at this point in the history
Describe repository contents. Improve inline documentation for
infrastructure files.
  • Loading branch information
eirrgang committed Jun 5, 2018
1 parent d093197 commit 105cf95
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 21 deletions.
36 changes: 24 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
# Build docker image with sample plugin `myplugin`
# Build docker image with sample plugin `myplugin`.

FROM gmxapi/gmxapi:devel

# Allow build for an arbitrary branch or tag, but default to the tip of `master`
#ARG BRANCH=master
# From the root directory of the repository (where this Dockerfile is), build an image named "restraint_test" with
# docker build -t sample_restraint .
# Note that public images for dockerhub are build with `docker build -t gmxapi/sample_restraint:tag .`
#
# Launch an ephemeral container with
# docker run --rm -ti -p 8888:8888 sample_restraint
# for the Jupyter notebook server, or, for just a shell
# docker run --rm -ti sample_restraint bash
# The container will be removed when the process (notebook server or shell) exits.
# To create and run a named container, do something like the following.
# docker run -ti --name restraint_test sample_restraint
#
#RUN wget https://github.com/eirrgang/sample_restraint/archive/$BRANCH.zip && \
# unzip $BRANCH.zip && \
# mv sample_restraint-$BRANCH /home/jovyan/samplerestraint && \
# rm $BRANCH.zip
# Test with
# docker run --cpus 2 --rm -ti gmxapi/sample_restraint:devel bash -c "cd /home/jovyan/samplerestraint/tests && mpiexec -n 2 python -m mpi4py -m pytest"
# or replace `gmxapi/sample_restraint:devel` with your local image name


# The base image is available on DockerHub, but you can also build your own from the gmxapi repository.
FROM gmxapi/gmxapi:devel

# Hot fix: clean out accidental cruft from an upstream base image.
RUN rm -rf /home/jovyan/sample_restraint /home/jovyan/plugin-build

# This is a bit risky and troublesome, but I want to test the current repo state without committing.
Expand All @@ -22,6 +33,7 @@ COPY --chown=1000 tests/ /home/jovyan/sample_restraint/tests/
# Prune the directory after removed or find will try to descend into a nonexistant directory
RUN find /home/jovyan -name __pycache__ -exec rm -rf \{\} \; -prune

# Build and install the plugin in the Conda virtual environment from the scipy-jupyter base image.
RUN mkdir /home/jovyan/plugin-build && \
(cd /home/jovyan/plugin-build && \
GROMACS_DIR=/home/jovyan/install/gromacs gmxapi_DIR=/home/jovyan/install/gromacs cmake ../sample_restraint -DPYTHON_EXECUTABLE=/opt/conda/bin/python && \
Expand All @@ -30,10 +42,10 @@ RUN mkdir /home/jovyan/plugin-build && \
make install) && \
PYTHONPATH=plugin-build/src/pythonmodule CONDA_DIR=/opt/conda /opt/conda/bin/python -m pytest sample_restraint/tests --verbose

# The jupyter notebook server might not pick this up, but we can make it a little easier to find the
# `gmx` binary from the default user shell.
RUN echo "source install/gromacs/bin/GMXRC.bash" >> /home/jovyan/.profile

# Grab some additional useful biomolecular simulation analysis tools.
RUN conda config --add channels conda-forge
RUN conda install mdanalysis

# Test with
# docker run --cpus 2 --rm -ti samplerestraint bash -c "cd /home/jovyan/samplerestraint/tests && mpiexec -n 2 python -m mpi4py -m pytest"
34 changes: 28 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Sample MD restraint plugin
==========================

This repository provides a complete and working implementation of a few GROMACS restraint potentials. It is intended as both
This `repository <https://github.com/kassonlab/sample_restraint>`_ provides a complete and working implementation of a few GROMACS restraint potentials. It is intended as both
a tutorial and as a template for implementing new custom restraint potentials.

Restraint potentials are implemented as "plugins" to GROMACS. The required GROMACS modifications are available at this
Expand All @@ -11,14 +11,31 @@ Restraint potentials are implemented as "plugins" to GROMACS. The required GROMA
The plugin potentials are loaded and configured via Python and are compatible with the `gmxapi <https://github.com/kassonlab/gmxapi>`_
Python package for MD simulation workflows.

For a quick start, consider pulling a recent Docker image and fiddle with the example notebook
in ``sample_restraint/examples/example``. Note that the ``--rm`` option tells docker not to save
any changes you make after launching the container. You can, however, download any changes you make to the notebook through the web interface. Refer to the `Docker documentation <https://docs.docker.com>`_ for more options on managing containers.
For a quick start, consider pulling a recent Docker image that has already been configured for gmxapi and this plug-in.

Repository Contents
===================
This repository uses CMake to build and install a Python C++ extension package.

* ``CMakeLists.txt``, ``cmake/FindGROMACS.cmake``, and ``src/CMakeLists.txt`` provide necessary CMake infrastructure. You should not need to edit these.
* ``src/cpp`` contains a header and ``cpp`` file for each restraint potential built with this module. When adding new potentials, you will update ``CMakeLists.txt`` to create build targets. Use the existing potentials as examples.
* ``src/pythonmodule/`` contains ``CMakeLists.txt``, ``export_plugin.h``, and ``export_plugin.cpp``. When you have written a new potential, you can add it to ``CMakeLists.txt`` and ``export_plugin.cpp``. This is the code that produces the C++ extension for Python.
* ``src/pybind11`` is just a copy of the Python bindings framework from the Pybind project (ref https://github.com/pybind/pybind11 ). It is used to wrap the C++ restraint code and give it a Python interface.
* ``tests/`` contains C++ and Python tests for the provided code. Update ``CMakeLists.txt`` to add your own.
* ``examples`` contains a sample SLURM job script and ``restrained-ensemble.py`` gmxapi script that have been used to do restrained ensemble simulations. ``example.py`` and ``example.ipynb`` explore a toy alanine dipeptide system. ``strip_notebook.py`` is a helper script to remove extra output and state data from an iPython notebook before checking updates back into the repository.
* ``Dockerfile`` is a recipe to build a Docker image from the root of the repository.

Docker quick-start
==================

Pull the docker image and launch a container::
Pull the docker image and launch a container with port 8888 on the host mapped to port 8888 in the container.
::

$ docker run --rm -ti -p 8888:8888 gmxapi/sample_restraint:devel

Note that the ``--rm`` option tells docker not to save
any changes you make after launching the container. You can, however, download any changes you make to the notebook through the web interface. Refer to the `Docker documentation <https://docs.docker.com>`_ for more options on managing containers.

You should then see something like the following, but with a different ``token`` for the URL. Open the
URL in a browser on the same (host) machine to access the notebook server. Browse to ``sample_restraint`` and ``examples`` and then launch the ``example`` notebook for an interactive walk-through. Example output::

Expand Down Expand Up @@ -74,6 +91,11 @@ appropriate location automatically for your Python interpreter. If you have admi
(such as when running on a desktop computer) or if you are using a Python virtual environment (recommended),
you don't need to specify anything additional. If you are an unprivileged user (such as on a shared machine) and are not in a Python virtual environment, set `-DGMXPLUGIN_USER_INSTALL=ON` to install into
the "user" Python packages directory in your home directory. (Equivalent to the ``--user`` option to ``pip``)

If you have multiple Python installations or just want to be unambiguous, provide CMake with the Python
interpreter you wish to use (the same as you are using for ``gmxapi``) with ``-DPYTHON_EXECUTABLE=/path/to/python``.
For instance, if you have both Python 3.x and Python 2.7,
but you plan to use Python 2.7, use ``-DPYTHON_EXECUTABLE=`which python2``` or ``-DPYTHON_EXECUTABLE=`which python``` (if ``python`` points to the Python 2 interpreter).
::

$ # build sample restraint
Expand All @@ -90,7 +112,7 @@ the "user" Python packages directory in your home directory. (Equivalent to the
$ # or
$ # cmake ../sample_restraint -DGMXPLUGIN_INSTALL_PATH=/path/to/install/directory
$ # or
$ # cmake ../sample_restraint -DGMXPLUGIN_USER_INSTALL=ON
$ # cmake ../sample_restraint -DGMXPLUGIN_USER_INSTALL=ON -DPYTHON_EXECUTABLE=`which python`
$ make
$ # run C++ tests
$ make test
Expand Down
6 changes: 6 additions & 0 deletions src/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Defines targets for the C++ restraints implemented here. These CMake targets are used by the
# unit tests and by the Python module target defined in ../pythonmodule/CMakeLists.txt

# Create a shared object library for a simple restraint.
add_library(harmonicpotential SHARED
harmonicpotential.h
harmonicpotential.cpp)
Expand All @@ -17,6 +21,8 @@ set_target_properties(harmonicpotential PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE
target_link_libraries(harmonicpotential PRIVATE Gromacs::gmxapi)



# Create a shared object library for our restrained ensemble plugin.
add_library(ensemblepotential SHARED
ensemblepotential.h
ensemblepotential.cpp)
Expand Down
9 changes: 6 additions & 3 deletions src/pythonmodule/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# The first argument sets the name of the target for CMake bookkeeping purposes. It is the default name of the
# shared object library that is produced, but we can override that.
# shared object library that is produced, but we can override that. There is no particular reason to
# change "sampleplugin" here unless you need different CMake target names to build several modules in
# a single project.
pybind11_add_module(sampleplugin MODULE export_plugin.cpp)

# Set the name of the shared object library (and the name of the Python module) to "myplugin"
#set_target_properties(sampleplugin PROPERTIES OUTPUT_NAME myplugin)
# Set the name of the shared object library (and the name of the Python module) to "myplugin".
# If you change "myplugin" you must also change the argument to the macro ``PYBIND11_MODULE(myplugin, m)`` in export_plugin.cpp
set_target_properties(sampleplugin PROPERTIES OUTPUT_NAME myplugin)

# We can't easily/reliably let a debug build of a Python module have a "d" suffix and still be importable with the same name.
set_target_properties(sampleplugin PROPERTIES DEBUG_POSTFIX "")

Expand Down

0 comments on commit 105cf95

Please sign in to comment.