Created
October 13, 2009 15:55
-
-
Save antunderwood/209308 to your computer and use it in GitHub Desktop.
crowd server action
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Splits up alignemnt into block sized chunks and then render them as html | |
class RenderAlignment < CloudCrowd::Action | |
require 'rubygems' | |
require 'bio' | |
# Split up alignment | |
def split | |
fasta_sequences = Bio::FlatFile.open(input_path).to_a | |
alignment = Bio::Alignment.new(fasta_sequences) | |
block_size = options['block_size'] | |
number_of_blocks = (alignment.alignment_length/block_size.to_f).ceil | |
(1..number_of_blocks).each do |block_number| | |
start_of_slice = (block_number-1)*block_size | |
end_of_slice = (block_number*block_size)-1 | |
alignment_slice = alignment.alignment_slice(start_of_slice..end_of_slice) | |
slicefile = File.new("alignslice-#{block_number}.fas", "w") | |
slicefile.write(alignment_slice.output_fasta) | |
slicefile.close | |
end | |
alignment_files = Dir["alignslice-*"].map {|slice| save(slice) } | |
alignment_files.to_json | |
end | |
# Convert an alignment into html | |
def process | |
# read in alignment | |
fasta_sequences = Bio::FlatFile.open(input_path).to_a | |
alignment = Bio::Alignment.new(fasta_sequences) | |
alignment.alignment_length | |
input_path.match(/alignslice-(\d+)\.fas$/) | |
block_number = $1.to_i | |
process_options = {'consensus_threshold' => 0.7 ,'block_size' => 81, 'highlight_colour' => "#6666FF", 'draw_ruler' => true, 'translate' => false , 'consensus' => false}.me | |
rge(options) | |
# find maximum sequence | |
max_name_length = (alignment.sequence_names.collect{|sequence_name| sequence_name.length}).max | |
sequence_names = alignment.sequence_names.collect{|sequence_name| sprintf("%#{max_name_length}s", sequence_name)} | |
sequence_names.collect!{|sequence_name| sequence_name.gsub(/\s/, " ") + " "} | |
html_string ="" | |
# generate consensus sequence string | |
consensus = alignment.consensus_string(process_options['consensus_threshold']) | |
if process_options['consensus'] | |
html_string << sprintf("%#{max_name_length}s", "consensus").gsub(/\s/, " ") + " " | |
html_string << consensus | |
html_string << "<br/>" | |
end | |
# print out sequences | |
sequences = alignment.alignment_collect{|sequence| sequence} | |
sequences.each_with_index do |sequence, index| | |
#set consensus match to false | |
consensus_mismatch = false | |
# print sequence name | |
html_string << sequence_names[index] | |
# loop through sequence blocks | |
(0..alignment.alignment_length-1).each do |alignment_position| | |
sequence_letter = sequence.slice(alignment_position,1).to_s | |
if sequence_letter == "X" or sequence_letter == "Z"# dodgy amino acid or stop | |
if consensus_mismatch == true | |
consensus_mismatch = false | |
html_string << "</span>" | |
end | |
# add base to html_string | |
if sequence_letter == "Z" | |
html_string << "<span style='background-color: #FF0000'>*</span>" | |
else | |
html_string << "<span style='background-color: #FF0000'>" + sequence_letter + "</span>" | |
end | |
elsif sequence_letter != consensus.slice(alignment_position,1).to_s # not a match | |
if consensus_mismatch == false | |
consensus_mismatch = true | |
html_string << "<span style='background-color: #{process_options['highlight_colour']}'>" | |
end | |
# add base to html_string | |
html_string << sequence_letter | |
else # a match | |
if consensus_mismatch == true | |
consensus_mismatch = false | |
html_string << "</span>" | |
end | |
# add base to html_string | |
if process_options['consensus'] | |
html_string << "." | |
else | |
html_string << sequence_letter | |
end | |
end | |
end | |
html_string << "</span>" if consensus_mismatch == true | |
html_string << "<br/>" | |
#translate ? | |
if process_options['translate'] | |
(max_name_length+1).times{html_string << " "} | |
(0..alignment.alignment_length-1).each do |alignment_position| | |
if alignment_position%3 == 0 | |
amino_acid = Bio::CodonTable::TABLES[1][sequence.slice(alignment_position,3).downcase] | |
if amino_acid.nil? | |
if sequence.slice(alignment_position,3) == "---" | |
html_string << " " | |
else | |
html_string << "X" | |
end | |
else | |
html_string << "#{amino_acid}" | |
end | |
else | |
html_string << " " | |
end | |
end | |
html_string << "<br/>" | |
end | |
end # end of sequence loop | |
# ruler drawing | |
if process_options['draw_ruler'] | |
# draw ticks | |
(max_name_length+1).times do html_string << " " end | |
(((block_number-1)*process_options['block_size'])+1..(block_number*process_options['block_size'])).each do |alignment_position| | |
break if alignment_position > ((block_number-1)*process_options['block_size']) + alignment.alignment_length | |
if alignment_position%10 == 0 | |
html_string << "|" | |
else | |
html_string << " " | |
end | |
end | |
# end | |
html_string << "<br/>" | |
# draw numbers | |
(max_name_length+1).times do html_string << " " end | |
alignment_position = ((block_number-1)*process_options['block_size'])+1 | |
while alignment_position <= (block_number*process_options['block_size']) do | |
break if alignment_position > ((block_number-1)*process_options['block_size']) + alignment.alignment_length | |
if alignment_position%10 == 0 | |
html_string << alignment_position.to_s | |
alignment_position += alignment_position.to_s.length | |
else | |
html_string << " " | |
alignment_position += 1 | |
end | |
end | |
html_string << "<br/>" | |
end # end of ruler drawing | |
html_string << "<br/>" | |
{'block_number' => block_number , 'html_string' => html_string} | |
end | |
# Merge all resulting htmls into one | |
def merge | |
all_htmls = Array.new | |
input.each do |html_data| | |
all_htmls[html_data['block_number']-1] = html_data['html_string'] | |
end | |
final_html_string = "" | |
all_htmls.each do |html_string| | |
final_html_string << html_string | |
end | |
final_html_string | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment