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

Source Code for Module generic_fns.grace

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2006 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 Numeric import array 
 24  from os import system 
 25  from re import match 
 26   
 27   
28 -class Grace:
29 - def __init__(self, relax):
30 """Operations, functions, etc common to the different model-free analysis methods.""" 31 32 self.relax = relax
33 34
35 - def determine_graph_type(self):
36 """Function for determining if the graph is of type xy, xydy, xydx, or xydxdy.""" 37 38 # Initial flags. 39 x_errors = 0 40 y_errors = 0 41 42 # Loop over the data. 43 for i in xrange(len(self.data)): 44 # X-axis errors. 45 if self.x_data_type != 'res' and self.data[i][3] != None: 46 x_errors = 1 47 48 # Y-axis errors. 49 if self.data[i][5] != None: 50 y_errors = 1 51 52 # Plot of values. 53 if self.plot_data == 'value': 54 # xy plot with errors along both axes. 55 if x_errors and y_errors: 56 self.graph_type = 'xydxdy' 57 58 # xy plot with errors along the Y-axis. 59 elif y_errors: 60 self.graph_type = 'xydy' 61 62 # xy plot with errors along the X-axis. 63 elif x_errors: 64 self.graph_type = 'xydx' 65 66 # xy plot with no errors. 67 else: 68 self.graph_type = 'xy' 69 70 # Plot of errors. 71 elif self.plot_data == 'error': 72 # xy plot of residue number vs error. 73 if self.x_data_type == 'res' and y_errors: 74 self.graph_type = 'xy' 75 76 # xy plot of error vs error. 77 elif x_errors and y_errors: 78 self.graph_type = 'xy' 79 80 # Invalid argument combination. 81 else: 82 raise RelaxError, "When plotting errors, the errors must exist." 83 84 # Plot of simulation values. 85 else: 86 # xy plot with no errors. 87 self.graph_type = 'xy'
88 89
90 - def get_data(self):
91 """Function for getting all the xy data.""" 92 93 # Initialise. 94 self.data = [] 95 96 # Loop over the residues. 97 for i in xrange(len(self.relax.data.res[self.run])): 98 # Remap the data structure 'self.relax.data.res[self.run][i]'. 99 data = self.relax.data.res[self.run][i] 100 101 # Skip the residue if there is no match to 'self.res_num' (unless it is None). 102 if type(self.res_num) == int: 103 if not data.num == self.res_num: 104 continue 105 elif type(self.res_num) == str: 106 if not match(self.res_num, `data.num`): 107 continue 108 109 # Skip the residue if there is no match to 'self.res_name' (unless it is None). 110 if self.res_name != None: 111 if not match(self.res_name, data.name): 112 continue 113 114 # Skip deselected residues. 115 if not data.select: 116 continue 117 118 # Number of data points per residue. 119 if self.plot_data == 'sim': 120 points = self.relax.data.sim_number[self.run] 121 else: 122 points = 1 123 124 # Loop over the data points. 125 for j in xrange(points): 126 # Initialise an empty array for the individual residue data. 127 res_data = [data.num, data.name, None, None, None, None] 128 129 # Residue number on the x-axis. 130 if self.x_data_type == 'res': 131 res_data[2] = data.num 132 133 # Parameter value for the x-axis. 134 else: 135 # Get the x-axis values and errors. 136 if self.plot_data == 'sim': 137 res_data[2], res_data[3] = self.x_return_value(self.run, i, self.x_data_type, sim=j) 138 else: 139 res_data[2], res_data[3] = self.x_return_value(self.run, i, self.x_data_type) 140 141 # Get the y-axis values and errors. 142 if self.plot_data == 'sim': 143 res_data[4], res_data[5] = self.y_return_value(self.run, i, self.y_data_type, sim=j) 144 else: 145 res_data[4], res_data[5] = self.y_return_value(self.run, i, self.y_data_type) 146 147 # Go to the next residue if there is missing data. 148 if res_data[2] == None or res_data[4] == None: 149 continue 150 151 # X-axis conversion factors. 152 if self.x_data_type != 'res': 153 res_data[2] = array(res_data[2]) / self.x_return_conversion_factor(self.x_data_type) 154 if res_data[3]: 155 res_data[3] = array(res_data[3]) / self.x_return_conversion_factor(self.x_data_type) 156 157 # Y-axis conversion factors. 158 res_data[4] = array(res_data[4]) / self.y_return_conversion_factor(self.y_data_type) 159 if res_data[5]: 160 res_data[5] = array(res_data[5]) / self.y_return_conversion_factor(self.y_data_type) 161 162 # Append the array to the full data structure. 163 self.data.append(res_data)
164 165
166 - def view(self, file=None, dir=None, grace_exe='xmgrace'):
167 """Function for running Grace.""" 168 169 # Test the binary file string corresponds to a valid executable. 170 self.relax.IO.test_binary(grace_exe) 171 172 # File path. 173 self.file_path = self.relax.IO.file_path(file, dir) 174 175 # Run Grace. 176 system(grace_exe + " " + self.file_path + " &")
177 178
179 - def write(self, run=None, x_data_type='res', y_data_type=None, res_num=None, res_name=None, plot_data='value', norm=1, file=None, dir=None, force=0):
180 """Function for writing data to a file.""" 181 182 # Arguments. 183 self.run = run 184 self.x_data_type = x_data_type 185 self.y_data_type = y_data_type 186 self.res_num = res_num 187 self.res_name = res_name 188 self.plot_data = plot_data 189 self.norm = norm 190 191 # Test if the run exists. 192 if not self.run in self.relax.data.run_names: 193 raise RelaxNoRunError, self.run 194 195 # Test if the sequence data is loaded. 196 if not self.relax.data.res.has_key(self.run): 197 raise RelaxNoSequenceError, self.run 198 199 # Test if the residue number is a valid regular expression. 200 if type(self.res_num) == str: 201 try: 202 compile(self.res_num) 203 except: 204 raise RelaxRegExpError, ('residue number', self.res_num) 205 206 # Test if the residue name is a valid regular expression. 207 if self.res_name: 208 try: 209 compile(self.res_name) 210 except: 211 raise RelaxRegExpError, ('residue name', self.res_name) 212 213 # Test if the plot_data argument is one of 'value', 'error', or 'sim'. 214 if self.plot_data not in ['value', 'error', 'sim']: 215 raise RelaxError, "The plot data argument " + `self.plot_data` + " must be set to either 'value', 'error', 'sim'." 216 217 # Test if the simulations exist. 218 if self.plot_data == 'sim' and (not hasattr(self.relax.data, 'sim_number') or not self.relax.data.sim_number.has_key(self.run)): 219 raise RelaxNoSimError, self.run 220 221 # Open the file for writing. 222 self.file = self.relax.IO.open_write_file(file, dir, force) 223 224 # Function type. 225 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)] 226 227 # Specific value and error, conversion factor, and units returning functions. 228 self.x_return_value = self.y_return_value = self.relax.specific_setup.setup('return_value', function_type) 229 self.x_return_conversion_factor = self.y_return_conversion_factor = self.relax.specific_setup.setup('return_conversion_factor', function_type) 230 self.x_return_units = self.y_return_units = self.relax.specific_setup.setup('return_units', function_type) 231 self.x_return_grace_string = self.y_return_grace_string = self.relax.specific_setup.setup('return_grace_string', function_type) 232 233 # Test if the X-axis data type is a minimisation statistic. 234 if self.x_data_type != 'res' and self.relax.generic.minimise.return_data_name(self.x_data_type): 235 self.x_return_value = self.relax.generic.minimise.return_value 236 self.x_return_conversion_factor = self.relax.generic.minimise.return_conversion_factor 237 self.x_return_units = self.relax.generic.minimise.return_units 238 self.x_return_grace_string = self.relax.generic.minimise.return_grace_string 239 240 # Test if the Y-axis data type is a minimisation statistic. 241 if self.relax.generic.minimise.return_data_name(self.y_data_type): 242 self.y_return_value = self.relax.generic.minimise.return_value 243 self.y_return_conversion_factor = self.relax.generic.minimise.return_conversion_factor 244 self.y_return_units = self.relax.generic.minimise.return_units 245 self.y_return_grace_string = self.relax.generic.minimise.return_grace_string 246 247 # Get the data. 248 self.get_data() 249 250 # Determine the graph type (ie xy, xydy, xydx, or xydxdy). 251 self.determine_graph_type() 252 253 # Test for multiple data sets. 254 self.multi = 1 255 try: 256 len(self.data[0][2]) 257 except TypeError: 258 self.multi = 0 259 260 # Multiple data sets. 261 if self.multi: 262 # Write the header. 263 self.write_multi_header() 264 265 # Write the data. 266 self.write_multi_data() 267 268 # Single data set. 269 else: 270 # Write the header. 271 self.write_header() 272 273 # Write the data. 274 self.write_data() 275 276 # Close the file. 277 self.file.close()
278 279
280 - def write_data(self):
281 """Write the data into the grace file.""" 282 283 # First graph and data set (graph 0, set 0). 284 self.file.write("@target G0.S0\n") 285 self.file.write("@type " + self.graph_type + "\n") 286 287 # Loop over the data. 288 for i in xrange(len(self.data)): 289 # Graph type xy. 290 if self.graph_type == 'xy': 291 # Write the data. 292 self.file.write("%-30s%-30s\n" % (self.data[i][2], self.data[i][4])) 293 294 # Graph type xydy. 295 elif self.graph_type == 'xydy': 296 # Catch y-axis errors of None. 297 y_error = self.data[i][5] 298 if y_error == None: 299 y_error = 0.0 300 301 # Write the data. 302 self.file.write("%-30s%-30s%-30s\n" % (self.data[i][2], self.data[i][4], y_error)) 303 304 # Graph type xydxdy. 305 elif self.graph_type == 'xydxdy': 306 # Catch x-axis errors of None. 307 x_error = self.data[i][3] 308 if x_error == None: 309 x_error = 0.0 310 311 # Catch y-axis errors of None. 312 y_error = self.data[i][5] 313 if y_error == None: 314 y_error = 0.0 315 316 # Write the data. 317 self.file.write("%-30s%-30s%-30s%-30s\n" % (self.data[i][2], self.data[i][4], x_error, y_error)) 318 319 # End of graph and data set. 320 self.file.write("&\n")
321 322
323 - def write_header(self):
324 """Write the grace header.""" 325 326 # Graph G0. 327 self.file.write("@with g0\n") 328 329 # X axis start and end. 330 if self.x_data_type == 'res': 331 self.file.write("@ world xmin " + `self.relax.data.res[self.run][0].num - 1` + "\n") 332 self.file.write("@ world xmax " + `self.relax.data.res[self.run][-1].num + 1` + "\n") 333 334 # X-axis label. 335 if self.x_data_type == 'res': 336 self.file.write("@ xaxis label \"Residue number\"\n") 337 else: 338 # Get the units. 339 units = self.x_return_units(self.x_data_type) 340 341 # Label. 342 if units: 343 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\\N (" + units + ")\"\n") 344 else: 345 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\"\n") 346 347 # X-axis specific settings. 348 self.file.write("@ xaxis label char size 1.48\n") 349 self.file.write("@ xaxis tick major size 0.75\n") 350 self.file.write("@ xaxis tick major linewidth 0.5\n") 351 self.file.write("@ xaxis tick minor linewidth 0.5\n") 352 self.file.write("@ xaxis tick minor size 0.45\n") 353 self.file.write("@ xaxis ticklabel char size 1.00\n") 354 355 # Y-axis label. 356 units = self.y_return_units(self.y_data_type) 357 if units: 358 self.file.write("@ yaxis label \"" + self.y_return_grace_string(self.y_data_type) + "\\N (" + units + ")\"\n") 359 else: 360 self.file.write("@ yaxis label \"" + self.y_return_grace_string(self.y_data_type) + "\"\n") 361 362 # Y-axis specific settings. 363 self.file.write("@ yaxis label char size 1.48\n") 364 self.file.write("@ yaxis tick major size 0.75\n") 365 self.file.write("@ yaxis tick major linewidth 0.5\n") 366 self.file.write("@ yaxis tick minor linewidth 0.5\n") 367 self.file.write("@ yaxis tick minor size 0.45\n") 368 self.file.write("@ yaxis ticklabel char size 1.00\n") 369 370 # Frame. 371 self.file.write("@ frame linewidth 0.5\n") 372 373 # Symbols. 374 self.file.write("@ s0 symbol 1\n") 375 self.file.write("@ s0 symbol size 0.45\n") 376 self.file.write("@ s0 symbol fill pattern 1\n") 377 self.file.write("@ s0 symbol linewidth 0.5\n") 378 self.file.write("@ s0 line linestyle 0\n") 379 380 # Error bars. 381 self.file.write("@ s0 errorbar size 0.5\n") 382 self.file.write("@ s0 errorbar linewidth 0.5\n") 383 self.file.write("@ s0 errorbar riser linewidth 0.5\n")
384 385
386 - def write_multi_data(self):
387 """Write the data into the grace file.""" 388 389 # Loop over the data. 390 for i in xrange(len(self.data)): 391 # Multi data set (graph 0, set i). 392 self.file.write("@target G0.S" + `i` + "\n") 393 self.file.write("@type " + self.graph_type + "\n") 394 395 # Normalisation. 396 norm_fact = 1.0 397 if self.norm: 398 norm_fact = self.data[i][4][0] 399 400 # Loop over the data of the set. 401 for j in xrange(len(self.data[i][2])): 402 # Graph type xy. 403 if self.graph_type == 'xy': 404 # Write the data. 405 self.file.write("%-30s%-30s\n" % (self.data[i][2][j], self.data[i][4][j]/norm_fact)) 406 407 # Graph type xydy. 408 elif self.graph_type == 'xydy': 409 # Catch y-axis errors of None. 410 y_error = self.data[i][5][j] 411 if y_error == None: 412 y_error = 0.0 413 414 # Write the data. 415 self.file.write("%-30s%-30s%-30s\n" % (self.data[i][2][j], self.data[i][4][j]/norm_fact, y_error/norm_fact)) 416 417 # Graph type xydxdy. 418 elif self.graph_type == 'xydxdy': 419 # Catch x-axis errors of None. 420 x_error = self.data[i][3][j] 421 if x_error == None: 422 x_error = 0.0 423 424 # Catch y-axis errors of None. 425 y_error = self.data[i][5][j] 426 if y_error == None: 427 y_error = 0.0 428 429 # Write the data. 430 self.file.write("%-30s%-30s%-30s%-30s\n" % (self.data[i][2][j], self.data[i][4][j]/norm_fact, x_error, y_error/norm_fact)) 431 432 # End of the data set i. 433 self.file.write("&\n")
434 435
436 - def write_multi_header(self):
437 """Write the grace header.""" 438 439 # Graph G0. 440 self.file.write("@with g0\n") 441 442 # X axis start and end. 443 if self.x_data_type == 'res': 444 self.file.write("@ world xmin " + `self.relax.data.res[self.run][0].num - 1` + "\n") 445 self.file.write("@ world xmax " + `self.relax.data.res[self.run][-1].num + 1` + "\n") 446 447 # X-axis label. 448 if self.x_data_type == 'res': 449 self.file.write("@ xaxis label \"Residue number\"\n") 450 else: 451 # Get the units. 452 units = self.x_return_units(self.x_data_type) 453 454 # Label. 455 if units: 456 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\\N (" + units + ")\"\n") 457 else: 458 self.file.write("@ xaxis label \"" + self.x_return_grace_string(self.x_data_type) + "\"\n") 459 460 # X-axis specific settings. 461 self.file.write("@ xaxis label char size 1.48\n") 462 self.file.write("@ xaxis tick major size 0.75\n") 463 self.file.write("@ xaxis tick major linewidth 0.5\n") 464 self.file.write("@ xaxis tick minor linewidth 0.5\n") 465 self.file.write("@ xaxis tick minor size 0.45\n") 466 self.file.write("@ xaxis ticklabel char size 1.00\n") 467 468 # Y-axis label. 469 units = self.y_return_units(self.y_data_type) 470 string = "@ yaxis label \"" + self.y_return_grace_string(self.y_data_type) 471 if units: 472 string = string + "\\N (" + units + ")" 473 if self.norm: 474 string = string + " \\q(normalised)\\Q" 475 self.file.write(string + "\"\n") 476 477 # Y-axis specific settings. 478 self.file.write("@ yaxis label char size 1.48\n") 479 self.file.write("@ yaxis tick major size 0.75\n") 480 self.file.write("@ yaxis tick major linewidth 0.5\n") 481 self.file.write("@ yaxis tick minor linewidth 0.5\n") 482 self.file.write("@ yaxis tick minor size 0.45\n") 483 self.file.write("@ yaxis ticklabel char size 1.00\n") 484 485 # Legend box. 486 self.file.write("@ legend off\n") 487 488 # Frame. 489 self.file.write("@ frame linewidth 0.5\n") 490 491 # Loop over the data sets. 492 for i in xrange(len(self.data)): 493 # Error bars. 494 self.file.write("@ s%i errorbar size 0.5\n" % i) 495 self.file.write("@ s%i errorbar linewidth 0.5\n" % i) 496 self.file.write("@ s%i errorbar riser linewidth 0.5\n" % i) 497 498 # Legend. 499 self.file.write("@ s%i legend \"Residue %s\"\n" % (i, self.data[i][1] + " " + `self.data[i][0]`))
500