opentox-ruby-api-wrapper 1.1.0

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.
@@ -0,0 +1,23 @@
1
+ = opentox-ruby-api-wrapper
2
+
3
+ Ruby wrapper for the OpenTox REST API (http://www.opentox.org)
4
+
5
+ == Installation
6
+
7
+ Run the following if you haven't already:
8
+
9
+ gem sources -a http://gems.github.com
10
+
11
+ Install the gem:
12
+
13
+ sudo gem install helma-opentox-ruby-api-wrapper
14
+
15
+ == Usage
16
+
17
+ - set the environment variables OPENTOX_COMPOUNDS, OPENTOX_FEATURES, OPENTOX_DATASETS, OPENTOX_FMINER to the base URI of the OpenTox REST webservices
18
+ - require 'opentox-ruby-api-wrapper' in your ruby application
19
+ - consult the rdoc API documentation for details
20
+
21
+ == Copyright
22
+
23
+ Copyright (c) 2009 Christoph Helma. See LICENSE for details.
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "opentox-ruby-api-wrapper"
8
+ gem.summary = %Q{Ruby wrapper for the OpenTox REST API}
9
+ gem.description = %Q{Ruby wrapper for the OpenTox REST API (http://www.opentox.org)}
10
+ gem.email = "helma@in-silico.ch"
11
+ gem.homepage = "http://github.com/helma/opentox-ruby-api-wrapper"
12
+ gem.authors = ["Christoph Helma"]
13
+ gem.add_dependency "technoweenie-rest-client"
14
+ gem.add_dependency "sinatra"
15
+ gem.add_dependency "rack"
16
+ gem.add_dependency "rack-contrib"
17
+ gem.add_dependency "thin"
18
+ gem.add_dependency "cucumber"
19
+ gem.add_dependency "ezmobius-redis-rb"
20
+ gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
21
+ gem.files.include %w(lib/tasks/opentox.rb, lib/tasks/redis.rb, lib/environment.rb, lib/algorithm.rb, lib/compound.rb, lib/dataset.rb, lib/feature.rb, lib/model.rb, lib/utils.rb, lib/templates/*)
22
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
23
+ end
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ begin
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/*_test.rb'
40
+ test.verbose = true
41
+ end
42
+ rescue LoadError
43
+ task :rcov do
44
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
45
+ end
46
+ end
47
+
48
+ task :test => :check_dependencies
49
+
50
+ task :default => :test
51
+
52
+ require 'rake/rdoctask'
53
+ Rake::RDocTask.new do |rdoc|
54
+ if File.exist?('VERSION')
55
+ version = File.read('VERSION')
56
+ else
57
+ version = ""
58
+ end
59
+
60
+ rdoc.rdoc_dir = 'rdoc'
61
+ rdoc.title = "opentox-ruby-api-wrapper #{version}"
62
+ rdoc.rdoc_files.include('README*')
63
+ rdoc.rdoc_files.include('lib/**/*.rb')
64
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
@@ -0,0 +1,37 @@
1
+ module OpenTox
2
+ module Algorithm
3
+
4
+ class Fminer < OpenTox
5
+ # Create a new dataset with BBRC features
6
+ def self.create(params)
7
+ puts params[:dataset_uri]
8
+ uri = RestClient.post File.join(@@config[:services]["opentox-algorithm"],'fminer'), :dataset_uri => params[:dataset_uri]
9
+ print "fminer finsihed "
10
+ puts uri
11
+ uri
12
+ end
13
+ end
14
+
15
+ class Similarity < OpenTox
16
+
17
+ def self.tanimoto(dataset1,compound1,dataset2,compound2)
18
+ RestClient.get File.join(@@config[:services]["opentox-algorithm"], 'tanimoto/dataset',dataset1.name,compound1.inchi,'dataset',dataset2.name,compound2.inchi)
19
+ end
20
+
21
+ def self.weighted_tanimoto(dataset1,compound1,dataset2,compound2)
22
+ # URI.escape does not work here
23
+ uri = File.join(@@config[:services]["opentox-algorithm"], 'weighted_tanimoto/dataset',CGI.escape(dataset1.name),'compound',CGI.escape(compound1.inchi),'dataset',CGI.escape(dataset2.name),'compound',CGI.escape(compound2.inchi))
24
+ RestClient.get uri
25
+ end
26
+
27
+ end
28
+
29
+ class Lazar < OpenTox
30
+ # Create a new prediction model from a dataset
31
+ def self.create(params)
32
+ RestClient.post File.join(@@config[:services]["opentox-algorithm"],"lazar_classification"), params
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,67 @@
1
+ module OpenTox
2
+
3
+ # uri: /compound/:inchi
4
+ class Compound < OpenTox
5
+
6
+ attr_reader :inchi
7
+
8
+ # 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)
9
+ def initialize(params)
10
+ @@cactus_uri="http://cactus.nci.nih.gov/chemical/structure/"
11
+ if params[:smiles]
12
+ @inchi = smiles2inchi(params[:smiles])
13
+ @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
14
+ elsif params[:inchi]
15
+ @inchi = params[:inchi]
16
+ @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
17
+ elsif params[:name]
18
+ @inchi = RestClient.get "#{@@cactus_uri}#{params[:name]}/stdinchi"
19
+ @uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
20
+ elsif params[:uri]
21
+ @inchi = params[:uri].sub(/^.*InChI/, 'InChI')
22
+ @uri = params[:uri]
23
+ end
24
+ end
25
+
26
+ # Get the (canonical) smiles
27
+ def smiles
28
+ obconversion(@inchi,'inchi','can')
29
+ end
30
+
31
+ def sdf
32
+ obconversion(@inchi,'inchi','sdf')
33
+ end
34
+
35
+ # Matchs a smarts string
36
+ def match?(smarts)
37
+ obconversion = OpenBabel::OBConversion.new
38
+ obmol = OpenBabel::OBMol.new
39
+ obconversion.set_in_format('inchi')
40
+ obconversion.read_string(obmol,@inchi)
41
+ smarts_pattern = OpenBabel::OBSmartsPattern.new
42
+ smarts_pattern.init(smarts)
43
+ smarts_pattern.match(obmol)
44
+ end
45
+
46
+ # Match an array of smarts features, returns matching features
47
+ def match(smarts_dataset)
48
+ smarts_dataset.all_features.collect{ |uri| uri if self.match?(Feature.new(:uri => uri).name) }.compact
49
+ end
50
+
51
+ def smiles2inchi(smiles)
52
+ obconversion(smiles,'smi','inchi')
53
+ end
54
+
55
+ def smiles2cansmi(smiles)
56
+ obconversion(smiles,'smi','can')
57
+ end
58
+
59
+ def obconversion(identifier,input_format,output_format)
60
+ obconversion = OpenBabel::OBConversion.new
61
+ obmol = OpenBabel::OBMol.new
62
+ obconversion.set_in_and_out_formats input_format, output_format
63
+ obconversion.read_string obmol, identifier
64
+ obconversion.write_string(obmol).gsub(/\s/,'').chomp
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,94 @@
1
+ module OpenTox
2
+
3
+ # key: /datasets
4
+ # set: dataset uris
5
+ # key: /dataset/:dataset/compounds
6
+ # set: compound uris
7
+ # key: /dataset/:dataset/compound/:inchi
8
+ # set: feature uris
9
+ class Dataset < OpenTox
10
+
11
+ # Initialize with <tt>:uri => uri</tt> or <tt>:name => name</tt> (creates a new dataset)
12
+ def initialize(uri)
13
+ super(uri)
14
+ end
15
+
16
+ def self.create(params)
17
+ uri = RestClient.post @@config[:services]["opentox-dataset"], :name => params[:name]
18
+ Dataset.new(uri.to_s)
19
+ end
20
+
21
+ def self.find(params)
22
+ begin
23
+ if params[:name]
24
+ uri = File.join(@@config[:services]["opentox-dataset"], URI.encode(params[:name]))
25
+ elsif params[:uri]
26
+ uri = params[:uri]
27
+ end
28
+ RestClient.get uri # check if the resource is available
29
+ Dataset.new(uri) if uri
30
+ rescue
31
+ nil
32
+ end
33
+ end
34
+
35
+ def self.find_or_create(params)
36
+ self.create(params) unless self.find(params)
37
+ end
38
+
39
+ def self.base_uri
40
+ @@config[:services]["opentox-dataset"]
41
+ end
42
+
43
+ def import(params)
44
+ if params[:csv]
45
+ # RestClient seems not to work for file uploads
46
+ #RestClient.post @uri + '/import', :compound_format => params[:compound_format], :content_type => "text/csv", :file => File.new(params[:csv])
47
+ `curl -X POST -F "file=@#{params[:csv]};type=text/csv" -F compound_format=#{params[:compound_format]} #{@uri + '/import'}`
48
+ end
49
+ end
50
+
51
+ def add(features)
52
+ RestClient.put @uri, :features => features
53
+ end
54
+
55
+ # Get all compounds from a dataset
56
+ def compound_uris
57
+ RestClient.get(File.join(@uri, 'compounds')).split("\n")
58
+ end
59
+
60
+ def compounds
61
+ compound_uris.collect{|uri| Compound.new(:uri => uri)}
62
+ end
63
+
64
+ # Get all features for a compound
65
+ def feature_uris(compound)
66
+ uri = File.join(@uri, 'compound', CGI.escape(compound.inchi)) # URI.encode does not work here
67
+ RestClient.get(uri).split("\n")
68
+ end
69
+
70
+ # Get all features for a compound
71
+ def features(compound)
72
+ feature_uris(compound).collect{|uri| Feature.new(:uri => uri)}
73
+ end
74
+
75
+ def all_features
76
+ RestClient.get(File.join(@uri, 'features')).split("\n")
77
+ end
78
+
79
+ # Delete a dataset
80
+ def delete
81
+ RestClient.delete @uri
82
+ end
83
+
84
+ def tanimoto(dataset)
85
+ RestClient.get(File.join(@uri,'tanimoto',dataset.path))
86
+ end
87
+
88
+ def weighted_tanimoto(dataset)
89
+ RestClient.get(File.join(@uri,'weighted_tanimoto',dataset.path))
90
+ end
91
+
92
+ end
93
+
94
+ end
@@ -0,0 +1,33 @@
1
+ # set default environment
2
+ ENV['RACK_ENV'] = 'test' unless ENV['RACK_ENV']
3
+
4
+ # load configuration
5
+ basedir = File.join(ENV['HOME'], ".opentox")
6
+ config_dir = File.join(basedir, "config")
7
+ @@tmp_dir = File.join(basedir, "tmp")
8
+ config_file = File.join(config_dir, "#{ENV['RACK_ENV']}.yaml")
9
+
10
+ if File.exist?(config_file)
11
+ @@config = YAML.load_file(config_file)
12
+ else
13
+ FileUtils.mkdir_p config_dir
14
+ FileUtils.mkdir_p @@tmp_dir
15
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'templates/config.yaml'), config_file)
16
+ puts "Please edit #{config_file} and restart your application."
17
+ exit
18
+ end
19
+
20
+ # configure redis database
21
+ begin
22
+ case ENV['RACK_ENV']
23
+ when 'production'
24
+ @@redis = Redis.new :db => 0
25
+ when 'development'
26
+ @@redis = Redis.new :db => 1
27
+ when 'test'
28
+ @@redis = Redis.new :db => 2
29
+ @@redis.flush_db
30
+ end
31
+ rescue
32
+ puts "Redis database not running, please start it with 'rake redis:start'."
33
+ end
@@ -0,0 +1,48 @@
1
+ module OpenTox
2
+
3
+ # uri: /feature/:name/:property_name/:property_value/...
4
+ class Feature < OpenTox
5
+
6
+ attr_accessor :name, :values
7
+
8
+ def initialize(params)
9
+ if params[:uri]
10
+ @uri = params[:uri]
11
+ items = URI.split(@uri)[5].split(/\//)
12
+ @name = items[1]
13
+ @values = {}
14
+ i = 2
15
+ while i < items.size
16
+ @values[items[i]] = items[i+1]
17
+ i += 2
18
+ end
19
+ else
20
+ @name = params[:name]
21
+ @values = {}
22
+ params.each do |k,v|
23
+ @values[k] = v unless k.to_s == 'name'
24
+ end
25
+ @uri = File.join(@@config[:services]["opentox-feature"],path)
26
+ end
27
+ end
28
+
29
+ def values_path
30
+ path = ''
31
+ @values.each do |k,v|
32
+ path = File.join path, URI.encode(k.to_s), URI.encode(v.to_s)
33
+ end
34
+ path
35
+ end
36
+
37
+ def path
38
+ File.join(URI.encode(@name),values_path)
39
+ end
40
+
41
+ def value(property)
42
+ items = @uri.split(/\//)
43
+ i = items.index(property)
44
+ items[i+1]
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,26 @@
1
+ helpers do
2
+
3
+ # Authentification
4
+ def protected!
5
+ response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth") and \
6
+ throw(:halt, [401, "Not authorized\n"]) and \
7
+ return unless authorized?
8
+ end
9
+
10
+ def authorized?
11
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
12
+ @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ['api', API_KEY]
13
+ end
14
+
15
+
16
+ =begin
17
+ def xml(object)
18
+ builder do |xml|
19
+ xml.instruct!
20
+ object.to_xml
21
+ end
22
+ end
23
+ =end
24
+
25
+ end
26
+
@@ -0,0 +1,71 @@
1
+ module OpenTox
2
+
3
+ module Model
4
+
5
+ class LazarClassification < OpenTox
6
+
7
+ # Create a new prediction model from a dataset
8
+ def initialize(uri)
9
+ super(uri)
10
+ end
11
+
12
+ def self.create(params)
13
+ uri = RestClient.post File.join(@@config[:services]["opentox-model"], 'lazar_classification'), params
14
+ puts "URI: " + uri
15
+ LazarClassification.new(uri.to_s)
16
+ end
17
+
18
+ def self.find(name)
19
+ uri = RestClient.get File.join(@@config[:services]["opentox-model"], 'lazar_classification', URI.encode(params[:name]))
20
+ LazarClassification.new(uri)
21
+ end
22
+
23
+ def self.find_all
24
+ RestClient.get File.join(@@config[:services]["opentox-model"], 'lazar_classification')#.split("\n")
25
+ end
26
+
27
+ # Predict a compound
28
+ def predict(compound)
29
+ LazarPrediction.new(:uri => RestClient.post(@uri, :compound_uri => compound.uri))
30
+ end
31
+
32
+ def self.base_uri
33
+ @@config[:services]["opentox-model"]
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ module Prediction
41
+
42
+ module Classification
43
+
44
+ class Lazar < OpenTox
45
+
46
+ def initialize(params)
47
+ super(params[:uri])
48
+ end
49
+
50
+ def classification
51
+ YAML.load(RestClient.get @uri)[:classification]
52
+ end
53
+
54
+ def confidence
55
+ YAML.load(RestClient.get @uri)[:confidence]
56
+ end
57
+
58
+ def neighbors
59
+ RestClient.get @uri + '/neighbors'
60
+ end
61
+
62
+ def features
63
+ RestClient.get @uri + '/features'
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end