opentox-ruby 2.0.1 → 2.1.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.
- data/Rakefile +39 -46
- data/VERSION +1 -1
- data/lib/algorithm.rb +797 -80
- data/lib/compound.rb +40 -0
- data/lib/config/config_ru.rb +2 -0
- data/lib/dataset.rb +57 -18
- data/lib/environment.rb +3 -3
- data/lib/feature.rb +15 -13
- data/lib/helper.rb +1 -2
- data/lib/model.rb +185 -82
- data/lib/opentox-ruby.rb +1 -1
- data/lib/overwrite.rb +2 -1
- data/lib/parser.rb +247 -69
- data/lib/rest_client_wrapper.rb +3 -2
- data/lib/serializer.rb +24 -10
- data/lib/task.rb +10 -3
- data/lib/to-html.rb +66 -41
- data/lib/validation.rb +93 -29
- metadata +206 -117
data/lib/serializer.rb
CHANGED
@@ -17,6 +17,7 @@ module OpenTox
|
|
17
17
|
# this should come from opentox.owl
|
18
18
|
OT.Compound => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
19
19
|
OT.Feature => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
20
|
+
OT.Model => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
20
21
|
OT.NominalFeature => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
21
22
|
OT.NumericFeature => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
22
23
|
OT.StringFeature => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
@@ -27,6 +28,8 @@ module OpenTox
|
|
27
28
|
OT.Parameter => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
28
29
|
OT.Task => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
29
30
|
OTA.PatternMiningSupervised => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
31
|
+
OTA.ClassificationLazySingleTarget => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
32
|
+
OTA.RegressionLazySingleTarget => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
30
33
|
|
31
34
|
#classes for validation
|
32
35
|
OT.Validation => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
|
@@ -45,6 +48,10 @@ module OpenTox
|
|
45
48
|
OT.values => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
46
49
|
OT.algorithm => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
47
50
|
OT.parameters => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
51
|
+
OT.featureDataset => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
52
|
+
OT.dependentVariables => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
53
|
+
OT.predictedVariables => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
54
|
+
OT.paramValue => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
48
55
|
|
49
56
|
#object props for validation#
|
50
57
|
OT.model => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
|
@@ -103,6 +110,7 @@ module OpenTox
|
|
103
110
|
OT.precision => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
104
111
|
OT.areaUnderRoc => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
105
112
|
OT.weightedAreaUnderRoc => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
113
|
+
OT.weightedAccuracy => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
106
114
|
OT.fMeasure => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
107
115
|
OT.percentIncorrect => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
108
116
|
OT.validationType => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
|
@@ -126,7 +134,7 @@ module OpenTox
|
|
126
134
|
OT.hasSource => { RDF["type"] => [{ "type" => "uri", "value" => OWL.DatatypeProperty }] } ,
|
127
135
|
OT.value => { RDF["type"] => [{ "type" => "uri", "value" => OWL.DatatypeProperty }] } ,
|
128
136
|
OT.paramScope => { RDF["type"] => [{ "type" => "uri", "value" => OWL.DatatypeProperty }] } ,
|
129
|
-
OT.paramValue => { RDF["type"] => [{ "type" => "uri", "value" => OWL.DatatypeProperty }] } ,
|
137
|
+
#OT.paramValue => { RDF["type"] => [{ "type" => "uri", "value" => OWL.DatatypeProperty }] } ,
|
130
138
|
}
|
131
139
|
|
132
140
|
@data_entries = {}
|
@@ -157,23 +165,16 @@ module OpenTox
|
|
157
165
|
# Add a dataset
|
158
166
|
# @param [String] uri Dataset URI
|
159
167
|
def add_dataset(dataset)
|
160
|
-
|
161
168
|
@dataset = dataset.uri
|
162
|
-
|
163
169
|
@object[dataset.uri] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Dataset }] }
|
164
|
-
|
165
170
|
add_metadata dataset.uri, dataset.metadata
|
166
|
-
|
167
171
|
dataset.compounds.each { |compound| add_compound compound }
|
168
|
-
|
169
172
|
dataset.features.each { |feature,metadata| add_feature feature,metadata }
|
170
|
-
|
171
173
|
dataset.data_entries.each do |compound,entry|
|
172
174
|
entry.each do |feature,values|
|
173
175
|
values.each { |value| add_data_entry compound,feature,value }
|
174
176
|
end
|
175
177
|
end
|
176
|
-
|
177
178
|
end
|
178
179
|
|
179
180
|
# Add a algorithm
|
@@ -188,6 +189,14 @@ module OpenTox
|
|
188
189
|
def add_model(uri,metadata)
|
189
190
|
@object[uri] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Model }] }
|
190
191
|
add_metadata uri, metadata
|
192
|
+
@object[metadata[OT.featureDataset]] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Dataset }] }
|
193
|
+
@object[metadata[OT.trainingDataset]] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Dataset }] }
|
194
|
+
@object[metadata[OT.dependentVariables]] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Feature }] }
|
195
|
+
metadata[OT.predictedVariables].each{|feature| @object[feature] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Feature }]}} #unless metadata[OT.predictedVariables].nil?
|
196
|
+
# TODO: add algorithms from parameters
|
197
|
+
@object["http://ot-dev.in-silico.ch/algorithm/fminer/bbrc"] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Algorithm }] }
|
198
|
+
@object["http://ot-dev.in-silico.ch/algorithm/fminer/last"] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Algorithm }] }
|
199
|
+
@object["http://ot-dev.in-silico.ch/algorithm/lazar"] = { RDF["type"] => [{ "type" => "uri", "value" => OT.Algorithm }] }
|
191
200
|
end
|
192
201
|
|
193
202
|
# Add a task
|
@@ -272,7 +281,7 @@ module OpenTox
|
|
272
281
|
@object[genid][name] = [{"type" => type(entry), "value" => entry }]
|
273
282
|
end
|
274
283
|
end
|
275
|
-
elsif v.is_a? Array and u == RDF.type
|
284
|
+
elsif v.is_a? Array #and u == RDF.type
|
276
285
|
@object[uri] = {} unless @object[uri]
|
277
286
|
v.each do |value|
|
278
287
|
@object[uri][u] = [] unless @object[uri][u]
|
@@ -354,7 +363,8 @@ module OpenTox
|
|
354
363
|
# @return [text/plain] Object OWL-DL in RDF/XML format
|
355
364
|
def to_rdfxml
|
356
365
|
Tempfile.open("owl-serializer"){|f| f.write(self.to_ntriples); @path = f.path}
|
357
|
-
|
366
|
+
# TODO: add base uri for ist services
|
367
|
+
`rapper -i ntriples -f 'xmlns:ot="#{OT.uri}"' -f 'xmlns:ota="#{OTA.uri}"' -f 'xmlns:dc="#{DC.uri}"' -f 'xmlns:rdf="#{RDF.uri}"' -f 'xmlns:owl="#{OWL.uri}"' -o rdfxml #{@path} 2>/dev/null`
|
358
368
|
end
|
359
369
|
|
360
370
|
# Convert to JSON as specified in http://n2.talis.com/wiki/RDF_JSON_Specification
|
@@ -373,6 +383,8 @@ module OpenTox
|
|
373
383
|
XSD.boolean
|
374
384
|
elsif value.is_a? Float
|
375
385
|
XSD.float
|
386
|
+
elsif value.is_a? Integer
|
387
|
+
XSD.integer
|
376
388
|
else
|
377
389
|
XSD.string
|
378
390
|
end
|
@@ -383,6 +395,8 @@ module OpenTox
|
|
383
395
|
datatype = OT.NominalFeature
|
384
396
|
elsif value.is_a? Float
|
385
397
|
datatype = OT.NumericFeature
|
398
|
+
elsif value.is_a? Integer
|
399
|
+
datatype = OT.NumericFeature
|
386
400
|
else
|
387
401
|
datatype = OT.StringFeature
|
388
402
|
end
|
data/lib/task.rb
CHANGED
@@ -38,6 +38,7 @@ module OpenTox
|
|
38
38
|
task = Task.new(task_uri.chomp)
|
39
39
|
|
40
40
|
# measure current memory consumption
|
41
|
+
=begin
|
41
42
|
memory = `free -m|sed -n '2p'`.split
|
42
43
|
free_memory = memory[3].to_i + memory[6].to_i # include cache
|
43
44
|
if free_memory < 20 # require at least 200 M free memory
|
@@ -56,6 +57,7 @@ module OpenTox
|
|
56
57
|
# return task
|
57
58
|
# #raise "Server too busy to start a new task"
|
58
59
|
#end
|
60
|
+
=end
|
59
61
|
|
60
62
|
task_pid = Spork.spork(:logger => LOGGER) do
|
61
63
|
LOGGER.debug "Task #{task.uri} started #{Time.now}"
|
@@ -167,6 +169,10 @@ module OpenTox
|
|
167
169
|
@metadata[OT.hasStatus] == 'Running'
|
168
170
|
end
|
169
171
|
|
172
|
+
def queued?
|
173
|
+
@metadata[OT.hasStatus] == 'Queued'
|
174
|
+
end
|
175
|
+
|
170
176
|
def completed?
|
171
177
|
@metadata[OT.hasStatus] == 'Completed'
|
172
178
|
end
|
@@ -244,7 +250,7 @@ module OpenTox
|
|
244
250
|
|
245
251
|
load_metadata # for extremely fast tasks
|
246
252
|
check_state
|
247
|
-
while self.running?
|
253
|
+
while self.running? or self.queued?
|
248
254
|
sleep dur
|
249
255
|
load_metadata
|
250
256
|
# if another (sub)task is waiting for self, set progress accordingly
|
@@ -284,9 +290,10 @@ module OpenTox
|
|
284
290
|
raise "illegal task state, task is completed, resultURI is no URI: '"+@metadata[OT.resultURI].to_s+
|
285
291
|
"'" unless @metadata[OT.resultURI] and @metadata[OT.resultURI].to_s.uri? if completed?
|
286
292
|
if @http_code == 202
|
287
|
-
raise "#{@uri}: illegal task state, code is 202, but hasStatus is not Running: '"+@metadata[OT.hasStatus]+"'" unless running?
|
293
|
+
raise "#{@uri}: illegal task state, code is 202, but hasStatus is not Running or Queued: '"+@metadata[OT.hasStatus]+"'" unless running? or queued?
|
288
294
|
elsif @http_code == 201
|
289
|
-
|
295
|
+
# ignore hasStatus
|
296
|
+
# raise "#{@uri}: illegal task state, code is 201, but hasStatus is not Completed: '"+@metadata[OT.hasStatus]+"'" unless completed?
|
290
297
|
raise "#{@uri}: illegal task state, code is 201, resultURI is no task-URI: '"+@metadata[OT.resultURI].to_s+
|
291
298
|
"'" unless @metadata[OT.resultURI] and @metadata[OT.resultURI].to_s.uri?
|
292
299
|
end
|
data/lib/to-html.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
|
2
|
-
OT_LOGO = "
|
2
|
+
OT_LOGO = File.join(CONFIG[:services]["opentox-validation"],"resources/ot-logo.png")
|
3
3
|
|
4
4
|
class String
|
5
5
|
|
6
6
|
# encloses URI in text with with link tag
|
7
7
|
# @return [String] new text with marked links
|
8
8
|
def link_urls
|
9
|
-
self.gsub(/(?i)http(s?):\/\/[^\r\n\s']*/, '<a href
|
9
|
+
self.gsub(/(?i)http(s?):\/\/[^\r\n\s']*/, '<a href="\0">\0</a>')
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -15,98 +15,123 @@ module OpenTox
|
|
15
15
|
# produces a html page for making web services browser friendly
|
16
16
|
# format of text (=string params) is preserved (e.g. line breaks)
|
17
17
|
# urls are marked as links
|
18
|
-
#
|
19
|
-
# [ [ [:mandatory_param_1], [:mandatory_param_2], [:optional_param,"default_value"] ],
|
20
|
-
# [ [:alteranative_mandatory_param_1], [:alteranative_mandatory_param_2] ]
|
21
|
-
# ]
|
18
|
+
#
|
22
19
|
# @param [String] text this is the actual content,
|
23
20
|
# @param [optional,String] related_links info on related resources
|
24
21
|
# @param [optional,String] description general info
|
25
|
-
# @param [optional,Array]
|
22
|
+
# @param [optional,Array] post_command, infos for the post operation, object defined below
|
26
23
|
# @return [String] html page
|
27
|
-
def self.text_to_html( text, subjectid=nil, related_links=nil, description=nil,
|
24
|
+
def self.text_to_html( text, subjectid=nil, related_links=nil, description=nil, post_command=nil )
|
28
25
|
|
29
26
|
# TODO add title as parameter
|
30
27
|
title = nil #$sinatra.url_for($sinatra.request.env['PATH_INFO'], :full) if $sinatra
|
31
28
|
html = "<html>"
|
32
29
|
html += "<title>"+title+"</title>" if title
|
33
|
-
html += "<img src
|
30
|
+
html += "<img src=\""+OT_LOGO+"\"><\/img><body>"
|
34
31
|
|
35
32
|
if AA_SERVER
|
36
33
|
user = OpenTox::Authorization.get_user(subjectid) if subjectid
|
37
34
|
html += "<pre><p align=\"right\">"
|
38
35
|
unless user
|
39
|
-
html += "You are currently not
|
40
|
-
", <a href="+$url_provider.url_for("/
|
36
|
+
html += "You are currently not signed in to "+$url_provider.url_for("",:full)+
|
37
|
+
", <a href="+$url_provider.url_for("/sign_in",:full)+">sign in</a>"
|
41
38
|
else
|
42
|
-
html += "You are
|
43
|
-
", <a href="+$url_provider.url_for("/
|
39
|
+
html += "You are signed in as '#{user}' to "+$url_provider.url_for("",:full)+
|
40
|
+
", <a href="+$url_provider.url_for("/sign_out",:full)+">sign out</a>"
|
44
41
|
end
|
45
42
|
html += " </p></pre>"
|
46
43
|
end
|
47
44
|
|
48
45
|
html += "<h3>Description</h3><pre><p>"+description.link_urls+"</p></pre>" if description
|
49
46
|
html += "<h3>Related links</h3><pre><p>"+related_links.link_urls+"</p></pre>" if related_links
|
50
|
-
if
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
html += "<pre><p>alternatively:</p></pre>" if count > 0
|
55
|
-
html += "<pre><p><table><thead><tr><th>param</th><th>default_value</th></tr></thead>"
|
56
|
-
p.each do |k,v|
|
57
|
-
html += "<tr><th>"+k.to_s+"</th><th>"+(v!=nil ? v.to_s : "<i>mandatory</i>")+"</th></tr>"
|
58
|
-
end
|
59
|
-
html += "</table></p></pre>"
|
60
|
-
count += 1
|
61
|
-
end
|
47
|
+
if post_command
|
48
|
+
raise "not a post command" unless post_command.is_a?(OpenTox::PostCommand)
|
49
|
+
html += "<h3>POST command</h3>"
|
50
|
+
html += post_command.to_html
|
62
51
|
end
|
63
|
-
html += "<h3>Content</h3>" if description || related_links
|
52
|
+
html += "<h3>Content</h3>" if description || related_links || post_command
|
64
53
|
html += "<pre><p style=\"padding:15px; border:10px solid \#5D308A\">"
|
65
54
|
html += text.link_urls
|
66
|
-
html += "</p></pre></body
|
55
|
+
html += "</p></pre></body></html>"
|
67
56
|
html
|
68
57
|
end
|
69
58
|
|
70
|
-
def self.
|
59
|
+
def self.sign_in( msg=nil )
|
71
60
|
html = "<html><title>Login</title><img src="+OT_LOGO+"><body>"
|
72
|
-
html += "<form method='POST' action='"+$url_provider.url_for("/
|
61
|
+
html += "<form method='POST' action='"+$url_provider.url_for("/sign_in",:full)+"'>"
|
73
62
|
html += "<pre><p style=\"padding:15px; border:10px solid \#5D308A\">"
|
74
63
|
html += msg+"\n\n" if msg
|
75
|
-
html += "Please
|
64
|
+
html += "Please sign in to "+$url_provider.url_for("",:full)+"\n\n"
|
76
65
|
html += "<table border=0>"
|
77
66
|
html += "<tr><td>user:</td><td><input type='text' name='user' size='15' /></td></tr>"+
|
78
67
|
"<tr><td>password:</td><td><input type='password' name='password' size='15' /></td></tr>"+
|
79
68
|
#"<input type=hidden name=back_to value="+back_to.to_s+">"+
|
80
|
-
"<tr><td><input type='submit' value='
|
81
|
-
html += "</table></p></pre></form></body
|
69
|
+
"<tr><td><input type='submit' value='Sign in' /></td></tr>"
|
70
|
+
html += "</table></p></pre></form></body></html>"
|
82
71
|
html
|
83
72
|
end
|
73
|
+
|
74
|
+
class PostAttribute
|
75
|
+
attr_accessor :name, :is_mandatory, :default, :description
|
76
|
+
|
77
|
+
def initialize(name, is_mandatory=true, default=nil, description=nil)
|
78
|
+
@name = name
|
79
|
+
@is_mandatory = is_mandatory
|
80
|
+
@default = default
|
81
|
+
@description = description
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class PostCommand
|
86
|
+
attr_accessor :attributes, :uri, :name
|
87
|
+
|
88
|
+
def initialize( uri, name="Send" )
|
89
|
+
@uri = uri
|
90
|
+
@name = name
|
91
|
+
@attributes = []
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_html
|
95
|
+
html = "<form method='POST' action='"+@uri.to_s+"'>"
|
96
|
+
html << "<pre><p>"
|
97
|
+
html << "<table border=0>"
|
98
|
+
#html << "<tr><td colspan='3'><i><sup>Mandatory params are marked with *.</sup></i></td></tr>"
|
99
|
+
attributes.each do |a|
|
100
|
+
mandatory_string = a.is_mandatory ? "*" : ""
|
101
|
+
html << "<tr><td>"+a.name.to_s+":"+mandatory_string+"</td>"
|
102
|
+
html << "<td><input type='text' name='"+a.name.to_s+
|
103
|
+
"' size='50' value='"+a.default.to_s+"'/></td>"
|
104
|
+
html << "<td><i><sup>"+a.description.to_s+"</sup></i></td></tr>"
|
105
|
+
end
|
106
|
+
html << "<tr><td colspan='3'><input type='submit' value='"+@name.to_s+"' /></td></tr>"
|
107
|
+
html << "</table></p></pre></form>"
|
108
|
+
html
|
109
|
+
end
|
110
|
+
end
|
84
111
|
end
|
85
112
|
|
86
|
-
|
87
|
-
get '/logout/?' do
|
113
|
+
get '/sign_out/?' do
|
88
114
|
response.set_cookie("subjectid",{:value=>nil})
|
89
115
|
content_type "text/html"
|
90
|
-
content = "Sucessfully
|
116
|
+
content = "Sucessfully signed out from "+$url_provider.url_for("",:full)
|
91
117
|
OpenTox.text_to_html(content)
|
92
118
|
end
|
93
119
|
|
94
|
-
get '/
|
120
|
+
get '/sign_in/?' do
|
95
121
|
content_type "text/html"
|
96
|
-
OpenTox.
|
122
|
+
OpenTox.sign_in
|
97
123
|
end
|
98
124
|
|
99
|
-
post '/
|
125
|
+
post '/sign_in/?' do
|
100
126
|
subjectid = OpenTox::Authorization.authenticate(params[:user], params[:password])
|
101
127
|
if (subjectid)
|
102
128
|
response.set_cookie("subjectid",{:value=>subjectid})
|
103
129
|
content_type "text/html"
|
104
|
-
content = "Sucessfully
|
130
|
+
content = "Sucessfully signed in as '"+params[:user]+"' to "+$url_provider.url_for("",:full)
|
105
131
|
OpenTox.text_to_html(content,subjectid)
|
106
132
|
else
|
107
133
|
content_type "text/html"
|
108
|
-
OpenTox.
|
134
|
+
OpenTox.sign_in("Login failed, please try again")
|
109
135
|
end
|
110
136
|
end
|
111
|
-
=end
|
112
137
|
|
data/lib/validation.rb
CHANGED
@@ -36,6 +36,30 @@ module OpenTox
|
|
36
36
|
Validation.new(uri)
|
37
37
|
end
|
38
38
|
|
39
|
+
# creates a training test validation, waits until it finishes, may take some time
|
40
|
+
# @param [Hash] params (required:algorithm_uri,training_dataset_uri,prediction_feature,test_dataset_uri,optional:algorithm_params)
|
41
|
+
# @param [String,optional] subjectid
|
42
|
+
# @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
43
|
+
# @return [OpenTox::Validation]
|
44
|
+
def self.create_training_test_validation( params, subjectid=nil, waiting_task=nil )
|
45
|
+
params[:subjectid] = subjectid if subjectid
|
46
|
+
uri = OpenTox::RestClientWrapper.post( File.join(CONFIG[:services]["opentox-validation"],"training_test_validation"),
|
47
|
+
params,{:content_type => "text/uri-list"},waiting_task )
|
48
|
+
Validation.new(uri)
|
49
|
+
end
|
50
|
+
|
51
|
+
# creates a bootstrapping validation, waits until it finishes, may take some time
|
52
|
+
# @param [Hash] params (required:algorithm_uri,dataset_uri,prediction_feature, optional:algorithm_params,random_seed(1))
|
53
|
+
# @param [String,optional] subjectid
|
54
|
+
# @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
55
|
+
# @return [OpenTox::Validation]
|
56
|
+
def self.create_bootstrapping_validation( params, subjectid=nil, waiting_task=nil )
|
57
|
+
params[:subjectid] = subjectid if subjectid
|
58
|
+
uri = OpenTox::RestClientWrapper.post( File.join(CONFIG[:services]["opentox-validation"],"bootstrapping"),
|
59
|
+
params,{:content_type => "text/uri-list"},waiting_task )
|
60
|
+
Validation.new(uri)
|
61
|
+
end
|
62
|
+
|
39
63
|
# looks for report for this validation, creates a report if no report is found
|
40
64
|
# @param [String,optional] subjectid
|
41
65
|
# @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
@@ -61,34 +85,27 @@ module OpenTox
|
|
61
85
|
@metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
|
62
86
|
end
|
63
87
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
88
|
+
# returns confusion matrix as array, predicted values are in rows
|
89
|
+
# example:
|
90
|
+
# [[nil,"active","moderate","inactive"],["active",1,3,99],["moderate",4,2,8],["inactive",3,8,6]]
|
91
|
+
# -> 99 inactive compounds have been predicted as active
|
92
|
+
def confusion_matrix
|
93
|
+
raise "no classification statistics, probably a regression valdiation" unless @metadata[OT.classificationStatistics]
|
94
|
+
matrix = @metadata[OT.classificationStatistics][OT.confusionMatrix][OT.confusionMatrixCell]
|
95
|
+
values = matrix.collect{|cell| cell[OT.confusionMatrixPredicted]}.uniq
|
96
|
+
table = [[nil]+values]
|
97
|
+
values.each do |c|
|
98
|
+
table << [c]
|
99
|
+
values.each do |r|
|
100
|
+
matrix.each do |cell|
|
101
|
+
if cell[OT.confusionMatrixPredicted]==c and cell[OT.confusionMatrixActual]==r
|
102
|
+
table[-1] << cell[OT.confusionMatrixValue].to_f
|
103
|
+
break
|
104
|
+
end
|
81
105
|
end
|
82
106
|
end
|
83
|
-
res
|
84
|
-
elsif @metadata[OT.regressionStatistics]
|
85
|
-
{
|
86
|
-
:nr_predictions => @metadata[OT.numInstances] - @metadata[OT.numUnpredicted],
|
87
|
-
:r_square => @metadata[OT.regressionStatistics][OT.rSquare],
|
88
|
-
:root_mean_squared_error => @metadata[OT.regressionStatistics][OT.rootMeanSquaredError],
|
89
|
-
:mean_absolute_error => @metadata[OT.regressionStatistics][OT.meanAbsoluteError],
|
90
|
-
}
|
91
107
|
end
|
108
|
+
table
|
92
109
|
end
|
93
110
|
end
|
94
111
|
|
@@ -147,9 +164,9 @@ module OpenTox
|
|
147
164
|
@metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
|
148
165
|
end
|
149
166
|
|
150
|
-
#
|
151
|
-
def
|
152
|
-
Validation.from_cv_statistics( @uri, subjectid )
|
167
|
+
# returns a Validation object containing the statistics of the crossavlidation
|
168
|
+
def statistics( subjectid=nil )
|
169
|
+
Validation.from_cv_statistics( @uri, subjectid )
|
153
170
|
end
|
154
171
|
end
|
155
172
|
|
@@ -198,7 +215,6 @@ module OpenTox
|
|
198
215
|
# @param [String,optional] subjectid
|
199
216
|
# @return [OpenTox::CrossvalidationReport]
|
200
217
|
def self.find( uri, subjectid=nil )
|
201
|
-
# PENDING load report data?
|
202
218
|
OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
|
203
219
|
rep = CrossvalidationReport.new(uri)
|
204
220
|
rep.load_metadata( subjectid )
|
@@ -227,6 +243,54 @@ module OpenTox
|
|
227
243
|
end
|
228
244
|
end
|
229
245
|
|
246
|
+
|
247
|
+
class AlgorithmComparisonReport
|
248
|
+
include OpenTox
|
249
|
+
|
250
|
+
# finds AlgorithmComparisonReport via uri, raises error if not found
|
251
|
+
# @param [String] uri
|
252
|
+
# @param [String,optional] subjectid
|
253
|
+
# @return [OpenTox::CrossvalidationReport]
|
254
|
+
def self.find( uri, subjectid=nil )
|
255
|
+
OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
|
256
|
+
rep = AlgorithmComparisonReport.new(uri)
|
257
|
+
rep.load_metadata( subjectid )
|
258
|
+
rep
|
259
|
+
end
|
260
|
+
|
261
|
+
# finds AlgorithmComparisonReport for a particular crossvalidation
|
262
|
+
# @param [String] crossvalidation uri
|
263
|
+
# @param [String,optional] subjectid
|
264
|
+
# @return [OpenTox::AlgorithmComparisonReport] nil if no report found
|
265
|
+
def self.find_for_crossvalidation( crossvalidation_uri, subjectid=nil )
|
266
|
+
uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
|
267
|
+
"/report/algorithm_comparison?crossvalidation="+crossvalidation_uri), {:subjectid => subjectid}).chomp.split("\n")
|
268
|
+
uris.size==0 ? nil : AlgorithmComparisonReport.new(uris[-1])
|
269
|
+
end
|
270
|
+
|
271
|
+
# creates a crossvalidation report via crossvalidation
|
272
|
+
# @param [Hash] crossvalidation uri_hash, see example
|
273
|
+
# @param [String,optional] subjectid
|
274
|
+
# @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
275
|
+
# @return [OpenTox::AlgorithmComparisonReport]
|
276
|
+
# example for hash:
|
277
|
+
# { :lazar-bbrc => [ http://host/validation/crossvalidation/x1, http://host/validation/crossvalidation/x2 ],
|
278
|
+
# :lazar-last => [ http://host/validation/crossvalidation/xy, http://host/validation/crossvalidation/xy ] }
|
279
|
+
def self.create( crossvalidation_uri_hash, subjectid=nil, waiting_task=nil )
|
280
|
+
identifier = []
|
281
|
+
validation_uris = []
|
282
|
+
crossvalidation_uri_hash.each do |id, uris|
|
283
|
+
uris.each do |uri|
|
284
|
+
identifier << id
|
285
|
+
validation_uris << uri
|
286
|
+
end
|
287
|
+
end
|
288
|
+
uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/algorithm_comparison"),
|
289
|
+
{ :validation_uris => validation_uris.join(","), :identifier => identifier.join(","), :subjectid => subjectid }, {}, waiting_task )
|
290
|
+
AlgorithmComparisonReport.new(uri)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
230
294
|
class QMRFReport
|
231
295
|
include OpenTox
|
232
296
|
|