summaryrefslogtreecommitdiff
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/batch.haml106
-rw-r--r--views/details.haml8
-rw-r--r--views/faq_layout.haml67
-rw-r--r--views/layout.haml43
-rw-r--r--views/license.haml1
-rw-r--r--views/model_details.haml158
-rw-r--r--views/neighbors.haml24
-rw-r--r--views/predict.haml13
-rw-r--r--views/prediction.haml109
-rw-r--r--views/style.scss14
-rw-r--r--views/validation.haml16
11 files changed, 286 insertions, 273 deletions
diff --git a/views/batch.haml b/views/batch.haml
index 9bfa67e..6c37a2b 100644
--- a/views/batch.haml
+++ b/views/batch.haml
@@ -2,57 +2,99 @@
%a.btn.btn-warning{:href => to('/predict')}
%span.glyphicon.glyphicon-menu-left{:aria=>{:hidden=>"true"}}
New Prediction
- / displays all prediction result in first table
+ %a.btn.btn-success{:href=>"#{to("/predict/#{@filename}")}", :title=>"download"}
+ %span.glyphicon.glyphicon-download-alt
+ download CSV
+
+ / show processed file name
+ %topline
+ %div.row
+ %div.col-md-4
+ %h3 Batch Prediction Results:
+ %div.col-md-8
+ %h3= @filename
+
+ / displays all prediction result in one table
%div.table-responsive
%table.table.table-bordered{:id=>"batch", :style=>"background-color:white;"}
- %thead
- %tr
- %h3.col-md-4{:style=>"padding-left:0;"} Batch Prediction Results:
- %h3.col-md-8= @filename
- %tr
- %span.btn.btn-default
- %a{:href=>"#{to("/predict/#{@filename}")}", :title=>"download"}
- %span.glyphicon.glyphicon-download-alt{:aria=>{:hidden=>"true"}}
- CSV
%tbody
- / key = compound, values = array of arrays with model, prediction
+ - if @warnings
+ - @warnings.each do |warning|
+ %tr
+ %td
+ %b Warning
+ %td
+ = warning.sub(/\b(tmp\/)\b/,"")
+ / key = compound, values = [model,prediction]
- @batch.each do |key, values|
- compound = key
- - mw = compound.molecular_weight
%tr
%td{:style=>"vertical-align:top;"}
%p= compound.svg
%p= compound.smiles
- / array = single prediction [endpoint, result]
+
+ / array[0] = model, array[1] = prediction
- values.each_with_index do |array,i|
%td{:style=>"vertical-align:top;white-space:nowrap;"}
- model = array[0]
+ / model type (classification|regression)
+ - model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression"
+ - unit = model.unit
- prediction = array[1]
+
%b{:class => "title"}
= "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
- %p
- - if prediction[:confidence] == "measured"
+
+ / check for prediction
+ - if prediction[:neighbors].size > 0
%p
- %b Measured activity:
- - if prediction[:value].is_a?(Array)
- = prediction[:value][0].numeric? ? prediction[:value].collect{|v| weight = compound.mmol_to_mg(v, mw); '%.2e' % v + " (#{model.unit})"+" | #{'%.2e' % weight} (mg/kg_bw/day)"}.join("</br>") : prediction[:value].join(", ")
- - else
- = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % compound.mmol_to_mg(prediction[:value], mw)} (mg/kg_bw/day)" : prediction[:value]
+ / show model type (classification|regression)
+ %b Type:
+ = type
%p
- %b Compound is part of the training dataset
- - elsif prediction[:neighbors].size > 0
+ / check for database hit
+ - if prediction[:warning] =~ /\b(identical)\b/i
+
+ / show message about dbhit and measurements
+ %p
+ %b Compound is part of the training dataset
+ %p
+ %b Measured activity:
+ %br
+ - if prediction[:measurements].is_a?(Array)
+ = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10} (#{unit})</br>#{compound.mmol_to_mg(value.delog10)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : prediction[:measurements].join(", ")
+ - else
+ = (type == "Regression") ? "#{prediction[:measurements].delog10} (#{unit})</br>#{compound.mmol_to_mg(prediction[:measurements].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
+
+
+ / show prediction
%p
- / model type (classification|regression)
- %b Type:
- = model.model.class.to_s.match("Classification") ? "Classification" : "Regression"
- %br
- %b Prediction:
- = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % compound.mmol_to_mg(prediction[:value], mw)} (mg/kg_bw/day)" : prediction[:value]
- %br
- / TODO probability
- %b Confidence:
- = prediction[:confidence].round(3)
+ %b Prediction:
+ %br
+ = (type == "Regression") ? "#{prediction[:value].delog10} (#{unit})</br>#{compound.mmol_to_mg(prediction[:value].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
+
+ / show prediction interval or probability
+ %p
+ - if type == "Regression"
+ %b 95% Prediction interval:
+ - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
+ %br
+ = interval.nil? ? "--" : "#{interval[1].delog10} - #{interval[0].delog10} (#{unit})"
+ %br
+ = "#{compound.mmol_to_mg(interval[1].delog10)} - #{compound.mmol_to_mg(interval[0].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil?
+ - else
+ %b Probability:
+ - unless prediction[:probabilities].nil?
+ %br
+ = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0]}"
+ %br
+ / show warnings
%p
+ - if !prediction[:warning].nil?
+ %b Warnings:
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Warnings", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"#{prediction[:warning]}"}}
+
+ / no prediction
- else
%p
= "Not enough similar compounds </br>in training dataset."
diff --git a/views/details.haml b/views/details.haml
index 8a57440..be4948a 100644
--- a/views/details.haml
+++ b/views/details.haml
@@ -1,8 +1,12 @@
+:javascript
+ $(document).ready(function(){
+ addExternalLinks();
+ });
%div.modal-body{:style=>"padding:10px;"}
%button.close{ :type=>" button", data: { dismiss:"modal"}} &times;
%h3
Names and synonyms:
- %img.img-responsive{:src=>"#{@compound.uri}/image", :alt=>"Compound image not available", :width=>"300px", :heigth=>"300px", :style=>"float:left;"}
+ %p= @compound.svg
%p
%b="SMILES:"
%p= @smiles
@@ -19,6 +23,6 @@
%hr
%p{:style=>"padding-left:0.5em;"}
/ pubchem link
- %a.btn.btn-primary{:href=>"http://aop.in-silico.ch/", :title=>"Link opens in new window.", :alt=>"pubchem read across", :target=>"_blank"} PubChem read across
+ %a.btn.btn-primary{:href=>"http://aop.in-silico.ch/", :title=>"Link opens in new window.", :alt=>"pubchem read across", :rel=>"external"} PubChem read across
%i (experimental)
%br
diff --git a/views/faq_layout.haml b/views/faq_layout.haml
deleted file mode 100644
index a9b6664..0000000
--- a/views/faq_layout.haml
+++ /dev/null
@@ -1,67 +0,0 @@
-!!!
-%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
- %head
- %meta{'charset'=>"utf-8"}
- %meta{'http-equiv'=>"X-UA-Compatible", :content=>"IE=edge"}
- %meta{'name'=>"viewport", :content=>"width=device-width, initial-scale=1"}
- %title Lazar GUI FAQ
- %link{:rel=>'icon', :type=>'image/x-icon', :href=>'/images/favicon.ico'}
- %link{:rel=>'stylesheet', :href=>"#{'/css/bootstrap.min.css'}"}
- %link{:rel=>'stylesheet', :href=>"#{'/css/theme.default.min.css'}"}
- %link{:rel=>'stylesheet', :href=>"#{'/css/theme.bootstrap.min.css'}"}
- %link{ :href=>"/style.css", :rel=>"stylesheet"}
- %link{ :href=>"/stylesheets/jquery-ui.css", :rel=>"stylesheet"}
- %script{:src=>"/javascripts/jquery-1.11.2.min.js"}
- %script{:src=>"/javascripts/bootstrap.min.js"}
- %script{ :src=>"/javascripts/lazar-gui.js"}
- %body
- %noscript
- %div{ :style=>"width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif"}
- Your web browser must have JavaScript enabled in order for this application to display correctly.
- %header.page-header
- %div.row
- %div.col-md-2
- %a{:href=> to("/predict")}
- %img.media-object{:src=>"/images/ist_logo.png", :alt=>"logo", :style=>"margin:0 3em 0 2em;"}
- %div.col-md-10
- %h1.media-heading{:style=>"margin: 0 0 0 1em;display:inline;"} Lazar GUI
- A Graphical User Interface for the <a href="http://github.com/opentox/lazar">Lazar</a> framework
-
- %div.container-fluid
- :javascript
- $(document).ready(function(){
- $("#back-top").hide();
- $(".blind").error(function(){
- $(this).attr('src', '/images/blind.png');
- });
- });
-
- = yield
-
- %footer.footer
- %div.container-fluid
- %p.text-muted
- &copy;
- %a{:href => 'http://www.in-silico.ch', :rel => "external"} <i style="font-family: serife">in silico</i> toxicology gmbh 2004 - #{Time.now.year.to_s}
-
- #back-top{:style => "z-index:100;position:fixed;bottom:1%;right:1%;"}
- %a{:href => "", :style=>"text:decoration:none;color:#ccc;"}
- %span.glyphicon.glyphicon-circle-arrow-up{:style => "font-size:3em;color:black;"}
- :javascript
- $("#back-top").hide();
- $(function () {
- $(window).scroll(function () {
- if ($(this).scrollTop() > 600) {
- $('#back-top').fadeIn();
- } else {
- $('#back-top').fadeOut();
- }
- });
- // scroll body to 0px on click
- $('#back-top a').click(function () {
- $('body,html').animate({
- scrollTop: 0
- }, 500);
- return false;
- });
- });
diff --git a/views/layout.haml b/views/layout.haml
index 5d6d57a..8a920ea 100644
--- a/views/layout.haml
+++ b/views/layout.haml
@@ -15,7 +15,7 @@
%script{:src=>"/javascripts/bootstrap.min.js"}
%script{:src=>"/javascripts/jquery.tablesorter.min.js"}
%script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
- %script{ :src=>"/javascripts/lazar-gui.js"}
+ %script{:src=>"/javascripts/lazar-gui.js"}
%body
%noscript
%div{ :style=>"width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif"}
@@ -26,34 +26,35 @@
%a{:href=> to("/predict")}
%img.media-object{:src=>"/images/IST_logo_s.png", :alt=>"logo", :width=>"150px", :heigth=>"150px", :style=>"margin:0 3em 0 2em;"}
%div.col-md-8
- %h1.media-heading{:style=>"margin: 0 0 0 2em;"}
+ %h1.media-heading
lazar toxicity predictions
%div.col-md-2
%h1.media-heading
%small
- %a{:href=>"https://nano-lazar.in-silico.ch"} nano-lazar
+ %a{:href=>"https://nano-lazar.in-silico.ch", :rel=>"external"} nano-lazar
%div.container-fluid
%topline
%div.row
- %div.col-md-8
+ %div.col-md-10
Problems, bugs, ideas for improvements ? Please report at our
%a{:href => 'https://github.com/opentox/lazar-gui/issues', :rel => "external"} issue tracker
- or send us an email
- %a{ :href=>"mailto:info@in-silico.ch", :target=>"_top"}
+ , check out the
+ %a{:href=> to("/faq"), :rel => "external"} FAQ
+ page or send us an email.
+ %a{ :href=>"mailto:info@in-silico.ch?subject=[lazar v#{@version}]", :target=>"_top"}
%img.share{:src=>"/images/Email.png"}
- (version #{@version}).
- %div.col-md-2
- %div.col-md-2
- %a{:href=>"https://twitter.com/intent/tweet?source=http%3A%2F%2Flazar.in-silico.ch&text=:%20http%3A%2F%2Flazar.in-silico.ch", :target=>"_blank", :title=>"Tweet"}
+ [version: #{@version}]
+ %div.col-md-2{:style=>"text-align:right;"}
+ %a{:href=>"https://twitter.com/intent/tweet?source=http%3A%2F%2Flazar.in-silico.ch&text=http%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Tweet"}
%img.share{:src=>"/images/Twitter.png"}
- %a{:href=>"https://plus.google.com/share?url=http%3A%2F%2Flazar.in-silico.ch", :target=>"_blank", :title=>"Share on Google+"}
+ %a{:href=>"https://plus.google.com/share?url=http%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Share on Google+"}
%img.share{:src=>"/images/Google+.png"}
- %a{:href=>"http://www.linkedin.com/shareArticle?mini=true&url=http%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=http%3A%2F%2Flazar.in-silico.ch", :target=>"_blank", :title=>"Share on LinkedIn"}
+ %a{:href=>"http://www.linkedin.com/shareArticle?mini=true&url=http%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=http%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Share on LinkedIn"}
%img.share{:src=>"/images/LinkedIn.png"}
- %a{:href=>"https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=http%3A%2F%2Flazar.in-silico.ch", :target=>"_blank", :title=>"Share on Facebook"}
+ %a{:href=>"https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=http%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Share on Facebook"}
%img.share{:src=>"/images/Facebook.png"}
-
+
:javascript
$(document).ready(function(){
$("#back-top").hide();
@@ -77,17 +78,19 @@
%p.text-muted
&copy;
%a{:href => 'http://www.in-silico.ch', :rel => "external"} <i style="font-family: serife">in silico</i> toxicology gmbh 2004 - #{Time.now.year.to_s}
+ |
+ %a{:href => to("/license"), :rel => "external"} GPL3 License
%supporters.col-md-12
- %p Financial support:
- %a{:href=>"http://www.bfr.bund.de/de/start.html", :target=>"_blank"}
+ %p Financial support by
+ %a{:href=>"http://www.bfr.bund.de/de/start.html", :rel=>"external"}
%img{:src=>"/images/bfr_logo.gif"}
- %a{:href=>"http://www.opentox.org/", :target=>"_blank"}
+ %a{:href=>"http://www.opentox.org/", :rel=>"external"}
%img{:src=>"/images/ot_logo.png"}
- %a{:href=>"https://enanomapper.net/", :target=>"_blank"}
+ %a{:href=>"https://enanomapper.net/", :rel=>"external"}
%img{:src=>"/images/enm_logo.png"}
- %a{:href=>"https://www.researchgate.net/institution/Nestle_SA/department/Nestle_Research_Center", :target=>"_blank"}
+ %a{:href=>"https://www.researchgate.net/institution/Nestle_SA/department/Nestle_Research_Center", :rel=>"external"}
%img{:src=>"/images/nestec.jpg"}
-
+
#back-top{:style => "z-index:100;position:fixed;bottom:1%;right:1%;"}
%a{:href => "", :style=>"text:decoration:none;color:#ccc;"}
diff --git a/views/license.haml b/views/license.haml
new file mode 100644
index 0000000..2813220
--- /dev/null
+++ b/views/license.haml
@@ -0,0 +1 @@
+= @license
diff --git a/views/model_details.haml b/views/model_details.haml
index 1be75e7..5c3aa4f 100644
--- a/views/model_details.haml
+++ b/views/model_details.haml
@@ -1,26 +1,43 @@
%b Model:
%br
Source:
-%a{:href=>model.source, :target=>"external"}
+%a{:href=>model.source, :rel=>"external"}
= model.source
%br
- model.classification? ? type = "Classification" : type = "Regression"
= "Type:\t"
= type
%br
-- training_dataset = OpenTox::Dataset.find model.training_dataset.id
+- training_dataset = OpenTox::Dataset.find model.model.training_dataset_id
= "Training compounds:\t"
-= training_dataset.compounds.size
-
+= training_dataset.data_entries.size
+%br
+= "Training dataset:\t"
+%a{:href=>"#{to("/predict/dataset/#{training_dataset.name}")}"}
+ = training_dataset.name
+%br
+%b Algorithms:
+%br
+Similarity:
+%a{:href=> "http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["similarity"]["method"].sub("::", "%2F")}", :rel=>"external"}
+ = model.model.algorithms["similarity"]["method"]
+= ", min: #{model.model.algorithms["similarity"]["min"]}"
+%br
+Prediction:
+%a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
+ = model.model.algorithms["prediction"]["method"]
+%br
+Descriptors:
+= model.model.algorithms["descriptors"]["method"]+","
+= model.model.algorithms["descriptors"]["type"]
%p
- if type == "Classification"
%b Independent crossvalidations:
- else
%b Independent crossvalidations (-log10 transformed):
%div.row{:id=>"validations#{model.id}", :style=>"background-color:#f5f5f5;"}
- - model.crossvalidations.each do |crossvalidation|
+ - crossvalidations.each do |cv|
%span.col-xs-4.col-sm-4.col-md-4.col-lg-4
- - cv = OpenTox::CrossValidation.find crossvalidation.id
= "Num folds:\t"
= cv.folds
%br
@@ -34,76 +51,83 @@ Source:
= "Accuracy:\t"
= cv.accuracy.round(3) if cv.accuracy
%br
- = "True positive rate:\t"
- = cv.true_rate["active"].round(3) if cv.true_rate["active"]
- %br
- = "True negative rate:\t"
- = cv.true_rate["inactive"].round(3) if cv.true_rate["inactive"]
- %br
- = "Positive predictive value:\t"
- = cv.predictivity["active"].round(3) if cv.predictivity["active"]
- %br
- = "Negative predictive value:\t"
- = cv.predictivity["inactive"].round(3) if cv.predictivity["inactive"]
+ = "Weighted accuracy:\t"
+ = cv.weighted_accuracy.round(3) if cv.weighted_accuracy
+ - if cv.true_rate
+ %br
+ = "True positive rate:\t"
+ = cv.true_rate[cv.accept_values[0]].round(3)
+ %br
+ = "True negative rate:\t"
+ = cv.true_rate[cv.accept_values[1]].round(3)
+ - if cv.predictivity
+ %br
+ = "Positive predictive value:\t"
+ = cv.predictivity[cv.accept_values[0]].round(3)
+ %br
+ = "Negative predictive value:\t"
+ = cv.predictivity[cv.accept_values[1]].round(3)
%p
- %b Confusion Matrix:
- %table.table.table-condensed.table-borderless{:style=>"width:20%;"}
- %tbody
- %tr
- %td
- %td
- %td
- %b actual
- %td
- %td
- %tr
- %td
- %td
- %td active
- %td inactive
- -#%td total
- %tr
- %td
- %b predicted
- %td active
- %td
- =cv.confusion_matrix[0][0]
- %td
- =cv.confusion_matrix[0][1]
- -#%td
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[0][1]
- %tr
- %td
- %td inactive
- %td
- =cv.confusion_matrix[1][0]
- %td
- =cv.confusion_matrix[1][1]
- -#%td
- =cv.confusion_matrix[1][0]+cv.confusion_matrix[1][1]
- -#%tr
- %td
- %td total
- %td
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[1][0]
- %td
- =cv.confusion_matrix[0][1]+cv.confusion_matrix[1][1]
- %td
- -#= "Confusion Matrix:\t"
- -#= cv.confusion_matrix
+ - ["confusion_matrix", "weighted_confusion_matrix"].each_with_index do |matrix,idx|
+ %b= (idx == 0 ? "Confusion Matrix" : "Weighted Confusion Matrix")
+ %table.table.table-condensed.table-borderless{:style=>"width:20%;"}
+ %tbody
+ %tr
+ %td
+ %td
+ %td
+ %b actual
+ %td
+ %td
+ %tr
+ %td
+ %td
+ %td active
+ %td inactive
+ -#%td total
+ %tr
+ %td
+ %b predicted
+ %td active
+ %td
+ =( idx == 1 ? cv.send(matrix)[0][0].round(3) : cv.send(matrix)[0][0])
+ %td
+ =( idx == 1 ? cv.send(matrix)[0][1].round(3) : cv.send(matrix)[0][1])
+ -#%td
+ =cv.confusion_matrix[0][0]+cv.confusion_matrix[0][1]
+ %tr
+ %td
+ %td inactive
+ %td
+ =( idx == 1 ? cv.send(matrix)[1][0].round(3) : cv.send(matrix)[1][0])
+ %td
+ =( idx == 1 ? cv.send(matrix)[1][1].round(3) : cv.send(matrix)[1][1])
+ -#%td
+ =cv.confusion_matrix[1][0]+cv.confusion_matrix[1][1]
+ -#%tr
+ %td
+ %td total
+ %td
+ =cv.confusion_matrix[0][0]+cv.confusion_matrix[1][0]
+ %td
+ =cv.confusion_matrix[0][1]+cv.confusion_matrix[1][1]
+ %td
+ -#= "Confusion Matrix:\t"
+ -#= cv.confusion_matrix
+ %br
%br
/= "Confidence plot:"
/%p.plot
/ %img{:src=>"confp#{cv.id}.svg"}
- if model.regression?
%br
- = "Root mean squared error:\t"
+ %a.ht5{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"} RMSE:
= cv.rmse.round(3) if cv.rmse
%br
- = "Mean absolute error:\t"
+ %a.ht5{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"} MAE:
= cv.mae.round(3) if cv.mae
%br
- = "R square:\t"
+ %a.ht5{:href=>"https://en.wikipedia.org/wiki/Coefficient_of_determination", :rel=>"external"}= "R"+"<sup>2</sup>"+":"
= cv.r_squared.round(3) if cv.r_squared
%br
/= "Confidence plot:"
@@ -113,5 +137,5 @@ Source:
/= "Correlation plot"
/%p.plot
/ %img{:src=>"/corrp#{cv.id}.svg"}
-
-%br
+
+%br
diff --git a/views/neighbors.haml b/views/neighbors.haml
index 096e432..2d7c4a5 100644
--- a/views/neighbors.haml
+++ b/views/neighbors.haml
@@ -67,10 +67,10 @@
Compound
%th.sorter-false{:style =>"vertical-align:middle;"}
Measured Activity
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Measured Activity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"left", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Measured Activity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
%th.sorter-false{:style =>"vertical-align:middle;"}
Similarity
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"left", html:"true", content:"<a href=\"https://en.wikipedia.org/wiki/Jaccard_index\">Tanimoto/Jaccard</a> similarity based on <a href=\"https://openbabel.org/docs/dev/FileFormats/MolPrint2D_format.html\">Molprint2D</a> fingerprints."}, :style=>"z-index:auto+10;"}
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"<a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://en.wikipedia.org/wiki/Jaccard_index\">Tanimoto/Jaccard</a> similarity based on <a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://openbabel.org/docs/dev/FileFormats/MolPrint2D_format.html\">Molprint2D</a> fingerprints."}, :style=>"z-index:auto+10;"}
/ %th{:style =>"vertical-align:middle;"}
/ Supporting Information
%tbody
@@ -79,20 +79,22 @@
- prediction[:neighbors].uniq.each_with_index do |neighbor,count|
%tr
/ Compound
- - c = Compound.find(neighbor["_id"])
+ - c = Compound.find(neighbor)
%td{:style =>"vertical-align:middle;padding-left:1em;width:50%;"}
- /%a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(neighbor["_id"])}/details"), :id=>"link#{j+1}#{count}"}}
- %p= c.svg
+ %a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(c.id.to_s)}/details"), :id=>"link#{j+1}#{count}"}}
+ = c.svg
%p= c.smiles
- - mw = c.molecular_weight
- / Measured Activity = compound.features
+
+ / Measured Activity
%td{:style =>"vertical-align:middle;padding-left:1em;width:20%;white-space:nowrap;"}
- - features = c.features.collect{|k,v| v if k == predictionFeature[j]["id"] }.compact.flatten
- = (predictionFeature[j]["type"] == "numeric") ? features.collect{|v| weight = c.mmol_to_mg(v); '%.2e' % v + " (#{@models[j].unit})"+" , #{'%.2e' % weight} #{(unit == "mmol/L") ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : features.join("</br>")
+ - if neighbor[:measurement].is_a?(Array)
+ = (type == "Regression") ? neighbor[:measurement].collect{|value| "#{value.delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : neighbor[:measurement].join(", ")
+ - else
+ = (type == "Regression") ? "#{neighbor[:measurement].delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(neighbor[:measurement].delog10).signif(3)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : neighbor[:measurement]
+
/ Similarity = tanimoto
%td{:style =>"vertical-align:middle;padding-left:1em;width:20%;"}
- / TODO differentiate between no neighbors found and compound found in dataset, display neighbors for compounds in dataset?
- = neighbor[:tanimoto] != nil ? neighbor[:tanimoto].to_f.round(3) : "Not enough similar compounds </br>in training dataset."
+ = neighbor[:similarity].round(3)
- else
%span.btn.btn-default.disabled
diff --git a/views/predict.haml b/views/predict.haml
index 010ed12..59630d0 100644
--- a/views/predict.haml
+++ b/views/predict.haml
@@ -111,7 +111,7 @@
};
// whole site content needs to be in one form. Input and checkboxes are proofed by js functions.
-%form{:name => "form", :action => to('/predict'), :method => "post", :enctype => "multipart/form-data", :onsubmit => "return !!(showcircle())" }
+%form{:name => "form", :action => to('/predict'), :method => "post", :enctype => "multipart/form-data", :onsubmit => "return !!(showcircle())" }
%fieldset#top.well
%h2 1. Draw a chemical structure
#insert
@@ -125,11 +125,13 @@
%br
%input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'}
%p
- %label{:for=>"fileselect"}
+ -#%label{:for=>"fileselect"}
or upload a CSV file for batch predictions (disabled in public version)
- %br
- %span.btn.btn-default.btn-file
- %input{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled"}
+ -#%a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"File format", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"auto", html:"true", content:"One column with compounds and keyword SMILES or InChI in the first row."}}
+ -#%br
+ -#%span.btn.btn-default.btn-file
+ -#%input{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled"}
+ %input{:type=>"hidden", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled"}
%fieldset#middle.well
%h2 2. Select one or more endpoints
@@ -162,6 +164,7 @@
document.getElementById("details#{model.id}").appendChild(details);
$(button).show();
$(image).hide();
+ addExternalLinks();
});
}
}
diff --git a/views/prediction.haml b/views/prediction.haml
index 0f3d57b..1b8d38d 100644
--- a/views/prediction.haml
+++ b/views/prediction.haml
@@ -1,10 +1,3 @@
-:javascript
- $(document).ready(function(){
- $('[data-toggle="popover"]').popover();
- $('.modal').on('hidden.bs.modal', function () {
- $(this).removeData('bs.modal');
- });
- });
%div.well
%a.btn.btn-warning{:href => to('/predict')}
%i.glyphicon.glyphicon-menu-left
@@ -16,9 +9,9 @@
%tbody
%tr
%td{:id=>"compound", :style=>"vertical-align:top;"}
- %p= @compound.svg
+ %a.btn.btn-link{:href => "#details0", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@compound.id.to_s)}/details"), :id=>"link01"}}
+ = @compound.svg
%p= @compound.smiles
- - mw = @compound.molecular_weight
- @model_types = {}
- @dbhit = {}
- @predictions.each_with_index do |prediction,i|
@@ -28,52 +21,66 @@
%td{:style=>"vertical-align:top;white-space:nowrap;"}
%b{:class => "title"}
= "#{@models[i].endpoint.gsub('_', ' ')} (#{@models[i].species})"
- %p
- - if prediction[:confidence] == "measured"
- - @dbhit[i] = true
+
+ / check for prediction
+ - if prediction[:neighbors].size > 0
%p
- %b Measured activity:
- - p prediction[:value]
- - if prediction[:value].is_a?(Array)
- = (type == "Regression") ? prediction[:value].collect{|v| weight = Compound.from_smiles(@compound.smiles).mmol_to_mg(v); '%.2e' % v + " (#{unit})"+", #{'%.2e' % weight} #{unit == "mmol/L" ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : prediction[:value].join(", ")
- - else
- = (type == "Regression") ? "#{"%.2e" % prediction[:value]} (#{unit}), #{'%.2e' % @compound.mmol_to_mg(prediction[:value])} #{(unit == "mmol/L") ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
- %p
- %b Compound is part of the training dataset
- - elsif prediction[:neighbors].size > 0
- %p
- / model type (classification|regression)
+ / show model type (classification|regression)
%b Type:
= type
- %br
- %b Prediction:
- = (type == "Regression") ? "#{'%.2e' % prediction[:value]} (#{unit}) , #{'%.2e' % @compound.mmol_to_mg(prediction[:value])} #{(unit == "mmol/L") ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
- / tabindex=0 seems the best fix for FF|S browsers on OSX better than trigger="click focus" which ends up in double click for FF.
- / prediction popover
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Prediction", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"<p>lazar searches the training dataset for similar compounds (neighbors) and calculates the prediction from their experimental activities.<p><b>Classification:</b></br>Majority vote of neighbor activities weighted by similarity.<p><b>Regression:</b></br>Prediction from a local partial least squares regression model with neighbor activities weighted by similarity.<p><a href=\"http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract\", target=\"_blank\"> Original publication</a>."}}
- %br
- - if type == "Regression"
- %b 95% Prediction interval:
- - interval = prediction[:prediction_interval].nil? ? " - - " : prediction[:prediction_interval].collect{|i| i.round(2)}
- %br
- = "#{interval[0]} - #{interval[1]} (#{unit}), #{'%.2e' % @compound.mmol_to_mg(interval[0])} - #{'%.2e' % @compound.mmol_to_mg(interval[1])} #{(unit == "mmol/L") ? "(mg/L)" : "(mg/kg_bw/day)"}"
- / prediction intervall popover
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Prediction intervall", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"An estimate of prediction uncertainty. The \"real\" value should be with 95% probability within the prediction interval."}}
+ %p
+ / check for database hit
+ - if prediction[:warning] =~ /\b(identical)\b/i
+ - @dbhit[i] = true
+
+ / show message about dbhit and measurements
+ %p
+ %b Compound is part of the training dataset
+ %p
+ %b Measured activity:
+ %br
+ - if prediction[:measurements].is_a?(Array)
+ = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)} (#{unit})</br>#{@compound.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : prediction[:measurements].join(", ")
+ - else
+ = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)} (#{unit})</br>#{@compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
+
- else
- %b Confidence:
- = prediction[:confidence].round(2) unless prediction[:confidence].nil?
- / confidence popover
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Confidence", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"Indicates the applicability domain of a model. Predictions with a high confidence can be expected to be more reliable than predictions with low confidence. Confidence values may take any value between 0 and 1. For most models confidence > 0.025 is a sensible (hard) cutoff to distinguish between reliable and unreliable predictions."}}
+ - @dbhit[i] = false
+
+ / show prediction
%p
- /TODO add tooltip for significant ftagments and descriptors
- / - if @model_type[i] =~ /classification/i && (p.data_entries[0][1] != nil && p.data_entries[0][1] != 0.0)
- / Significant fragments:
- / %a.btn.btn-default.btn-sm{:id=>"linkSigFragments", :href => "#detailsTop", :tabindex=>"0", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[i]}/#{CGI.escape(@compound.uri)}/fingerprints")}} Significant fragments
- / - if @model_type[i] =~ /regression/i && (p.data_entries[0][1] != nil && p.data_entries[0][1] != 0.0)
- / Descriptors
- / %a.btn.btn-default.btn-sm{:id=>"linkDescriptors", :href => "#detailsTop", :tabindex=>"0", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[i]}/#{CGI.escape(@compound.uri)}/fingerprints")}} Descriptors
- / %p
+ %b Prediction:
+ / prediction popover
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Prediction", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"<p>lazar searches the training dataset for similar compounds (neighbors) and calculates the prediction from their experimental activities.<p><b>Classification:</b></br>Majority vote of neighbor activities weighted by similarity.<p><b>Regression:</b></br>Prediction from a local partial least squares regression model with neighbor activities weighted by similarity.<p><a href=\"http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract\", target=\"_blank\"> Original publication</a>."}}
+ %br
+ = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})</br>#{@compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
+
+ / show prediction interval or probability
+ %p
+ - if type == "Regression"
+ %b 95% Prediction interval:
+ - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
+ / prediction interval popover
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Prediction intervall", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"An estimate of prediction uncertainty. The \"real\" value should be with 95% probability within the prediction interval."}}
+ %br
+ = interval.nil? ? "--" : "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} (#{unit})"
+ %br
+ = "#{@compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{@compound.mmol_to_mg(interval[0].delog10).signif(3)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil?
+ - else
+ %b Probability:
+ / probability popover
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Pobability", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"Probability that the prediction belongs to one of the given classes."}}
+ - unless prediction[:probabilities].nil?
+ %br
+ = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0].signif(3)}"
+ %br
+ = "#{prediction[:probabilities].keys[1]}: #{prediction[:probabilities].values[1].signif(3)}"
+
+ / show warnings
%p
+ - if !prediction[:warning].nil?
+ %b Warnings:
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Warnings", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"auto", html:"true", content:"#{prediction[:warning]}"}}
- else
- @dbhit[i] = false
%p
@@ -81,4 +88,8 @@
/ always show the neighbors table, message is given there
= haml :neighbors, :layout => false, :model_type => @model_types, :dbhit => @dbhit
+
+%div.modal.fade{:id=>"details0", :role=>"dialog"}
+ %div.modal-dialog.modal-lg
+ %div.modal-content
diff --git a/views/style.scss b/views/style.scss
index 49e03ab..2c84781 100644
--- a/views/style.scss
+++ b/views/style.scss
@@ -51,10 +51,12 @@ ul.share-buttons{
padding: 0 2px 1px 2px !important;
}
.page-header{
- margin:20px 0 20px;
- text-align:justify;
+ background-color: #fff;
+ padding:20px 0 20px 0;
+ margin: 0;
+ text-align:center;
display:inline-block;
- width:98.5%;
+ width:100%;
}
.share{
width: 30px;
@@ -62,9 +64,13 @@ ul.share-buttons{
}
supporters{
background-color: white;
-
+ text-align:center;
img{
width: 200px;
margin-right: 1em;
}
}
+
+.footer{
+ margin-top:3em;
+}
diff --git a/views/validation.haml b/views/validation.haml
deleted file mode 100644
index fd63ea6..0000000
--- a/views/validation.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-- case @model_type
-- when "classification"
- - prediction = @cv.metadata["http://www.opentox.org/api/1.2#classificationStatistics"]["http://www.opentox.org/api/1.2#numCorrect"] + @cv.metadata["http://www.opentox.org/api/1.2#classificationStatistics"]["http://www.opentox.org/api/1.2#numIncorrect"]
- %p= "Number of predictions: #{prediction}"
- - percent = @cv.metadata["http://www.opentox.org/api/1.2#classificationStatistics"]["http://www.opentox.org/api/1.2#percentCorrect"]
- %p= "Correct predictions: #{percent.round(2)} %"
-- when "regression"
- - prediction = @cv.metadata["http://www.opentox.org/api/1.2#numInstances"].to_i - @cv.metadata["http://www.opentox.org/api/1.2#numUnpredicted"].to_i
- %p= "Number of predictions: #{prediction}"
- - rSquare = @cv.metadata["http://www.opentox.org/api/1.2#regressionStatistics"]["http://www.opentox.org/api/1.2#rSquare"]
- %p= "R-squared: #{rSquare.round(2)} %"
- - rootMeanSquaredError = @cv.metadata["http://www.opentox.org/api/1.2#regressionStatistics"]["http://www.opentox.org/api/1.2#rootMeanSquaredError"]
- %p= "Root Mean Square Error: #{rootMeanSquaredError.round(2)} %"
- - meanAbsoluteError = @cv.metadata["http://www.opentox.org/api/1.2#regressionStatistics"]["http://www.opentox.org/api/1.2#meanAbsoluteError"]
- %p= "Mean Absolute Error: #{meanAbsoluteError.round(2)} %"
-