summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormguetlein <martin.guetlein@gmail.com>2010-06-25 20:44:49 +0200
committermguetlein <martin.guetlein@gmail.com>2010-06-25 20:44:49 +0200
commit5cdd09a98b1edfb8be3e4693a4b129b9b35ad9f2 (patch)
treefa70316a483282d7f77306c04bc4aca6dc72ad7a /lib
parente5838e7607533b5087a89949fea15f694f184b17 (diff)
parentba287d744cdc929df7e3ed3986151b813ddf8fb1 (diff)
resolved conflicts, replace text/x-yaml with application/x-yaml, acceess classification values w/o confidence
Diffstat (limited to 'lib')
-rw-r--r--lib/algorithm.rb7
-rw-r--r--lib/compound.rb4
-rw-r--r--lib/config/config_ru.rb31
-rw-r--r--lib/dataset.rb145
-rw-r--r--lib/environment.rb13
-rw-r--r--lib/model.rb69
-rw-r--r--lib/task.rb11
-rw-r--r--lib/templates/config.yaml74
-rw-r--r--lib/validation.rb12
9 files changed, 141 insertions, 225 deletions
diff --git a/lib/algorithm.rb b/lib/algorithm.rb
index 7a25408..cc06032 100644
--- a/lib/algorithm.rb
+++ b/lib/algorithm.rb
@@ -21,8 +21,11 @@ module OpenTox
def self.create_model(params)
LOGGER.debug params
LOGGER.debug File.basename(__FILE__) + ": creating model"
- resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "text/x-yaml")
- @uri = resource.post(:dataset_uri => params[:dataset_uri], :feature_uri => params[:feature_uri], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).chomp
+ LOGGER.debug File.join(@@config[:services]["opentox-algorithm"], "lazar")
+ #resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
+ resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
+ #@uri = resource.post(:dataset_uri => params[:dataset_uri], :feature_uri => params[:feature_uri], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).chomp
+ @uri = resource.post(:dataset_uri => params[:dataset_uri], :prediction_feature => params[:prediction_feature], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).body.chomp
end
def self.uri
diff --git a/lib/compound.rb b/lib/compound.rb
index cc29fc5..6ab78e0 100644
--- a/lib/compound.rb
+++ b/lib/compound.rb
@@ -18,7 +18,9 @@ module OpenTox
@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
elsif params[:name]
# paranoid URI encoding to keep SMILES charges and brackets
- @inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").chomp
+ @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]
diff --git a/lib/config/config_ru.rb b/lib/config/config_ru.rb
index 1d32c7e..3d8dce2 100644
--- a/lib/config/config_ru.rb
+++ b/lib/config/config_ru.rb
@@ -18,3 +18,34 @@ set :raise_errors, true
end
use Rack::ShowExceptions
+if defined?(MAIL)
+
+ # monkeypatch with the original method
+ # strangely enough my mailserver returns "Connection refused - connect(2)" errors without this patch
+ module Rack
+ class MailExceptions
+
+ def send_notification(exception, env)
+ mail = generate_mail(exception, env)
+ smtp = config[:smtp]
+ env['mail.sent'] = true
+ return if smtp[:server] == 'example.com'
+
+ Net::SMTP.start smtp[:server], smtp[:port], smtp[:domain], smtp[:user_name], smtp[:password], smtp[:authentication] do |server|
+ mail.to.each do |recipient|
+ server.send_message mail.to_s, mail.from, recipient
+ end
+ end
+ end
+ end
+ end
+
+
+ require "socket"
+ use Rack::MailExceptions do |mail|
+ mail.to MAIL[:user_name]
+ mail.subject '[ERROR] %s'
+ mail.from "#{Socket.gethostname}@#{MAIL[:domain]}"
+ mail.smtp MAIL
+ end
+end
diff --git a/lib/dataset.rb b/lib/dataset.rb
index e506305..1254992 100644
--- a/lib/dataset.rb
+++ b/lib/dataset.rb
@@ -15,15 +15,16 @@ module OpenTox
def self.find(uri, accept_header=nil)
unless accept_header
- if uri.match(@@config[:services]["opentox-dataset"]) || uri=~ /188.40.32.88/ || uri =~ /in-silico.ch/
- accept_header = 'text/x-yaml'
+ #if uri.match(@@config[:services]["opentox-dataset"]) || uri=~ /188.40.32.88/ || uri =~ /informatik/
+ if !@@config[:accept_headers]["opentox-dataset"].grep(/yaml/).empty?
+ accept_header = 'application/x-yaml'
else
accept_header = "application/rdf+xml"
end
end
case accept_header
- when "text/x-yaml"
- d = YAML.load RestClientWrapper.get(uri.to_s.strip, :accept => 'text/x-yaml').to_s
+ when "application/x-yaml"
+ d = YAML.load RestClientWrapper.get(uri.to_s.strip, :accept => 'application/x-yaml').to_s
d.uri = uri unless d.uri
when "application/rdf+xml"
owl = OpenTox::Owl.from_uri(uri.to_s.strip, "Dataset")
@@ -90,15 +91,16 @@ module OpenTox
else
return "no classification key"
end
- else
- raise "predicted class value is not a hash\n"+
+ elsif v.is_a?(Array)
+ raise "predicted class value is an array\n"+
"value "+v.to_s+"\n"+
"value-class "+v.class.to_s+"\n"+
"dataset "+@uri.to_s+"\n"+
"compound "+compound.to_s+"\n"+
"feature "+feature.to_s+"\n"
+ else
+ return v
end
-
end
# returns prediction confidence if available
@@ -112,12 +114,14 @@ module OpenTox
raise "no confidence key"
end
else
- raise "prediction confidence value is not a hash value\n"+
- "value "+v.to_s+"\n"+
- "value-class "+v.class.to_s+"\n"+
- "dataset "+@uri.to_s+"\n"+
- "compound "+compound.to_s+"\n"+
- "feature "+feature.to_s+"\n"
+ LOGGER.warn "no confidence for compound: "+compound.to_s+", feature: "+feature.to_s
+ return 1
+# raise "prediction confidence value is not a hash value\n"+
+# "value "+v.to_s+"\n"+
+# "value-class "+v.class.to_s+"\n"+
+# "dataset "+@uri.to_s+"\n"+
+# "compound "+compound.to_s+"\n"+
+# "feature "+feature.to_s+"\n"
end
end
@@ -172,122 +176,9 @@ module OpenTox
@features.uniq!
@compounds.uniq!
- OpenTox::RestClientWrapper.post(@@config[:services]["opentox-dataset"],{:content_type => "text/x-yaml"},self.to_yaml).strip.to_s
- end
-
-=begin
- # create/add to entry from uris or Redland::Resources
- def add(compound,feature,value)
- compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
- feature = self.find_or_create_feature feature unless feature.class == Redland::Resource
- data_entry = @model.subject OT['compound'], compound
- if data_entry.nil?
- data_entry = @model.create_resource
- dataset = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add dataset, OT['dataEntry'], data_entry
- @model.add data_entry, RDF['type'], OT["DataEntry"]
- @model.add data_entry, OT['compound'], compound
- end
- values = @model.create_resource
- @model.add data_entry, OT['values'], values
- @model.add values, RDF['type'], OT['FeatureValue']
- @model.add values, OT['feature'], feature
- @model.add values, OT['value'], value.to_s
- end
-
- def add_tuple(compound,tuple)
- compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
- data_entry = @model.subject OT['compound'], compound
- if data_entry.nil?
- data_entry = @model.create_resource
- dataset = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add dataset, OT['dataEntry'], data_entry
- @model.add data_entry, RDF['type'], OT["DataEntry"]
- @model.add data_entry, OT['compound'], compound
- end
- @model.add data_entry, OT['values'], tuple
- end
-
- def create_tuple(feature,t)
- feature = self.find_or_create_feature feature unless feature.class == Redland::Resource
- tuple = @model.create_resource
- @model.add tuple, RDF['type'], OT["Tuple"]
- @model.add tuple, OT['feature'], feature
- t.each do |name,value|
- f = self.find_or_create_feature name unless name.class == Redland::Resource
- complex_value = @model.create_resource
- feature = self.find_or_create_feature(name)
- @model.add tuple, OT['complexValue'], complex_value
- @model.add complex_value, RDF['type'], OT["FeatureValue"]
- @model.add complex_value, OT['feature'], f
- @model.add complex_value, OT['value'], value.to_s
- end
-
- tuple
- end
-
- # find or create a new compound and return the resource
- def find_or_create_compound(uri)
- compound = @model.subject(DC["identifier"], uri)
- if compound.nil?
- compound = @model.create_resource(uri)
- @model.add compound, RDF['type'], OT["Compound"]
- @model.add compound, DC["identifier"], uri
- end
- compound
- end
-
- # find or create a new feature and return the resource
- def find_or_create_feature(uri)
- feature = @model.subject(DC["identifier"], uri)
- if feature.nil?
- feature = @model.create_resource(uri)
- @model.add feature, RDF['type'], OT["Feature"]
- @model.add feature, DC["identifier"], uri
- @model.add feature, DC["title"], File.basename(uri).split(/#/)[1]
- @model.add feature, DC['source'], uri
- end
- feature
- end
-
- def self.create(data, content_type = 'application/rdf+xml')
- resource = RestClient::Resource.new(@@config[:services]["opentox-dataset"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- uri = resource.post data, :content_type => content_type
- dataset = Dataset.new
- dataset.read uri.chomp.to_s
- dataset
- end
-
- def features
- features = []
- @model.subjects(RDF['type'], OT["Feature"]).each do |feature_node|
- features << @model.object(feature_node, DC["identifier"])#
- end
- features
- end
-
- def compounds
- compounds = []
- @model.subjects(RDF['type'], OT["Compound"]).each do |compound_node|
- compounds << @model.object(compound_node, DC["identifier"]).to_s
- end
- compounds
- end
-
- # Delete a dataset
- def delete
- resource = RestClient::Resource.new(@uri, :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.delete
- end
-
- def to_owl
- end
-
- def from_owl
+ OpenTox::RestClientWrapper.post(@@config[:services]["opentox-dataset"],{:content_type => "application/x-yaml"},self.to_yaml).strip
end
-=end
-
def init_dirty_features(owl)
@dirty_features = @features
@owl = owl
diff --git a/lib/environment.rb b/lib/environment.rb
index d24c37d..b53167b 100644
--- a/lib/environment.rb
+++ b/lib/environment.rb
@@ -25,8 +25,7 @@ end
# database
if @@config[:database]
- #['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types'].each{|lib| require lib }
- ['rubygems', 'datamapper'].each{|lib| require lib }
+ ['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations' ].each{|lib| require lib }
case @@config[:database][:adapter]
when /sqlite/i
db_dir = File.join(basedir, "db")
@@ -42,13 +41,16 @@ if @@config[:database]
end
end
+# mail for error messages
+load File.join config_dir,"mail.rb" if File.exists?(File.join config_dir,"mail.rb")
+
# hack: store sinatra in global var to make url_for and halt methods accessible
before{ $sinatra = self unless $sinatra }
class Sinatra::Base
# overwriting halt to log halts (!= 202)
def halt(*response)
- LOGGER.error "halt "+response.first.to_s+" "+(response.size>1 ? response[1].to_s : "") if response.first >= 300
+ LOGGER.error "halt "+response.first.to_s+" "+(response.size>1 ? response[1].to_s : "") if response and response.first and response.first >= 300
# orig sinatra code:
response = response.first if response.length == 1
throw :halt, response
@@ -105,6 +107,7 @@ end
logfile = "#{LOG_DIR}/#{ENV["RACK_ENV"]}.log"
LOGGER = MyLogger.new(logfile,'daily') # daily rotation
+LOGGER.level = Logger::WARN if ENV["RACK_ENV"] == 'production'
#LOGGER = MyLogger.new(STDOUT)
#LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S "
@@ -136,3 +139,7 @@ XML = Redland::Namespace.new 'http://www.w3.org/2001/XMLSchema#'
# Regular expressions for parsing classification data
TRUE_REGEXP = /^(true|active|$1^)/
FALSE_REGEXP = /^(false|inactive|$0^)/
+
+# Task durations
+DEFAULT_TASK_MAX_DURATION = @@config[:default_task_max_duration]
+EXTERNAL_TASK_MAX_DURATION = @@config[:external_task_max_duration]
diff --git a/lib/model.rb b/lib/model.rb
index 3553919..e3ddeb0 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -96,79 +96,12 @@ module OpenTox
def save
@features.uniq!
resource = RestClient::Resource.new(@@config[:services]["opentox-model"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.post(self.to_yaml, :content_type => "text/x-yaml").chomp.to_s
+ resource.post(self.to_yaml, :content_type => "application/x-yaml").chomp.to_s
end
def self.find_all
RestClientWrapper.get(@@config[:services]["opentox-model"]).chomp.split("\n")
end
-=begin
-
- # Predict a compound
- def predict(compound)
- # nicht absichern??
- resource = RestClient::Resource.new(@uri, :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.post(:compound_uri => compound.uri)
- end
-
- def self.base_uri
- File.join @@config[:services]["opentox-model"],'lazar'
- end
-
- def self.create(data)
- resource = RestClient::Resource.new(@@config[:services]["opentox-model"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.post(data, :content_type => "text/x-yaml").chomp.to_s
- end
-
- def delete
- resource = RestClient::Resource.new(self.uri, :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- resource.delete
- #RestClient.delete @uri if @uri
- #RestClient.delete model.task_uri if model.task_uri
- end
-
-# def self.create(task)
-# @uri = RestClient.post(@@config[:services]["opentox-model"], :task_uri => task.uri)
-# end
-
-# def yaml=(data)
-# RestClient.put(@@uri, data, :content_type => "text/x-yaml").to_s
-# end
-
- def endpoint
- YAML.load(RestClient.get(uri))[:endpoint]
- end
-
- def algorithm=(algorithm)
- me = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add me, OT['algorithm'], Redland::Uri.new(algorithm) # untyped individual comes from this line, why??
- @model.add Redland::Uri.new(algorithm), RDF['type'], OT['Algorithm']
- end
-
- def trainingDataset=(trainingDataset)
- me = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add me, OT['trainingDataset'], Redland::Uri.new(trainingDataset) # untyped individual comes from this line, why??
- @model.add Redland::Uri.new(trainingDataset), RDF['type'], OT['Dataset']
- end
-
- def dependentVariables=(dependentVariables)
- me = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add me, OT['dependentVariables'], Redland::Uri.new(dependentVariables) # untyped individual comes from this line, why??
- @model.add Redland::Uri.new(dependentVariables), RDF['type'], OT['Feature']
- end
-
- def independentVariables=(independentVariables)
- me = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add me, OT['independentVariables'], Redland::Uri.new(independentVariables) # untyped individual comes from this line, why??
- @model.add Redland::Uri.new(independentVariables), RDF['type'], OT['Feature']
- end
-
- def predictedVariables=(predictedVariables)
- me = @model.subject(RDF['type'],OT[self.owl_class])
- @model.add me, OT['predictedVariables'], Redland::Uri.new(predictedVariables) # untyped individual comes from this line, why??
- @model.add Redland::Uri.new(predictedVariables), RDF['type'], OT['Feature']
- end
-=end
end
end
end
diff --git a/lib/task.rb b/lib/task.rb
index 60c1159..88bcb71 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -1,8 +1,5 @@
LOGGER.progname = File.expand_path(__FILE__)
-DEFAULT_TASK_MAX_DURATION = 10*60*60
-EXTERNAL_TASK_MAX_DURATION = 10*60*60
-
$self_task=nil
module OpenTox
@@ -40,18 +37,14 @@ module OpenTox
end
def reload
- if uri=~ /188.40.32.88/ || uri=~/in-silico.ch/
- result = RestClientWrapper.get(uri, {:accept => 'text/x-yaml'}, false)
- else
- result = RestClientWrapper.get(uri, {:accept => 'application/rdf+xml'}, false)
- end
+ result = RestClientWrapper.get(uri, {:accept => 'application/rdf+xml'}, false)#'application/x-yaml'})
@http_code = result.code
reload_from_data(result, result.content_type, uri)
end
def reload_from_data( data, content_type, base_uri )
case content_type
- when /text\/x-yaml/
+ when /yaml/
task = YAML.load data
TASK_ATTRIBS.each do |a|
raise "task yaml data invalid, key missing: "+a.to_s unless task.has_key?(a)
diff --git a/lib/templates/config.yaml b/lib/templates/config.yaml
index ad7c4ab..3b97983 100644
--- a/lib/templates/config.yaml
+++ b/lib/templates/config.yaml
@@ -1,20 +1,68 @@
# Example configuration for OpenTox, please adjust to your settings
#
+# Database setup:
+#
+# Example MySql:
+#
+ :database:
+ :adapter: mysql
+ :database: production
+ :username: root
+ :password: opentox
+ :host: localhost
+#
# Example 1: Using external test services
#
# :services:
-# opentox-compound: "http://webservices.in-silico.ch/test/compound/"
-# opentox-dataset: "http://webservices.in-silico.ch/test/dataset/"
-# opentox-algorithm: "http://webservices.in-silico.ch/test/algorithm/"
-# opentox-model: "http://webservices.in-silico.ch/test/model/"
-# opentox-task: "http://webservices.in-silico.ch/test/task/"
+# opentox-compound: "http://webservices.in-silico.ch/compound/"
+# opentox-dataset: "http://webservices.in-silico.ch/dataset/"
+# opentox-algorithm: "http://webservices.in-silico.ch/algorithm/"
+# opentox-model: "http://webservices.in-silico.ch/model/"
+# opentox-task: "http://webservices.in-silico.ch/task/"
+# opentox-validation: "http://opentox.informatik.uni-freiburg.de/validation/"
#
# Example 2: Using local services
-# :base_dir: /home/ch/webservices
-# :webserver: thin
-# :services:
-# opentox-compound: "http://localhost:4000/"
-# opentox-dataset: "http://localhost:4001/"
-# opentox-algorithm: "http://localhost:4002/"
-# opentox-model: "http://localhost:4003/"
-# opentox-task: "http://localhost:4004/"
+ :base_dir: /home/ist/webservices
+ :webserver: passenger
+ :services:
+ opentox-compound: "http://localhost/compound/"
+ opentox-dataset: "http://localhost/dataset/"
+ opentox-algorithm: "http://localhost/algorithm/"
+ opentox-model: "http://localhost/model/"
+ opentox-task: "http://localhost/task/"
+ opentox-validation: "http://opentox.informatik.uni-freiburg.de/validation/"
+#
+# Accept headers:
+#
+ :accept_headers:
+ opentox-compound:
+ - "chemical/x-daylight-smiles"
+ - "chemical/x-inchi"
+ - "chemical/x-mdl-sdfile"
+ - "image/gif"
+ - "text/plain"
+ opentox-dataset:
+ - "application/x-yaml"
+ - "text/x-yaml"
+ - "application/rdf+xml"
+ opentox-algorithm:
+ - "application/x-yaml"
+ - "text/x-yaml"
+ - "application/rdf+xml"
+ opentox-model:
+ - "application/x-yaml"
+ - "text/x-yaml"
+ - "application/rdf+xml"
+ opentox-task:
+ - "application/x-yaml"
+ - "text/x-yaml"
+ - "application/rdf+xml"
+ opentox-validation:
+ - "application/x-yaml"
+ - "text/x-yaml"
+ - "application/rdf+xml"
+
+# Timeouts:
+#
+ :default_task_max_duration: 3600
+ :external_task_max_duration: 3600
diff --git a/lib/validation.rb b/lib/validation.rb
index 6fd5704..bd38488 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -4,8 +4,16 @@ module OpenTox
attr_accessor :uri
def initialize(params)
- resource = RestClient::Resource.new(params[:uri], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
- @uri = resource.post(params).to_s
+ #resource = RestClient::Resource.new(params[:uri], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
+ #@uri = resource.post(params).body
+ #LOGGER.debug "VALIDATION URI: " + @uri.to_s
+ call = "curl -X POST "
+ params.each do |k,v|
+ call += " -d "+k.to_s+"=\""+URI.encode(v.to_s)+"\"" unless k == :uri
+ end
+ call += " "+params[:uri]
+ LOGGER.debug call
+ @uri = `#{call}`
end
def self.crossvalidation(params)