diff options
author | mr <mr@mrautenberg.de> | 2011-05-23 13:04:48 +0200 |
---|---|---|
committer | mr <mr@mrautenberg.de> | 2011-05-23 13:04:48 +0200 |
commit | 97cb287f1f0b8cb787a27a0776deebdb969a0b8e (patch) | |
tree | 67858a4d5a0504f3e33c0f33923019007625cf43 | |
parent | 41851663e591433fec1b021b88aa77a8fb0d37b0 (diff) | |
parent | 0902a4a0b2d83d167277b82fcfd9cc12c0b993a9 (diff) |
new release 2.0.0
-rw-r--r-- | Rakefile | 16 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | lib/algorithm.rb | 26 | ||||
-rw-r--r-- | lib/authorization.rb | 29 | ||||
-rw-r--r-- | lib/dataset.rb | 33 | ||||
-rw-r--r-- | lib/environment.rb | 2 | ||||
-rw-r--r-- | lib/error.rb | 4 | ||||
-rw-r--r-- | lib/feature.rb | 25 | ||||
-rw-r--r-- | lib/helper.rb | 67 | ||||
-rw-r--r-- | lib/model.rb | 18 | ||||
-rw-r--r-- | lib/ontology.rb (renamed from lib/ontology_service.rb) | 28 | ||||
-rw-r--r-- | lib/opentox-ruby.rb | 2 | ||||
-rw-r--r-- | lib/opentox.rb | 9 | ||||
-rw-r--r-- | lib/overwrite.rb | 15 | ||||
-rw-r--r-- | lib/parser.rb | 53 | ||||
-rw-r--r-- | lib/rest_client_wrapper.rb | 2 | ||||
-rw-r--r-- | lib/serializer.rb | 20 | ||||
-rw-r--r-- | lib/task.rb | 2 | ||||
-rw-r--r-- | lib/templates/config.yaml | 86 | ||||
-rw-r--r-- | lib/validation.rb | 74 |
20 files changed, 296 insertions, 217 deletions
@@ -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 @@ -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 |