Skip to content

Instantly share code, notes, and snippets.

@trvrb
Last active December 15, 2015 14:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trvrb/5277297 to your computer and use it in GitHub Desktop.
Save trvrb/5277297 to your computer and use it in GitHub Desktop.
Ruby script to restart BEAST runs. This constructs a new XML control file from the original control file and the last logged parameter values.
#!/usr/bin/ruby
# Designed to allow checkpointing of BEAST output files
# Input: beast_analysis.xml output_file_1.log output_file_2.log ... tree_file.trees
# Expect at least 3 files
# This matches column names in log files to parameter names in the original XML to set initial conditions
xml_filename = ARGV.shift
tree_filename = ARGV.pop
log_filenames = ARGV
# Go through log files and create a hash of parameter name to value
param = Hash.new
log_filenames.each {|log_filename|
lines = File.open(log_filename,"r").readlines
lines.delete_if{|line|
line[0] == "#"
}
names = lines[0].split("\t")
values = lines[-1].split("\t")
names.zip(values).map{|name, value|
param[name] = value
}
}
# If there is a string of names in the form name1 \t name2 \t name3, this is a parameter array
# and its map should be name to a list of values separated by spaces
additional = Hash.new
param.each_pair{|name, value|
m = name.match(/^(\S+[^0-9])[0-9]+$/)
if m != nil
shortname = m[1]
if additional[shortname] == nil
additional[shortname] = "#{value}"
else
additional[shortname] += " #{value}"
end
end
}
param.merge!(additional)
# Remove non-initialized parameters from param.
empty_parameters = ["treeModel.rootHeight"]
empty_parameters.each {|name|
param.delete(name)
}
# Go through trees file and construct hash of id to taxa name
trees = File.open(tree_filename, "r").readlines
taxa = Hash.new
trees.each { |line|
m = line.match(/(\d+) '*([A-Za-z0-9\-\_\.\/\|]+)'*/)
if m != nil
id = m[1]
name = m[2]
taxa[id] = name
end
m = line.match(/tree STATE_/)
if m != nil
break
end
}
# Go through last tree and replace ids with taxa names
tree = trees[-1]
m = tree.match(/tree STATE/)
if m == nil
tree = trees[-2]
end
tree.gsub!(/\d+\[/) {|s| taxa[s.chop]+"[" }
tree.gsub!(/\d+\:/) {|s| taxa[s.chop]+":" }
tree.sub!(/^tree STATE_.+ = \[\&R\] /, "")
# Go through XML file and replace initial parameter values with values from param
hold = false
File.open(xml_filename,"r").each_line {|line|
m = line.match(/<coalescentTree id="startingTree">/)
if m != nil
hold = true
end
m = line.match(/parameter id="([^"]+)"/)
if m != nil
name = m[1]
value = param[name] # check for value in param
if value != nil
n = line.match(/value=/) # check line for value=""
if n != nil
line.sub!(/value="([^"]+)"/, "value=\"#{value}\"")
else
line.sub!(/parameter id="([^"]+)"/, "parameter id=\"#{name}\" value=\"#{value}\"")
end
end
end
if hold == false
puts line
end
m = line.match(/<\/coalescentTree>/)
if m != nil
hold = false
puts "\t<newick id=\"startingTree\">"
puts "\t\t#{tree}"
puts "\t<\/newick>"
puts
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment