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
158 utilities.unlink_gmx(self.multi_ndx)
159 except (AttributeError, OSError):
160 pass
161
162
163
164
165
166 if 'G_mindist' in registry:
167
169 """Gromacs tool 'g_mindist' (with patch to handle multiple ndx files)."""
170 command_name = 'g_mindist'
171 registry['G_mindist'] = G_mindist
172
173 if 'G_dist' in registry:
174
175 - class G_dist(GromacsCommandMultiIndex):
176 """Gromacs tool 'g_dist' (with patch to handle multiple ndx files)."""
177 command_name = 'g_dist'
178 registry['G_dist'] = G_dist
179
180
181
182
183
184 for rec in config.load_scripts:
185 name, clsname, doc = rec
186 exec_name = os.path.basename(name)
187 registry[clsname] = type(clsname, (Command,),
188 {'command_name':name,
189 '__doc__': "External tool %(exec_name)r\n\n%(doc)s." % vars()})
190
191
192
193 globals().update(registry)
194 __all__ = registry.keys()
195
196
197 cls = clsname = name = rec = doc = None
198 del rec, name, cls, clsname, doc
199