summaryrefslogtreecommitdiff
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/batch.haml155
-rw-r--r--views/details.haml12
-rw-r--r--views/error.haml9
-rw-r--r--views/faq.haml8
-rw-r--r--views/help.haml68
-rw-r--r--views/info.haml5
-rw-r--r--views/layout.haml144
-rw-r--r--views/model_details.haml323
-rw-r--r--views/neighbors.haml178
-rw-r--r--views/predict.haml221
-rw-r--r--views/prediction.haml211
-rw-r--r--views/significant_fragments.haml66
-rw-r--r--views/style.scss81
-rw-r--r--views/upload.haml28
14 files changed, 706 insertions, 803 deletions
diff --git a/views/batch.haml b/views/batch.haml
index 0e7efc7..6bc2354 100644
--- a/views/batch.haml
+++ b/views/batch.haml
@@ -1,109 +1,50 @@
-%div.well
- %a.btn.btn-warning{:href => to('/predict')}
- %span.glyphicon.glyphicon-menu-left{:aria=>{:hidden=>"true"}}
+:javascript
+ // kill task pid if page is reloaded, `false` makes the request synchronous
+ window.addEventListener('unload', ktpid, false);
+ function ktpid() {
+ var client = new XMLHttpRequest();
+ client.open("GET", '//#{$host_with_port}/prediction/task?ktpid=#{@pid}', false);
+ client.setRequestHeader("Content-Type", "application/json");
+ client.send(null);
+ };
+%div.card
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict?tpid=#{@pid}"}
+ %span.fa.fa-caret-left{:aria=>{:hidden=>"true"}}
New Prediction
- %a.btn.btn-success{:id => "downbutton", :href=>"#{to("/predict/#{@tmppath}/#{@filename}")}", :title=>"download"}
- %span.glyphicon.glyphicon-download-alt
- Download CSV
+%div.card.bg-light
+ %div.card-body
+ %h3.card-title="Batch prediction results for: #{@filename}"
+
+ // prepare variable values for javascript
+ // increase timer interval for large datasets
+ - timer = 10000#((@compounds_size/1000) == 0 ? 1000 : ((@compounds_size/1000)*1000))
+ // process batch predictions
+ - @models.each_with_index do |model,idx|
+ - m = Model::Validation.find model
+ - task = @tasks[idx].id
+ #result.card.bg-light{:id=>idx}
+ %div.card-body
+ %div.row
+ %div.col-6
+ %h5.card-title="#{m.endpoint} (#{m.species})"
+ #pager{:id=>idx}
+ %div.col-6
+ %a.btn.btn-outline-info.btn-sm.disabled{:id => "detailsbutton_#{idx}", :data=>{:toggle=>"collapse"}, :href=>"javascript:void(0)", :onclick=>"pagePredictions('//#{$host_with_port}/prediction/task/?predictions=#{task}','#{model}','#{idx}','#{@compounds_size}')"}
+ %span.fa.fa-caret-right
+ Details
+ %a.btn.btn-outline-info.btn-sm.disabled{:id => "downbutton_#{idx}", :href=>"//#{$host_with_port}/predict/batch/download?tid=#{task}", :title=>"download"}
+ %span.fa.fa-download
+ CSV
+ %p{:id=>"est_#{idx}"}
+ waiting ...
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle_#{idx}", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
+ :javascript
+ $(document).ready(function() {
+ taskProgress('#{idx}','#{timer}','//#{$host_with_port}/prediction/task/?turi=#{task}');
+ });
+ #data-container.card.d-none.table-responsive{:id=>idx}
+ :javascript
+%div.modal.fade{:id=>"details", :tabindex=>"-1", :role=>"dialog"}
+ %div.modal-dialog.modal-lg{:role=>"document"}
+ %div.modal-content
- / show 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;"}
- %tbody
- - if @warnings
- - @warnings.each do |warning|
- %tr
- %td
- %b Warning
- %td
- = warning.sub(/\b(tmp\/)\b/,"")
- - @view.each do |compound, array|
- %tr
- %td{:style=>"vertical-align:top;"}
- %p= compound.svg
- %p= compound.smiles
- - array.each do |model,prediction|
- %td{:style=>"vertical-align:top;white-space:nowrap;"}
- - model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression"
- - unit = model.unit
-
- %b{:class => "title"}
- = "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
-
- / check for prediction
- - if prediction[:value]
- %p
- / show model type (classification|regression)
- %b Type:
- = type
- %p
- / check for database hit
- - if prediction[:info] =~ /\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.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(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
-
-
- / show prediction
- %p
- %b Prediction:
- %br
- = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})</br>#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mmol\/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.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(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil?
- - else
- %b Probability:
- - unless prediction[:probabilities].nil?
- - probabilities = ""
- - prediction[:probabilities].each{|k,v| probabilities += "#{k}: #{v.signif(3)}<br>"}
- %br
- = probabilities
- / show warnings
- %p
- - if !prediction[:info].blank?
- %b Info:
- %br
- %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
- - if !prediction[:warnings].blank?
- %b Warnings:
- - prediction[:warnings].uniq.each do |warning|
- %br
- %p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
-
- / no prediction
- - else
- %br
- - if !prediction[:info].blank?
- %b Info:
- %br
- %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
- - if !prediction[:warnings].blank?
- %b Warnings:
- - prediction[:warnings].uniq.each do |warning|
- %br
- %p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
- %tr
diff --git a/views/details.haml b/views/details.haml
index be4948a..abf7518 100644
--- a/views/details.haml
+++ b/views/details.haml
@@ -6,7 +6,7 @@
%button.close{ :type=>" button", data: { dismiss:"modal"}} &times;
%h3
Names and synonyms:
- %p= @compound.svg
+ %p= embedded_svg(@compound.svg, :title=>"x")
%p
%b="SMILES:"
%p= @smiles
@@ -14,6 +14,11 @@
%b="InChI:"
%p= @inchi
%br
+ - cid = @compound.cid
+ - if cid
+ %b="CID:"
+ %p= cid
+ %br
%b="Names:"
%p{:style=>"padding-left:0.5em;"}
- if @names !~ /^no names/i
@@ -23,6 +28,9 @@
%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", :rel=>"external"} PubChem read across
+ - if cid
+ %a.btn.btn-primary{:href=>"http://aop.in-silico.ch/cid/#{cid}", :title=>"Link opens in new window.", :alt=>"pubchem read across", :rel=>"external"} PubChem read across
+ - else
+ %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/error.haml b/views/error.haml
index 05cb0da..d00b578 100644
--- a/views/error.haml
+++ b/views/error.haml
@@ -1,7 +1,6 @@
-%div.well
- %a.btn.btn-warning{:href => to('/predict')}
- %i.glyphicon.glyphicon-menu-left
+%div.card
+ %a.btn.btn-warning{:href => "//#{$host_with_port}/predict"}
+ %i.fa.fa-caret-left
Back
- %hr
- %div.well{:style=>"width:100%;margin-bottom:2em;"}
+ %div.card-body
= @error
diff --git a/views/faq.haml b/views/faq.haml
index 818b96a..8c0e604 100644
--- a/views/faq.haml
+++ b/views/faq.haml
@@ -1,2 +1,6 @@
-%div.well.faq
- = @faq
+%div.card
+ %a.btn.btn-warning{:href => "//#{$host_with_port}/predict"}
+ %i.fa.fa-caret-left
+ Back
+ %div.card-body
+ = @faq
diff --git a/views/help.haml b/views/help.haml
new file mode 100644
index 0000000..84be516
--- /dev/null
+++ b/views/help.haml
@@ -0,0 +1,68 @@
+%div.card.bg-light
+ %div.card-body
+ %h3 How to use batch prediction
+
+ %p
+ You have two options to format your comma or tab sperated spreadsheet for batch predictions:
+
+ %br
+ %p
+ %div.row
+ %div.col-md-6
+ %strong Option 1:
+ %br
+ A spreadsheet with a single column and a header. The header should specify the input format (SMILES or InChI are accepted).
+ %div.col-md-6
+ %table.help
+ %tr.row
+ %th.col-md-12
+ SMILES
+ %tr.row
+ %td.col-md-12
+ C1ccccc1NN
+ %tr.row
+ %td.col-md-12
+ Cc1ccc(cc1\N=C=O)/N=C=O
+ %tr.row
+ %td.col-md-12
+ OC(=O)c1ccc(cc1)C(=O)O
+ %tr.row
+ %td.col-md-12
+ ="..."
+ %br
+ %p
+ %div.row
+ %div.col-md-6
+ %strong Option 2:
+ %br
+ A spreadsheet with two columns and a header. The first column may contain an arbitrary ID,
+ the second column the compound structure (as SMILES or InChI).
+ The header consists of "ID" followed by the input format (SMILES or InChI).
+ %div.col-md-6
+ %table.help
+ %tr.row
+ %th.col-md-4
+ ID
+ %th.col-md-8
+ SMILES
+ %tr.row
+ %td.col-md-4
+ 2735
+ %td.col-md-8
+ C1ccccc1NN
+ %tr.row
+ %td.col-md-4
+ A2
+ %td.col-md-8
+ O=C(OCCCC)C1=CC=CC=C1C(OCCCC)=O
+ %tr.row
+ %td.col-md-4
+ 82 B-6 304663
+ %td.col-md-8
+ CC(C)(C)C1=CC2(C=C(C1=O)C(C)(C)C)CCC(=O)O2
+ %tr.row
+ %td.col-md-4
+ ="..."
+ %td.col-md-8
+ ="..."
+ %br
diff --git a/views/info.haml b/views/info.haml
index d8b93f9..d2730aa 100644
--- a/views/info.haml
+++ b/views/info.haml
@@ -1,2 +1,3 @@
-%div.info
- We are rebuilding the models. It will take a while, please be patient and reload the page in some time.
+%div.card.border-warning.mb-3
+ %div.card-body
+ We are rebuilding our models. It will take a while, please be patient and reload the page later.
diff --git a/views/layout.haml b/views/layout.haml
index 9b13e2f..8cd5dfb 100644
--- a/views/layout.haml
+++ b/views/layout.haml
@@ -6,77 +6,53 @@
%meta{'name'=>"viewport", :content=>"width=device-width, initial-scale=1"}
%title lazar Toxicity Predictions
%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/jquery.tablesorter.min.js"}
- %script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
+ %link{:href=>"/stylesheets/bootstrap.min.css", :rel=>"stylesheet"}
+ %link{:href=>"/stylesheets/font-awesome.min.css", :rel=>"stylesheet"}
+ %link{:href=>"/stylesheets/pagination.css", :rel=>"stylesheet"}
+ %link{:href=>"/style.css", :rel=>"stylesheet"}
+ %script{ :src=>"/javascripts/jquery.min.js"}
+ %script{ :src=>"/javascripts/popper.min.js"}
%script{:src=>"/javascripts/lazar-gui.js"}
- %script{:src=>"/javascripts/google_analytics_lazar.js"}
+ %script{ :src=>"/javascripts/bootstrap.js"}
+ %script{:src=>"/javascripts/pagination.min.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-3
- %a{:href=> to("/predict")}
- %img.media-object{:src=>"/images/IST_logo_s.png", :alt=>"logo", :width=>"150px", :heigth=>"150px"}
- %div.col-md-6
- %h1.media-heading
- lazar toxicity predictions
- %div.col-md-3
- %h1.media-heading
- %small
- %a.btn{:href=>"https://nano-lazar.in-silico.ch", :rel=>"external"}
- nano-lazar
- %span.glyphicon.glyphicon-new-window
-
+ %header.container-fluid.page-header
+ %div.row.align-items-center
+ %div.col-3
+ %a.card-link{:href=> "https://in-silico.ch/", :rel=>"external"}
+ %img{:src=>"/images/IST_logo_s.png", :alt=>"logo", :width=>"120px"}
+ %div.col-7
+ %h1 lazar toxicity predictions
+ %div.col-2
+ %h5
+ %a.text-right{:href=>"https://nano-lazar.in-silico.ch", :rel=>"external"}
+ nano-lazar
+ %span.fa.fa-xs.fa-external-link
%div.container-fluid
%topline.alert
- %div.row
- %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
- , 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{: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", :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", :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", :rel=>"external", :title=>"Share on Facebook"}
- %img.share{:src=>"/images/Facebook.png"}
- %div.row
- %div.col-md-12
- Please cite
- %a{ :href=>"https://doi.org/10.3389/fphar.2013.00038", :rel=>"external"}
- %img{ :src=>"https://zenodo.org/badge/DOI/10.3389/zenodo.10.3389.svg", :alt=>"DOI"}
- in scientific publications.
-
- :javascript
- $(document).ready(function(){
- $("#back-top").hide();
- $(".blind").error(function(){
- $(this).attr('src', '/images/blind.png');
- });
- });
- $(document).ready(function(){
- $('[data-toggle="popover"]').popover();
- $('.modal').on('hidden.bs.modal', function () {
- $(this).removeData('bs.modal');
- });
- });
+ %p
+ Problems, bugs or ideas for improvements ? Please check the
+ %a{:href=> "//#{$host_with_port}/predict/faq"} FAQ
+ page or send us an email.
+ %a{ :href=>"mailto:info@in-silico.ch?subject=[lazar v#{@version}]", :target=>"_top"}
+ %span.fa.fa-envelope
+ [version: #{@version}]
+ %p
+ A graphical overview of the service API can be found
+ %a{:href => "//#{$host_with_port}/api", :rel => "external"} here.
+ Please cite
+ %a{ :href=>"https://doi.org/10.3389/fphar.2013.00038", :rel=>"external"}
+ %img{ :src=>"https://zenodo.org/badge/DOI/10.3389/zenodo.10.3389.svg", :alt=>"DOI"}
+ in scientific publications.
+ %a{:href=>"https://twitter.com/intent/tweet?source=http%3A%2F%2Flazar.in-silico.ch&text=https%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Tweet"}
+ %span.fa.fa-twitter-square
+ %a{:href=>"http://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=https%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Share on LinkedIn"}
+ %span.fa.fa-linkedin-square
+ %a{:href=>"https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Flazar.in-silico.ch&title=&summary=&source=https%3A%2F%2Flazar.in-silico.ch", :rel=>"external", :title=>"Share on Facebook"}
+ %span.fa.fa-facebook-square
= yield
@@ -88,24 +64,24 @@
&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
- %div.panel.panel-default
+ %a{:href => "//#{$host_with_port}/predict/license", :rel => "external"} GPL3 License
+ %supporters.row
+ %div.card-body.text-center
+ %div.card-title
Financial support by
- %div.panel-body
- %a{:href=>"http://www.bfr.bund.de/de/start.html", :rel=>"external"}
- %img{:src=>"/images/bfr_logo.gif"}
- %a{:href=>"http://www.opentox.org/", :rel=>"external"}
- %img{:src=>"/images/ot_logo.png"}
- %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", :rel=>"external"}
- %img{:src=>"/images/nestec.jpg"}
-
+ %div.card-text
+ %a{:href=>"https://www.bfr.bund.de/de/start.html", :rel=>"external"}
+ %img{:src=>"/images/bfr_logo.gif"}
+ %a{:href=>"https://www.opentox.org/", :rel=>"external"}
+ %img{:src=>"/images/ot_logo.png"}
+ %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", :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;"}
- %span.glyphicon.glyphicon-circle-arrow-up{:style => "font-size:3em;color:black;"}
+ %span.fa.fa-caret-up{:style => "font-size:3em;color:black;"}
:javascript
$("#back-top").hide();
$(function () {
@@ -124,3 +100,15 @@
return false;
});
});
+ $(document).ready(function(){
+ $("#back-top").hide();
+ $(".blind").on('error', function(){
+ $(this).attr('src', '/images/blind.png');
+ });
+ });
+ $(document).ready(function(){
+ //$('[data-toggle="popover"]').popover();
+ $('.modal').on('hidden.bs.modal', function () {
+ $(this).removeData('bs.modal');
+ });
+ });
diff --git a/views/model_details.haml b/views/model_details.haml
index c5e3370..ab58035 100644
--- a/views/model_details.haml
+++ b/views/model_details.haml
@@ -1,7 +1,6 @@
-%div.panel.panel-default
- %div.panel-heading
- %b Model:
- %div.panel-body
+%div.card.bg-light
+ %div.card-body
+ %h6.card-title Model:
Source:
%a{:href=>model.source, :rel=>"external"}
= model.source
@@ -10,152 +9,188 @@
= "Type:\t"
= type
%br
- - training_dataset = OpenTox::Dataset.find model.model.training_dataset_id
= "Training compounds:\t"
- = training_dataset.data_entries.size
+ = data_entries.count/3
%br
= "Training dataset:\t"
- %a{:href=>"#{to("/predict/dataset/#{training_dataset.name}")}"}
+ %a{:href=>"//#{$host_with_port}/predict/dataset/#{training_dataset.name}"}
= training_dataset.name
-%div.panel.panel-default
- %div.panel-heading
- %b Algorithms:
- %div.panel-body
- 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:
- - if model.model.algorithms["prediction"]["method"] !~ /Caret/
- %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
- = model.model.algorithms["prediction"]["method"]
+%div.card.bg-light
+ %div.card-body
+ %h6.card-title Algorithms:
+ %p.card-text
+ Similarity:
+ %a.card-link{: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:
+ - if model.model.algorithms["prediction"]["method"] !~ /Caret/
+ %a.card-link{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
+ = model.model.algorithms["prediction"]["method"]
+ - else
+ %a.card-link{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox/Algorithm/Caret", :rel=>"external"}
+ = model.model.algorithms["prediction"]["method"]
+
+ %br
+ Descriptors:
+ = model.model.algorithms["descriptors"]["method"]+","
+ = model.model.algorithms["descriptors"]["type"]
+
+%div.card.bg-light
+ %div.card-body
+ - if type == "Classification"
+ %h6.card-title #{crossvalidations.size} independent 10-fold crossvalidations:
- else
- %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox/Algorithm/Caret", :rel=>"external"}
- = model.model.algorithms["prediction"]["method"]
+ %h6.card-title #{crossvalidations.size} independent 10-fold crossvalidations (-log10 transformed):
+ - crossvalidations.each_with_index do |cv,idx|
+ %p.card-text
+ - if model.classification?
+ / accuracy, confusion matrixes
+ - accept_values = cv.accept_values
+ - av = []
+ - if accept_values[1] =~ /^non/
+ - av << accept_values[0]
+ - av << accept_values[1]
+ - else
+ - av = accept_values
+ - keys = cv.accuracy.collect{|key, value| key}
+ - acc = cv.accuracy.collect{|key, value| value.signif(3)}
+ - tpr = cv.true_rate.collect{|key, hash| hash[av[0]].signif(3)}
+ - fpr = cv.true_rate.collect{|key, hash| hash[av[1]].signif(3)}
+ - pp = cv.predictivity.collect{|key, hash| hash[av[0]].signif(3)}
+ - np = cv.predictivity.collect{|key, hash| hash[av[1]].signif(3)}
+ %table.table.table-bordered.table-responsive.text-center.bg-white
+ %tr
+ %td.text-center.bg-light
+ = "Nr.#{idx+1}"
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Accuracy_and_precision", :rel=>"external"}
+ Accuracy
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Sensitivity_and_specificity", :rel=>"external"}
+ True positive rate (Sensitivity, Recall)
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Sensitivity_and_specificity", :rel=>"external"}
+ True negative rate (Specificity)
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Positive_and_negative_predictive_values", :rel=>"external"}
+ Positive predictive value (Precision)
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Positive_and_negative_predictive_values", :rel=>"external"}
+ Negative predictive value
+ - keys.each_with_index do |key,idx|
+ %tr
+ / keys
+ %td.fit.text-right= key.gsub("_", " ")
+ / acc,accuray value:
+ %td= acc[idx]
+ / tpr,true positive rate
+ %td= tpr[idx]
+ / fpr,false positive rate
+ %td= fpr[idx]
+ / pp,positive predictions
+ %td= pp[idx]
+ / np,negative predictions
+ %td= np[idx]
+ %div.row.justify-content-center
+ %h6 Confusion matrix
+ %div.row{:id=>"matrix#{model.id}#{idx}"}
+ %table.table.table-borderless.table-responsive
+ %tr
+ %td.fit.text-center all
+ %td.fit.text-center confidence high
+ %td.fit.text-center confidence low
+ %tr.justify-content-around
+ / confusion matrix
+ - keys.each do |key|
+ - matrix = cv.confusion_matrix[key]
+ %td
+ %table.table-sm.text-center
+ %tr
+ %td
+ %td
+ %td{:colspan=>"2"} measured
+ %td
+ %tr
+ %td
+ %td
+ %td.border.bg-secondary.text-white active
+ %td.border.bg-secondary.text-white inactive
+ %tr
+ %td.align-middle{:rowspan=>"2"} predicted
+ %td.border.bg-secondary.text-white active
+ %td.border.bg-white
+ %b= matrix[0][0]
+ %td.border.bg-white
+ = matrix[0][1]
+ %tr
+ //%td
+ %td.border.bg-secondary.text-white inactive
+ %td.border.bg-white
+ = matrix[1][0]
+ %td.border.bg-white
+ %b= matrix[1][1]
+ %div.row.justify-content-center
+ %h6 Probability plot
+ %div.row
+ %div.plot.mx-auto{:id=>"pplot#{model.id}#{idx}"}
+ %img{:src=>"/#{cv.id}.png", :alt=>"#{cv.id}.png"}
- %br
- Descriptors:
- = model.model.algorithms["descriptors"]["method"]+","
- = model.model.algorithms["descriptors"]["type"]
+ / regression
+ - if model.regression?
+ / rmse, mae, r_squared, pred nr, within intv, out intv
+ - keys = cv.rmse.collect{|key, value| key}
+ - rmse = cv.rmse.collect{|key, value| value.signif(3)}
+ - mae = cv.mae.collect{|key, value| value.signif(3)}
+ - rsq = cv.r_squared.collect{|key, value| value.signif(3)}
+ - nrp = cv.nr_predictions.collect{|key,value| value}
+ - wpi = cv.within_prediction_interval.collect{|key,value| value}
+ - opi = cv.out_of_prediction_interval.collect{|key,value| value}
+ %table.table.table-bordered.table-responsive.text-center.bg-white
+ %tr
+ %td.text-center.bg-light
+ = "Nr.#{idx+1}"
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"}
+ RMSE
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"}
+ MAE
+ %td
+ %a{:href=>"https://en.wikipedia.org/wiki/Coefficient_of_determination", :rel=>"external"}= "R"+"<sup>2</sup>"
+ %td Number of predictions
+ %td Within prediction interval
+ %td Out of prediction interval
+ - keys.each_with_index do |key,idx|
+ %tr
+ / keys
+ %td.fit.text-right= key.gsub("_", " ")
+ / rsme:
+ %td= rmse[idx]
+ / mae:
+ %td= mae[idx]
+ / r_squared:
+ %td= rsq[idx]
+ / Predictions number:
+ %td= nrp[idx]
+ / Within prediction interval:
+ %td= wpi[idx]
+ / Out of prediction interval:
+ %td= opi[idx]
+ %div.row.justify-content-center
+ %h6 Correlation plot
+ %div.row
+ %div.plot.mx-auto{:id=>"cplot#{model.id}#{idx}"}
+ %img{:src=>"/#{cv.id}.png", :alt=>"#{cv.id}.png"}
+ - unless idx == crossvalidations.size-1
+ %hr
-%div.panel.panel-default
- - if type == "Classification"
- %div.panel-heading
- %b Independent crossvalidations:
- - else
- %div.panel-heading
- %b Independent crossvalidations (-log10 transformed):
- %div.panel-body
- /%div.row{:id=>"validations#{model.id}", :style=>"background-color:#f5f5f5;"}
- %div.row{:id=>"validations#{model.id}"}
- - crossvalidations.each do |cv|
- %span.col-xs-4.col-sm-4.col-md-4.col-lg-4
- = "Num folds:\t"
- = cv.folds
- %br
- = "Num instances:\t"
- = cv.nr_instances
- %br
- = "Num unpredicted"
- = cv.nr_unpredicted
- - if model.classification?
- %br
- = "Accuracy:\t"
- = cv.accuracy.round(3) if cv.accuracy
- %br
- = "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
- - ["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
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"} RMSE:
- = cv.rmse.round(3) if cv.rmse
- %br
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"} MAE:
- = cv.mae.round(3) if cv.mae
- %br
- %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:"
- /%p.plot
- / %img{:src=>"/confp#{cv.id}.svg"}
- /%br
- /= "Correlation plot"
- /%p.plot
- / %img{:src=>"/corrp#{cv.id}.svg"}
-
-%div.panel.panel-default
- %div.panel-heading
- %b QMRF:
- %div.panel-body
- %a.btn.btn-default.btn-xs{:href=>"#{to("/report/#{model.id}")}", :id=>"report#{model.id}", :style=>"font-size:small;"}
- %span.glyphicon.glyphicon-download-alt
+%div.card.bg-light
+ %div.card-body
+ %h6.card-title QMRF:
+ %a.btn.btn-outline-info{:href=>"//#{$host_with_port}/predict/report/#{model.id}", :id=>"report#{model.id}", :style=>"font-size:small;"}
+ %span.fa.fa-download
XML
+%br
diff --git a/views/neighbors.haml b/views/neighbors.haml
index 8af59b6..e67c664 100644
--- a/views/neighbors.haml
+++ b/views/neighbors.haml
@@ -1,83 +1,101 @@
-%div.results
- %h3 Neighbors:
- / tabs div
- #tabs
- %ul.nav.nav-tabs.nav-justified{:id=>"neighborTabs", :role=>"tablist", :style=>"width:100%;overflow-x:auto;"}
- - @models.each_with_index do |model,i|
- / get predictionFeature type
- - m = Model::Lazar.find model.model_id.to_s
- %li{:class => ("active" if i == 0)}
- %a{:href => "#results_#{i+1}", :id => "linkTab#{i+1}", data: {toggle:"tab"}}
- = "#{model.endpoint} (#{model.species})"
- %div.tab-content
- - @predictions.each_with_index do |prediction,j|
- #results.tab-pane{:id=>"#{j+1}", :class => ("active" if j == 0)}
- :javascript
- $(document).ready(function(){
- $("table##{j+1}").tablesorter({
- debug: false,
- theme: "bootstrap",
- headerTemplate: '',
- widgets: ['columns', 'uitheme', 'stickyHeaders'],
- widgetOptions: {
- stickyHeaders_attachTo : '.tab-content',
- stickyHeaders : '',
- stickyHeaders_offset : 0,
- stickyHeaders_cloneId : '-sticky',
- stickyHeaders_addResizeEvent : true,
- stickyHeaders_includeCaption : true,
- stickyHeaders_zIndex : 2,
- stickyHeaders_attachTo : null,
- stickyHeaders_xScroll : null,
- stickyHeaders_yScroll : null,
- stickyHeaders_filteredToTop: true
- },
- sortList: [[2,1]],
- headers: {sorter: false},
- widthFixed: false
- });
- });
- - if prediction[:neighbors]
- %div.table-responsive
- %table{:id=>"#{j+1}", :style=>"border-style: solid;"}
- %thead
- %tr
- %th.sorter-false{:style =>"vertical-align:middle;"}
- Compound
- %th.sorter-false{:style =>"vertical-align:middle;"}
- Measured Activity
- %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=>"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;"}
- %tbody
- - type = @model_types[j]
- - unit = @models[j].unit
- - prediction[:neighbors].uniq.each_with_index do |neighbor,count|
- %tr
- / Compound
- - 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(c.id.to_s)}/details"), :id=>"link#{j+1}#{count}"}}
- = c.svg
- %p= c.smiles
-
- / Measured Activity
- %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;white-space:nowrap;"}
- - 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
- - if !neighbor[:measurement].nil?
- = (type == "Regression") ? "#{neighbor[:measurement].delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(neighbor[:measurement].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : neighbor[:measurement]
- / Similarity = tanimoto
- %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;"}
- = neighbor[:similarity].round(3)
+%div.card.bg-light
+ %div.card-body
+ %div.card-title
+ %h3 Neighbors:
+ #tabs
+ %ul.nav.nav-pills.nav-justified{:id=>"neighborTabs", :role=>"tablist"}
+ - @models.each_with_index do |model,i|
+ / get predictionFeature type
+ - m = Model::Lazar.find model.model_id.to_s
+ %li.nav-item
+ %a.nav-link{:class => ("active" if i ==0), :href => "#results_#{i+1}", :id => "linkTab#{i+1}", data: {toggle:"tab"}}
+ = "#{model.endpoint} (#{model.species})"
+ %div.tab-content
+ - @predictions.each_with_index do |prediction,j|
+ #results.tab-pane{:id=>"#{j+1}", :class => ("active" if j == 0)}
+ - if prediction[:neighbors]
+ %div.table-responsive
+ %table.table.table-bordered.table-hover{:id=>"nTable#{j+1}"}
+ %thead
+ %tr
+ %th{:scope=>"col"}
+ Compound
+ %th{:scope=>"col"}
+ Measured Activity
+ %a.btn.fa.fa-info-circle{: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{:scope=>"col"}
+ Similarity
+ %a.btn.fa.fa-info-circle{: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;"}
+ %tbody
+ - type = @model_types[j]
+ - unit = @models[j].unit
+ - prediction[:neighbors].uniq.each_with_index do |neighbor,count|
+ %tr
+ / Compound
+ - c = Compound.find(neighbor)
+ %td
+ %a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: "//#{$host_with_port}/prediction/#{CGI.escape(c.id.to_s)}/details", :id=>"link#{j+1}#{count}"}}
+ = embedded_svg(c.svg, :title=>"click for details")
+
+ / Measured Activity
+ %td
+ - 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
+ - if !neighbor[:measurement].nil?
+ = (type == "Regression") ? "#{neighbor[:measurement].delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(neighbor[:measurement].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : neighbor[:measurement]
+ - if c.cid && c.cid != "0"
+ %p
+ %a{:href=>PUBCHEM_CID_URI+c.cid, :rel => "external"}
+ PubChem
+ %span.fa.fa-xs.fa-external-link
+ / Similarity = tanimoto
+ %td
+ = neighbor[:similarity].round(3)
- - else
- %span.btn.btn-default.disabled
- = "Not enough similar compounds in training dataset"
+ - else
+ %span.btn.btn-default.disabled
+ = "Not enough similar compounds in training dataset"
- %div.modal.fade{:id=>"details#{j+1}", :role=>"dialog"}
- %div.modal-dialog.modal-lg
- %div.modal-content
+ %div.modal.fade{:id=>"details#{j+1}", :role=>"dialog"}
+ %div.modal-dialog.modal-lg{:role=>"document"}
+ %div.modal-content
+- @models.each_with_index do |model,i|
+ :javascript
+ // sort all neighbors tables by similarity
+ document.addEventListener('DOMContentLoaded', function() {
+ var id = '#{i+1}';
+ var table, rows, switching, i, x, y, shouldSwitch;
+ table = document.getElementById("nTable"+id);
+ switching = true;
+ /* Make a loop that will continue until
+ no switching has been done: */
+ while (switching) {
+ // Start by saying: no switching is done:
+ switching = false;
+ rows = table.rows;
+ /* Loop through all table rows (except the
+ first, which contains table headers): */
+ for (i = 1; i < (rows.length - 1); i++) {
+ // Start by saying there should be no switching:
+ shouldSwitch = false;
+ /* Get the two elements you want to compare,
+ one from current row and one from the next: */
+ x = rows[i].getElementsByTagName("TD")[2];
+ y = rows[i + 1].getElementsByTagName("TD")[2];
+ // Check if the two rows should switch place:
+ if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
+ // If so, mark as a switch and break the loop:
+ shouldSwitch = true;
+ break;
+ }
+ }
+ if (shouldSwitch) {
+ /* If a switch has been marked, make the switch
+ and mark that a switch has been done: */
+ rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
+ switching = true;
+ }
+ }
+ }, false);
diff --git a/views/predict.haml b/views/predict.haml
index 2308911..7dedf63 100644
--- a/views/predict.haml
+++ b/views/predict.haml
@@ -1,185 +1,50 @@
%link{ :href=>"/jsme/jsa.css", :rel=>"stylesheet", :property=>"stylesheet"}
%script{:src=>"/jsme/jsme.nocache.js"}
-:javascript
- var HttpClient = function() {
- this.get = function(aUrl, aCallback) {
- var anHttpRequest = new XMLHttpRequest();
- anHttpRequest.onreadystatechange = function() {
- if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
- aCallback(anHttpRequest.responseText);
- }
- anHttpRequest.open( "GET", aUrl, true );
- anHttpRequest.send( null );
- }
- };
-
- $(function() {
- $('a[data-toggle="tab"]').on('click', function (e) {
- localStorage.setItem('lastTab', $(e.target).attr('href'));
- });
- var lastTab = localStorage.getItem('lastTab');
- if (lastTab) {
- $('a[href="'+lastTab+'"]').click();
- }
- });
-
- function getInput(){
- identifier = document.getElementById("identifier").value.trim();
- fileselect = document.getElementById("fileselect").value;
- if (fileselect != ""){
- return 1;
- };
- if (identifier != ""){
- return 2;
- };
- return 0;
- };
- function showcircle() {
- switch (getInput()){
- case 0:
- alert("Please draw or insert a chemical structure.");
- return false;
- break;
- case 1:
- if (checkfile() && checkboxes()){
- button = document.getElementById("submit");
- image = document.getElementById("circle");
- button.parentNode.replaceChild(image, button);
- $("img.circle").show();
- return true;
- };
- return false;
- break;
- case 2:
- if (checksmiles() && checkboxes()){
- button = document.getElementById("submit");
- image = document.getElementById("circle");
- button.parentNode.replaceChild(image, button);
- $("img.circle").show();
- return true;
- };
- return false;
- break;
- default: false;
- };
- return false;
- };
- function checkfile() {
- var fileinput = document.getElementById("fileselect");
- if(fileinput.value != "") {
- //TODO check file type is csv
- return true;
- };
- alert("Please select a file (csv).");
- return false;
- };
- function checksmiles () {
- getsmiles();
- if (document.form.identifier.value == "") {
- alert("Please draw or insert a chemical structure.");
- document.form.identifier.focus();
- $("img.circle").hide();
- return false;
- };
- return true;
- };
- function checkboxes () {
- var checked = false;
- $('input[type="checkbox"]').each(function() {
- if ($(this).is(":checked")) {
- checked = true;
- };
- });
- if (checked == false){
- alert("Please select an endpoint.");
- $("img.circle").hide();
- return false;
- };
- return true;
- };
- function jsmeOnLoad() {
- jsmeApplet = new JSApplet.JSME("appletContainer", "380px", "340px", {
- //optional parameters
- "options" : "polarnitro"
- });
- document.JME = jsmeApplet;
- };
- function getsmiles() {
- if (document.JME.smiles() != '') {
- document.form.identifier.value = document.JME.smiles() ;
- };
- };
-
-// 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())" }
- %fieldset#top.well
- %h2 1. Draw a chemical structure
- #insert
+// whole site content needs to be in one form. Input and checkboxes are proofed by js functions.
+%form{:name => "form", :action => "//#{$host_with_port}/predict", :method => "post", :enctype => "multipart/form-data", :onsubmit => "return !!(showcircle())" }
+ %fieldset#top.card.bg-light
+ #insert.card-body
+ %h2.card-title 1. Draw a chemical structure
%label &nbsp;
- #appletContainer
- %br
- %label{:for => 'identifier'}
- or enter the
- %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification", :rel => "external"} SMILES
- string:
+ #appletContainer.d-flex
%br
- %input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'}
%p
- -#%label{:for=>"fileselect"}
- or upload a CSV file for batch predictions:
- -#%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{:style=>"display:none;"}
- %input{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled", :type=>"hidden"}
+ %label{:for => 'identifier'}
+ or enter the
+ %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification", :rel => "external"} SMILES
+ string:
+ %input.form-control{:type => 'text', :name => 'identifier', :id => 'identifier'}
+ %p{:style=>("display:none;" unless ENV["BATCH_MODE"].to_boolean)}
+ %label{:for=>"fileselect"}
+ or upload a CSV file for batch predictions:
+ %br
+ %span.btn.btn-file{:style=>"background-color:white;"}
+ %input.form-control-file{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv"}
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict/help", :rel => "external", :style=>"margin-left: 1em;"} Help
- %fieldset#middle.well
- %h2 2. Select one or more endpoints
- #models
+ %fieldset#middle.card.bg-light
+ #models.card-body
+ %h2.card-title 2. Select one or more endpoints
- @endpoints.each do |endpoint|
- %div{:id=>endpoint.gsub(/\s+/, "_")}
- %h4.head-back=endpoint
- - @models.select{|m| m.endpoint == endpoint}.each do |model|
- %div.row{:id => model.id,:style=>"margin-bottom:1em;"}
- %span.col-lg-4.col-md-4.col-sm-4.col-xs-4
- %input{:type => "checkbox", :name => "selection[#{model.id}]", :id => "selection[#{model.species.gsub(/\s+/, "_")}]", :value => true, :disabled => false}
- %label{:for => "selection[#{model.species.gsub(/\s+/, "_")}]"}
- = model.species
- %span.col-lg-8.col-md-8.col-sm-8.col-xs-8
- %a.btn.btn-default.btn-xs{:data=>{:toggle=>"collapse"}, :href=>"#details#{model.id}", :onclick=>"load#{model.id}Details('#{model}')", :id => "link#{model.id}", :style=>"font-size:small;"}
- %span.glyphicon.glyphicon-menu-right
- Details | Validation
- %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle#{model.id}", :class=>"circle#{model.id}", :alt=>"wait", :style=>"display:none;"}
- %div.panel-collapse.collapse{:id=>"details#{model.id}", :style=>"margin-left:1em;"}
- :javascript
- function load#{model.id}Details(model) {
- button = document.getElementById("link#{model.id}");
- span = button.childNodes[1];
- if (span.className == "glyphicon glyphicon-menu-right"){
- span.className = "glyphicon glyphicon-menu-down";
- } else if (span.className = "glyphicon glyphicon-menu-down"){
- span.className = "glyphicon glyphicon-menu-right";
- };
- image = document.getElementById("circle#{model.id}");
- if ($('modeldetails#{model.id}').length == 0) {
- $(button).hide();
- $(image).show();
- aClient = new HttpClient();
- aClient.get("#{to("/predict/modeldetails/#{model.id}")}", function(response) {
- var details = document.createElement("modeldetails#{model.id}");
- details.innerHTML = response;
- document.getElementById("details#{model.id}").appendChild(details);
- $(button).show();
- $(image).hide();
- addExternalLinks();
- });
- }
- }
- %fieldset#bottom.well
- %div.row
- %div.col-lg-2.col-md-2.col-sm-2.col-xs-2
- %h2
- 3. Predict
- %div.col-lg-10.col-md-10.col-sm-10.col-xs-10
- %button.has-feedback.btn.btn-warning.h2{:type => "submit", :id => "submit", :value=>"", :onclick => "getsmiles()"}
- %span.glyphicon.glyphicon-play
- %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
+ %div.card{:id=>endpoint.gsub(/\s+/, "_")}
+ %div.card-header
+ %h5.card-title=endpoint
+ %div.card-body
+ - @models.select{|m| m.endpoint == endpoint}.each do |model|
+ %div.row{:id => model.id,:style=>"margin-bottom:1em;"}
+ %span.col-6
+ %input{:type => "checkbox", :name => "selection[#{model.id}]", :id => "selection[#{model.species.gsub(/\s+/, "_")}]", :value => true, :disabled => false}
+ %label{:for => "selection[#{model.species.gsub(/\s+/, "_")}]"}
+ = model.species
+ %span.col-6
+ %a.btn.btn-outline-info{:role=>"button", :data=>{:toggle=>"collapse"}, :href=>"#details#{model.id}", :aria=>{:expanded=>"false", :controls=>"details#{model.id}"}, :onclick=>"loadDetails('#{model.id}','//#{$host_with_port}/predict/modeldetails/#{model.id}')", :id => "link#{model.id}", :style=>"font-size:small;"}
+ %span.fa.fa-caret-right
+ Details | Validation
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle#{model.id}", :class=>"circle#{model.id}", :alt=>"wait", :style=>"display:none;"}
+ %div.collapse{:id=>"details#{model.id}", :style=>"margin-left:1em;"}
+ %fieldset#bottom.card.bg-light
+ %div.card-body
+ %h2.card-title 3. Predict
+ %button.has-feedback.btn.btn-primary.btn-lg{:type => "submit", :id => "submit", :value=>"", :onclick => "getsmiles()"}
+ %span.fa.fa-play
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
diff --git a/views/prediction.haml b/views/prediction.haml
index 4181c22..44d5fa8 100644
--- a/views/prediction.haml
+++ b/views/prediction.haml
@@ -1,120 +1,127 @@
-: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
+%div.card
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict"}
+ %span.fa.fa-caret-left
New Prediction
- / displays all prediction result in first table
- %h3 Prediction Results:
- %div.table-responsive
- %table.table.table-bordered{:id=>"overview"}
- %tbody
- %tr
- %td{:id=>"compound", :style=>"vertical-align:top;text-align:center;"}
- %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
- - @model_types = {}
- - @dbhit = {}
- - @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})"
-
- / check for prediction
- - if prediction[:neighbors] and !prediction[:value].nil?
+%div.card.bg-light
+ %div.card-body
+ %h3.card-title Prediction:
+ %div.table-responsive
+ %table.table.table-bordered{:id=>"overview"}
+ %tbody
+ %tr
+ %td.align-items-center{:id=>"compound"}
+ %a.btn.btn-link{:href => "#details0", data: { toggle: "modal", remote: "//#{$host_with_port}/prediction/#{@compound.id}/details", :id=>"link01"}}
+ = embedded_svg(@compound.svg, :title=>"click for details")
+ %p= @compound.smiles
+ - if @compound.cid && @compound.cid != "0"
%p
- / show model type (classification|regression)
- %b Type:
- = type
- %p
- / check for database hit
- - if prediction[:info] =~ /\b(identical)\b/i
- - @dbhit[i] = true
-
- / show message about dbhit and measurements
+ %a{:href=>PUBCHEM_CID_URI+@compound.cid, :rel => "external"}
+ PubChem
+ %span.fa.fa-xs.fa-external-link
+ - @model_types = {}
+ - @dbhit = {}
+ - @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
+ %b{:class => "title"}
+ = "#{@models[i].endpoint.gsub('_', ' ')} (#{@models[i].species})"
+
+ / check for prediction
+ - if prediction[:neighbors] and !prediction[:value].nil?
%p
- :plain
- This compound was part of the training dataset. <i>All</i> information </br>
- from this compound was removed from the training data before the </br>
- prediction, to obtain unbiased results.
+ / show model type (classification|regression)
+ %b Type:
+ = type
+ %p
+ / check for database hit
+ - if prediction[:info] =~ /\b(identical)\b/i
+ - @dbhit[i] = true
+
+ / show message about dbhit and measurements
%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(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
-
- - else
- - @dbhit[i] = false
-
- / show prediction
- %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>.<hr></hr><a href=\"https://doi.org/10.3389/fphar.2013.00038\", target=\"_blank\"><img src=\"https://zenodo.org/badge/DOI/10.3389/zenodo.10.3389.svg\" alt=\"DOI\"></a>"}}
- %br
- = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})</br>#{@compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
+ :plain
+ This compound was part of the training dataset. <i>All</i> information </br>
+ from this compound was removed from the training data before the </br>
+ prediction, to obtain unbiased results.
+ %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(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
- / show prediction interval or probability
+ - else
+ - @dbhit[i] = false
+
+ / show prediction
%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."}}
+ %b Prediction:
+ / prediction popover
+ %a.btn.fa.fa-info-circle{: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>.<hr></hr><a href=\"https://doi.org/10.3389/fphar.2013.00038\", target=\"_blank\"><img src=\"https://zenodo.org/badge/DOI/10.3389/zenodo.10.3389.svg\" alt=\"DOI\"></a>"}}
%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(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !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?
+ = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})</br>#{@compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
+
+ / show prediction interval or probability
+ - if type == "Regression"
+ %p
+ %b 95% Prediction interval:
+ - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
+ / prediction interval popover
+ %a.btn.fa.fa-info-circle{: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
- = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0].signif(3)}"
- - if prediction[:probabilities].size == 2
+ = "#{@compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{@compound.mmol_to_mg(interval[0].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !interval.nil?
+ %p
+ %b Confidence:
+ %br
+ = prediction[:confidence]
+ - else
+ %p
+ %b Probability:
+ / probability popover
+ %a.btn.fa.fa-info-circle{: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[1]}: #{prediction[:probabilities].values[1].signif(3)}"
-
- / show warnings and info
- %p
- - if !prediction[:info].blank?
+ = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0].signif(3)}"
+ - if prediction[:probabilities].size == 2
+ %br
+ = "#{prediction[:probabilities].keys[1]}: #{prediction[:probabilities].values[1].signif(3)}"
+ %p
+ %b Confidence:
+ %br
+ = prediction[:confidence]
+
+ / show warnings and info
+ %p
+ - unless @dbhit[i] || prediction[:info].blank?
+ %b Info:
+ %br
+ %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
+ - unless prediction[:warnings].blank?
+ - warning = prediction[:warnings].last
+ %b Warnings:
+ %br
+ %p=warning#.sub(/,/, ",<br>")
+ - else
+ %br
+ - unless @dbhit[i] || prediction[:info].blank?
%b Info:
%br
%p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
- - if !prediction[:warnings].blank?
+ - unless prediction[:warnings].blank?
+ - warning = prediction[:warnings].last
%b Warnings:
- - prediction[:warnings].uniq.each do |warning|
- %p=warning #.sub(/,/, ",<br>")
- /%p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
- - else
- %br
- - if !prediction[:info].blank?
- %b Info:
- %br
- %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
- - if !prediction[:warnings].blank?
- %b Warnings:
- - prediction[:warnings].uniq.each do |warning|
%br
- %p=warning.sub(/,/, ",<br>")
+ %p=warning#.sub(/,/, ",<br>")
- / always show the neighbors table, message is given there
- = haml :neighbors, :layout => false, :model_type => @model_types, :dbhit => @dbhit
+/ 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.fade{:id=>"details0", :tabindex=>"-1", :role=>"dialog"}
+ %div.modal-dialog.modal-lg{:role=>"document"}
%div.modal-content
diff --git a/views/significant_fragments.haml b/views/significant_fragments.haml
deleted file mode 100644
index bd3598d..0000000
--- a/views/significant_fragments.haml
+++ /dev/null
@@ -1,66 +0,0 @@
-%div.modal-body{:style=>"padding:10px;"}
- %button.close{ :type=>" button", data: { dismiss:"modal"}} &times;
- - if @type =~ /classification/i
- %div.row
- %div.col-md-4
- %h3{:style=>"margin-left:8px;"}
- Significant fragments:
- %img{:src=>"#{@compound.uri}/image", :alt=>"#{@compound.smiles}", :title=>"#{@compound.smiles}", :width=>"300px", :heigth=>"300px"}
- - if !@significant_fragments.empty?
- %div.col-md-8
- %table{:id => "sf"}
- %tr
- / @value_map => hash; interpret the effect
- %th{:style=>"border:2px solid #E6E6E6;"}
- Predominantly in compounds with activity "inactive"
- %th{:style=>"border:2px solid #E6E6E6;"}
- p value
- - @significant_fragments.each do |fragments|
- / fragments == [effect, smarts, pValue]
- / fragments[0] = effect
- /- $logger.debug "effect:\t#{fragments[0]}\n"
- - if fragments[0] == @value_map.index("inactive")
- %tr
- %td
- / fragments[1] = smarts
- = fragments[1]
- -#%img{:src => "http://smartsview.de/smartsview/auto/png/1/both/#{CGI.escape(fragments[1])}", :class => "smarts"}
- %td
- /fragments[2] = pValue
- = fragments[2]
- %tr
- %th{:style=>"border:2px solid #E6E6E6;"}
- Predominantly in compounds with activity "active"
- %th{:style=>"border:2px solid #E6E6E6;"}
- p value
- - @significant_fragments.each do |fragments|
- / fragments == [effect, smarts, pValue]
- - if fragments[0] == @value_map.index("active")
- %tr
- %td
- -#%img{:src => "http://smartsview.de/smartsview/auto/png/1/both/#{CGI.escape(fragments[1])}", :class => "smarts"}
- = fragments[1]
- %td
- = fragments[2]
- %br
- - if @type =~ /regression/i
- %div.row
- %div.col-md-4
- %h3
- Descriptors:
- %img{:src=>"#{@compound.uri}/image", :alt=>"#{@compound.smiles}", :title=>"#{@compound.smiles}", :width=>"300px", :heigth=>"300px"}
- - if !@significant_fragments.empty?
- %div.col-md-8
- %table{:id =>"de"}
- %tr
- %th{:style=>"border:2px solid #E6E6E6;"}
- Descriptor
- %th{:style=>"border:2px solid #E6E6E6;"}
- value
- - @significant_fragments.each do |fragments|
- %tr
- %td
- = fragments[0]
- %td
- = fragments[1][0].round(3)
- %br
diff --git a/views/style.scss b/views/style.scss
index a23bb5d..63f9e74 100644
--- a/views/style.scss
+++ b/views/style.scss
@@ -1,57 +1,43 @@
-@media (min-width: 320px){
+/*@media (min-width: 320px){
.page-header{
- img.media-object{
- margin-left:0;
- }
+ //img.media-object{
+ // margin-left:0;
+ //}
background-color: #fff;
padding:10px 0 10px 0;
margin: 0;
- text-align:left;
+ //text-align:left;
//display:inline-block;
width:100%;
}
}
@media (min-width: 480px){
.page-header{
- img.media-object{
- margin-left:1em;
- }
+ //img.media-object{
+ // margin-left:1em;
+ //}
background-color: #fff;
padding:20px 0 20px 0;
margin: 0;
- text-align:center;
+ //text-align:center;
//display:inline-block;
width:100%;
}
+}*/
+.page-header {
+ background-color: #fff;
}
body {
background-color:#E7E7E7;
}
-table.table-borderless tbody tr td{
- border-top: none;
-}
-h4.head-back, h5.head-back{
- background-color: #E7E7E7;
-}
-.nav-tabs {
- background-color: #E7E7E7;
-
- li.active a:hover {
- background-color: #f5f5f5;
- }
-
- li a {
- //height: 7em;
- }
-}
img {
max-width: 100%;
max-height: 100%;
}
.plot {
- height: 300px;
- width: 300px;
+ height: 50%;
+ width: 50%;
}
.faq {
text-align: block;
@@ -62,12 +48,6 @@ img {
.faq h1 {
text-align: center;
}
-.tablesorter-bootstrap thead .sorter-false {
- cursor: default;
-}
-.tablesorter-bootstrap thead {
- background-color: #E7E7E7;
-}
ul.share-buttons{
list-style: none;
}
@@ -82,14 +62,41 @@ ul.share-buttons{
width: 30px;
padding-right: 5px;
}
+.footer{
+ margin-top:3em;
+}
+.single-batch{
+ table-layout: fixed;
+ width: 100%;
+}
+.help table, .help th, .help td {
+ background-color: white;
+ border: 1px solid black;
+ border-bottom: none;
+ width: 100%;
+}
+.help th, .help td {
+ padding: 10px;
+ text-align: left;
+}
+/*img.supporters {
+ width: 150px;
+ height: 150px;
+}*/
supporters{
- text-align:center;
+ background-color: #fff;
img{
width: 200px;
margin: 1em;
}
}
-.footer{
- margin-top:3em;
+.table td.fit,
+.table th.fit {
+ white-space: nowrap;
+ width: 1%;
+}
+
+.modal-body p {
+ word-wrap: break-word;
}
diff --git a/views/upload.haml b/views/upload.haml
new file mode 100644
index 0000000..54faa5c
--- /dev/null
+++ b/views/upload.haml
@@ -0,0 +1,28 @@
+%div.card
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict"}
+ %span.fa.fa-caret-left{:aria=>{:hidden=>"true"}}
+ New Prediction
+%div.card.bg-light{:id=>"uploadDataset"}
+ %div.card-body
+ %h3.card-title="Processing file #{@filename} to dataset."
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle_upload", :class=>"circle", :alt=>"processing"}
+ :javascript
+ $(document).ready(function() {
+ var aClient = new HttpClient();
+ aClient.post('//#{$host_with_port}/predict', 'models=#{@models}&batchfile=#{@filename}', function(res1) {
+ var contentType = res1.getResponseHeader('content-type');
+ if (contentType == "application/json"){
+ var response = JSON.parse(res1.responseText);
+ } else {
+ var response = res1.responseText;
+ }
+ if (res1.status == 200 && response['models'] && response['dataset_id']){
+ aClient.post('//#{$host_with_port}/predict', 'models='+response['models']+'&dataset_id='+response['dataset_id'], function(res2) {
+ $("body").html(res2.responseText);
+ });
+ }
+ if (res1.status == 200 && contentType == "text/html"){
+ $("body").html(response);
+ }
+ });
+ });