summaryrefslogtreecommitdiff
path: root/lib/compound.rb
blob: 49c166f1719b955836ee7747b08adcf87d5eb192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@@cactus_uri="http://cactus.nci.nih.gov/chemical/structure/"
@@ambit_uri="http://ambit.uni-plovdiv.bg:8080/ambit2/depict/cdk?search="

module OpenTox

	class Compound #< OpenTox

		attr_reader :inchi, :uri

		# 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)
		def initialize(params)
			if params[:smiles]
				@inchi = smiles2inchi(params[:smiles])
				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
			elsif params[:inchi]
				@inchi = params[:inchi]
				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
			elsif params[:sdf]
				@inchi = sdf2inchi(params[:sdf])
				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
			elsif params[:name]
				# paranoid URI encoding to keep SMILES charges and brackets
				@inchi = RestClient.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").body.chomp
				# this was too hard for me to debug and leads to additional errors (ch)
				#@inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").chomp
				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
			elsif params[:uri]
				@uri = params[:uri]
				case params[:uri]
				when /ambit/ # Ambit does not deliver InChIs reliably
					smiles = RestClientWrapper.get @uri, :accept => 'chemical/x-daylight-smiles'
					@inchi = obconversion(smiles,'smi','inchi')
				when /InChI/ # shortcut for IST services
					@inchi = params[:uri].sub(/^.*InChI/, 'InChI')
				else
					@inchi = RestClientWrapper.get @uri, :accept => 'chemical/x-inchi'
				end
			end
		end

		# Get the (canonical) smiles
		def smiles
			obconversion(@inchi,'inchi','can')
		end

		def sdf
			obconversion(@inchi,'inchi','sdf')
		end

		def gif
			RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/image")
		end

		def png
      RestClientWrapper.get(File.join @uri, "image")
		end

		def names
      begin
        RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/names")
      rescue
        "not available"
      end
		end

    def display_smarts_uri(activating, deactivating, highlight = nil)
      LOGGER.debug activating.to_yaml unless activating.nil?
      activating_smarts = URI.encode "\"#{activating.join("\"/\"")}\""
      deactivating_smarts = URI.encode "\"#{deactivating.join("\"/\"")}\""
      if highlight.nil?
        File.join @@config[:services]["opentox-compound"], "smiles", URI.encode(smiles), "smarts/activating", URI.encode(activating_smarts),"deactivating", URI.encode(deactivating_smarts)
      else
        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)
      end
    end

		def image_uri
      File.join @uri, "image"
		end

		# Matchs a smarts string
		def match?(smarts)
			obconversion = OpenBabel::OBConversion.new
			obmol = OpenBabel::OBMol.new
			obconversion.set_in_format('inchi')
			obconversion.read_string(obmol,@inchi) 
			smarts_pattern = OpenBabel::OBSmartsPattern.new
			smarts_pattern.init(smarts)
			smarts_pattern.match(obmol)
		end

		# Match an array of smarts features, returns matching features
		def match(smarts_array)
			smarts_array.collect{|s| s if match?(s)}.compact
		end

		# AM
		# Match an array of smarts features, returns (0)1 for (non)matching features at each pos
		def match_all(smarts_array)
			smarts_array.collect{|s| match?(s) ? 1 : 0 }
		end

		def sdf2inchi(sdf)
			obconversion(sdf,'sdf','inchi')
		end

		def smiles2inchi(smiles)
			obconversion(smiles,'smi','inchi')
		end

		def smiles2cansmi(smiles)
			obconversion(smiles,'smi','can')
		end

		def obconversion(identifier,input_format,output_format)
			obconversion = OpenBabel::OBConversion.new
			obmol = OpenBabel::OBMol.new
			obconversion.set_in_and_out_formats input_format, output_format
			obconversion.read_string obmol, identifier
			case output_format
			when /smi|can|inchi/
				obconversion.write_string(obmol).gsub(/\s/,'').chomp
			else
				obconversion.write_string(obmol)
			end
		end
	end
end