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

Source Code for Module generic_fns.palmer

  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 math import pi 
 24  from os import F_OK, P_WAIT, access, chdir, chmod, getcwd, listdir, remove, spawnlp, system 
 25  from re import match, search 
 26  from string import split 
 27   
 28   
29 -class Palmer:
30 - def __init__(self, relax):
31 """Class used to create and process input and output for the program Modelfree 4.""" 32 33 self.relax = relax
34 35
36 - def create(self, run, dir, force, diff_search, sims, sim_type, trim, steps, constraints, nucleus, atom1, atom2):
37 """Function for creating the Modelfree4 input files. 38 39 The following files are created: 40 dir/mfin 41 dir/mfdata 42 dir/mfpar 43 dir/mfmodel 44 dir/run.sh 45 """ 46 47 # Test if the run exists. 48 if not run in self.relax.data.run_names: 49 raise RelaxNoRunError, run 50 51 # Test if sequence data is loaded. 52 if not self.relax.data.res.has_key(run): 53 raise RelaxNoSequenceError, run 54 55 # Test if the PDB file is loaded (for the spheroid and ellipsoid). 56 if not self.relax.data.diff[run].type == 'sphere' and not self.relax.data.pdb.has_key(run): 57 raise RelaxNoPdbError, run 58 59 # Test if the nucleus type has been set. 60 if not hasattr(self.relax.data, 'gx'): 61 raise RelaxNucleusError 62 63 # Directory creation. 64 if dir == None: 65 dir = run 66 self.relax.IO.mkdir(dir, print_flag=0) 67 68 # Place the arguments into 'self'. 69 self.run = run 70 self.dir = dir 71 self.force = force 72 self.diff_search = diff_search 73 self.sims = sims 74 self.sim_type = sim_type 75 self.trim = trim 76 self.steps = steps 77 self.constraints = constraints 78 self.nucleus = nucleus 79 self.atom1 = atom1 80 self.atom2 = atom2 81 82 # Number of field strengths and values. 83 self.num_frq = 0 84 self.frq = [] 85 for i in xrange(len(self.relax.data.res[self.run])): 86 if hasattr(self.relax.data.res[self.run][i], 'num_frq'): 87 if self.relax.data.res[self.run][i].num_frq > self.num_frq: 88 # Number of field strengths. 89 self.num_frq = self.relax.data.res[self.run][i].num_frq 90 91 # Field strength values. 92 for frq in self.relax.data.res[self.run][i].frq: 93 if frq not in self.frq: 94 self.frq.append(frq) 95 96 # The 'mfin' file. 97 mfin = self.open_file('mfin') 98 self.create_mfin(mfin) 99 mfin.close() 100 101 # Open the 'mfdata', 'mfmodel', and 'mfpar' files. 102 mfdata = self.open_file('mfdata') 103 mfmodel = self.open_file('mfmodel') 104 mfpar = self.open_file('mfpar') 105 106 # Loop over the sequence. 107 for i in xrange(len(self.relax.data.res[self.run])): 108 if hasattr(self.relax.data.res[self.run][i], 'num_frq'): 109 # The 'mfdata' file. 110 if not self.create_mfdata(i, mfdata): 111 continue 112 113 # The 'mfmodel' file. 114 self.create_mfmodel(i, mfmodel) 115 116 # The 'mfpar' file. 117 self.create_mfpar(i, mfpar) 118 119 # Close the 'mfdata', 'mfmodel', and 'mfpar' files. 120 mfdata.close() 121 mfmodel.close() 122 mfpar.close() 123 124 # The 'run.sh' script. 125 run = self.open_file('run.sh') 126 self.create_run(run) 127 run.close() 128 chmod(self.dir + '/run.sh', 0755)
129 130
131 - def create_mfdata(self, i, file):
132 """Create the Modelfree4 input file 'mfmodel'.""" 133 134 # Spin title. 135 file.write("\nspin " + self.relax.data.res[self.run][i].name + "_" + `self.relax.data.res[self.run][i].num` + "\n") 136 137 # Data written flag. 138 written = 0 139 140 # Loop over the frequencies. 141 for j in xrange(self.num_frq): 142 # Set the data to None. 143 r1, r2, noe = None, None, None 144 145 # Loop over the relevant relaxation data. 146 for k in xrange(self.relax.data.res[self.run][i].num_ri): 147 if self.frq[j] != self.relax.data.res[self.run][i].frq[self.relax.data.res[self.run][i].remap_table[k]]: 148 continue 149 150 # Find the corresponding R1. 151 if self.relax.data.res[self.run][i].ri_labels[k] == 'R1': 152 r1 = self.relax.data.res[self.run][i].relax_data[k] 153 r1_err = self.relax.data.res[self.run][i].relax_error[k] 154 155 # Find the corresponding R2. 156 elif self.relax.data.res[self.run][i].ri_labels[k] == 'R2': 157 r2 = self.relax.data.res[self.run][i].relax_data[k] 158 r2_err = self.relax.data.res[self.run][i].relax_error[k] 159 160 # Find the corresponding NOE. 161 elif self.relax.data.res[self.run][i].ri_labels[k] == 'NOE': 162 noe = self.relax.data.res[self.run][i].relax_data[k] 163 noe_err = self.relax.data.res[self.run][i].relax_error[k] 164 165 # Test if the R1 exists for this frequency, otherwise skip the data. 166 if r1: 167 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('R1', self.frq[j]*1e-6, r1, r1_err, 1)) 168 else: 169 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('R1', self.frq[j]*1e-6, 0, 0, 0)) 170 171 # Test if the R2 exists for this frequency, otherwise skip the data. 172 if r2: 173 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('R2', self.frq[j]*1e-6, r2, r2_err, 1)) 174 else: 175 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('R2', self.frq[j]*1e-6, 0, 0, 0)) 176 177 # Test if the NOE exists for this frequency, otherwise skip the data. 178 if noe: 179 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('NOE', self.frq[j]*1e-6, noe, noe_err, 1)) 180 else: 181 file.write('%-7s%-10.3f%20f%20f %-3i\n' % ('NOE', self.frq[j]*1e-6, 0, 0, 0)) 182 183 written = 1 184 185 return written
186 187
188 - def create_mfin(self, file):
189 """Create the Modelfree4 input file 'mfin'.""" 190 191 # Set the diffusion tensor specific values. 192 if self.relax.data.diff[self.run].type == 'sphere': 193 diff = 'isotropic' 194 algorithm = 'brent' 195 tm = self.relax.data.diff[self.run].tm / 1e-9 196 dratio = 1 197 theta = 0 198 phi = 0 199 elif self.relax.data.diff[self.run].type == 'spheroid': 200 diff = 'axial' 201 algorithm = 'powell' 202 tm = self.relax.data.diff[self.run].tm / 1e-9 203 dratio = self.relax.data.diff[self.run].Dratio 204 theta = self.relax.data.diff[self.run].theta * 360.0 / (2.0 * pi) 205 phi = self.relax.data.diff[self.run].phi * 360.0 / (2.0 * pi) 206 elif self.relax.data.diff[self.run].type == 'ellipsoid': 207 diff = 'anisotropic' 208 algorithm = 'powell' 209 tm = self.relax.data.diff[self.run].tm / 1e-9 210 dratio = 0 211 theta = 0 212 phi = 0 213 214 # Add the main options. 215 file.write("optimization tval\n\n") 216 file.write("seed 0\n\n") 217 file.write("search grid\n\n") 218 219 # Diffusion type. 220 if self.relax.data.diff[self.run].fixed: 221 algorithm = 'fix' 222 223 file.write("diffusion " + diff + " " + self.diff_search + "\n\n") 224 file.write("algorithm " + algorithm + "\n\n") 225 226 # Monte Carlo simulations. 227 if self.sims: 228 file.write("simulations " + self.sim_type + " " + `self.sims` + " " + `self.trim` + "\n\n") 229 else: 230 file.write("simulations none\n\n") 231 232 selection = 'none' # To be changed. 233 file.write("selection " + selection + "\n\n") 234 file.write("sim_algorithm " + algorithm + "\n\n") 235 236 file.write("fields " + `self.num_frq`) 237 for frq in self.frq: 238 file.write(" " + `frq*1e-6`) 239 file.write("\n") 240 241 # tm. 242 file.write('%-7s' % 'tm') 243 file.write('%14.3f' % tm) 244 file.write('%2i' % 1) 245 file.write('%3i' % 0) 246 file.write('%5i' % 5) 247 file.write('%6i' % 15) 248 file.write('%4i\n' % 20) 249 250 # dratio. 251 file.write('%-7s' % 'Dratio') 252 file.write('%14s' % dratio) 253 file.write('%2i' % 1) 254 file.write('%3i' % 0) 255 file.write('%5i' % 0) 256 file.write('%6i' % 2) 257 file.write('%4i\n' % 5) 258 259 # theta. 260 file.write('%-7s' % 'Theta') 261 file.write('%14s' % theta) 262 file.write('%2i' % 1) 263 file.write('%3i' % 0) 264 file.write('%5i' % 0) 265 file.write('%6i' % 180) 266 file.write('%4i\n' % 10) 267 268 # phi. 269 file.write('%-7s' % 'Phi') 270 file.write('%14s' % phi) 271 file.write('%2i' % 1) 272 file.write('%3i' % 0) 273 file.write('%5i' % 0) 274 file.write('%6i' % 360) 275 file.write('%4i\n' % 10)
276 277
278 - def create_mfmodel(self, i, file):
279 """Create the Modelfree4 input file 'mfmodel'.""" 280 281 # Spin title. 282 file.write("\nspin " + self.relax.data.res[self.run][i].name + "_" + `self.relax.data.res[self.run][i].num` + "\n") 283 284 # tloc. 285 file.write('%-3s%-6s%-6.1f' % ('M1', 'tloc', 0)) 286 if 'tm' in self.relax.data.res[self.run][i].params: 287 file.write('%-4i' % 1) 288 else: 289 file.write('%-4i' % 0) 290 291 if self.constraints: 292 file.write('%-2i' % 2) 293 else: 294 file.write('%-2i' % 0) 295 296 file.write('%11.3f%12.3f %-4s\n' % (0, 20, self.steps)) 297 298 # Theta. 299 file.write('%-3s%-6s%-6.1f' % ('M1', 'Theta', 0)) 300 file.write('%-4i' % 0) 301 302 if self.constraints: 303 file.write('%-2i' % 2) 304 else: 305 file.write('%-2i' % 0) 306 307 file.write('%11.3f%12.3f %-4s\n' % (0, 90, self.steps)) 308 309 # S2f. 310 file.write('%-3s%-6s%-6.1f' % ('M1', 'Sf2', 1)) 311 if 'S2f' in self.relax.data.res[self.run][i].params: 312 file.write('%-4i' % 1) 313 else: 314 file.write('%-4i' % 0) 315 316 if self.constraints: 317 file.write('%-2i' % 2) 318 else: 319 file.write('%-2i' % 0) 320 321 file.write('%11.3f%12.3f %-4s\n' % (0, 1, self.steps)) 322 323 # S2s. 324 file.write('%-3s%-6s%-6.1f' % ('M1', 'Ss2', 1)) 325 if 'S2s' in self.relax.data.res[self.run][i].params or 'S2' in self.relax.data.res[self.run][i].params: 326 file.write('%-4i' % 1) 327 else: 328 file.write('%-4i' % 0) 329 330 if self.constraints: 331 file.write('%-2i' % 2) 332 else: 333 file.write('%-2i' % 0) 334 335 file.write('%11.3f%12.3f %-4s\n' % (0, 1, self.steps)) 336 337 # te. 338 file.write('%-3s%-6s%-6.1f' % ('M1', 'te', 0)) 339 if 'te' in self.relax.data.res[self.run][i].params or 'ts' in self.relax.data.res[self.run][i].params: 340 file.write('%-4i' % 1) 341 else: 342 file.write('%-4i' % 0) 343 344 if self.constraints: 345 file.write('%-2i' % 2) 346 else: 347 file.write('%-2i' % 0) 348 349 file.write('%11.3f%12.3f %-4s\n' % (0, 10000, self.steps)) 350 351 # Rex. 352 file.write('%-3s%-6s%-6.1f' % ('M1', 'Rex', 0)) 353 if 'Rex' in self.relax.data.res[self.run][i].params: 354 file.write('%-4i' % 1) 355 else: 356 file.write('%-4i' % 0) 357 358 if self.constraints: 359 file.write('%-2i' % -1) 360 else: 361 file.write('%-2i' % 0) 362 363 file.write('%11.3f%12.3f %-4s\n' % (0, 20, self.steps))
364 365
366 - def create_mfpar(self, i, file):
367 """Create the Modelfree4 input file 'mfpar'.""" 368 369 # Spin title. 370 file.write("\nspin " + self.relax.data.res[self.run][i].name + "_" + `self.relax.data.res[self.run][i].num` + "\n") 371 372 file.write('%-14s' % "constants") 373 file.write('%-6i' % self.relax.data.res[self.run][i].num) 374 file.write('%-7s' % self.nucleus) 375 file.write('%-8.3f' % (self.relax.data.gx / 1e7)) 376 file.write('%-8.3f' % (self.relax.data.res[self.run][i].r * 1e10)) 377 file.write('%-8.3f\n' % (self.relax.data.res[self.run][i].csa * 1e6)) 378 379 file.write('%-10s' % "vector") 380 file.write('%-4s' % self.atom1) 381 file.write('%-4s\n' % self.atom2)
382 383
384 - def create_run(self, file):
385 """Create the script 'run.sh' for the execution of Modelfree4.""" 386 387 file.write("#! /bin/sh\n") 388 file.write("modelfree4 -i mfin -d mfdata -p mfpar -m mfmodel -o mfout -e out") 389 if self.relax.data.diff[self.run].type != 'sphere': 390 # Copy the pdb file to the model directory so there are no problems with the existance of *.rotate files. 391 system('cp ' + self.relax.data.pdb[self.run].file_name + ' ' + self.dir) 392 file.write(" -s " + self.relax.data.pdb[self.run].file_name.split('/')[-1]) 393 file.write("\n")
394 395
396 - def execute(self, run, dir, force):
397 """Function for executing Modelfree4. 398 399 BUG: Control-C during execution causes the cwd to stay as dir. 400 """ 401 402 # The current directory. 403 orig_dir = getcwd() 404 405 # The directory. 406 if dir == None: 407 dir = run 408 if not access(dir, F_OK): 409 raise RelaxDirError, ('Modelfree4', dir) 410 411 # Change to this directory. 412 chdir(dir) 413 414 # Catch failures and return to the correct directory. 415 try: 416 # Test if the 'mfin' input file exists. 417 if not access('mfin', F_OK): 418 raise RelaxFileError, ('mfin input', 'mfin') 419 420 # Test if the 'mfdata' input file exists. 421 if not access('mfdata', F_OK): 422 raise RelaxFileError, ('mfdata input', 'mfdata') 423 424 # Test if the 'mfmodel' input file exists. 425 if not access('mfmodel', F_OK): 426 raise RelaxFileError, ('mfmodel input', 'mfmodel') 427 428 # Test if the 'mfpar' input file exists. 429 if not access('mfpar', F_OK): 430 raise RelaxFileError, ('mfpar input', 'mfpar') 431 432 # Test if the 'PDB' input file exists. 433 if self.relax.data.diff[run].type != 'sphere': 434 pdb = self.relax.data.pdb[self.run].file_name.split('/')[-1] 435 if not access(pdb, F_OK): 436 raise RelaxFileError, ('PDB', pdb) 437 else: 438 pdb = None 439 440 # Remove the file 'mfout' and '*.out' if the force flag is set. 441 if force: 442 for file in listdir(getcwd()): 443 if search('out$', file) or search('rotate$', file): 444 remove(file) 445 446 # Execute Modelfree4. 447 if pdb: 448 spawnlp(P_WAIT, 'modelfree4', 'modelfree4', '-i', 'mfin', '-d', 'mfdata', '-p', 'mfpar', '-m', 'mfmodel', '-o', 'mfout', '-e', 'out', '-s', pdb) 449 else: 450 test = spawnlp(P_WAIT, 'modelfree4', 'modelfree4', '-i', 'mfin', '-d', 'mfdata', '-p', 'mfpar', '-m', 'mfmodel', '-o', 'mfout', '-e', 'out') 451 if test: 452 raise RelaxProgFailError, 'Modelfree4' 453 454 # Failure. 455 except: 456 # Change back to the original directory. 457 chdir(orig_dir) 458 459 # Reraise the error. 460 raise 461 462 # Change back to the original directory. 463 chdir(orig_dir)
464 465
466 - def extract(self, run, dir):
467 """Function for extracting the Modelfree4 results out of the 'mfout' file.""" 468 469 # Arguments. 470 self.run = run 471 472 # Test if sequence data is loaded. 473 if not self.relax.data.res.has_key(self.run): 474 raise RelaxNoSequenceError, self.run 475 476 # The directory. 477 if dir == None: 478 dir = run 479 if not access(dir, F_OK): 480 raise RelaxDirError, ('Modelfree4', dir) 481 482 # Test if the file exists. 483 if not access(dir + "/mfout", F_OK): 484 raise RelaxFileError, ('Modelfree4', dir + "/mfout") 485 486 # Open the file. 487 mfout_file = open(dir + "/mfout", 'r') 488 mfout = mfout_file.readlines() 489 mfout_file.close() 490 491 # Find out if simulations were carried out. 492 sims = 0 493 for i in xrange(len(mfout)): 494 if search('_iterations', mfout[i]): 495 row = split(mfout[i]) 496 sims = int(row[1]) 497 498 # Loop over the sequence. 499 for i in xrange(len(self.relax.data.res[self.run])): 500 # Missing data sets. 501 if not hasattr(self.relax.data.res[self.run][i], 'model'): 502 continue 503 504 # Get the S2 data. 505 data = self.get_mf_data('S2', mfout, self.relax.data.res[self.run][i].num) 506 if data != None: 507 s2, s2_err = data 508 self.relax.data.res[self.run][i].s2 = s2 509 #self.relax.data.res[self.run][i].s2_err = s2_err 510 511 # Get the S2f data. 512 if 'S2f' in self.relax.data.res[self.run][i].params or 'S2s' in self.relax.data.res[self.run][i].params: 513 data = self.get_mf_data('S2f', mfout, self.relax.data.res[self.run][i].num) 514 if data != None: 515 s2f, s2f_err = data 516 self.relax.data.res[self.run][i].s2f = s2f 517 #self.relax.data.res[self.run][i].s2f_err = s2f_err 518 519 # Get the S2s data. 520 if 'S2f' in self.relax.data.res[self.run][i].params or 'S2s' in self.relax.data.res[self.run][i].params: 521 data = self.get_mf_data('S2s', mfout, self.relax.data.res[self.run][i].num) 522 if data != None: 523 s2s, s2s_err = data 524 self.relax.data.res[self.run][i].s2s = s2s 525 #self.relax.data.res[self.run][i].s2s_err = s2s_err 526 527 # Get the te and ts data. 528 if 'te' in self.relax.data.res[self.run][i].params or 'ts' in self.relax.data.res[self.run][i].params: 529 data = self.get_mf_data('te', mfout, self.relax.data.res[self.run][i].num) 530 if data != None: 531 te, te_err = data 532 self.relax.data.res[self.run][i].te = te / 1e12 533 #self.relax.data.res[self.run][i].te_err = te_err / 1e12 534 if 'ts' in self.relax.data.res[self.run][i].params: 535 self.relax.data.res[self.run][i].ts = te / 1e12 536 #self.relax.data.res[self.run][i].ts_err = te_err / 1e12 537 538 # Get the Rex data. 539 if 'Rex' in self.relax.data.res[self.run][i].params: 540 data = self.get_mf_data('Rex', mfout, self.relax.data.res[self.run][i].num) 541 if data != None: 542 rex, rex_err = data 543 self.relax.data.res[self.run][i].rex = rex / (2.0 * pi * self.relax.data.res[self.run][i].frq[0])**2 544 #self.relax.data.res[self.run][i].rex_err = rex_err / (2.0 * pi * self.relax.data.res[self.run][i].frq[0])**2 545 546 # Get the chi-squared data. 547 self.relax.data.res[self.run][i].chi2 = self.get_chi2(sims, mfout, self.relax.data.res[self.run][i].num)
548 549
550 - def get_chi2(self, sims, mfout, res):
551 """Extract the chi-squared data from the mfout file.""" 552 553 # Move to the section starting with 'data_sse'. 554 for i in xrange(len(mfout)): 555 if match('data_sse', mfout[i]): 556 break 557 558 # Get the chi-squared value. 559 for j in xrange(i+3, len(mfout)): 560 row = split(mfout[j]) 561 if `res` == row[0]: 562 return float(row[1]) 563 564 # Catch the end. 565 if row[0] == 'data_correlation_matrix': 566 return
567 568
569 - def get_mf_data(self, data_type, mfout, res):
570 """Extract the model-free data from the mfout file.""" 571 572 # Move to the section starting with 'data_model_1'. 573 for i in xrange(len(mfout)): 574 if match('data_model_1', mfout[i]): 575 break 576 577 # Move to the subsection starting with data_type. 578 for j in xrange(i, len(mfout)): 579 row = split(mfout[j]) 580 if len(row) == 0: 581 continue 582 elif match(data_type, row[0]): 583 break 584 585 # Find the residue specific information. 586 for k in xrange(j+1, len(mfout)): 587 row = split(mfout[k]) 588 if `res` == row[0]: 589 try: 590 # Catch a series of '*' joining two columns. 591 val = split(row[1], '*') 592 err = split(row[4], '*') 593 594 # Return the values. 595 return float(val[0]), float(err[0]) 596 except: 597 return None, None 598 599 # Catch the end. 600 if row[0] == 'stop_': 601 return
602 603
604 - def open_file(self, file_name):
605 """Function for opening a file to write to.""" 606 607 file_name = self.dir + "/" + file_name 608 if access(file_name, F_OK) and not self.force: 609 raise RelaxFileOverwriteError, (file_name, 'force flag') 610 return open(file_name, 'w')
611