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