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

Source Code for Module Bio.Phylo.PAML.baseml

  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  # For using with statement in Python 2.5 or Jython 
  7  from __future__ import with_statement 
  8   
  9  import os 
 10  import os.path 
 11  from _paml import Paml, _relpath 
 12  import _parse_baseml 
 13   
 14   
15 -class BasemlError(EnvironmentError):
16 """BASEML has failed. Run with verbose = True to view BASEML's error 17 message"""
18 19
20 -class Baseml(Paml):
21 """This class implements an interface to BASEML, part of the PAML package.""" 22
23 - def __init__(self, alignment = None, tree = None, working_dir = None, 24 out_file = None):
25 """Initialize the Baseml instance. 26 27 The user may optionally pass in strings specifying the locations 28 of the input alignment and tree files, the working directory and 29 the final output file. 30 """ 31 Paml.__init__(self, alignment, working_dir, out_file) 32 if tree is not None: 33 if not os.path.exists(tree): 34 raise IOError("The specified tree file does not exist.") 35 self.tree = tree 36 self.ctl_file = "baseml.ctl" 37 self._options = {"noisy": None, 38 "verbose": None, 39 "runmode": None, 40 "model": None, 41 "model_options": None, 42 "Mgene": None, 43 "ndata": None, 44 "clock": None, 45 "fix_kappa": None, 46 "kappa": None, 47 "fix_alpha": None, 48 "alpha": None, 49 "Malpha": None, 50 "ncatG": None, 51 "fix_rho": None, 52 "rho": None, 53 "nparK": None, 54 "nhomo": None, 55 "getSE": None, 56 "RateAncestor": None, 57 "Small_Diff": None, 58 "cleandata": None, 59 "icode": None, 60 "fix_blength": None, 61 "method": None}
62
63 - def write_ctl_file(self):
64 """Dynamically build a BASEML control file from the options. 65 66 The control file is written to the location specified by the 67 ctl_file property of the baseml class. 68 """ 69 # Make sure all paths are relative to the working directory 70 self._set_rel_paths() 71 if True: # Dummy statement to preserve indentation for diff 72 with open(self.ctl_file, 'w') as ctl_handle: 73 ctl_handle.write("seqfile = %s\n" % self._rel_alignment) 74 ctl_handle.write("outfile = %s\n" % self._rel_out_file) 75 ctl_handle.write("treefile = %s\n" % self._rel_tree) 76 for option in self._options.items(): 77 if option[1] is None: 78 # If an option has a value of None, there's no need 79 # to write it in the control file; it's normally just 80 # commented out. 81 continue 82 if option[0] == "model_options": 83 continue 84 # If "model" is 9 or 10, it may be followed in the cotnrol 85 # file by further options such as 86 # [1 (TC CT AG GA)] 87 # or 88 # [5 (AC CA) (AG GA) (AT TA) (CG GC) (CT TC)] 89 # which are to be stored in "model_options" as a string. 90 if option[0] == "model" and option[1] in [9, 10]: 91 if self._options["model_options"] is not None: 92 ctl_handle.write("model = %s %s" % (option[1], 93 self._options["model_options"])) 94 continue 95 ctl_handle.write("%s = %s\n" % (option[0], option[1]))
96
97 - def read_ctl_file(self, ctl_file):
98 """Parse a control file and load the options into the Baseml instance. 99 """ 100 temp_options = {} 101 if not os.path.isfile(ctl_file): 102 raise IOError("File not found: %r" % ctl_file) 103 else: 104 with open(ctl_file) as ctl_handle: 105 for line in ctl_handle: 106 line = line.strip() 107 uncommented = line.split("*",1)[0] 108 if uncommented != "": 109 if "=" not in uncommented: 110 raise AttributeError( 111 "Malformed line in control file:\n%r" % line) 112 (option, value) = uncommented.split("=") 113 option = option.strip() 114 value = value.strip() 115 if option == "seqfile": 116 self.alignment = value 117 elif option == "treefile": 118 self.tree = value 119 elif option == "outfile": 120 self.out_file = value 121 elif option not in self._options: 122 raise KeyError("Invalid option: %s" % option) 123 elif option == "model": 124 if len(value) <= 2 and value.isdigit(): 125 temp_options["model"] = int(value) 126 temp_options["model_options"] = None 127 else: 128 model_num = value.partition(" ")[0] 129 model_opt = value.partition(" ")[2].strip() 130 temp_options["model"] = int(model_num) 131 temp_options["model_options"] = model_opt 132 else: 133 if "." in value or "e-" in value: 134 try: 135 converted_value = float(value) 136 except: 137 converted_value = value 138 else: 139 try: 140 converted_value = int(value) 141 except: 142 converted_value = value 143 temp_options[option] = converted_value 144 for option in self._options.keys(): 145 if option in temp_options.keys(): 146 self._options[option] = temp_options[option] 147 else: 148 self._options[option] = None
149
150 - def _set_rel_paths(self):
151 """Convert all file/directory locations to paths relative to the current working directory. 152 153 BASEML requires that all paths specified in the control file be 154 relative to the directory from which it is called rather than 155 absolute paths. 156 """ 157 Paml._set_rel_paths(self) 158 if self.tree is not None: 159 self._rel_tree = _relpath(self.tree, self.working_dir)
160
161 - def run(self, ctl_file = None, verbose = False, command = "baseml", 162 parse = True):
163 """Run baseml using the current configuration and then parse the results. 164 165 Return a process signal so the user can determine if 166 the execution was successful (return code 0 is successful, -N 167 indicates a failure). The arguments may be passed as either 168 absolute or relative paths, despite the fact that BASEML 169 requires relative paths. 170 """ 171 if self.tree is None: 172 raise ValueError("Tree file not specified.") 173 if not os.path.exists(self.tree): 174 raise IOError("The specified tree file does not exist.") 175 Paml.run(self, ctl_file, verbose, command) 176 if parse: 177 results = read(self.out_file) 178 else: 179 results = None 180 return results
181 182
183 -def read(results_file):
184 results = {} 185 """Parse a BASEML results file.""" 186 if not os.path.exists(results_file): 187 raise IOError("Results file does not exist.") 188 handle = open(results_file) 189 lines = handle.readlines() 190 handle.close() 191 (results, num_params) = _parse_baseml.parse_basics(lines, results) 192 results = _parse_baseml.parse_parameters(lines, results, num_params) 193 if results.get("version") is None: 194 raise ValueError("Invalid results file") 195 return results
196