Back to index

python-biopython  1.60
yn00.py
Go to the documentation of this file.
00001 # Copyright (C) 2011 by Brandon Invergo (b.invergo@gmail.com)
00002 # This code is part of the Biopython distribution and governed by its
00003 # license. Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 
00006 import os.path
00007 from _paml import Paml, PamlError
00008 import _parse_yn00
00009 
00010 #TODO - Restore use of with statement for closing handles automatically
00011 #after dropping Python 2.4
00012 
00013 class Yn00Error(EnvironmentError):
00014     """yn00 has failed. Run with verbose = True to view yn00's error
00015 message"""
00016 
00017 class Yn00(Paml):
00018     """This class implements an interface to yn00, part of the PAML package."""
00019 
00020     def __init__(self, alignment = None, working_dir = None,
00021                 out_file = None):
00022         """Initialize the Yn00 instance. 
00023         
00024         The user may optionally pass in strings specifying the locations
00025         of the input alignment, the working directory and
00026         the final output file. 
00027         """
00028         Paml.__init__(self, alignment, working_dir, out_file)
00029         self.ctl_file = "yn00.ctl"
00030         self._options = {"verbose": None,
00031                         "icode": None,
00032                         "weighting": None,
00033                         "commonf3x4": None,
00034                         "ndata": None}
00035 
00036     def write_ctl_file(self):
00037         """Dynamically build a yn00 control file from the options.
00038         
00039         The control file is written to the location specified by the 
00040         ctl_file property of the yn00 class.
00041         """
00042         # Make sure all paths are relative to the working directory
00043         self._set_rel_paths()
00044         if True: #Dummy statement to preserve indentation for diff
00045             ctl_handle = open(self.ctl_file, 'w')
00046             ctl_handle.write("seqfile = %s\n" % self._rel_alignment)
00047             ctl_handle.write("outfile = %s\n" % self._rel_out_file)
00048             for option in self._options.items():
00049                 if option[1] is None:
00050                     # If an option has a value of None, there's no need
00051                     # to write it in the control file; it's normally just
00052                     # commented out.
00053                     continue
00054                 ctl_handle.write("%s = %s\n" % (option[0], option[1]))
00055             ctl_handle.close()
00056 
00057     def read_ctl_file(self, ctl_file):
00058         """Parse a control file and load the options into the yn00 instance.
00059         """
00060         temp_options = {}
00061         if not os.path.isfile(ctl_file):
00062             raise IOError("File not found: %r" % ctl_file)
00063         else:
00064             ctl_handle = open(ctl_file)
00065             for line in ctl_handle:
00066                 line = line.strip()
00067                 uncommented = line.split("*",1)[0]
00068                 if uncommented != "":
00069                     if "=" not in uncommented:
00070                         ctl_handle.close()
00071                         raise AttributeError, \
00072                             "Malformed line in control file:\n%r" % line
00073                     (option, value) = uncommented.split("=")
00074                     option = option.strip()
00075                     value = value.strip()
00076                     if option == "seqfile":
00077                         self.alignment = value
00078                     elif option == "outfile":
00079                         self.out_file = value
00080                     elif option not in self._options:
00081                         ctl_handle.close()
00082                         raise KeyError, "Invalid option: %s" % option
00083                     else:
00084                         if "." in value or "e-" in value:
00085                             try:
00086                                 converted_value = float(value)
00087                             except:
00088                                 converted_value = value
00089                         else:
00090                             try:
00091                                 converted_value = int(value)
00092                             except:
00093                                 converted_value = value
00094                         temp_options[option] = converted_value
00095             ctl_handle.close()
00096         for option in self._options.keys():
00097             if option in temp_options.keys():
00098                 self._options[option] = temp_options[option]
00099             else:
00100                 self._options[option] = None
00101                 
00102     def run(self, ctl_file = None, verbose = False, command = "yn00",
00103                 parse = True):
00104         Paml.run(self, ctl_file, verbose, command)
00105         if parse:
00106             results = read(self.out_file)
00107         else:
00108             results = None
00109         return results
00110 
00111 def read(results_file):
00112     """Parse a yn00 results file."""
00113     results = {}
00114     if not os.path.exists(results_file):
00115         raise IOError, "Results file does not exist."
00116     handle = open(results_file)
00117     lines = handle.readlines()
00118     handle.close()
00119     for line_num in range(len(lines)):
00120         line = lines[line_num]
00121         if "(A) Nei-Gojobori (1986) method" in line:
00122             ng86_start = line_num + 1 
00123         elif "(B) Yang & Nielsen (2000) method" in line:
00124             (results, sequences) = _parse_yn00.parse_ng86(lines[ng86_start:line_num], 
00125                     results)
00126             yn00_start = line_num + 1
00127         elif "(C) LWL85, LPB93 & LWLm methods" in line:
00128             results = _parse_yn00.parse_yn00(lines[yn00_start:line_num], results, 
00129                     sequences)
00130             results = _parse_yn00.parse_others(lines[line_num+1:], results, 
00131                     sequences)
00132     if len(results) == 0:
00133         raise ValueError, "Invalid results file."
00134     return results
00135 
00136