Package Bio :: Package Phylo :: Package PAML :: Module _paml
[hide private]
[frames] | no frames]

Source Code for Module Bio.Phylo.PAML._paml

  1  # Copyright (C) 2011 by Brandon Invergo (b.invergo@gmail.com) 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license. Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5   
  6  from __future__ import print_function 
  7   
  8  import os 
  9  import subprocess 
 10   
 11   
12 -class PamlError(EnvironmentError):
13 """paml has failed. 14 15 Run with verbose=True to view the error message. 16 """
17 18
19 -class Paml(object):
20 """Base class for wrapping PAML commands.""" 21
22 - def __init__(self, alignment=None, working_dir=None, 23 out_file=None):
24 if working_dir is None: 25 self.working_dir = os.getcwd() 26 else: 27 self.working_dir = working_dir 28 if alignment is not None: 29 if not os.path.exists(alignment): 30 raise IOError("The specified alignment file does not exist.") 31 self.alignment = alignment 32 self.out_file = out_file 33 self._options = {} # will be set in subclasses
34
35 - def write_ctl_file(self):
36 pass
37
38 - def read_ctl_file(self):
39 pass
40
41 - def print_options(self):
42 """Print out all of the options and their current settings.""" 43 for option in self._options.items(): 44 print("%s = %s" % (option[0], option[1]))
45
46 - def set_options(self, **kwargs):
47 """Set the value of an option. 48 49 This function abstracts the options dict to prevent the user from 50 adding options that do not exist or misspelling options. 51 """ 52 for option, value in kwargs.items(): 53 if option not in self._options: 54 raise KeyError("Invalid option: " + option) 55 else: 56 self._options[option] = value
57
58 - def get_option(self, option):
59 """Return the value of an option.""" 60 if option not in self._options: 61 raise KeyError("Invalid option: " + option) 62 else: 63 return self._options.get(option)
64
65 - def get_all_options(self):
66 """Return the values of all the options.""" 67 return list(self._options.items())
68
69 - def _set_rel_paths(self):
70 """Convert all file/directory locations to paths relative to the current working directory. 71 72 paml requires that all paths specified in the control file be 73 relative to the directory from which it is called rather than 74 absolute paths. 75 """ 76 if self.working_dir is not None: 77 self._rel_working_dir = os.path.relpath(self.working_dir) 78 if self.alignment is not None: 79 self._rel_alignment = os.path.relpath(self.alignment, 80 self.working_dir) 81 if self.out_file is not None: 82 self._rel_out_file = os.path.relpath(self.out_file, self.working_dir)
83
84 - def run(self, ctl_file, verbose, command):
85 """Run a paml program using the current configuration and then parse the results. 86 87 Return a process signal so the user can determine if 88 the execution was successful (return code 0 is successful, -N 89 indicates a failure). The arguments may be passed as either 90 absolute or relative paths, despite the fact that paml 91 requires relative paths. 92 """ 93 if self.alignment is None: 94 raise ValueError("Alignment file not specified.") 95 if not os.path.exists(self.alignment): 96 raise IOError("The specified alignment file does not exist.") 97 if self.out_file is None: 98 raise ValueError("Output file not specified.") 99 if self.working_dir is None: 100 raise ValueError("Working directory not specified.") 101 # Get the current working directory 102 cwd = os.getcwd() 103 # Move to the desired working directory 104 if not os.path.exists(self.working_dir): 105 os.mkdir(self.working_dir) 106 os.chdir(self.working_dir) 107 # If no external control file was specified... 108 if ctl_file is None: 109 # Dynamically build a control file 110 self.write_ctl_file() 111 ctl_file = self.ctl_file 112 else: 113 if not os.path.exists(ctl_file): 114 raise IOError("The specified control file does not exist.") 115 if verbose: 116 result_code = subprocess.call([command, ctl_file]) 117 else: 118 with open(os.devnull) as dn: 119 result_code = subprocess.call([command, ctl_file], stdout=dn, stderr=dn) 120 os.chdir(cwd) 121 if result_code > 0: 122 # If the program fails for any reason 123 raise PamlError( 124 "%s has failed (return code %i). Run with verbose = True to view error message" 125 % (command, result_code)) 126 if result_code < 0: 127 # If the paml process is killed by a signal somehow 128 raise EnvironmentError("The %s process was killed (return code %i)." 129 % (command, result_code))
130