diff options
Diffstat (limited to 'views')
-rw-r--r-- | views/layout.haml | 103 | ||||
-rw-r--r-- | views/license.haml | 1 | ||||
-rw-r--r-- | views/predict.haml | 299 | ||||
-rw-r--r-- | views/prediction.haml | 152 |
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? + |