opentox-ruby-api-wrapper 1.1.0

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