Package gromacs :: Package analysis :: Package plugins :: Module distances
[hide private]
[frames] | no frames]

Source Code for Module gromacs.analysis.plugins.distances

  1  # $Id$ 
  2  # Copyright (c) 2009 Oliver Beckstein <orbeckst@gmail.com> 
  3  # Released under the GNU Public License 3 (or higher, your choice) 
  4  # See the file COPYING for details. 
  5   
  6  """ 
  7  Distance plugin 
  8  =============== 
  9   
 10  Time series of a selected set of distances. 
 11   
 12  Plugin class 
 13  ------------ 
 14   
 15  .. autoclass:: Distances 
 16     :members: worker_class 
 17     :undoc-members: 
 18   
 19  Worker class 
 20  ------------ 
 21   
 22  The worker class performs the analysis. 
 23   
 24  .. autoclass:: _Distances 
 25     :members: 
 26   
 27   
 28  """ 
 29  __docformat__ = "restructuredtext en" 
 30   
 31  import sys 
 32  import os.path 
 33  import warnings 
 34  import subprocess 
 35  import tempfile 
 36  import numpy 
 37   
 38  import gromacs 
 39  from gromacs.utilities import AttributeDict, asiterable 
 40  from gromacs.formats import XVG 
 41  from gromacs.analysis.core import Worker, Plugin 
 42   
 43   
 44  # Worker classes that are registered via Plugins (see below) 
 45  # ---------------------------------------------------------- 
 46  # These must be defined before the plugins. 
 47   
48 -class _Distances(Worker):
49 """Analysis of distances. 50 51 See :class:`Distances` for usage. 52 53 Also used as a base class for :class:`mindistances._MinDistances`. 54 """ 55 56 #: list of results (not used at the moment, see _register_hook()) 57 names = ["distance"] 58 59 #: dict of labels for the plot x-axis; one for each result 60 xlabels = {"distance": r"time $t/$ns", 61 "contacts": r"time $t/$ns", 62 } 63 #: dict of labels for the plot y-axis; one for each result 64 ylabels = {"distance": r"distance $d/$nm", 65 "contacts": r"contacts $N$", 66 } 67 68 default_plot_columns = [0, 1] # plot time and distance only 69
70 - def __init__(self,**kwargs):
71 """Set up customized distance analysis. 72 73 :Arguments: 74 groups : list of index group names 75 The first entry is the *primary group*. All other entries 76 are *secondary groups* and the plugin calculates the minimum distance 77 between members of the primary group and the members of each 78 secondary group. 79 ndx : index filename or list 80 All index files that contain the listed groups. 81 cutoff : float 82 A contact is recorded if the distance is <cutoff [0.6 nm] 83 """ 84 # Note: this init is also used for mindistances._MinDistance 85 # thus we have the add. file contacts that is not used otherwise 86 # specific setup 87 indexgroups = kwargs.pop('groups',None) 88 if indexgroups is None or len(indexgroups) < 2 or type(indexgroups) is str: 89 raise ValueError("groups must be a list with at least a primary and secondary group") 90 ndx = kwargs.pop('ndx', None) 91 cutoff = kwargs.pop('cutoff', 0.6) # default: 0.6 nm 92 93 # super class: do this before setting any instance attributes 94 # sets self.simulation if available! 95 super(_Distances,self).__init__(**kwargs) 96 97 self.parameters.indexgroups = indexgroups 98 self.parameters.ndx = ndx 99 self.parameters.cutoff = cutoff 100 101 if not self.simulation is None: 102 self._register_hook()
103
104 - def _register_hook(self, **kwargs):
105 """Run when registering; requires simulation. 106 107 Defines output files (note that we overwrite the 108 parameters.filenames and figname that super might have set). 109 """ 110 111 super(_Distances, self)._register_hook(**kwargs) 112 assert not self.simulation is None 113 114 # output filenames for g_dist 115 self.parameters.filenames = { 116 'distance': self.plugindir('distance.xvg'), 117 } 118 119 # default filename for the combined plot 120 self.parameters.figname = self.figdir('distances')
121 122 123 # override 'API' methods of base class 124
125 - def run(self,**kwargs):
126 """Run ``g_dist `` to compute distances between A and B groups. 127 128 Additional arguments can be provided (e.g. ``-b`` or ``-e``) 129 but an error will result if one tries to set parameters that 130 are already being set by the method itself such as ``-s`` or 131 ``-d``; one must to provide the appropriate values to the 132 class constructor. 133 134 If the primary output file already exists then no data are generated 135 and the method returns immediately unless one sets *force* = ``True``. 136 """ 137 force = kwargs.pop('force',False) 138 if not force and \ 139 self.check_file_exists(self.parameters.filenames['distance'], resolve='warn'): 140 return 141 indexgroups = self.parameters.indexgroups 142 ngroups = len(indexgroups) - 1 # number of secondary groups 143 if ngroups != 1: 144 raise ValueError("g_dist can only compute the distance between a primary and a secondary group") 145 gromacs.g_dist(s=self.simulation.tpr, n=self.parameters.ndx, f=self.simulation.xtc, 146 o=self.parameters.filenames['distance'], 147 input=indexgroups, 148 **kwargs)
149
150 - def analyze(self,**kwargs):
151 """Make data files available as numpy arrays.""" 152 results = AttributeDict() 153 for name, f in self.parameters.filenames.items(): 154 results[name] = XVG(f) 155 self.results = results 156 return results
157
158 - def plot(self, names=None, **kwargs):
159 """Plot the selected data. 160 161 :Arguments: 162 names : string or list 163 Selects which results should be plotted. ``None`` plots all 164 in separate graphs. 165 columns : list 166 Which columns to plot; typically the default is ok. 167 figure 168 - ``True``: save figures in the given formats 169 - "name.ext": save figure under this filename (``ext`` -> format) 170 - ``False``: only show on screen 171 formats : sequence 172 sequence of all formats that should be saved [('png', 'pdf')] 173 callbacks : dict 174 **hack**: provide a dictionary that contains callback functions 175 to customize the plot. They will be called at the end of 176 generating a subplot and must be indexed by *name*. They will 177 be called with the keyword arguments *name* and *axis* 178 (current subplot axis object):: 179 180 callback(name=name, axis=ax) 181 kwargs 182 All other keyword arguments are directly passed to 183 meth:`gromacs.formats.XVG.plot`. 184 """ 185 import pylab 186 187 figure = kwargs.pop('figure', False) 188 extensions = kwargs.pop('formats', ('pdf','png')) 189 callbacks = kwargs.pop('callbacks', None) 190 def ps2ns(a): 191 """Transform first column (in ps) to ns.""" 192 _a = numpy.array(a, copy=True) 193 _a[0] *= 0.001 194 return _a
195 kwargs.setdefault('transform', ps2ns) 196 kwargs.setdefault('columns', self.default_plot_columns) 197 198 if names is None: 199 names = self.results.keys() 200 names = asiterable(names) # this is now a list (hopefully of strings) 201 ngraphs = len(names) 202 for plotNum, name in enumerate(names): 203 plotNum += 1 204 ax = pylab.subplot(1, ngraphs, plotNum) 205 try: 206 data = self.results[name].plot(**kwargs) # results are XVG objects with plot method 207 except KeyError: 208 ax.close() 209 raise KeyError('name = %r not known, choose one of %r' % (name, self.results.keys())) 210 #pylab.title(r'Distances: %s' % name) 211 pylab.xlabel(self.xlabels[name]) 212 pylab.ylabel(self.ylabels[name]) 213 214 # hack: callbacks for customization 215 if not callbacks is None: 216 try: 217 callbacks[name](name=name, axis=ax) 218 except KeyError: 219 pass 220 221 # pylab.legend(loc='best') 222 if figure is True: 223 for ext in extensions: 224 self.savefig(ext=ext) 225 elif figure: 226 self.savefig(filename=figure)
227 228 229 230 231 # Public classes that register the worker classes 232 #------------------------------------------------ 233
234 -class Distances(Plugin):
235 """*Distances* plugin. 236 237 The distance between the center of mass of two index groups are 238 calculated for each time step and written to files. 239 240 .. class:: Distances(groups, ndx, [cutoff, [, name[, simulation]]]) 241 242 :Arguments: 243 name : string 244 plugin name (used to access it) 245 simulation : instance 246 The :class:`gromacs.analysis.Simulation` instance that owns the plugin. 247 groups : list of index group names 248 The first entry is the *primary group*, the second is the 249 *secondary group. 250 ndx : index filename or list 251 All index files that contain the listed groups. 252 cutoff : float 253 A contact is recorded if the distance is <cutoff [0.6 nm] 254 255 Example: 256 257 Generate index files with the groups of interest, for instance 258 with :class:`gromacs.cbook.IndexBuilder`:: 259 260 from gromacs.cbook import IndexBuilder 261 A_grp, A_ndx = IndexBuilder(tpr, ['@a 62549 & r NA'], names=['Na1_ion'], offset=-9, 262 out_ndx='Na1.ndx', name_all="Na1").combine() 263 B = IndexBuilder(tpr, ['S312:OG','T313:OG1','A38:O','I41:O','A309:O'], offset=-9, 264 out_ndx='Na1_site.ndx', name_all="Na1_site") 265 B_grp, B_ndx = B.combine() 266 all_ndx_files = [A_ndx, B_ndx] 267 268 To calculate the distance between "Na1" and the "Na1_site", create an instance with 269 the appropriate parameters and add them to a :class:`gromacs.analysis.Simulation` instance:: 270 271 dist_Na1_site = Distances(name='Dsite', groups=['Na1', 'Na1_site'], ndx=all_ndx_files) 272 S.add_plugin(dist_Na1_site) 273 274 275 """ 276 worker_class = _Distances
277