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/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
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__),"lib","opentox-client.rb")
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib'
7
+ t.libs << 'test'
8
+ t.test_files = FileList['test/*.rb']
9
+ t.verbose = true
10
+ end
11
+
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