diff options
author | Christoph Helma <helma@in-silico.ch> | 2011-02-04 16:42:35 +0100 |
---|---|---|
committer | Christoph Helma <helma@in-silico.ch> | 2011-02-04 16:42:35 +0100 |
commit | beaabdac3faf7b2ad86fa719f0726a8907706721 (patch) | |
tree | a2767cdbf89b8b39e6b69a12c5ee895b6c32f406 | |
parent | 55f81bb50e76e99f370516ec8625a5aae902e898 (diff) | |
parent | e035b7136b8c2df70de980379695fbfeaf070290 (diff) |
Merge commit 'mguetlein/development' into development
Conflicts:
lib/validation.rb
-rw-r--r-- | lib/algorithm.rb | 4 | ||||
-rw-r--r-- | lib/authorization.rb | 7 | ||||
-rw-r--r-- | lib/dataset.rb | 2 | ||||
-rw-r--r-- | lib/environment.rb | 4 | ||||
-rw-r--r-- | lib/error.rb | 41 | ||||
-rw-r--r-- | lib/model.rb | 4 | ||||
-rw-r--r-- | lib/overwrite.rb | 28 | ||||
-rw-r--r-- | lib/parser.rb | 33 | ||||
-rw-r--r-- | lib/rest_client_wrapper.rb | 44 | ||||
-rw-r--r-- | lib/task.rb | 10 | ||||
-rw-r--r-- | lib/validation.rb | 158 | ||||
-rw-r--r-- | opentox-ruby.gemspec | 13 |
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} |