summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2011-02-04 16:42:35 +0100
committerChristoph Helma <helma@in-silico.ch>2011-02-04 16:42:35 +0100
commitbeaabdac3faf7b2ad86fa719f0726a8907706721 (patch)
treea2767cdbf89b8b39e6b69a12c5ee895b6c32f406
parent55f81bb50e76e99f370516ec8625a5aae902e898 (diff)
parente035b7136b8c2df70de980379695fbfeaf070290 (diff)
Merge commit 'mguetlein/development' into development
Conflicts: lib/validation.rb
-rw-r--r--lib/algorithm.rb4
-rw-r--r--lib/authorization.rb7
-rw-r--r--lib/dataset.rb2
-rw-r--r--lib/environment.rb4
-rw-r--r--lib/error.rb41
-rw-r--r--lib/model.rb4
-rw-r--r--lib/overwrite.rb28
-rw-r--r--lib/parser.rb33
-rw-r--r--lib/rest_client_wrapper.rb44
-rw-r--r--lib/task.rb10
-rw-r--r--lib/validation.rb158
-rw-r--r--opentox-ruby.gemspec13
12 files changed, 274 insertions, 74 deletions
diff --git a/lib/algorithm.rb b/lib/algorithm.rb
index ee3109c..bfa9860 100644
--- a/lib/algorithm.rb
+++ b/lib/algorithm.rb
@@ -16,7 +16,7 @@ module OpenTox
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
# @return [String] URI of new resource (dataset, model, ...)
def run(params=nil, waiting_task=nil)
- RestClientWrapper.post(@uri, {:accept => 'text/uri-list'}, params, waiting_task).to_s
+ RestClientWrapper.post(@uri, params, {:accept => 'text/uri-list'}, waiting_task).to_s
end
# Get OWL-DL representation in RDF/XML format
@@ -34,7 +34,7 @@ module OpenTox
# Find Generic Opentox Algorithm via URI, and loads metadata
# @param [String] uri Algorithm URI
# @return [OpenTox::Algorithm::Generic] Algorithm instance, nil if alogrithm was not found
- def self.find(uri, subjectid)
+ def self.find(uri, subjectid=nil)
return nil unless uri
alg = Generic.new(uri)
alg.load_metadata( subjectid )
diff --git a/lib/authorization.rb b/lib/authorization.rb
index b4c1ee5..dd7dc12 100644
--- a/lib/authorization.rb
+++ b/lib/authorization.rb
@@ -195,7 +195,7 @@ module OpenTox
# resource = RestClient::Resource.new("#{AA_SERVER}/Pol/opensso-pol")
LOGGER.debug "OpenTox::Authorization.create_policy policy: #{policy[168,43]} with token:" + subjectid.to_s + " length: " + subjectid.length.to_s
# return true if resource.post(policy, :subjectid => subjectid, :content_type => "application/xml")
- return true if RestClientWrapper.post("#{AA_SERVER}/pol", {:subjectid => subjectid, :content_type => "application/xml"}, policy)
+ return true if RestClientWrapper.post("#{AA_SERVER}/pol", policy, {:subjectid => subjectid, :content_type => "application/xml"})
rescue
return false
end
@@ -381,4 +381,9 @@ module OpenTox
end
end
+# PENDING delete as soon as new free uri handling is merged
+# this allows GET access to all URIS that do NOT end with /<number> or /<number>/
+OpenTox::Authorization.whitelist( /\/[0-9]+(\/?)$/, "GET", true )
+OpenTox::Authorization.whitelist( /\/[0-9]+(\/?)$/, "POST", true )
+
diff --git a/lib/dataset.rb b/lib/dataset.rb
index 9c20968..a4716dc 100644
--- a/lib/dataset.rb
+++ b/lib/dataset.rb
@@ -285,7 +285,7 @@ module OpenTox
@compounds.uniq!
if @uri
if (CONFIG[:yaml_hosts].include?(URI.parse(@uri).host))
- RestClientWrapper.post(@uri,{:content_type => "application/x-yaml", :subjectid => subjectid},self.to_yaml)
+ RestClientWrapper.post(@uri,self.to_yaml,{:content_type => "application/x-yaml", :subjectid => subjectid})
else
File.open("ot-post-file.rdf","w+") { |f| f.write(self.to_rdfxml); @path = f.path }
task_uri = RestClient.post(@uri, {:file => File.new(@path)},{:accept => "text/uri-list" , :subjectid => subjectid}).to_s.chomp
diff --git a/lib/environment.rb b/lib/environment.rb
index 203ebc6..b30b3f3 100644
--- a/lib/environment.rb
+++ b/lib/environment.rb
@@ -54,8 +54,8 @@ else
end
# Regular expressions for parsing classification data
-TRUE_REGEXP = /^(true|active|1|1.0)$/i
-FALSE_REGEXP = /^(false|inactive|0|0.0)$/i
+TRUE_REGEXP = /^(true|active|1|1.0|tox)$/i
+FALSE_REGEXP = /^(false|inactive|0|0.0|low tox)$/i
# Task durations
DEFAULT_TASK_MAX_DURATION = 36000
diff --git a/lib/error.rb b/lib/error.rb
index 8c666f3..49756d5 100644
--- a/lib/error.rb
+++ b/lib/error.rb
@@ -18,6 +18,10 @@ module OpenTox
class NotFoundError < RuntimeError
def http_code; 404; end
end
+
+ class ServiceUnavailableError < RuntimeError
+ def http_code; 503; end
+ end
class RestCallError < RuntimeError
attr_accessor :rest_params
@@ -28,18 +32,31 @@ module OpenTox
# TODO replace params with URIs (errorCause -> OT.errorCause)
attr_reader :message, :actor, :errorCause, :http_code, :errorDetails, :errorType
+
+ private
+ def initialize( http_code, erroType, message, actor, errorCause, rest_params=nil, backtrace=nil )
+ @http_code = http_code
+ @errorType = erroType
+ @message = message
+ @actor = actor
+ @errorCause = errorCause
+ @rest_params = rest_params
+ @backtrace = backtrace
+ end
+ public
# creates a error report object, from an ruby-exception object
- # @param [Exception] error
- # @param [String] actor, URI of the call that cause the error
- def initialize( error, actor )
- @http_code = error.http_code
- @errorType = error.class.to_s
- @message = error.message
- @actor = actor
- @errorCause = error.errorCause if error.errorCause
- @rest_params = error.rest_params if error.is_a?(OpenTox::RestCallError) and error.rest_params
- @backtrace = error.backtrace.short_backtrace if CONFIG[:backtrace]
+ # @param [Exception] error
+ # @param [String] actor, URI of the call that cause the error
+ def self.create( error, actor )
+ rest_params = error.rest_params if error.is_a?(OpenTox::RestCallError) and error.rest_params
+ backtrace = error.backtrace.short_backtrace if CONFIG[:backtrace]
+ ErrorReport.new( error.http_code, error.class.to_s, error.message, actor, error.errorCause, rest_params, backtrace )
+ end
+
+ def self.from_rdf(rdf)
+ metadata = OpenTox::Parser::Owl.metadata_from_rdf( rdf, OT.ErrorReport )
+ ErrorReport.new(metadata[OT.statusCode], metadata[OT.errorCode], metadata[OT.message], metadata[OT.actor], metadata[OT.errorCause])
end
# overwrite sorting to make easier readable
@@ -61,10 +78,6 @@ module OpenTox
c[OT.errorCause] = @errorCause.rdf_content if @errorCause
c
end
-
- def self.from_rdf(rdf)
- raise "not yet implemented"
- end
def to_rdfxml
s = Serializer::Owl.new
diff --git a/lib/model.rb b/lib/model.rb
index 80d7ec4..7cf52ad 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -17,7 +17,7 @@ module OpenTox
end
end
LOGGER.info "running model "+@uri.to_s+", params: "+params.inspect+", accept: "+accept_header.to_s
- RestClientWrapper.post(@uri,{:accept => accept_header},params,waiting_task).to_s
+ RestClientWrapper.post(@uri,params,{:accept => accept_header},waiting_task).to_s
end
# Generic OpenTox model class for all API compliant services
@@ -303,7 +303,7 @@ module OpenTox
# Save model at model service
def save(subjectid)
- self.uri = RestClientWrapper.post(@uri,{:content_type => "application/x-yaml", :subjectid => subjectid},self.to_yaml)
+ self.uri = RestClientWrapper.post(@uri,self.to_yaml,{:content_type => "application/x-yaml", :subjectid => subjectid})
end
# Delete model at model service
diff --git a/lib/overwrite.rb b/lib/overwrite.rb
index e52618c..7b53122 100644
--- a/lib/overwrite.rb
+++ b/lib/overwrite.rb
@@ -16,13 +16,12 @@ before {
# IMPT: set sinatra settings :show_exceptions + :raise_errors to false in config.ru, otherwise Rack::Showexceptions takes over
error Exception do
error = request.env['sinatra.error']
- # log error to logfile
+ # log error message and backtrace to logfile
LOGGER.error error.class.to_s+": "+error.message
- # log backtrace only if code is 500 -> unwanted (Runtime)Exceptions and internal errors (see error.rb)
- LOGGER.error ":\n"+error.backtrace.join("\n") if error.http_code==500
+ LOGGER.error ":\n"+error.backtrace.join("\n")
actor = "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
- rep = OpenTox::ErrorReport.new(error, actor)
+ rep = OpenTox::ErrorReport.create(error, actor)
case request.env['HTTP_ACCEPT']
when /rdf/
@@ -37,6 +36,27 @@ error Exception do
end
end
+class Sinatra::Base
+
+ def return_task( task )
+ code = task.running? ? 202 : 200
+ case request.env['HTTP_ACCEPT']
+ when /rdf/
+ response['Content-Type'] = "application/rdf+xml"
+ halt code,task.to_rdfxml
+ when /yaml/
+ response['Content-Type'] = "application/rdf+xml"
+ halt 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)
+ else # default /uri-list/
+ response['Content-Type'] = "text/uri-list"
+ halt code,task.uri+"\n"
+ end
+ end
+end
+
class String
def task_uri?
self.uri? && !self.match(/task/).nil?
diff --git a/lib/parser.rb b/lib/parser.rb
index a913cf2..e055eec 100644
--- a/lib/parser.rb
+++ b/lib/parser.rb
@@ -30,7 +30,6 @@ module OpenTox
# Read metadata from opentox service
# @return [Hash] Object metadata
def load_metadata(subjectid=nil)
-
if @dataset
uri = File.join(@uri,"metadata")
else
@@ -55,6 +54,38 @@ module OpenTox
end
@metadata
end
+
+ # loads metadata from rdf-data
+ # @param [String] rdf
+ # @param [String] type of the info (e.g. OT.Task, OT.ErrorReport) needed to get the subject-uri
+ # @return [Hash] metadata
+ def self.metadata_from_rdf( rdf, type )
+ # write to file and read convert with rapper into tripples
+ file = Tempfile.new("ot-rdfxml")
+ file.puts rdf
+ file.close
+ file = "file://"+file.path
+ #puts "cmd: rapper -i rdfxml -o ntriples #{file} 2>/dev/null"
+ triples = `rapper -i rdfxml -o ntriples #{file} 2>/dev/null`
+
+ # load uri via type
+ uri = nil
+ triples.each_line do |line|
+ triple = line.to_triple
+ if triple[1] == RDF['type'] and triple[2]==type
+ raise "uri already set, two uris found with type: "+type.to_s if uri
+ uri = triple[0]
+ end
+ end
+
+ # load metadata
+ metadata = {}
+ triples.each_line do |line|
+ triple = line.to_triple
+ metadata[triple[1]] = triple[2].split('^^').first if triple[0] == uri and triple[1] != RDF['type']
+ end
+ metadata
+ end
# Generic parser for all OpenTox classes
class Generic
diff --git a/lib/rest_client_wrapper.rb b/lib/rest_client_wrapper.rb
index 7c2d719..658f111 100644
--- a/lib/rest_client_wrapper.rb
+++ b/lib/rest_client_wrapper.rb
@@ -14,21 +14,21 @@ module OpenTox
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
# @param [wait,Boolean] wait set to false to NOT wait for task if result is task
# @return [OpenTox::WrapperResult] a String containing the result-body of the REST call
- def self.get(uri, headers=nil, waiting_task=nil, wait=true )
- execute( "get", uri, headers, nil, waiting_task, wait)
+ def self.get(uri, headers={}, waiting_task=nil, wait=true )
+ execute( "get", uri, nil, headers, waiting_task, wait)
end
# performs a POST REST call
# raises OpenTox::Error if call fails (rescued in overwrite.rb -> halt 502)
# per default: waits for Task to finish and returns result URI of Task
# @param [String] uri destination URI
- # @param [optional,Hash] headers contains params like accept-header
# @param [optional,String] payload data posted to the service
+ # @param [optional,Hash] headers contains params like accept-header
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
# @param [wait,Boolean] wait set to false to NOT wait for task if result is task
# @return [OpenTox::WrapperResult] a String containing the result-body of the REST call
- def self.post(uri, headers, payload=nil, waiting_task=nil, wait=true )
- execute( "post", uri, headers, payload, waiting_task, wait )
+ def self.post(uri, payload=nil, headers={}, waiting_task=nil, wait=true )
+ execute( "post", uri, payload, headers, waiting_task, wait )
end
# performs a PUT REST call
@@ -37,8 +37,8 @@ module OpenTox
# @param [optional,Hash] headers contains params like accept-header
# @param [optional,String] payload data put to the service
# @return [OpenTox::WrapperResult] a String containing the result-body of the REST call
- def self.put(uri, headers, payload=nil )
- execute( "put", uri, headers, payload )
+ def self.put(uri, payload=nil, headers={} )
+ execute( "put", uri, payload, headers )
end
# performs a DELETE REST call
@@ -47,36 +47,42 @@ module OpenTox
# @param [optional,Hash] headers contains params like accept-header
# @return [OpenTox::WrapperResult] a String containing the result-body of the REST call
def self.delete(uri, headers=nil )
- execute( "delete", uri, headers, nil)
+ execute( "delete", uri, nil, headers)
end
private
- def self.execute( rest_call, uri, headers, payload=nil, waiting_task=nil, wait=true )
+ def self.execute( rest_call, uri, payload=nil, headers={}, waiting_task=nil, wait=true )
raise OpenTox::BadRequestError.new "uri is null" unless uri
raise OpenTox::BadRequestError.new "not a uri: "+uri.to_s unless uri.to_s.uri?
- raise OpenTox::BadRequestError.new "headers are no hash: "+headers.inspect unless headers==nil or headers.is_a?(Hash)
- raise OpenTox::BadRequestError.new "nil headers for post not allowed, use {}" if rest_call=="post" and headers==nil
+ raise "headers are no hash: "+headers.inspect unless headers==nil or headers.is_a?(Hash)
+ raise OpenTox::BadRequestError.new "accept should go into the headers" if payload and payload.is_a?(Hash) and payload[:accept]
+ raise OpenTox::BadRequestError.new "content_type should go into the headers" if payload and payload.is_a?(Hash) and payload[:content_type]
+ raise "__waiting_task__ must be 'nil' or '(sub)task', is "+waiting_task.class.to_s if
+ waiting_task!=nil and !(waiting_task.is_a?(Task) || waiting_task.is_a?(SubTask))
headers.each{ |k,v| headers.delete(k) if v==nil } if headers #remove keys with empty values, as this can cause problems
+ # PENDING needed for NUTA, until we finally agree on how to send subjectid
+ headers[:subjectid] = payload.delete(:subjectid) if uri=~/ntua/ and payload and payload.is_a?(Hash) and payload.has_key?(:subjectid)
+
begin
#LOGGER.debug "RestCall: "+rest_call.to_s+" "+uri.to_s+" "+headers.inspect+" "+payload.inspect
- resource = RestClient::Resource.new(uri,{:timeout => 60})
- if payload
+ resource = RestClient::Resource.new(uri,{:timeout => 60})
+ if rest_call=="post" || rest_call=="put"
result = resource.send(rest_call, payload, headers)
- elsif headers
- result = resource.send(rest_call, headers)
else
- result = resource.send(rest_call)
+ result = resource.send(rest_call, headers)
end
+ # PENDING NTUA does return errors with 200
+ raise RestClient::ExceptionWithResponse.new(result) if uri=~/ntua/ and result.body =~ /about.*http:\/\/anonymous.org\/error/
+
# result is a string, with the additional fields content_type and code
res = WrapperResult.new(result.body)
res.content_type = result.headers[:content_type]
raise "content-type not set" unless res.content_type
res.code = result.code
- #LOGGER.debug "RestCall result: "+res.to_s+" "+res.code.to_s+" "+res.content_type.to_s
# TODO: Ambit returns task representation with 200 instead of result URI
return res if res.code==200 || !wait
@@ -87,10 +93,10 @@ module OpenTox
return res
rescue RestClient::RequestTimeout => ex
- received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers}
+ received_error ex.message, 408, nil, {:rest_uri => uri, :headers => headers, :payload => payload}
rescue RestClient::ExceptionWithResponse => ex
# error comming from a different webservice,
- received_error ex.http_body, ex.http_code, ex.response.net_http_res.content_type, {:rest_uri => uri, :headers => headers}
+ received_error ex.http_body, ex.http_code, ex.response.net_http_res.content_type, {:rest_uri => uri, :headers => headers, :payload => payload}
rescue OpenTox::RestCallError => ex
# already a rest-error, probably comes from wait_for_task, just pass through
raise ex
diff --git a/lib/task.rb b/lib/task.rb
index 74940de..9c52299 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -33,7 +33,7 @@ module OpenTox
def self.create( title=nil, creator=nil, max_duration=DEFAULT_TASK_MAX_DURATION, description=nil )
params = {:title=>title, :creator=>creator, :max_duration=>max_duration, :description=>description }
- task_uri = RestClientWrapper.post(CONFIG[:services]["opentox-task"], params, nil, false).to_s
+ task_uri = RestClientWrapper.post(CONFIG[:services]["opentox-task"], params, {}, nil, false).to_s
task = Task.new(task_uri.chomp)
# measure current memory consumption
@@ -64,9 +64,8 @@ module OpenTox
task.completed(result)
rescue => error
LOGGER.error "task failed: "+error.class.to_s+": "+error.message
- # log backtrace only if code is 500 -> unwanted (Runtime)Exceptions and internal errors (see error.rb)
- LOGGER.error ":\n"+error.backtrace.join("\n") if error.http_code==500
- task.error(OpenTox::ErrorReport.new(error, creator))
+ LOGGER.error ":\n"+error.backtrace.join("\n")
+ task.error(OpenTox::ErrorReport.create(error, creator))
end
end
task.pid = task_pid
@@ -188,7 +187,7 @@ module OpenTox
# create is private now, use OpenTox::Task.as_task
#def self.create( params )
- #task_uri = RestClientWrapper.post(CONFIG[:services]["opentox-task"], params, nil, false).to_s
+ #task_uri = RestClientWrapper.post(CONFIG[:services]["opentox-task"], params, {}, false).to_s
#Task.find(task_uri.chomp)
#end
@@ -285,7 +284,6 @@ module OpenTox
raise OpenTox::BadRequestError.new ex.message+" (task-uri:"+@uri+")"
end
end
-
end
# Convenience class to split a (sub)task into subtasks
diff --git a/lib/validation.rb b/lib/validation.rb
index 23b246b..c9e87f3 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -1,12 +1,29 @@
module OpenTox
- class Validation
+ class Crossvalidation
include OpenTox
- attr_accessor :report_uri, :qmrf_report_uri
+ attr_reader :report
+
+ # find crossvalidation, raises error if not found
+ # @param [String] uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::Crossvalidation]
+ def self.find( uri, subjectid=nil )
+ # PENDING load crossvalidation data?
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
+ Crossvalidation.new(uri)
+ end
- def self.create_crossvalidation(params)
- params[:uri] = File.join(CONFIG[:services]['opentox-validation'], "crossvalidation")
+ # creates a crossvalidations, waits until it finishes, may take some time
+ # @param [Hash] params
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [OpenTox::Crossvalidation]
+ def self.create( params, subjectid=nil, waiting_task=nil )
+ params[:uri] = File.join(CONFIG[:services]['opentox-validation'], "crossvalidation")
params[:num_folds] = 10 unless params[:num_folds]
+=begin
+<<<<<<< HEAD:lib/validation.rb
params[:random_seed] = 2 unless params[:random_seed]
params[:stratified] = false unless params[:stratified]
uri = OpenTox::RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/crossvalidation"),params,nil,false)
@@ -42,29 +59,128 @@ module OpenTox
elsif cell[:confusion_matrix_predicted] == "true" and cell[:confusion_matrix_actual] == "false"
fp = cell[:confusion_matrix_value]
n += fp
+=======
+=end
+ params[:random_seed] = 2 unless params[:random_seed]
+ params[:stratified] = false unless params[:stratified]
+ params[:subjectid] = subjectid if subjectid
+ uri = OpenTox::RestClientWrapper.post( File.join(CONFIG[:services]["opentox-validation"],"/crossvalidation"),
+ params,{:content_type => "text/uri-list"},waiting_task )
+ Crossvalidation.new(uri)
+ end
+
+ # looks for report for this crossvalidation, 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 [OpenTox::CrossvalidationReport]
+ def find_or_create_report( subjectid=nil, waiting_task=nil )
+ @report = CrossvalidationReport.find_for_crossvalidation(self, subjectid) unless @report
+ @report = CrossvalidationReport.create(self, subjectid, waiting_task) unless @report
+ @report
+ end
+
+ # PENDING: creates summary as used for ToxCreate
+ def summary( subjectid=nil )
+ v = YAML.load RestClientWrapper.get(File.join(@uri, 'statistics'),{:accept => "application/x-yaml", :subjectid => subjectid}).to_s
+ if v[OT.classificationStatistics]
+ res = {
+ :nr_predictions => v[OT.numInstances] - v[OT.numUnpredicted],
+ :correct_predictions => v[OT.classificationStatistics][OT.percentCorrect],
+ :weighted_area_under_roc => v[OT.classificationStatistics][OT.weightedAreaUnderRoc],
+ }
+ v[OT.classificationStatistics][OT.classValueStatistics].each do |s|
+ if s[OT.classValue].to_s=="true"
+ res[:true_positives] = s[OT.numTruePositives]
+ res[:false_positives] = s[OT.numFalsePositives]
+ res[:true_negatives] = s[OT.numTrueNegatives]
+ res[:false_negatives] = s[OT.numFalseNegatives]
+ res[:sensitivity] = s[OT.truePositiveRate]
+ res[:specificity] = s[OT.falsePositiveRate]
+ break
+#>>>>>>> mguetlein/development:lib/validation.rb
end
end
+ res
+ elsif v[OT.regressionStatistics]
{
- :nr_predictions => n,
- :true_positives => tp,
- :false_positives => fp,
- :true_negatives => tn,
- :false_negatives => fn,
- :correct_predictions => 100*(tp+tn).to_f/n,
- :weighted_area_under_roc => v[:classification_statistics][:weighted_area_under_roc].to_f,
- :sensitivity => tp.to_f/(tp+fn),
- :specificity => tn.to_f/(tn+fp),
- }
- when "regression"
- {
- :nr_predictions => v[:num_instances] - v[:num_unpredicted],
- :r_square => v[:regression_statistics][:r_square],
- :root_mean_squared_error => v[:regression_statistics][:root_mean_squared_error],
- :mean_absolute_error => v[:regression_statistics][:mean_absolute_error],
+ :nr_predictions => v[OT.numInstances] - v[OT.numUnpredicted],
+ :r_square => v[OT.regressionStatistics][OT.rSquare],
+ :root_mean_squared_error => v[OT.regressionStatistics][OT.rootMeanSquaredError],
+ :mean_absolute_error => v[OT.regressionStatistics][OT.meanAbsoluteError],
}
end
end
+ end
- end
+ class CrossvalidationReport
+ include OpenTox
+
+ # finds CrossvalidationReport via uri, raises error if not found
+ # @param [String] uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::CrossvalidationReport]
+ def self.find( uri, subjectid=nil )
+ # PENDING load report data?
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
+ CrossvalidationReport.new(uri)
+ end
+
+ # finds CrossvalidationReport for a particular crossvalidation
+ # @param [OpenTox::Crossvalidation]
+ # @param [String,optional] subjectid
+ # @return [OpenTox::CrossvalidationReport] nil if no report found
+ def self.find_for_crossvalidation( crossvalidation, subjectid=nil )
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
+ "/report/crossvalidation?crossvalidation="+crossvalidation.uri), {:subjectid => subjectid}).chomp.split("\n")
+ uris.size==0 ? nil : CrossvalidationReport.new(uris[-1])
+ end
+
+ # creates a crossvalidation report via crossvalidation
+ # @param [OpenTox::Crossvalidation]
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [OpenTox::CrossvalidationReport]
+ def self.create( crossvalidation, subjectid=nil, waiting_task=nil )
+ uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/crossvalidation"),
+ { :validation_uris => crossvalidation.uri, :subjectid => subjectid }, {}, waiting_task )
+ CrossvalidationReport.new(uri)
+ end
+ end
+
+ class QMRFReport
+ include OpenTox
+
+ # finds QMRFReport, raises Error if not found
+ # @param [String] uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::QMRFReport]
+ def self.find( uri, subjectid=nil )
+ # PENDING load crossvalidation data?
+ OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid})
+ QMRFReport.new(uri)
+ end
+
+ # finds QMRF report for a particular model
+ # @param [OpenTox::Crossvalidation]
+ # @param [String,optional] subjectid
+ # @return [OpenTox::QMRFReport] nil if no report found
+ def self.find_for_model( model, subjectid=nil )
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
+ "/reach_report/qmrf?model="+model.uri), {:subjectid => subjectid}).chomp.split("\n")
+ uris.size==0 ? nil : QMRFReport.new(uris[-1])
+ end
+
+ # creates a qmrf report via model
+ # @param [OpenTox::Model]
+ # @param [String,optional] subjectid
+ # @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
+ # @return [OpenTox::QMRFReport]
+ def self.create( model, subjectid=nil, waiting_task=nil )
+ uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/reach_report/qmrf"),
+ { :model_uri => model.uri, :subjectid => subjectid }, {}, waiting_task )
+ QMRFReport.new(uri)
+ end
+ end
+
end
diff --git a/opentox-ruby.gemspec b/opentox-ruby.gemspec
index 9320dae..3903af7 100644
--- a/opentox-ruby.gemspec
+++ b/opentox-ruby.gemspec
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Christoph Helma, Martin Guetlein, Andreas Maunz, Micha Rautenberg, David Vorgrimmler"]
- s.date = %q{2010-11-30}
+ s.date = %q{2011-01-27}
s.description = %q{Ruby wrapper for the OpenTox REST API (http://www.opentox.org)}
s.email = %q{helma@in-silico.ch}
s.executables = ["opentox-install-ubuntu.sh", "opentox-install-debian.sh"]
@@ -25,23 +25,34 @@ Gem::Specification.new do |s|
"bin/opentox-install-debian.sh",
"bin/opentox-install-ubuntu.sh",
"lib/algorithm.rb",
+ "lib/authorization.rb",
"lib/compound.rb",
"lib/config/config_ru.rb",
"lib/dataset.rb",
"lib/environment.rb",
+ "lib/error.rb",
"lib/feature.rb",
"lib/helper.rb",
"lib/model.rb",
+ "lib/ontology_service.rb",
"lib/opentox-ruby.rb",
"lib/opentox.owl",
"lib/opentox.rb",
"lib/overwrite.rb",
+ "lib/owl.rb.RDF",
+ "lib/owl.rb.nt",
+ "lib/owl.rb.rdfxml.initial",
+ "lib/owl.rb.redland",
"lib/parser.rb",
+ "lib/policy.rb",
"lib/rest_client_wrapper.rb",
"lib/serializer.rb",
"lib/spork.rb",
"lib/task.rb",
"lib/templates/config.yaml",
+ "lib/templates/default_guest_policy.xml",
+ "lib/templates/default_policy.xml",
+ "lib/to-html.rb",
"lib/validation.rb"
]
s.homepage = %q{http://github.com/helma/opentox-ruby}