lazar-gui 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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;"}