class Bio::PAML::Common

Description

Bio::PAML::Common is a basic wrapper class for PAML programs. The class provides methods for generating the necessary configuration file, and running a program.

Constants

DEFAULT_PARAMETERS

Default parameters. Should be redefined in subclass.

DEFAULT_PARAMETERS_ORDER

Preferred order of parameters.

DEFAULT_PROGRAM

Default program. Should be redifined in subclass.

Attributes

command[R]

the last executed command (Array of String)

data_stdout[R]

the last output to the stdout (String)

exit_status[R]

the last exit status of the program

output[R]

the last result of the program (String)

parameters[RW]

Parameters described in the control file. (Hash) Each key of the hash must be a Symbol object, and each value must be a String object or nil.

report[R]

Report object created from the last result

supplemental_outputs[R]

contents of supplemental output files (Hash). Each key is a file name and value is content of the file.

Public Class Methods

new(program = nil, params = {}) click to toggle source

Creates a wrapper instance, which will run using the specified binary location or the command in the PATH. If program is specified as nil, DEFAULT_PROGRAM is used. Default parameters are automatically loaded and merged with the specified parameters.


Arguments:

  • (optional) program: path to the program, or command name (String)

  • (optional) params: parameters (Hash)

   # File lib/bio/appl/paml/common.rb
73 def initialize(program = nil, params = {})
74   @program = program || self.class::DEFAULT_PROGRAM
75   set_default_parameters
76   self.parameters.update(params)
77 end

Public Instance Methods

dump_parameters() click to toggle source

Shows parameters (content of control file) as a string. The string can be used for control file.


Returns

string representation of the parameters (String)

    # File lib/bio/appl/paml/common.rb
270 def dump_parameters
271   keyorder = DEFAULT_PARAMETERS_ORDER
272   keys = parameters.keys
273   str = ''
274   keys.sort do |x, y|
275     (keyorder.index(x) || (keyorder.size + keys.index(x))) <=>
276       (keyorder.index(y) || (keyorder.size + keys.index(y)))
277   end.each do |key|
278     value = parameters[key]
279     # Note: spaces are required in both side of the "=".
280     str.concat "#{key.to_s} = #{value.to_s}\n" if value
281   end
282   str
283 end
load_parameters(str) click to toggle source

Loads parameters from the specified string. Note that all previous parameters are erased. Returns the parameters as a hash.


Arguments:

  • (required) str: contents of a PAML control file (String)

Returns

parameters (Hash)

    # File lib/bio/appl/paml/common.rb
248 def load_parameters(str)
249   hash = {}
250   str.each_line do |line|
251     param, value = parse_parameter(line)
252     hash[param] = value if param
253   end
254   self.parameters = hash
255 end
query(alignment, tree = nil) click to toggle source

Runs the program on the internal parameters with the specified sequence alignment and tree.

Note that parameters and parameters are always modified, and parameters is modified when tree is specified.

To prevent overwrite of existing files by PAML, this method automatically creates a temporary directory and the program is run inside the directory. After the end of the program, the temporary directory is automatically removed.


Arguments:

Returns

Report object

    # File lib/bio/appl/paml/common.rb
117 def query(alignment, tree = nil)
118   astr = alignment.output(:phylipnon)
119   if tree then
120     tstr = [ sprintf("%3d %2d\n", tree.leaves.size, 1), "\n",
121              tree.output(:newick,
122                          { :indent => false,
123                            :bootstrap_style => :disabled,
124                            :branch_length_style => :disabled })
125            ].join('')
126   else
127     tstr = nil
128   end
129   str = _query_by_string(astr, tstr)
130   @report = self.class::Report.new(str)
131   @report
132 end
query_by_string(alignment = nil, tree = nil) click to toggle source

Runs the program on the internal parameters with the specified sequence alignment data string and tree data string.

Note that parameters is always modified, and parameters and parameters are modified when alignment and tree are specified respectively.

It raises RuntimeError if seqfile is not specified in the argument or in the parameter.

For other information, see the document of query method.


Arguments:

  • (optional) alignment: String

  • (optional) tree: String or nil

Returns

contents of output file (String)

    # File lib/bio/appl/paml/common.rb
151 def query_by_string(alignment = nil, tree = nil)
152   _query_by_string(alignment, tree)
153 end
run(control_file) click to toggle source

Runs the program on the parameters in the passed control file. No parameters checks are performed. All internal parameters are ignored and are kept untouched. The output and report attributes are cleared in this method.

Warning about PAML's behavior: PAML writes supplemental output files in the current directory with fixed file names which can not be changed with parameters or command-line options, for example, rates, rst, and rub. This behavior may ovarwrite existing files, especially previous supplemental results.


Arguments:

  • (optional) control_file: file name of control file (String)

Returns

messages printed to the standard output (String)

   # File lib/bio/appl/paml/common.rb
95 def run(control_file)
96   exec_local([ control_file ])
97 end
set_default_parameters() click to toggle source

Loads system-wide default parameters. Note that all previous parameters are erased. Returns the parameters as a hash.


Returns

parameters (Hash)

    # File lib/bio/appl/paml/common.rb
262 def set_default_parameters
263   self.parameters = self.class::DEFAULT_PARAMETERS.merge(Hash.new)
264 end

Private Instance Methods

_query_by_string(alignment = nil, tree = nil) click to toggle source

(private) implementation of query_by_string().

    # File lib/bio/appl/paml/common.rb
156 def _query_by_string(alignment = nil, tree = nil)
157   @parameters ||= {}
158   Bio::Command.mktmpdir('paml') do |path|
159     #$stderr.puts path.inspect
160     filenames = []
161     begin
162       # preparing outfile
163       outfile = Tempfile.new('out', path)
164       outfile.close(false)
165       outfn = File.basename(outfile.path)
166       self.parameters[:outfile] = outfn
167       filenames.push outfn
168       # preparing seqfile
169       if alignment then
170         seqfile = Tempfile.new('seq', path)
171         seqfile.print alignment
172         seqfile.close(false)
173         seqfn = File.basename(seqfile.path)
174         self.parameters[:seqfile] = seqfn
175         filenames.push seqfn
176       end
177       # preparing treefile
178       if tree then
179         treefile = Tempfile.new('tree', path)
180         treefile.print tree
181         treefile.close(false)
182         treefn = File.basename(treefile.path)
183         self.parameters[:treefile] = treefn
184         filenames.push treefn
185       end
186       # preparing control file
187       ctlfile = Tempfile.new('control', path)
188       ctlfile.print self.dump_parameters
189       ctlfile.close(false)
190       ctlfn = File.basename(ctlfile.path)
191       filenames.push ctlfn
192       # check parameters
193       if errors = check_parameters then
194         msg = errors.collect { |e| "error in parameter #{e[0]}: #{e[1]}" }
195         raise RuntimeError, msg.join("; ")
196       end
197       # exec command
198       exec_local([ ctlfn ], { :chdir => path })
199       # get main output
200       outfile.open
201       @output = outfile.read
202       # get supplemental result files
203       @supplemental_outputs = {}
204       (Dir.entries(path) - filenames).each do |name|
205         next unless /\A\w/ =~ name
206         fn = File.join(path, name)
207         if File.file?(fn) then
208           @supplemental_outputs[name] = File.read(fn)
209         end
210       end
211     ensure
212       outfile.close(true) if outfile
213       seqfile.close(true) if seqfile
214       treefile.close(true) if treefile
215       ctlfile.close(true) if ctlfile
216     end
217   end
218   @output
219 end
check_parameters() click to toggle source

(private) Checks parameters. Returns nil if no errors found. Otherwise, returns an Array containing [ parameter, message ] pairs.


Arguments:

Returns

nil or Array

    # File lib/bio/appl/paml/common.rb
337 def check_parameters
338   errors = []
339   param = self.parameters
340   if !param[:seqfile] or param[:seqfile].empty? then
341     errors.push([ :seqfile, 'seqfile not specified' ]) 
342   end
343   errors.empty? ? nil : errors
344 end
exec_local(arguments, options = {}) click to toggle source

(private) Runs the program on the parameters in the passed control file. No parameter check are executed.


Arguments:

  • (optional) control_file: file name of control file (String)

Returns

messages printed to the standard output (String)

    # File lib/bio/appl/paml/common.rb
321 def exec_local(arguments, options = {})
322   reset
323   cmd = [ @program, *arguments ]
324   @command = cmd
325   stdout = Bio::Command.query_command(cmd, nil, options)
326   @exit_status = $?
327   @data_stdout = stdout
328   stdout
329 end
parse_parameter(line) click to toggle source

(private) parses a parameter in a line


Arguments:

  • (required) line: single line string (String)

Returns

parameter name (Symbol or nil), value (String or nil)

    # File lib/bio/appl/paml/common.rb
302 def parse_parameter(line)
303   # remove comment
304   line = line.sub(/\*.*/, '')
305   # Note: spaces are required in both side of the "=".
306   param, value = line.strip.split(/\s+=\s+/, 2)
307   if !param or param.empty? then
308     param = nil
309   else
310     param = param.to_sym
311   end
312   return param, value
313 end
reset() click to toggle source

(private) clear attributes except program and parameters

    # File lib/bio/appl/paml/common.rb
288 def reset
289   @command = nil
290   @output = nil
291   @report = nil
292   @exit_status = nil
293   @data_stdout = nil
294   @supplemental_outputs = nil
295 end