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