summaryrefslogtreecommitdiff
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/layout.haml103
-rw-r--r--views/license.haml1
-rw-r--r--views/predict.haml299
-rw-r--r--views/prediction.haml152
4 files changed, 555 insertions, 0 deletions
diff --git a/views/layout.haml b/views/layout.haml
new file mode 100644
index 0000000..0f5f290
--- /dev/null
+++ b/views/layout.haml
@@ -0,0 +1,103 @@
+!!!
+%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 Nano Lazar Toxicity Predictions
+ %link{:rel=>'icon', :type=>'image/x-icon', :href=>'/images/favicon.ico'}
+ %link{:rel=>'stylesheet', :href=>"#{'/css/style.css'}"}
+ %link{:rel=>'stylesheet', :href=>"#{'/css/bootstrap.min.css'}"}
+ %link{:rel=>'stylesheet', :href=>"#{'/css/theme.bootstrap.min.css'}"}
+ %link{:rel=>'stylesheet', :href=>"#{'/css/theme.default.min.css'}"}
+ %script{:src=>"/javascripts/jquery-1.11.2.min.js"}
+ %script{:src=>"/javascripts/jquery.tablesorter.min.js"}
+ %script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
+ %script{:src=>"/javascripts/jquery.tablesorter.staticrow.min.js"}
+ %script{:src=>"/javascripts/jquery.doubleScroll.js"}
+ %script{:src=>"/javascripts/bootstrap.min.js"}
+ %script{:src=>"/javascripts/nanolazar.js"}
+ %script{:src=>"/javascripts/google_analytics.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{:style=>"margin:20px 0 20px;"}
+ %div.row{:style=>"display:flex;flex-direction:row;align-items:center;justify-content:center"}
+ %div.col-sm-2
+ %a{:href=> to("/predict")}
+ %img.media-object{:src=>"/images/IST_logo_s.png", :alt=>"logo_ist", :width=>"150px", :heigth=>"150px", :style=>"margin:0 0 0 1em;"}
+ %div.col-sm-2
+ %a{:href=> "http://www.enanomapper.net"}
+ %img.media-object{:src=>"/images/enm_logo.png", :width=>"150px", :heigth=>"150px", :alt=>"logo_enm", :style=>"margin:0 0 0 1em;"}
+ %div.col-sm-6
+ %h1.media-heading{:style=>"margin:0 0 0 1em;"} nano-lazar toxicity predictions
+ %div.col-sm-2
+ %h1.media-heading{:style=>"margin:0 0 0 1em;"}
+ %small
+ %a{:href=>"https://lazar.in-silico.ch/predict", :rel=>"external"} lazar
+
+ %div.container-fluid
+ %topline
+ %div.row
+ %div.col-md-8
+ Problems, bugs, ideas for improvements ? Please report at our
+ %a{:href => 'https://github.com/enanomapper/nano-lazar/issues', :rel => "external"} issue tracker
+ or send us an email
+ %a{ :href=>"mailto:info@in-silico.ch?subject=[nano-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"}
+ %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+"}
+ %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"}
+ %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"}
+ %img.share{:src=>"/images/Facebook.png"}
+ %div.row
+ %div.col-md-12
+ Please cite
+ %a{ :href=>"https://doi.org/10.3389/fphar.2017.00377", :rel=>"external"}
+ %img{ :src=>"https://zenodo.org/badge/DOI/10.3389/fphar.2017.00377.svg", :alt=>"DOI"}
+ in scientific publications.
+ %br
+
+ :javascript
+ $(document).ready(function(){
+ $("#back-top").hide();
+ });
+
+ = yield
+
+ %footer.footer
+ %div.container-fluid
+ %p.text-muted
+ ©
+ %a{:href => 'http://www.in-silico.ch', :rel => "external"} <i style="font-family: serife">in silico</i> toxicology gmbh 2014 - #{Time.now.year.to_s}
+ |
+ %a{:href => to("/license"), :rel => "external"} GPL3 License
+
+ #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/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/predict.haml b/views/predict.haml
new file mode 100644
index 0000000..206ee63
--- /dev/null
+++ b/views/predict.haml
@@ -0,0 +1,299 @@
+:javascript
+
+ $(window).bind("pageshow", function(event) {
+ $("img.circle").hide();
+ });
+
+ function showcircle() {
+ $("img.circle").show();
+ };
+
+ function addCoating(type, coatings) {
+ //console.log(type, coatings);
+ var allCoatings = coatings;
+ var usedCoatings = [];
+ var removedCoating = [];
+ var div = document.getElementById("coatings");
+ var selectChilds = div.getElementsByTagName("select");
+ console.log(selectChilds);
+ // iterate the whole select elements and decide to add or remove;
+ // last coating should be always present; remove all used coatings
+ // from the option list for new elements, but add them back if a
+ // select element was removed;
+ for(i=0; i < selectChilds.length; i++){
+ id = selectChilds[i].id;
+ console.log(selectChilds[i].id);
+ value = selectChilds[i].value;
+ console.log(selectChilds[i].value);
+
+ if (type === "add"){
+ var element = document.getElementById(id);
+ var clone = element.cloneNode(true);
+ console.log(i);
+ console.log(i+1);
+ clone.id = "selCoating" + (selectChilds.length + 1);
+ clone.name = "input_coating_" + (selectChilds.length + 1);
+ console.log(clone.name);
+ div.appendChild(clone);
+ break;
+ };
+ if (type === "remove" && i !== 0){
+ var id = selectChilds[selectChilds.length - 1].id
+ document.getElementById(id).remove();
+ break;
+ }else{
+ //alert("One coating is required.")
+ };
+ };
+ };
+
+ $(document).ready(function(){
+ $('#selCore1').change(function(){
+ var selection = $(this).val();
+ switch(selection){
+ case "Ag":
+ $("#physchem1").prop('disabled', false);
+ $("#physchem2").prop('disabled', false);
+ $("#physchem3").prop('disabled', true);
+ $("#physchem4").prop('disabled', true);
+ $("#physchem5").prop('disabled', true);
+ $("#physchem6").prop('disabled', false);
+ $("#physchem7").prop('disabled', true);
+ $("#physchem8").prop('disabled', true);
+ $("#physchem9").prop('disabled', true);
+ $("#physchem10").prop('disabled', true);
+ break;
+ case "Au":
+ $("#physchem1").prop('disabled', false);
+ $("#physchem2").prop('disabled', false);
+ $("#physchem3").prop('disabled', false);
+ $("#physchem4").prop('disabled', false);
+ $("#physchem5").prop('disabled', false);
+ $("#physchem6").prop('disabled', false);
+ $("#physchem7").prop('disabled', false);
+ $("#physchem8").prop('disabled', false);
+ $("#physchem9").prop('disabled', false);
+ $("#physchem10").prop('disabled', false);
+ break;
+ };
+ });
+ });
+
+%div.well
+ %h3.help-block
+ Select an endpoint:
+ #tabs
+ %ul.nav.nav-tabs{:id=>"modelTab", :role=>"tablist"}
+ - @prediction_models.each_with_index do |m, idx|
+ %li{:class => ("active" if idx == 0)}
+ %a{:href => "#model_#{idx}", :id => "linkTab#{idx}", data: {toggle:"tab"}}
+ = "#{idx+1}. #{m["type"].capitalize}"
+ %div.tab-content
+ - @prediction_models.each_with_index do |m, idx|
+ - case m["type"]
+ - when "fingerprint"
+ - example = @example_fingerprint
+ - type = "fingerprint"
+ - relevant_features = @fingerprint_relevant_features
+ - when "physchem"
+ - example = @example_physchem
+ - type = "physchem"
+ - relevant_features = @physchem_relevant_features
+ - when "proteomics"
+ - example = @example_proteomics
+ - type = "proteomics"
+ - relevant_features = @proteomics_relevant_features
+
+ #model.tab-pane{:id=>"#{idx}", :class => ("active" if idx == 0)}
+ %b Model:
+ %br
+ Name:
+ = m.model.name
+ %br
+ Type: regression
+ %br
+ Source:
+ %a{:href=>"#{m.source}", :alt=>"source", :rel=>"external"}
+ = m.source
+ %br
+ Species:
+ = m.species
+ %br
+ Training nanoparticles:
+ = m.model.training_dataset.nanoparticles.size
+ %br
+ Endpoint:
+ = m.endpoint
+ %br
+ Unit:
+ = m.unit
+ %br
+ %b Algorithms:
+ %br
+ Similarity:
+ %a{:href=> "http://www.rubydoc.info/gems/lazar/OpenTox%2F#{m.model.algorithms["similarity"]["method"].sub("::", "%2F")}", :rel=>"external"}
+ = m.model.algorithms["similarity"]["method"]
+ = ", min: #{m.model.algorithms["similarity"]["min"]}"
+ %br
+ Prediction:
+ %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{m.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
+ = m.model.algorithms["prediction"]["method"]
+ %br
+ Feature selection:
+ = m.model.algorithms["feature_selection"]["method"].split(".").last if m.model.algorithms["feature_selection"]
+ %br
+ Descriptors:
+ = m.model.algorithms["descriptors"]["method"]+","
+ = m.model.algorithms["descriptors"]["categories"]
+ %p
+ %b Independent crossvalidations (log2 transformed):
+ %div.row{:id=>"validations#{m.id}", :style=>"background-color:#f5f5f5;"}
+ - m.crossvalidations.each do |cv|
+ %span.col-xs-2.col-sm-2.col-md-2.col-lg-2
+ = "Num folds:\t"
+ = cv.folds
+ %br
+ = "Num instances:\t"
+ = cv.nr_instances
+ %br
+ = "Num unpredicted"
+ = cv.nr_unpredicted
+ %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
+ %b QMRF report
+ %p
+ %a.btn.btn-default{:href=>to('/qmrf-report/'+m.id), :rel=>"external"} download
+ %hr
+ %form{:id=>idx, :role=>"form", :action=> to("/predict"), :method=>"post"}
+ %h3.help-block
+ Please characterise a nanoparticle:
+
+ - if type == "fingerprint"
+
+ %div.form-group
+ // type = fingerprint
+ // send hidden example data to compare
+ %input{:id=>"type",:type=>"hidden",:name=>"type",:value=>"#{type}"}
+ %input{:id=>"example_core",:type=>"hidden",:name=>"example_core",:value=>"#{example.core["name"]}"}
+ - example.coating.each_with_index do |ex_coating, idx|
+ %input{:id=>"example_coating_#{idx}",:type=>"hidden",:name=>"example_coating_#{idx}",:value=>"#{ex_coating["name"]}"}
+ %input{:id=>"example_pc",:type=>"hidden",:name=>"example_pc",:value=>"{}"}
+ %input{:id=>"id",:type=>"hidden",:name=>"example_id",:value=>example.id}
+
+ // input form parameters to transfer
+ // core
+ %div.form-group
+ %label{:for=>"selCore#{idx}"} Core
+ %select.form-control{:id=>"selCore#{idx}", :autocomplete=>"off", :name=>"input_core",:value=>example.core["name"]}
+ %option{:selected => ("selected" if example.core["name"] == "Ag"), :value => "Ag"} Ag
+ %option{:selected => ("selected" if example.core["name"] == "Au"), :value => "Au"} Au
+
+ // coating
+ - coatings = $coating_list.collect{|nano| nano.coating.collect{|co| co["name"]}}.flatten.compact.uniq.sort_by(&:downcase)
+ %div.form-group{:id=>"coatings"}
+ %label{:for=>"selCoating#{idx}"} Coating
+ - example.coating.each_with_index do |ex_coating, idx|
+ %select.form-control{:id=>"selCoating#{idx}", :autocomplete=>"off", :name=>"input_coating_#{idx}",:value=>ex_coating["name"]}
+ - coatings.each do |co|
+ %option{:selected => ("selected" if ex_coating["name"] == co), :value => co}
+ = co
+
+ %div{:id=>"coating_buttons"}
+ %span.btn.glyphicon.glyphicon-plus{:onclick=>"addCoating(\"add\", #{coatings});"}
+ %span.btn.glyphicon.glyphicon-minus{:onclick=>"addCoating(\"remove\", #{coatings});"}
+
+ - if type =~ /physchem/
+ %div.form-group
+ // type = physchem,proteomics
+ // send hidden example data to compare
+ %input{:id=>"type",:type=>"hidden",:name=>"type",:value=>"#{type}"}
+ %input{:id=>"example_core",:type=>"hidden",:name=>"example_core",:value=>"#{example.core["name"]}"}
+ %input{:id=>"example_coating",:type=>"hidden",:name=>"example_coating",:value=>"#{example.coating[0]["name"]}"}
+ %input{:id=>"example_pc",:type=>"hidden",:name=>"example_pc",:value=>"#{example.properties}"}
+ - size = relevant_features.size
+ %input{:id=>"size",:type=>"hidden",:name=>"size",:value=>size}
+ %input{:id=>"id",:type=>"hidden",:name=>"example_id",:value=>example.id}
+
+ // input form parameters to transfer
+ // core
+ %div.form-group
+ %label{:for=>"selCore#{idx}"} Core
+ %select.form-control{:id=>"selCore#{idx}", :autocomplete=>"off", :name=>"input_core",:value=>example.core["name"]}
+ %option{:selected => ("selected" if example.core["name"] == "Ag"), :value => "Ag"} Ag
+ %option{:selected => ("selected" if example.core["name"] == "Au"), :value => "Au"} Au
+
+ // relevant features
+ - relevant_features.sort_by{|f| f.name}.each_with_index do |relf,id|
+ - feature = relf
+ - v = example.properties.find{|id,v| id == feature.id.to_s }
+ - name = feature.name
+ - if feature[:conditions] && !feature[:conditions]["MEDIUM"].blank?
+ - name = feature.name + " / " + feature[:conditions]["MEDIUM"]
+ - else
+ - name = feature.name
+ - val = !v.nil? ? v[1] : ""
+ - id = id + 1
+
+ %h5
+ %a.descriptor{:href=>$npo[feature.name], :rel=>"external"}= name + (feature.unit.blank? ? "" : " (#{feature.unit})")
+
+ // input physchem parameters
+ %input.input-sm.form-control{:id=>"physchem#{id}",:type=>"text",:name=>"input_value_#{id}",:value=>"#{val[0]}", :disabled=>("disabled" if val[0].blank?)}
+ %input{:id=>id,:type=>"hidden",:name=>"input_key_#{id}",:value=>feature.id}
+
+ - if type =~ /proteomics/
+ %div.form-group
+ // type = physchem,proteomics
+ // send hidden example data to compare
+ %input{:id=>"type",:type=>"hidden",:name=>"type",:value=>"#{type}"}
+ %input{:id=>"example_core",:type=>"hidden",:name=>"example_core",:value=>"#{example.core["name"]}"}
+ %input{:id=>"example_coating",:type=>"hidden",:name=>"example_coating",:value=>"#{example.coating[0]["name"]}"}
+ %input{:id=>"example_pc",:type=>"hidden",:name=>"example_pc",:value=>"#{example.properties}"}
+ - size = relevant_features.size
+ %input{:id=>"size",:type=>"hidden",:name=>"size",:value=>size}
+ %input{:id=>"id",:type=>"hidden",:name=>"example_id",:value=>example.id}
+
+ // input form parameters to transfer
+ // core
+ %div.form-group
+ %label{:for=>"selCore#{idx}"} Core
+ %select.form-control{:id=>"selCore#{idx}", :autocomplete=>"off", :name=>"input_core",:value=>example.core["name"]}
+ %option{:selected => ("selected" if example.core["name"] == "Ag"), :value => "Ag"} Ag
+ %option{:selected => ("selected" if example.core["name"] == "Au"), :value => "Au"} Au
+
+ // relevant features
+ - relevant_features.sort_by{|f| f.name}.each_with_index do |relf,id|
+ - feature = relf
+ - v = example.properties.find{|id,v| id == feature.id.to_s }
+ - name = feature.name
+ - if feature[:conditions] && !feature[:conditions]["MEDIUM"].blank?
+ - name = feature.name + " / " + feature[:conditions]["MEDIUM"]
+ - else
+ - name = feature.name
+ - val = !v.nil? ? v[1] : ""
+ - id = id + 1
+
+ %h5
+ %a{:href=>"http://www.uniprot.org/uniprot/#{name}", :rel=>"external"}= name + (feature.unit.blank? ? "" : " (#{feature.unit})")
+
+ // input physchem parameters
+ %input.input-sm.form-control{:id=>"#{id}",:type=>"text",:name=>"input_value_#{id}",:value=>"#{val[0]}"}
+ %input{:id=>id,:type=>"hidden",:name=>"input_key_#{id}",:value=>feature.id}
+
+ // prediction model id
+ %input{:id=>"prediction_model",:type=>"hidden",:name=>"prediction_model",:value=>m.id}
+
+ %hr
+ #predict
+ %button.btn.btn-success{:id=>"submitbutton", :type=>"submit", :onclick=>"showcircle();"}
+ Find similar nano particles
+ %span.glyphicon.glyphicon-chevron-right{:id=>"span"}
+ %img{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
diff --git a/views/prediction.haml b/views/prediction.haml
new file mode 100644
index 0000000..e05285a
--- /dev/null
+++ b/views/prediction.haml
@@ -0,0 +1,152 @@
+%div
+ %a.btn.btn-xs.btn-default{:href => to('/predict'), :style=>"margin-bottom:1em;"}
+ %span.glyphicon.glyphicon-chevron-left
+ New Prediction
+
+ %h3.help-block
+ Similar particles
+
+ %hr
+ :javascript
+ $(document).ready(function(){
+ $(".tablesorter").tablesorter({
+ debug: false,
+ theme: "bootstrap",
+ //headerTemplate: '{content} {icon}',
+ widgets: ['uitheme', 'staticRow', 'stickyHeaders'],
+ widgetOptions: {
+ stickyHeaders_attachTo: 'neighbors',
+ stickyHeaders_offset: 0,
+ stickyHeaders_xScroll : null
+ },
+ sortList: [[1,1]],
+ widthFixed: false,
+ });
+ $('#neighbors').doubleScroll();
+ });
+
+
+ #neighbors.table-responsive
+ /%table.tablesorter{:style => "max-width:100%;white-space:nowrap;"}
+ %table.tablesorter
+ %thead
+ %tr
+ %th
+ ID
+ %th
+ Similarity
+ %th
+ Composition
+ %th.tox{:style => "max-width:100%;white-space:nowrap;"}
+ Toxicity
+ %br
+ Net cell association
+ %br
+ [mL/ug(Mg)]
+ - if @type =~ /physchem|proteomics/
+ - @input.each{|d| Feature.find(d[0]).category}.each do |key|
+ - feature = Feature.find_by(:id=>key[0])
+ - name = feature.name
+ - if (feature[:conditions] && !feature[:conditions]["MEDIUM"].blank?)
+ - name = feature.name + " / " + feature[:conditions]["MEDIUM"]
+ - else
+ - name = feature.name
+ %th.physchem.sorter-false
+ %a.descriptor{:href=>$npo[feature.name], :rel=>"external"}= name + (feature.unit.blank? ? "" : " (#{feature.unit})")
+ %tbody
+ / query and match combined
+ %tr.static
+ / id
+ %td
+ - if @match
+ %a{:href=> $ambit_search+@name, :rel=>"external"}
+ %h5.th5= @name
+ - else
+ %h5.th5 Query
+ / similarity
+ %td
+ %h5.th5 1.0
+ / composition
+ %td
+ - core = Substance.find @nanoparticle[:core_id]
+ %h5.th5 Core:
+ %a{:href=>core.source, :rel=>"external"}= "["+core.name+"]"
+ %br
+ - if @type == "fingerprint"
+ - coating = []
+ - @nanoparticle[:coating_ids].each{|id| coating << Substance.find(id) }
+ %h5.th5 Coating:
+ - coating.each do |co|
+ %a{:href=>co.source, :rel=>"external"}= co.name
+ %br
+ / tox
+ %td.tox
+ - if @prediction[:value]
+ %h5.th5 Prediction:
+ = @prediction[:value].round(3)
+ %br
+ - if @prediction[:value].blank?
+ %h5.th5 Prediction:
+ = "not available"
+ %br
+ - if @prediction[:prediction_interval]
+ %h5
+ %a{:href=>"https://en.wikipedia.org/wiki/Prediction_interval", :rel=>"external"} 95% Prediction interval:
+ - interval = @prediction[:prediction_interval].nil? ? " - - " : @prediction[:prediction_interval].collect{|i| i.round(2)}
+ = "#{interval[0]} - #{interval[1]}"
+ - if @prediction[:measurements]
+ %br
+ %h5.th5 Measurement:
+ - @prediction[:measurements].each do |m|
+ = m
+ - if !@prediction[:value] && !@prediction[:measurements]
+ %h5.th5 not available
+ / physchem
+ - if @type =~ /physchem|proteomics/
+ - @input.each do |v|
+ %td.physchem
+ %div{:style=>"display:inline-block;padding-right:20px;"}
+ - if v[1].nil?
+ %p x
+ - else
+ %p= v[1][0].round(3)
+
+ / neighbors
+ - if @prediction[:neighbors]
+ - @prediction[:neighbors].each_with_index do |neighbor,idx|
+ - nano = Nanoparticle.find(neighbor[:id])
+ - core = Substance.find nano.core_id
+ - coating = []
+ - nano.coating_ids.each{|id| coating << Substance.find(id)}
+ %tr
+ / ID
+ %td
+ %a{:href=> $ambit_search+nano.name, :rel=>"external"}
+ %h5.th5= nano.name
+ / Similarity
+ %td
+ %h5.th5= neighbor[:similarity].round(3)
+ / Composition
+ %td
+ %h5.th5 Core:
+ %a{:href=>core.source, :rel=> "external"}= "["+core.name+"]"
+ %br
+ %h5.th5 Coating:
+ - coating.each do |co|
+ %a{:href=>co.source, :rel=>"external"}= co.name
+ %br
+ / Tox
+ %td.tox
+ %h5.th5 Measurement:
+ = neighbor[:measurement]
+ / Physchem
+ - case @type
+ - when "physchem"
+ - nano.properties.delete_if{|id,v| !@physchem_relevant_features.include?(Feature.find(id))}.sort_by{|id,v| @physchem_relevant_features.index Feature.find(id)}.each do |k,v|
+ %td.physchem
+ = v[0].round(3) unless v.nil?
+ - when "proteomics"
+ - nano.properties.delete_if{|id,v| !@proteomics_relevant_features.include?(Feature.find(id))}.sort_by{|id,v| @proteomics_relevant_features.index Feature.find(id)}.each do |k,v|
+ %td.physchem
+ = v[0].round(3) unless v.nil?
+