From ac54997dccc571471a0cdf62939e2fcbc42e06e2 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Fri, 13 Jan 2012 12:49:09 +0100 Subject: compound added --- lib/compound.rb | 39 +++++++-------------------- lib/opentox-ruby-minimal.rb | 2 ++ lib/opentox.rb | 64 +++++++++++++++++++++++++++------------------ test/all.rb | 9 ++++--- test/compound.rb | 53 +++++++++++++++++++++++++++++++++++++ test/ruby-api.rb | 17 ++++++++++++ 6 files changed, 126 insertions(+), 58 deletions(-) create mode 100644 lib/opentox-ruby-minimal.rb create mode 100644 test/compound.rb create mode 100644 test/ruby-api.rb diff --git a/lib/compound.rb b/lib/compound.rb index 189db7b..974e46e 100644 --- a/lib/compound.rb +++ b/lib/compound.rb @@ -6,44 +6,27 @@ module OpenTox # Ruby wrapper for OpenTox Compound Webservices (http://opentox.org/dev/apis/api-1.2/structure). class Compound - attr_accessor :inchi, :uri - - # Create compound with optional uri - # @example - # compound = OpenTox::Compound.new("http://webservices.in-silico.ch/compound/InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H"") - # @param [optional, String] uri Compound URI - # @return [OpenTox::Compound] Compound - def initialize(uri=nil) - @uri = uri - case @uri - when /InChI/ # shortcut for IST services - @inchi = @uri.sub(/^.*InChI/, 'InChI') - else - @inchi = RestClientWrapper.get(@uri, :accept => 'chemical/x-inchi').to_s.chomp if @uri - end - end - # Create a compound from smiles string # @example # compound = OpenTox::Compound.from_smiles("c1ccccc1") # @param [String] smiles Smiles string # @return [OpenTox::Compound] Compound - def self.from_smiles(smiles) - Compound.new RestClientWrapper.post(CONFIG[:services]["opentox-compound"], smiles, :content_type => 'chemical/x-daylight-smiles').to_s.chomp + def self.from_smiles service_uri, smiles, subjectid=nil + Compound.new RestClientWrapper.post(service_uri, smiles, :content_type => 'chemical/x-daylight-smiles').to_s.chomp end # Create a compound from inchi string # @param [String] smiles InChI string # @return [OpenTox::Compound] Compound - def self.from_inchi(inchi) - Compound.new RestClientWrapper.post(CONFIG[:services]["opentox-compound"], inchi, :content_type => 'chemical/x-inchi').to_s.chomp + def self.from_inchi(service_uri, inchi) + Compound.new RestClientWrapper.post(service_uri, inchi, :content_type => 'chemical/x-inchi').to_s.chomp end # Create a compound from sdf string # @param [String] smiles SDF string # @return [OpenTox::Compound] Compound - def self.from_sdf(sdf) - Compound.new RestClientWrapper.post(CONFIG[:services]["opentox-compound"], sdf, :content_type => 'chemical/x-mdl-sdfile').to_s.chomp + def self.from_sdf(service_uri, sdf) + Compound.new RestClientWrapper.post(service_uri, sdf, :content_type => 'chemical/x-mdl-sdfile').to_s.chomp end # Create a compound from name. Relies on an external service for name lookups. @@ -51,18 +34,16 @@ module OpenTox # compound = OpenTox::Compound.from_name("Benzene") # @param [String] name name can be also an InChI/InChiKey, CAS number, etc # @return [OpenTox::Compound] Compound - def self.from_name(name) - c = Compound.new + def self.from_name(service_uri, name) # paranoid URI encoding to keep SMILES charges and brackets - c.inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(name, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").to_s.chomp - c.uri = File.join(CONFIG[:services]["opentox-compound"],URI.escape(c.inchi)) - c + inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(name, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").to_s.chomp + Compound.new File.join(service_uri,URI.escape(inchi)) end # Get InChI # @return [String] InChI string def to_inchi - @inchi + RestClientWrapper.get(@uri, :accept => 'chemical/x-inchi').to_s.chomp if @uri end # Get (canonical) smiles diff --git a/lib/opentox-ruby-minimal.rb b/lib/opentox-ruby-minimal.rb new file mode 100644 index 0000000..e0d5489 --- /dev/null +++ b/lib/opentox-ruby-minimal.rb @@ -0,0 +1,2 @@ +require "opentox" +require "compound" diff --git a/lib/opentox.rb b/lib/opentox.rb index b0ffcb1..a6ac1d4 100644 --- a/lib/opentox.rb +++ b/lib/opentox.rb @@ -11,8 +11,8 @@ SERVICES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation" module OpenTox - attr_accessor :subjectid, :uri #, :service_uri - #attr_writer :metadata + attr_accessor :subjectid, :uri + attr_writer :metadata # Initialize OpenTox object with optional subjectid # @param [optional, String] subjectid @@ -21,14 +21,26 @@ module OpenTox @subjectid = subjectid end - def metadata - metadata = {} - RDF::Reader.open(@uri) do |reader| - reader.each_statement do |statement| - metadata[statement.predicate] = statement.object if statement.subject == @uri + # Ruby interface + + def metadata reload=true + if reload + @metadata = {} + RDF::Reader.open(@uri) do |reader| + reader.each_statement do |statement| + @metadata[statement.predicate] = statement.object if statement.subject == @uri + end end end - metadata + @metadata + end + + def save + rdf = RDF::Writer.buffer do |writer| + @metadata.each { |p,o| writer << RDF::Statement.new(RDF::URI.new(@uri), p, o) } + end + puts rdf + #post(@uri, rdf, { :content_type => 'application/rdf+xml', :subjectid => subjectid}).to_s.chomp, @subjectid end # REST API @@ -74,17 +86,31 @@ module OpenTox RestClientWrapper.delete(@uri.to_s,:subjectid => @subjectid) end + + module Service + def create service_uri, subjectid=nil + service = eval("#{self}.new(\"#{service_uri}\", #{subjectid})") + uri = service.post({}, {}, subjectid).to_s + eval "#{self}.new(\"#{uri}\", #{subjectid})" + end + end + # create default classes - SERVICES.each { |s| eval "class #{s}; include OpenTox; end" } + SERVICES.each do |s| + eval "class #{s} + include OpenTox + extend OpenTox::Service + end" + end =begin - # Tools + private def uri_available? url = URI.parse(@uri) - req = Net::HTTP.new(url.host,url.port) - req['subjectid'] = @subjectid if @subjectid - req.start(url.host, url.port) do |http| + #req = Net::HTTP.new(url.host,url.port) + #req['subjectid'] = @subjectid if @subjectid + Net::HTTP.start(url.host, url.port) do |http| return http.head("#{url.request_uri}#{subjectidstr}").code == "200" end end @@ -93,10 +119,6 @@ module OpenTox include OpenTox - def find - uri_available? ? object_class.new(@uri, @subjectid) : nil - end - def create metadata object_class.new post(service_uri, metadata.to_rdfxml, { :content_type => 'application/rdf+xml', :subjectid => subjectid}).to_s.chomp, @subject_id end @@ -107,14 +129,6 @@ module OpenTox get(:accept => "text/uri-list").to_s.split(/\n/).collect{|uri| object_class.new uri,@subjectid} end - def save object - object_class.new post(object.to_rdfxml, :content_type => 'application/rdf+xml').to_s, @subjectid - end - - def object_class - eval self.class.to_s.sub(/::Collection/,'') - end - # create collection classes SERVICES.each { |s| eval "class #{s}; include Collection; end" } diff --git a/test/all.rb b/test/all.rb index 6666e84..91a994c 100644 --- a/test/all.rb +++ b/test/all.rb @@ -1,10 +1,11 @@ -require 'rubygems' -require 'test/unit' -require 'opentox-ruby-minimal' +#require 'rubygems' +#require 'test/unit' +#require 'opentox-ruby-minimal' require './rest.rb' +require './ruby-api.rb' require './feature.rb' +require './compound.rb' #require './authorization.rb' -#require './compound.rb' #require './dataset.rb' #require './parser.rb' #require './task.rb' diff --git a/test/compound.rb b/test/compound.rb new file mode 100644 index 0000000..35fc514 --- /dev/null +++ b/test/compound.rb @@ -0,0 +1,53 @@ +$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' ) +require 'rubygems' +require 'opentox-ruby-minimal.rb' +require 'test/unit' + +class CompoundTest < Test::Unit::TestCase + + def setup + @service_uri = "http://ot-dev.in-silico.ch/compound" + end + + def test_compound_from_smiles_0 + c = OpenTox::Compound.from_smiles @service_uri, "F[B-](F)(F)F.[Na+]" + assert_equal "InChI=1S/BF4.Na/c2-1(3,4)5;/q-1;+1", c.to_inchi + assert_equal "[Na+].F[B-](F)(F)F", c.to_smiles # still does not work on 64bit machines + end + + def test_compound_from_smiles_1 + c = OpenTox::Compound.from_smiles @service_uri, "CC(=O)CC(C)C#N" + assert_equal "InChI=1S/C6H9NO/c1-5(4-7)3-6(2)8/h5H,3H2,1-2H3", c.to_inchi + assert_equal "CC(CC(=O)C)C#N", c.to_smiles + end + + def test_compound_from_name + c = OpenTox::Compound.from_name @service_uri, "Benzene" + assert_equal "InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H", c.to_inchi + assert_equal "c1ccccc1", c.to_smiles + end + + def test_compound_from_smiles_2 + c = OpenTox::Compound.from_smiles @service_uri, "N#[N+]C1=CC=CC=C1.F[B-](F)(F)F" + assert_equal "InChI=1S/C6H5N2.BF4/c7-8-6-4-2-1-3-5-6;2-1(3,4)5/h1-5H;/q+1;-1", c.to_inchi + assert_equal "N#[N+]c1ccccc1.F[B-](F)(F)F", c.to_smiles + end + + def test_compound_from_inchi + c = OpenTox::Compound.from_inchi @service_uri, "InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H" + assert_equal "c1ccccc1", c.to_smiles + end + + def test_compound_ambit + c = OpenTox::Compound.new "http://apps.ideaconsult.net:8080/ambit2/compound/144036" + assert_equal "InChI=1S/C6H11NO2/c1-3-5-6(4-2)7(8)9/h5H,3-4H2,1-2H3", c.to_inchi + assert_equal "CCC=C(CC)[N+](=O)[O-]", c.to_smiles + end + +=begin + def test_match_hits + c = OpenTox::Compound.from_smiles @service_uri, "N=C=C1CCC(=F=FO)C1" + assert_equal ({"FF"=>2, "CC"=>10, "C"=>6, "C1CCCC1"=>10, "C=C"=>2}), c.match_hits(['CC','F=F','C','C=C','FF','C1CCCC1','OO']) + end +=end +end diff --git a/test/ruby-api.rb b/test/ruby-api.rb new file mode 100644 index 0000000..be828fb --- /dev/null +++ b/test/ruby-api.rb @@ -0,0 +1,17 @@ +$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' ) +require 'rubygems' +require 'opentox-ruby-minimal.rb' +require 'test/unit' + +class RubyAPITest < Test::Unit::TestCase + + def test_create + d = OpenTox::Dataset.create "http://ot-dev.in-silico.ch/dataset"#, {RDF::DC.title => "test dataset"} + assert_equal OpenTox::Dataset, d.class + assert_equal RDF::OT.Dataset, d.metadata[RDF.type] + end + + def test_save + end + +end -- cgit v1.2.3