opentox-ruby 0.0.1 → 0.0.2

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/lib/compound.rb CHANGED
@@ -3,82 +3,120 @@
3
3
 
4
4
  module OpenTox
5
5
 
6
- class Compound #< OpenTox
7
-
8
- attr_reader :inchi, :uri
9
-
10
- # Initialize with <tt>:uri => uri</tt>, <tt>:smiles => smiles</tt> or <tt>:name => name</tt> (name can be also an InChI/InChiKey, CAS number, etc)
11
- def initialize(params)
12
- if params[:smiles]
13
- @inchi = smiles2inchi(params[:smiles])
14
- @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
15
- elsif params[:inchi]
16
- @inchi = params[:inchi]
17
- @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
18
- elsif params[:sdf]
19
- @inchi = sdf2inchi(params[:sdf])
20
- @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
21
- elsif params[:name]
22
- # paranoid URI encoding to keep SMILES charges and brackets
23
- @inchi = RestClient.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").body.chomp
24
- # this was too hard for me to debug and leads to additional errors (ch)
25
- #@inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").chomp
26
- @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
27
- elsif params[:uri]
28
- @uri = params[:uri]
29
- case params[:uri]
30
- when /ambit/ # Ambit does not deliver InChIs reliably
31
- smiles = RestClientWrapper.get @uri, :accept => 'chemical/x-daylight-smiles'
32
- @inchi = obconversion(smiles,'smi','inchi')
33
- when /InChI/ # shortcut for IST services
34
- @inchi = params[:uri].sub(/^.*InChI/, 'InChI')
35
- else
36
- @inchi = RestClientWrapper.get @uri, :accept => 'chemical/x-inchi'
37
- end
38
- end
39
- end
6
+ # Ruby wrapper for OpenTox Compound Webservices (http://opentox.org/dev/apis/api-1.2/structure).
7
+ class Compound
8
+
9
+ attr_accessor :inchi, :uri
10
+
11
+ # Create compound with optional uri
12
+ # @example
13
+ # compound = OpenTox::Compound.new("http://webservices.in-silico.ch/compound/InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H"")
14
+ # @param [optional, String] uri Compound URI
15
+ # @return [OpenTox::Compound] Compound
16
+ def initialize(uri=nil)
17
+ @uri = uri
18
+ case @uri
19
+ when /InChI/ # shortcut for IST services
20
+ @inchi = @uri.sub(/^.*InChI/, 'InChI')
21
+ else
22
+ @inchi = RestClientWrapper.get(@uri, :accept => 'chemical/x-inchi').to_s.chomp if @uri
23
+ end
24
+ end
25
+
26
+ # Create a compound from smiles string
27
+ # @example
28
+ # compound = OpenTox::Compound.from_smiles("c1ccccc1")
29
+ # @param [String] smiles Smiles string
30
+ # @return [OpenTox::Compound] Compound
31
+ def self.from_smiles(smiles)
32
+ c = Compound.new
33
+ c.inchi = Compound.smiles2inchi(smiles)
34
+ c.uri = File.join(CONFIG[:services]["opentox-compound"],URI.escape(c.inchi))
35
+ c
36
+ end
37
+
38
+ # Create a compound from inchi string
39
+ # @param [String] smiles InChI string
40
+ # @return [OpenTox::Compound] Compound
41
+ def self.from_inchi(inchi)
42
+ c = Compound.new
43
+ c.inchi = inchi
44
+ c.uri = File.join(CONFIG[:services]["opentox-compound"],URI.escape(c.inchi))
45
+ c
46
+ end
40
47
 
41
- # Get the (canonical) smiles
42
- def smiles
43
- obconversion(@inchi,'inchi','can')
48
+ # Create a compound from sdf string
49
+ # @param [String] smiles SDF string
50
+ # @return [OpenTox::Compound] Compound
51
+ def self.from_sdf(sdf)
52
+ c = Compound.new
53
+ c.inchi = Compound.sdf2inchi(sdf)
54
+ c.uri = File.join(CONFIG[:services]["opentox-compound"],URI.escape(c.inchi))
55
+ c
56
+ end
57
+
58
+ # Create a compound from name. Relies on an external service for name lookups.
59
+ # @example
60
+ # compound = OpenTox::Compound.from_name("Benzene")
61
+ # @param [String] name name can be also an InChI/InChiKey, CAS number, etc
62
+ # @return [OpenTox::Compound] Compound
63
+ def self.from_name(name)
64
+ c = Compound.new
65
+ # paranoid URI encoding to keep SMILES charges and brackets
66
+ c.inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(name, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").to_s.chomp
67
+ c.uri = File.join(CONFIG[:services]["opentox-compound"],URI.escape(c.inchi))
68
+ c
69
+ end
70
+
71
+ # Get (canonical) smiles
72
+ # @return [String] Smiles string
73
+ def to_smiles
74
+ Compound.obconversion(@inchi,'inchi','can')
44
75
  end
45
76
 
46
- def sdf
47
- obconversion(@inchi,'inchi','sdf')
77
+ # Get sdf
78
+ # @return [String] SDF string
79
+ def to_sdf
80
+ Compound.obconversion(@inchi,'inchi','sdf')
48
81
  end
49
82
 
50
- def gif
83
+ # Get gif image
84
+ # @return [image/gif] Image data
85
+ def to_gif
51
86
  RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/image")
52
87
  end
53
88
 
54
- def png
89
+ # Get png image
90
+ # @example
91
+ # image = compound.to_png
92
+ # @return [image/png] Image data
93
+ def to_png
55
94
  RestClientWrapper.get(File.join @uri, "image")
56
95
  end
57
96
 
58
- def names
97
+ # Get URI of compound image
98
+ # @return [String] Compound image URI
99
+ def to_image_uri
100
+ File.join @uri, "image"
101
+ end
102
+
103
+ # Get all known compound names. Relies on an external service for name lookups.
104
+ # @example
105
+ # names = compound.to_names
106
+ # @return [String] Compound names
107
+ def to_names
59
108
  begin
60
- RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/names")
109
+ RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/names").split("\n")
61
110
  rescue
62
111
  "not available"
63
112
  end
64
113
  end
65
114
 
66
- def display_smarts_uri(activating, deactivating, highlight = nil)
67
- LOGGER.debug activating.to_yaml unless activating.nil?
68
- activating_smarts = URI.encode "\"#{activating.join("\"/\"")}\""
69
- deactivating_smarts = URI.encode "\"#{deactivating.join("\"/\"")}\""
70
- if highlight.nil?
71
- File.join @@config[:services]["opentox-compound"], "smiles", URI.encode(smiles), "smarts/activating", URI.encode(activating_smarts),"deactivating", URI.encode(deactivating_smarts)
72
- else
73
- File.join @@config[:services]["opentox-compound"], "smiles", URI.encode(smiles), "smarts/activating", URI.encode(activating_smarts),"deactivating", URI.encode(deactivating_smarts), "highlight", URI.encode(highlight)
74
- end
75
- end
76
-
77
- def image_uri
78
- File.join @uri, "image"
79
- end
80
-
81
- # Matchs a smarts string
115
+ # Match a smarts string
116
+ # @example
117
+ # compound = OpenTox::Compound.from_name("Benzene")
118
+ # compound.match?("cN") # returns false
119
+ # @param [String] smarts Smarts string
82
120
  def match?(smarts)
83
121
  obconversion = OpenBabel::OBConversion.new
84
122
  obmol = OpenBabel::OBMol.new
@@ -89,30 +127,57 @@ module OpenTox
89
127
  smarts_pattern.match(obmol)
90
128
  end
91
129
 
92
- # Match an array of smarts features, returns matching features
130
+ # Match an array of smarts strings, returns array with matching smarts
131
+ # @example
132
+ # compound = OpenTox::Compound.from_name("Benzene")
133
+ # compound.match(['cc','cN']) # returns ['cc']
134
+ # @param [Array] smarts_array Array with Smarts strings
135
+ # @return [Array] Array with matching Smarts strings
93
136
  def match(smarts_array)
94
- smarts_array.collect{|s| s if match?(s)}.compact
137
+ # avoid recreation of OpenBabel objects
138
+ obconversion = OpenBabel::OBConversion.new
139
+ obmol = OpenBabel::OBMol.new
140
+ obconversion.set_in_format('inchi')
141
+ obconversion.read_string(obmol,@inchi)
142
+ smarts_pattern = OpenBabel::OBSmartsPattern.new
143
+ smarts_array.collect do |smarts|
144
+ smarts_pattern.init(smarts)
145
+ smarts if smarts_pattern.match(obmol)
146
+ end.compact
147
+ #smarts_array.collect { |s| s if match?(s)}.compact
95
148
  end
96
149
 
97
- # AM
98
- # Match an array of smarts features, returns (0)1 for (non)matching features at each pos
99
- def match_all(smarts_array)
100
- smarts_array.collect{|s| match?(s) ? 1 : 0 }
101
- end
150
+ # Get URI of compound image with highlighted fragments
151
+ #
152
+ # @param [Array] activating Array with activating Smarts strings
153
+ # @param [Array] deactivating Array with deactivating Smarts strings
154
+ # @return [String] URI for compound image with highlighted fragments
155
+ def matching_smarts_image_uri(activating, deactivating)
156
+ activating_smarts = URI.encode "\"#{activating.join("\"/\"")}\""
157
+ deactivating_smarts = URI.encode "\"#{deactivating.join("\"/\"")}\""
158
+ File.join @uri, "smarts/activating", URI.encode(activating_smarts),"deactivating", URI.encode(deactivating_smarts)
159
+ end
160
+
161
+
162
+ private
102
163
 
103
- def sdf2inchi(sdf)
104
- obconversion(sdf,'sdf','inchi')
164
+ # Convert sdf to inchi
165
+ def self.sdf2inchi(sdf)
166
+ Compound.obconversion(sdf,'sdf','inchi')
105
167
  end
106
168
 
107
- def smiles2inchi(smiles)
108
- obconversion(smiles,'smi','inchi')
169
+ # Convert smiles to inchi
170
+ def self.smiles2inchi(smiles)
171
+ Compound.obconversion(smiles,'smi','inchi')
109
172
  end
110
173
 
111
- def smiles2cansmi(smiles)
112
- obconversion(smiles,'smi','can')
174
+ # Convert smiles to canonical smiles
175
+ def self.smiles2cansmi(smiles)
176
+ Compound.obconversion(smiles,'smi','can')
113
177
  end
114
178
 
115
- def obconversion(identifier,input_format,output_format)
179
+ # Convert identifier from OpenBabel input_format to OpenBabel output_format
180
+ def self.obconversion(identifier,input_format,output_format)
116
181
  obconversion = OpenBabel::OBConversion.new
117
182
  obmol = OpenBabel::OBMol.new
118
183
  obconversion.set_in_and_out_formats input_format, output_format