Package specific_fns :: Module noe
[hide private]
[frames] | no frames]

Source Code for Module specific_fns.noe

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-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 math import sqrt 
 24  from re import match 
 25   
 26   
27 -class Noe:
28 - def __init__(self, relax):
29 """Class containing functions for relaxation data.""" 30 31 self.relax = relax
32 33
34 - def assign_function(self, run=None, i=None, intensity=None):
35 """Function for assigning peak intensity data to either the reference or saturated spectra.""" 36 37 # Add the data. 38 if self.spectrum_type == 'ref': 39 self.relax.data.res[run][i].ref = intensity 40 elif self.spectrum_type == 'sat': 41 self.relax.data.res[run][i].sat = intensity
42 43
44 - def calculate(self, run=None, print_flag=1):
45 """Function for calculating the NOE and its error. 46 47 The error for each peak is calculated using the formula: 48 ___________________________________________ 49 \/ {sd(sat)*I(unsat)}^2 + {sd(unsat)*I(sat)}^2 50 sd(NOE) = ----------------------------------------------- 51 I(unsat)^2 52 """ 53 54 # Arguments. 55 self.run = run 56 57 # Test if the run exists. 58 if not self.run in self.relax.data.run_names: 59 raise RelaxNoRunError, self.run 60 61 # Loop over the sequence. 62 for i in xrange(len(self.relax.data.res[self.run])): 63 # Remap the data structure 'self.relax.data.res[self.run][i]'. 64 data = self.relax.data.res[self.run][i] 65 66 # Skip unselected residues. 67 if not data.select: 68 continue 69 70 # Calculate the NOE. 71 data.noe = data.sat / data.ref 72 73 # Calculate the error. 74 data.noe_err = sqrt((data.sat_err * data.ref)**2 + (data.ref_err * data.sat)**2) / data.ref**2
75 76
77 - def overfit_deselect(self, run):
78 """Function for deselecting residues without sufficient data to support calculation""" 79 80 # Test the sequence data exists: 81 if not self.relax.data.res.has_key(run): 82 raise RelaxNoSequenceError, run 83 84 # Loop over residue data: 85 for residue in self.relax.data.res[run]: 86 87 # Check for sufficient data. 88 if not (hasattr(residue, 'ref') and hasattr(residue, 'sat') and hasattr(residue, 'ref_err') and hasattr(residue, 'sat_err')): 89 residue.select = 0 90 continue
91 92
93 - def read(self, run=None, file=None, dir=None, spectrum_type=None, format=None, heteronuc=None, proton=None, int_col=None):
94 """Function for reading peak intensity data.""" 95 96 # Arguments. 97 self.run = run 98 self.spectrum_type = spectrum_type 99 100 # Spectrum type argument. 101 spect_type_list = ['ref', 'sat'] 102 if self.spectrum_type not in spect_type_list: 103 raise RelaxArgNotInListError, ('spectrum type', self.spectrum_type, spect_type_list) 104 if self.spectrum_type == 'ref': 105 print "Reference spectrum." 106 if self.spectrum_type == 'sat': 107 print "Saturated spectrum." 108 109 # Generic intensity function. 110 self.relax.generic.intensity.read(run=run, file=file, dir=dir, format=format, heteronuc=heteronuc, proton=proton, int_col=int_col, assign_func=self.assign_function)
111 112
113 - def read_columnar_results(self, run, file_data):
114 """Function for reading the results file.""" 115 116 # Arguments. 117 self.run = run 118 119 # Extract and remove the header. 120 header = file_data[0] 121 file_data = file_data[1:] 122 123 # Sort the column numbers. 124 col = {} 125 for i in xrange(len(header)): 126 if header[i] == 'Num': 127 col['num'] = i 128 elif header[i] == 'Name': 129 col['name'] = i 130 elif header[i] == 'Selected': 131 col['select'] = i 132 elif header[i] == 'Ref_intensity': 133 col['ref_int'] = i 134 elif header[i] == 'Ref_error': 135 col['ref_err'] = i 136 elif header[i] == 'Sat_intensity': 137 col['sat_int'] = i 138 elif header[i] == 'Sat_error': 139 col['sat_err'] = i 140 elif header[i] == 'NOE': 141 col['noe'] = i 142 elif header[i] == 'NOE_error': 143 col['noe_err'] = i 144 145 # Test the file. 146 if len(col) < 2: 147 raise RelaxInvalidDataError 148 149 150 # Sequence. 151 ########### 152 153 # Generate the sequence. 154 for i in xrange(len(file_data)): 155 # Residue number and name. 156 try: 157 res_num = int(file_data[i][col['num']]) 158 except ValueError: 159 raise RelaxError, "The residue number " + file_data[i][col['num']] + " is not an integer." 160 res_name = file_data[i][col['name']] 161 162 # Add the residue. 163 self.relax.generic.sequence.add(self.run, res_num, res_name, select=int(file_data[i][col['select']])) 164 165 166 # Data. 167 ####### 168 169 # Loop over the file data. 170 for i in xrange(len(file_data)): 171 # Residue number and name. 172 try: 173 res_num = int(file_data[i][col['num']]) 174 except ValueError: 175 raise RelaxError, "The residue number " + file_data[i][col['num']] + " is not an integer." 176 res_name = file_data[i][col['name']] 177 178 # Find the residue index. 179 index = None 180 for j in xrange(len(self.relax.data.res[self.run])): 181 if self.relax.data.res[self.run][j].num == res_num and self.relax.data.res[self.run][j].name == res_name: 182 index = j 183 break 184 if index == None: 185 raise RelaxError, "Residue " + `res_num` + " " + res_name + " cannot be found in the sequence." 186 187 # Reassign data structure. 188 data = self.relax.data.res[self.run][index] 189 190 # Skip unselected residues. 191 if not data.select: 192 continue 193 194 # Reference intensity. 195 try: 196 data.ref = float(file_data[i][col['ref_int']]) 197 except ValueError: 198 data.ref = None 199 200 # Reference error. 201 try: 202 data.ref_err = float(file_data[i][col['ref_err']]) 203 except ValueError: 204 data.ref_err = None 205 206 # Saturated intensity. 207 try: 208 data.sat = float(file_data[i][col['sat_int']]) 209 except ValueError: 210 data.sat = None 211 212 # Saturated error. 213 try: 214 data.sat_err = float(file_data[i][col['sat_err']]) 215 except ValueError: 216 data.sat_err = None 217 218 # NOE. 219 try: 220 data.noe = float(file_data[i][col['noe']]) 221 except ValueError: 222 data.noe = None 223 224 # NOE error. 225 try: 226 data.noe_err = float(file_data[i][col['noe_err']]) 227 except ValueError: 228 data.noe_err = None
229 230
231 - def return_conversion_factor(self, stat_type):
232 """Dummy function for returning 1.0.""" 233 234 return 1.0
235 236
237 - def return_data_name(self, name):
238 """ 239 NOE calculation data type string matching patterns 240 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 241 242 ____________________________________________________________________________________________ 243 | | | | 244 | Data type | Object name | Patterns | 245 |________________________|______________|__________________________________________________| 246 | | | | 247 | Reference intensity | 'ref' | '^[Rr]ef$' or '[Rr]ef[ -_][Ii]nt' | 248 | | | | 249 | Saturated intensity | 'sat' | '^[Ss]at$' or '[Ss]at[ -_][Ii]nt' | 250 | | | | 251 | NOE | 'noe' | '^[Nn][Oo][Ee]$' | 252 |________________________|______________|__________________________________________________| 253 254 """ 255 256 # Reference intensity. 257 if match('^[Rr]ef$', name) or match('[Rr]ef[ -_][Ii]nt', name): 258 return 'ref' 259 260 # Saturated intensity. 261 if match('^[Ss]at$', name) or match('[Ss]at[ -_][Ii]nt', name): 262 return 'sat' 263 264 # NOE. 265 if match('^[Nn][Oo][Ee]$', name): 266 return 'noe'
267 268
269 - def return_grace_string(self, data_type):
270 """Function for returning the Grace string representing the data type for axis labelling.""" 271 272 # Get the object name. 273 object_name = self.return_data_name(data_type) 274 275 # Reference intensity. 276 if object_name == 'ref': 277 grace_string = 'Reference intensity' 278 279 # Saturated intensity. 280 if object_name == 'sat': 281 grace_string = 'Saturated intensity' 282 283 # NOE. 284 if object_name == 'noe': 285 grace_string = '\\qNOE\\Q' 286 287 # Return the Grace string. 288 return grace_string
289 290
291 - def return_units(self, stat_type):
292 """Dummy function which returns None as the stats have no units.""" 293 294 return None
295 296
297 - def return_value(self, run, i, data_type='noe'):
298 """Function for returning the NOE value and error.""" 299 300 # Arguments. 301 self.run = run 302 303 # Remap the data structure 'self.relax.data.res[run][i]'. 304 data = self.relax.data.res[run][i] 305 306 # Get the object. 307 object_name = self.return_data_name(data_type) 308 if not object_name: 309 raise RelaxError, "The NOE calculation data type " + `data_type` + " does not exist." 310 object_error = object_name + "_err" 311 312 # Get the value. 313 value = None 314 if hasattr(data, object_name): 315 value = getattr(data, object_name) 316 317 # Get the error. 318 error = None 319 if hasattr(data, object_error): 320 error = getattr(data, object_error) 321 322 # Return the data. 323 return value, error
324 325
326 - def set_error(self, run=None, error=0.0, spectrum_type=None, res_num=None, res_name=None):
327 """Function for setting the errors.""" 328 329 # Arguments. 330 self.run = run 331 self.spectrum_type = spectrum_type 332 self.res_num = res_num 333 self.res_name = res_name 334 335 # Test if the run exists. 336 if not run in self.relax.data.run_names: 337 raise RelaxNoRunError, run 338 339 # Test if the sequence data is loaded. 340 if not self.relax.data.res.has_key(run): 341 raise RelaxNoSequenceError, run 342 343 # Test if the residue number is a valid regular expression. 344 if type(res_num) == str: 345 try: 346 compile(res_num) 347 except: 348 raise RelaxRegExpError, ('residue number', res_num) 349 350 # Test if the residue name is a valid regular expression. 351 if res_name: 352 try: 353 compile(res_name) 354 except: 355 raise RelaxRegExpError, ('residue name', res_name) 356 357 # Loop over the sequence. 358 for i in xrange(len(self.relax.data.res[run])): 359 # Remap the data structure 'self.relax.data.res[self.run][i]'. 360 data = self.relax.data.res[self.run][i] 361 362 # Skip unselected residues. 363 if not data.select: 364 continue 365 366 # If 'res_num' is not None, skip the residue if there is no match. 367 if type(res_num) == int and not data.num == res_num: 368 continue 369 elif type(res_num) == str and not match(res_num, `data.num`): 370 continue 371 372 # If 'res_name' is not None, skip the residue if there is no match. 373 if res_name != None and not match(res_name, data.name): 374 continue 375 376 # Set the error. 377 if self.spectrum_type == 'ref': 378 data.ref_err = float(error) 379 elif self.spectrum_type == 'sat': 380 data.sat_err = float(error)
381 382
383 - def write(self, run=None, file=None, dir=None, force=0):
384 """Function for writing NOE values and errors to a file.""" 385 386 # Arguments 387 self.run = run 388 389 # Test if the run exists. 390 if not self.run in self.relax.data.run_names: 391 raise RelaxNoRunError, self.run 392 393 # Test if the sequence data is loaded. 394 if not self.relax.data.res.has_key(self.run): 395 raise RelaxNoSequenceError, self.run 396 397 # Open the file for writing. 398 noe_file = self.relax.IO.open_write_file(file, dir, force) 399 400 # Write the data. 401 self.relax.generic.value.write_data(self.run, None, noe_file, return_value=self.return_value) 402 403 # Close the file. 404 noe_file.close()
405 406
407 - def write_columnar_line(self, file=None, num=None, name=None, select=None, ref_int=None, ref_err=None, sat_int=None, sat_err=None, noe=None, noe_err=None):
408 """Function for printing a single line of the columnar formatted results.""" 409 410 # Residue number and name. 411 file.write("%-4s %-5s " % (num, name)) 412 413 # Selected flag and data set. 414 file.write("%-9s " % select) 415 if not select: 416 file.write("\n") 417 return 418 419 # Reference and saturated data. 420 file.write("%-25s %-25s " % (ref_int, ref_err)) 421 file.write("%-25s %-25s " % (sat_int, sat_err)) 422 423 # NOE and error. 424 file.write("%-25s %-25s " % (noe, noe_err)) 425 426 # End of the line. 427 file.write("\n")
428 429
430 - def write_columnar_results(self, file, run):
431 """Function for printing the results into a file.""" 432 433 # Arguments. 434 self.run = run 435 436 # Test if the run exists. 437 if not self.run in self.relax.data.run_names: 438 raise RelaxNoRunError, self.run 439 440 # Test if sequence data is loaded. 441 if not self.relax.data.res.has_key(self.run): 442 raise RelaxNoSequenceError, self.run 443 444 445 # Header. 446 ######### 447 448 449 # Write the header line. 450 self.write_columnar_line(file=file, num='Num', name='Name', select='Selected', ref_int='Ref_intensity', ref_err='Ref_error', sat_int='Sat_intensity', sat_err='Sat_error', noe='NOE', noe_err='NOE_error') 451 452 453 # Values. 454 ######### 455 456 # Loop over the sequence. 457 for i in xrange(len(self.relax.data.res[self.run])): 458 # Reassign data structure. 459 data = self.relax.data.res[self.run][i] 460 461 # Unselected residues. 462 if not data.select: 463 self.write_columnar_line(file=file, num=data.num, name=data.name, select=0) 464 continue 465 466 # Reference intensity. 467 ref_int = None 468 if hasattr(data, 'ref'): 469 ref_int = data.ref 470 471 # Reference error. 472 ref_err = None 473 if hasattr(data, 'ref_err'): 474 ref_err = data.ref_err 475 476 # Saturated intensity. 477 sat_int = None 478 if hasattr(data, 'sat'): 479 sat_int = data.sat 480 481 # Saturated error. 482 sat_err = None 483 if hasattr(data, 'sat_err'): 484 sat_err = data.sat_err 485 486 # NOE 487 noe = None 488 if hasattr(data, 'noe'): 489 noe = data.noe 490 491 # NOE error. 492 noe_err = None 493 if hasattr(data, 'noe_err'): 494 noe_err = data.noe_err 495 496 # Write the line. 497 self.write_columnar_line(file=file, num=data.num, name=data.name, select=data.select, ref_int=ref_int, ref_err=ref_err, sat_int=sat_int, sat_err=sat_err, noe=noe, noe_err=noe_err)
498