lazar-gui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/FAQ.md +29 -0
  4. data/Gemfile +7 -0
  5. data/README.md +15 -0
  6. data/VERSION +1 -0
  7. data/application.rb +317 -0
  8. data/bin/lazar-start +5 -0
  9. data/bin/lazar-start.sh +8 -0
  10. data/bin/lazar-stop +6 -0
  11. data/bin/lazar-stop.sh +52 -0
  12. data/config.ru +5 -0
  13. data/helper.rb +218 -0
  14. data/lazar-gui.gemspec +29 -0
  15. data/public/css/bootstrap-theme.min.css +5 -0
  16. data/public/css/bootstrap.min.css +5 -0
  17. data/public/css/images/black-asc.gif +0 -0
  18. data/public/css/images/black-desc.gif +0 -0
  19. data/public/css/images/black-unsorted.gif +0 -0
  20. data/public/css/images/bootstrap-black-unsorted.png +0 -0
  21. data/public/css/images/bootstrap-white-unsorted.png +0 -0
  22. data/public/css/images/dragtable-handle.png +0 -0
  23. data/public/css/images/dragtable-handle.svg +7 -0
  24. data/public/css/images/dropbox-asc-hovered.png +0 -0
  25. data/public/css/images/dropbox-asc.png +0 -0
  26. data/public/css/images/dropbox-desc-hovered.png +0 -0
  27. data/public/css/images/dropbox-desc.png +0 -0
  28. data/public/css/images/first.png +0 -0
  29. data/public/css/images/green-asc.gif +0 -0
  30. data/public/css/images/green-desc.gif +0 -0
  31. data/public/css/images/green-header.gif +0 -0
  32. data/public/css/images/green-unsorted.gif +0 -0
  33. data/public/css/images/ice-asc.gif +0 -0
  34. data/public/css/images/ice-desc.gif +0 -0
  35. data/public/css/images/ice-unsorted.gif +0 -0
  36. data/public/css/images/last.png +0 -0
  37. data/public/css/images/loading.gif +0 -0
  38. data/public/css/images/metro-black-asc.png +0 -0
  39. data/public/css/images/metro-black-desc.png +0 -0
  40. data/public/css/images/metro-loading.gif +0 -0
  41. data/public/css/images/metro-unsorted.png +0 -0
  42. data/public/css/images/metro-white-asc.png +0 -0
  43. data/public/css/images/metro-white-desc.png +0 -0
  44. data/public/css/images/next.png +0 -0
  45. data/public/css/images/prev.png +0 -0
  46. data/public/css/images/white-asc.gif +0 -0
  47. data/public/css/images/white-desc.gif +0 -0
  48. data/public/css/images/white-unsorted.gif +0 -0
  49. data/public/css/jquery-ui.css +1225 -0
  50. data/public/css/jquery-ui.theme.min.css +5 -0
  51. data/public/css/theme.bootstrap.css +158 -0
  52. data/public/css/theme.bootstrap.min.css +1 -0
  53. data/public/css/theme.default.min.css +1 -0
  54. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  55. data/public/fonts/glyphicons-halflings-regular.svg +288 -0
  56. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  57. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  58. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  59. data/public/images/Email.png +0 -0
  60. data/public/images/Facebook.png +0 -0
  61. data/public/images/Google+.png +0 -0
  62. data/public/images/IST_logo_s.png +0 -0
  63. data/public/images/LinkedIn.png +0 -0
  64. data/public/images/OpenToxEuro2013_small.png +0 -0
  65. data/public/images/Twitter.png +0 -0
  66. data/public/images/arrow_down_float.png +0 -0
  67. data/public/images/arrow_left_float.png +0 -0
  68. data/public/images/arrow_right_float.png +0 -0
  69. data/public/images/arrow_up_float.png +0 -0
  70. data/public/images/asc.gif +0 -0
  71. data/public/images/bfr_logo.gif +0 -0
  72. data/public/images/bg.gif +0 -0
  73. data/public/images/blind.png +0 -0
  74. data/public/images/desc.gif +0 -0
  75. data/public/images/enm_logo.png +0 -0
  76. data/public/images/favicon.ico +0 -0
  77. data/public/images/gray_jean.png +0 -0
  78. data/public/images/info_white.png +0 -0
  79. data/public/images/ist_logo.png +0 -0
  80. data/public/images/nestec.jpg +0 -0
  81. data/public/images/ot_logo.png +0 -0
  82. data/public/images/wait30trans.gif +0 -0
  83. data/public/javascripts/bootstrap.min.js +7 -0
  84. data/public/javascripts/jquery-1.11.2.min.js +4 -0
  85. data/public/javascripts/jquery-1.8.3.min.js +2 -0
  86. data/public/javascripts/jquery-ui-1.10.3.custom.min.js +6 -0
  87. data/public/javascripts/jquery.bpopup.min.js +7 -0
  88. data/public/javascripts/jquery.tablesorter.min.js +2 -0
  89. data/public/javascripts/jquery.tablesorter.widgets.js +2678 -0
  90. data/public/javascripts/jquery.tools.min.js +5 -0
  91. data/public/javascripts/lazar-gui.js +11 -0
  92. data/public/jsme/057C029061D565E59B91BCF8D80FA08E.cache.html +651 -0
  93. data/public/jsme/05B63F17C4ECC632F0004998FE93F0D9.cache.png +0 -0
  94. data/public/jsme/0D71BA88E8DB59E613D3BD042277F3CA.cache.html +636 -0
  95. data/public/jsme/143B86F220A77EA4A06DF2CE62EF455A.cache.html +636 -0
  96. data/public/jsme/1AFB129BECD672F835F8C27B14A9D8F2.cache.html +619 -0
  97. data/public/jsme/20865588BA1E58170CC8C13CEAD50C3C.cache.html +615 -0
  98. data/public/jsme/20B12D7884BFE17E1879B157A966B4D0.cache.html +631 -0
  99. data/public/jsme/222DCE3CD01E8F29C3D81A37CE3EC2B8.cache.html +626 -0
  100. data/public/jsme/230043C4988F4EECEF225437640D792F.cache.html +625 -0
  101. data/public/jsme/3014E46F5C6FB35E6CF0D7870071174B.cache.html +615 -0
  102. data/public/jsme/396F806CD63ABD414BFBB9D57429F05B.cache.png +0 -0
  103. data/public/jsme/3F57AECC67986E796A3148265F038FF1.cache.html +639 -0
  104. data/public/jsme/40BAF81124143A595056A9CCA0E9DBBA.cache.png +0 -0
  105. data/public/jsme/469A5B5AE16905A2CD712E25B9517A14.cache.html +644 -0
  106. data/public/jsme/4722AB194B521805C997130865A7EE3D.cache.html +638 -0
  107. data/public/jsme/4841BDE9DC293BA35F7762B4D8EFD236.cache.png +0 -0
  108. data/public/jsme/497588C27DED1A6E8FE1E0AB8417B414.cache.html +626 -0
  109. data/public/jsme/571D27D70DEF8240841DA5CAFC363CFF.cache.html +619 -0
  110. data/public/jsme/5F7FD5A5750634DF9F5480F2778D9CD7.cache.html +651 -0
  111. data/public/jsme/6187B195CC6073B1DB0A30F6CD64ACA3.cache.html +620 -0
  112. data/public/jsme/6DED0C7A48F0BB72DDB1FDE5C05E60B5.cache.html +642 -0
  113. data/public/jsme/73F66F1A578E65144682885B3DC28556.cache.html +620 -0
  114. data/public/jsme/76252DEA9FB0A670947525C4C89E2530.cache.html +657 -0
  115. data/public/jsme/84DE2DAB8AD49C4E122A548C4B072500.cache.html +625 -0
  116. data/public/jsme/98150D1CD230B36339E35812F0BD3D0E.cache.html +629 -0
  117. data/public/jsme/9BA3A5A02DFF97BADFD3F9FE3817341B.cache.html +636 -0
  118. data/public/jsme/9D58CD61900096C805154C0AC693DCE7.cache.html +639 -0
  119. data/public/jsme/A3D2B7C95C4FC47DB0996CBDF930EA17.cache.html +657 -0
  120. data/public/jsme/A6DF9CFFF55769DE62DA6868C558B3F2.cache.html +629 -0
  121. data/public/jsme/B70D7DA2E93A6B0FB7E5BC15540F7B15.cache.html +645 -0
  122. data/public/jsme/DF7764EEC1903CD03C9545B354D8D8E4.cache.png +0 -0
  123. data/public/jsme/E07214401017B41AF0BDAB1EB811CC83.cache.html +645 -0
  124. data/public/jsme/E45DF2A61DB551567FA3454B1A00412D.cache.html +631 -0
  125. data/public/jsme/E97CDFD075EEB4D0578A219C5564A988.cache.html +642 -0
  126. data/public/jsme/EBCDA5C12B4318C17A4741474FB9D7CA.cache.html +643 -0
  127. data/public/jsme/clear.cache.gif +0 -0
  128. data/public/jsme/gwt/chrome/chrome.css +1155 -0
  129. data/public/jsme/gwt/chrome/chrome_rtl.css +1155 -0
  130. data/public/jsme/gwt/chrome/images/button/menu-button-arrow-disabled.png +0 -0
  131. data/public/jsme/gwt/chrome/images/button/menu-button-arrow.png +0 -0
  132. data/public/jsme/gwt/chrome/images/button/split-button-arrow-active.png +0 -0
  133. data/public/jsme/gwt/chrome/images/button/split-button-arrow-disabled.png +0 -0
  134. data/public/jsme/gwt/chrome/images/button/split-button-arrow-focus.png +0 -0
  135. data/public/jsme/gwt/chrome/images/button/split-button-arrow-hover.png +0 -0
  136. data/public/jsme/gwt/chrome/images/button/split-button-arrow.png +0 -0
  137. data/public/jsme/gwt/chrome/images/combobox/arrow-down-disabled.png +0 -0
  138. data/public/jsme/gwt/chrome/images/combobox/arrow-down.png +0 -0
  139. data/public/jsme/gwt/chrome/images/combobox/ellipsis-disabled.png +0 -0
  140. data/public/jsme/gwt/chrome/images/combobox/ellipsis.png +0 -0
  141. data/public/jsme/gwt/chrome/images/corner.png +0 -0
  142. data/public/jsme/gwt/chrome/images/corner_ie6.png +0 -0
  143. data/public/jsme/gwt/chrome/images/fastree/selectionBar.gif +0 -0
  144. data/public/jsme/gwt/chrome/images/fastree/treeClosed.gif +0 -0
  145. data/public/jsme/gwt/chrome/images/fastree/treeLoading.gif +0 -0
  146. data/public/jsme/gwt/chrome/images/fastree/treeOpen.gif +0 -0
  147. data/public/jsme/gwt/chrome/images/glasspanel/blue_ridge.png +0 -0
  148. data/public/jsme/gwt/chrome/images/hborder.png +0 -0
  149. data/public/jsme/gwt/chrome/images/hborder_ie6.png +0 -0
  150. data/public/jsme/gwt/chrome/images/ie6/corner_dialog_topleft.png +0 -0
  151. data/public/jsme/gwt/chrome/images/ie6/corner_dialog_topright.png +0 -0
  152. data/public/jsme/gwt/chrome/images/ie6/hborder_blue_shadow.png +0 -0
  153. data/public/jsme/gwt/chrome/images/ie6/hborder_gray_shadow.png +0 -0
  154. data/public/jsme/gwt/chrome/images/ie6/vborder_blue_shadow.png +0 -0
  155. data/public/jsme/gwt/chrome/images/ie6/vborder_gray_shadow.png +0 -0
  156. data/public/jsme/gwt/chrome/images/scrolltable/bg_header_gradient.gif +0 -0
  157. data/public/jsme/gwt/chrome/images/splitPanelThumb.png +0 -0
  158. data/public/jsme/gwt/chrome/images/valuespinner/bg_textbox.png +0 -0
  159. data/public/jsme/gwt/chrome/images/vborder.png +0 -0
  160. data/public/jsme/gwt/chrome/images/vborder_ie6.png +0 -0
  161. data/public/jsme/gwt/chrome/mosaic.css +1252 -0
  162. data/public/jsme/gwt/chrome/mosaic_rtl.css +1252 -0
  163. data/public/jsme/hosted.html +365 -0
  164. data/public/jsme/jsa.css +175 -0
  165. data/public/jsme/jsme.nocache.js +18 -0
  166. data/public/rect.png +0 -0
  167. data/public/stylesheets/jquery-ui.css +1186 -0
  168. data/test/lazarweb.rb +193 -0
  169. data/test/setup.rb +7 -0
  170. data/unicorn.rb +7 -0
  171. data/views/batch.haml +58 -0
  172. data/views/details.haml +24 -0
  173. data/views/error.haml +8 -0
  174. data/views/faq.haml +2 -0
  175. data/views/faq_layout.haml +67 -0
  176. data/views/info.haml +2 -0
  177. data/views/jme_help.html +197 -0
  178. data/views/js_link.haml +5 -0
  179. data/views/layout.haml +113 -0
  180. data/views/model_details.haml +117 -0
  181. data/views/neighbors.haml +104 -0
  182. data/views/predict.haml +175 -0
  183. data/views/prediction.haml +84 -0
  184. data/views/significant_fragments.haml +66 -0
  185. data/views/style.scss +70 -0
  186. data/views/validation.haml +16 -0
  187. metadata +373 -0
@@ -0,0 +1,5 @@
1
+ %a{:href => "#{destination}", :id => "js_link#{@link_id}"} #{name}
2
+ :javascript
3
+ $("a#js_link#{@link_id}").click(function () {
4
+ $("#{destination}").#{method}();
5
+ });
data/views/layout.haml ADDED
@@ -0,0 +1,113 @@
1
+ !!!
2
+ %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
3
+ %head
4
+ %meta{'charset'=>"utf-8"}
5
+ %meta{'http-equiv'=>"X-UA-Compatible", :content=>"IE=edge"}
6
+ %meta{'name'=>"viewport", :content=>"width=device-width, initial-scale=1"}
7
+ %title lazar Toxicity Predictions
8
+ %link{:rel=>'icon', :type=>'image/x-icon', :href=>'/images/favicon.ico'}
9
+ %link{:rel=>'stylesheet', :href=>"#{'/css/bootstrap.min.css'}"}
10
+ %link{:rel=>'stylesheet', :href=>"#{'/css/theme.default.min.css'}"}
11
+ %link{:rel=>'stylesheet', :href=>"#{'/css/theme.bootstrap.min.css'}"}
12
+ %link{ :href=>"/style.css", :rel=>"stylesheet"}
13
+ %link{ :href=>"/stylesheets/jquery-ui.css", :rel=>"stylesheet"}
14
+ %script{:src=>"/javascripts/jquery-1.11.2.min.js"}
15
+ %script{:src=>"/javascripts/bootstrap.min.js"}
16
+ %script{:src=>"/javascripts/jquery.tablesorter.min.js"}
17
+ %script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
18
+ %script{ :src=>"/javascripts/lazar-gui.js"}
19
+ %body
20
+ %noscript
21
+ %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"}
22
+ Your web browser must have JavaScript enabled in order for this application to display correctly.
23
+ %header.page-header
24
+ %div.row
25
+ %div.col-md-2
26
+ %a{:href=> to("/predict")}
27
+ %img.media-object{:src=>"/images/IST_logo_s.png", :alt=>"logo", :width=>"150px", :heigth=>"150px", :style=>"margin:0 3em 0 2em;"}
28
+ %div.col-md-8
29
+ %h1.media-heading{:style=>"margin: 0 0 0 2em;"}
30
+ lazar toxicity predictions
31
+ %div.col-md-2
32
+ %h1.media-heading
33
+ %small
34
+ %a{:href=>"https://nano-lazar.in-silico.ch"} nano-lazar
35
+
36
+ %div.container-fluid
37
+ %topline
38
+ %div.row
39
+ %div.col-md-8
40
+ Problems, bugs, ideas for improvements ? Please report at our
41
+ %a{:href => 'https://github.com/opentox/lazar-gui/issues', :rel => "external"} issue tracker.
42
+ or send us an email:
43
+ %a{ :href=>"mailto:info@in-silico.ch", :target=>"_top"}
44
+ %img.share{:src=>"/images/Email.png"}
45
+ %div.col-md-2
46
+ %div.col-md-2
47
+ %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"}
48
+ %img.share{:src=>"/images/Twitter.png"}
49
+ %a{:href=>"https://plus.google.com/share?url=http%3A%2F%2Flazar.in-silico.ch", :target=>"_blank", :title=>"Share on Google+"}
50
+ %img.share{:src=>"/images/Google+.png"}
51
+ %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"}
52
+ %img.share{:src=>"/images/LinkedIn.png"}
53
+ %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"}
54
+ %img.share{:src=>"/images/Facebook.png"}
55
+ %div.row
56
+ Previous version:
57
+ %a{:href=>"http://lazar-old.in-silico.ch"} lazar-old
58
+ :javascript
59
+ $(document).ready(function(){
60
+ $("#back-top").hide();
61
+ $(".blind").error(function(){
62
+ $(this).attr('src', '/images/blind.png');
63
+ });
64
+ });
65
+ $(document).ready(function(){
66
+ $('[data-toggle="popover"]').popover();
67
+ $('.modal').on('hidden.bs.modal', function () {
68
+ $(this).removeData('bs.modal');
69
+ });
70
+ });
71
+
72
+ = yield
73
+
74
+ %footer.footer
75
+ %div.container-fluid
76
+ %div.row
77
+ %div.col-md-12
78
+ %p.text-muted
79
+ ©
80
+ %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}
81
+ %supporters.col-md-12
82
+ %p Financial support:
83
+ %a{:href=>"http://www.bfr.bund.de/de/start.html", :target=>"_blank"}
84
+ %img{:src=>"/images/bfr_logo.gif"}
85
+ %a{:href=>"http://www.opentox.org/", :target=>"_blank"}
86
+ %img{:src=>"/images/ot_logo.png"}
87
+ %a{:href=>"https://enanomapper.net/", :target=>"_blank"}
88
+ %img{:src=>"/images/enm_logo.png"}
89
+ %a{:href=>"https://www.researchgate.net/institution/Nestle_SA/department/Nestle_Research_Center", :target=>"_blank"}
90
+ %img{:src=>"/images/nestec.jpg"}
91
+
92
+
93
+ #back-top{:style => "z-index:100;position:fixed;bottom:1%;right:1%;"}
94
+ %a{:href => "", :style=>"text:decoration:none;color:#ccc;"}
95
+ %span.glyphicon.glyphicon-circle-arrow-up{:style => "font-size:3em;color:black;"}
96
+ :javascript
97
+ $("#back-top").hide();
98
+ $(function () {
99
+ $(window).scroll(function () {
100
+ if ($(this).scrollTop() > 600) {
101
+ $('#back-top').fadeIn();
102
+ } else {
103
+ $('#back-top').fadeOut();
104
+ }
105
+ });
106
+ // scroll body to 0px on click
107
+ $('#back-top a').click(function () {
108
+ $('body,html').animate({
109
+ scrollTop: 0
110
+ }, 500);
111
+ return false;
112
+ });
113
+ });
@@ -0,0 +1,117 @@
1
+ %b Model:
2
+ %br
3
+ Source:
4
+ %a{:href=>model.source, :target=>"external"}
5
+ = model.source
6
+ %br
7
+ - model.classification? ? type = "Classification" : type = "Regression"
8
+ = "Type:\t"
9
+ = type
10
+ %br
11
+ - training_dataset = OpenTox::Dataset.find model.training_dataset.id
12
+ = "Training compounds:\t"
13
+ = training_dataset.compounds.size
14
+
15
+ %p
16
+ - if type == "Classification"
17
+ %b Independent crossvalidations:
18
+ - else
19
+ %b Independent crossvalidations (-log10 transformed):
20
+ %div.row{:id=>"validations#{model.id}", :style=>"background-color:#f5f5f5;"}
21
+ - model.crossvalidations.each do |crossvalidation|
22
+ %span.col-xs-4.col-sm-4.col-md-4.col-lg-4
23
+ - cv = OpenTox::CrossValidation.find crossvalidation.id
24
+ = "Num folds:\t"
25
+ = cv.folds
26
+ %br
27
+ = "Num instances:\t"
28
+ = cv.nr_instances
29
+ %br
30
+ = "Num unpredicted"
31
+ = cv.nr_unpredicted
32
+ - if model.classification?
33
+ %br
34
+ = "Accuracy:\t"
35
+ = cv.accuracy.round(3) if cv.accuracy
36
+ %br
37
+ = "True positive rate:\t"
38
+ = cv.true_rate["active"].round(3) if cv.true_rate["active"]
39
+ %br
40
+ = "True negative rate:\t"
41
+ = cv.true_rate["inactive"].round(3) if cv.true_rate["inactive"]
42
+ %br
43
+ = "Positive predictive value:\t"
44
+ = cv.predictivity["active"].round(3) if cv.predictivity["active"]
45
+ %br
46
+ = "Negative predictive value:\t"
47
+ = cv.predictivity["inactive"].round(3) if cv.predictivity["inactive"]
48
+ %p
49
+ %b Confusion Matrix:
50
+ %table.table.table-condensed.table-borderless{:style=>"width:20%;"}
51
+ %tbody
52
+ %tr
53
+ %td
54
+ %td
55
+ %td
56
+ %b actual
57
+ %td
58
+ %td
59
+ %tr
60
+ %td
61
+ %td
62
+ %td active
63
+ %td inactive
64
+ -#%td total
65
+ %tr
66
+ %td
67
+ %b predicted
68
+ %td active
69
+ %td
70
+ =cv.confusion_matrix[0][0]
71
+ %td
72
+ =cv.confusion_matrix[0][1]
73
+ -#%td
74
+ =cv.confusion_matrix[0][0]+cv.confusion_matrix[0][1]
75
+ %tr
76
+ %td
77
+ %td inactive
78
+ %td
79
+ =cv.confusion_matrix[1][0]
80
+ %td
81
+ =cv.confusion_matrix[1][1]
82
+ -#%td
83
+ =cv.confusion_matrix[1][0]+cv.confusion_matrix[1][1]
84
+ -#%tr
85
+ %td
86
+ %td total
87
+ %td
88
+ =cv.confusion_matrix[0][0]+cv.confusion_matrix[1][0]
89
+ %td
90
+ =cv.confusion_matrix[0][1]+cv.confusion_matrix[1][1]
91
+ %td
92
+ -#= "Confusion Matrix:\t"
93
+ -#= cv.confusion_matrix
94
+ %br
95
+ /= "Confidence plot:"
96
+ /%p.plot
97
+ / %img{:src=>"confp#{cv.id}.svg"}
98
+ - if model.regression?
99
+ %br
100
+ = "Root mean squared error:\t"
101
+ = cv.rmse.round(3) if cv.rmse
102
+ %br
103
+ = "Mean absolute error:\t"
104
+ = cv.mae.round(3) if cv.mae
105
+ %br
106
+ = "R square:\t"
107
+ = cv.r_squared.round(3) if cv.r_squared
108
+ %br
109
+ /= "Confidence plot:"
110
+ /%p.plot
111
+ / %img{:src=>"/confp#{cv.id}.svg"}
112
+ /%br
113
+ /= "Correlation plot"
114
+ /%p.plot
115
+ / %img{:src=>"/corrp#{cv.id}.svg"}
116
+
117
+ %br
@@ -0,0 +1,104 @@
1
+ / unpacks multi prediction array ;
2
+ / prepare it for neighbors ;
3
+ / align single prediction to endpoint ;
4
+ / display preordered in table view ;
5
+
6
+ %div.results
7
+ %h3 Neighbors:
8
+ / tabs div
9
+ #tabs
10
+ %ul.nav.nav-tabs.nav-justified{:id=>"neighborTabs", :role=>"tablist"}
11
+ / each model a tab head ;
12
+ / hash for predictionFeature
13
+ - predictionFeature = {}
14
+ - @models.each_with_index do |model,i|
15
+ / get predictionFeature type
16
+ - m = Model::Lazar.find model.model_id.to_s
17
+ - predFeature = Feature.find m.prediction_feature_id.to_s
18
+ / define feature type (numeric : nominal)
19
+ - predFeatureType = (predFeature.numeric? ? "numeric" : "nominal")
20
+ / use prediction feature id for neighbor compound features
21
+ - predFeatureId = m.prediction_feature_id.to_s
22
+ - predictionFeature[i] = {"id" => predFeatureId, "type" => predFeatureType}
23
+ %li{:class => ("active" if i == 0)}
24
+ %a{:href => "#results_#{i+1}", :id => "linkTab#{i+1}", data: {toggle:"tab"}}
25
+ = "#{model.endpoint} (#{model.species})"
26
+ %div.tab-content
27
+ / unpack to single arrays
28
+ - @predictions.each_with_index do |prediction,j|
29
+ / pass model type for significant fragments view
30
+ #results.tab-pane{:id=>"#{j+1}", :class => ("active" if j == 0)}
31
+ / prepare dataset for neighbors table ;
32
+ / delete first array which contains prediction ;
33
+ / following arrays are the neighbor predictions ;
34
+ / call the tablesorter plugin ;
35
+ / presort by similarity ;
36
+ :javascript
37
+ $(document).ready(function(){
38
+ $("table##{j+1}").tablesorter({
39
+ debug: false,
40
+ theme: "bootstrap",
41
+ headerTemplate: '',
42
+ widgets: ['columns', 'uitheme', 'stickyHeaders'],
43
+ widgetOptions: {
44
+ stickyHeaders_attachTo : '.tab-content',
45
+ stickyHeaders : '',
46
+ stickyHeaders_offset : 0,
47
+ stickyHeaders_cloneId : '-sticky',
48
+ stickyHeaders_addResizeEvent : true,
49
+ stickyHeaders_includeCaption : true,
50
+ stickyHeaders_zIndex : 2,
51
+ stickyHeaders_attachTo : null,
52
+ stickyHeaders_xScroll : null,
53
+ stickyHeaders_yScroll : null,
54
+ stickyHeaders_filteredToTop: true
55
+ },
56
+ sortList: [[2,1]],
57
+ headers: {sorter: false},
58
+ widthFixed: false
59
+ });
60
+ });
61
+ - if prediction[:neighbors].size > 0
62
+ %div.table-responsive
63
+ %table{:id=>"#{j+1}", :style=>"border-style: solid;"}
64
+ %thead
65
+ %tr
66
+ %th.sorter-false{:style =>"vertical-align:middle;"}
67
+ Compound
68
+ %th.sorter-false{:style =>"vertical-align:middle;"}
69
+ Measured Activity
70
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Measured Activity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"left", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
71
+ %th.sorter-false{:style =>"vertical-align:middle;"}
72
+ Similarity
73
+ %a.btn.glyphicon.glyphicon-info-sign{:href=>"#neighbors", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"left", html:"true", content:"<a href=\"https://en.wikipedia.org/wiki/Jaccard_index\">Tanimoto/Jaccard</a> similarity based on <a href=\"https://openbabel.org/docs/dev/FileFormats/MolPrint2D_format.html\">Molprint2D</a> fingerprints."}, :style=>"z-index:auto+10;"}
74
+ / %th{:style =>"vertical-align:middle;"}
75
+ / Supporting Information
76
+ %tbody
77
+ - type = @model_types[j]
78
+ - unit = @models[j].unit
79
+ - prediction[:neighbors].uniq.each_with_index do |neighbor,count|
80
+ %tr
81
+ / Compound
82
+ - c = Compound.find(neighbor["_id"])
83
+ %td{:style =>"vertical-align:middle;padding-left:1em;width:50%;"}
84
+ /%a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(neighbor["_id"])}/details"), :id=>"link#{j+1}#{count}"}}
85
+ %p= c.svg
86
+ %p= c.smiles
87
+ - mw = c.molecular_weight
88
+ / Measured Activity = compound.features
89
+ %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;white-space:nowrap;"}
90
+ - features = c.features.collect{|k,v| v if k == predictionFeature[j]["id"] }.compact.flatten
91
+ = (predictionFeature[j]["type"] == "numeric") ? features.collect{|v| weight = c.mmol_to_mg(v); '%.2e' % v + " (#{@models[j].unit})"+" , #{'%.2e' % weight} #{(unit == "mmol/L") ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : features.join("</br>")
92
+ / Similarity = tanimoto
93
+ %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;"}
94
+ / TODO differentiate between no neighbors found and compound found in dataset, display neighbors for compounds in dataset?
95
+ = neighbor[:tanimoto] != nil ? neighbor[:tanimoto].to_f.round(3) : "Not enough similar compounds </br>in training dataset."
96
+
97
+ - else
98
+ %span.btn.btn-default.disabled
99
+ = "Not enough similar compounds in training dataset"
100
+
101
+ %div.modal.fade{:id=>"details#{j+1}", :role=>"dialog"}
102
+ %div.modal-dialog.modal-lg
103
+ %div.modal-content
104
+
@@ -0,0 +1,175 @@
1
+ %link{ :href=>"/jsme/jsa.css", :rel=>"stylesheet", :property=>"stylesheet"}
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
118
+ %label &nbsp;
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:
125
+ %br
126
+ %input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'}
127
+ %p
128
+ %label{:for=>"fileselect"}
129
+ or upload a CSV file for batch predictions (disabled in public version)
130
+ %br
131
+ %span.btn.btn-default.btn-file
132
+ %input{:type=>"file", :name=> "fileselect", :id=>"fileselect", :accept=>"text/csv", :disabled=>"disabled"}
133
+
134
+ %fieldset#middle.well
135
+ %h2 2. Select one or more endpoints
136
+ #models
137
+ - @endpoints.each do |endpoint|
138
+ %div{:id=>endpoint.gsub(/\s+/, "_")}
139
+ %h4.head-back=endpoint
140
+ - @models.select{|m| m.endpoint == endpoint}.each do |model|
141
+ %div.row{:id => model.id}
142
+ %span.col-sm-4
143
+ %input{:type => "checkbox", :name => "selection[#{model.id}]", :id => "selection[#{model.species.gsub(/\s+/, "_")}]", :value => true, :disabled => false}
144
+ %label{:for => "selection[#{model.species.gsub(/\s+/, "_")}]"}
145
+ = model.species
146
+ %span.col-sm-8
147
+ %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;"}
148
+ Details | Validation
149
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle#{model.id}", :class=>"circle#{model.id}", :alt=>"wait", :style=>"display:none;"}
150
+ %div.panel-collapse.collapse{:id=>"details#{model.id}", :style=>"margin-left:1em;"}
151
+ :javascript
152
+ function load#{model.id}Details(model) {
153
+ button = document.getElementById("link#{model.id}");
154
+ image = document.getElementById("circle#{model.id}");
155
+ if ($('modeldetails#{model.id}').length == 0) {
156
+ $(button).hide();
157
+ $(image).show();
158
+ aClient = new HttpClient();
159
+ aClient.get("#{to("/predict/modeldetails/#{model.id}")}", function(response) {
160
+ var details = document.createElement("modeldetails#{model.id}");
161
+ details.innerHTML = response;
162
+ document.getElementById("details#{model.id}").appendChild(details);
163
+ $(button).show();
164
+ $(image).hide();
165
+ });
166
+ }
167
+ }
168
+ %fieldset#bottom.well
169
+ %div.row
170
+ %div.col-md-2
171
+ %h2
172
+ 3. Predict
173
+ %div.col-md-10
174
+ %input.btn.btn-warning.h2{ :type => "submit", :id => "submit", :value=>">>", :onclick => "getsmiles()"}
175
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"}