Package generic_fns :: Module grace
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.grace

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2005 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  from os import system 
 24  from re import match 
 25   
 26   
27 -class Grace:
28 - def __init__(self, relax):
29 """Operations, functions, etc common to the different model-free analysis methods.""" 30 31 self.relax = relax
32 33
34 - def determine_graph_type(self):
35 """Function for determining if the graph is of type xy, xydy, xydx, or xydxdy.""" 36 37 # Initial flags. 38 x_errors = 0 39 y_errors = 0 40 41 # Loop over the data. 42 for i in xrange(len(self.data)): 43 # X-axis errors. 44 if self.x_data_type != 'res' and self.data[i][1] != None: 45 x_errors = 1 46 47 # Y-axis errors. 48 if self.data[i][3] != None: 49 y_errors = 1 50 51 # Plot of values. 52 if self.plot_data == 'value': 53 # xy plot with errors along both axes. 54 if x_errors and y_errors: 55 self.graph_type = 'xydxdy' 56 57 # xy plot with errors along the Y-axis. 58 elif y_errors: 59 self.graph_type = 'xydy' 60 61 # xy plot with errors along the X-axis. 62 elif x_errors: 63 self.graph_type = 'xydx' 64 65 # xy plot with no errors. 66 else: 67 self.graph_type = 'xy' 68 69 # Plot of errors. 70 elif self.plot_data == 'error': 71 # xy plot of residue number vs error. 72 if self.x_data_type == 'res' and y_errors: 73 self.graph_type = 'xy' 74 75 # xy plot of error vs error. 76 elif x_errors and y_errors: 77 self.graph_type = 'xy' 78 79 # Invalid argument combination. 80 else: 81 raise RelaxError, "When plotting errors, the errors must exist." 82 83 # Plot of simulation values. 84 else: 85 # xy plot with no errors. 86 self.graph_type = 'xy'
87 88
89 - def get_data(self):
90 """Function for getting all the xy data.""" 91 92 # Initialise. 93 self.data = [] 94 95 # Loop over the residues. 96 for i in xrange(len(self.relax.data.res[self.run])): 97 # Remap the data structure 'self.relax.data.res[self.run][i]'. 98 data = self.relax.data.res[self.run][i] 99 100 # Skip the residue if there is no match to 'self.res_num' (unless it is None). 101 if type(self.res_num) == int: 102 if not data.num == self.res_num: 103 continue 104 elif type(self.res_num) == str: 105 if not match(self.res_num, `data.num`): 106 continue 107 108 # Skip the residue if there is no match to 'self.res_name' (unless it is None). 109 if self.res_name != None: 110 if not match(self.res_name, data.name): 111 continue 112 113 # Number of data points per residue. 114 if self.plot_data == 'sim': 115 points = self.relax.data.sim_number[self.run] 116 else: 117 points = 1 118 119 # Loop over the data points. 120 for j in xrange(points): 121 # Initialise an empty array for the individual residue data. 122 res_data = [None, None, None, None] 123 124 # Residue number on the x-axis. 125 if self.x_data_type == 'res': 126 res_data[0] = data.num 127 128 # Parameter value for the x-axis. 129 else: 130 # Get the x-axis values and errors. 131 if self.plot_data == 'sim': 132 res_data[0], res_data[1] = self.x_return_value(self.run, i, self.x_data_type, sim=j) 133 else: 134 res_data[0], res_data[1] = self.x_return_value(self.run, i, self.x_data_type) 135 136 # Get the y-axis values and errors. 137 if self.plot_data == 'sim': 138 res_data[2], res_data[3] = self.y_return_value(self.run, i, self.y_data_type, sim=j) 139 else: 140 res_data[2], res_data[3] = self.y_return_value(self.run, i, self.y_data_type) 141 142 # Go to the next residue if there is missing data. 143 if res_data[0] == None or res_data[2] == None: 144 continue 145 146 # X-axis conversion factors. 147 if self.x_data_type != 'res': 148 res_data[0] = res_data[0] / self.x_return_conversion_factor(self.x_data_type) 149 if res_data[1]: 150 res_data[1] = res_data[1] / self.x_return_conversion_factor(self.x_data_type) 151 152 # Y-axis conversion factors. 153 res_data[2] = res_data[2] / self.y_return_conversion_factor(self.y_data_type) 154 if res_data[3]: 155 res_data[3] = res_data[3] / self.y_return_conversion_factor(self.y_data_type) 156 157 # Append the array to the full data structure. 158 self.data.append(res_data)
159 160
161 - def view(self, file=None, dir=None, grace_exe='xmgrace'):
162 """Function for running Grace.""" 163 164 # File path. 165 self.file_path = self.relax.IO.file_path(file, dir) 166 167 # Run Grace. 168 system(grace_exe + " " + self.file_path + " &")
169 170
171 - def write(self, run=None, x_data_type='res', y_data_type=None, res_num=None, res_name=None, plot_data='value', file=None, dir=None, force=0):
172 """Function for writing data to a file.""" 173 174 # Arguments. 175 self.run = run 176 self.x_data_type = x_data_type 177 self.y_data_type = y_data_type 178 self.res_num = res_num 179 self.res_name = res_name 180 self.plot_data = plot_data 181 182 # Test if the run exists. 183 if not self.run in self.relax.data.run_names: 184 raise RelaxNoRunError, self.run 185 186 # Test if the sequence data is loaded. 187 if not self.relax.data.res.has_key(self.run): 188 raise RelaxNoSequenceError, self.run 189 190 # Test if the residue number is a valid regular expression. 191 if type(self.res_num) == str: 192 try: 193 compile(self.res_num) 194 except: 195 raise RelaxRegExpError, ('residue number', self.res_num) 196 197 # Test if the residue name is a valid regular expression. 198 if self.res_name: 199 try: 200 compile(self.res_name) 201 except: 202 raise RelaxRegExpError, ('residue name', self.res_name) 203 204 # Test if the plot_data argument is one of 'value', 'error', or 'sim'. 205 if self.plot_data not in ['value', 'error', 'sim']: 206 raise RelaxError, "The plot data argument " + `self.plot_data` + " must be set to either 'value', 'error', 'sim'." 207 208 # Test if the simulations exist. 209 if self.plot_data == 'sim' and (not hasattr(self.relax.data, 'sim_number') or not self.relax.data.sim_number.has_key(self.run)): 210 raise RelaxNoSimError, self.run 211 212 # Open the file for writing. 213 self.file = self.relax.IO.open_write_file(file, dir, force) 214 215 # Function type. 216 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)] 217 218 # Specific value and error, conversion factor, and units returning functions. 219 self.x_return_value = self.y_return_value = self.relax.specific_setup.setup('return_value', function_type) 220 self.x_return_conversion_factor = self.y_return_conversion_factor = self.relax.specific_setup.setup('return_conversion_factor', function_type) 221 self.x_return_units = self.y_return_units = self.relax.specific_setup.setup('return_units', function_type) 222 self.x_return_grace_string = self.y_return_grace_string = self.relax.specific_setup.setup('return_grace_string', function_type) 223 224 # Test if the X-axis data type is a minimisation statistic. 225 if self.x_data_type != 'res' and self.relax.generic.minimise.return_data_name(self.x_data_type): 226 self.x_return_value = self.relax.generic.minimise.return_value 227 self.x_return_conversion_factor = self.relax.generic.minimise.return_conversion_factor 228 self.x_return_units = self.relax.generic.minimise.return_units 229 self.x_return_grace_string = self.relax.generic.minimise.return_grace_string 230 231 # Test if the Y-axis data type is a minimisation statistic. 232 if self.relax.generic.minimise.return_data_name(self.y_data_type): 233 self.y_return_value = self.relax.generic.minimise.return_value 234 self.y_return_conversion_factor = self.relax.generic.minimise.return_conversion_factor 235 self.y_return_units = self.relax.generic.minimise.return_units 236 self.y_return_grace_string = self.relax.generic.minimise.return_grace_string 237 238 # Get the data. 239 self.get_data() 240 241 # Determine the graph type (ie xy, xydy, xydx, or xydxdy). 242 self.determine_graph_type() 243 244 # Write the header. 245 self.write_header() 246 247 # Write the data. 248 self.write_data() 249 250 # Close the file. 251 self.file.close()
252 253
254 - def write_data(self):
255 """Write the data into the grace file.""" 256 257 # Loop over the data. 258 for i in xrange(len(self.data)): 259 # Graph type xy. 260 if self.graph_type == 'xy': 261 # Write the data. 262 self.file.write("%-30s%-30s\n" % (self.data[i][0], self.data[i][2])) 263 264 # Graph type xydy. 265 elif self.graph_type == 'xydy': 266 # Catch y-axis errors of None. 267 y_error = self.data[i][3] 268 if y_error == None: 269 y_error = 0.0 270 271 # Write the data. 272 self.file.write("%-30s%-30s%-30s\n" % (self.data[i][0], self.data[i][2], y_error)) 273 274 # Graph type xydxdy. 275 elif self.graph_type == 'xydxdy': 276 # Catch x-axis errors of None. 277 x_error = self.data[i][1] 278 if x_error == None: 279 x_error = 0.0 280 281 # Catch y-axis errors of None. 282 y_error = self.data[i][3] 283 if y_error == None: 284 y_error = 0.0 285 286 # Write the data. 287 self.file.write("%-30s%-30s%-30s%-30s\n" % (self.data[i][0], self.data[i][2], x_error, y_error)) 288 289 # End of graph 0, set 0. 290 self.file.write("&\n")
291 292
293 - def write_header(self):
294 """Write the grace header.""" 295 296 # Graph G0. 297 self.file.write("@with g0\n") 298 299 # X axis start and end. 300 if self.x_data_type == 'res': 301 self.file.write("@ world xmin " + `self.relax.data.res[self.run][0].num - 1` + "\n") 302 self.file.write("@ world xmax " + `self.relax.data.res[self.run][-1].num + 1` + "\n") 303 304 # X-axis label. 305 if self.x_data_type == 'res': 306 self.file.write("@ xaxis label \"Residue number\"") 307 else: 308 # Get the units. 309 units = self.x_return_units(self.x_data_type) 310 311 # Label. 312 if units: 313 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\\N (" + units + ")\"\n") 314 else: 315 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\"\n") 316 317 # X-axis specific settings. 318 self.file.write("@ xaxis label char size 1.48\n") 319 self.file.write("@ xaxis tick major size 0.75\n") 320 self.file.write("@ xaxis tick major linewidth 0.5\n") 321 self.file.write("@ xaxis tick minor linewidth 0.5\n") 322 self.file.write("@ xaxis tick minor size 0.45\n") 323 self.file.write("@ xaxis ticklabel char size 1.00\n") 324 325 # Y-axis label. 326 units = self.y_return_units(self.y_data_type) 327 if units: 328 self.file.write("@ yaxis label \"" + self.y_return_grace_string(self.y_data_type) + "\\N (" + units + ")\"\n") 329 else: 330 self.file.write("@ yaxis label \"" + self.y_return_grace_string(self.y_data_type) + "\"\n") 331 332 # Y-axis specific settings. 333 self.file.write("@ yaxis label char size 1.48\n") 334 self.file.write("@ yaxis tick major size 0.75\n") 335 self.file.write("@ yaxis tick major linewidth 0.5\n") 336 self.file.write("@ yaxis tick minor linewidth 0.5\n") 337 self.file.write("@ yaxis tick minor size 0.45\n") 338 self.file.write("@ yaxis ticklabel char size 1.00\n") 339 340 # Frame. 341 self.file.write("@ frame linewidth 0.5\n") 342 343 # Symbols. 344 self.file.write("@ s0 symbol 9\n") 345 self.file.write("@ s0 symbol size 1.00\n") 346 self.file.write("@ s0 symbol fill pattern 1\n") 347 self.file.write("@ s0 symbol linewidth 0.5\n") 348 self.file.write("@ s0 line linestyle 0\n") 349 350 # Error bars. 351 self.file.write("@ s0 errorbar size 0.5\n") 352 self.file.write("@ s0 errorbar linewidth 0.5\n") 353 self.file.write("@ s0 errorbar riser linewidth 0.5\n") 354 355 # Graph 0, set 0. 356 self.file.write("@target G0.S0\n") 357 self.file.write("@type " + self.graph_type + "\n")
358