lazar-gui 1.0.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/FAQ.md +14 -25
  4. data/Gemfile +3 -1
  5. data/LICENSE.md +596 -0
  6. data/VERSION +1 -1
  7. data/application.rb +71 -191
  8. data/config.ru +2 -1
  9. data/helper.rb +0 -215
  10. data/lazar-gui.gemspec +7 -7
  11. data/public/css/bootstrap.vertical-tabs.min.css +1 -0
  12. data/public/jsme/.DS_Store +0 -0
  13. data/public/jsme/222ADBFEC322C2723C6ED2C4FB31B217.cache.js +1 -0
  14. data/public/jsme/293DFEFA807A962F28C09E358B34A434.cache.js +1 -0
  15. data/public/jsme/61B683D3493CAED438D5743A0404863D.cache.js +1 -0
  16. data/public/jsme/6ABB8447ACAB1353A478923AC9C0550B.cache.js +1 -0
  17. data/public/jsme/7A65B607B90DE29D7EA26AA83BF69D4F.cache.js +1 -0
  18. data/public/jsme/8816D61E367E34DBCFA53666849E21D8.cache.js +1 -0
  19. data/public/jsme/8BDB7ED57B756F8D50277056A0D59DA8.cache.js +1 -0
  20. data/public/jsme/96E40B969193BD74B8A621486920E79C.cache.js +606 -0
  21. data/public/jsme/A2384E54F71557BAEA414A43D47F17EA.cache.js +1 -0
  22. data/public/jsme/A6DBDE07E3A8F66E8959A4F32505E16B.cache.png +0 -0
  23. data/public/jsme/C8A71BD2E1367E9BB43A1B9C25871BEE.cache.js +1 -0
  24. data/public/jsme/C9EEF554958AACEE6A060F620375E4FA.cache.js +1 -0
  25. data/public/jsme/D4DF9EC9DD21B943E35F3D5696D5D2A1.cache.js +1 -0
  26. data/public/jsme/D9A64F1634E29088B910B3E0D4621E49.cache.js +1 -0
  27. data/public/jsme/compilation-mappings.txt +2689 -0
  28. data/public/jsme/deferredjs/.DS_Store +0 -0
  29. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/1.cache.js +1 -0
  30. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/2.cache.js +1 -0
  31. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/3.cache.js +1 -0
  32. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/4.cache.js +1 -0
  33. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/5.cache.js +1 -0
  34. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/6.cache.js +1 -0
  35. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/7.cache.js +1 -0
  36. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/8.cache.js +1 -0
  37. data/public/jsme/deferredjs/222ADBFEC322C2723C6ED2C4FB31B217/9.cache.js +1 -0
  38. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/1.cache.js +1 -0
  39. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/2.cache.js +1 -0
  40. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/3.cache.js +1 -0
  41. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/4.cache.js +1 -0
  42. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/5.cache.js +1 -0
  43. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/6.cache.js +1 -0
  44. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/7.cache.js +1 -0
  45. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/8.cache.js +1 -0
  46. data/public/jsme/deferredjs/293DFEFA807A962F28C09E358B34A434/9.cache.js +1 -0
  47. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/1.cache.js +1 -0
  48. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/2.cache.js +1 -0
  49. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/3.cache.js +1 -0
  50. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/4.cache.js +1 -0
  51. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/5.cache.js +1 -0
  52. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/6.cache.js +1 -0
  53. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/7.cache.js +1 -0
  54. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/8.cache.js +1 -0
  55. data/public/jsme/deferredjs/61B683D3493CAED438D5743A0404863D/9.cache.js +1 -0
  56. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/1.cache.js +1 -0
  57. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/2.cache.js +1 -0
  58. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/3.cache.js +1 -0
  59. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/4.cache.js +1 -0
  60. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/5.cache.js +1 -0
  61. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/6.cache.js +1 -0
  62. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/7.cache.js +1 -0
  63. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/8.cache.js +1 -0
  64. data/public/jsme/deferredjs/6ABB8447ACAB1353A478923AC9C0550B/9.cache.js +1 -0
  65. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/1.cache.js +1 -0
  66. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/2.cache.js +1 -0
  67. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/3.cache.js +1 -0
  68. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/4.cache.js +1 -0
  69. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/5.cache.js +1 -0
  70. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/6.cache.js +1 -0
  71. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/7.cache.js +1 -0
  72. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/8.cache.js +1 -0
  73. data/public/jsme/deferredjs/7A65B607B90DE29D7EA26AA83BF69D4F/9.cache.js +1 -0
  74. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/1.cache.js +1 -0
  75. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/2.cache.js +1 -0
  76. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/3.cache.js +1 -0
  77. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/4.cache.js +1 -0
  78. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/5.cache.js +1 -0
  79. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/6.cache.js +1 -0
  80. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/7.cache.js +1 -0
  81. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/8.cache.js +1 -0
  82. data/public/jsme/deferredjs/8816D61E367E34DBCFA53666849E21D8/9.cache.js +1 -0
  83. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/1.cache.js +1 -0
  84. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/2.cache.js +1 -0
  85. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/3.cache.js +1 -0
  86. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/4.cache.js +1 -0
  87. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/5.cache.js +1 -0
  88. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/6.cache.js +1 -0
  89. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/7.cache.js +1 -0
  90. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/8.cache.js +1 -0
  91. data/public/jsme/deferredjs/8BDB7ED57B756F8D50277056A0D59DA8/9.cache.js +1 -0
  92. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/1.cache.js +1 -0
  93. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/2.cache.js +1 -0
  94. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/3.cache.js +1 -0
  95. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/4.cache.js +1 -0
  96. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/5.cache.js +1 -0
  97. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/6.cache.js +1 -0
  98. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/7.cache.js +1 -0
  99. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/8.cache.js +1 -0
  100. data/public/jsme/deferredjs/A2384E54F71557BAEA414A43D47F17EA/9.cache.js +1 -0
  101. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/1.cache.js +1 -0
  102. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/2.cache.js +1 -0
  103. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/3.cache.js +1 -0
  104. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/4.cache.js +1 -0
  105. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/5.cache.js +1 -0
  106. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/6.cache.js +1 -0
  107. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/7.cache.js +1 -0
  108. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/8.cache.js +1 -0
  109. data/public/jsme/deferredjs/C8A71BD2E1367E9BB43A1B9C25871BEE/9.cache.js +1 -0
  110. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/1.cache.js +1 -0
  111. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/2.cache.js +1 -0
  112. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/3.cache.js +1 -0
  113. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/4.cache.js +1 -0
  114. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/5.cache.js +1 -0
  115. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/6.cache.js +1 -0
  116. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/7.cache.js +1 -0
  117. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/8.cache.js +1 -0
  118. data/public/jsme/deferredjs/C9EEF554958AACEE6A060F620375E4FA/9.cache.js +1 -0
  119. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/1.cache.js +1 -0
  120. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/2.cache.js +1 -0
  121. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/3.cache.js +1 -0
  122. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/4.cache.js +1 -0
  123. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/5.cache.js +1 -0
  124. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/6.cache.js +1 -0
  125. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/7.cache.js +1 -0
  126. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/8.cache.js +1 -0
  127. data/public/jsme/deferredjs/D4DF9EC9DD21B943E35F3D5696D5D2A1/9.cache.js +1 -0
  128. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/1.cache.js +1 -0
  129. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/2.cache.js +1 -0
  130. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/3.cache.js +1 -0
  131. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/4.cache.js +1 -0
  132. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/5.cache.js +1 -0
  133. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/6.cache.js +1 -0
  134. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/7.cache.js +1 -0
  135. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/8.cache.js +1 -0
  136. data/public/jsme/deferredjs/D9A64F1634E29088B910B3E0D4621E49/9.cache.js +1 -0
  137. data/public/jsme/gwt/.DS_Store +0 -0
  138. data/public/jsme/gwt/chrome/.DS_Store +0 -0
  139. data/public/jsme/jsa.css +10 -2
  140. data/public/jsme/jsme.devmode.js +1 -0
  141. data/public/jsme/jsme.nocache.js +27 -18
  142. data/views/batch.haml +74 -32
  143. data/views/details.haml +6 -2
  144. data/views/layout.haml +34 -25
  145. data/views/license.haml +1 -0
  146. data/views/model_details.haml +91 -67
  147. data/views/neighbors.haml +14 -35
  148. data/views/predict.haml +8 -5
  149. data/views/prediction.haml +79 -51
  150. data/views/style.scss +36 -9
  151. metadata +148 -93
  152. data/public/jsme/057C029061D565E59B91BCF8D80FA08E.cache.html +0 -651
  153. data/public/jsme/05B63F17C4ECC632F0004998FE93F0D9.cache.png +0 -0
  154. data/public/jsme/0D71BA88E8DB59E613D3BD042277F3CA.cache.html +0 -636
  155. data/public/jsme/143B86F220A77EA4A06DF2CE62EF455A.cache.html +0 -636
  156. data/public/jsme/1AFB129BECD672F835F8C27B14A9D8F2.cache.html +0 -619
  157. data/public/jsme/20865588BA1E58170CC8C13CEAD50C3C.cache.html +0 -615
  158. data/public/jsme/20B12D7884BFE17E1879B157A966B4D0.cache.html +0 -631
  159. data/public/jsme/222DCE3CD01E8F29C3D81A37CE3EC2B8.cache.html +0 -626
  160. data/public/jsme/230043C4988F4EECEF225437640D792F.cache.html +0 -625
  161. data/public/jsme/3014E46F5C6FB35E6CF0D7870071174B.cache.html +0 -615
  162. data/public/jsme/3F57AECC67986E796A3148265F038FF1.cache.html +0 -639
  163. data/public/jsme/469A5B5AE16905A2CD712E25B9517A14.cache.html +0 -644
  164. data/public/jsme/4722AB194B521805C997130865A7EE3D.cache.html +0 -638
  165. data/public/jsme/497588C27DED1A6E8FE1E0AB8417B414.cache.html +0 -626
  166. data/public/jsme/571D27D70DEF8240841DA5CAFC363CFF.cache.html +0 -619
  167. data/public/jsme/5F7FD5A5750634DF9F5480F2778D9CD7.cache.html +0 -651
  168. data/public/jsme/6187B195CC6073B1DB0A30F6CD64ACA3.cache.html +0 -620
  169. data/public/jsme/6DED0C7A48F0BB72DDB1FDE5C05E60B5.cache.html +0 -642
  170. data/public/jsme/73F66F1A578E65144682885B3DC28556.cache.html +0 -620
  171. data/public/jsme/76252DEA9FB0A670947525C4C89E2530.cache.html +0 -657
  172. data/public/jsme/84DE2DAB8AD49C4E122A548C4B072500.cache.html +0 -625
  173. data/public/jsme/98150D1CD230B36339E35812F0BD3D0E.cache.html +0 -629
  174. data/public/jsme/9BA3A5A02DFF97BADFD3F9FE3817341B.cache.html +0 -636
  175. data/public/jsme/9D58CD61900096C805154C0AC693DCE7.cache.html +0 -639
  176. data/public/jsme/A3D2B7C95C4FC47DB0996CBDF930EA17.cache.html +0 -657
  177. data/public/jsme/A6DF9CFFF55769DE62DA6868C558B3F2.cache.html +0 -629
  178. data/public/jsme/B70D7DA2E93A6B0FB7E5BC15540F7B15.cache.html +0 -645
  179. data/public/jsme/E07214401017B41AF0BDAB1EB811CC83.cache.html +0 -645
  180. data/public/jsme/E45DF2A61DB551567FA3454B1A00412D.cache.html +0 -631
  181. data/public/jsme/E97CDFD075EEB4D0578A219C5564A988.cache.html +0 -642
  182. data/public/jsme/EBCDA5C12B4318C17A4741474FB9D7CA.cache.html +0 -643
  183. data/public/jsme/hosted.html +0 -365
  184. data/views/faq_layout.haml +0 -67
  185. data/views/validation.haml +0 -16
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.2
1
+ 1.1.3
@@ -1,14 +1,16 @@
1
1
  #require_relative 'helper.rb'
2
- #require 'rdiscount'
2
+ require 'rdiscount'
3
3
  include OpenTox
4
- #require File.join(ENV["HOME"],".opentox","config","lazar-gui.rb") # until added to ot-tools
5
4
 
6
- # DG: workaround for https://github.com/sinatra/sinatra/issues/808
7
- # Date: 18/11/2013
8
- #set :protection, :except => :path_traversal
5
+
6
+ configure :production do
7
+ $logger = Logger.new(STDOUT)
8
+ enable :reloader
9
+ end
9
10
 
10
11
  configure :development do
11
12
  $logger = Logger.new(STDOUT)
13
+ enable :reloader
12
14
  end
13
15
 
14
16
  helpers do
@@ -20,230 +22,91 @@ helpers do
20
22
 
21
23
  end
22
24
 
25
+ before do
26
+ @version = File.read("VERSION").chomp
27
+ end
28
+
29
+ not_found do
30
+ redirect to('/predict')
31
+ end
32
+
23
33
  get '/?' do
24
34
  redirect to('/predict')
25
35
  end
26
36
 
27
37
  get '/predict/?' do
28
- @version = File.read("VERSION").chomp
29
- @models = OpenTox::Model::Prediction.all
38
+ @models = OpenTox::Model::Validation.all
39
+ @models = @models.delete_if{|m| m.model.name =~ /\b(Net cell association)\b/}
30
40
  @endpoints = @models.collect{|m| m.endpoint}.sort.uniq
31
41
  @models.count <= 0 ? (haml :info) : (haml :predict)
32
42
  end
33
43
 
34
44
  get '/predict/modeldetails/:model' do
35
- model = OpenTox::Model::Prediction.find params[:model]
36
- crossvalidations = model.crossvalidations
37
- #confidence_plots = crossvalidations.collect{|cv| [cv.id, cv.confidence_plot]}
38
- #confidence_plots.each do |confp|
39
- # File.open(File.join('public', "confp#{confp[0]}.svg"), 'w'){|file| file.write(confp[1])} unless File.exists? File.join('public', "confp#{confp[0]}.svg")
40
- #end
41
- #if model.regression?
42
- # correlation_plots = crossvalidations.collect{|cv| [cv.id, cv.correlation_plot]}
43
- # correlation_plots.each do |corrp|
44
- # File.open(File.join('public', "corrp#{corrp[0]}.svg"), 'w'){|file| file.write(corrp[1])} unless File.exists? File.join('public', "corrp#{corrp[0]}.svg")
45
- # end
46
- #end
47
-
48
- return haml :model_details, :layout=> false, :locals => {:model => model}
49
- end
45
+ model = OpenTox::Model::Validation.find params[:model]
46
+ crossvalidations = OpenTox::Validation::RepeatedCrossValidation.find(model.repeated_crossvalidation_id).crossvalidations
50
47
 
51
- get '/jme_help/?' do
52
- File.read(File.join('views','jme_help.html'))
48
+ return haml :model_details, :layout=> false, :locals => {:model => model, :crossvalidations => crossvalidations}
53
49
  end
54
50
 
55
51
  # get individual compound details
56
52
  get '/prediction/:neighbor/details/?' do
57
- @compound = OpenTox::Compound.new params[:neighbor]
53
+ @compound = OpenTox::Compound.find params[:neighbor]
58
54
  @smiles = @compound.smiles
59
- task = OpenTox::Task.run("Get names for '#{@smiles}'.") do
60
- names = @compound.names
61
- end
62
- task.wait
63
-
64
- case task[RDF::OT.hasStatus]
65
- when "Error"
66
- @names = "No names for this compound available."
67
- when "Completed"
68
- @names = @compound.names
69
- else
55
+ begin
56
+ @names = @compound.names.nil? ? "No names for this compound available." : @compound.names
57
+ rescue
70
58
  @names = "No names for this compound available."
71
59
  end
72
60
  @inchi = @compound.inchi.gsub("InChI=", "")
73
61
 
74
62
  haml :details, :layout => false
75
63
  end
76
- =begin
77
- # sdf representation for datasets
78
- #TODO fix 502 errors from compound service
79
- get '/predict/:dataset_uri/sdf/?' do
80
- uri = CGI.unescape(params[:dataset_uri])
81
- $logger.debug uri
82
- bad_request_error "Not a dataset uri." unless URI.dataset? uri
83
- dataset = OpenTox::Dataset.find uri
84
- @compounds = dataset.compounds
85
- @data_entries = dataset.data_entries
86
- sum=""
87
- @compounds.each_with_index{ |c, idx|
88
- sum << c.inchi
89
- sum << c.sdf.sub(/\n\$\$\$\$/,'')
90
- @data_entries[idx].each{ |f,v|
91
- sum << "> <\"#{f}\">\n"
92
- sum << v.join(", ")
93
- sum << "\n\n"
94
- }
95
- sum << "$$$$\n"
96
- }
97
- send_file sum, :filename => "#{dataset.title}.sdf"
98
- end
99
- =end
100
- # fingerprints for compound in predictions
101
- get '/prediction/:model_uri/:type/:compound_uri/fingerprints/?' do
102
- @type = params[:type]
103
- model = OpenTox::Model::Lazar.find params[:model_uri]
104
- feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
105
- @compound = OpenTox::Compound.new params[:compound_uri]
106
- @significant_fragments = []
107
- if @type =~ /classification/i
108
- # collect all feature values with fingerprint
109
- fingerprints = OpenTox::Algorithm::Descriptor.send("smarts_match", [@compound], feature_dataset.features.collect{ |f| f[RDF::DC.title]})[@compound.uri]
110
- #$logger.debug "fingerprints:\t#{fingerprints}\n"
111
-
112
- # collect fingerprints with value 1
113
- @fingerprint_values = fingerprints.collect{|smarts, value| [smarts, value] if value > 0}
114
-
115
- # collect all features from feature_dataset
116
- @features = feature_dataset.features.collect{|f| f }
117
-
118
- # search for each fingerprint in all features and collect feature values( effect, smarts, pValue )
119
- @fingerprint_values.each{ |fi, v| @features.each{ |f| @significant_fragments << [f[RDF::OT.effect].to_i, f[RDF::OT.smarts], f[RDF::OT.pValue]] if fi == f[RDF::OT.smarts] } }
120
-
121
- # pass value_map, important to interprete effect value
122
- prediction_feature_uri = ""
123
- model.parameters.each {|p|
124
- if p[RDF::DC.title].to_s == "prediction_feature_uri"
125
- prediction_feature_uri = p[RDF::OT.paramValue].object
126
- end
127
- }
128
- prediction_feature = OpenTox::Feature.find prediction_feature_uri
129
- @value_map = prediction_feature.value_map
130
-
131
- else #regression
132
- feature_calc_algo = ""
133
- model.parameters.each {|p|
134
- if p[RDF::DC.title].to_s == "feature_calculation_algorithm"
135
- feature_calc_algo = p[RDF::OT.paramValue].object
136
- end
137
- }
138
64
 
139
- @desc = []
140
- fingerprints = OpenTox::Algorithm::Descriptor.send( feature_calc_algo, [ @compound ], feature_dataset.features.collect{ |f| f[RDF::DC.title] } )
141
- fingerprints.each{|x, h| h.each{|descriptor, value| @desc << [descriptor, [value]]}}
142
-
143
- pc_descriptor_titles_descriptions = {}
144
- feature_dataset.features.collect{ |f|
145
- pc_descriptor_titles_descriptions[f[RDF::DC.title]]= f[RDF::DC.description]
146
- }
147
-
148
- @desc.each{|d, v| @significant_fragments << [pc_descriptor_titles_descriptions[d], v] }
149
- end
150
-
151
- haml :significant_fragments, :layout => false
65
+ get '/jme_help/?' do
66
+ File.read(File.join('views','jme_help.html'))
152
67
  end
153
68
 
154
- get '/prediction/:model_uri/:type/:neighbor/significant_fragments/?' do
155
- @type = params[:type]
156
- @compound = OpenTox::Compound.new params[:neighbor]
157
- model = OpenTox::Model::Lazar.find params[:model_uri]
158
- #$logger.debug "model for significant fragments:\t#{model.uri}"
159
-
160
- feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
161
- $logger.debug "feature_dataset_uri:\t#{feature_dataset.uri}\n"
162
-
163
- # load all compounds
164
- feature_dataset.compounds
165
-
166
- # load all features
167
- @features = feature_dataset.features.collect{|f| f}
168
-
169
- # find all features and values for a neighbor compound
170
- @significant_fragments = []
171
- # check type first
172
- if @type =~ /classification/i
173
- # get compound index in feature dataset
174
- c_idx = feature_dataset.compound_indices @compound.uri
175
-
176
- # collect feature uris with value
177
- @feat = @features.collect{|f| [feature_dataset.data_entry_value(c_idx[0], f.uri), f.uri]}
178
- #$logger.debug "@feat:\t#{@feat}\n"
179
-
180
- # pass feature uris if value > 0
181
- @feat.each do |f|
182
- # search relevant features
183
- if f[0] > 0
184
- f = OpenTox::Feature.find f[1]
185
- # pass relevant features with [ effect, smarts, pValue ]
186
- @significant_fragments << [f[RDF::OT.effect].to_i, f[RDF::OT.smarts], f[RDF::OT.pValue].to_f.round(3)]
187
- end
188
- end
189
- # pass value_map, important to interprete effect value
190
- prediction_feature_uri = ""
191
- model.parameters.each {|p|
192
- if p[RDF::DC.title].to_s == "prediction_feature_uri"
193
- prediction_feature_uri = p[RDF::OT.paramValue].object
194
- end
195
- }
196
- prediction_feature = OpenTox::Feature.find prediction_feature_uri
197
- @value_map = prediction_feature.value_map
198
-
199
- else # regression
200
- # find a value in feature dataset by compound and feature
201
- @values = @features.collect{|f| feature_dataset.values(@compound, f)}
202
- #$logger.debug "values in fd:\t#{@values}"
203
-
204
- @features.each_with_index{|f, i| @significant_fragments << [f.description, @values[i]]}
205
- end
206
- #$logger.debug "significant fragments:\t#{@significant_fragments}\n"
207
-
208
- haml :significant_fragments, :layout => false
69
+ get '/predict/dataset/:name' do
70
+ response['Content-Type'] = "text/csv"
71
+ dataset = Dataset.find_by(:name=>params[:name])
72
+ csv = dataset.to_csv
73
+ csv
209
74
  end
210
75
 
211
76
  get '/predict/?:csv?' do
212
77
  response['Content-Type'] = "text/csv"
213
- @csv = "\"Compound\",\"Endpoint\",\"Type\",\"Prediction\",\"Confidence\"\n"
78
+ @csv = "\"Compound\",\"Endpoint\",\"Type\",\"Prediction\",\"95% Prediction interval\"\n"
214
79
  @@batch.each do |key, values|
80
+ compound = key
81
+ smiles = compound.smiles
215
82
  values.each do |array|
216
83
  model = array[0]
84
+ type = model.model.class.to_s.match("Classification") ? "Classification" : "Regression"
217
85
  prediction = array[1]
218
- compound = key.smiles
219
- mw = key.molecular_weight
220
86
  endpoint = "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
221
87
  if prediction[:confidence] == "measured"
222
88
  if prediction[:value].is_a?(Array)
223
89
  prediction[:value].each do |value|
224
- type = ""
225
- weight = Compound.from_smiles(compound).mmol_to_mg(value, mw)
226
- pred = value.numeric? ? "#{'%.2e' % value} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : value
227
- confidence = "measured activity"
228
- @csv += "\"#{compound}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{confidence}\"\n"
90
+ pred = value.numeric? ? "#{value} (#{model.unit}), #{compound.mmol_to_mg(value.delog10)} #{(model.unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : value
91
+ int = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
92
+ interval = (int.nil? ? "--" : "#{int[1].delog10} - #{int[0].delog10} (#{model.unit})")
93
+ @csv += "\"#{smiles}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{interval}\"\n"
229
94
  end
230
95
  else
231
- type = ""
232
- weight = Compound.from_smiles(compound).mmol_to_mg(prediction[:value], mw)
233
- pred = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : prediction[:value]
96
+ pred = prediction[:value].numeric? ? "#{prediction[:value]} (#{model.unit}), #{compound.mmol_to_mg(prediction[:value].delog10)} #{(model.unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
234
97
  confidence = "measured activity"
235
98
  end
236
99
  elsif prediction[:neighbors].size > 0
237
- weight = Compound.from_smiles(compound).mmol_to_mg(prediction[:value], mw)
238
100
  type = model.model.class.to_s.match("Classification") ? "Classification" : "Regression"
239
- pred = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : prediction[:value]
240
- confidence = prediction[:confidence]
101
+ pred = prediction[:value].numeric? ? "#{prediction[:value].delog10} (#{model.unit}), #{compound.mmol_to_mg(prediction[:value].delog10)} #{(model.unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
102
+ int = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
103
+ interval = (int.nil? ? "--" : "#{int[1].delog10} - #{int[0].delog10} (#{model.unit})")
241
104
  else
242
105
  type = ""
243
106
  pred = "Not enough similar compounds in training dataset."
244
- confidence = ""
107
+ interval = ""
245
108
  end
246
- @csv += "\"#{compound}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{confidence}\"\n" unless prediction[:value].is_a?(Array)
109
+ @csv += "\"#{smiles}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{interval}\"\n" unless prediction[:value].is_a?(Array)
247
110
  end
248
111
  end
249
112
  @csv
@@ -261,11 +124,21 @@ post '/predict/?' do
261
124
  f.write(params[:fileselect][:tempfile].read)
262
125
  end
263
126
  @filename = params[:fileselect][:filename]
264
- input = OpenTox::Dataset.from_csv_file File.join "tmp", params[:fileselect][:filename]
265
- dataset = OpenTox::Dataset.find input.id
127
+ begin
128
+ input = OpenTox::Dataset.from_csv_file File.join("tmp", params[:fileselect][:filename]), true
129
+ if input.class == OpenTox::Dataset
130
+ dataset = OpenTox::Dataset.find input
131
+ else
132
+ @error_report = "Could not serialize file '#{@filename}' ."
133
+ return haml :error
134
+ end
135
+ rescue
136
+ @error_report = "Could not serialize file '#{@filename}' ."
137
+ return haml :error
138
+ end
266
139
  @compounds = dataset.compounds
267
140
  if @compounds.size == 0
268
- @error_report = "No valid SMILES submitted."
141
+ @error_report = dataset[:warnings]
269
142
  dataset.delete
270
143
  return haml :error
271
144
  end
@@ -273,13 +146,15 @@ post '/predict/?' do
273
146
  @compounds.each do |compound|
274
147
  @batch[compound] = []
275
148
  params[:selection].keys.each do |model_id|
276
- model = Model::Prediction.find model_id
149
+ model = OpenTox::Model::Validation.find model_id
277
150
  prediction = model.predict(compound)
278
151
  @batch[compound] << [model, prediction]
279
152
  end
280
153
  end
281
154
  @@batch = @batch
155
+ @warnings = dataset[:warnings]
282
156
  dataset.delete
157
+ File.delete File.join("tmp", params[:fileselect][:filename])
283
158
  return haml :batch
284
159
  end
285
160
 
@@ -291,26 +166,31 @@ post '/predict/?' do
291
166
  # get compound from SMILES
292
167
  @compound = Compound.from_smiles @identifier
293
168
  if @compound.blank?
294
- @error_report = "Attention, '#{@identifier}' is not a valid SMILES string."
169
+ @error_report = "'#{@identifier}' is not a valid SMILES string."
295
170
  return haml :error
296
171
  end
297
172
 
298
173
  @models = []
299
174
  @predictions = []
300
175
  params[:selection].keys.each do |model_id|
301
- model = Model::Prediction.find model_id
176
+ model = OpenTox::Model::Validation.find model_id
302
177
  @models << model
303
178
  @predictions << model.predict(@compound)
304
179
  end
305
180
  haml :prediction
306
181
  end
307
182
  end
308
- =begin
183
+
184
+ get '/license' do
185
+ @license = RDiscount.new(File.read("LICENSE.md")).to_html
186
+ haml :license, :layout => false
187
+ end
188
+
309
189
  get '/faq' do
310
190
  @faq = RDiscount.new(File.read("FAQ.md")).to_html
311
- haml :faq, :layout => :faq_layout
191
+ haml :faq, :layout => false
312
192
  end
313
- =end
193
+
314
194
  get '/style.css' do
315
195
  headers 'Content-Type' => 'text/css; charset=utf-8'
316
196
  scss :style
data/config.ru CHANGED
@@ -1,5 +1,6 @@
1
- SERVICE = "lazar"
1
+ ENV["LAZAR_ENV"] = "production"
2
2
  require 'bundler'
3
3
  Bundler.require
4
4
  require File.expand_path './application.rb'
5
+ require "sinatra/reloader" if development?
5
6
  run Sinatra::Application
data/helper.rb CHANGED
@@ -1,218 +1,3 @@
1
1
  helpers do
2
-
3
- def is_authorized(uri, action)
4
- if OpenTox::Authorization.server && session[:subjectid] != nil
5
- return OpenTox::Authorization.authorized?(uri, action, session[:subjectid])
6
- else
7
- return true
8
- end
9
- return false
10
- end
11
-
12
- def is_aluist
13
- OpenTox::Authorization.list_user_groups(session[:username], session[:subjectid]).include?("aluist")
14
- end
15
-
16
- def hide_link(destination)
17
- @link_id = 0 unless @link_id
18
- @link_id += 1
19
- haml :js_link, :locals => {:name => "hide", :destination => destination, :method => "hide"}, :layout => false
20
- end
21
-
22
- def toggle_link(destination,name)
23
- @link_id = 0 unless @link_id
24
- @link_id += 1
25
- haml :js_link, :locals => {:name => name, :destination => destination, :method => "toggle"}, :layout => false
26
- end
27
-
28
- def sort(descriptors,value_map)
29
- features = {:activating => [], :deactivating => [], :pc_features => []}
30
- if descriptors.kind_of?(Array)
31
- descriptors.each do |d|
32
- if !value_map.empty?
33
- features[:activating] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]} if d[OT.effect] == 2
34
- features[:deactivating] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]} if d[OT.effect] == 1
35
- else
36
- if d[OT.effect] =~ TRUE_REGEXP
37
- features[:activating] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]}
38
- elsif d[OT.effect] =~ FALSE_REGEXP
39
- features[:deactivating] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]}
40
- end
41
- end
42
- end
43
- else
44
- descriptors.each do |d,v|
45
- features[:pc_features] << {:feature => d, :value => v}
46
- end
47
- end
48
- features
49
- end
50
-
51
- def compound_image(compound,descriptors,value_map)
52
- haml :compound_image, :locals => {:compound => compound, :features => sort(descriptors,value_map)}, :layout => false
53
- end
54
2
 
55
- def activity_markup(activity,value_map)
56
- if value_map and !value_map.empty?
57
- if value_map.size == 2
58
- activity = value_map.index(activity) if value_map.has_value? activity
59
- if activity.to_i == 2
60
- haml ".active #{value_map[activity]}", :layout => false
61
- elsif activity.to_i == 1
62
- haml ".inactive #{value_map[activity]}", :layout => false
63
- else
64
- haml ".other #{activity.to_s}", :layout => false
65
- end
66
- else
67
- haml ".other #{activity.to_s}", :layout => false
68
- end
69
- elsif OpenTox::Algorithm::numeric? activity
70
- haml ".other #{sprintf('%.03g', activity.to_f)}", :layout => false
71
- else
72
- haml ".other #{activity.to_s}", :layout => false
73
- end
74
- =begin
75
- case activity.class.to_s
76
- when /Float/
77
- haml ".other #{sprintf('%.03g', activity)}", :layout => false
78
- when /String/
79
- case activity
80
- when "true"
81
- haml ".active active", :layout => false
82
- when "false"
83
- haml ".inactive inactive", :layout => false
84
- else
85
- haml ".other #{activity.to_s}", :layout => false
86
- end
87
- else
88
- if activity #true
89
- haml ".active active", :layout => false
90
- elsif !activity # false
91
- haml ".inactive inactive", :layout => false
92
- else
93
- haml ".other #{activity.to_s}", :layout => false
94
- end
95
- end
96
- =end
97
- end
98
-
99
- def neighbors_navigation
100
- @page = 0 unless @page
101
- haml :neighbors_navigation, :layout => false
102
- end
103
-
104
- def models_navigation
105
- @page = 0 unless @page
106
- haml :models_navigation, :layout => false
107
- end
108
-
109
- def models_navigation_bottom
110
- @page = 0 unless @page
111
- haml :models_navigation_bottom, :layout => false
112
- end
113
-
114
- def endpoint_option_list(max_time=3600)
115
- out = ""
116
- tmpfile = File.join(TMP_DIR, 'endpoint_option_list')
117
- if File.exists? tmpfile
118
- if Time.now-File.mtime(tmpfile) <= max_time
119
- f = File.open(tmpfile, 'r+')
120
- f.each{|line| out << line}
121
- return out
122
- else
123
- File.unlink(tmpfile)
124
- end
125
- end
126
- result = endpoint_selection()
127
- if result.lines.count > 3
128
- f = File.new(tmpfile,'w')
129
- f.print result
130
- f.close
131
- end
132
- result
133
- end
134
-
135
- def endpoint_level(endpoint="Endpoints", level=1)
136
- results = OpenTox::Ontology::Echa.echa_endpoints(endpoint) rescue results = []
137
- out = ""
138
- out += "<ul id='list_#{endpoint}' class='endpoint level_#{level}'>\n" if results.size > 0
139
- results.each do |result|
140
- r = result.split(',')
141
- endpointname = CGI.escape(r.first.split("#").last).gsub(".","")
142
- title = r[1..r.size-1].to_s
143
- out += " <li class='level_#{level}'><input type='radio' name='endpoint' value='#{result}' id='#{endpointname}' class='endpoint_list' /><label for='#{endpointname}' id='label_#{endpointname}'>#{title.gsub("\"","")}</label>\n"
144
- out += endpoint_level(endpointname, level + 1)
145
- out += "</li>\n"
146
- end
147
- out += "</ul>\n" if results.size > 0
148
- return out
149
- end
150
-
151
- def endpoint_selection()
152
- out = "<span id='endpoint_label'></span><input type='button' id='endpoint_list_button' value='Select endpoint' /> \n
153
- <div id='div_endpoint'>\n"
154
- out += "<b>Please select:</b>\n"
155
- out += endpoint_level
156
- js = ""
157
- out += "</div>\n"
158
- return out
159
- end
160
-
161
- def logmmol_to_mg(value ,mw)
162
- mg = round_to((10**(-1.0*round_to(value.to_f, 2))*(mw.to_f*1000)),4)
163
- return mg
164
- end
165
-
166
- def logmg_to_mg(value)
167
- mg = round_to(10**round_to(value.to_f, 2),4)
168
- return mg
169
- end
170
-
171
- def ptd50_to_td50(value ,mw)
172
- td50 = round_to((10**(-1.0*round_to(value.to_f, 2))*(mw.to_f*1000)),4)
173
- return td50
174
- end
175
-
176
- def round_to(value, deci)
177
- rounded = (value.to_f*(10**deci)).round / (10**deci).to_f
178
- return rounded
179
- end
180
-
181
- def calc_mw(compound_uri)
182
- ds = OpenTox::Dataset.new()
183
- ds.save(@subjectid)
184
- ds.add_compound(compound_uri)
185
- ds.save(@subjectid)
186
- mw_algorithm_uri = File.join(CONFIG[:services]["opentox-algorithm"],"pc/MW")
187
- mw_uri = OpenTox::RestClientWrapper.post(mw_algorithm_uri, {:dataset_uri=>ds.uri})
188
- ds.delete(@subjectid)
189
- mw_ds = OpenTox::Dataset.find(mw_uri, @subjectid)
190
- mw = mw_ds.data_entries[compound_uri][mw_uri.to_s + "/feature/MW"].first.to_f
191
- mw_ds.delete(@subjectid)
192
- return mw
193
- end
194
-
195
- def transform(value, compound_uri, name, haml)
196
- prediction_trans = nil
197
- model_name = name.to_s.downcase
198
- if model_name.include? "ptd50"
199
- mw = calc_mw(compound_uri)
200
- td50 = ptd50_to_td50(value, mw)
201
- prediction_trans = "TD50: #{td50}"
202
- elsif model_name.include? "loael"
203
- if model_name.include? "mol"
204
- mw = calc_mw(compound_uri)
205
- mg = logmmol_to_mg(value, mw)
206
- prediction_trans = "mg/kg bw/day: #{mg}"
207
- elsif model_name.include? "mg"
208
- mg = logmg_to_mg(value)
209
- prediction_trans = "mg/kg bw/day: #{mg}"
210
- end
211
- end
212
- if haml == true
213
- haml ".other #{prediction_trans.to_s}", :layout => false
214
- else
215
- return prediction_trans
216
- end
217
- end
218
3
  end