The `pip install` options `--no-index` and `--find-links` allow for an offline stash of package archives so that
satisfying dependencies for a new virtualenv does not require network access or lengthy build times.
+
+# Dependencies
+
+## OS X
+Some dependencies (notably, a Python installation itself) may require some fiddling
+with the XCode SDK.
+https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes#3035624
\ No newline at end of file
--- /dev/null
+_skbuild
+pip-wheel-metadata
set(GMXAPI_PYTHON_EXTENSION_SOURCES
gmxapi/module.cpp
+ gmxapi/export_context.cpp
+ gmxapi/export_system.cpp
+ gmxapi/pycontext.cpp
+ gmxapi/pysystem.cpp
)
pybind11_add_module(_gmxapi
"""gmxapi Python package for GROMACS."""
-__all__ = ['commandline_operation', 'logger', 'operation']
+__all__ = ['commandline_operation', 'exceptions', 'logger', 'operation']
+import os
+
+from gmxapi import exceptions
from gmxapi import operation
from gmxapi._logging import logger
from gmxapi.commandline import commandline_operation
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief Bindings for Context class.
+ *
+ *
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ *
+ * \ingroup module_python
+ */
+#include "module.h"
+
+#include "gmxapi/context.h"
+#include "gmxapi/exceptions.h"
+#include "pycontext.h"
+
+
+namespace gmxpy
+{
+
+namespace detail
+{
+
+namespace py = pybind11;
+
+
+/*! \internal
+ * \brief Update a parameter structure for a simulation execution context.
+ *
+ * \param mdargs [OUT] Container for parameters made available to the MD library context.
+ * \param params Python dictionary mapping parameter names to argument values.
+ *
+ * Note that the current library infrastructure does not provide a way for the
+ * simulation machinery to express human-readable parameter names with rich
+ * descriptions, so a few of the most necessary mdrun command line parameters
+ * are hard coded here. Ref. https://redmine.gromacs.org/issues/2877
+ *
+ * For reference and default values, see
+ * http://manual.gromacs.org/current/onlinehelp/gmx-mdrun.html#options
+ */
+static void setMDArgs(std::vector<std::string>* mdargs,
+ py::dict params)
+{
+ mdargs->clear();
+ if (params.contains("grid"))
+ {
+ if (py::len(params["grid"]) == 0)
+ {
+ throw gmxapi::UsageError("Grid argument must describe domain decomposition grid.");
+ }
+ std::vector<std::string> vals;
+ for (auto && val : params["grid"])
+ {
+ vals.emplace_back(py::cast<std::string>(py::str(val)));
+ }
+ mdargs->emplace_back("-dd");
+ for (auto && val : vals)
+ {
+ mdargs->emplace_back(val);
+ }
+ }
+ if (params.contains("pme_ranks"))
+ {
+ auto val = py::cast<std::string>(py::str(params["pme_ranks"]));
+ mdargs->emplace_back("-npme");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("threads"))
+ {
+ auto val = py::cast<std::string>(py::str(params["threads"]));
+ mdargs->emplace_back("-nt");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("tmpi"))
+ {
+ auto val = py::cast<std::string>(py::str(params["tmpi"]));
+ mdargs->emplace_back("-ntmpi");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("threads_per_rank"))
+ {
+ auto val = py::cast<std::string>(py::str(params["threads_per_rank"]));
+ mdargs->emplace_back("-ntomp");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("pme_threads_per_rank"))
+ {
+ auto val = py::cast<std::string>(py::str(params["pme_threads_per_rank"]));
+ mdargs->emplace_back("-ntomp_pme");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("steps"))
+ {
+ auto val = py::cast<std::string>(py::str(params["steps"]));
+ mdargs->emplace_back("-nsteps");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("max_hours"))
+ {
+ auto val = py::cast<std::string>(py::str(params["max_hours"]));
+ mdargs->emplace_back("-maxh");
+ mdargs->emplace_back(val);
+ }
+ if (params.contains("append_output"))
+ {
+ try
+ {
+ if (!params["append_output"].cast<bool>())
+ {
+ mdargs->emplace_back("-noappend");
+ }
+ }
+ catch (const py::cast_error &e)
+ {
+ // Couldn't cast to bool for some reason.
+ // Convert to gmxapi exception (not implemented)
+ // ref. https://github.com/kassonlab/gmxapi/issues/125
+ throw;
+ }
+ }
+}
+
+void export_context(py::module &m)
+{
+ // Add argument type before it is used for more sensible automatic bindings behavior.
+ py::class_ < MDArgs, std::unique_ptr < MDArgs>> mdargs(m, "MDArgs");
+ mdargs.def(py::init(), "Create an empty MDArgs object.");
+ mdargs.def("set",
+ [](MDArgs* self, py::dict params){ setMDArgs(self, params); },
+ "Assign parameters in MDArgs from Python dict.");
+
+ // Export execution context class
+ py::class_ < PyContext, std::shared_ptr < PyContext>> context(m, "Context");
+ context.def(py::init(), "Create a default execution context.");
+ context.def("setMDArgs", &PyContext::setMDArgs, "Set MD runtime parameters.");
+
+ context.def("add_mdmodule", &PyContext::addMDModule,
+ "Add an MD plugin for the simulation.");
+}
+
+} // end namespace gmxpy::detail
+
+} // end namespace gmxpy
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief Bindings for System and session launch.
+ *
+ * \ingroup module_python
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ */
+
+#include "module.h"
+
+#include <iostream>
+
+#include "gmxapi/md.h"
+#include "gmxapi/session.h"
+#include "gmxapi/status.h"
+#include "gmxapi/system.h"
+
+#include "pycontext.h"
+#include "pysystem.h"
+
+// Note that PyCapsule symbols from Python.h should be imported by way of the pybind headers, so let's not
+// muddy the waters by explicitly including Python.h here unless we want to get more particular about the
+// CMake configuration.
+
+namespace gmxpy
+{
+
+namespace detail
+{
+
+namespace py = pybind11;
+
+
+void export_system(py::module &m)
+{
+ using ::gmxapi::System;
+
+ // The Session is a resource shared by active API operations.
+ // We can't completely surrender ownership to Python because other API objects may refer to it.
+ // We could use our own holder class instead of shared_ptr, but developers would
+ // have to keep in mind that Python may make new references in different scopes
+ // and threads, and pass references into other C++ code. Using shared_ptr
+ // self-documents intent. Future implementations could refactor Session as a
+ // dynamically accessed facet of the Context, which the API client would be
+ // required to maintain and to pass to the API.
+ py::class_ < ::gmxapi::Session, std::shared_ptr < ::gmxapi::Session>> session(m, "MDSession");
+ session.def("run", &::gmxapi::Session::run, "Run the simulation workflow");
+ session.def("close", &::gmxapi::Session::close, "Shut down the execution environment and close the session.");
+
+ // Export system container class
+ py::class_<System, std::shared_ptr<System> > system(m, "MDSystem");
+ system.def("launch",
+ [](System* system, std::shared_ptr<PyContext> context)
+ {
+ auto newSession = system->launch(context->get());
+ return newSession;
+ },
+ "Launch the configured workflow in the provided context.");
+
+ // Module-level function
+ m.def("from_tpr", &gmxpy::from_tpr, "Return a system container initialized from the given input record.");
+}
+
+} // end namespace gmxpy::detail
+
+} // end namespace gmxpy
* the research papers on the package. Check out http://www.gromacs.org.
*/
+/*! \internal \file
+ * \brief Exports Python bindings for gmxapi._gmxapi module.
+ *
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ *
+ * \ingroup module_python
+ */
+
+#include "module.h"
+
+#include <memory>
+
+#include "gmxapi/status.h"
+#include "gmxapi/version.h"
+
#include "pybind11/pybind11.h"
-PYBIND11_MODULE(_gmxapi, m) {
-}
+namespace py = pybind11;
+
+// Export Python module.
+
+/// used to set __doc__
+/// pybind11 uses const char* objects for docstrings. C++ raw literals can be used.
+const char* const docstring = R"delimeter(
+gmxapi core module
+==================
+
+gmxapi._gmxapi provides Python access to the GROMACS C++ API so that client code can be
+implemented in Python, C++, or a mixture. The classes provided are mirrored on the
+C++ side in the gmxapi namespace as best as possible.
+
+This documentation is generated from C++ extension code. Refer to C++ source
+code and developer documentation for more details.
+
+)delimeter";
+
+/*! \brief Export gmxapi._gmxapi Python module in shared object file.
+ *
+ * \ingroup module_python
+ */
+
+// Instantiate the Python module
+PYBIND11_MODULE(_gmxapi, m){
+ using namespace gmxpy::detail;
+ m.doc() = docstring;
+
+ // Export core bindings
+ m.def("has_feature",
+ &gmxapi::Version::hasFeature,
+ "Check the gmxapi library for a named feature.");
+
+ py::class_< ::gmxapi::Status > gmx_status(m, "Status", "Holds status for API operations.");
+
+ // Get bindings exported by the various components.
+ export_context(m);
+ export_system(m);
+
+} // end pybind11 module
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \defgroup module_python Python module for accessing Gromacs library
+ * The Python module ``gmxapi`` consists of a high-level interface implemented in
+ * pure Python and a low-level interface implemented as a C++ extension in the
+ * submodule, gmxapi._gmxapi.
+ */
+/*! \file
+ * \brief Declares symbols to be exported to gmxapi._gmxapi Python module.
+ *
+ * Declares namespace gmxpy, used internally in the C++ extension.
+ * \ingroup module_python
+ */
+#ifndef GMXPY_MODULE_H
+#define GMXPY_MODULE_H
+
+#include "pybind11/pybind11.h"
+
+
+/*! \brief API client code from which to export Python bindings
+ *
+ * gmxpy is not a public interface. It implements bindings for the public
+ * Python API in the C++ Python extension it produces, and it uses the public
+ * C++ Gromacs API, but is itself an API *client* and its C++ interfaces are not
+ * intended to be used in external code.
+ * \ingroup module_python
+ */
+namespace gmxpy
+{
+
+namespace detail
+{
+
+void export_context(pybind11::module &m);
+void export_system(pybind11::module &m);
+
+} // end namespace gmxpy::detail
+
+} // end namespace gmxpy
+
+#endif // GMXPY_MODULE_H
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief Wrapper code for gmxapi::Context.
+ *
+ * \ingroup module_python
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ */
+#include "pycontext.h"
+
+#include "gmxapi/gmxapi.h"
+#include "gmxapi/md.h"
+
+
+namespace py = pybind11;
+
+namespace gmxpy
+{
+
+void PyContext::setMDArgs(const MDArgs &mdArgs)
+{
+ assert(context_);
+ context_->setMDArgs(mdArgs);
+}
+
+std::shared_ptr<gmxapi::Session> PyContext::launch(const gmxapi::Workflow &work)
+{
+ assert(context_);
+ return context_->launch(work);
+}
+
+std::shared_ptr<gmxapi::MDWorkSpec> PyContext::getSpec() const
+{
+ assert(workNodes_);
+ return workNodes_;
+}
+
+std::shared_ptr<gmxapi::Context> PyContext::get() const
+{
+ assert(context_);
+ return context_;
+}
+
+PyContext::PyContext() :
+ context_ {std::make_shared<gmxapi::Context>()},
+workNodes_ {
+ std::make_shared<gmxapi::MDWorkSpec>()
+}
+{
+ assert(context_);
+ assert(workNodes_);
+}
+
+void PyContext::addMDModule(pybind11::object force_object)
+{
+ // If force_object has a bind method, give it a PyCapsule with a pointer
+ // to our C++ object.
+ if (py::hasattr(force_object, "bind"))
+ {
+ auto spec = getSpec();
+ auto holder = new gmxapi::MDHolder(spec);
+ holder->name_ = "pygmx holder";
+ auto deleter = [](PyObject *o) {
+ if (PyCapsule_IsValid(o, gmxapi::MDHolder_Name))
+ {
+ auto holder_ptr = (gmxapi::MDHolder *) PyCapsule_GetPointer(o, gmxapi::MDHolder_Name);
+ delete holder_ptr;
+ // \todo double-check whether there is something we should do to invalidate a PyCapsule.
+ }
+ ;
+ };
+ auto capsule = py::capsule(holder,
+ gmxapi::MDHolder_Name,
+ deleter);
+ py::object bind = force_object.attr("bind");
+ // py::capsule does not have bindings and does not implicitly convert to py::object
+ py::object obj = capsule;
+ bind(obj);
+ }
+ else
+ {
+ // Note: Exception behavior is likely to change.
+ // Ref: https://github.com/kassonlab/gmxapi/issues/125
+ throw py::value_error("Argument must provide a `bind` method.");
+ }
+}
+
+} // end namespace gmxpy
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief Declarations for Context wrappers.
+ *
+ * \ingroup module_python
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ */
+
+#ifndef GMXPY_PYCONTEXT_H
+#define GMXPY_PYCONTEXT_H
+
+#include "pybind11/pybind11.h"
+
+#include "gmxapi/context.h"
+#include "gmxapi/md.h"
+
+namespace gmxpy
+{
+
+using gmxapi::MDArgs;
+
+
+/*!
+ * \brief Wrapper for gmxapi::Context
+ *
+ * Proxies gmxapi::Context methods and includes additions not yet provided by
+ * by upstream library.
+ */
+class PyContext
+{
+ public:
+ PyContext();
+ void setMDArgs(const MDArgs &mdArgs);
+ std::shared_ptr<gmxapi::Session> launch(const gmxapi::Workflow &work);
+ std::shared_ptr<gmxapi::Context> get() const;
+
+ void addMDModule(pybind11::object forceProvider);
+
+ /*!
+ * \brief Borrow shared ownership of the System's container of associated modules.
+ *
+ * Used with gmxapi::MDHolder to add MD Modules to the simulation to be run.
+ *
+ * \return handle to be passed to gmxapi::MDHolder
+ *
+ */
+ std::shared_ptr<gmxapi::MDWorkSpec> getSpec() const;
+
+ private:
+ std::shared_ptr<gmxapi::Context> context_;
+ std::shared_ptr<gmxapi::MDWorkSpec> workNodes_;
+};
+
+
+} // end namespace gmxpy
+
+#endif //GMXPY_PYCONTEXT_H
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief Implement System helper code.
+ *
+ * \ingroup module_python
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ */
+
+#include "pysystem.h"
+
+#include <memory>
+
+namespace gmxpy
+{
+
+std::shared_ptr<gmxapi::System> from_tpr(std::string filename)
+{
+ auto system = gmxapi::fromTprFile(filename);
+ return std::make_shared<gmxapi::System>(std::move(system));
+}
+
+} // end namespace gmxpy
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+#ifndef GMXPY_SYSTEM_H
+#define GMXPY_SYSTEM_H
+
+/*! \file
+ * \brief Declare helpers for gmxapi::System.
+ *
+ * \ingroup module_python
+ * \author M. Eric Irrgang <ericirrgang@gmail.com>
+ */
+
+#include <memory>
+#include <string>
+
+#include "gmxapi/gmxapi.h"
+#include "gmxapi/system.h"
+
+namespace gmxpy
+{
+
+std::shared_ptr<gmxapi::System> from_tpr(std::string filename);
+
+} // end namespace gmxpy
+
+#endif // header guard
--- /dev/null
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2019, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+
+"""Test gromacs.mdrun operation.
+
+Factory produces deferred execution operation.
+
+TODO: Factory expects input for conformation, topology, simulation parameters, simulation state.
+
+TODO: Factory accepts additional keyword input to indicate binding
+ to the "potential" interface.
+"""
+
+import logging
+import os
+import pytest
+
+# Configure the `logging` module before and non-built-in packages start to use it.
+logging.getLogger().setLevel(logging.DEBUG)
+# create console handler
+ch = logging.StreamHandler()
+ch.setLevel(logging.DEBUG)
+# create formatter and add it to the handler
+formatter = logging.Formatter('%(asctime)s:%(name)s:%(levelname)s: %(message)s')
+ch.setFormatter(formatter)
+# add the handlers to the logger
+logging.getLogger().addHandler(ch)
+
+from gmxapi import _gmxapi
+
+from pytesthelpers import withmpi_only
+
+@pytest.mark.usefixtures('cleandir')
+def test_run_from_tpr(spc_water_box):
+ assert os.path.exists(spc_water_box)
+ filename = os.path.abspath(spc_water_box)
+ system = _gmxapi.from_tpr(filename)
+ context = _gmxapi.Context()
+ md = system.launch(context)
+ md.run()