summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormr <mr@mrautenberg.de>2011-05-23 13:04:48 +0200
committermr <mr@mrautenberg.de>2011-05-23 13:04:48 +0200
commit97cb287f1f0b8cb787a27a0776deebdb969a0b8e (patch)
tree67858a4d5a0504f3e33c0f33923019007625cf43
parent41851663e591433fec1b021b88aa77a8fb0d37b0 (diff)
parent0902a4a0b2d83d167277b82fcfd9cc12c0b993a9 (diff)
new release 2.0.0
-rw-r--r--Rakefile16
-rw-r--r--VERSION2
-rw-r--r--lib/algorithm.rb26
-rw-r--r--lib/authorization.rb29
-rw-r--r--lib/dataset.rb33
-rw-r--r--lib/environment.rb2
-rw-r--r--lib/error.rb4
-rw-r--r--lib/feature.rb25
-rw-r--r--lib/helper.rb67
-rw-r--r--lib/model.rb18
-rw-r--r--lib/ontology.rb (renamed from lib/ontology_service.rb)28
-rw-r--r--lib/opentox-ruby.rb2
-rw-r--r--lib/opentox.rb9
-rw-r--r--lib/overwrite.rb15
-rw-r--r--lib/parser.rb53
-rw-r--r--lib/rest_client_wrapper.rb2
-rw-r--r--lib/serializer.rb20
-rw-r--r--lib/task.rb2
-rw-r--r--lib/templates/config.yaml86
-rw-r--r--lib/validation.rb74
20 files changed, 296 insertions, 217 deletions
diff --git a/Rakefile b/Rakefile
index b496cc2..08959b0 100644
--- a/Rakefile
+++ b/Rakefile
@@ -28,8 +28,17 @@ begin
"tmail",
"rinruby",
"ohm",
+ "ohm-contrib",
"SystemTimer",
- "rjb"
+ "rjb",
+ #valiation-gems
+ "dm-core",
+ "dm-serializer",
+ "dm-timestamps",
+ "dm-types",
+ "dm-migrations",
+ "dm-validations",
+ "dm-sqlite-adapter"
].each { |dep| gem.add_dependency dep }
=begin
[ "dm-core",
@@ -41,11 +50,12 @@ begin
"dm-validations",
].each {|dep| gem.add_dependency dep, ">= 1" }
=end
+ #valiation-gem
gem.add_dependency "haml", ">=3"
+ # validation-gems
+ gem.add_dependency "ruby-plot", "~>0.4.0"
['jeweler'].each { |dep| gem.add_development_dependency dep }
gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
- #gem.files.include %w(lib/environment.rb, lib/algorithm.rb, lib/compound.rb, lib/dataset.rb, lib/model.rb, lib/validation.rb, lib/templates/*)
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
Jeweler::GemcutterTasks.new
rescue LoadError
diff --git a/VERSION b/VERSION
index e6d5cb8..359a5b9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.2 \ No newline at end of file
+2.0.0 \ No newline at end of file
diff --git a/lib/algorithm.rb b/lib/algorithm.rb
index 21a5729..7fbe0dc 100644
--- a/lib/algorithm.rb
+++ b/lib/algorithm.rb
@@ -52,9 +52,9 @@ module OpenTox
class BBRC
include Fminer
# Initialize bbrc algorithm
- def initialize
+ def initialize(subjectid=nil)
super File.join(CONFIG[:services]["opentox-algorithm"], "fminer/bbrc")
- load_metadata
+ load_metadata(subjectid)
end
end
@@ -62,9 +62,9 @@ module OpenTox
class LAST
include Fminer
# Initialize last algorithm
- def initialize
+ def initialize(subjectid=nil)
super File.join(CONFIG[:services]["opentox-algorithm"], "fminer/last")
- load_metadata
+ load_metadata(subjectid)
end
end
@@ -74,9 +74,9 @@ module OpenTox
class Lazar
include Algorithm
# Initialize lazar algorithm
- def initialize
+ def initialize(subjectid=nil)
super File.join(CONFIG[:services]["opentox-algorithm"], "lazar")
- load_metadata
+ load_metadata(subjectid)
end
end
@@ -167,9 +167,17 @@ module OpenTox
def self.local_svm_regression(neighbors,params )
sims = neighbors.collect{ |n| Algorithm.gauss(n[:similarity]) } # similarity values between query and neighbors
conf = sims.inject{|sum,x| sum + x }
+
+ # AM: Control log taking
+ take_logs=true
+ neighbors.each do |n|
+ if (! n[:activity].nil?) && (n[:activity].to_f < 0.0)
+ take_logs = false
+ end
+ end
acts = neighbors.collect do |n|
act = n[:activity]
- Math.log10(act.to_f)
+ take_logs ? Math.log10(act.to_f) : act.to_f
end # activities of neighbors for supervised learning
neighbor_matches = neighbors.collect{ |n| n[:features] } # as in classification: URIs of matches
@@ -214,8 +222,8 @@ module OpenTox
@r.eval "sims<-as.kernelMatrix(matrix(sims,1))"
LOGGER.debug "Predicting ..."
@r.eval "p<-predict(model,sims)[1,1]"
- prediction = 10**(@r.p.to_f)
- LOGGER.debug "Prediction is: '" + @prediction.to_s + "'."
+ prediction = 10**(@r.p.to_f) if take_logs
+ LOGGER.debug "Prediction is: '" + prediction.to_s + "'."
@r.quit # free R
end
confidence = conf/neighbors.size if neighbors.size > 0
diff --git a/lib/authorization.rb b/lib/authorization.rb
index eab20df..288733a 100644
--- a/lib/authorization.rb
+++ b/lib/authorization.rb
@@ -137,16 +137,23 @@ module OpenTox
# Lists policies alongside with affected uris
# @param [String] subjectid
# @return [Hash] keys: all policies of the subjectid owner, values: uris affected by those policies
- def self.list_policy_uris( subjectid )
+ def self.list_policies_uris( subjectid )
names = list_policies(subjectid)
policies = {}
names.each do |n|
- p = OpenTox::Policies.new
- p.load_xml( list_policy(n, subjectid) )
- policies[n] = p.uris
+ policies[n] = list_policy_uris( n, subjectid )
end
policies
end
+
+ # Lists policies alongside with affected uris
+ # @param [String] subjectid
+ # @return [Hash] keys: all policies of the subjectid owner, values: uris affected by those policies
+ def self.list_policy_uris( policy, subjectid )
+ p = OpenTox::Policies.new
+ p.load_xml( list_policy(policy, subjectid) )
+ p.uris
+ end
#Returns the owner (who created the first policy) of an URI
# @param [String, String]uri,subjectid
@@ -220,7 +227,9 @@ module OpenTox
begin
resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/search")
grps = resource.post(:admin => subjectid, :attributes_names => "objecttype", :attributes_values_objecttype => "group")
- grps.split("\n").collect{|x| x.sub("string=","")}
+ grps = grps.split("\n").collect{|x| x.sub("string=","")}
+ grps.delete_if{|g|g=="MemberManagement"||g=="Webmasters"}
+ grps
rescue
[]
end
@@ -279,10 +288,12 @@ module OpenTox
# @return [Boolean]
def self.delete_policies_from_uri(uri, subjectid)
policies = list_uri_policies(uri, subjectid)
- policies.each do |policy|
- ret = delete_policy(policy, subjectid)
- LOGGER.debug "OpenTox::Authorization delete policy: #{policy} - with result: #{ret}"
- end
+ if policies
+ policies.each do |policy|
+ ret = delete_policy(policy, subjectid)
+ LOGGER.debug "OpenTox::Authorization delete policy: #{policy} - with result: #{ret}"
+ end
+ end
return true
end
diff --git a/lib/dataset.rb b/lib/dataset.rb
index 546eb2e..4005c1c 100644
--- a/lib/dataset.rb
+++ b/lib/dataset.rb
@@ -167,24 +167,33 @@ module OpenTox
@features
end
+ def feature_classes(feature, subjectid=nil)
+ if Feature.find(feature, subjectid).feature_type == "classification"
+ classes = []
+ @data_entries.each do |c,e|
+ e[feature].each { |v| classes << v.to_s }
+ end
+ classes.uniq.sort
+ else
+ nil
+ end
+ end
+
+=begin
# Detect feature type(s) in the dataset
# @return [String] `classification", "regression", "mixed" or unknown`
def feature_type(subjectid=nil)
load_features(subjectid)
- feature_types = @features.collect{|f,metadata| metadata[OT.isA]}.uniq
- if feature_types.size > 1
- "mixed"
+ feature_types = @features.collect{|f,metadata| metadata[RDF.type]}.flatten.uniq
+ if feature_types.include?(OT.NominalFeature)
+ "classification"
+ elsif feature_types.include?(OT.NumericFeature)
+ "regression"
else
- case feature_types.first
- when /NominalFeature/
- "classification"
- when /NumericFeature/
- "regression"
- else
- "unknown"
- end
+ "unknown"
end
end
+=end
# Get Spreadsheet representation
# @return [Spreadsheet::Workbook] Workbook which can be written with the spreadsheet gem (data_entries only, metadata will will be discarded))
@@ -288,7 +297,7 @@ module OpenTox
else
compounds.each do |c|
features.each do |f|
- unless @data_entries[c][f]
+ if @data_entries[c]==nil or @data_entries[c][f]==nil
dataset.add(c,f,nil)
else
@data_entries[c][f].each do |v|
diff --git a/lib/environment.rb b/lib/environment.rb
index 59578c1..ffc4f60 100644
--- a/lib/environment.rb
+++ b/lib/environment.rb
@@ -23,7 +23,7 @@ else
end
# database
-`redis-server /opt/redis/redis.conf` unless File.exists? "/var/run/redis.pid"
+#`redis-server /opt/redis/redis.conf` unless File.exists? "/var/run/redis.pid" # removed by AM
Ohm.connect :thread_safe => true
# load mail settings for error messages
diff --git a/lib/error.rb b/lib/error.rb
index 7ca9767..b92f2a4 100644
--- a/lib/error.rb
+++ b/lib/error.rb
@@ -69,7 +69,7 @@ module OpenTox
def rdf_content()
c = {
- RDF.type => OT.ErrorReport,
+ RDF.type => [OT.ErrorReport],
OT.statusCode => @http_code,
OT.message => @message,
OT.actor => @actor,
@@ -96,4 +96,4 @@ class Array
end
short.join("\n")
end
-end \ No newline at end of file
+end
diff --git a/lib/feature.rb b/lib/feature.rb
index e768f7b..b631e46 100644
--- a/lib/feature.rb
+++ b/lib/feature.rb
@@ -16,23 +16,19 @@ module OpenTox
feature
end
- # provides domain (possible target values) of classification feature
- # @return [Array] list with possible target values
- def domain
- if metadata[OT.acceptValue]
- raise "accept value found, remove hack and implement correctly"
- else
- if @uri=~/feature\/26221/ || @uri=~/feature\/221726/
- return ["mutagen" , "nonmutagen"]
- end
- return [true, false]
- end
- end
-
# provides feature type, possible types are "regression" or "classification"
# @return [String] feature type, unknown if OT.isA property is unknown/ not set
def feature_type
- case metadata[OT.isA]
+ if metadata[RDF.type].flatten.include?(OT.NominalFeature)
+ "classification"
+ elsif metadata[RDF.type].flatten.include?(OT.NumericFeature)
+ "regression"
+ else
+ #"unknown"
+ metadata[RDF.type].inspect
+ end
+=begin
+ case metadata[RDF.type]
when /NominalFeature/
"classification"
when /NumericFeature/
@@ -40,6 +36,7 @@ module OpenTox
else
"unknown"
end
+=end
end
end
diff --git a/lib/helper.rb b/lib/helper.rb
index 7009082..3a6126a 100644
--- a/lib/helper.rb
+++ b/lib/helper.rb
@@ -44,21 +44,12 @@ helpers do
def uri_available?(urlStr)
url = URI.parse(urlStr)
- unless @subjectid
- Net::HTTP.start(url.host, url.port) do |http|
- return http.head(url.request_uri).code == "200"
- end
- else
- Net::HTTP.start(url.host, url.port) do |http|
- return http.post(url.request_uri, "subjectid=#{@subjectid}").code == "202"
- end
+ Net::HTTP.start(url.host, url.port) do |http|
+ return http.head("#{url.request_uri}?subjectid=#{CGI.escape @subjectid}").code == "200"
end
end
-end
-
-before do
- unless !AA_SERVER or login_requests or CONFIG[:authorization][:free_request].include?(env['REQUEST_METHOD'])
+ def get_subjectid
begin
subjectid = nil
subjectid = session[:subjectid] if session[:subjectid]
@@ -69,31 +60,37 @@ before do
subjectid = CGI.unescape(subjectid) if subjectid.include?("%23")
@subjectid = subjectid
rescue
- #LOGGER.debug "OpenTox ruby api wrapper: helper before filter: NO subjectid for URI: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
- subjectid = ""
+ subjectid = nil
end
- @subjectid = subjectid
- protected!(subjectid)
-
- extension = File.extname(request.path_info) # params[:id] is not yet available
+ end
+ def get_extension
+ extension = File.extname(request.path_info)
unless extension.empty?
- #request.path_info.sub!(/\.#{extension}$/,'')
- case extension
- when "html"
- @accept = 'text/html'
- when "yaml"
- @accept = 'application/x-yaml'
- when "csv"
- @accept = 'text/csv'
- when "rdfxml"
- @accept = 'application/rdf+xml'
- when "xls"
- @accept = 'application/ms-excel'
- else
- #halt 404, "File format #{extension} not supported."
- end
- end
-
+ case extension.gsub(".","")
+ when "html"
+ @accept = 'text/html'
+ when "yaml"
+ @accept = 'application/x-yaml'
+ when "csv"
+ @accept = 'text/csv'
+ when "rdfxml"
+ @accept = 'application/rdf+xml'
+ when "xls"
+ @accept = 'application/ms-excel'
+ when "css"
+ @accept = 'text/css'
+ else
+ # halt 404, "File format #{extension} not supported."
+ end
+ end
+ end
+end
+
+before do
+ @subjectid = get_subjectid()
+ @accept = get_extension()
+ unless !AA_SERVER or login_requests or CONFIG[:authorization][:free_request].include?(env['REQUEST_METHOD'])
+ protected!(@subjectid)
end
end
diff --git a/lib/model.rb b/lib/model.rb
index 74408d8..048de85 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -44,11 +44,10 @@ module OpenTox
load_metadata(subjectid) if @metadata==nil or @metadata.size==0 or (@metadata.size==1 && @metadata.values[0]==@uri)
algorithm = OpenTox::Algorithm::Generic.find(@metadata[OT.algorithm], subjectid)
algorithm_title = algorithm ? algorithm.metadata[DC.title] : nil
- algorithm_type = algorithm ? algorithm.metadata[OT.isA] : nil
+ algorithm_type = algorithm ? algorithm.metadata[RDF.type] : nil
dependent_variable = OpenTox::Feature.find( @metadata[OT.dependentVariables],subjectid )
dependent_variable_type = dependent_variable ? dependent_variable.feature_type : nil
- type_indicators = [dependent_variable_type, @metadata[OT.isA], @metadata[DC.title],
- @uri, algorithm_type, algorithm_title]
+ type_indicators = [dependent_variable_type, @metadata[RDF.type], @metadata[DC.title], @uri, algorithm_type, algorithm_title].flatten
type_indicators.each do |type|
case type
when /(?i)classification/
@@ -113,9 +112,10 @@ module OpenTox
# @param [optional,Hash] params Parameters for the lazar algorithm (OpenTox::Algorithm::Lazar)
# @return [OpenTox::Model::Lazar] lazar model
def self.create(params)
+ subjectid = params[:subjectid]
lazar_algorithm = OpenTox::Algorithm::Generic.new File.join( CONFIG[:services]["opentox-algorithm"],"lazar")
model_uri = lazar_algorithm.run(params)
- OpenTox::Model::Lazar.find(model_uri, params[:subjectid])
+ OpenTox::Model::Lazar.find(model_uri, subjectid)
end
# Get a parameter value
@@ -187,7 +187,7 @@ module OpenTox
if @neighbors.size == 0
@prediction_dataset.add_feature(prediction_feature_uri, {
- OT.isA => OT.MeasuredFeature,
+ RDF.type => [OT.MeasuredFeature],
OT.hasSource => @uri,
DC.creator => @uri,
DC.title => URI.decode(File.basename( @metadata[OT.dependentVariables] )),
@@ -198,7 +198,7 @@ module OpenTox
else
@prediction_dataset.add_feature(prediction_feature_uri, {
- OT.isA => OT.ModelPrediction,
+ RDF.type => [OT.ModelPrediction],
OT.hasSource => @uri,
DC.creator => @uri,
DC.title => URI.decode(File.basename( @metadata[OT.dependentVariables] )),
@@ -215,7 +215,7 @@ module OpenTox
feature_uri = File.join( @prediction_dataset.uri, "feature", "descriptor", f.to_s)
features[feature] = feature_uri
@prediction_dataset.add_feature(feature_uri, {
- OT.isA => OT.Substructure,
+ RDF.type => [OT.Substructure],
OT.smarts => feature,
OT.pValue => @p_values[feature],
OT.effect => @effects[feature]
@@ -236,7 +236,7 @@ module OpenTox
OT.compound => neighbor[:compound],
OT.similarity => neighbor[:similarity],
OT.measuredActivity => neighbor[:activity],
- OT.isA => OT.Neighbor
+ RDF.type => [OT.Neighbor]
})
@prediction_dataset.add @compound.uri, neighbor_uri, true
f = 0 unless f
@@ -250,7 +250,7 @@ module OpenTox
unless features.has_key? feature
features[feature] = feature_uri
@prediction_dataset.add_feature(feature_uri, {
- OT.isA => OT.Substructure,
+ RDF.type => [OT.Substructure],
OT.smarts => feature,
OT.pValue => @p_values[feature],
OT.effect => @effects[feature]
diff --git a/lib/ontology_service.rb b/lib/ontology.rb
index 4ff688f..fa4ea6f 100644
--- a/lib/ontology_service.rb
+++ b/lib/ontology.rb
@@ -1,6 +1,7 @@
module OpenTox
- module OntologyService
- module Endpoints
+ module Ontology
+ module Echa
+=begin
require 'sparql/client'
@sparql = SPARQL::Client.new("http://apps.ideaconsult.net:8080/ontology")
def self.qs(classname="Endpoints")
@@ -12,11 +13,11 @@ module OpenTox
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX otee:<http://www.opentox.org/echaEndpoints.owl#>
PREFIX toxcast:<http://www.opentox.org/toxcast.owl#>
- select ?Endpoints ?title ?id
- where {?Endpoints rdfs:subClassOf otee:#{classname}.
- OPTIONAL {?Endpoints dc:title ?title}.
- OPTIONAL {?Endpoints dc:identifier ?id}.}
- ORDER BY ?title"
+ select *
+ where {
+ ?endpoint rdfs:subClassOf otee:#{classname}.
+ ?endpoint dc:title ?title.
+ }"
end
def self.make_option_list(endpoint="Endpoints", level=1)
@@ -38,6 +39,17 @@ module OpenTox
out += "</select>\n"
return out
end
+=end
+
+ def self.endpoints
+ RestClientWrapper.get("http://apps.ideaconsult.net:8080/ambit2/query/ndatasets_endpoint",:accept => "text/csv").collect { |line| line.split(',').first if line.match(/^http/) }.compact
+ end
+
+ def self.datasets(endpoint)
+ RestClientWrapper.get("http://apps.ideaconsult.net:8080/ambit2/dataset?feature_sameas=#{URI.encode endpoint}", :accept => "text/uri-list").split("\n")
+ end
+
end
+
end
-end \ No newline at end of file
+end
diff --git a/lib/opentox-ruby.rb b/lib/opentox-ruby.rb
index ab8d824..ae05cb2 100644
--- a/lib/opentox-ruby.rb
+++ b/lib/opentox-ruby.rb
@@ -9,6 +9,6 @@ rescue LoadError
end
['opentox', 'compound','dataset', 'parser','serializer', 'algorithm','model','task','validation','feature',
- 'rest_client_wrapper', 'authorization', 'policy', 'helper', 'to-html' ].each do |lib|
+ 'rest_client_wrapper', 'authorization', 'policy', 'helper', 'to-html', 'ontology' ].each do |lib|
require lib
end
diff --git a/lib/opentox.rb b/lib/opentox.rb
index 1992896..c76e21a 100644
--- a/lib/opentox.rb
+++ b/lib/opentox.rb
@@ -31,7 +31,14 @@ module OpenTox
end
def add_metadata(metadata)
- metadata.each { |k,v| @metadata[k] = v }
+ metadata.each do |k,v|
+ if v.is_a? Array
+ @metadata[k] = [] unless @metadata[k]
+ @metadata[k] << v
+ else
+ @metadata[k] = v
+ end
+ end
end
# Get OWL-DL representation in RDF/XML format
diff --git a/lib/overwrite.rb b/lib/overwrite.rb
index fbe775d..df4e1b7 100644
--- a/lib/overwrite.rb
+++ b/lib/overwrite.rb
@@ -8,6 +8,7 @@ before {
$url_provider = self
# stupid internet explorer does not ask for text/html, add this manually
request.env['HTTP_ACCEPT'] += ";text/html" if request.env["HTTP_USER_AGENT"]=~/MSIE/
+ request.env['HTTP_ACCEPT']=request.params["media"] if request.params["media"]
}
# Error handling
@@ -39,20 +40,24 @@ end
class Sinatra::Base
def return_task( task )
- code = task.running? ? 202 : 200
+ raise "http_code == nil" unless task.http_code!=nil
case request.env['HTTP_ACCEPT']
when /rdf/
response['Content-Type'] = "application/rdf+xml"
- halt code,task.to_rdfxml
+ halt task.http_code,task.to_rdfxml
when /yaml/
response['Content-Type'] = "application/x-yaml"
- halt code,task.to_yaml # PENDING differs from task-webservice
+ halt task.http_code,task.to_yaml # PENDING differs from task-webservice
when /html/
response['Content-Type'] = "text/html"
- halt code,OpenTox.text_to_html(task.to_yaml, @subjectid)
+ halt task.http_code,OpenTox.text_to_html(task.to_yaml, @subjectid)
else # default /uri-list/
response['Content-Type'] = "text/uri-list"
- halt code,task.uri+"\n"
+ if task.completed?
+ halt task.http_code,task.resultURI+"\n"
+ else
+ halt task.http_code,task.uri+"\n"
+ end
end
end
end
diff --git a/lib/parser.rb b/lib/parser.rb
index f33017d..7bdee95 100644
--- a/lib/parser.rb
+++ b/lib/parser.rb
@@ -55,7 +55,14 @@ module OpenTox
parameter_ids = []
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
triple = line.to_triple
- @metadata[triple[1]] = triple[2].split('^^').first if triple[0] == @uri and triple[1] != RDF['type']
+ if triple[0] == @uri
+ if triple[1] == RDF.type # allow multiple types
+ @metadata[triple[1]] = [] unless @metadata[triple[1]]
+ @metadata[triple[1]] << triple[2].split('^^').first
+ else
+ @metadata[triple[1]] = triple[2].split('^^').first
+ end
+ end
statements << triple
parameter_ids << triple[2] if triple[1] == OT.parameters
end
@@ -156,6 +163,7 @@ module OpenTox
data = {}
feature_values = {}
feature = {}
+ feature_accept_values = {}
other_statements = {}
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
triple = line.chomp.split(' ',3)
@@ -175,6 +183,9 @@ module OpenTox
if triple[2]=~/#{OT.Compound}/i and !data[triple[0]]
data[triple[0]] = {:compound => triple[0], :values => []}
end
+ when /#{OT.acceptValue}/i # acceptValue in ambit datasets is only provided in dataset/<id> no in dataset/<id>/features
+ feature_accept_values[triple[0]] = [] unless feature_accept_values[triple[0]]
+ feature_accept_values[triple[0]] << triple[2]
else
end
end
@@ -185,20 +196,25 @@ module OpenTox
@dataset.add_compound(entry[:compound])
else
entry[:values].each do |value_id|
- split = feature_values[value_id].split(/\^\^/)
- case split[-1]
- when XSD.double, XSD.float
- value = split.first.to_f
- when XSD.boolean
- value = split.first=~/(?i)true/ ? true : false
- else
- value = split.first
+ if feature_values[value_id]
+ split = feature_values[value_id].split(/\^\^/)
+ case split[-1]
+ when XSD.double, XSD.float
+ value = split.first.to_f
+ when XSD.boolean
+ value = split.first=~/(?i)true/ ? true : false
+ else
+ value = split.first
+ end
end
@dataset.add entry[:compound],feature[value_id],value
end
end
end
load_features subjectid
+ feature_accept_values.each do |feature, values|
+ @dataset.features[feature][OT.acceptValue] = values
+ end
@dataset.metadata = load_metadata(subjectid)
@dataset
end
@@ -223,7 +239,7 @@ module OpenTox
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
triple = line.chomp.split('> ').collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}[0..2]
statements << triple
- features << triple[0] if triple[1] == RDF['type'] and (triple[2] == OT.Feature || triple[2] == OT.NumericFeature)
+ features << triple[0] if triple[1] == RDF.type and (triple[2] =~ /Feature|Substructure/)
end
File.delete(to_delete) if to_delete
statements.each do |triple|
@@ -289,7 +305,7 @@ module OpenTox
else
type = types.first
end
- @dataset.add_feature_metadata(feature,{OT.isA => type})
+ @dataset.add_feature_metadata(feature,{RDF.type => [type]})
info += "\"#{@dataset.feature_name(feature)}\" detected as #{type.split('#').last}."
# TODO: rewrite feature values
@@ -341,16 +357,23 @@ module OpenTox
when OT.NominalFeature
case value.to_s
when TRUE_REGEXP
- @dataset.add(compound.uri, feature, true )
+ val = true
when FALSE_REGEXP
- @dataset.add(compound.uri, feature, false )
+ val = false
end
when OT.NumericFeature
- @dataset.add compound.uri, feature, value.to_f
+ val = value.to_f
when OT.StringFeature
- @dataset.add compound.uri, feature, value.to_s
+ val = value.to_s
@activity_errors << smiles+", "+row.join(", ")
end
+ if val!=nil
+ @dataset.add(compound.uri, feature, val)
+ if type!=OT.NumericFeature
+ @dataset.features[feature][OT.acceptValue] = [] unless @dataset.features[feature][OT.acceptValue]
+ @dataset.features[feature][OT.acceptValue] << val.to_s unless @dataset.features[feature][OT.acceptValue].include?(val.to_s)
+ end
+ end
end
end
diff --git a/lib/rest_client_wrapper.rb b/lib/rest_client_wrapper.rb
index dac24dc..747a353 100644
--- a/lib/rest_client_wrapper.rb
+++ b/lib/rest_client_wrapper.rb
@@ -98,6 +98,8 @@ module OpenTox
rescue RestClient::RequestTimeout => ex
received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload}
+ rescue Errno::ETIMEDOUT => ex
+ received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload}
rescue Errno::ECONNREFUSED => ex
received_error ex.message, 500, nil, {:rest_uri => uri, :headers => headers, :payload => payload}
rescue RestClient::ExceptionWithResponse => ex
diff --git a/lib/serializer.rb b/lib/serializer.rb
index 44b4414..e4cb541 100644
--- a/lib/serializer.rb
+++ b/lib/serializer.rb
@@ -26,6 +26,8 @@ module OpenTox
OT.Algorithm => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
OT.Parameter => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
OT.Task => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
+ OTA.PatternMiningSupervised => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
+
#classes for validation
OT.Validation => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
OT.ClassificationStatistics => { RDF["type"] => [{ "type" => "uri", "value" => OWL['Class'] }] } ,
@@ -40,10 +42,10 @@ module OpenTox
OT.compound => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.feature => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.dataEntry => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
- OT.acceptValue => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.values => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.algorithm => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.parameters => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
+
#object props for validation#
OT.model => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
OT.trainingDataset => { RDF["type"] => [{ "type" => "uri", "value" => OWL.ObjectProperty }] } ,
@@ -67,12 +69,14 @@ module OpenTox
DC.creator => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
DC.description => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
DC.date => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
- OT.isA => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
+ #OT.isA => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
OT.Warnings => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
XSD.anyURI => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
OT.hasStatus => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
OT.resultURI => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
OT.percentageCompleted => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
+ OT.acceptValue => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
+
# annotation props for validation
OT.numUnpredicted => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
OT.crossvalidationFold => { RDF["type"] => [{ "type" => "uri", "value" => OWL.AnnotationProperty }] } ,
@@ -256,7 +260,8 @@ module OpenTox
def add_metadata(uri,metadata)
id = 0
metadata.each do |u,v|
- if v.is_a? Array and u == OT.parameters
+ #if v.is_a? Array and (u == OT.parameters or u == RDF.type)
+ if v.is_a? Array and u == OT.parameters#or u == RDF.type)
@object[uri][u] = [] unless @object[uri][u]
v.each do |value|
id+=1
@@ -267,7 +272,13 @@ module OpenTox
@object[genid][name] = [{"type" => type(entry), "value" => entry }]
end
end
- else # v.is_a? String
+ elsif v.is_a? Array and u == RDF.type
+ @object[uri] = {} unless @object[uri]
+ v.each do |value|
+ @object[uri][u] = [] unless @object[uri][u]
+ @object[uri][u] << {"type" => type(value), "value" => value }
+ end
+ elsif v.is_a? String
@object[uri] = {} unless @object[uri]
@object[uri][u] = [{"type" => type(v), "value" => v }]
end
@@ -309,6 +320,7 @@ module OpenTox
OT.value => v
}
@object[feature][RDF["type"]] << { "type" => "uri", "value" => featuretype(value) }
+ #@object[feature][RDF["type"]] = { "type" => "uri", "value" => featuretype(value) }
end
# Serializers
diff --git a/lib/task.rb b/lib/task.rb
index 0ee3a11..19f42d6 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -8,6 +8,7 @@ module OpenTox
def initialize(uri=nil)
super uri
+ @http_code = 202
@metadata = {
DC.title => "",
DC.date => "",
@@ -154,6 +155,7 @@ module OpenTox
# not stored just for to_rdf
def add_error_report( error_report )
+ raise "not an error report: "+error_report.class.to_s unless error_report.is_a?(ErrorReport)
@error_report = error_report
end
diff --git a/lib/templates/config.yaml b/lib/templates/config.yaml
deleted file mode 100644
index 8a5e460..0000000
--- a/lib/templates/config.yaml
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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/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/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://localhost/validation/"
-#
-# Yaml capable hosts (faster than OWL-DL)
-#
-:yaml_hosts:
- - "localhost"
-
-# Uncomment for verbose logging
-# :logger: debug
-# :backtrace: 1
-
-
-# OpenSSO Authorization
-# set ":server: " to disable A&A
-:authorization:
- :server: "https://opensso.in-silico.ch"
- :free_request: #request-method not controlled by A&A
- - "GET"
- :authenticate_request: #only for authenticated user
- - "POST"
- :authorize_request: #only for authenticated and authorizeduser
- - "DELETE"
- - "PUT"
- # Exceptions:
- :free_uris: #request-method for uri not controlled by A&A
- ? - :GET
- : - !ruby/regexp /localhost\/algorithm/
- - "http://localhost/dataset"
- - "http://localhost/model"
- - "http://localhost/validation"
- - "http://localhost/validation/crossvalidation"
- - "http://localhost/validation/reach_report"
- - "http://localhost/validation/reach_report/crossvalidation"
- - "http://localhost/validation/report"
- - "http://localhost/validation/report/crossvalidation"
- - "http://localhost/validation/reach_report/qmrf"
- ? - :GET
- - :POST
- : - !ruby/regexp /localhost\/toxcreate/
- - !ruby/regexp /localhost\/task/
- - !ruby/regexp /localhost\/compound/
- ? - :PUT
- : - !ruby/regexp /localhost\/task/
-
- :authorize_exceptions: #request-method for uri only authenticated, no authorization
- ? - :POST
- : - !ruby/regexp /localhost\/algorithm/
- - "http://localhost/dataset"
- - "http://localhost/model"
- - "http://localhost/validation"
- - !ruby/regexp /localhost\/validation\/[a-z,A-Z,\/,_\-]*$/
-
-
- \ No newline at end of file
diff --git a/lib/validation.rb b/lib/validation.rb
index a47a554..d58d36e 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -12,6 +12,40 @@ module OpenTox
val
end
+ # returns a filtered list of validation uris
+ # @param [Hash,optional] params, validation-params to filter the uris (could be model, training_dataset, ..)
+ # @return [Array]
+ def self.list( params={} )
+ filter_string = ""
+ params.each do |k,v|
+ filter_string = "?" if filter_string.length==0
+ filter_string += k.to_s+"="+v
+ end
+ (OpenTox::RestClientWrapper.get(CONFIG[:services]["opentox-validation"]+filter_string).split("\n"))
+ end
+
+ # creates a training test split validation, waits until it finishes, may take some time
+ # @param [Hash] params (required:algorithm_uri,dataset_uri,prediction_feature, optional:algorithm_params,split_ratio(0.67),random_seed(1))
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [OpenTox::Validation]
+ def self.create_training_test_split( params, subjectid=nil, waiting_task=nil )
+ params[:subjectid] = subjectid if subjectid
+ uri = OpenTox::RestClientWrapper.post( File.join(CONFIG[:services]["opentox-validation"],"training_test_split"),
+ params,{:content_type => "text/uri-list"},waiting_task )
+ Validation.new(uri)
+ end
+
+ # looks for report for this validation, creates a report if no report is found
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [String] report uri
+ def find_or_create_report( subjectid=nil, waiting_task=nil )
+ @report = ValidationReport.find_for_validation(@uri, subjectid) unless @report
+ @report = ValidationReport.create(@uri, subjectid, waiting_task) unless @report
+ @report.uri
+ end
+
# creates a validation object from crossvaldiation statistics, raise error if not found
# (as crossvaldiation statistics are returned as an average valdidation over all folds)
# @param [String] crossvalidation uri
@@ -42,7 +76,7 @@ module OpenTox
res[:true_negatives] = s[OT.numTrueNegatives]
res[:false_negatives] = s[OT.numFalseNegatives]
res[:sensitivity] = s[OT.truePositiveRate]
- res[:specificity] = s[OT.falsePositiveRate]
+ res[:specificity] = s[OT.trueNegativeRate]
break
end
end
@@ -72,6 +106,18 @@ module OpenTox
cv.load_metadata( subjectid )
cv
end
+
+ # returns a filtered list of crossvalidation uris
+ # @param [Hash,optional] params, crossvalidation-params to filter the uris (could be algorithm, dataset, ..)
+ # @return [Array]
+ def self.list( params={} )
+ filter_string = ""
+ params.each do |k,v|
+ filter_string = "?" if filter_string.length==0
+ filter_string += k.to_s+"="+v
+ end
+ (OpenTox::RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],"crossvalidation")+filter_string).split("\n"))
+ end
# creates a crossvalidations, waits until it finishes, may take some time
# @param [Hash] params (required:algorithm_uri,dataset_uri,prediction_feature, optional:algorithm_params,num_folds(10),random_seed(1),stratified(false))
@@ -110,6 +156,17 @@ module OpenTox
class ValidationReport
include OpenTox
+ # finds ValidationReport via uri, raises error if not found
+ # @param [String] uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::ValidationReport]
+ def self.find( uri, subjectid=nil )
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
+ rep = ValidationReport.new(uri)
+ rep.load_metadata( subjectid )
+ rep
+ end
+
# finds ValidationReport for a particular validation
# @param [String] crossvalidation uri
# @param [String,optional] subjectid
@@ -120,6 +177,17 @@ module OpenTox
uris.size==0 ? nil : ValidationReport.new(uris[-1])
end
+ # creates a validation report via validation
+ # @param [String] validation uri
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [OpenTox::ValidationReport]
+ def self.create( validation_uri, subjectid=nil, waiting_task=nil )
+ uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/validation"),
+ { :validation_uris => validation_uri, :subjectid => subjectid }, {}, waiting_task )
+ ValidationReport.new(uri)
+ end
+
end
class CrossvalidationReport
@@ -132,7 +200,9 @@ module OpenTox
def self.find( uri, subjectid=nil )
# PENDING load report data?
OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
- CrossvalidationReport.new(uri)
+ rep = CrossvalidationReport.new(uri)
+ rep.load_metadata( subjectid )
+ rep
end
# finds CrossvalidationReport for a particular crossvalidation