opentox-ruby 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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