require 'genevalidator/version' require 'fileutils' require 'erb' require 'yaml' require 'thread' module GeneValidator class Output attr_accessor :prediction_len attr_accessor :prediction_def attr_accessor :nr_hits # list of +ValidationReport+ objects attr_accessor :validations attr_accessor :filename attr_accessor :html_path attr_accessor :yaml_path attr_accessor :idx attr_accessor :start_idx attr_accessor :overall_score attr_accessor :fails attr_accessor :successes attr_accessor :mutex attr_accessor :mutex_yaml attr_accessor :mutex_html ## # Initilizes the object # Params: # +mutex+: +Mutex+ for exclusive access to the console # +mutex_yaml+: +Mutex+ for exclusive access to the YAML file # +mutex_html+: +Mutex+ for exclusive access to the HTML file # +filename+: name of the fasta input file # +html_path+: path of the html folder # +yaml_path+: path where the yaml output wil be saved # +idx+: idnex of the current query # +start_idx+: number of the sequence from the file to start with def initialize(mutex, mutex_yaml, mutex_html, filename, html_path, yaml_path, idx = 0, start_idx = 0) @prediction_len = 0 @prediction_def = 'no_definition' @nr_hits = 0 @filename = filename @html_path = html_path @yaml_path = yaml_path @idx = idx @start_idx = start_idx @mutex = mutex @mutex_yaml = mutex_yaml @mutex_html = mutex_html end def print_output_console if @idx == @start_idx header = sprintf('%3s|%s|%20s|%5s', 'No', 'Score', 'Identifier', 'No_Hits') validations.map do |v| header << "|#{v.short_header}" end puts header end short_def = @prediction_def.scan(/([^ ]+)/)[0][0] validation_outputs = validations.map(&:print) output = sprintf('%3s|%d|%20s|%5s|', @idx, @overall_score, short_def, @nr_hits) validation_outputs.each do |item| output << item output << '|' end @mutex.synchronize do puts output.gsub(' ', ' ') end end def print_output_file_yaml file_yaml = "#{@yaml_path}/#{@filename}.yaml" report = validations if @idx == @start_idx @mutex_yaml.synchronize do File.open(file_yaml, 'w') do |f| YAML.dump({ @prediction_def.scan(/([^ ]+)/)[0][0] => report }, f) end end else @mutex_yaml.synchronize do hash = {} # YAML.load_file(file_yaml) hash[@prediction_def.scan(/([^ ]+)/)[0][0]] = report File.open(file_yaml, 'a') do |f| new_report = hash.to_yaml f.write(new_report[4..new_report.length - 1]) end end end end def generate_html if @fails == 0 bg_icon = 'success' else bg_icon = 'danger' end index_file = "#{@html_path}/results.html" table_file = "#{@html_path}/files/table.html" aux_dir = File.join(File.dirname(File.expand_path(__FILE__)), '../../aux') # if it's the first time I write in the html file if @idx == @start_idx @mutex_html.synchronize do template_header = File.join(aux_dir, 'template_header.erb') template_file = File.open(template_header, 'r').read erb = ERB.new(template_file, 0, '>') # Creating a Separate output file for the web app app_template_header = File.join(aux_dir, 'app_template_header.erb') table_template_file = File.open(app_template_header, 'r').read erb_table = ERB.new(table_template_file, 0, '>') File.open(index_file, 'w+') do |file| file.write(erb.result(binding)) end File.open(table_file, 'w+') do |file| file.write(erb_table.result(binding)) end end end toggle = "toggle#{@idx}" @mutex_yaml.synchronize do template_query = File.join(aux_dir, 'template_query.erb') template_file = File.open(template_query, 'r').read erb = ERB.new(template_file, 0, '>') File.open(index_file, 'a') do |file| file.write(erb.result(binding)) end File.open(table_file, 'a') do |file| file.write(erb.result(binding)) end end end ## # Method that closes the gas in the html file and writes the overall # evaluation # Param: # +all_query_outputs+: array with +ValidationTest+ objects # +html_path+: path of the html folder # +filemane+: name of the fasta input file # def self.print_footer(all_query_outputs, html_path, filename) def self.print_footer(no_queries, scores, good_predictions, bad_predictions, nee, no_mafft, no_internet, map_errors, running_times, html_path, filename) # compute the statistics # overall_evaluation = overall_evaluation(all_query_outputs, filename) overall_evaluation = overall_evaluation(no_queries, good_predictions, bad_predictions, nee, no_mafft, no_internet, map_errors, running_times) less = overall_evaluation[0] less = less.gsub("\n", '
').gsub("'", %q(\\\')) # print to console evaluation = '' overall_evaluation.each { |e| evaluation << "\n#{e}" } puts evaluation puts '' # print to html # make the historgram with the resulted scores statistics_filename = "#{html_path}/files/json/#{filename}_statistics.json" f = File.open(statistics_filename, 'w') f.write( [scores.group_by { |a| a }.map { |k, vs| { 'key' => k, 'value' => vs.length, 'main' => false } }].to_json) f.close plot_statistics = Plot.new("files/json/#{filename}_statistics.json", :simplebars, 'Overall evaluation', '', 'validation score', 'number of queries', 10) evaluation = evaluation.gsub("\n", '
').gsub("'", %q(\\\')) index_file = "#{html_path}/results.html" table_file = "#{html_path}/files/table.html" aux_dir = File.join(File.dirname(File.expand_path(__FILE__)), '../../aux') template_footer = File.join(aux_dir, 'template_footer.erb') app_template_footer = File.join(aux_dir, 'app_template_footer.erb') template_file = File.open(template_footer, 'r').read erb = ERB.new(template_file, 0, '>') File.open(index_file, 'a+') do |file| file.write(erb.result(binding)) end table_footer_template = File.open(app_template_footer, 'r').read table_erb = ERB.new(table_footer_template, 0, '>') File.open(table_file, 'a+') do |file| file.write(table_erb.result(binding)) end end ## # Calculates an overall evaluation of the output # Params: # +all_query_outputs+: Array of +ValidationTest+ objects # Output # Array of Strigs with the reports def self.overall_evaluation(no_queries, good_scores, bad_scores, no_evidence, no_mafft, no_internet, map_errors, running_times) good_pred = (good_scores == 1) ? 'One' : "#{good_scores} are" bad_pred = (bad_scores == 1) ? 'One' : "#{bad_scores} are" eval = "Overall Query Score Evaluation:\n" \ "#{no_queries} predictions were validated, from which there" \ " were:\n" \ "#{good_pred} good prediction(s),\n" \ "#{bad_pred} possibly weak prediction(s).\n" if no_evidence != 0 eval << "#{no_evidence} could not be evaluated due to the lack of" \ ' evidence.' end # errors per validation error_eval = '' map_errors.each do |k, v| error_eval << "\nWe couldn't run #{k} Validation for #{v} queries" end if no_mafft >= (no_queries - no_evidence) error_eval << "\nWe couldn't run MAFFT multiple alignment" end if no_internet >= (no_queries - no_evidence) error_eval << "\nWe couldn't make use of your internet connection" end time_eval = '' running_times.each do |key, value| average_time = value.x / (value.y + 0.0) time_eval << "\nAverage running time for #{key} Validation:" \ " #{average_time.round(3)}s per validation" end overall_evaluation = [eval, error_eval, time_eval] overall_evaluation.select { |e| e != '' } end end end