opentox-ruby-api-wrapper 1.6.4 → 1.6.5
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 +2 -1
- data/VERSION +1 -1
- data/lib/algorithm.rb +12 -0
- data/lib/dataset.rb +8 -5
- data/lib/environment.rb +1 -1
- data/lib/model.rb +99 -69
- data/lib/owl.rb +5 -0
- data/lib/task.rb +37 -29
- data/lib/validation.rb +1 -10
- metadata +3 -3
data/Rakefile
CHANGED
@@ -34,7 +34,8 @@ begin
|
|
34
34
|
'dm-timestamps',
|
35
35
|
'dm-types',
|
36
36
|
'dm-migrations',
|
37
|
-
"dm-mysql-adapter"
|
37
|
+
"dm-mysql-adapter",
|
38
|
+
"dm-validations",
|
38
39
|
].each {|dep| gem.add_dependency dep, ">= 1" }
|
39
40
|
gem.add_dependency "haml", ">=3"
|
40
41
|
['cucumber','jeweler'].each { |dep| gem.add_development_dependency dep }
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.6.
|
1
|
+
1.6.5
|
data/lib/algorithm.rb
CHANGED
@@ -64,6 +64,18 @@ module OpenTox
|
|
64
64
|
0.0
|
65
65
|
end
|
66
66
|
end
|
67
|
+
def self.euclidean(prop_a,prop_b)
|
68
|
+
common_properties = prop_a.keys & prop_b.keys
|
69
|
+
if common_properties.size > 1
|
70
|
+
dist_sum = 0
|
71
|
+
common_properties.each do |p|
|
72
|
+
dist_sum += (prop_a[p] - prop_b[p])**2
|
73
|
+
end
|
74
|
+
1/(1+Math.sqrt(dist_sum))
|
75
|
+
else
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
end
|
67
79
|
end
|
68
80
|
|
69
81
|
end
|
data/lib/dataset.rb
CHANGED
@@ -66,8 +66,8 @@ module OpenTox
|
|
66
66
|
raise "no new compounds selected" unless new_compounds and new_compounds.size>0
|
67
67
|
|
68
68
|
# load require features
|
69
|
-
if ((defined? @dirty_features) && (@dirty_features
|
70
|
-
(@dirty_features
|
69
|
+
if ((defined? @dirty_features) && (@dirty_features & new_features).size > 0)
|
70
|
+
(@dirty_features & new_features).each{|f| load_feature_values(f)}
|
71
71
|
end
|
72
72
|
|
73
73
|
dataset = OpenTox::Dataset.new
|
@@ -202,16 +202,19 @@ module OpenTox
|
|
202
202
|
|
203
203
|
# overwrite to yaml:
|
204
204
|
# in case dataset is loaded from owl:
|
205
|
-
# * load all values
|
206
|
-
# * set @owl to nil (not necessary in yaml)
|
205
|
+
# * load all values
|
207
206
|
def to_yaml
|
208
207
|
# loads all features
|
209
208
|
if ((defined? @dirty_features) && @dirty_features.size > 0)
|
210
209
|
load_feature_values
|
211
210
|
end
|
212
|
-
@owl = nil
|
213
211
|
super
|
214
212
|
end
|
213
|
+
|
214
|
+
# * remove @owl from yaml, not necessary
|
215
|
+
def to_yaml_properties
|
216
|
+
super - ["@owl"]
|
217
|
+
end
|
215
218
|
|
216
219
|
# saves (changes) as new dataset in dataset service
|
217
220
|
# returns uri
|
data/lib/environment.rb
CHANGED
@@ -25,7 +25,7 @@ end
|
|
25
25
|
|
26
26
|
# database
|
27
27
|
if @@config[:database]
|
28
|
-
['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations' ].each{|lib| require lib }
|
28
|
+
['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations', 'dm-validations' ].each{|lib| require lib }
|
29
29
|
case @@config[:database][:adapter]
|
30
30
|
when /sqlite/i
|
31
31
|
db_dir = File.join(basedir, "db")
|
data/lib/model.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module OpenTox
|
2
|
-
|
2
|
+
module Model
|
3
3
|
|
4
|
-
|
4
|
+
class Generic
|
5
5
|
|
6
6
|
MODEL_ATTRIBS = [:uri, :title, :creator, :date, :format, :predictedVariables, :independentVariables, :dependentVariables, :trainingDataset, :algorithm]
|
7
7
|
MODEL_ATTRIBS.each{ |a| attr_accessor(a) }
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
def self.find(uri)
|
10
|
+
owl = OpenTox::Owl.from_uri(uri, "Model")
|
11
11
|
return self.new(owl)
|
12
12
|
end
|
13
13
|
|
@@ -28,86 +28,116 @@ module OpenTox
|
|
28
28
|
if ENV['RACK_ENV'] =~ /test|debug/
|
29
29
|
begin
|
30
30
|
raise "uri invalid" unless Utils.is_uri?(@uri)
|
31
|
-
raise "no algorithm" unless @algorithm and @algorithm.size>0
|
32
|
-
raise "no dependent variables" unless @dependentVariables and @dependentVariables.size>0
|
33
|
-
raise "no indenpendent variables" unless @independentVariables
|
34
31
|
raise "no predicted variables" unless @predictedVariables and @predictedVariables.size>0
|
35
32
|
rescue => ex
|
36
33
|
RestClientWrapper.raise_uri_error "invalid model: '"+ex.message+"'\n"+self.to_yaml+"\n",@uri.to_s
|
37
34
|
end
|
35
|
+
LOGGER.warn "model has no dependent variable" unless @dependentVariables and @dependentVariables.size>0
|
36
|
+
LOGGER.warn "model has no algorithm" unless @algorithm and @algorithm.size>0
|
37
|
+
LOGGER.warn "model has no indenpendent variables" unless @independentVariables
|
38
38
|
end
|
39
|
-
|
40
|
-
|
39
|
+
end
|
40
|
+
end
|
41
41
|
|
42
|
-
|
42
|
+
class PredictionModel < Generic
|
43
|
+
|
44
|
+
def self.build( algorithm_uri, algorithm_params )
|
45
|
+
|
46
|
+
LOGGER.debug "Build model, algorithm_uri:"+algorithm_uri.to_s+", algorithm_parms: "+algorithm_params.inspect.to_s
|
47
|
+
uri = OpenTox::RestClientWrapper.post(algorithm_uri,algorithm_params).to_s
|
48
|
+
LOGGER.debug "Build model done: "+uri.to_s
|
49
|
+
RestClientWrapper.raise_uri_error("Invalid build model result: '"+uri.to_s+"'", algorithm_uri, algorithm_params ) unless Utils.model_uri?(uri)
|
50
|
+
return PredictionModel.find(uri)
|
51
|
+
end
|
43
52
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
elsif @uri =~/ambit2/ and @title =~ /pKa/ || @title =~ /Regression|Caco/
|
72
|
-
return false
|
73
|
-
elsif @uri =~/majority/
|
74
|
-
return (@uri =~ /class/) != nil
|
75
|
-
else
|
76
|
-
raise "unknown model, uri:'"+@uri.to_s+"' title:'"+@title.to_s+"'"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
53
|
+
def predict_dataset( dataset_uri )
|
54
|
+
|
55
|
+
LOGGER.debug "Predict dataset: "+dataset_uri.to_s+" with model "+@uri.to_s
|
56
|
+
uri = RestClientWrapper.post(@uri, {:accept => "text/uri-list", :dataset_uri=>dataset_uri})
|
57
|
+
RestClientWrapper.raise_uri_error("Prediciton result no dataset uri: "+uri.to_s, @uri, {:dataset_uri=>dataset_uri} ) unless Utils.dataset_uri?(uri)
|
58
|
+
uri
|
59
|
+
end
|
60
|
+
|
61
|
+
def classification?
|
62
|
+
#HACK replace with request to ontology server
|
63
|
+
if @title =~ /(?i)classification/
|
64
|
+
return true
|
65
|
+
elsif @title =~ /(?i)regression/
|
66
|
+
return false
|
67
|
+
elsif @uri =~/ntua/ and @title =~ /mlr/
|
68
|
+
return false
|
69
|
+
elsif @uri =~/tu-muenchen/ and @title =~ /regression|M5P|GaussP/
|
70
|
+
return false
|
71
|
+
elsif @uri =~/ambit2/ and @title =~ /pKa/ || @title =~ /Regression|Caco/
|
72
|
+
return false
|
73
|
+
elsif @uri =~/majority/
|
74
|
+
return (@uri =~ /class/) != nil
|
75
|
+
else
|
76
|
+
raise "unknown model, uri:'"+@uri.to_s+"' title:'"+@title.to_s+"'"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
81
80
|
|
82
|
-
|
81
|
+
class Lazar < Generic
|
83
82
|
|
84
83
|
attr_accessor :feature_dataset_uri, :effects, :activities, :p_values, :fingerprints, :features
|
85
84
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
85
|
+
def initialize
|
86
|
+
@source = "http://github.com/helma/opentox-model"
|
87
|
+
@algorithm = File.join(@@config[:services]["opentox-algorithm"],"lazar")
|
88
|
+
#@independent_variables = File.join(@@config[:services]["opentox-algorithm"],"fminer#BBRC_representative")
|
89
|
+
@features = []
|
90
|
+
@effects = {}
|
91
|
+
@activities = {}
|
92
|
+
@p_values = {}
|
93
|
+
@fingerprints = {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def save
|
97
|
+
@features.uniq!
|
98
|
+
resource = RestClient::Resource.new(@@config[:services]["opentox-model"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
|
99
|
+
resource.post(self.to_yaml, :content_type => "application/x-yaml").chomp.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.find_all
|
103
|
+
RestClientWrapper.get(@@config[:services]["opentox-model"]).chomp.split("\n")
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.predict(compound_uri,model_uri)
|
107
|
+
#RestClientWrapper.post(model_uri,{:compound_uri => compound_uri, :accept => 'application/x-yaml'})
|
108
|
+
`curl -X POST -d 'compound_uri=#{compound_uri}' -H 'Accept:application/x-yaml' #{model_uri}`
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class PropertyLazar < Generic
|
113
|
+
|
114
|
+
attr_accessor :feature_dataset_uri, :properties, :features, :activities#, :effects, :p_values
|
115
|
+
|
116
|
+
def initialize
|
117
|
+
@source = "http://github.com/helma/opentox-model"
|
118
|
+
@algorithm = File.join(@@config[:services]["opentox-algorithm"],"property_lazar")
|
119
|
+
#@independent_variables = File.join(@@config[:services]["opentox-algorithm"],"fminer#BBRC_representative")
|
120
|
+
@features = []
|
121
|
+
#@effects = {}
|
122
|
+
@activities = {}
|
123
|
+
#@p_values = {}
|
124
|
+
@properties = {}
|
125
|
+
end
|
96
126
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
127
|
+
def save
|
128
|
+
@features.uniq!
|
129
|
+
resource = RestClient::Resource.new(@@config[:services]["opentox-model"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
|
130
|
+
resource.post(self.to_yaml, :content_type => "application/x-yaml").chomp.to_s
|
131
|
+
end
|
102
132
|
|
103
|
-
|
104
|
-
|
105
|
-
|
133
|
+
def self.find_all
|
134
|
+
RestClientWrapper.get(@@config[:services]["opentox-model"]).chomp.split("\n")
|
135
|
+
end
|
106
136
|
|
107
137
|
def self.predict(compound_uri,model_uri)
|
108
138
|
#RestClientWrapper.post(model_uri,{:compound_uri => compound_uri, :accept => 'application/x-yaml'})
|
109
|
-
|
139
|
+
`curl -X POST -d 'compound_uri=#{compound_uri}' -H 'Accept:application/x-yaml' #{model_uri}`
|
110
140
|
end
|
111
|
-
|
112
|
-
|
141
|
+
end
|
142
|
+
end
|
113
143
|
end
|
data/lib/owl.rb
CHANGED
@@ -518,6 +518,11 @@ module OpenTox
|
|
518
518
|
value_node = value_nodes[0]
|
519
519
|
|
520
520
|
compound_uri = get_value( @model.object(value_node, node('compound')) )
|
521
|
+
unless compound_uri
|
522
|
+
LOGGER.warn "'compound' missing for data-entry of feature "+feature_uri.to_s+
|
523
|
+
", value: "+@model.object(feature_value_node,node("value")).to_s
|
524
|
+
next
|
525
|
+
end
|
521
526
|
|
522
527
|
value_node_type = @model.object(feature_value_node, RDF_TYPE)
|
523
528
|
if (value_node_type == node('FeatureValue'))
|
data/lib/task.rb
CHANGED
@@ -2,7 +2,7 @@ $self_task=nil
|
|
2
2
|
|
3
3
|
module OpenTox
|
4
4
|
|
5
|
-
|
5
|
+
class Task
|
6
6
|
|
7
7
|
# due_to_time is only set in local tasks
|
8
8
|
TASK_ATTRIBS = [ :uri, :date, :title, :creator, :description, :hasStatus, :percentageCompleted, :resultURI, :due_to_time ]
|
@@ -15,13 +15,13 @@ module OpenTox
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# create is private now, use OpenTox::Task.as_task
|
18
|
-
|
19
|
-
task_uri = RestClientWrapper.post(@@config[:services]["opentox-task"],
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def self.create( params )
|
19
|
+
task_uri = RestClientWrapper.post(@@config[:services]["opentox-task"], params, nil, false).to_s
|
20
|
+
Task.find(task_uri.chomp)
|
21
|
+
end
|
22
|
+
|
23
23
|
public
|
24
|
-
def self.find( uri, accept_header=
|
24
|
+
def self.find( uri, accept_header=nil )
|
25
25
|
task = Task.new(uri)
|
26
26
|
task.reload( accept_header )
|
27
27
|
return task
|
@@ -34,7 +34,14 @@ module OpenTox
|
|
34
34
|
return task
|
35
35
|
end
|
36
36
|
|
37
|
-
def reload( accept_header=
|
37
|
+
def reload( accept_header=nil )
|
38
|
+
unless accept_header
|
39
|
+
if (@@config[:yaml_hosts].include?(URI.parse(uri).host))
|
40
|
+
accept_header = "application/x-yaml"
|
41
|
+
else
|
42
|
+
accept_header = 'application/rdf+xml'
|
43
|
+
end
|
44
|
+
end
|
38
45
|
result = RestClientWrapper.get(uri, {:accept => accept_header}, false)#'application/x-yaml'})
|
39
46
|
@http_code = result.code
|
40
47
|
reload_from_data(result, result.content_type, uri)
|
@@ -58,20 +65,20 @@ module OpenTox
|
|
58
65
|
raise "uri is null after loading" unless @uri and @uri.to_s.strip.size>0
|
59
66
|
end
|
60
67
|
|
61
|
-
|
68
|
+
def cancel
|
62
69
|
RestClientWrapper.put(File.join(@uri,'Cancelled'))
|
63
70
|
reload
|
64
|
-
|
71
|
+
end
|
65
72
|
|
66
|
-
|
67
|
-
|
73
|
+
def completed(uri)
|
74
|
+
RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri})
|
68
75
|
reload
|
69
|
-
|
76
|
+
end
|
70
77
|
|
71
|
-
|
78
|
+
def error(description)
|
72
79
|
RestClientWrapper.put(File.join(@uri,'Error'),{:description => description.to_s[0..2000]})
|
73
80
|
reload
|
74
|
-
|
81
|
+
end
|
75
82
|
|
76
83
|
def pid=(pid)
|
77
84
|
RestClientWrapper.put(File.join(@uri,'pid'), {:pid => pid})
|
@@ -81,16 +88,16 @@ module OpenTox
|
|
81
88
|
@hasStatus.to_s == 'Running'
|
82
89
|
end
|
83
90
|
|
84
|
-
|
85
|
-
|
86
|
-
|
91
|
+
def completed?
|
92
|
+
@hasStatus.to_s == 'Completed'
|
93
|
+
end
|
87
94
|
|
88
|
-
|
89
|
-
|
90
|
-
|
95
|
+
def error?
|
96
|
+
@hasStatus.to_s == 'Error'
|
97
|
+
end
|
91
98
|
|
92
99
|
# waits for a task, unless time exceeds or state is no longer running
|
93
|
-
|
100
|
+
def wait_for_completion(dur=0.3)
|
94
101
|
|
95
102
|
if (@uri.match(@@config[:services]["opentox-task"]))
|
96
103
|
due_to_time = (@due_to_time.is_a?(Time) ? @due_to_time : Time.parse(@due_to_time))
|
@@ -102,17 +109,17 @@ module OpenTox
|
|
102
109
|
end
|
103
110
|
LOGGER.debug "start waiting for task "+@uri.to_s+" at: "+Time.new.to_s+", waiting at least until "+due_to_time.to_s
|
104
111
|
|
105
|
-
|
106
|
-
|
112
|
+
while self.running?
|
113
|
+
sleep dur
|
107
114
|
reload
|
108
115
|
check_state
|
109
116
|
if (Time.new > due_to_time)
|
110
117
|
raise "max wait time exceeded ("+running_time.to_s+"sec), task: '"+@uri.to_s+"'"
|
111
118
|
end
|
112
|
-
|
119
|
+
end
|
113
120
|
|
114
121
|
LOGGER.debug "Task '"+@hasStatus+"': "+@uri.to_s+", Result: "+@resultURI.to_s
|
115
|
-
|
122
|
+
end
|
116
123
|
|
117
124
|
def check_state
|
118
125
|
begin
|
@@ -133,10 +140,11 @@ module OpenTox
|
|
133
140
|
|
134
141
|
# returns the task uri
|
135
142
|
# catches halts and exceptions, task state is set to error then
|
136
|
-
def self.as_task(max_duration=DEFAULT_TASK_MAX_DURATION)
|
143
|
+
def self.as_task( title, creator, max_duration=DEFAULT_TASK_MAX_DURATION, description=nil )
|
137
144
|
#return yield nil
|
138
145
|
|
139
|
-
|
146
|
+
params = {:title=>title, :creator=>creator, :max_duration=>max_duration, :description=>description }
|
147
|
+
task = OpenTox::Task.create(params)
|
140
148
|
task_pid = Spork.spork(:logger => LOGGER) do
|
141
149
|
LOGGER.debug "Task #{task.uri} started #{Time.now}"
|
142
150
|
$self_task = task
|
@@ -163,6 +171,6 @@ module OpenTox
|
|
163
171
|
LOGGER.debug "Started task: "+task.uri.to_s
|
164
172
|
task.uri
|
165
173
|
end
|
166
|
-
|
174
|
+
end
|
167
175
|
|
168
176
|
end
|
data/lib/validation.rb
CHANGED
@@ -4,16 +4,7 @@ module OpenTox
|
|
4
4
|
attr_accessor :uri
|
5
5
|
|
6
6
|
def initialize(params)
|
7
|
-
|
8
|
-
#@uri = resource.post(params).body
|
9
|
-
#LOGGER.debug "VALIDATION URI: " + @uri.to_s
|
10
|
-
call = "curl -X POST "
|
11
|
-
params.each do |k,v|
|
12
|
-
call += " -d "+k.to_s+"=\""+URI.encode(v.to_s)+"\"" unless k == :uri
|
13
|
-
end
|
14
|
-
call += " "+params[:uri]
|
15
|
-
LOGGER.debug call
|
16
|
-
@uri = `#{call}`
|
7
|
+
@uri = OpenTox::RestClientWrapper.post(File.join(@@config[:services]["opentox-validation"],"/crossvalidation"),params,nil,false)
|
17
8
|
end
|
18
9
|
|
19
10
|
def self.crossvalidation(params)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opentox-ruby-api-wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 1.6.
|
9
|
+
- 5
|
10
|
+
version: 1.6.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christoph Helma, Martin Guetlein
|