1
2
3
4
5
6 """
7 :mod:`gromacs.tools` -- Gromacs commands classes
8 ================================================
9
10 A Gromacs command class can be thought of as a factory function that
11 produces an instance of a gromacs command
12 (:class:`gromacs.core.GromacsCommand`) with initial default values.
13
14 By convention, a class has the capitalized name of the corresponding Gromacs
15 tool; dots are replaced by underscores to make it a valid python identifier.
16
17 The list of Gromacs tools to be loaded is configured in
18 :data:`gromacs.config.gmx_tool_groups`.
19
20 It is also possible to extend the basic commands and patch in additional
21 functionality. For example, the :class:`GromacsCommandMultiIndex` class makes a
22 command accept multiple index files and concatenates them on the fly; the
23 behaviour mimics Gromacs' "multi-file" input that has not yet been enabled for
24 all tools.
25
26 .. autoclass:: GromacsCommandMultiIndex
27 :members: run, _fake_multi_ndx, __del__
28
29 Example
30 -------
31
32 In this example we create two instances of the :class:`gromacs.tools.Trjconv` command (which
33 runs the Gromacs ``trjconv`` command)::
34
35 import gromacs.tools as tools
36
37 trjconv = tools.Trjconv()
38 trjconv_compact = tools.Trjconv(ur='compact', center=True, boxcenter='tric', pbc='mol',
39 input=('protein','system'),
40 doc="Returns a compact representation of the system centered on the protein")
41
42 The first one, ``trjconv``, behaves as the standard commandline tool but the
43 second one, ``trjconv_compact``, will by default create a compact
44 representation of the input data by taking into account the shape of the unit
45 cell. Of course, the same effect can be obtained by providing the corresponding
46 arguments to ``trjconv`` but by naming the more specific command differently
47 one can easily build up a library of small tools that will solve a specifi,
48 repeatedly encountered problem reliably. This is particularly helpful when doing
49 interactive work.
50
51 Gromacs tools
52 -------------
53 .. The docs for the tool classes are auto generated.
54 """
55
56 __docformat__ = "restructuredtext en"
57
58 import os.path
59 import tempfile
60
61 import config
62 from core import GromacsCommand, Command
63 import utilities
64
65
66
67 registry = {}
68
69
70
71
72
73 for name in config.load_tools:
74
75 clsname = name.replace('.','_').replace('-','_').capitalize()
76 cls = type(clsname, (GromacsCommand,), {'command_name':name,
77 '__doc__': "Gromacs tool %(name)r." % vars()})
78 registry[clsname] = cls
79
80
81
82
83
84
85
86
89 """Initialize instance.
90
91 1) Sets up the combined index file.
92 2) Inititialize :class:`~gromacs.core.GromacsCommand` with the
93 new index file.
94
95 See the documentation for :class:`gromacs.core.GromacsCommand` for details.
96 """
97 kwargs = self._fake_multi_ndx(**kwargs)
98 super(GromacsCommandMultiIndex, self).__init__(**kwargs)
99
100 - def run(self,*args,**kwargs):
104
106 """Combine multiple index file into a single one and return appropriate kwargs.
107
108 Calling the method combines multiple index files into a a single
109 temporary one so that Gromacs tools that do not (yet) support multi
110 file input for index files can be used transparently as if they did.
111
112 If a temporary index file is required then it is deleted once the
113 object is destroyed.
114
115 :Returns:
116 The method returns the input keyword arguments with the necessary
117 changes to use the temporary index files.
118
119 :Keywords:
120 Only the listed keywords have meaning for the method:
121
122 *n* : filename or list of filenames
123 possibly multiple index files; *n* is replaced by the name of
124 the temporary index file.
125 *s* : filename
126 structure file (tpr, pdb, ...) or ``None``; if a structure file is
127 supplied then the Gromacs default index groups are automatically added
128 to the temporary indexs file.
129
130 :Example:
131 Used in derived classes that replace the standard
132 :meth:`run` (or :meth:`__init__`) methods with something like::
133
134 def run(self,*args,**kwargs):
135 kwargs = self._fake_multi_ndx(**kwargs)
136 return super(G_mindist, self).run(*args, **kwargs)
137
138 """
139 ndx = kwargs.get('n')
140 if not (ndx is None or type(ndx) is str):
141 if len(ndx) > 1:
142
143
144
145 fd, self.multi_ndx = tempfile.mkstemp(suffix='.ndx', prefix='multi_')
146 make_ndx = Make_ndx(f=kwargs.get('s'), n=ndx)
147 rc,out,err = make_ndx(o=self.multi_ndx, input=['q'],
148 stdout=False, stderr=False)
149 self.orig_ndx = ndx
150 kwargs['n'] = self.multi_ndx
151 return kwargs
152
154 """Clean up temporary multi-index files if they were used."""
155
156 try:
157 from utilities import unlink_gmx
158
159 unlink_gmx(self.multi_ndx)
160 except (AttributeError, OSError):
161 pass
162
163
164
165
166
167 if 'G_mindist' in registry:
168
170 """Gromacs tool 'g_mindist' (with patch to handle multiple ndx files)."""
171 command_name = 'g_mindist'
172 registry['G_mindist'] = G_mindist
173
174 if 'G_dist' in registry:
175
176 - class G_dist(GromacsCommandMultiIndex):
177 """Gromacs tool 'g_dist' (with patch to handle multiple ndx files)."""
178 command_name = 'g_dist'
179 registry['G_dist'] = G_dist
180
181
182
183
184
185 for rec in config.load_scripts:
186 name, clsname, doc = rec
187 exec_name = os.path.basename(name)
188 registry[clsname] = type(clsname, (Command,),
189 {'command_name':name,
190 '__doc__': "External tool %(exec_name)r\n\n%(doc)s." % vars()})
191
192
193
194 globals().update(registry)
195 __all__ = registry.keys()
196
197
198 cls = clsname = name = rec = doc = None
199 del rec, name, cls, clsname, doc
200