opentox-client 0.0.1pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/LICENSE +674 -0
- data/README.markdown +17 -0
- data/Rakefile +11 -0
- data/lib/algorithm.rb +15 -0
- data/lib/authorization.rb +392 -0
- data/lib/compound.rb +170 -0
- data/lib/dataset.rb +318 -0
- data/lib/error.rb +106 -0
- data/lib/model.rb +14 -0
- data/lib/opentox-client.rb +32 -0
- data/lib/opentox.rb +145 -0
- data/lib/otlogger.rb +45 -0
- data/lib/overwrite.rb +90 -0
- data/lib/policy.rb +261 -0
- data/lib/rest-client-wrapper.rb +47 -0
- data/lib/task.rb +123 -0
- data/lib/templates/default_guest_policy.xml +53 -0
- data/lib/templates/default_policy.xml +53 -0
- data/opentox-client.gemspec +27 -0
- data/test/compound.rb +52 -0
- data/test/data/CPDBAS_v5c_1547_29Apr2008part.sdf +13553 -0
- data/test/data/EPAFHM.csv +618 -0
- data/test/data/EPAFHM.mini.csv +21 -0
- data/test/data/ISSCAN-multi.csv +59 -0
- data/test/data/cpdb_100.csv +101 -0
- data/test/data/hamster_carcinogenicity.csv +86 -0
- data/test/data/hamster_carcinogenicity.mini.csv +11 -0
- data/test/data/hamster_carcinogenicity.sdf +2805 -0
- data/test/data/hamster_carcinogenicity.xls +0 -0
- data/test/data/hamster_carcinogenicity.yaml +352 -0
- data/test/data/hamster_carcinogenicity_with_errors.csv +88 -0
- data/test/data/kazius.csv +4069 -0
- data/test/data/multi_cell_call.csv +1067 -0
- data/test/data/multicolumn.csv +5 -0
- data/test/dataset.rb +53 -0
- data/test/error.rb +35 -0
- data/test/feature.rb +36 -0
- data/test/task.rb +85 -0
- metadata +144 -0
data/README.markdown
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
opentox-ruby-minimal
|
2
|
+
====================
|
3
|
+
|
4
|
+
Thin Ruby wrapper for the [OpenTox](http://www.opentox.org) REST API
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
gem install opentox-client
|
10
|
+
|
11
|
+
[API documentation](http://rdoc.info/gems/opentox-client)
|
12
|
+
-------------------------------------------------------------------
|
13
|
+
|
14
|
+
Copyright
|
15
|
+
---------
|
16
|
+
|
17
|
+
Copyright (c) 2009-2012 Christoph Helma, Martin Guetlein, Micha Rautenberg, Andreas Maunz, David Vorgrimmler, Denis Gebele. See LICENSE for details.
|
data/Rakefile
ADDED
data/lib/algorithm.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module OpenTox
|
2
|
+
|
3
|
+
# Wrapper for OpenTox Algorithms
|
4
|
+
class Algorithm
|
5
|
+
|
6
|
+
# Execute algorithm with parameters, please consult the OpenTox API and the webservice documentation for acceptable parameters
|
7
|
+
# @param [optional,Hash] params Algorithm parameters
|
8
|
+
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
9
|
+
# @return [String] URI of new resource (dataset, model, ...)
|
10
|
+
def run params=nil
|
11
|
+
post params, {:accept => 'text/uri-list'}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,392 @@
|
|
1
|
+
module OpenTox
|
2
|
+
|
3
|
+
#Module for Authorization and Authentication
|
4
|
+
#@example Authentication
|
5
|
+
# require "opentox-client"
|
6
|
+
# OpenTox::Authorization::AA_SERVER = "https://opensso.in-silico.ch" #if not set in .opentox/conf/[environment].yaml
|
7
|
+
# token = OpenTox::Authorization.authenticate("benutzer", "passwort")
|
8
|
+
#@see http://www.opentox.org/dev/apis/api-1.2/AA OpenTox A&A API 1.2 specification
|
9
|
+
|
10
|
+
module Authorization
|
11
|
+
|
12
|
+
#Helper Class AA to create and send default policies out of xml templates
|
13
|
+
#@example Creating a default policy to a URI
|
14
|
+
# aa=OpenTox::Authorization::AA.new(tok)
|
15
|
+
# xml=aa.get_xml('http://uri....')
|
16
|
+
# OpenTox::Authorization.create_policy(xml,tok)
|
17
|
+
|
18
|
+
class AA
|
19
|
+
attr_accessor :user, :subjectid, :policy
|
20
|
+
|
21
|
+
#Generates AA object - requires subjectid
|
22
|
+
# @param [String] subjectid
|
23
|
+
def initialize(subjectid)
|
24
|
+
@user = Authorization.get_user(subjectid)
|
25
|
+
@subjectid = subjectid
|
26
|
+
@policy = Policies.new()
|
27
|
+
end
|
28
|
+
|
29
|
+
#Cleans AA Policies and loads default xml file into policy attribute
|
30
|
+
#set uri and user, returns Policyfile(XML) for open-sso
|
31
|
+
# @param [String] URI to create a policy for
|
32
|
+
def get_xml(uri)
|
33
|
+
@policy.drop_policies
|
34
|
+
@policy.load_default_policy(@user, uri)
|
35
|
+
return @policy.to_xml
|
36
|
+
end
|
37
|
+
|
38
|
+
#Loads and sends Policyfile(XML) to open-sso server
|
39
|
+
# @param [String] URI to create a policy for
|
40
|
+
def send(uri)
|
41
|
+
xml = get_xml(uri)
|
42
|
+
ret = false
|
43
|
+
ret = Authorization.create_policy(xml, @subjectid)
|
44
|
+
@@logger.debug "Policy send with subjectid: #{@subjectid}"
|
45
|
+
@@logger.warn "Not created Policy is: #{xml}" if !ret
|
46
|
+
ret
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
#Returns the open-sso server set in the config file .opentox/config/[environment].yaml
|
52
|
+
# @return [String, nil] the openSSO server URI or nil
|
53
|
+
def self.server
|
54
|
+
return AA_SERVER
|
55
|
+
end
|
56
|
+
|
57
|
+
#Authentication against OpenSSO. Returns token. Requires Username and Password.
|
58
|
+
# @param [String, String]Username,Password
|
59
|
+
# @return [String, nil] gives subjectid or nil
|
60
|
+
def self.authenticate(user, pw)
|
61
|
+
return nil if !AA_SERVER
|
62
|
+
begin
|
63
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/auth/authenticate")
|
64
|
+
out = resource.post(:username=>user, :password => pw).sub("token.id=","").sub("\n","")
|
65
|
+
return out
|
66
|
+
rescue
|
67
|
+
return nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#Logout on opensso. Make token invalid. Requires token
|
72
|
+
# @param [String]subjectid the subjectid
|
73
|
+
# @return [Boolean] true if logout is OK
|
74
|
+
def self.logout(subjectid)
|
75
|
+
begin
|
76
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/auth/logout")
|
77
|
+
resource.post(:subjectid => subjectid)
|
78
|
+
return true
|
79
|
+
rescue
|
80
|
+
return false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
#Authorization against OpenSSO for a URI with request-method (action) [GET/POST/PUT/DELETE]
|
85
|
+
# @param [String,String,String]uri,action,subjectid
|
86
|
+
# @return [Boolean, nil] returns true, false or nil (if authorization-request fails).
|
87
|
+
def self.authorize(uri, action, subjectid)
|
88
|
+
return true if !AA_SERVER
|
89
|
+
begin
|
90
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/auth/authorize")
|
91
|
+
return true if resource.post(:uri => uri, :action => action, :subjectid => subjectid) == "boolean=true\n"
|
92
|
+
rescue
|
93
|
+
return nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#Checks if a token is a valid token
|
98
|
+
# @param [String]subjectid subjectid from openSSO session
|
99
|
+
# @return [Boolean] subjectid is valid or not.
|
100
|
+
def self.is_token_valid(subjectid)
|
101
|
+
return true if !AA_SERVER
|
102
|
+
begin
|
103
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/auth/isTokenValid")
|
104
|
+
return true if resource.post(:tokenid => subjectid) == "boolean=true\n"
|
105
|
+
rescue
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#Returns array with all policies of the token owner
|
111
|
+
# @param [String]subjectid requires subjectid
|
112
|
+
# @return [Array, nil] returns an Array of policy names or nil if request fails
|
113
|
+
def self.list_policies(subjectid)
|
114
|
+
begin
|
115
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/pol")
|
116
|
+
out = resource.get(:subjectid => subjectid)
|
117
|
+
return out.split("\n")
|
118
|
+
rescue RestClient::InternalServerError => e
|
119
|
+
raise e.response
|
120
|
+
rescue
|
121
|
+
return nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#Returns a policy in xml-format
|
126
|
+
# @param [String, String]policy,subjectid
|
127
|
+
# @return [String] XML of the policy
|
128
|
+
def self.list_policy(policy, subjectid)
|
129
|
+
begin
|
130
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/pol")
|
131
|
+
return resource.get(:subjectid => subjectid,:id => policy)
|
132
|
+
rescue
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Lists policies alongside with affected uris
|
138
|
+
# @param [String] subjectid
|
139
|
+
# @return [Hash] keys: all policies of the subjectid owner, values: uris affected by those policies
|
140
|
+
def self.list_policies_uris( subjectid )
|
141
|
+
names = list_policies(subjectid)
|
142
|
+
policies = {}
|
143
|
+
names.each do |n|
|
144
|
+
policies[n] = list_policy_uris( n, subjectid )
|
145
|
+
end
|
146
|
+
policies
|
147
|
+
end
|
148
|
+
|
149
|
+
# Lists policies alongside with affected uris
|
150
|
+
# @param [String] subjectid
|
151
|
+
# @return [Hash] keys: all policies of the subjectid owner, values: uris affected by those policies
|
152
|
+
def self.list_policy_uris( policy, subjectid )
|
153
|
+
p = OpenTox::Policies.new
|
154
|
+
p.load_xml( list_policy(policy, subjectid) )
|
155
|
+
p.uris
|
156
|
+
end
|
157
|
+
|
158
|
+
#Returns the owner (who created the first policy) of an URI
|
159
|
+
# @param [String, String]uri,subjectid
|
160
|
+
# return [String, nil]owner,nil returns owner of the URI
|
161
|
+
def self.get_uri_owner(uri, subjectid)
|
162
|
+
begin
|
163
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/pol")
|
164
|
+
return resource.get(:uri => uri, :subjectid => subjectid).sub("\n","")
|
165
|
+
rescue
|
166
|
+
return nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
#Checks if a policy exists to a URI. Requires URI and token.
|
171
|
+
# @param [String, String]uri,subjectid
|
172
|
+
# return [Boolean]
|
173
|
+
def self.uri_has_policy(uri, subjectid)
|
174
|
+
owner = get_uri_owner(uri, subjectid)
|
175
|
+
return true if owner and owner != "null"
|
176
|
+
false
|
177
|
+
end
|
178
|
+
|
179
|
+
#List all policynames for a URI. Requires URI and token.
|
180
|
+
# @param [String, String]uri,subjectid
|
181
|
+
# return [Array, nil] returns an Array of policy names or nil if request fails
|
182
|
+
def self.list_uri_policies(uri, subjectid)
|
183
|
+
begin
|
184
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/pol")
|
185
|
+
out = resource.get(:uri => uri, :polnames => true, :subjectid => subjectid)
|
186
|
+
policies = []; notfirstline = false
|
187
|
+
out.split("\n").each do |line|
|
188
|
+
policies << line if notfirstline
|
189
|
+
notfirstline = true
|
190
|
+
end
|
191
|
+
return policies
|
192
|
+
rescue
|
193
|
+
return nil
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
#Sends a policy in xml-format to opensso server. Requires policy-xml and token.
|
198
|
+
# @param [String, String]policyxml,subjectid
|
199
|
+
# return [Boolean] returns true if policy is created
|
200
|
+
def self.create_policy(policy, subjectid)
|
201
|
+
begin
|
202
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/Pol/opensso-pol")
|
203
|
+
@@logger.debug "OpenTox::Authorization.create_policy policy: #{policy[168,43]} with token:" + subjectid.to_s + " length: " + subjectid.length.to_s
|
204
|
+
return true if resource.post(policy, :subjectid => subjectid, :content_type => "application/xml")
|
205
|
+
rescue
|
206
|
+
return false
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
#Deletes a policy
|
211
|
+
# @param [String, String]policyname,subjectid
|
212
|
+
# @return [Boolean,nil]
|
213
|
+
def self.delete_policy(policy, subjectid)
|
214
|
+
begin
|
215
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/pol")
|
216
|
+
@@logger.debug "OpenTox::Authorization.delete_policy policy: #{policy} with token: #{subjectid}"
|
217
|
+
return true if resource.delete(:subjectid => subjectid, :id => policy)
|
218
|
+
rescue
|
219
|
+
return nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
#Returns array of all possible LDAP-Groups
|
224
|
+
# @param [String]subjectid
|
225
|
+
# @return [Array]
|
226
|
+
def self.list_groups(subjectid)
|
227
|
+
begin
|
228
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/search")
|
229
|
+
grps = resource.post(:admin => subjectid, :attributes_names => "objecttype", :attributes_values_objecttype => "group")
|
230
|
+
grps = grps.split("\n").collect{|x| x.sub("string=","")}
|
231
|
+
grps.delete_if{|g|g=="MemberManagement"||g=="Webmasters"}
|
232
|
+
grps
|
233
|
+
rescue
|
234
|
+
[]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
#Returns array of the LDAP-Groups of an user
|
239
|
+
# @param [String]subjectid
|
240
|
+
# @return [Array] gives array of LDAP groups of a user
|
241
|
+
def self.list_user_groups(user, subjectid)
|
242
|
+
begin
|
243
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/read")
|
244
|
+
out = resource.post(:name => user, :admin => subjectid, :attributes_names => "group")
|
245
|
+
grps = []
|
246
|
+
out.split("\n").each do |line|
|
247
|
+
grps << line.sub("identitydetails.group=","") if line.include?("identitydetails.group=")
|
248
|
+
end
|
249
|
+
return grps
|
250
|
+
rescue
|
251
|
+
[]
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
#Returns the owner (user id) of a token
|
256
|
+
# @param [String]subjectid
|
257
|
+
# @return [String]user
|
258
|
+
def self.get_user(subjectid)
|
259
|
+
begin
|
260
|
+
resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/attributes")
|
261
|
+
out = resource.post(:subjectid => subjectid, :attributes_names => "uid")
|
262
|
+
user = ""; check = false
|
263
|
+
out.split("\n").each do |line|
|
264
|
+
if check
|
265
|
+
user = line.sub("userdetails.attribute.value=","") if line.include?("userdetails.attribute.value=")
|
266
|
+
check = false
|
267
|
+
end
|
268
|
+
check = true if line.include?("userdetails.attribute.name=uid")
|
269
|
+
end
|
270
|
+
return user
|
271
|
+
rescue
|
272
|
+
nil
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
#Send default policy with Authorization::AA class
|
277
|
+
# @param [String, String]URI,subjectid
|
278
|
+
def self.send_policy(uri, subjectid)
|
279
|
+
return true if !AA_SERVER
|
280
|
+
aa = Authorization::AA.new(subjectid)
|
281
|
+
ret = aa.send(uri)
|
282
|
+
@@logger.debug "OpenTox::Authorization send policy for URI: #{uri} | subjectid: #{subjectid} - policy created: #{ret}"
|
283
|
+
ret
|
284
|
+
end
|
285
|
+
|
286
|
+
#Deletes all policies of an URI
|
287
|
+
# @param [String, String]URI,subjectid
|
288
|
+
# @return [Boolean]
|
289
|
+
def self.delete_policies_from_uri(uri, subjectid)
|
290
|
+
policies = list_uri_policies(uri, subjectid)
|
291
|
+
if policies
|
292
|
+
policies.each do |policy|
|
293
|
+
ret = delete_policy(policy, subjectid)
|
294
|
+
@@logger.debug "OpenTox::Authorization delete policy: #{policy} - with result: #{ret}"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
return true
|
298
|
+
end
|
299
|
+
|
300
|
+
# Checks (if subjectid is valid) if a policy exist and create default policy if not
|
301
|
+
# @param [String] uri
|
302
|
+
# @param [String] subjectid
|
303
|
+
# @return [Boolean] true if policy checked/created successfully (or no uri/subjectid given), false else
|
304
|
+
def self.check_policy(uri, subjectid)
|
305
|
+
return true unless uri and subjectid
|
306
|
+
token_valid = OpenTox::Authorization.is_token_valid(subjectid)
|
307
|
+
@@logger.debug "OpenTox::Authorization.check_policy with uri: #{uri}, subjectid: #{subjectid} is valid: #{token_valid}"
|
308
|
+
# check if subjectid is valid
|
309
|
+
unless token_valid
|
310
|
+
# abort if invalid
|
311
|
+
@@logger.error "OpenTox::Authorization.check_policy, subjectid NOT valid: #{subjectid}"
|
312
|
+
return false
|
313
|
+
end
|
314
|
+
|
315
|
+
if !uri_has_policy(uri, subjectid)
|
316
|
+
# if no policy exists, create a policy, return result of send policy
|
317
|
+
send_policy(uri, subjectid)
|
318
|
+
else
|
319
|
+
# if policy exists check for POST rights
|
320
|
+
if authorize(uri, "POST", subjectid)
|
321
|
+
true
|
322
|
+
else
|
323
|
+
@@logger.error "OpenTox::Authorization.check_policy, already exists, but no POST-authorization with subjectid: #{subjectid}"
|
324
|
+
false
|
325
|
+
end
|
326
|
+
end
|
327
|
+
true
|
328
|
+
end
|
329
|
+
|
330
|
+
class << self
|
331
|
+
alias :token_valid? :is_token_valid
|
332
|
+
end
|
333
|
+
|
334
|
+
# Check Authorization for a resource (identified via URI) with method and subjectid.
|
335
|
+
# @param [String] uri
|
336
|
+
# @param [String] request_method, should be GET, POST, PUT, DELETE
|
337
|
+
# @param [String] subjectid
|
338
|
+
# @return [Boolean] true if access granted, else otherwise
|
339
|
+
def self.authorized?(uri, request_method, subjectid)
|
340
|
+
if CONFIG[:authorization][:free_request].include?(request_method)
|
341
|
+
#@@logger.debug "authorized? >>true<< (request is free), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
342
|
+
true
|
343
|
+
elsif OpenTox::Authorization.free_uri?(uri, request_method)
|
344
|
+
#@@logger.debug "authorized? >>true<< (uris is free_uri), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
345
|
+
true
|
346
|
+
elsif CONFIG[:authorization][:authenticate_request].include?(request_method)
|
347
|
+
ret = OpenTox::Authorization.is_token_valid(subjectid)
|
348
|
+
@@logger.debug "authorized? >>#{ret}<< (token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
349
|
+
ret
|
350
|
+
elsif OpenTox::Authorization.authorize_exception?(uri, request_method)
|
351
|
+
ret = OpenTox::Authorization.is_token_valid(subjectid)
|
352
|
+
@@logger.debug "authorized? >>#{ret}<< (uris is authorize exception, token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
353
|
+
ret
|
354
|
+
elsif CONFIG[:authorization][:authorize_request].include?(request_method)
|
355
|
+
ret = OpenTox::Authorization.authorize(uri, request_method, subjectid)
|
356
|
+
@@logger.debug "authorized? >>#{ret}<< (uri (not) authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
357
|
+
ret
|
358
|
+
else
|
359
|
+
@@logger.error "invalid request/uri method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
360
|
+
false
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
private
|
365
|
+
def self.free_uri?(uri, request_method)
|
366
|
+
if CONFIG[:authorization][:free_uris]
|
367
|
+
CONFIG[:authorization][:free_uris].each do |request_methods,uris|
|
368
|
+
if request_methods and uris and request_methods.include?(request_method.to_sym)
|
369
|
+
uris.each do |u|
|
370
|
+
return true if u.match uri
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
return false
|
376
|
+
end
|
377
|
+
|
378
|
+
def self.authorize_exception?(uri, request_method)
|
379
|
+
if CONFIG[:authorization][:authorize_exceptions]
|
380
|
+
CONFIG[:authorization][:authorize_exceptions].each do |request_methods,uris|
|
381
|
+
if request_methods and uris and request_methods.include?(request_method.to_sym)
|
382
|
+
uris.each do |u|
|
383
|
+
return true if u.match uri
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
return false
|
389
|
+
end
|
390
|
+
|
391
|
+
end
|
392
|
+
end
|
data/lib/compound.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
CACTUS_URI="http://cactus.nci.nih.gov/chemical/structure/"
|
2
|
+
|
3
|
+
module OpenTox
|
4
|
+
|
5
|
+
# Ruby wrapper for OpenTox Compound Webservices (http://opentox.org/dev/apis/api-1.2/structure).
|
6
|
+
class Compound
|
7
|
+
|
8
|
+
# Create a compound from smiles string
|
9
|
+
# @example
|
10
|
+
# compound = OpenTox::Compound.from_smiles("c1ccccc1")
|
11
|
+
# @param [String] smiles Smiles string
|
12
|
+
# @return [OpenTox::Compound] Compound
|
13
|
+
def self.from_smiles service_uri, smiles, subjectid=nil
|
14
|
+
Compound.new RestClientWrapper.post(service_uri, smiles, {:content_type => 'chemical/x-daylight-smiles', :subjectid => subjectid})
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create a compound from inchi string
|
18
|
+
# @param [String] smiles InChI string
|
19
|
+
# @return [OpenTox::Compound] Compound
|
20
|
+
def self.from_inchi service_uri, inchi, subjectid=nil
|
21
|
+
Compound.new RestClientWrapper.post(service_uri, inchi, {:content_type => 'chemical/x-inchi', :subjectid => subjectid})
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create a compound from sdf string
|
25
|
+
# @param [String] smiles SDF string
|
26
|
+
# @return [OpenTox::Compound] Compound
|
27
|
+
def self.from_sdf service_uri, sdf, subjectid=nil
|
28
|
+
Compound.new RestClientWrapper.post(service_uri, sdf, {:content_type => 'chemical/x-mdl-sdfile', :subjectid => subjectid})
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a compound from name. Relies on an external service for name lookups.
|
32
|
+
# @example
|
33
|
+
# compound = OpenTox::Compound.from_name("Benzene")
|
34
|
+
# @param [String] name name can be also an InChI/InChiKey, CAS number, etc
|
35
|
+
# @return [OpenTox::Compound] Compound
|
36
|
+
def self.from_name service_uri, name, subjectid=nil
|
37
|
+
Compound.new RestClientWrapper.post(service_uri, name, {:content_type => 'text/plain', :subjectid => subjectid})
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get InChI
|
41
|
+
# @return [String] InChI string
|
42
|
+
def to_inchi
|
43
|
+
get(:accept => 'chemical/x-inchi').to_s.chomp if @uri
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get (canonical) smiles
|
47
|
+
# @return [String] Smiles string
|
48
|
+
def to_smiles
|
49
|
+
get(:accept => 'chemical/x-daylight-smiles').chomp
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get sdf
|
53
|
+
# @return [String] SDF string
|
54
|
+
def to_sdf
|
55
|
+
get(:accept => 'chemical/x-mdl-sdfile').chomp
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get gif image
|
59
|
+
# @return [image/gif] Image data
|
60
|
+
def to_gif
|
61
|
+
get("#{CACTUS_URI}#{to_inchi}/image")
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get png image
|
65
|
+
# @example
|
66
|
+
# image = compound.to_png
|
67
|
+
# @return [image/png] Image data
|
68
|
+
def to_png
|
69
|
+
get(File.join @uri, "image")
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get URI of compound image
|
73
|
+
# @return [String] Compound image URI
|
74
|
+
def to_image_uri
|
75
|
+
File.join @uri, "image"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get all known compound names. Relies on an external service for name lookups.
|
79
|
+
# @example
|
80
|
+
# names = compound.to_names
|
81
|
+
# @return [String] Compound names
|
82
|
+
def to_names
|
83
|
+
begin
|
84
|
+
get("#{CACTUS_URI}#{to_inchi}/names").split("\n")
|
85
|
+
rescue
|
86
|
+
"not available"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
=begin
|
91
|
+
# Match a smarts string
|
92
|
+
# @example
|
93
|
+
# compound = OpenTox::Compound.from_name("Benzene")
|
94
|
+
# compound.match?("cN") # returns false
|
95
|
+
# @param [String] smarts Smarts string
|
96
|
+
def match?(smarts)
|
97
|
+
obconversion = OpenBabel::OBConversion.new
|
98
|
+
obmol = OpenBabel::OBMol.new
|
99
|
+
obconversion.set_in_format('inchi')
|
100
|
+
obconversion.read_string(obmol,@inchi)
|
101
|
+
smarts_pattern = OpenBabel::OBSmartsPattern.new
|
102
|
+
smarts_pattern.init(smarts)
|
103
|
+
smarts_pattern.match(obmol)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Match an array of smarts strings, returns array with matching smarts
|
107
|
+
# @example
|
108
|
+
# compound = OpenTox::Compound.from_name("Benzene")
|
109
|
+
# compound.match(['cc','cN']) # returns ['cc']
|
110
|
+
# @param [Array] smarts_array Array with Smarts strings
|
111
|
+
# @return [Array] Array with matching Smarts strings
|
112
|
+
def match(smarts_array)
|
113
|
+
# avoid recreation of OpenBabel objects
|
114
|
+
obconversion = OpenBabel::OBConversion.new
|
115
|
+
obmol = OpenBabel::OBMol.new
|
116
|
+
obconversion.set_in_format('inchi')
|
117
|
+
obconversion.read_string(obmol,@inchi)
|
118
|
+
smarts_pattern = OpenBabel::OBSmartsPattern.new
|
119
|
+
smarts_array.collect do |smarts|
|
120
|
+
smarts_pattern.init(smarts)
|
121
|
+
smarts if smarts_pattern.match(obmol)
|
122
|
+
end.compact
|
123
|
+
#smarts_array.collect { |s| s if match?(s)}.compact
|
124
|
+
end
|
125
|
+
|
126
|
+
# Get URI of compound image with highlighted fragments
|
127
|
+
#
|
128
|
+
# @param [Array] activating Array with activating Smarts strings
|
129
|
+
# @param [Array] deactivating Array with deactivating Smarts strings
|
130
|
+
# @return [String] URI for compound image with highlighted fragments
|
131
|
+
def matching_smarts_image_uri(activating, deactivating)
|
132
|
+
activating_smarts = URI.encode "\"#{activating.join("\"/\"")}\""
|
133
|
+
deactivating_smarts = URI.encode "\"#{deactivating.join("\"/\"")}\""
|
134
|
+
File.join @uri, "smarts/activating", URI.encode(activating_smarts),"deactivating", URI.encode(deactivating_smarts)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# Convert sdf to inchi
|
141
|
+
def self.sdf2inchi(sdf)
|
142
|
+
Compound.obconversion(sdf,'sdf','inchi')
|
143
|
+
end
|
144
|
+
|
145
|
+
# Convert smiles to inchi
|
146
|
+
def self.smiles2inchi(smiles)
|
147
|
+
Compound.obconversion(smiles,'smi','inchi')
|
148
|
+
end
|
149
|
+
|
150
|
+
# Convert smiles to canonical smiles
|
151
|
+
def self.smiles2cansmi(smiles)
|
152
|
+
Compound.obconversion(smiles,'smi','can')
|
153
|
+
end
|
154
|
+
|
155
|
+
# Convert identifier from OpenBabel input_format to OpenBabel output_format
|
156
|
+
def self.obconversion(identifier,input_format,output_format)
|
157
|
+
obconversion = OpenBabel::OBConversion.new
|
158
|
+
obmol = OpenBabel::OBMol.new
|
159
|
+
obconversion.set_in_and_out_formats input_format, output_format
|
160
|
+
obconversion.read_string obmol, identifier
|
161
|
+
case output_format
|
162
|
+
when /smi|can|inchi/
|
163
|
+
obconversion.write_string(obmol).gsub(/\s/,'').chomp
|
164
|
+
else
|
165
|
+
obconversion.write_string(obmol)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
=end
|
169
|
+
end
|
170
|
+
end
|