From 31f1217be7162aac06aa262376f432f676928749 Mon Sep 17 00:00:00 2001 From: gebele Date: Thu, 9 Nov 2017 14:28:30 +0000 Subject: cleanup and reorder code;save prediction object also for single prediction --- application.rb | 235 ++++++++++++++++++++++++++++++++----------------------- helper.rb | 228 +++++++++++++++++++++++------------------------------ prediction.rb | 7 +- views/batch.haml | 2 +- 4 files changed, 239 insertions(+), 233 deletions(-) diff --git a/application.rb b/application.rb index 13de7ab..21955b5 100644 --- a/application.rb +++ b/application.rb @@ -6,6 +6,8 @@ include OpenTox configure :production, :development do $logger = Logger.new(STDOUT) enable :reloader + also_reload './helper.rb' + also_reload './prediction.rb' end before do @@ -43,71 +45,74 @@ get '/task/?' do task = Task.find(params[:turi].to_s) return JSON.pretty_generate(:percent => task.percent) elsif params[:predictions] + task = Task.find(params[:predictions].to_s) + predictions = task.predictions[params[:model]] pageSize = params[:pageSize].to_i - 1 pageNumber= params[:pageNumber].to_i - 1 - compound = Compound.find @@compounds_ids[pageNumber] + prediction_object = Prediction.find predictions[pageNumber] + prediction = prediction_object.prediction + compound = Compound.find prediction_object.compound + model = Model::Validation.find prediction_object.model image = compound.svg smiles = compound.smiles - task = Task.find(params[:predictions].to_s) - unless task.predictions[params[:model]].nil? - if params[:model] == "Cramer" - prediction = task.predictions[params[:model]] - html = "" - html += "" - string = "" - html += "#{string}
#{image}
#{smiles}
" - string += "" - string += "" - string += "
Cramer rules:#{prediction["Cramer rules"][pageNumber.to_i]}
Cramer rules, with extensions:#{prediction["Cramer rules, with extensions"][pageNumber.to_i]}
" - else - model = Model::Validation.find params[:model].to_s - type = (model.regression? ? "Regression" : "Classification") - html = "" - html += "" - string = "" : "")+(k =~ /lazar/i ? "" + end + string += "
#{image}
#{smiles}
" - prediction = task.predictions[params[:model]][pageNumber.to_i] - sorter = [] - if prediction[:info] - sorter << {"Info" => prediction[:info]} - if prediction["measurements_string"].kind_of?(Array) - sorter << {"Measured activity" => "#{prediction["measurements_string"].join(";")}
#{prediction["converted_measurements"].join(";")}"} - else - sorter << {"Measured activity" => "#{prediction["measurements_string"]}
#{prediction["converted_measurements"]}"} - end - end - - # regression - if prediction[:value] && type == "Regression" - sorter << {"Prediction" => "#{prediction["prediction_value"]}
#{prediction["converted_prediction_value"]}"} - sorter << {"95% Prediction interval" => "#{prediction[:interval]}
#{prediction["converted_interval"]}"} - sorter << {"Warnings" => prediction[:warnings].join("
")} - # classification - elsif prediction[:value] && type == "Classification" - sorter << {"Consensus prediction" => prediction["Consensus prediction"]} - sorter << {"Consensus confidence" => prediction["Consensus confidence"]} - sorter << {"Structural alerts for mutagenicity" => prediction["Structural alerts for mutagenicity"]} - sorter << {"Lazar mutagenicity (Salmonella typhimurium)" => ""} - sorter << {"Prediction" => prediction[:value]} - sorter << {"Probability" => prediction[:probabilities].collect{|k,v| "#{k}: #{v.signif(3)}"}.join("
")} + if params[:model] == "Cramer" + task = Task.find(params[:turi].to_s) + prediction = task.predictions[params[:model]] + html = "
" + html += "" + string = "" + html += "#{string}
#{image}
#{smiles}
" + string += "" + string += "" + string += "
Cramer rules:#{prediction["Cramer rules"][pageNumber.to_i]}
Cramer rules, with extensions:#{prediction["Cramer rules, with extensions"][pageNumber.to_i]}
" + else + type = (model.regression? ? "Regression" : "Classification") + html = "" + html += "" + string = "" - html += "#{string}
#{image}
#{smiles}
" + sorter = [] + if prediction[:info] + prediction[:info] = "This compound was part of the training dataset. All information from this compound was "\ + "removed from the training data before the prediction to obtain unbiased results." + sorter << {"Info" => prediction[:info]} + if prediction["measurements_string"].kind_of?(Array) + sorter << {"Measured activity" => "#{prediction["measurements_string"].join(";")}
#{prediction["converted_measurements"].join(";")}"} else - sorter << {"Warnings" => prediction[:warnings].join("
")} - end - sorter.each_with_index do |hash,idx| - k = hash.keys[0] - v = hash.values[0] - string += (idx == 0 ? "" : "")+(k =~ /lazar/i ? "" + sorter << {"Measured activity" => "#{prediction["measurements_string"]}
#{prediction["converted_measurements"]}"} end - string += "
" : "") - # keyword - string += "#{k}:" - string += "" - # values - string += "#{v}" - string += "
" end + + # regression + if prediction[:value] && type == "Regression" + sorter << {"Prediction" => "#{prediction["prediction_value"]}
#{prediction["converted_prediction_value"]}"} + sorter << {"95% Prediction interval" => "#{prediction[:interval]}
#{prediction["converted_interval"]}"} + sorter << {"Warnings" => prediction[:warnings].join("
")} + # classification + elsif prediction[:value] && type == "Classification" + sorter << {"Consensus prediction" => prediction["Consensus prediction"]} + sorter << {"Consensus confidence" => prediction["Consensus confidence"]} + sorter << {"Structural alerts for mutagenicity" => prediction["Structural alerts for mutagenicity"]} + sorter << {"Lazar mutagenicity (Salmonella typhimurium)" => ""} + sorter << {"Prediction" => prediction[:value]} + sorter << {"Probability" => prediction[:probabilities].collect{|k,v| "#{k}: #{v.signif(3)}"}.join("
")} + else + sorter << {"Warnings" => prediction[:warnings].join("
")} + end + sorter.each_with_index do |hash,idx| + k = hash.keys[0] + v = hash.values[0] + string += (idx == 0 ? "
" : "") + # keyword + string += "#{k}:" + string += "" + # values + string += "#{v}" + string += "
" + html += "#{string}" end - return JSON.pretty_generate(:predictions => [html]) + return JSON.pretty_generate(:prediction => [html]) end end @@ -132,10 +137,18 @@ end get '/predict/csv/:task/:model/:filename/?' do response['Content-Type'] = "text/csv" task = Task.find params[:task].to_s - m = Model::Validation.find params[:model].to_s + m = Model::Validation.find params[:model].to_s unless params[:model] == "Cramer" endpoint = (params[:model] == "Cramer") ? "Oral_toxicity_(Cramer_rules)" : (m.endpoint =~ /Mutagenicity/i ? "Consensus_mutagenicity" : "#{m.endpoint}_(#{m.species})") tempfile = Tempfile.new - tempfile.write(task.csv) + if params[:model] == "Cramer" + tempfile.write(task.csv) + else + header = task.csv + lines = [] + task.predictions[params[:model]].each_with_index{|p,idx| lines << "#{idx+1},#{Prediction.find(p).csv}"} + csv = header + lines.join("") + tempfile.write(csv) + end tempfile.rewind send_file tempfile, :filename => "#{Time.now.strftime("%Y-%m-%d")}_lazar_batch_prediction_#{endpoint}_#{params[:filename]}", :type => "text/csv", :disposition => "attachment" end @@ -202,13 +215,21 @@ post '/predict/?' do p = 100.0/@compounds.size counter = 1 predictions = [] - @compounds.each do |compound| + @compounds.each_with_index do |compound,idx| if Prediction.where(compound: compound.id, model: m.id).exists? - prediction = Prediction.find_by(compound: compound.id, model: m.id).prediction + prediction_object = Prediction.find_by(compound: compound.id, model: m.id) + prediction = prediction_object.prediction + prediction_id = prediction_object.id + # in case prediction object was created by single prediction + if prediction_object.csv.blank? + prediction_object[:csv] = prediction_to_csv(m,compound,prediction) + prediction_object.save + end else prediction = m.predict(compound) # save prediction object prediction_object = Prediction.new + prediction_id = prediction_object.id prediction_object[:compound] = compound.id prediction_object[:model] = m.id if type == "Classification"# consensus mutagenicity @@ -229,40 +250,41 @@ post '/predict/?' do prediction["Consensus confidence"] = confidence.signif(3) prediction["Structural alerts for mutagenicity"] = sa_prediction[:matches].blank? ? "none" : sa_prediction[:matches].collect{|a| a.first}.join("; ") end - prediction_object[:prediction] = prediction - prediction_object.save - end - # regression - unless prediction[:value].blank? - if type == "Regression" + # add additionally fields for html representation + unless prediction[:value].blank? || type == "Classification" prediction[:prediction_value] = "#{prediction[:value].delog10.signif(3)} #{unit}" prediction["converted_prediction_value"] = "#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{converted_unit}" end + unless prediction[:prediction_interval].blank? + interval = prediction[:prediction_interval] + prediction[:interval] = "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} #{unit}" + prediction[:converted_interval] = "#{compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{compound.mmol_to_mg(interval[0].delog10).signif(3)} #{converted_unit}" + end + prediction["unit"] = unit + prediction["converted_unit"] = converted_unit + if prediction[:measurements].is_a?(Array) + prediction["measurements_string"] = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)} #{unit}"} : prediction[:measurements].join("
") + prediction["converted_measurements"] = prediction[:measurements].collect{|value| "#{compound.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"} if type == "Regression" + else + output["measurements_string"] = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)} #{unit}}" : prediction[:measurements] + output["converted_measurements"] = "#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if type == "Regression" + end + + # store in prediction_object + prediction_object[:prediction] = prediction + prediction_object[:csv] = prediction_to_csv(m,compound,prediction) + prediction_object.save end - unless prediction[:prediction_interval].blank? - interval = prediction[:prediction_interval] - prediction[:interval] = "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} #{unit}" - prediction[:converted_interval] = "#{compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{compound.mmol_to_mg(interval[0].delog10).signif(3)} #{converted_unit}" - end - prediction["unit"] = unit - prediction["converted_unit"] = converted_unit - if prediction[:measurements].is_a?(Array) - prediction["measurements_string"] = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)} #{unit}"} : prediction[:measurements].join("
") - prediction["converted_measurements"] = prediction[:measurements].collect{|value| "#{compound.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"} if type == "Regression" - else - output["measurements_string"] = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)} #{unit}}" : prediction[:measurements] - output["converted_measurements"] = "#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if type == "Regression" - end - predictions << prediction.delete_if{|k,v| k =~ /neighbors|prediction_feature_id|r_squared|rmse/i} + # collect prediction_object ids + predictions << prediction_id t.update_percent((counter*p).ceil) counter += 1 end # write csv - t[:csv] = header + to_csv(model,predictions,@compounds) + t[:csv] = header # write predictions @predictions["#{model}"] = predictions else # Cramer model - #t[:csv] = to_csv(model,nil,@compounds) compounds = @compounds.collect{|c| c.smiles} prediction = [Toxtree.predict(compounds, "Cramer rules"), Toxtree.predict(compounds, "Cramer rules with extensions")] output = {} @@ -321,23 +343,36 @@ post '/predict/?' do else model = Model::Validation.find model_id @models << model - if model.model.name =~ /kazius/ - sa_prediction = KaziusAlerts.predict(@compound.smiles) - lazar_mutagenicity = model.predict(@compound) - confidence = 0 - lazar_mutagenicity_val = (lazar_mutagenicity[:value] == "non-mutagenic" ? false : true) - if sa_prediction[:prediction] == false && lazar_mutagenicity_val == false - confidence = 0.85 - elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == true - confidence = 0.85 * ( 1 - sa_prediction[:error_product] ) - elsif sa_prediction[:prediction] == false && lazar_mutagenicity_val == true - confidence = 0.11 - elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == false - confidence = ( 1 - sa_prediction[:error_product] ) - 0.57 - end - @predictions << [lazar_mutagenicity, {:prediction => sa_prediction, :confidence => confidence}] + if Prediction.where(compound: @compound.id, model: model.id).exists? + prediction_object = Prediction.find_by(compound: @compound.id, model: model.id) + prediction = prediction_object.prediction + @predictions << prediction else - @predictions << model.predict(@compound) + prediction_object = Prediction.new + + if model.model.name =~ /kazius/ + sa_prediction = KaziusAlerts.predict(@compound.smiles) + lazar_mutagenicity = model.predict(@compound) + confidence = 0 + lazar_mutagenicity_val = (lazar_mutagenicity[:value] == "non-mutagenic" ? false : true) + if sa_prediction[:prediction] == false && lazar_mutagenicity_val == false + confidence = 0.85 + elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == true + confidence = 0.85 * ( 1 - sa_prediction[:error_product] ) + elsif sa_prediction[:prediction] == false && lazar_mutagenicity_val == true + confidence = 0.11 + elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == false + confidence = ( 1 - sa_prediction[:error_product] ) - 0.57 + end + prediction << [lazar_mutagenicity, {:prediction => sa_prediction, :confidence => confidence}] + else + prediction << model.predict(@compound) + end + prediction_object[:compound] = @compound.id + prediction_object[:model] = model.id + prediction_object[:prediction] = prediction + prediction_object.save + @predictions << prediction end end end diff --git a/helper.rb b/helper.rb index 3bd1755..d423285 100644 --- a/helper.rb +++ b/helper.rb @@ -1,4 +1,5 @@ helpers do + def embedded_svg image, options={} doc = Nokogiri::HTML::DocumentFragment.parse image svg = doc.at_css 'svg' @@ -14,146 +15,111 @@ helpers do doc.to_html.html_safe end - def to_csv(m,predictions,compounds) - model = (m != "Cramer" ? Model::Validation.find(m.to_s) : "Cramer") + def prediction_to_csv(m,c,p) + #model = Model::Validation.find(m.to_s) + model = m + model_name = "#{model.endpoint.gsub('_', ' ')} (#{model.species})" + model_unit = model.regression? ? "(#{model.unit})" : "" + converted_model_unit = model.regression? ? "#{model.unit =~ /\b(mmol\/L)\b/ ? "(mg/L)" : "(mg/kg_bw/day)"}" : "" + + #predictions = predictions_ids.collect{|prediction_id| Prediction.find prediction_id} csv = "" - if model == "Cramer" - compounds = compounds.collect{|c| c.smiles} - - prediction = [Toxtree.predict(compounds, "Cramer rules"), Toxtree.predict(compounds, "Cramer rules with extensions")] - output = {} - output["model_name"] = "Oral toxicity (Cramer rules)" - output["model_type"] = false - output["model_unit"] = false - ["measurements", "converted_measurements", "prediction_value", "converted_value", "interval", "converted_interval", "probability", "db_hit", "warnings", "info", "toxtree", "sa_prediction", "sa_matches", "confidence"].each do |key| - output["#{key}"] = false + compound = c#Compound.find prediction_object.compound + prediction = p#prediction_object.prediction + #prediction.delete_if{|k,v| k =~ /neighbors|prediction_feature_id/} + output = {} + line = "" + output["model_name"] = model_name + output["model_unit"] = model_unit + output["converted_model_unit"] = converted_model_unit + + if prediction[:value] + inApp = (prediction[:warnings].join(" ") =~ /Cannot/ ? "no" : (prediction[:warnings].join(" ") =~ /may|Insufficient/ ? "maybe" : "yes")) + if prediction[:info] =~ /\b(identical)\b/i + prediction[:info] = "This compound was part of the training dataset. All information "\ + "from this compound was removed from the training data before the "\ + "prediction to obtain unbiased results." end - output["toxtree"] = true - output["cramer_rules"] = prediction.collect{|array| array.collect{|hash| hash["Cramer rules"]}}.flatten.compact - output["cramer_rules_extensions"] = prediction.collect{|array| array.collect{|hash| hash["Cramer rules, with extensions"]}}.flatten.compact + note = "\"#{prediction[:warnings].uniq.join(" ")}\"" + + output["prediction_value"] = model.regression? ? "#{prediction[:value].delog10.signif(3)}" : "#{prediction[:value]}" + output["converted_value"] = model.regression? ? "#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)}" : nil + + if prediction[:measurements].is_a?(Array) + output["measurements"] = model.regression? ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)}"} : prediction[:measurements].collect{|value| "#{value}"} + output["converted_measurements"] = model.regression? ? prediction[:measurements].collect{|value| "#{compound.mmol_to_mg(value.delog10).signif(3)}"} : false + else + output["measurements"] = model.regression? ? "#{prediction[:measurements].delog10.signif(3)}" : "#{prediction[:measurements]}" + output["converted_measurements"] = model.regression? ? "#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)}" : false + + end #db_hit + + if model.regression? + + if !prediction[:prediction_interval].blank? + interval = prediction[:prediction_interval] + output['interval'] = [] + output['converted_interval'] = [] + output['interval'] << interval[1].delog10.signif(3) + output['interval'] << interval[0].delog10.signif(3) + output['converted_interval'] << compound.mmol_to_mg(interval[1].delog10).signif(3) + output['converted_interval'] << compound.mmol_to_mg(interval[0].delog10).signif(3) + end #prediction interval + + line += "#{output['model_name']},#{compound.smiles},"\ + "\"#{prediction[:info] ? prediction[:info] : "no"}\",\"#{output['measurements'].join("; ") if prediction[:info]}\","\ + "#{!output['prediction_value'].blank? ? output['prediction_value'] : ""},"\ + "#{!output['converted_value'].blank? ? output['converted_value'] : ""},"\ + "#{!prediction[:prediction_interval].blank? ? output['interval'].first : ""},"\ + "#{!prediction[:prediction_interval].blank? ? output['interval'].last : ""},"\ + "#{!prediction[:prediction_interval].blank? ? output['converted_interval'].first : ""},"\ + "#{!prediction[:prediction_interval].blank? ? output['converted_interval'].last : ""},"\ + "#{inApp},#{note.nil? ? "" : note.chomp}\n" + else # Classification + + if !prediction[:probabilities].blank? + output['probabilities'] = [] + prediction[:probabilities].each{|k,v| output['probabilities'] << v.signif(3)} + end + + line += "Consensus mutagenicity,#{compound.smiles},"\ + "\"#{prediction[:info] ? prediction[:info] : "no"}\",\"#{output['measurements'].join("; ") if prediction[:info]}\","\ + "#{prediction['Consensus prediction']},"\ + "#{prediction['Consensus confidence']},"\ + "#{prediction['Structural alerts for mutagenicity']},"\ + "#{output['prediction_value']},"\ + "#{!prediction[:probabilities].blank? ? output['probabilities'].first : ""},"\ + "#{!prediction[:probabilities].blank? ? output['probabilities'].last : ""},"\ + "#{inApp},#{note.nil? ? "" : note}\n" - # header - csv = "ID,Endpoint,Unique SMILES,Cramer rules,Cramer rules with extensions\n" + end - compounds.each_with_index do |smiles, idx| - csv << "#{idx+1},#{output["model_name"]},#{smiles},"\ - "#{output["cramer_rules"][idx] != "nil" ? output["cramer_rules"][idx] : "none" },"\ - "#{output["cramer_rules_extensions"][idx] != "nil" ? output["cramer_rules_extensions"][idx] : "none"}\n" + output['warnings'] = prediction[:warnings] if prediction[:warnings] + + else #no prediction value + inApp = "no" + if prediction[:info] =~ /\b(identical)\b/i + prediction[:info] = "This compound was part of the training dataset. All information "\ + "from this compound was removed from the training data before the "\ + "prediction to obtain unbiased results." end + note = "\"#{prediction[:warnings].join(" ")}\"" - else - output = {} - predictions.each_with_index do |prediction,idx| - compound = compounds[idx] - line = "" - output["model_name"] = "#{model.endpoint.gsub('_', ' ')} (#{model.species})" - output["model_type"] = model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression" - output["model_unit"] = (type == "Regression") ? "(#{model.unit})" : "" - output["converted_model_unit"] = (type == "Regression") ? "#{model.unit =~ /\b(mmol\/L)\b/ ? "(mg/L)" : "(mg/kg_bw/day)"}" : "" - ["measurements", "converted_measurements", "prediction_value", "converted_value", "interval", "converted_interval", "probability", "db_hit", "warnings", "info", "toxtree", "sa_prediction", "sa_matches", "confidence"].each do |key| - output["#{key}"] = false - end - - if prediction[:value] - inApp = (prediction[:warnings].join(" ") =~ /Cannot/ ? "no" : (prediction[:warnings].join(" ") =~ /may|Insufficient/ ? "maybe" : "yes")) - if prediction[:info] =~ /\b(identical)\b/i - prediction[:info] = "This compound was part of the training dataset. All information "\ - "from this compound was removed from the training data before the "\ - "prediction to obtain unbiased results." - end - note = "\"#{prediction[:warnings].uniq.join(" ")}\"" - - output["prediction_value"] = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)}" : "#{prediction[:value]}" - output["converted_value"] = "#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)}" if type == "Regression" - - output["db_hit"] = prediction[:info] if prediction[:info] - - if prediction[:measurements].is_a?(Array) - output["measurements"] = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)}"} : prediction[:measurements].collect{|value| "#{value}"} - output["converted_measurements"] = (type == "Regression") ? prediction[:measurements].collect{|value| "#{compound.mmol_to_mg(value.delog10).signif(3)}"} : false - else - output["measurements"] = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)}" : "#{prediction[:measurements]}" - output["converted_measurements"] = (type == "Regression") ? "#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)}" : false - - end #db_hit - - if type == "Regression" - - if !prediction[:prediction_interval].nil? - interval = prediction[:prediction_interval] - output['interval'] = "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)}" - output['converted_interval'] = "#{compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{compound.mmol_to_mg(interval[0].delog10).signif(3)}" - end #prediction interval - - line += "#{idx+1},#{output['model_name']},#{compound.smiles},"\ - "\"#{prediction[:info] ? prediction[:info] : "no"}\",\"#{output['measurements'].join("; ") if prediction[:info]}\","\ - "#{output['prediction_value'] != false ? output['prediction_value'] : ""},"\ - "#{output['converted_value'] != false ? output['converted_value'] : ""},"\ - "#{output['interval'].split(" - ").first.strip unless output['interval'] == false},"\ - "#{output['interval'].split(" - ").last.strip unless output['interval'] == false},"\ - "#{output['converted_interval'].split(" - ").first.strip unless output['converted_interval'] == false},"\ - "#{output['converted_interval'].split(" - ").last.strip unless output['converted_interval'] == false},"\ - "#{inApp},#{note.nil? ? "" : note.chomp}\n" - else # Classification - - # consensus mutagenicity - sa_prediction = KaziusAlerts.predict(compound.smiles) - lazar_mutagenicity = prediction - confidence = 0 - lazar_mutagenicity_val = (lazar_mutagenicity[:value] == "non-mutagenic" ? false : true) - if sa_prediction[:prediction] == false && lazar_mutagenicity_val == false - confidence = 0.85 - elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == true - confidence = 0.85 * ( 1 - sa_prediction[:error_product] ) - elsif sa_prediction[:prediction] == false && lazar_mutagenicity_val == true - confidence = 0.11 - elsif sa_prediction[:prediction] == true && lazar_mutagenicity_val == false - confidence = ( 1 - sa_prediction[:error_product] ) - 0.57 - end - output['sa_prediction'] = sa_prediction - output['sa_matches'] = sa_prediction[:matches].collect{|a| a.first}.join("; ") unless sa_prediction[:matches].blank? - output['confidence'] = confidence.signif(3) - output['model_name'] = "Lazar #{model.endpoint.gsub('_', ' ').downcase} (#{model.species}):" - output['probability'] = prediction[:probabilities] ? prediction[:probabilities].collect{|k,v| "#{k}: #{v.signif(3)}"} : false - - line += "#{idx+1},Consensus mutagenicity,#{compound.smiles},"\ - "\"#{prediction[:info] ? prediction[:info] : "no"}\",\"#{output['measurements'].join("; ") if prediction[:info]}\","\ - "#{sa_prediction[:prediction] == false ? "non-mutagenic" : "mutagenic"},"\ - "#{output['confidence']},#{output['sa_matches'] != false ? "\"#{output['sa_matches']}\"" : "none"},"\ - "#{output['prediction_value']},"\ - "#{output['probability'][0] != false ? output['probability'][0].split(":").last : ""},"\ - "#{output['probability'][1] != false ? output['probability'][1].split(":").last : ""},"\ - "#{inApp},#{note.nil? ? "" : note}\n" - - end - - output["warnings"] = prediction[:warnings] if prediction[:warnings] - - else #no prediction value - inApp = "no" - if prediction[:info] =~ /\b(identical)\b/i - prediction[:info] = "This compound was part of the training dataset. All information "\ - "from this compound was removed from the training data before the "\ - "prediction to obtain unbiased results." - end - note = "\"#{prediction[:warnings].join(" ")}\"" - - output["warnings"] = prediction[:warnings] - output["info"] = prediction[:info] if prediction[:info] - - if type == "Regression" - line += "#{idx+1},#{output['model_name']},#{compound.smiles},#{prediction[:info] ? prediction[:info] : "no"},"\ - "#{prediction[:measurements].collect{|m| m.delog10.signif(3)}.join("; ") if prediction[:info]},,,,,,,"+ [inApp,note].join(",")+"\n" - else - line += "#{idx+1},Consensus mutagenicity,#{compound.smiles},#{prediction[:info] ? prediction[:info] : "no"},"\ - "#{prediction[:measurements].join("; ") if prediction[:info]},,,,,,,"+ [inApp,note].join(",")+"\n" - end + output['warnings'] = prediction[:warnings] + output['info'] = prediction[:info] if prediction[:info] - end - csv += line + if model.regression? + line += "#{output['model_name']},#{compound.smiles},#{prediction[:info] ? prediction[:info] : "no"},"\ + "#{prediction[:measurements].collect{|m| m.delog10.signif(3)}.join("; ") if prediction[:info]},,,,,,,"+ [inApp,note].join(",")+"\n" + else + line += "Consensus mutagenicity,#{compound.smiles},#{prediction[:info] ? prediction[:info] : "no"},"\ + "#{prediction[:measurements].join("; ") if prediction[:info]},,,,,,,"+ [inApp,note].join(",")+"\n" end - csv + end + csv += line + # output + csv end end diff --git a/prediction.rb b/prediction.rb index 4e46d52..afceb08 100644 --- a/prediction.rb +++ b/prediction.rb @@ -9,8 +9,9 @@ module OpenTox field :compound, type: BSON::ObjectId field :model, type: BSON::ObjectId field :prediction, type: Hash, default:{} + field :csv, type: String - attr_accessor :compound, :model, :prediction + attr_accessor :compound, :model, :prediction, :csv def compound self[:compound] @@ -24,6 +25,10 @@ module OpenTox self[:prediction] end + def csv + self[:csv] + end + end end diff --git a/views/batch.haml b/views/batch.haml index 2fb5966..0f0e3b9 100644 --- a/views/batch.haml +++ b/views/batch.haml @@ -54,7 +54,7 @@ $('#pager_'+id).show(); $('#pager_'+id).pagination({ dataSource: '#{to("/")}' + 'task/?predictions=' + task_id + '&model=' + model_id , - locator: 'predictions', + locator: 'prediction', totalNumber: #{@compounds.size}, pageSize: 1, showPageNumbers: true, -- cgit v1.2.3