From bf6834445feb6f93f0a20359462dbd1e7e89f4b8 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Thu, 12 Jul 2012 16:38:03 +0200 Subject: all opentox-client tests pass --- lib/dataset.rb | 134 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 19 deletions(-) (limited to 'lib/dataset.rb') diff --git a/lib/dataset.rb b/lib/dataset.rb index 33e1571..ed0ccdd 100644 --- a/lib/dataset.rb +++ b/lib/dataset.rb @@ -3,32 +3,128 @@ module OpenTox # Ruby wrapper for OpenTox Dataset Webservices (http://opentox.org/dev/apis/api-1.2/dataset). class Dataset - def data_entries - data_entries = [] - #pull - #@reload = false - begin - self.[](RDF::OT.dataEntry).collect{|data_entry| data_entries << @rdf.to_hash[data_entry] } - rescue + attr_accessor :features, :compounds, :data_entries + + def initialize uri=nil, subjectid=nil + super uri, subjectid + @features = [] + @compounds = [] + @data_entries = [] + append RDF.type, RDF::OT.OrderedDataset + end + + def upload filename + file = File.new filename + RestClientWrapper.put(@uri, {:file => file}, {:subjectid => @subjectid}) + end + + def get + super + @features = [] + @compounds = [] + @data_entries = [] + query = RDF::Query.new do + pattern [:uri, RDF.type, RDF::OT.OrderedDataset] end - begin - # TODO: remove API 1.1 - self.[](RDF::OT1.dataEntry).collect{|data_entry| data_entries << @rdf.to_hash[data_entry] } - rescue + if query.execute(@rdf).first # ordered dataset + query = RDF::Query.new do + pattern [:uri, RDF.type, RDF::OT.Compound] + pattern [:uri, RDF::OLO.index, :idx] + end + @compounds = query.execute(@rdf).sort_by{|s| s.idx}.collect{|s| OpenTox::Compound.new s.uri.to_s} + query = RDF::Query.new do + pattern [:uri, RDF.type, RDF::OT.Feature] + pattern [:uri, RDF::OLO.index, :idx] + end + @features = query.execute(@rdf).sort_by{|s| s.idx}.collect{|s| OpenTox::Feature.new(s.uri.to_s)} + numeric_features = @features.collect{|f| f.get; f[RDF.type].include? RDF::OT.NumericFeature} + @compounds.each_with_index do |compound,i| + query = RDF::Query.new do + pattern [:data_entry, RDF::OLO.index, i] + pattern [:data_entry, RDF::OT.values, :values] + pattern [:values, RDF::OT.feature, :feature] + pattern [:feature, RDF::OLO.index, :feature_idx] + pattern [:values, RDF::OT.value, :value] + end + values = query.execute(@rdf).sort_by{|s| s.feature_idx}.collect do |s| + numeric_features[s.feature_idx] ? s.value.to_s.to_f : s.value.to_s + end + @data_entries << values + end + else + query = RDF::Query.new do + pattern [:uri, RDF.type, RDF::OT.Feature] + end + @features = query.execute(@rdf).collect{|s| OpenTox::Feature.new(s.uri.to_s)} + query = RDF::Query.new do + pattern [:data_entry, RDF::OT.compound, :compound] + end + @compounds = query.execute(@rdf).sort_by{|s| s.data_entry}.collect{|s| OpenTox::Compound.new s.compound.to_s} + numeric_features = @features.collect{|f| f.get; f[RDF.type].include? RDF::OT.NumericFeature} + @compounds.each do |compound| + values = [] + @features.each_with_index do |feature,i| + query = RDF::Query.new do + pattern [:data_entry, RDF::OT.compound, RDF::URI.new(compound.uri)] + pattern [:data_entry, RDF::OT.values, :values] + pattern [:values, RDF::OT.feature, RDF::URI.new(feature.uri)] + pattern [:values, RDF::OT.value, :value] + end + value = query.execute(@rdf).first.value.to_s + value = value.to_f if numeric_features[i] + values << value + end + @data_entries << values + end end - #@reload = true - data_entries end - def compounds - uri = File.join(@uri,"compounds") - RestClientWrapper.get(uri,{},{:accept => "text/uri-list", :subjectid => @subjectid}).split("\n").collect{|uri| OpenTox::Compound.new uri} + def get_metadata + uri = File.join(@uri,"metadata") + begin + parse_ntriples RestClientWrapper.get(uri,{},{:accept => "text/plain", :subjectid => @subjectid}) + rescue # fall back to rdfxml + parse_rdfxml RestClientWrapper.get(uri,{},{:accept => "application/rdf+xml", :subjectid => @subjectid}) + end + metadata end - def features - uri = File.join(@uri,"features") - RestClientWrapper.get(uri,{},{:accept => "text/uri-list", :subjectid => @subjectid}).split("\n").collect{|uri| OpenTox::Feature.new uri} + def << data_entry + compound = data_entry.shift + bad_request_error "Dataset features are empty." unless features + bad_request_error "data_entry size does not match features size." unless data_entry.size == features.size + bad_request_error "First data_entry is not a OpenTox::Compound" unless compound.class == OpenTox::Compound + @compounds << compound + @data_entries << data_entry end + RDF_FORMATS.each do |format| + + # redefine rdf serialization methods + send :define_method, "to_#{format}".to_sym do + # TODO: check, might affect appending to unordered datasets + features.each_with_index do |feature,i| + @rdf << [RDF::URI.new(feature.uri), RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.Feature)] + @rdf << [RDF::URI.new(feature.uri), RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)] + end + compounds.each_with_index do |compound,i| + @rdf << [RDF::URI.new(compound.uri), RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.Compound)] + @rdf << [RDF::URI.new(compound.uri), RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)] + data_entry_node = RDF::Node.new + @rdf << [RDF::URI.new(@uri), RDF::URI.new(RDF::OT.dataEntry), data_entry_node] + @rdf << [data_entry_node, RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.DataEntry)] + @rdf << [data_entry_node, RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)] + @rdf << [data_entry_node, RDF::URI.new(RDF::OT.compound), RDF::URI.new(compound.uri)] + data_entries[i].each_with_index do |value,j| + value_node = RDF::Node.new + @rdf << [data_entry_node, RDF::URI.new(RDF::OT.values), value_node] + @rdf << [value_node, RDF::URI.new(RDF::OT.feature), RDF::URI.new(@features[j].uri)] + @rdf << [value_node, RDF::URI.new(RDF::OT.value), RDF::Literal.new(value)] + end + end + super() + end + + end end end -- cgit v1.2.3