gmx Python module reference¶
The Gromacs Python interface is implemented as a high-level scripting interface implemented in pure Python and a
lower-level API implemented as a C++ extension.
The pure Python implementation provides the basic gmx
module and
classes with a very stable syntax that can be maintained with maximal compatibility
while mapping to lower level interfaces that may take a while to sort out. The
separation also serves as a reminder that different execution contexts may be
implemented quite diffently, though Python scripts using only the high-level
interface should execute on all. Bindings to the libgromacs
C++ API are
provided in the submodule gmx.core
.
The following documentation is extracted from the gmx
Python module and is also available
directly, using either pydoc
from the command line or help()
from within Python, such
as during an interactive session.
Refer to the Python source code itself for additional clarification.
Procedural interface¶
gmx.run()
gmx.get_context()
gmx.workflow.from_tpr()
gmx.workflow.get_source_elements()
gmx.version.api_is_at_least()
-
gmx.
run
(work=None)[source]¶ Run the provided work on available resources.
Parameters: work (gmx.workflow.WorkSpec) – either a WorkSpec or an object with a workspec attribute containing a WorkSpec object. Returns: run status. Return type: gmx.status.Status
-
gmx.
get_context
(work=None)[source]¶ Get a concrete Context object.
Parameters: work (gmx.workflow.WorkSpec) – runnable work as a valid gmx.workflow.WorkSpec object Returns: An object implementing the gmx.context.Context
interface, if possible.Raises: gmx.exceptions.ValueError if an appropriate context for work
could not be loaded.If work is provided, return a Context object capable of running the provided work or produce an error.
The semantics for finding Context implementations needs more consideration, and a more informative exception is likely possible.
A Context can run the provided work if
- the Context supports can resolve all operations specified in the elements
- the Context supports DAG topologies implied by the network of dependencies
- the Context supports features required by the elements with the specified parameters, such as synchronous array jobs.
-
gmx.workflow.
from_tpr
(input=None, **kwargs)[source]¶ Create a WorkSpec from a (list of) tpr file(s).
Generates a work specification based on the provided simulation input and returns a handle to the MD simulation element of the workflow. Key word arguments can override simulation behavior from
input
.If the MD operation discovers artifacts from a previous simulation that was launched from the same input, the simulation resumes from the last checkpointed step. If
append_output
is setFalse
, existing artifacts are kept separate from new output with the standard file naming convention, and new output begins from the last checkpointed step, if any.Setting
end_time
redefines the end point of the simulation trajectory from what was provided ininput
. It is equivalent to changing the number of steps requested in the MDP (or TPR) input, but it time is provided as picoseconds instead of a number of time steps.Deprecated since version 0.0.7: If
steps=N
is provided and N is an integer greater than or equal to 1, the MD operation advances the trajectory byN
steps, regardless of the number of simulation steps specified ininput
orend_time
. For convenience, settingsteps=None
does not overrideinput
. Note that when it is notNone
,steps
takes precedence overend_time
andinput
, but can still be superceded by a signal, such as if an MD plugin or other code has a simulation completion condition that occurs beforeN
additional steps have run.Where key word arguments correspond to
gmx mdrun
command line options, the corresponding flags are noted below.Keyword Arguments: - input (str) – Required string or list of strings giving the filename(s) of simulation input
- append_output (bool) – Append output for continuous trajectories if True, truncate existing output data if False. (default True)
- end_time (float) – Specify the final time in the simulation trajectory, overriding input read from TPR.
- grid (tuple) – Domain decomposition grid divisions (nx, ny, nz). (-dd)
- max_hours (float) – Terminate after 0.99 times this many hours if simulation is still running. (-maxh)
- pme_ranks (int) – number of separate ranks to be used for PME electrostatics. (-npme)
- pme_threads_per_rank (int) – Number of OpenMP threads per PME rank. (-ntomp_pme)
- steps (int) – Override input files and run for this many steps. (-nsteps; deprecated)
- threads (int) – Total number of threads to start. (-nt)
- threads_per_rank (int) – number of OpenMP threads to start per MPI rank. (-ntomp)
- tmpi (int) – number of thread-MPI ranks to start. (-ntmpi)
Returns: simulation member of a gmx.workflow.WorkSpec object
Produces a WorkSpec with the following data:
version: gmxapi_workspec_0_1 elements: tpr_input: namespace: gromacs operation: load_tpr params: {'input': ['tpr_filename1', 'tpr_filename2', ...]} md_sim: namespace: gmxapi operation: md depends: ['tpr_input'] params: {'kw1': arg1, 'kw2': arg2, ...}
- Bugs: version 0.0.6
- There is not a way to programatically check the current step number on disk. See https://github.com/kassonlab/gmxapi/issues/56 and https://github.com/kassonlab/gmxapi/issues/85
-
gmx.workflow.
get_source_elements
(workspec)[source]¶ Get an iterator of the starting nodes in the work spec.
Source elements have no dependencies and can be processed immediately. Elements with dependencies cannot be processed, instantiated, or added to a work spec until after their dependencies have been.
Parameters: workspec – an existing work specification to analyze, such as by a Context implementation preparing to schedule work. Returns: iterator of gmx.workflow.WorkElement objects that may be processed without dependencies. This function is provided in the API to allow flexibility in how source elements are determined.
-
gmx.version.
api_is_at_least
(major_version, minor_version=0, patch_version=0)[source]¶ Allow client to check whether installed module supports the requested API level.
Parameters: - major_version (int) – gmxapi major version number.
- minor_version (int) – optional gmxapi minor version number (default: 0).
- patch_version (int) – optional gmxapi patch level number (default: 0).
Returns: True if installed gmx package is greater than or equal to the input level
Note that if gmx.version.release is False, the package is not guaranteed to correctly or fully support the reported API level.
Python API¶
Python context managers¶
Objects implementing the Context interfaces defined in gmx.context
implement
the Python context manager protocol. When used in a with
block, a Context
produces a Session
object. See examples below.
Note
Session
is not well specified in gmxapi 0.0.6.
gmx.fileio module¶
Provide the high-level interface to the file i/o behaviors the gmx package.
The submodule name may seem longer than necessary, but avoids a namespace collision with a standard Python module on the default path.
-
class
gmx.fileio.
TprFile
(filename=None, mode=None)[source]¶ Handle to a Gromacs simulation run input file.
Open a TPR file.
File access mode is indicated by ‘r’ for read-only access.
Parameters: - filename (str) – Path to a run input file (e.g. ‘myfile.tpr’)
- mode (str) – File access mode.
Note
Currently, TPR files are read-only from the Python interface.
Example
>>> import gmx >>> filehandle = gmx.fileio.TprFile(filename, 'r')
-
gmx.fileio.
read_tpr
(tprfile=None)[source]¶ Get a simulation input object from a TPR run input file.
Parameters: tprfile – TPR input object or filename Returns: simulation input object The returned object may be inspected by the user. Simulation input parameters may be extracted through the parameters attribute.
Example
>>> sim_input = gmx.fileio.read_tpr(tprfile=tprfilename) >>> params = sim_input.parameters.extract() >>> print(params['init-step']) 0
Supports the read_tpr gmxapi work graph operation. (not yet implemented)
-
gmx.fileio.
write_tpr_file
(output, input=None)[source]¶ Create a new TPR file, combining user-provided input.
New in version 0.0.8: Initial version of this tool does not know how to generate a valid simulation run input file from scratch, so it requires input derived from an already valid TPR file.
The simulation input object should provide the gmx simulation_input interface, with output ports for parameters, structure, topology, and state, such as a TprFileHandle
Parameters: - output – TPR file name to write.
- input – simulation input data from which to write a simulation run input file.
Use this function to write a new TPR file with data updated from an existing TPR file. Keyword arguments are objects that can provide gmxapi compatible access to the necessary simulation input data.
In the initial version, data must originate from an existing TPR file, and only simulation parameters may be rewritten. See gmx.fileio.read_tpr()
Example
>>> sim_input = gmx.fileio.read_tpr(tprfile=tprfilename) >>> sim_input.parameters.set('init-step', 1) >>> gmx.fileio.write_tpr_file(newfilename, input=sim_input)
Warning
The interface is in flux.
Todo
Be consistent about terminology for “simulation state”. We are currently using “simulation state” to refer both to the aggregate of data (superset) necessary to launch or continue a simulation _and_ to the extra data (subset) necessary to capture full program state, beyond the model/method input parameters and current phase space coordinates. Maybe we shouldn’t expose that as a separate user-accessible object and should instead make it an implementation detail of a wrapper object that has standard interfaces for the non-implementation-dependent encapsulated data.
Returns: possibly a completion condition of some sort and/or handle to the new File Return type: TBD
gmx.context module¶
Execution Context¶
-
class
gmx.context.
Context
(work=None, workdir_list=None, communicator=None)[source]¶ Manage an array of simulation work executing in parallel.
This is the first implementation of a new style of Context class that has some extra abstraction and uses the new WorkSpec idea.
Additional facilities are available to elements of the array members.
- array element corresponding to work in the current sub-context
- “global” resources managed by the ParallelArrayContext
-
work :obj:`gmx.workflow.WorkSpec`
specification of work to be performed when a session is launched.
-
rank
¶ numerical index of the current worker in a running session (None if not running)
-
work_width
¶ Minimum width needed for the parallelism required by the array of work being executed.
-
elements
¶ dictionary of references to elements of the workflow.
rank, work_width, and elements are empty or None until the work is processed, as during session launch.
Example
Use
mpiexec -n 2 python -m mpi4py myscript.py
to run two jobs at the same time. In this example the jobs are identical. In myscript.py:>>> import gmx >>> import gmx.core >>> from gmx.data import tpr_filename # Get a test tpr filename >>> work = gmx.workflow.from_tpr([tpr_filename, tpr_filename]) >>> gmx.run(work)
Example
>>> import gmx >>> import gmx.core >>> from gmx.data import tpr_filename # Get a test tpr filename >>> work = gmx.workflow.from_tpr([tpr_filename, tpr_filename]) >>> context = gmx.context.get_context(work) >>> with context as session: ... session.run() ... # The session is one abstraction too low to know what rank it is. It lets the spawning context manage ... # such things. ... # rank = session.rank ... # The local context object knows where it fits in the global array. ... rank = context.rank ... output_path = os.path.join(context.workdir_list[rank], 'traj.trr') ... assert(os.path.exists(output_path)) ... print('Worker {} produced {}'.format(rank, output_path))
Implementation notes:
To produce a running session, the Context __enter__() method is called, according to the Python context manager protocol. At this time, the attached WorkSpec must be feasible on the available resources. To turn the specified work into an executable directed acyclic graph (DAG), handle objects for the elements in the work spec are sequenced in dependency-compatible order and the context creates a “builder” for each according to the element’s operation. Each builder is subscribed to the builders of its dependency elements. The DAG is then assembled by calling each builder in sequence. A builder can add zero, one, or more nodes and edges to the DAG.
The Session is then launched from the DAG. What happens next is implementation-dependent, and it may take a while for us to decide whether and how to standardize interfaces for the DAG nodes and edges and/or execution protocols. I expect each node will at least have a launch() method, but will also probably have typed input and output ports as well as some signalling. A sophisticated and abstract Session implementation could schedule work only to satisfy data dependencies of requested output upon request. Our immediate implementation will use the following protocol.
Each node has a launch() method. When the session is entered, the launch() method is called for each node in dependency order. The launch method returns either a callable (run() function) or None, raising an exception in case of an error. The sequence of non-None callables is stored by the Session. When Session.run() is called, the sequence of callables is called in order. If StopIteration is raised by the callable, it is removed from the sequence. The sequence is processed repeatedly until there are no more callables.
Note that this does not rigorously handle races or deadlocks, or flexibility in automatically chasing dependencies. A more thorough implementation could recursively call launch on dependencies (launch could be idempotent or involve some signalling to dependents when complete), run calls could be entirely event driven, and/or nodes could “publish” output (including just a completion message), blocking for acknowledgement before looking for the next set of subscribed inputs.
Create manager for computing resources.
Does not initialize resources because Python objects by themselves do not have a good way to deinitialize resources. Instead, resources are initialized using the Python context manager protocol when sessions are entered and exited.
Appropriate computing resources need to be knowable when the Context is created.
Keyword Arguments: - work – work specification with which to initialize this context
- workdir_list – deprecated
- communicator – non-owning reference to a multiprocessing communicator
If provided, communicator must implement the mpi4py.MPI.Comm interface. The Context will use this communicator as the parent for subcommunicators used when launching sessions. If provided, communicator is owned by the caller, and must be freed by the caller after any sessions are closed. By default, the Context will get a reference to MPI_COMM_WORLD, which will be freed when the Python process ends and cleans up its resources. The communicator stored by the Context instance will not be used directly, but will be duplicated when launching sessions using
with
.-
add_operation
(namespace, operation, get_builder)[source]¶ Add a builder factory to the operation map.
Extends the known operations of the Context by mapping an operation in a namespace to a function that returns a builder to process a work element referencing the operation. Must be called before the work specification is added, since the spec is inspected to confirm that the Context can run it.
It may be more appropriate to add this functionality to the Context constructor or as auxiliary information in the workspec, or to remove it entirely; it is straight-forward to just add snippets of code to additional files in the working directory and to make them available as modules for the Context to import.
Example
>>> # Import some custom extension code. >>> import myplugin >>> myelement = myplugin.new_element() >>> workspec = gmx.workflow.WorkSpec() >>> workspec.add_element(myelement) >>> context = gmx.context.ParallelArrayContext() >>> context.add_operation(myelement.namespace, myelement.operation, myplugin.element_translator) >>> context.work = workspec >>> with get_context() as session: ... session.run()
Depends on gmx.status, gmx.exceptions, gmx.workflow
gmx.exceptions module¶
Exceptions and Warnings raised by gmx module operations¶
Errors, warnings, and other exceptions used in the Gromacs gmx Python package are defined in the gmx.exceptions submodule.
The Gromacs gmx Python package defines a root exception, gmx.exceptions.Error, from which all Exceptions thrown from within the module should derive. If a published component of the gmx package throws an exception that cannot be caught as a gmx.exceptions.Error, please report the bug.
-
exception
gmx.exceptions.
ApiError
[source]¶ An API operation was attempted with an incompatible object.
-
exception
gmx.exceptions.
CompatibilityError
[source]¶ An operation or data is incompatible with the current gmxapi environment.
-
exception
gmx.exceptions.
FeatureNotAvailableError
[source]¶ Feature is not installed, is missing dependencies, or is not compatible.
-
exception
gmx.exceptions.
FeatureNotAvailableWarning
[source]¶ Feature is not installed, is missing dependencies, or is not compatible.
-
exception
gmx.exceptions.
TypeError
(got=None, expected=None)[source]¶ An object is of a type incompatible with the API operation.
gmx.status module¶
gmx.system module¶
-
class
gmx.system.
System
[source]¶ Gromacs simulation system objects. (Deprecated)
Deprecated since version 0.0.7: Instead, use
gmx.workflow
tools to set up a system for simulation.Version 0.0.6 and earlier:
A System object connects all of the objects necessary to describe a molecular system to be simulated.
Once a system is created, objects can be attached or edited, accessed through the following properties.
-
workflow
¶ element of work to be executed.
Example
>>> my_sim = gmx.System._from_file(tpr_filename) >>> status = my_sim.run()
Example
>>> my_sim = gmx.System._from_file(tpr_filename) >>> # Launch exectution of the runner and work on available resources. >>> with gmx.context.DefaultContext(system) as session: ... # Run the work specified in the TPR file ... session.run() ... # Extend the simulation and run an additional 1000 steps. ... # (version 0.1.0) ... #status = session.run(1000) ... print(status) ... gmx.Status(True) Success
-
run
(parameters=None)[source]¶ Launch execution.
If the System is attached to a Context, the Context is initialized, if necessary, and its instance run() method is called. If there is not yet a Context, one is created and then used.
Note: currently always initializes new context informed by the runner.
Parameters: parameters – optional parameters to pass to runner. Parameter type varies by runner type. Returns: Gromacs status object.
-
gmx.version module¶
Provide version and release information.
-
gmx.version.
major
¶ gmxapi major version number.
Type: int
-
gmx.version.
minor
¶ gmxapi minor version number.
Type: int
-
gmx.version.
patch
¶ gmxapi patch level number.
Type: int
-
gmx.version.
release
¶ True if imported gmx module is an officially tagged release, else False.
Type: bool
-
gmx.version.
api_is_at_least
(major_version, minor_version=0, patch_version=0)[source] Allow client to check whether installed module supports the requested API level.
Parameters: - major_version (int) – gmxapi major version number.
- minor_version (int) – optional gmxapi minor version number (default: 0).
- patch_version (int) – optional gmxapi patch level number (default: 0).
Returns: True if installed gmx package is greater than or equal to the input level
Note that if gmx.version.release is False, the package is not guaranteed to correctly or fully support the reported API level.
gmx.workflow module¶
Provide workflow-level utilities and classes¶
Single-sim example:
>>> md = gmx.workflow.from_tpr(filename)
>>> gmx.run(md)
>>>
>>> # The above is shorthand for
>>> md = gmx.workflow.from_tpr(filename)
>>> with gmx.get_context(md.workspec) as session:
... session.run()
Array sim example:
>>> md = gmx.workflow.from_tpr([filename1, filename2])
>>> gmx.run(md)
The representation of work and the way it is dispatched are areas of active development. See also https://github.com/kassonlab/gmxapi/milestone/3
-
class
gmx.workflow.
WorkSpec
[source]¶ Container of workflow elements with data dependency information and requirements for execution.
An element cannot be added to a WorkSpec if it has dependencies that are not in the WorkSpec.
Work is added to the specification by passing a WorkElement object to
WorkSpec.add_element()
. Any dependencies in the WorkElement must already be specified in the target WorkSpec.When iterated over, a WorkSpec object returns WorkElement objects. WorkElement objects are yielded in a valid order to keep dependencies satisfied, but not necessarily the same order in which add_element() calls were originally made. In other words, the WorkSpec is a directed acyclic dependency graph, and its iterator returns nodes in an arbitrary but topologically correct order.
The string representation of a WorkSpec object is a valid JSON serialized data object.
The schema for version 0.1 of the specification allows data structures like the following.
{ 'version': 'gmxapi_workspec_0_1', 'elements': { 'myinput': { 'namespace': 'gromacs', 'operation': 'load_tpr', 'params': {'input': ['tpr_filename1', 'tpr_filename2']} }, 'mydata': { 'namespace': 'gmxapi', 'operation': 'open_global_data_with_barrier', 'params': ['data_filename'] }, 'mypotential': { 'namespace': 'myplugin', 'operation': 'create_mdmodule', 'params': {...}, 'depends': ['mydata'] }, 'mysim': { 'namespace': 'gmxapi', 'operation': 'md', 'depends': ['myinput', 'mypotential'] } } }
The first mapping (
version
) is required as shown. Theelements
map contains uniquely named elements specifying an operation, the operation’s namespace, and parameters and dependencies of the operation for this element.depends
is a sequence of string names of elements that are also in the work spec.params
is a key-value map with string keys and values that are valid JSON data.namespace
andoperation
are strings that theContext
can map to directors it uses to construct the session. Namespacegmxapi
is reserved for operations specified by the API. Namespacegromacs
is reserved for operations implemented as GROMACS adapters (versioned separately from gmxapi). The period character (“.”) has special meaning and should not be used in naming elements, namespaces, or operations.-
add_element
(element)[source]¶ Add an element to a work specification if possible.
Adding an element to a WorkSpec must preserve the validity of the workspec, which involves several checks. We do not yet check for element uniqueness beyond a string name.
If an element is added that was previously in another WorkSpec, it must first be removed from the other WorkSpec.
-
serialize
()[source]¶ Serialize the work specification in a form suitable to pass to any Context implementation.
Serialization is performed with the JSON data serialization module.
To simplify unique identification of work specifications, this function will also impose rules for reproducibility.
- All key-value maps are sorted alphanumerically by their string keys.
- Strings must consist of valid ASCII characters.
- Output is a byte sequence of the utf-8 encoded densely formatted JSON document.
Returns: unicode
object in Python 2,bytes
object in Python 3Output of serialize() should be explicitly converted to a string before passing to a JSON deserializer.
>>> my_object = my_workspec.serialize() >>> my_data_structure = json.loads(my_object.decode('utf-8')) >>> # or... >>> my_data_structure = json.loads(my_object, encoding='utf-8')
-
uid
()[source]¶ Get a unique identifier for this work specification.
Returns: hash value Generate a cryptographic hash of this work specification that is guaranteed to match that of another equivalent work specification. The returned string is a 64-character hexadecimal encoded SHA-256 hash digest of the serialized WorkSpec.
The definition of equivalence is likely to evolve, but currently means a work spec of the same version with the same named elements containing the same operations, dependencies, and parameters, as represented in the serialized version of the work specification. Note that this does not include checks on the actual contents of input files or anything that does not appear in the work specification directly. Also, the hash is lossy, so it is remotely conceivable that two specs could have the same hash. The work specs should be compared before making any expensive decisions based on work spec equivalence, such as with hash(workspec).
Element names probably shouldn’t be included in the unique identifying information (so that we can optimize out duplicated artifacts), but they are. A future API specification may add unique identification to the elements…
-
-
class
gmx.workflow.
WorkElement
(namespace='gmxapi', operation=None, params=None, depends=())[source]¶ Encapsulate an element of a work specification.
-
add_dependency
(element)[source]¶ Add another element as a dependency.
First move the provided element to the same WorkSpec, if not already here. Then, add to
depends
and update the WorkSpec.
-
classmethod
deserialize
(input, name=None, workspec=None)[source]¶ Create a new WorkElement object from a serialized representation.
Parameters: - input – a serialized WorkElement
- name – new element name (optional) (deprecated)
- workspec – an existing workspec to attach this element to (optional)
When subclasses become distinct, this factory function will need to do additional dispatching to create an object of the correct type. Alternatively, instead of subclassing, a slightly heavier single class may suffice, or more flexible duck typing might be better.
-
serialize
()[source]¶ Create a byte sequence representation of the work element.
The WorkElement class exists just to provide convenient handles in Python. The WorkSpec is not actually a container of WorkElement objects.
Returns: Byte sequence of utf-8 encoded JSON document. May need to be decoded if needed as a (Unicode) string.
-
Depends on gmx.exceptions, gmx.util
Core API¶
Gromacs core module¶
gmx.core 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.
This documentation is generated from docstrings exported by C++ extension code.
Functions¶
-
gmx.core.
from_tpr
(arg0: str) → gmx.core.MDSystem¶ Return a system container initialized from the given input record.
Classes¶
-
class
gmx.core.
Context
(self: gmx.core.Context) → None¶ Create a default execution context.
-
add_mdmodule
(self: gmx.core.Context, arg0: object) → None¶ Add an MD plugin for the simulation.
-
setMDArgs
(self: gmx.core.Context, arg0: gmx.core.MDArgs) → None¶ Set MD runtime parameters.
-
-
class
gmx.core.
MDArgs
(self: gmx.core.MDArgs) → None¶ Create an empty MDArgs object.
-
set
(self: gmx.core.MDArgs, arg0: dict) → None¶ Assign parameters in MDArgs from Python dict.
-
-
class
gmx.core.
MDSession
¶ -
close
(self: gmx.core.MDSession) → gmx.core.Status¶ Shut down the execution environment and close the session.
-
run
(self: gmx.core.MDSession) → gmx.core.Status¶ Run the simulation workflow
-
-
class
gmx.core.
MDSystem
¶ -
launch
(self: gmx.core.MDSystem, arg0: gmx.core.Context) → gmx.core.MDSession¶ Launch the configured workflow in the provided context.
-
-
class
gmx.core.
Status
¶ Holds status for API operations.
-
class
gmx.core.
TestModule
(self: gmx.core.TestModule) → None¶ Test module…