summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.de>2009-09-08 11:15:50 +0200
committerChristoph Helma <helma@in-silico.de>2009-09-08 11:15:50 +0200
commit525a9229395070f04c54fe6aec3c2cd5e64235cd (patch)
treed942bde22ccc03e66223b9e284354387f64e4dcb
parent55d99f141275fc34019a621d1f0c444804ebc053 (diff)
tests successful
-rw-r--r--application.rb192
-rw-r--r--compound.rb33
-rw-r--r--dataset.rb159
-rw-r--r--feature.rb14
-rw-r--r--import.rb22
-rw-r--r--test/test.rb46
6 files changed, 123 insertions, 343 deletions
diff --git a/application.rb b/application.rb
index b9f518d..2ebbbc8 100644
--- a/application.rb
+++ b/application.rb
@@ -1,5 +1,5 @@
# SETUP
-[ 'rubygems', 'redis', 'opentox-ruby-api-wrapper', 'openbabel' ].each do |lib|
+[ 'rubygems', 'redis', 'opentox-ruby-api-wrapper' ].each do |lib|
require lib
end
@@ -15,8 +15,6 @@ end
set :default_content, :yaml
load File.join(File.dirname(__FILE__), 'dataset.rb')
-load File.join(File.dirname(__FILE__), 'compound.rb')
-load File.join(File.dirname(__FILE__), 'feature.rb')
helpers do
@@ -26,206 +24,64 @@ helpers do
end
def uri(name)
- uri = url_for("/", :full) + URI.encode(name) #.gsub(/\s|\n/,'_')
+ uri = url_for("/dataset/", :full) + URI.encode(name)
end
end
-=begin
-# current sinatra version does not halt in before filter, should be resolved in future versions
-before do
- if params[:name] and !request.post?
- halt 404, "Dataset \"#{params[:name]}\" not found." unless @dataset = Dataset.find(url_for("/", :full) + name.gsub(/\s|\n/,'_'))
- end
-end
-=end
-
## REST API
-get '/?' do
+load 'compound.rb'
+load 'feature.rb'
+
+get '/datasets/?' do
Dataset.find_all.join("\n")
end
-get '/*/tanimoto/*/?' do
+get '/dataset/*/tanimoto/*/?' do
find
@set.tanimoto(uri(params[:splat][1]))
end
-get '/*/weighted_tanimoto/*/?' do
+get '/dataset/*/weighted_tanimoto/*/?' do
find
@set.weighted_tanimoto(uri(params[:splat][1]))
end
# catch the rest
-get '/*/?' do
+get '/dataset/*/?' do
find
- @set.to_yaml
+ @set.members.join("\n")
end
-post '/?' do
-
+# create a dataset
+post '/datasets/?' do
dataset_uri = uri(params[:name])
halt 403, "Dataset \"#{dataset_uri}\" exists." if Dataset.find(dataset_uri)
-
@set = Dataset.create(dataset_uri)
- @compounds_set = Dataset.create File.join(dataset_uri, "compounds")
- #@activities_set = Dataset.create File.join(dataset_uri, "activities")
- #@features_set = Dataset.create File.join(dataset_uri, "features")
- @set.add(@compounds_set.uri)
- #@set.add(@activities_set.uri)
- #@set.add(@features_set.uri)
- @set.uri
-
-end
-
-post '/*/activities/?' do
-
- find
- @compounds_set = Dataset.find File.join(@set.uri, "compounds")
- #@activities_set = Dataset.find File.join(@set.uri, "activities")
- File.open(params[:file][:tempfile].path).each_line do |line|
- record = line.chomp.split(/,\s*/)
- inchi = Compound.new(:smiles => record[0]).inchi
- feature = Feature.new(:name => @set.name, :values => {:classification => record[1]})
- @compound_activities = Dataset.find_or_create File.join(@set.uri, inchi)
- #@activity_compounds = Dataset.find_or_create File.join(@set.uri, feature.path)
- @compounds_set.add(inchi)
- #@activities_set.add(feature.path)
- @compound_activities.add(feature.path)
- #@activity_compounds.add(inchi)
- end
+ @set.add Dataset.create(File.join(dataset_uri, "compounds")).uri
@set.uri
-
end
-post '/*/features/?' do
+load 'import.rb'
+# import yaml
+post '/dataset/*/?' do
find
@compounds_set = Dataset.find File.join(@set.uri, "compounds")
- #@features_set = Dataset.find File.join(@set.uri, "features")
- YAML.load(params[:features]).each do |inchi,features|
- @compound_features = Dataset.find_or_create File.join(@set.uri, inchi)
- features.each do |feature|
- #@feature_compounds = Dataset.find_or_create File.join(@set.uri, feature)
- @compounds_set.add(inchi)
- #@features_set.add(feature)
- @compound_features.add(feature)
- #@feature_compounds.add(inchi)
+ YAML.load(params[:features]).each do |compound_uri,feature_uris|
+ # key: /dataset/:dataset/compound/:inchi/:feature_type
+ @compound_features = Dataset.find_or_create File.join(@set.uri,'compound',OpenTox::Compound.new(:uri => compound_uri).inchi,URI.escape(params[:feature_type]))
+ feature_uris.each do |feature_uri|
+ @compounds_set.add compound_uri
+ @compound_features.add feature_uri
end
end
@set.uri
-
end
-delete '/*/?' do
+delete '/dataset/*/?' do
find
- @set.members.each{|m| Dataset.find(m).delete}
+ @set.members.each{|m| Dataset.find(m).delete} if @set.members
@set.delete
end
-
-put '/*/?' do
- find
- @set.add(params[:uri])
-end
-
-=begin
-get '/:name' do
- not_found?
- respond_to do |format|
- format.yaml { @dataset.to_yaml }
- format.xml { builder :dataset }
- end
-end
-
-get '/:name/name' do
- not_found?
- URI.decode(params[:name])
-end
-
-get '/:name/compounds' do
- not_found?
- @dataset.compound_uris.join("\n")
-end
-
-get '/:name/features' do
- not_found?
- @dataset.feature_uris.join("\n")
-end
-
-get '/:name/compound/*/features' do
- not_found?
- compound_uri = params[:splat].first.gsub(/ /,'+')
- @dataset.feature_uris_for_compound(compound_uri).join("\n")
-end
-
-get '/:name/feature/*/compounds' do
- not_found?
- @dataset.compound_uris_for_feature(params[:splat].first).join("\n")
-end
-
-get '/tanimoto/:name0/compound/*/:name1/compound/*/?' do
- compound_uris = params[:splat].collect{ |c| c.gsub(/ /,'+') }
- features = [ {:dataset_uri => uri(params[:name0]), :compound_uri => compound_uris[0]}, {:dataset_uri => uri(params[:name1]), :compound_uri => compound_uris[1]} ]
- "#{Dataset.tanimoto(features)}"
-end
-
-get '/weighted_tanimoto/:name0/compound/*/:name1/compound/*/?' do
- compound_uris = params[:splat].collect{ |c| c.gsub(/ /,'+') }
- features = [ {:dataset_uri => uri(params[:name0]), :compound_uri => compound_uris[0]}, {:dataset_uri => uri(params[:name1]), :compound_uri => compound_uris[1]} ]
- Dataset.weighted_tanimoto(features)
-end
-
-post '/?' do
- #protected!
- halt 403, "Dataset \"#{name}\" exists - please choose another name." if Dataset.exists?(uri params[:name])
-
- dataset = Dataset.create(uri params[:name])
-
- if params[:file]
- File.open(params[:file][:tempfile].path).each_line do |line|
- record = line.chomp.split(/,\s*/)
- compound_uri = OpenTox::Compound.new(:smiles => record[0]).uri
- feature_uri = OpenTox::Feature.new(:name => params[:name], :values => {:classification => record[1]}).uri
- dataset.add(compound_uri, feature_uri)
- end
- end
- dataset.uri
-end
-
-put '/:name/?' do
- #protected!
- not_found?
- @dataset.add(params[:compound_uri],params[:feature_uri])
- @dataset.uri + " sucessfully updated."
-end
-
-delete '/:name/?' do
- #protected!
- not_found?
- @dataset.destroy
- "Successfully deleted dataset \"#{params[:name]}\"."
-end
-
-# Dataset collections
-get '/collections/?' do
- DatasetCollection.find_all.join("\n")
-end
-
-get '/collection/:name/?' do
- @collection = DatasetCollection.find(uri params[:name])
- respond_to do |format|
- format.yaml { @collection.to_yaml }
- format.xml { builder :collection }
- end
-end
-
-post '/collections/?' do
- halt 403, "Dataset collection \"#{name}\" exists - please choose another name." if DatasetCollection.exists?(uri params[:name])
- DatasetCollection.create(uri params[:name], :dataset_uris => params[:datasets]).uri
-end
-
-delete '/collection/:name/?' do
- DatasetCollection.find(uri params[:name]).destroy
- "Successfully deleted dataset collection \"#{params[:name]}\"."
-end
-=end
diff --git a/compound.rb b/compound.rb
new file mode 100644
index 0000000..9c1552e
--- /dev/null
+++ b/compound.rb
@@ -0,0 +1,33 @@
+mime :uid, "text/plain"
+mime :smiles, "chemical/x-daylight-smiles"
+mime :inchi, "chemical/x-inchi"
+mime :sdf, "chemical/x-mdl-sdfile"
+mime :image, "image/gif"
+mime :names, "text/plain"
+
+set :default_content, :smiles
+
+get '/compound/*/match/*' do
+ "#{OpenTox::Compound.new(:inchi => params[:splat][0]).match(params[:splat][1])}"
+end
+
+get %r{/compound/(.+)} do |inchi| # catches all remaining get requests
+ inchi.gsub!(/ /,'+') # fix CGI? escaping of + signs
+ respond_to do |format|
+ format.smiles { inchi2smiles inchi }
+ format.names { RestClient.get "#{CACTUS_URI}#{inchi}/names" }
+ format.inchi { inchi }
+ format.sdf { RestClient.get "#{CACTUS_URI}#{inchi}/sdf" }
+ format.image { "#{CACTUS_URI}#{inchi}/image" }
+ end
+end
+
+post '/compound/?' do
+ if params[:smiles]
+ OpenTox::Compound.new(:smiles => params[:smiles]).uri
+ elsif params[:inchi]
+ OpenTox::Compound.new(:inchi => params[:inchi]).uri
+ elsif params[:name]
+ OpenTox::Compound.new(:name => params[:name]).uri
+ end
+end
diff --git a/dataset.rb b/dataset.rb
index 25adf86..82d228f 100644
--- a/dataset.rb
+++ b/dataset.rb
@@ -39,6 +39,10 @@ class Dataset
@@redis.set_members "datasets"
end
+ def member?(uri)
+ @@redis.set_member? @uri, uri
+ end
+
def add(member_uri)
@@redis.set_add @uri , member_uri
@members << member_uri
@@ -65,8 +69,8 @@ class Dataset
p_sum_union = 0.0
p_sum_intersect = 0.0
- union.each{ |f| p_sum_union += OpenTox::Utils::gauss(Feature.value(f,'p_value').to_f) }
- intersect.each{ |f| p_sum_intersect += OpenTox::Utils::gauss(Feature.value(f,'p_value').to_f) }
+ union.each{ |f| p_sum_union += OpenTox::Utils::gauss(OpenTox::Feature.new(:uri => f).value('p_value').to_f) }
+ intersect.each{ |f| p_sum_intersect += OpenTox::Utils::gauss(OpenTox::Feature.new(:uri => f).value('p_value').to_f) }
"#{p_sum_intersect/p_sum_union}"
end
@@ -77,154 +81,3 @@ class Dataset
end
-=begin
-class Dataset
-
- include OpenTox::Utils
- attr_reader :uri, :name
-
- def initialize(uri)
- @name = File.basename(uri)
- @uri = uri
- @members = []
- end
-
- def self.create(uri)
- dataset = Dataset.new(uri)
- dataset.save
- dataset
- end
-
- def self.find(uri)
- if @@redis.set_member? "datasets", uri
- Dataset.new(uri)
- else
- nil
- end
- end
-
- def self.exists?(uri)
- @@redis.set_member? "datasets", uri
- end
-
- def self.find_all
- @@redis.set_members("datasets")
- end
-
- def save
- @@redis.set_add "datasets", @uri
- end
-
- def destroy
- @@redis.set_members(@uri + '::compounds').each do |compound_uri|
- @@redis.delete @uri + '::' + compound_uri
- end
- @@redis.delete @uri + '::compounds'
- @@redis.set_members(@uri + '::features').each do |feature_uri|
- @@redis.delete @uri + '::' + feature_uri
- end
- @@redis.delete @uri + '::features'
- @@redis.set_delete "datasets", @uri
- end
-
- def add(compound_uri,feature_uri)
- @@redis.set_add @uri + '::compounds', compound_uri
- @@redis.set_add @uri + '::features', feature_uri
- @@redis.set_add @uri + '::' + compound_uri + '::features', feature_uri
- @@redis.set_add @uri + '::' + feature_uri + '::compounds', compound_uri
- end
-
- def compound_uris
- @@redis.set_members(@uri + "::compounds")
- end
-
- def feature_uris
- @@redis.set_members(@uri + "::features")
- end
-
- def feature_uris_for_compound(compound_uri)
- @@redis.set_members(@uri + '::' + compound_uri + '::features')
- end
-
- def compound_uris_for_feature(feature_uri)
- @@redis.set_members(@uri + '::' + feature_uri + '::compounds')
- end
-
- def self.tanimoto(features)
- raise "Exactly 2 compounds are needed for similarity calculations" unless features.size == 2
- compound_keys = features.collect{ |f| f[:dataset_uri] + '::' + f[:compound_uri] + "::features" }
- union_size = @@redis.set_union(compound_keys[0], compound_keys[1]).size
- intersect_size = @@redis.set_intersect(compound_keys[0], compound_keys[1]).size
- intersect_size.to_f/union_size.to_f
- end
-
- def self.weighted_tanimoto(features)
- raise "Exactly 2 compounds are needed for similarity calculations" unless features.size == 2
- compound_keys = features.collect{ |f| f[:dataset_uri] + '::' + f[:compound_uri] + "::features" }
- union = @@redis.set_union(compound_keys[0], compound_keys[1])
- intersect = @@redis.set_intersect(compound_keys[0], compound_keys[1])
-
- p_sum_union = 0.0
- p_sum_intersect = 0.0
-
- union.each{ |f| p_sum_union += OpenTox::Utils::gauss(OpenTox::Feature.new(:uri => f).value('p_value').to_f) }
- intersect.each{ |f| p_sum_intersect += OpenTox::Utils::gauss(OpenTox::Feature.new(:uri => f).value('p_value').to_f) }
- "#{p_sum_intersect/p_sum_union}"
- end
-
-end
-
-class Dataset
-
- attr_accessor :uri, :set_uris
-
- def initialize(uri, set_uris)
- @uri = uri
- @set_uris = set_uris
- end
-
- def self.create(uri, set_uris)
- collection = DatasetCollection.new(uri, set_uris)
- collection.save
- collection
- end
-
- def self.find(uri)
- if @@redis.set_member? "collections", uri
- set_uris = @@redis.set_members uri
- DatasetCollection.new(uri, set_uris)
- else
- nil
- end
- end
-
- def self.exists?(uri)
- @@redis.set_member? "collections", uri
- end
-
- def self.find_all
- @@redis.set_members("collections").collect{ |uri| self.find(uri) }
- end
-
- def save
- @@redis.set_add "collections", @uri
- @set_uris.each do |uri|
- @@redis.set_add @uri + '::sets', uri
- end
- end
-
- def destroy
- @set_uris.each do |uri|
- Dataset.new(uri).destroy
- end
- @@redis.delete @uri + '::sets'
- @@redis.set_delete "collections", @uri
- end
-
- def add(set_uri)
- @set_uris << set_uri
- @@redis.set_add @uri, set_uri
- end
-
-end
-=end
diff --git a/feature.rb b/feature.rb
new file mode 100644
index 0000000..1f138be
--- /dev/null
+++ b/feature.rb
@@ -0,0 +1,14 @@
+set :default_content, :yaml
+
+## REST API
+get '/feature/*/?' do
+ @feature = OpenTox::Feature.new(request.url)
+ respond_to do |format|
+ format.yaml { @feature.to_yaml }
+ format.xml { builder :feature }
+ end
+end
+
+post '/feature/?' do
+ OpenTox::Feature.new(:name => params[:name], :values => params[:values]).uri
+end
diff --git a/import.rb b/import.rb
new file mode 100644
index 0000000..de6f60b
--- /dev/null
+++ b/import.rb
@@ -0,0 +1,22 @@
+post '/dataset/*/import/?' do
+ find
+ halt 404, "Compound format #{params[:compound_format]} not (yet) supported" unless params[:compound_format] =~ /smiles|inchi|name/
+ @compounds_set = Dataset.find File.join(@set.uri, "compounds")
+ case params[:file][:type]
+ when "text/csv"
+ File.open(params[:file][:tempfile].path).each_line do |line|
+ record = line.chomp.split(/,\s*/)
+ compound_uri = OpenTox::Compound.new(:smiles => record[0]).uri
+ feature_uri = OpenTox::Feature.new(:name => @set.name.sub(/dataset\//,''), :values => {:classification => record[1]}).uri
+ @compounds_set.add compound_uri unless @compounds_set.member? compound_uri
+ # key: /dataset/:dataset/compound/:inchi/:feature_type
+ @compound_features = Dataset.find_or_create File.join(@set.uri,'compound',OpenTox::Compound.new(:uri => compound_uri).inchi,URI.escape(params[:feature_type]))
+ @compound_features.add feature_uri
+ end
+ else
+ halt 404, "File format #{request.content_type} not (yet) supported"
+ end
+ @set.uri
+
+end
+
diff --git a/test/test.rb b/test/test.rb
index 611113b..603e27d 100644
--- a/test/test.rb
+++ b/test/test.rb
@@ -15,15 +15,15 @@ class DatasetsTest < Test::Unit::TestCase
end
def test_index
- get '/'
+ get '/datasets'
assert last_response.ok?
end
def test_create_dataset
- post '/', :name => "Test dataset"
+ post '/datasets', :name => "Test dataset"
assert last_response.ok?
uri = last_response.body
- assert_equal "http://example.org/Test%20dataset", uri
+ assert_equal "http://example.org/dataset/Test%20dataset", uri
get uri
assert last_response.ok?
delete uri
@@ -34,20 +34,17 @@ class DatasetsTest < Test::Unit::TestCase
def test_create_dataset_from_csv
smiles = 'CC(=O)Nc1scc(n1)c1ccc(o1)[N+](=O)[O-]'
- compound = Compound.new(:smiles => smiles)
- post '/', :name => "Hamster Carcinogenicity"
+ compound = OpenTox::Compound.new(:smiles => smiles)
+ post '/datasets', :name => "Hamster Carcinogenicity"
uri = last_response.body
- post uri + '/activities', :file => Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), "hamster_carcinogenicity.csv"))
+ assert last_response.ok?
+ post uri + '/import', :file => Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), "hamster_carcinogenicity.csv"), "text/csv"), :compound_format => "smiles", :feature_type => "in vivo carcinogenicity"
get uri
assert last_response.ok?
get uri + '/compounds'
assert last_response.ok?
assert last_response.body.include?(compound.inchi)
- #get uri + '/activities'
- #assert last_response.ok?
- #assert last_response.body.include?("Hamster%20Carcinogenicity/classification/true")
- #assert last_response.body.include?("Hamster%20Carcinogenicity/classification/false")
- get File.join(uri ,compound.inchi)
+ get File.join(uri , 'compound', compound.inchi, URI.encode("in vivo carcinogenicity"))
assert last_response.ok?
assert last_response.body.include?("Hamster%20Carcinogenicity/classification/true")
delete uri
@@ -56,14 +53,16 @@ class DatasetsTest < Test::Unit::TestCase
assert !last_response.ok?
end
+=begin
def test_create_large_dataset_from_csv
- post '/', :name => "Salmonella Mutagenicity"
+ post '/datasets', :name => "Salmonella Mutagenicity"
uri = last_response.body
- post uri + '/activities', :file => Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), "kazius.csv"))
+ post uri + '/import', :file => Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__), "kazius.csv"), "text/csv"), :compound_format => "smiles", :feature_type => "activity"
uri = last_response.body
get uri
assert last_response.ok?
end
+=end
def test_tanimoto_similarity
#@feature_set = OpenTox::Algorithms::Fminer.new :dataset_uri => @dataset
@@ -95,7 +94,7 @@ class DatasetsTest < Test::Unit::TestCase
'F' => 0.9,
}
}
- post '/', :name => name
+ post '/datasets', :name => name
assert last_response.ok?
uri = last_response.body
get uri
@@ -104,25 +103,28 @@ class DatasetsTest < Test::Unit::TestCase
feature_data = {}
data.each do |smiles,features|
- compound = Compound.new(:smiles => smiles).inchi
+ compound = OpenTox::Compound.new(:smiles => smiles).uri
feature_data[compound] = []
features.each do |k,v|
- feature= Feature.new(:name => k, :values => {:p_value => v}).path
+ feature= OpenTox::Feature.new(:name => k, :values => {:p_value => v}).uri
feature_data[compound] << feature
end
end
- post uri + '/features', :features => feature_data.to_yaml
+ post uri , :features => feature_data.to_yaml, :feature_type => 'test'
assert last_response.ok?
data.each do |smiles,features|
- compound= Compound.new(:smiles => smiles).inchi
+ compound= OpenTox::Compound.new(:smiles => smiles).inchi
data.each do |s,f|
unless s == smiles
- neighbor= Compound.new(:smiles => s).inchi
- get "/#{name}/#{compound}/"
+ neighbor= OpenTox::Compound.new(:smiles => s).inchi
+ get "/dataset/#{name}/compounds"
+ assert last_response.ok?
+ get "/dataset/#{name}/compound/#{compound}/test"
assert last_response.ok?
- get "/#{name}/#{compound}/tanimoto/#{name}/#{neighbor}"
+ get "/dataset/#{name}/compound/#{compound}/test/tanimoto/#{name}/compound/#{neighbor}/test"
+ puts last_response.body
assert last_response.ok?
sim = last_response.body
features_a = data[smiles].keys
@@ -132,7 +134,7 @@ class DatasetsTest < Test::Unit::TestCase
mysim = intersect.size.to_f/union.size.to_f
assert_equal sim, mysim.to_s
puts "tanimoto::#{smiles}::#{s}::#{last_response.body}"
- get "/#{name}/#{compound}/weighted_tanimoto/#{name}/#{neighbor}"
+ get "/dataset/#{name}/compound/#{compound}/test/weighted_tanimoto/#{name}/compound/#{neighbor}/test"
assert last_response.ok?
puts "weighted_tanimoto::#{smiles}::#{s}::#{last_response.body}"
end