summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgebele <gebele@in-silico.ch>2016-04-15 09:59:43 +0000
committergebele <gebele@in-silico.ch>2016-04-15 09:59:43 +0000
commitdf8ed98fcc052da2641c26897a8dd0592f274e53 (patch)
treefab67ee95f1e73af49f9e2d4c0c121ebe2be3eb7
parent4a108bd930a367cad06b3ef0208c7b7760753329 (diff)
reactivated info buttons; changed unit for fish; introduced FAQ
-rw-r--r--FAQ.md29
-rw-r--r--README10
-rw-r--r--README.md15
-rw-r--r--application.rb6
-rw-r--r--lazar-gui.gemspec4
-rw-r--r--views/faq.haml2
-rw-r--r--views/faq_layout.haml67
-rw-r--r--views/layout.haml5
-rw-r--r--views/neighbors.haml7
-rw-r--r--views/prediction.haml23
-rw-r--r--views/style.scss12
11 files changed, 154 insertions, 26 deletions
diff --git a/FAQ.md b/FAQ.md
new file mode 100644
index 0000000..73fec91
--- /dev/null
+++ b/FAQ.md
@@ -0,0 +1,29 @@
+Frequently Asked Questions
+==========================
+<br>
+####How does this prediction works?
+>
+
+####You talk about significant fragments. Where can I find them?
+> We will show up those significant fragments in a further version.
+
+####What is endpoint details about?
+> You get the source from where we took compounds for the endpoint. The type and the number of compounds we used.
+
+####What is three times independent validation about?
+>
+
+####Do you consider providing plots for the validation results?
+> In a further version we will show up confidence and correlation plots.
+
+####What does 'Not enough similar compounds in training dataset' mean?
+> Lazar uses neighbors from the training dataset of the endpoint to predict your compound. If there are not enough neighbors for Lazar it is not possible to make a prediction.
+
+####Is there a minimum number of necessary neighbors to make a prediction?
+>
+
+####How can I activate the 'batch prediction' option?
+> Please contact us directly via [mail](mailto:support@in-silico.ch).
+
+####Not the right answers for me. Is there a way to contact you or report problems.
+> You can always ask your questions via [mail](mailto:support@in-silico.ch). If you run into problems with the GUI please post your issue [here](https://github.com/opentox/lazar-gui/issues). If you would like to post any other issue e.g. about an expected prediction result please use this [form](https://github.com/opentox/lazar/issues).
diff --git a/README b/README
deleted file mode 100644
index f162be7..0000000
--- a/README
+++ /dev/null
@@ -1,10 +0,0 @@
-IST Software&Services GUI
-
-installation:
-- bundle install
-- ~/.opentox/config/lazar-gui.rb (point to services)
-
-usage:
--start services
--run 'unicorn -D'
--visit 'localhost:8080'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2142dd5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+IST Software&Services GUI
+=========================
+
+Installation:
+-------------
+ bundle install
+
+Usage:
+------
+ sudo /etc/init.d/mongod start
+ unicorn -D
+
+Visit:
+------
+ http://localhost:8080
diff --git a/application.rb b/application.rb
index 6c6a73f..cebe4f2 100644
--- a/application.rb
+++ b/application.rb
@@ -1,4 +1,5 @@
require_relative 'helper.rb'
+require 'rdiscount'
include OpenTox
#require File.join(ENV["HOME"],".opentox","config","lazar-gui.rb") # until added to ot-tools
@@ -304,6 +305,11 @@ post '/predict/?' do
end
end
+get '/faq' do
+ @faq = RDiscount.new(File.read("FAQ.md")).to_html
+ haml :faq, :layout => :faq_layout
+end
+
get '/style.css' do
headers 'Content-Type' => 'text/css; charset=utf-8'
scss :style
diff --git a/lazar-gui.gemspec b/lazar-gui.gemspec
index dd852a0..db29827 100644
--- a/lazar-gui.gemspec
+++ b/lazar-gui.gemspec
@@ -15,9 +15,9 @@ Gem::Specification.new do |s|
s.files = `git ls-files`.split("\n")
s.required_ruby_version = '>= 1.9.2'
- #s.add_runtime_dependency "opentox-server"
- s.add_runtime_dependency "lazar"
+ s.add_runtime_dependency "lazar", "~> 0.9.3"
s.add_runtime_dependency "sinatra"
+ s.add_runtime_dependency "rdiscount"
s.add_runtime_dependency "haml"
s.add_runtime_dependency "sass"
s.add_runtime_dependency "unicorn"
diff --git a/views/faq.haml b/views/faq.haml
new file mode 100644
index 0000000..818b96a
--- /dev/null
+++ b/views/faq.haml
@@ -0,0 +1,2 @@
+%div.well.faq
+ = @faq
diff --git a/views/faq_layout.haml b/views/faq_layout.haml
new file mode 100644
index 0000000..a9b6664
--- /dev/null
+++ b/views/faq_layout.haml
@@ -0,0 +1,67 @@
+!!!
+%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 60f2bb3..46d326d 100644
--- a/views/layout.haml
+++ b/views/layout.haml
@@ -16,7 +16,7 @@
%script{:src=>"/javascripts/jquery.tablesorter.min.js"}
%script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
%script{ :src=>"/javascripts/lazar-gui.js"}
- %body{:style=>"background-color:#E7E7E7"}
+ %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.
@@ -27,6 +27,9 @@
%img.media-object{:src=>"/images/ist_logo.png", :alt=>"logo", :style=>"margin:0 3em 0 2em;"}
%div.col-md-8
%h1.media-heading{:style=>"margin: 0 0 0 1em;"} Lazar Toxicity Predictions
+ %div.col-md-2
+ %a.btn.btn-info{:href=> to("/faq"), :rel => "external"}
+ FAQ
%div.container-fluid
:javascript
diff --git a/views/neighbors.haml b/views/neighbors.haml
index 6011a6d..c94331a 100644
--- a/views/neighbors.haml
+++ b/views/neighbors.haml
@@ -75,12 +75,13 @@
%tr
%td
%td{:style=>"font-size:x-small;padding:0px;"}
- / %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Measured Activity", data: {toggle:"popover", placement:"auto", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
+ %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;"}
%td{:style=>"font-size:x-small;padding:0px;"}
- / %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Similarity", data: {toggle:"popover", placement:"auto", html:"true", content:"LAZAR calculates activity specific similarities based on the presence of statistically significant fragments. This procedure will <ul><li>consider only those parts of a chemical structure that are relevant for a particular endpoint</li><li>ignore inert parts of the structure</li><li>lead to different similarities, depending on the toxic endpoint Similarities of 1 may be encountered even for structurally dissimilar compounds, because inert parts are ignored.</li></ul>"}, :style=>"z-index:auto+10;"}
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"left", html:"true", content:"LAZAR calculates activity specific similarities based on the presence of statistically significant fragments. This procedure will <ul><li>consider only those parts of a chemical structure that are relevant for a particular endpoint</li><li>ignore inert parts of the structure</li><li>lead to different similarities, depending on the toxic endpoint Similarities of 1 may be encountered even for structurally dissimilar compounds, because inert parts are ignored.</li></ul>"}, :style=>"z-index:auto+10;"}
/ %td
%tbody
- type = @model_types[j]
+ - unit = @models[j].unit
- prediction[:neighbors].uniq.each_with_index do |neighbor,count|
%tr
/ Compound
@@ -93,7 +94,7 @@
/ Measured Activity = compound.features
%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} (mg/kg_bw/day)"}.join("</br>") : features.join("</br>")
+ = (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>")
/ 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?
diff --git a/views/prediction.haml b/views/prediction.haml
index f99df75..89c33d6 100644
--- a/views/prediction.haml
+++ b/views/prediction.haml
@@ -24,6 +24,7 @@
- @predictions.each_with_index do |prediction,i|
- type = @models[i].model.class.to_s.match("Classification") ? "Classification" : "Regression"
- @model_types[i] = type
+ - unit = @models[i].unit
%td{:style=>"vertical-align:top;white-space:nowrap;"}
%b{:class => "title"}
= "#{@models[i].endpoint.gsub('_', ' ')} (#{@models[i].species})"
@@ -34,9 +35,9 @@
%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 + " (#{@models[i].unit})"+"|#{'%.2e' % weight} (mg/kg_bw/day)"}.join("</br>") : prediction[:value].join(", ")
+ = (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]} (#{@models[i].unit}) | #{'%.2e' % @compound.mmol_to_mg(prediction[:value])} (mg/kg_bw/day)" : prediction[:value]
+ = (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
@@ -46,27 +47,29 @@
= type
%br
%b Prediction:
- = (type == "Regression") ? "#{'%.2e' % prediction[:value]} (#{@models[i].unit}) | #{'%.2e' % @compound.mmol_to_mg(prediction[:value])} (mg/kg_bw/day)" : prediction[:value]
- / TODO update description
- / %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Prediction", data: {toggle:"popover", placement:"left", html:"true", content:"LAZAR calculates searches the training dataset for similar compounds (neighbors) and calculates the prediction from their measured activities. LAZAR calculates predictions using <ul><li>a majority vote (weighted by compound similarity) for<br /><b>classification</b> (<a href='http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract', target='_blank'>original publication</a>) </li><li>a local QSAR model based on neighbors for<br /><b>regression</b> (<a href='http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract', target='_blank'</h>original publication</a>) </li></ul>Please keep in mind that predictions are based on the measured activities of neighbors."}}
+ = (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.
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Prediction", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"LAZAR calculates searches the training dataset for similar compounds (neighbors) and calculates the prediction from their measured activities. LAZAR calculates predictions using <ul><li>a majority vote (weighted by compound similarity) for<br /><b>classification</b> (<a href='http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract', target='_blank'>original publication</a>) </li><li>a local QSAR model based on neighbors for<br /><b>regression</b> (<a href='http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract', target='_blank'</h>original publication</a>) </li></ul>Please keep in mind that predictions are based on the measured activities of neighbors."}}
%br
- / TODO probability
- if type == "Regression"
%b 95% Prediction interval:
- interval = prediction[:prediction_interval].nil? ? "[ - - ]" : prediction[:prediction_interval].collect{|i| i.round(2)}
- = interval
+ = "[#{interval[0]} (#{unit}), #{interval[1]} (#{unit})]"
+ / 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:"A <b>prediction interval</b> (<a href='https://en.wikipedia.org/wiki/Prediction_interval', target='_blank'>wikipedia</a>) is an estimate of an interval in which future observations will fall, with a certain probability, given what has already been observed."}}
- else
%b Confidence:
= prediction[:confidence].round(2) unless prediction[:confidence].nil?
- / %a.btn.glyphicon.glyphicon-info-sign{:href=>"#", :title=>"Confidence", data: {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."}}
+ / 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."}}
%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", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[i]}/#{CGI.escape(@compound.uri)}/fingerprints")}} 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", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[i]}/#{CGI.escape(@compound.uri)}/fingerprints")}} 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
%p
- else
diff --git a/views/style.scss b/views/style.scss
index a0502b5..70c8035 100644
--- a/views/style.scss
+++ b/views/style.scss
@@ -1,3 +1,6 @@
+body {
+ background-color:#E7E7E7;
+}
table.table-borderless tbody tr td{
border-top: none;
}
@@ -25,3 +28,12 @@ img {
height: 300px;
width: 300px;
}
+.faq {
+ text-align: block;
+ margin-left:15%;
+ margin-right:15%;
+ margin-top:2%;
+}
+.faq h1 {
+ text-align: center;
+}