1
2
3
4
5
6 import os
7 import subprocess
8
9 try:
10 from os.path import relpath as _relpath
11 except ImportError:
12
14 """Return a relative version of a path.
15
16 Implementation by James Gardner in his BareNecessities
17 package, under MIT licence.
18
19 With a fix for Windows where posixpath.sep (and functions like
20 join) use the Unix slash not the Windows slash.
21 """
22 import posixpath
23 if start is None:
24 start = posixpath.curdir
25 else:
26 start = start.replace(os.path.sep, posixpath.sep)
27 if not path:
28 raise ValueError("no path specified")
29 else:
30 path = path.replace(os.path.sep, posixpath.sep)
31 start_list = posixpath.abspath(start).split(posixpath.sep)
32 path_list = posixpath.abspath(path).split(posixpath.sep)
33
34 i = len(posixpath.commonprefix([start_list, path_list]))
35 rel_list = [posixpath.pardir] * (len(start_list)-i) + path_list[i:]
36 if not rel_list:
37 return posixpath.curdir.replace(posixpath.sep, os.path.sep)
38 return posixpath.join(*rel_list).replace(posixpath.sep, os.path.sep)
39
41 """paml has failed. Run with verbose = True to view the error
42 message"""
43
45
46 - def __init__(self, alignment = None, working_dir = None,
47 out_file = None):
48 if working_dir is None:
49 self.working_dir = os.getcwd()
50 else:
51 self.working_dir = working_dir
52 if alignment is not None:
53 if not os.path.exists(alignment):
54 raise IOError, "The specified alignment file does not exist."
55 self.alignment = alignment
56 self.out_file = out_file
57
60
63
65 """Print out all of the options and their current settings."""
66 for option in self._options.items():
67 print "%s = %s" % (option[0], option[1])
68
70 """Set the value of an option.
71
72 This function abstracts the options dict to prevent the user from
73 adding options that do not exist or mispelling options.
74 """
75 for option, value in kwargs.items():
76 if not self._options.has_key(option):
77 raise KeyError, "Invalid option: " + option
78 else:
79 self._options[option] = value
80
82 """Return the value of an option."""
83 if not self._options.has_key(option):
84 raise KeyError, "Invalid option: " + option
85 else:
86 return self._options.get(option)
87
89 """Return the values of all the options."""
90 return self._options.items()
91
93 """Convert all file/directory locations to paths relative to the current working directory.
94
95 paml requires that all paths specified in the control file be
96 relative to the directory from which it is called rather than
97 absolute paths.
98 """
99 if self.working_dir is not None:
100 self._rel_working_dir = _relpath(self.working_dir)
101 if self.alignment is not None:
102 self._rel_alignment = _relpath(self.alignment,
103 self.working_dir)
104 if self.out_file is not None:
105 self._rel_out_file = _relpath(self.out_file, self.working_dir)
106
107 - def run(self, ctl_file, verbose, command):
108 """Run a paml program using the current configuration and then parse the results.
109
110 Return a process signal so the user can determine if
111 the execution was successful (return code 0 is successful, -N
112 indicates a failure). The arguments may be passed as either
113 absolute or relative paths, despite the fact that paml
114 requires relative paths.
115 """
116 if self.alignment is None:
117 raise ValueError, "Alignment file not specified."
118 if not os.path.exists(self.alignment):
119 raise IOError, "The specified alignment file does not exist."
120 if self.out_file is None:
121 raise ValueError, "Output file not specified."
122 if self.working_dir is None:
123 raise ValueError, "Working directory not specified."
124
125 cwd = os.getcwd()
126
127 if not os.path.exists(self.working_dir):
128 os.mkdir(self.working_dir)
129 os.chdir(self.working_dir)
130
131 if ctl_file is None:
132
133 self.write_ctl_file()
134 if verbose:
135 result_code = subprocess.call([command, self.ctl_file])
136 else:
137
138 result_code = subprocess.call([command, self.ctl_file],
139 stdout=subprocess.PIPE)
140 else:
141 if not os.path.exists(ctl_file):
142 raise IOError, "The specified control file does not exist."
143 if verbose:
144 result_code = subprocess.call([command, ctl_file])
145 else:
146 result_code = subprocess.call([command, ctl_file],
147 stdout=subprocess.PIPE)
148 os.chdir(cwd)
149 if result_code > 0:
150
151 raise PamlError, \
152 "%s has failed (return code %i). Run with verbose = True to view error message" \
153 % (command, result_code)
154 if result_code < 0:
155
156 raise EnvironmentError, "The %s process was killed (return code %i)." \
157 % (command, result_code)
158