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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63fad5e104b2e9a3d87993b4ce490de848ab14ac
4
+ data.tar.gz: 4f50c319f247c6716c0df6490c8d63a592d9202c
5
+ SHA512:
6
+ metadata.gz: 177829a3a7d2025d2ac5819a37a7b87ec3e659ab427758a1305d8aa3c62bee0c3e445b0a976ac72f8bc404d0be004c1ff79545fd022bbd32fb40513fd7b11303
7
+ data.tar.gz: ea8728c578e29b430a4a0d4a7192c6ce53bb45f9af2e0a8320159db26dec2dd182234d445396b99ea082244489a85dfe36f6c8064cf8384f7e3530e2c345dabb
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ .sass-cache/
3
+ tmp/*
data/FAQ.md ADDED
@@ -0,0 +1,29 @@
1
+ Frequently Asked Questions
2
+ ==========================
3
+ <br>
4
+ ####How does this prediction works?
5
+ >
6
+
7
+ ####You talk about significant fragments. Where can I find them?
8
+ > We will show up those significant fragments in a further version.
9
+
10
+ ####What is endpoint details about?
11
+ > You get the source from where we took compounds for the endpoint. The type and the number of compounds we used.
12
+
13
+ ####What is three times independent validation about?
14
+ >
15
+
16
+ ####Do you consider providing plots for the validation results?
17
+ > In a further version we will show up confidence and correlation plots.
18
+
19
+ ####What does 'Not enough similar compounds in training dataset' mean?
20
+ > Lazar uses neighbors from the training dataset of the endpoint to predict your compound. If there are not enough neighbors for Lazar it is not possible to make a prediction.
21
+
22
+ ####Is there a minimum number of necessary neighbors to make a prediction?
23
+ >
24
+
25
+ ####How can I activate the 'batch prediction' option?
26
+ > Please contact us directly via [mail](mailto:support@in-silico.ch).
27
+
28
+ ####Not the right answers for me. Is there a way to contact you or report problems.
29
+ > You can always ask your questions via [mail](mailto:support@in-silico.ch). If you run into problems with the GUI please post your issue [here](https://github.com/opentox/lazar-gui/issues). If you would like to post any other issue e.g. about an expected prediction result please use this [form](https://github.com/opentox/lazar/issues).
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+ gem "lazar"
4
+ gem "gem-path"
5
+ gem "sinatra"
6
+ gem "haml"
7
+ gem "sass"
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ IST Software&Services GUI
2
+ =========================
3
+
4
+ Installation:
5
+ -------------
6
+ bundle install
7
+
8
+ Usage:
9
+ ------
10
+ sudo /etc/init.d/mongod start
11
+ unicorn -D
12
+
13
+ Visit:
14
+ ------
15
+ http://localhost:8080
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/application.rb ADDED
@@ -0,0 +1,317 @@
1
+ #require_relative 'helper.rb'
2
+ #require 'rdiscount'
3
+ include OpenTox
4
+ #require File.join(ENV["HOME"],".opentox","config","lazar-gui.rb") # until added to ot-tools
5
+
6
+ # DG: workaround for https://github.com/sinatra/sinatra/issues/808
7
+ # Date: 18/11/2013
8
+ #set :protection, :except => :path_traversal
9
+
10
+ configure :development do
11
+ $logger = Logger.new(STDOUT)
12
+ end
13
+
14
+ helpers do
15
+ class Numeric
16
+ def percent_of(n)
17
+ self.to_f / n.to_f * 100.0
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ get '/?' do
24
+ redirect to('/predict')
25
+ end
26
+
27
+ get '/predict/?' do
28
+ @models = OpenTox::Model::Prediction.all
29
+ @endpoints = @models.collect{|m| m.endpoint}.sort.uniq
30
+ @models.count <= 0 ? (haml :info) : (haml :predict)
31
+ end
32
+
33
+ get '/predict/modeldetails/:model' do
34
+ model = OpenTox::Model::Prediction.find params[:model]
35
+ crossvalidations = model.crossvalidations
36
+ #confidence_plots = crossvalidations.collect{|cv| [cv.id, cv.confidence_plot]}
37
+ #confidence_plots.each do |confp|
38
+ # 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")
39
+ #end
40
+ #if model.regression?
41
+ # correlation_plots = crossvalidations.collect{|cv| [cv.id, cv.correlation_plot]}
42
+ # correlation_plots.each do |corrp|
43
+ # 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")
44
+ # end
45
+ #end
46
+
47
+ return haml :model_details, :layout=> false, :locals => {:model => model}
48
+ end
49
+
50
+ get '/jme_help/?' do
51
+ File.read(File.join('views','jme_help.html'))
52
+ end
53
+
54
+ # get individual compound details
55
+ get '/prediction/:neighbor/details/?' do
56
+ @compound = OpenTox::Compound.new params[:neighbor]
57
+ @smiles = @compound.smiles
58
+ task = OpenTox::Task.run("Get names for '#{@smiles}'.") do
59
+ names = @compound.names
60
+ end
61
+ task.wait
62
+
63
+ case task[RDF::OT.hasStatus]
64
+ when "Error"
65
+ @names = "No names for this compound available."
66
+ when "Completed"
67
+ @names = @compound.names
68
+ else
69
+ @names = "No names for this compound available."
70
+ end
71
+ @inchi = @compound.inchi.gsub("InChI=", "")
72
+
73
+ haml :details, :layout => false
74
+ end
75
+ =begin
76
+ # sdf representation for datasets
77
+ #TODO fix 502 errors from compound service
78
+ get '/predict/:dataset_uri/sdf/?' do
79
+ uri = CGI.unescape(params[:dataset_uri])
80
+ $logger.debug uri
81
+ bad_request_error "Not a dataset uri." unless URI.dataset? uri
82
+ dataset = OpenTox::Dataset.find uri
83
+ @compounds = dataset.compounds
84
+ @data_entries = dataset.data_entries
85
+ sum=""
86
+ @compounds.each_with_index{ |c, idx|
87
+ sum << c.inchi
88
+ sum << c.sdf.sub(/\n\$\$\$\$/,'')
89
+ @data_entries[idx].each{ |f,v|
90
+ sum << "> <\"#{f}\">\n"
91
+ sum << v.join(", ")
92
+ sum << "\n\n"
93
+ }
94
+ sum << "$$$$\n"
95
+ }
96
+ send_file sum, :filename => "#{dataset.title}.sdf"
97
+ end
98
+ =end
99
+ # fingerprints for compound in predictions
100
+ get '/prediction/:model_uri/:type/:compound_uri/fingerprints/?' do
101
+ @type = params[:type]
102
+ model = OpenTox::Model::Lazar.find params[:model_uri]
103
+ feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
104
+ @compound = OpenTox::Compound.new params[:compound_uri]
105
+ @significant_fragments = []
106
+ if @type =~ /classification/i
107
+ # collect all feature values with fingerprint
108
+ fingerprints = OpenTox::Algorithm::Descriptor.send("smarts_match", [@compound], feature_dataset.features.collect{ |f| f[RDF::DC.title]})[@compound.uri]
109
+ #$logger.debug "fingerprints:\t#{fingerprints}\n"
110
+
111
+ # collect fingerprints with value 1
112
+ @fingerprint_values = fingerprints.collect{|smarts, value| [smarts, value] if value > 0}
113
+
114
+ # collect all features from feature_dataset
115
+ @features = feature_dataset.features.collect{|f| f }
116
+
117
+ # search for each fingerprint in all features and collect feature values( effect, smarts, pValue )
118
+ @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] } }
119
+
120
+ # pass value_map, important to interprete effect value
121
+ prediction_feature_uri = ""
122
+ model.parameters.each {|p|
123
+ if p[RDF::DC.title].to_s == "prediction_feature_uri"
124
+ prediction_feature_uri = p[RDF::OT.paramValue].object
125
+ end
126
+ }
127
+ prediction_feature = OpenTox::Feature.find prediction_feature_uri
128
+ @value_map = prediction_feature.value_map
129
+
130
+ else #regression
131
+ feature_calc_algo = ""
132
+ model.parameters.each {|p|
133
+ if p[RDF::DC.title].to_s == "feature_calculation_algorithm"
134
+ feature_calc_algo = p[RDF::OT.paramValue].object
135
+ end
136
+ }
137
+
138
+ @desc = []
139
+ fingerprints = OpenTox::Algorithm::Descriptor.send( feature_calc_algo, [ @compound ], feature_dataset.features.collect{ |f| f[RDF::DC.title] } )
140
+ fingerprints.each{|x, h| h.each{|descriptor, value| @desc << [descriptor, [value]]}}
141
+
142
+ pc_descriptor_titles_descriptions = {}
143
+ feature_dataset.features.collect{ |f|
144
+ pc_descriptor_titles_descriptions[f[RDF::DC.title]]= f[RDF::DC.description]
145
+ }
146
+
147
+ @desc.each{|d, v| @significant_fragments << [pc_descriptor_titles_descriptions[d], v] }
148
+ end
149
+
150
+ haml :significant_fragments, :layout => false
151
+ end
152
+
153
+ get '/prediction/:model_uri/:type/:neighbor/significant_fragments/?' do
154
+ @type = params[:type]
155
+ @compound = OpenTox::Compound.new params[:neighbor]
156
+ model = OpenTox::Model::Lazar.find params[:model_uri]
157
+ #$logger.debug "model for significant fragments:\t#{model.uri}"
158
+
159
+ feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
160
+ $logger.debug "feature_dataset_uri:\t#{feature_dataset.uri}\n"
161
+
162
+ # load all compounds
163
+ feature_dataset.compounds
164
+
165
+ # load all features
166
+ @features = feature_dataset.features.collect{|f| f}
167
+
168
+ # find all features and values for a neighbor compound
169
+ @significant_fragments = []
170
+ # check type first
171
+ if @type =~ /classification/i
172
+ # get compound index in feature dataset
173
+ c_idx = feature_dataset.compound_indices @compound.uri
174
+
175
+ # collect feature uris with value
176
+ @feat = @features.collect{|f| [feature_dataset.data_entry_value(c_idx[0], f.uri), f.uri]}
177
+ #$logger.debug "@feat:\t#{@feat}\n"
178
+
179
+ # pass feature uris if value > 0
180
+ @feat.each do |f|
181
+ # search relevant features
182
+ if f[0] > 0
183
+ f = OpenTox::Feature.find f[1]
184
+ # pass relevant features with [ effect, smarts, pValue ]
185
+ @significant_fragments << [f[RDF::OT.effect].to_i, f[RDF::OT.smarts], f[RDF::OT.pValue].to_f.round(3)]
186
+ end
187
+ end
188
+ # pass value_map, important to interprete effect value
189
+ prediction_feature_uri = ""
190
+ model.parameters.each {|p|
191
+ if p[RDF::DC.title].to_s == "prediction_feature_uri"
192
+ prediction_feature_uri = p[RDF::OT.paramValue].object
193
+ end
194
+ }
195
+ prediction_feature = OpenTox::Feature.find prediction_feature_uri
196
+ @value_map = prediction_feature.value_map
197
+
198
+ else # regression
199
+ # find a value in feature dataset by compound and feature
200
+ @values = @features.collect{|f| feature_dataset.values(@compound, f)}
201
+ #$logger.debug "values in fd:\t#{@values}"
202
+
203
+ @features.each_with_index{|f, i| @significant_fragments << [f.description, @values[i]]}
204
+ end
205
+ #$logger.debug "significant fragments:\t#{@significant_fragments}\n"
206
+
207
+ haml :significant_fragments, :layout => false
208
+ end
209
+
210
+ get '/predict/?:csv?' do
211
+ response['Content-Type'] = "text/csv"
212
+ @csv = "\"Compound\",\"Endpoint\",\"Type\",\"Prediction\",\"Confidence\"\n"
213
+ @@batch.each do |key, values|
214
+ values.each do |array|
215
+ model = array[0]
216
+ prediction = array[1]
217
+ compound = key.smiles
218
+ mw = key.molecular_weight
219
+ endpoint = "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
220
+ if prediction[:confidence] == "measured"
221
+ if prediction[:value].is_a?(Array)
222
+ prediction[:value].each do |value|
223
+ type = ""
224
+ weight = Compound.from_smiles(compound).mmol_to_mg(value, mw)
225
+ pred = value.numeric? ? "#{'%.2e' % value} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : value
226
+ confidence = "measured activity"
227
+ @csv += "\"#{compound}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{confidence}\"\n"
228
+ end
229
+ else
230
+ type = ""
231
+ weight = Compound.from_smiles(compound).mmol_to_mg(prediction[:value], mw)
232
+ pred = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : prediction[:value]
233
+ confidence = "measured activity"
234
+ end
235
+ elsif prediction[:neighbors].size > 0
236
+ weight = Compound.from_smiles(compound).mmol_to_mg(prediction[:value], mw)
237
+ type = model.model.class.to_s.match("Classification") ? "Classification" : "Regression"
238
+ pred = prediction[:value].numeric? ? "#{'%.2e' % prediction[:value]} (#{model.unit}) | #{'%.2e' % weight} (mg/kg_bw/day)" : prediction[:value]
239
+ confidence = prediction[:confidence]
240
+ else
241
+ type = ""
242
+ pred = "Not enough similar compounds in training dataset."
243
+ confidence = ""
244
+ end
245
+ @csv += "\"#{compound}\",\"#{endpoint}\",\"#{type}\",\"#{pred}\",\"#{confidence}\"\n" unless prediction[:value].is_a?(Array)
246
+ end
247
+ end
248
+ @csv
249
+ end
250
+
251
+ post '/predict/?' do
252
+
253
+ # process batch prediction
254
+ if !params[:fileselect].blank?
255
+ if params[:fileselect][:filename] !~ /\.csv$/
256
+ @error_report = "Please submit a csv file."
257
+ return haml :error
258
+ end
259
+ File.open('tmp/' + params[:fileselect][:filename], "w") do |f|
260
+ f.write(params[:fileselect][:tempfile].read)
261
+ end
262
+ @filename = params[:fileselect][:filename]
263
+ input = OpenTox::Dataset.from_csv_file File.join "tmp", params[:fileselect][:filename]
264
+ dataset = OpenTox::Dataset.find input.id
265
+ @compounds = dataset.compounds
266
+ if @compounds.size == 0
267
+ @error_report = "No valid SMILES submitted."
268
+ dataset.delete
269
+ return haml :error
270
+ end
271
+ @batch = {}
272
+ @compounds.each do |compound|
273
+ @batch[compound] = []
274
+ params[:selection].keys.each do |model_id|
275
+ model = Model::Prediction.find model_id
276
+ prediction = model.predict(compound)
277
+ @batch[compound] << [model, prediction]
278
+ end
279
+ end
280
+ @@batch = @batch
281
+ dataset.delete
282
+ return haml :batch
283
+ end
284
+
285
+ # validate identifier input
286
+ # transfered input
287
+ if !params[:identifier].blank?
288
+ @identifier = params[:identifier]
289
+ $logger.debug "input:#{@identifier}"
290
+ # get compound from SMILES
291
+ @compound = Compound.from_smiles @identifier
292
+ if @compound.blank?
293
+ @error_report = "Attention, '#{@identifier}' is not a valid SMILES string."
294
+ return haml :error
295
+ end
296
+
297
+ @models = []
298
+ @predictions = []
299
+ params[:selection].keys.each do |model_id|
300
+ model = Model::Prediction.find model_id
301
+ @models << model
302
+ @predictions << model.predict(@compound)
303
+ end
304
+ haml :prediction
305
+ end
306
+ end
307
+ =begin
308
+ get '/faq' do
309
+ @faq = RDiscount.new(File.read("FAQ.md")).to_html
310
+ haml :faq, :layout => :faq_layout
311
+ end
312
+ =end
313
+ get '/style.css' do
314
+ headers 'Content-Type' => 'text/css; charset=utf-8'
315
+ scss :style
316
+ end
317
+
data/bin/lazar-start ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ bin_dir = File.expand_path(File.dirname(__FILE__))
3
+ shell_script_path = File.join(bin_dir, 'lazar-start.sh')
4
+
5
+ `#{shell_script_path}`
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+ sudo mongod &
3
+ R CMD Rserve
4
+ LAZARPATH=$(gem path lazar-gui)
5
+ cd $LAZARPATH
6
+ unicorn -c unicorn.rb -E production -D
7
+
8
+ exit 0
data/bin/lazar-stop ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ bin_dir = File.expand_path(File.dirname(__FILE__))
3
+ shell_script_path = File.join(bin_dir, 'lazar-stop.sh')
4
+
5
+ `#{shell_script_path}`
6
+
data/bin/lazar-stop.sh ADDED
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+ grep_lazar=`ps aux | grep -v grep | grep lazar-start`
3
+ grep_mongo=`ps aux | grep -v grep | grep mongod`
4
+ grep_rserve=`ps aux | grep -v grep | grep Rserve`
5
+ grep_unicorn=`ps aux | grep -v grep | grep unicorn`
6
+
7
+ # lazar
8
+ if [ ${#grep_lazar} -gt 0 ]
9
+ then
10
+ PID=`ps ax | grep -v grep | grep lazar-start | awk '{ print $1 }'`
11
+ for i in "${PID}"
12
+ do
13
+ `kill $i`
14
+ done
15
+ else
16
+ echo "Lazar is stopped."
17
+ fi
18
+
19
+ # mongod
20
+ if [ ${#grep_mongo} -gt 0 ]
21
+ then
22
+ PID=`ps ax | grep -v grep | grep mongod | awk '{ print $1 }'`
23
+ for i in "${PID}"
24
+ do
25
+ `sudo kill $i`
26
+ done
27
+ else
28
+ echo "MongoDB is not running."
29
+ fi
30
+
31
+ # rserve
32
+ if [ ${#grep_rserve} -gt 0 ]
33
+ then
34
+ PID=`ps ax | grep -v grep | grep Rserve | awk '{ print $1 }'`
35
+ for i in "${PID}"
36
+ do
37
+ `kill $i`
38
+ done
39
+ else
40
+ echo "Rserve is not running."
41
+ fi
42
+
43
+ # unicorn
44
+ if [ ${#grep_unicorn} -gt 0 ]
45
+ then
46
+ PID=`ps ax | grep -v grep | grep unicorn | awk '{ print $1 }'`
47
+ `kill ${PID[0]}`
48
+ else
49
+ echo "Unicorn is not running."
50
+ fi
51
+
52
+ exit 0