lazar-gui 1.3.1 → 1.4.0.pre.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/FAQ.md +9 -6
  4. data/Gemfile +2 -2
  5. data/README.md +19 -8
  6. data/VERSION +1 -1
  7. data/api/api.json +1000 -0
  8. data/application.rb +269 -206
  9. data/config.ru +7 -2
  10. data/docker/Dockerfile +73 -0
  11. data/docker/start.sh +12 -0
  12. data/docker/swagger.html +107 -0
  13. data/helper.rb +46 -1
  14. data/lazar-gui.gemspec +6 -6
  15. data/lib/api.rb +29 -0
  16. data/lib/compound.rb +68 -0
  17. data/lib/dataset.rb +33 -0
  18. data/lib/endpoint.rb +23 -0
  19. data/lib/feature.rb +29 -0
  20. data/lib/model.rb +152 -0
  21. data/lib/report.rb +29 -0
  22. data/lib/substance.rb +34 -0
  23. data/lib/swagger.rb +3 -0
  24. data/lib/validation.rb +67 -0
  25. data/public/fonts/FontAwesome.otf +0 -0
  26. data/public/fonts/fontawesome-webfont.eot +0 -0
  27. data/public/fonts/fontawesome-webfont.svg +2671 -0
  28. data/public/fonts/fontawesome-webfont.ttf +0 -0
  29. data/public/fonts/fontawesome-webfont.woff +0 -0
  30. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  31. data/public/images/orn-logo.jpg +0 -0
  32. data/public/javascripts/bootstrap.js +3944 -0
  33. data/public/javascripts/google_analytics_lazar.js +2 -2
  34. data/public/javascripts/jquery.min.js +2 -0
  35. data/public/javascripts/lazar-gui.js +313 -0
  36. data/public/javascripts/pagination.min.js +11 -0
  37. data/public/javascripts/popper.min.js +5 -0
  38. data/public/stylesheets/bootstrap.min.css +7 -0
  39. data/public/stylesheets/bootstrap.min.css.map +1 -0
  40. data/public/stylesheets/font-awesome.min.css +4 -0
  41. data/public/stylesheets/pagination.css +1 -0
  42. data/qmrf_report.rb +64 -14
  43. data/task.rb +68 -0
  44. data/unicorn.rb +0 -1
  45. data/views/batch.haml +48 -107
  46. data/views/details.haml +10 -2
  47. data/views/error.haml +4 -5
  48. data/views/faq.haml +6 -2
  49. data/views/help.haml +68 -0
  50. data/views/info.haml +3 -2
  51. data/views/layout.haml +68 -78
  52. data/views/model_details.haml +179 -144
  53. data/views/neighbors.haml +98 -80
  54. data/views/predict.haml +43 -178
  55. data/views/prediction.haml +109 -102
  56. data/views/style.scss +44 -37
  57. data/views/upload.haml +28 -0
  58. metadata +51 -105
  59. data/public/css/bootstrap-theme.min.css +0 -5
  60. data/public/css/bootstrap.min.css +0 -5
  61. data/public/css/bootstrap.vertical-tabs.min.css +0 -1
  62. data/public/css/images/black-asc.gif +0 -0
  63. data/public/css/images/black-desc.gif +0 -0
  64. data/public/css/images/black-unsorted.gif +0 -0
  65. data/public/css/images/bootstrap-black-unsorted.png +0 -0
  66. data/public/css/images/bootstrap-white-unsorted.png +0 -0
  67. data/public/css/images/dragtable-handle.png +0 -0
  68. data/public/css/images/dragtable-handle.svg +0 -7
  69. data/public/css/images/dropbox-asc-hovered.png +0 -0
  70. data/public/css/images/dropbox-asc.png +0 -0
  71. data/public/css/images/dropbox-desc-hovered.png +0 -0
  72. data/public/css/images/dropbox-desc.png +0 -0
  73. data/public/css/images/first.png +0 -0
  74. data/public/css/images/green-asc.gif +0 -0
  75. data/public/css/images/green-desc.gif +0 -0
  76. data/public/css/images/green-header.gif +0 -0
  77. data/public/css/images/green-unsorted.gif +0 -0
  78. data/public/css/images/ice-asc.gif +0 -0
  79. data/public/css/images/ice-desc.gif +0 -0
  80. data/public/css/images/ice-unsorted.gif +0 -0
  81. data/public/css/images/last.png +0 -0
  82. data/public/css/images/loading.gif +0 -0
  83. data/public/css/images/metro-black-asc.png +0 -0
  84. data/public/css/images/metro-black-desc.png +0 -0
  85. data/public/css/images/metro-loading.gif +0 -0
  86. data/public/css/images/metro-unsorted.png +0 -0
  87. data/public/css/images/metro-white-asc.png +0 -0
  88. data/public/css/images/metro-white-desc.png +0 -0
  89. data/public/css/images/next.png +0 -0
  90. data/public/css/images/prev.png +0 -0
  91. data/public/css/images/white-asc.gif +0 -0
  92. data/public/css/images/white-desc.gif +0 -0
  93. data/public/css/images/white-unsorted.gif +0 -0
  94. data/public/css/jquery-ui.css +0 -1225
  95. data/public/css/jquery-ui.theme.min.css +0 -5
  96. data/public/css/theme.bootstrap.css +0 -158
  97. data/public/css/theme.bootstrap.min.css +0 -1
  98. data/public/css/theme.default.min.css +0 -1
  99. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  100. data/public/fonts/glyphicons-halflings-regular.svg +0 -288
  101. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  102. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  103. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  104. data/public/images/Email.png +0 -0
  105. data/public/images/Facebook.png +0 -0
  106. data/public/images/Google+.png +0 -0
  107. data/public/images/LinkedIn.png +0 -0
  108. data/public/images/OpenToxEuro2013_small.png +0 -0
  109. data/public/images/Twitter.png +0 -0
  110. data/public/images/arrow_down_float.png +0 -0
  111. data/public/images/arrow_left_float.png +0 -0
  112. data/public/images/arrow_right_float.png +0 -0
  113. data/public/images/arrow_up_float.png +0 -0
  114. data/public/images/asc.gif +0 -0
  115. data/public/images/bg.gif +0 -0
  116. data/public/images/desc.gif +0 -0
  117. data/public/images/gray_jean.png +0 -0
  118. data/public/images/info_white.png +0 -0
  119. data/public/javascripts/bootstrap.min.js +0 -7
  120. data/public/javascripts/jquery-1.11.2.min.js +0 -4
  121. data/public/javascripts/jquery-1.8.3.min.js +0 -2
  122. data/public/javascripts/jquery-ui-1.10.3.custom.min.js +0 -6
  123. data/public/javascripts/jquery.bpopup.min.js +0 -7
  124. data/public/javascripts/jquery.tablesorter.min.js +0 -2
  125. data/public/javascripts/jquery.tablesorter.widgets.js +0 -2678
  126. data/public/javascripts/jquery.tools.min.js +0 -5
  127. data/public/rect.png +0 -0
  128. data/test/lazarweb.rb +0 -193
  129. data/test/setup.rb +0 -7
  130. data/views/significant_fragments.haml +0 -66
data/views/predict.haml CHANGED
@@ -1,185 +1,50 @@
1
1
  %link{ :href=>"/jsme/jsa.css", :rel=>"stylesheet", :property=>"stylesheet"}
2
2
  %script{:src=>"/jsme/jsme.nocache.js"}
3
- :javascript
4
- var HttpClient = function() {
5
- this.get = function(aUrl, aCallback) {
6
- var anHttpRequest = new XMLHttpRequest();
7
- anHttpRequest.onreadystatechange = function() {
8
- if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
9
- aCallback(anHttpRequest.responseText);
10
- }
11
- anHttpRequest.open( "GET", aUrl, true );
12
- anHttpRequest.send( null );
13
- }
14
- };
15
-
16
- $(function() {
17
- $('a[data-toggle="tab"]').on('click', function (e) {
18
- localStorage.setItem('lastTab', $(e.target).attr('href'));
19
- });
20
- var lastTab = localStorage.getItem('lastTab');
21
- if (lastTab) {
22
- $('a[href="'+lastTab+'"]').click();
23
- }
24
- });
25
-
26
- function getInput(){
27
- identifier = document.getElementById("identifier").value.trim();
28
- fileselect = document.getElementById("fileselect").value;
29
- if (fileselect != ""){
30
- return 1;
31
- };
32
- if (identifier != ""){
33
- return 2;
34
- };
35
- return 0;
36
- };
37
- function showcircle() {
38
- switch (getInput()){
39
- case 0:
40
- alert("Please draw or insert a chemical structure.");
41
- return false;
42
- break;
43
- case 1:
44
- if (checkfile() && checkboxes()){
45
- button = document.getElementById("submit");
46
- image = document.getElementById("circle");
47
- button.parentNode.replaceChild(image, button);
48
- $("img.circle").show();
49
- return true;
50
- };
51
- return false;
52
- break;
53
- case 2:
54
- if (checksmiles() && checkboxes()){
55
- button = document.getElementById("submit");
56
- image = document.getElementById("circle");
57
- button.parentNode.replaceChild(image, button);
58
- $("img.circle").show();
59
- return true;
60
- };
61
- return false;
62
- break;
63
- default: false;
64
- };
65
- return false;
66
- };
67
- function checkfile() {
68
- var fileinput = document.getElementById("fileselect");
69
- if(fileinput.value != "") {
70
- //TODO check file type is csv
71
- return true;
72
- };
73
- alert("Please select a file (csv).");
74
- return false;
75
- };
76
- function checksmiles () {
77
- getsmiles();
78
- if (document.form.identifier.value == "") {
79
- alert("Please draw or insert a chemical structure.");
80
- document.form.identifier.focus();
81
- $("img.circle").hide();
82
- return false;
83
- };
84
- return true;
85
- };
86
- function checkboxes () {
87
- var checked = false;
88
- $('input[type="checkbox"]').each(function() {
89
- if ($(this).is(":checked")) {
90
- checked = true;
91
- };
92
- });
93
- if (checked == false){
94
- alert("Please select an endpoint.");
95
- $("img.circle").hide();
96
- return false;
97
- };
98
- return true;
99
- };
100
- function jsmeOnLoad() {
101
- jsmeApplet = new JSApplet.JSME("appletContainer", "380px", "340px", {
102
- //optional parameters
103
- "options" : "polarnitro"
104
- });
105
- document.JME = jsmeApplet;
106
- };
107
- function getsmiles() {
108
- if (document.JME.smiles() != '') {
109
- document.form.identifier.value = document.JME.smiles() ;
110
- };
111
- };
112
-
113
- // whole site content needs to be in one form. Input and checkboxes are proofed by js functions.
114
- %form{:name => "form", :action => to('/predict'), :method => "post", :enctype => "multipart/form-data", :onsubmit => "return !!(showcircle())" }
115
- %fieldset#top.well
116
- %h2 1. Draw a chemical structure
117
- #insert
3
+ // whole site content needs to be in one form. Input and checkboxes are proofed by js functions.
4
+ %form{:name => "form", :action => "//#{$host_with_port}/predict", :method => "post", :enctype => "multipart/form-data", :onsubmit => "return !!(showcircle())" }
5
+ %fieldset#top.card.bg-light
6
+ #insert.card-body
7
+ %h2.card-title 1. Draw a chemical structure
118
8
  %label  
119
- #appletContainer
120
- %br
121
- %label{:for => 'identifier'}
122
- or enter the
123
- %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification", :rel => "external"} SMILES
124
- string:
9
+ #appletContainer.d-flex
125
10
  %br
126
- %input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'}
127
11
  %p
128
- -#%label{:for=>"fileselect"}
129
- or upload a CSV file for batch predictions:
130
- -#%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."}}
131
- -#%br
132
- %span.btn.btn-default.btn-file{:style=>"display:none;"}
133
- %input{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled", :type=>"hidden"}
12
+ %label{:for => 'identifier'}
13
+ or enter the
14
+ %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification", :rel => "external"} SMILES
15
+ string:
16
+ %input.form-control{:type => 'text', :name => 'identifier', :id => 'identifier'}
17
+ %p{:style=>("display:none;" unless ENV["BATCH_MODE"].to_boolean)}
18
+ %label{:for=>"fileselect"}
19
+ or upload a CSV file for batch predictions:
20
+ %br
21
+ %span.btn.btn-file{:style=>"background-color:white;"}
22
+ %input.form-control-file{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv"}
23
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict/help", :rel => "external", :style=>"margin-left: 1em;"} Help
134
24
 
135
- %fieldset#middle.well
136
- %h2 2. Select one or more endpoints
137
- #models
25
+ %fieldset#middle.card.bg-light
26
+ #models.card-body
27
+ %h2.card-title 2. Select one or more endpoints
138
28
  - @endpoints.each do |endpoint|
139
- %div{:id=>endpoint.gsub(/\s+/, "_")}
140
- %h4.head-back=endpoint
141
- - @models.select{|m| m.endpoint == endpoint}.each do |model|
142
- %div.row{:id => model.id,:style=>"margin-bottom:1em;"}
143
- %span.col-lg-4.col-md-4.col-sm-4.col-xs-4
144
- %input{:type => "checkbox", :name => "selection[#{model.id}]", :id => "selection[#{model.species.gsub(/\s+/, "_")}]", :value => true, :disabled => false}
145
- %label{:for => "selection[#{model.species.gsub(/\s+/, "_")}]"}
146
- = model.species
147
- %span.col-lg-8.col-md-8.col-sm-8.col-xs-8
148
- %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;"}
149
- %span.glyphicon.glyphicon-menu-right
150
- Details | Validation
151
- %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle#{model.id}", :class=>"circle#{model.id}", :alt=>"wait", :style=>"display:none;"}
152
- %div.panel-collapse.collapse{:id=>"details#{model.id}", :style=>"margin-left:1em;"}
153
- :javascript
154
- function load#{model.id}Details(model) {
155
- button = document.getElementById("link#{model.id}");
156
- span = button.childNodes[1];
157
- if (span.className == "glyphicon glyphicon-menu-right"){
158
- span.className = "glyphicon glyphicon-menu-down";
159
- } else if (span.className = "glyphicon glyphicon-menu-down"){
160
- span.className = "glyphicon glyphicon-menu-right";
161
- };
162
- image = document.getElementById("circle#{model.id}");
163
- if ($('modeldetails#{model.id}').length == 0) {
164
- $(button).hide();
165
- $(image).show();
166
- aClient = new HttpClient();
167
- aClient.get("#{to("/predict/modeldetails/#{model.id}")}", function(response) {
168
- var details = document.createElement("modeldetails#{model.id}");
169
- details.innerHTML = response;
170
- document.getElementById("details#{model.id}").appendChild(details);
171
- $(button).show();
172
- $(image).hide();
173
- addExternalLinks();
174
- });
175
- }
176
- }
177
- %fieldset#bottom.well
178
- %div.row
179
- %div.col-lg-2.col-md-2.col-sm-2.col-xs-2
180
- %h2
181
- 3. Predict
182
- %div.col-lg-10.col-md-10.col-sm-10.col-xs-10
183
- %button.has-feedback.btn.btn-warning.h2{:type => "submit", :id => "submit", :value=>"", :onclick => "getsmiles()"}
184
- %span.glyphicon.glyphicon-play
185
- %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
29
+ %div.card{:id=>endpoint.gsub(/\s+/, "_")}
30
+ %div.card-header
31
+ %h5.card-title=endpoint
32
+ %div.card-body
33
+ - @models.select{|m| m.endpoint == endpoint}.each do |model|
34
+ %div.row{:id => model.id,:style=>"margin-bottom:1em;"}
35
+ %span.col-6
36
+ %input{:type => "checkbox", :name => "selection[#{model.id}]", :id => "selection[#{model.species.gsub(/\s+/, "_")}]", :value => true, :disabled => false}
37
+ %label{:for => "selection[#{model.species.gsub(/\s+/, "_")}]"}
38
+ = model.species
39
+ %span.col-6
40
+ %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;"}
41
+ %span.fa.fa-caret-right
42
+ Details | Validation
43
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle#{model.id}", :class=>"circle#{model.id}", :alt=>"wait", :style=>"display:none;"}
44
+ %div.collapse{:id=>"details#{model.id}", :style=>"margin-left:1em;"}
45
+ %fieldset#bottom.card.bg-light
46
+ %div.card-body
47
+ %h2.card-title 3. Predict
48
+ %button.has-feedback.btn.btn-primary.btn-lg{:type => "submit", :id => "submit", :value=>"", :onclick => "getsmiles()"}
49
+ %span.fa.fa-play
50
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
@@ -1,120 +1,127 @@
1
- :javascript
2
- $(document).ready(function(){
3
- $('[data-toggle="popover"]').popover();
4
- $('.modal').on('hidden.bs.modal', function () {
5
- $(this).removeData('bs.modal');
6
- });
7
- });
8
-
9
- %div.well
10
- %a.btn.btn-warning{:href => to('/predict')}
11
- %i.glyphicon.glyphicon-menu-left
1
+ %div.card
2
+ %a.btn.btn-outline-info{:href => "//#{$host_with_port}/predict"}
3
+ %span.fa.fa-caret-left
12
4
  New Prediction
13
- / displays all prediction result in first table
14
- %h3 Prediction Results:
15
- %div.table-responsive
16
- %table.table.table-bordered{:id=>"overview"}
17
- %tbody
18
- %tr
19
- %td{:id=>"compound", :style=>"vertical-align:top;text-align:center;"}
20
- %a.btn.btn-link{:href => "#details0", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(@compound.id.to_s)}/details"), :id=>"link01"}}
21
- = @compound.svg
22
- %p= @compound.smiles
23
- - @model_types = {}
24
- - @dbhit = {}
25
- - @predictions.each_with_index do |prediction,i|
26
- - type = @models[i].model.class.to_s.match("Classification") ? "Classification" : "Regression"
27
- - @model_types[i] = type
28
- - unit = @models[i].unit
29
- %td{:style=>"vertical-align:top;white-space:nowrap;"}
30
- %b{:class => "title"}
31
- = "#{@models[i].endpoint.gsub('_', ' ')} (#{@models[i].species})"
32
-
33
- / check for prediction
34
- - if prediction[:neighbors] and !prediction[:value].nil?
5
+ %div.card.bg-light
6
+ %div.card-body
7
+ %h3.card-title Prediction:
8
+ %div.table-responsive
9
+ %table.table.table-bordered{:id=>"overview"}
10
+ %tbody
11
+ %tr
12
+ %td.align-items-center{:id=>"compound"}
13
+ %a.btn.btn-link{:href => "#details0", data: { toggle: "modal", remote: "//#{$host_with_port}/prediction/#{@compound.id}/details", :id=>"link01"}}
14
+ = embedded_svg(@compound.svg, :title=>"click for details")
15
+ %p= @compound.smiles
16
+ - if @compound.cid && @compound.cid != "0"
35
17
  %p
36
- / show model type (classification|regression)
37
- %b Type:
38
- = type
39
- %p
40
- / check for database hit
41
- - if prediction[:info] =~ /\b(identical)\b/i
42
- - @dbhit[i] = true
43
-
44
- / show message about dbhit and measurements
18
+ %a{:href=>PUBCHEM_CID_URI+@compound.cid, :rel => "external"}
19
+ PubChem
20
+ %span.fa.fa-xs.fa-external-link
21
+ - @model_types = {}
22
+ - @dbhit = {}
23
+ - @predictions.each_with_index do |prediction,i|
24
+ - type = @models[i].model.class.to_s.match("Classification") ? "Classification" : "Regression"
25
+ - @model_types[i] = type
26
+ - unit = @models[i].unit
27
+ %td
28
+ %b{:class => "title"}
29
+ = "#{@models[i].endpoint.gsub('_', ' ')} (#{@models[i].species})"
30
+
31
+ / check for prediction
32
+ - if prediction[:neighbors] and !prediction[:value].nil?
45
33
  %p
46
- :plain
47
- This compound was part of the training dataset. <i>All</i> information </br>
48
- from this compound was removed from the training data before the </br>
49
- prediction, to obtain unbiased results.
34
+ / show model type (classification|regression)
35
+ %b Type:
36
+ = type
37
+ %p
38
+ / check for database hit
39
+ - if prediction[:info] =~ /\b(identical)\b/i
40
+ - @dbhit[i] = true
41
+
42
+ / show message about dbhit and measurements
50
43
  %p
51
- %b Measured activity:
52
- %br
53
- - if prediction[:measurements].is_a?(Array)
54
- = (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(", ")
55
- - else
56
- = (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]
57
-
58
- - else
59
- - @dbhit[i] = false
60
-
61
- / show prediction
62
- %p
63
- %b Prediction:
64
- / prediction popover
65
- %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>"}}
66
- %br
67
- = (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]
44
+ :plain
45
+ This compound was part of the training dataset. <i>All</i> information </br>
46
+ from this compound was removed from the training data before the </br>
47
+ prediction, to obtain unbiased results.
48
+ %p
49
+ %b Measured activity:
50
+ %br
51
+ - if prediction[:measurements].is_a?(Array)
52
+ = (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(", ")
53
+ - else
54
+ = (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]
68
55
 
69
- / show prediction interval or probability
56
+ - else
57
+ - @dbhit[i] = false
58
+
59
+ / show prediction
70
60
  %p
71
- - if type == "Regression"
72
- %b 95% Prediction interval:
73
- - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
74
- / prediction interval popover
75
- %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."}}
61
+ %b Prediction:
62
+ / prediction popover
63
+ %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>"}}
76
64
  %br
77
- = interval.nil? ? "--" : "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} (#{unit})"
78
- %br
79
- = "#{@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?
80
- - else
81
- %b Probability:
82
- / probability popover
83
- %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."}}
84
- - unless prediction[:probabilities].nil?
65
+ = (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]
66
+
67
+ / show prediction interval or probability
68
+ - if type == "Regression"
69
+ %p
70
+ %b 95% Prediction interval:
71
+ - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
72
+ / prediction interval popover
73
+ %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."}}
74
+ %br
75
+ = interval.nil? ? "--" : "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} (#{unit})"
85
76
  %br
86
- = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0].signif(3)}"
87
- - if prediction[:probabilities].size == 2
77
+ = "#{@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?
78
+ %p
79
+ %b Confidence:
80
+ %br
81
+ = prediction[:confidence]
82
+ - else
83
+ %p
84
+ %b Probability:
85
+ / probability popover
86
+ %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."}}
87
+ - unless prediction[:probabilities].nil?
88
88
  %br
89
- = "#{prediction[:probabilities].keys[1]}: #{prediction[:probabilities].values[1].signif(3)}"
90
-
91
- / show warnings and info
92
- %p
93
- - if !prediction[:info].blank?
89
+ = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0].signif(3)}"
90
+ - if prediction[:probabilities].size == 2
91
+ %br
92
+ = "#{prediction[:probabilities].keys[1]}: #{prediction[:probabilities].values[1].signif(3)}"
93
+ %p
94
+ %b Confidence:
95
+ %br
96
+ = prediction[:confidence]
97
+
98
+ / show warnings and info
99
+ %p
100
+ - unless @dbhit[i] || prediction[:info].blank?
101
+ %b Info:
102
+ %br
103
+ %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
104
+ - unless prediction[:warnings].blank?
105
+ - warning = prediction[:warnings].last
106
+ %b Warnings:
107
+ %br
108
+ %p=warning#.sub(/,/, ",<br>")
109
+ - else
110
+ %br
111
+ - unless @dbhit[i] || prediction[:info].blank?
94
112
  %b Info:
95
113
  %br
96
114
  %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
97
- - if !prediction[:warnings].blank?
115
+ - unless prediction[:warnings].blank?
116
+ - warning = prediction[:warnings].last
98
117
  %b Warnings:
99
- - prediction[:warnings].uniq.each do |warning|
100
- %p=warning #.sub(/,/, ",<br>")
101
- /%p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
102
- - else
103
- %br
104
- - if !prediction[:info].blank?
105
- %b Info:
106
- %br
107
- %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
108
- - if !prediction[:warnings].blank?
109
- %b Warnings:
110
- - prediction[:warnings].uniq.each do |warning|
111
118
  %br
112
- %p=warning.sub(/,/, ",<br>")
119
+ %p=warning#.sub(/,/, ",<br>")
113
120
 
114
- / always show the neighbors table, message is given there
115
- = haml :neighbors, :layout => false, :model_type => @model_types, :dbhit => @dbhit
121
+ / always show the neighbors table, message is given there
122
+ = haml :neighbors, :layout => false, :model_type => @model_types, :dbhit => @dbhit
116
123
 
117
- %div.modal.fade{:id=>"details0", :role=>"dialog"}
118
- %div.modal-dialog.modal-lg
124
+ %div.modal.fade{:id=>"details0", :tabindex=>"-1", :role=>"dialog"}
125
+ %div.modal-dialog.modal-lg{:role=>"document"}
119
126
  %div.modal-content
120
127