opentox-client 0.0.1pre
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/.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
|