gromacs.core
– Core functionality¶
Here the basic command class GromacsCommand
is defined. All Gromacs
command classes in gromacs.tools
are automatically generated from
it. The documentation of GromacsCommand
applies to all wrapped Gromacs
commands and should be read by anyone using this package.
Input and Output¶
Each command wrapped by either GromacsCommand
or Command
takes three additional keyword arguments: stdout, stderr, and
input. stdout and stderr determine how the command returns its own
output.
The input keyword is a string that is fed to the standard input of the
command (actually, subprocess.Popen.stdin
). Or, if it is not string-like
then we assume it’s actually a file-like object that we can read from, e.g. a
subprocess.Popen.stdout
or a File
.
By setting the stdout and stderr keywords appropriately, one can have the
output simply printed to the screen (use True
; this is the default,
although see below for the use of the capture_output
gromacs.environment
flag), capture in a python variable as a string for
further processing (use False
), write to a file (use a File
instance) or as input for another command (e.g. use the
subprocess.Popen.stdin
).
When writing setup- and analysis pipelines it can be rather cumbersome to have
the gromacs output on the screen. For these cases GromacsWrapper allows you to
change its behaviour globally. By setting the value of the
gromacs.environment
Flag
capture_output
to True
(in the GromacsWrapper
gromacs.environment.flags
registry)
import gromacs.environment
gromacs.environment.flags['capture_output'] = True
all commands will capture their output (like stderr = False
and stdout
= False
). Explicitly setting these keywords overrides the global
default. The default value for flags['capture_output']
is False
,
i.e. output is directed through STDOUT and STDERR.
Warning
One downside of flags['capture_output'] = True
is that it becomes much
harder to debug scripts unless the script is written in such a way to show
the output when the command fails. Therefore, it is advisable to only
capture output on well-tested scripts.
A third value of capture_output
is the value "file"
:
gromacs.environment.flags['capture_output'] = "file"
This writes the captured output to a file. The file name is specified in
flags['capture_output_filename'
and defaults to
“gromacs_captured_output.txt”. This file is over-written for each
command. In this way one can investigate the output from the last command
(presumably because it failed). STDOUT and STDERR are captured into this file
by default. STDERR is printed first and then STDOUT, which does not necessarily
reflect the order of output one would see on the screen. If your code captures
STDOUT for further processing then an uncaptured STDERR is written to the
capture file.
Note
There are some commands for which capturing output
(flags['capture_output'] = True
) might be problematic. If the command
produces a large or inifinite amount of data then a memory error will occur
because Python nevertheless stores the output internally first. Thus one
should avoid capturing progress output from
e.g. Mdrun
unless the output has been throttled
appropriately.
Classes¶
-
class
gromacs.core.
GromacsCommand
(*args, **kwargs)¶ Base class for wrapping a Gromacs tool.
Limitations: User must have sourced
GMXRC
so that the python script can inherit the environment and find the gromacs programs.The class doc string is dynamically replaced by the documentation of the gromacs command the first time the doc string is requested. If the tool is not available at the time (i.e., cannot be found on :env:`PATH`) then the generic doc string is shown and an
OSError
exception is only raised when the user is actually trying to the execute the command.Set up the command with gromacs flags as keyword arguments.
The following are generic instructions; refer to the Gromacs command usage information that should have appeared before this generic documentation.
As an example, a generic Gromacs command could use the following flags:
cmd = GromacsCommand('v', f=['md1.xtc','md2.xtc'], o='processed.xtc', t=200, ...)
which would correspond to running the command in the shell as
GromacsCommand -v -f md1.xtc md2.xtc -o processed.xtc -t 200
Gromacs command line arguments
Gromacs boolean switches (such as
-v
) are given as python positional arguments ('v'
) or as keyword argument (v=True
); note the quotes in the first case. Negating a boolean switch can be done with'nov'
,nov=True
orv=False
(and evennov=False
works as expected: it is the same asv=True
).Any Gromacs options that take parameters are handled as keyword arguments. If an option takes multiple arguments (such as the multi-file input
-f file1 file2 ...
) then the list of files must be supplied as a python list.If a keyword has the python value
None
then it will not be added to the Gromacs command line; this allows for flexible scripting if it is not known in advance if an input file is needed. In this case the default value of the gromacs tool is used.Keywords must be legal python keywords or the interpreter raises a
SyntaxError
but of course Gromacs commandline arguments are not required to be legal python. In this case “quote” the option with an underscore (_
) and the underscore will be silently stripped. For instance,-or
translates to the illegal keywordor
so it must be underscore-quoted:cmd(...., _or='mindistres.xvg')
Command execution
The command is executed with the
run()
method or by calling it as a function. The two next lines are equivalent:cmd(...) cmd.run(...)
When the command is run one can override options that were given at initialization or one can add additional ones. The same rules for supplying Gromacs flags apply as described above.
Non-Gromacs keyword arguments
The other keyword arguments (listed below) are not passed on to the Gromacs tool but determine how the command class behaves. They are only useful when instantiating a class, i.e. they determine how this tool behaves during all future invocations although it can be changed by settingfailuremode
. This is mostly of interest to developers.Keywords: - failure
determines how a failure of the gromacs command is treated; it can be one of the following:
- ‘raise’
raises GromacsError if command fails
- ‘warn’
issue a
GromacsFailureWarning
None
just continue silently
- doc : string
additional documentation (ignored) []
Changed in version 0.6.0: The doc keyword is now ignored (because it was not worth the effort to make it work with the lazy-loading of docs).
-
Popen
(*args, **kwargs)¶ Returns a special Popen instance (
PopenWithInput
).The instance has its input pre-set so that calls to
communicate()
will not need to supply input. This is necessary if one wants to chain the output from one command to an input from another.TODO: Write example.
-
commandline
(*args, **kwargs)¶ Returns the commandline that run() uses (without pipes).
-
failuremode
¶ mode determines how the GromacsCommand behaves during failure
It can be one of the following:
- ‘raise’
- raises GromacsError if command fails
- ‘warn’
- issue a
GromacsFailureWarning
None
- just continue silently
-
failuremodes
= ('raise', 'warn', None)¶ Available failure modes.
-
help
(long=False)¶ Print help; same as using
?
inipython
. long=True also gives call signature.
-
run
(*args, **kwargs)¶ Run the command; args/kwargs are added or replace the ones given to the constructor.
-
transform_args
(*args, **kwargs)¶ Combine arguments and turn them into gromacs tool arguments.
-
class
gromacs.core.
Command
(*args, **kwargs)¶ Wrap simple script or command.
Set up the command class.
The arguments can always be provided as standard positional arguments such as
"-c", "config.conf", "-o", "output.dat", "--repeats=3", "-v", "input.dat"
In addition one can also use keyword arguments such as
c="config.conf", o="output.dat", repeats=3, v=True
These are automatically transformed appropriately according to simple rules:
- Any single-character keywords are assumed to be POSIX-style options and will be prefixed with a single dash and the value separated by a space.
- Any other keyword is assumed to be a GNU-style long option and thus will be prefixed with two dashes and the value will be joined directly with an equals sign and no space.
If this does not work (as for instance for the options of the UNIX
find
command) then provide options and values in the sequence of positional arguments.-
Popen
(*args, **kwargs)¶ Returns a special Popen instance (
PopenWithInput
).The instance has its input pre-set so that calls to
communicate()
will not need to supply input. This is necessary if one wants to chain the output from one command to an input from another.TODO: Write example.
-
__call__
(*args, **kwargs)¶ Run command with the given arguments:
rc,stdout,stderr = command(*args, input=None, **kwargs)
All positional parameters args and all gromacs kwargs are passed on to the Gromacs command. input and output keywords allow communication with the process via the python subprocess module.
Arguments: - input : string, sequence
to be fed to the process’ standard input; elements of a sequence are concatenated with newlines, including a trailing one [
None
]- stdin
None
or automatically set toPIPE
if input given [None
]- stdout
how to handle the program’s stdout stream [
None
]- filehandle
anything that behaves like a file object
None
orTrue
to see output on screen
False
orPIPE
returns the output as a string in the stdout parameter
- stderr
how to handle the stderr stream [
None
]STDOUT
merges standard error with the standard out stream
False
orPIPE
returns the output as a string in the stderr return parameter
None
orTrue
keeps it on stderr (and presumably on screen)
Depending on the value of the GromacsWrapper flag
gromacs.environment.flags```['capture_output']`
the above default behaviour can be different.All other kwargs are passed on to the Gromacs tool.
Returns: The shell return code rc of the command is always returned. Depending on the value of output, various strings are filled with output from the command.
Notes: In order to chain different commands via pipes one must use the special
PopenWithInput
object (seeGromacsCommand.Popen()
method) instead of the simple call described here and first construct the pipeline explicitly and then call thePopenWithInput.communicate()
method.STDOUT
andPIPE
are objects provided by thesubprocess
module. Any python stream can be provided and manipulated. This allows for chaining of commands. Usefrom subprocess import PIPE, STDOUT
when requiring these special streams (and the special boolean switches
True
/False
cannot do what you need.)(TODO: example for chaining commands)
-
command_name
= None¶ Derive a class from command; typically one only has to set command_name to the name of the script or executable. The full path is required if it cannot be found by searching
PATH
.
-
help
(long=False)¶ Print help; same as using
?
inipython
. long=True also gives call signature.
-
run
(*args, **kwargs)¶ Run the command; args/kwargs are added or replace the ones given to the constructor.
-
transform_args
(*args, **kwargs)¶ Transform arguments and return them as a list suitable for Popen.
-
class
gromacs.core.
PopenWithInput
(*args, **kwargs)¶ Popen class that knows its input.
- Set up the instance, including all the input it shoould receive.
- Call
PopenWithInput.communicate()
later.
Note
Some versions of python have a bug in the subprocess module ( issue 5179 ) which does not clean up open file descriptors. Eventually code (such as this one) fails with the error:
OSError: [Errno 24] Too many open filesA weak workaround is to increase the available number of open file descriptors with
ulimit -n 2048
and run analysis in different scripts.Initialize with the standard
subprocess.Popen
arguments.Keywords: - input
string that is piped into the command
-
communicate
(use_input=True)¶ Run the command, using the input that was set up on __init__ (for use_input =
True
)