opentox-ruby 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/dataset.rb CHANGED
@@ -1,226 +1,330 @@
1
1
  module OpenTox
2
2
 
3
+ # Ruby wrapper for OpenTox Dataset Webservices (http://opentox.org/dev/apis/api-1.2/dataset).
3
4
  class Dataset
4
5
 
5
- attr_accessor :uri, :title, :creator, :data, :features, :compounds
6
+ include OpenTox
6
7
 
7
- def initialize( owl=nil )
8
- @data = {}
9
- @features = []
8
+ attr_reader :features, :compounds, :data_entries, :metadata
9
+
10
+ # Create dataset with optional URI. Does not load data into the dataset - you will need to execute one of the load_* methods to pull data from a service or to insert it from other representations.
11
+ # @example Create an empty dataset
12
+ # dataset = OpenTox::Dataset.new
13
+ # @example Create an empty dataset with URI
14
+ # dataset = OpenTox::Dataset.new("http:://webservices.in-silico/ch/dataset/1")
15
+ # @param [optional, String] uri Dataset URI
16
+ # @return [OpenTox::Dataset] Dataset object
17
+ def initialize(uri=nil)
18
+ super uri
19
+ @features = {}
10
20
  @compounds = []
11
-
12
- # creates dataset object from Opentox::Owl object
13
- # use Dataset.find( <uri> ) to load dataset from rdf-supporting datasetservice
14
- # note: does not load all feature values, as this is time consuming
15
- if owl
16
- raise "invalid param" unless owl.is_a?(OpenTox::Owl)
17
- @title = owl.get("title")
18
- @creator = owl.get("creator")
19
- @uri = owl.uri
20
- # when loading a dataset from owl, only compound- and feature-uris are loaded
21
- owl.load_dataset(@compounds, @features)
22
- # all features are marked as dirty
23
- # as soon as a feature-value is requested all values for this feature are loaded from the rdf
24
- @dirty_features = @features.dclone
25
- @owl = owl
26
- end
21
+ @data_entries = {}
27
22
  end
28
-
29
- def self.find(uri, accept_header=nil)
30
-
31
- unless accept_header
32
- if (@@config[:yaml_hosts].include?(URI.parse(uri).host))
33
- accept_header = 'application/x-yaml'
34
- else
35
- accept_header = "application/rdf+xml"
36
- end
37
- end
38
-
39
- case accept_header
40
- when "application/x-yaml"
41
- d = YAML.load RestClientWrapper.get(uri.to_s.strip, :accept => 'application/x-yaml').to_s
42
- d.uri = uri unless d.uri
43
- when "application/rdf+xml"
44
- owl = OpenTox::Owl.from_uri(uri.to_s.strip, "Dataset")
45
- d = Dataset.new(owl)
46
- else
47
- raise "cannot get datset with accept header: "+accept_header.to_s
48
- end
49
- d
23
+
24
+ # Create an empty dataset and save it at the dataset service (assigns URI to dataset)
25
+ # @example Create new dataset and save it to obtain a URI
26
+ # dataset = OpenTox::Dataset.create
27
+ # @param [optional, String] uri Dataset URI
28
+ # @return [OpenTox::Dataset] Dataset object
29
+ def self.create(uri=CONFIG[:services]["opentox-dataset"])
30
+ dataset = Dataset.new
31
+ dataset.save
32
+ dataset
50
33
  end
51
-
52
- # converts a dataset represented in owl to yaml
53
- # (uses a temporary dataset)
54
- # note: to_yaml is overwritten, loads complete owl dataset values
55
- def self.owl_to_yaml( owl_data, uri)
56
- owl = OpenTox::Owl.from_data(owl_data, uri, "Dataset")
57
- d = Dataset.new(owl)
58
- d.to_yaml
34
+
35
+ # Create dataset from CSV file (format specification: http://toxcreate.org/help)
36
+ # - loads data_entries, compounds, features
37
+ # - sets metadata (warnings) for parser errors
38
+ # - you will have to set remaining metadata manually
39
+ # @param [String] file CSV file path
40
+ # @return [OpenTox::Dataset] Dataset object with CSV data
41
+ def self.create_from_csv_file(file)
42
+ dataset = Dataset.create
43
+ parser = Parser::Spreadsheets.new
44
+ parser.dataset = dataset
45
+ parser.load_csv(File.open(file).read)
46
+ dataset.save
47
+ dataset
59
48
  end
60
-
61
- # creates a new dataset, using only those compounsd specified in new_compounds
62
- # returns uri of new dataset
63
- def create_new_dataset( new_compounds, new_features, new_title, new_creator )
64
-
65
- LOGGER.debug "create new dataset with "+new_compounds.size.to_s+"/"+compounds.size.to_s+" compounds"
66
- raise "no new compounds selected" unless new_compounds and new_compounds.size>0
67
-
68
- # load require features
69
- if ((defined? @dirty_features) && (@dirty_features & new_features).size > 0)
70
- (@dirty_features & new_features).each{|f| load_feature_values(f)}
71
- end
72
-
73
- dataset = OpenTox::Dataset.new
74
- dataset.title = new_title
75
- dataset.creator = new_creator
76
- dataset.features = new_features
77
- dataset.compounds = new_compounds
78
-
79
- # Copy dataset data for compounds and features
80
- # PENDING: why storing feature values in an array?
81
- new_compounds.each do |c|
82
- data_c = []
83
- raise "no data for compound '"+c.to_s+"'" if @data[c]==nil
84
- @data[c].each do |d|
85
- m = {}
86
- new_features.each do |f|
87
- m[f] = d[f]
88
- end
89
- data_c << m
90
- end
91
- dataset.data[c] = data_c
92
- end
93
- return dataset.save
49
+
50
+ # Find a dataset and load all data. This can be time consuming, use Dataset.new together with one of the load_* methods for a fine grained control over data loading.
51
+ # @param [String] uri Dataset URI
52
+ # @return [OpenTox::Dataset] Dataset object with all data
53
+ def self.find(uri)
54
+ dataset = Dataset.new(uri)
55
+ dataset.load_all
56
+ dataset
57
+ end
58
+
59
+ # Get all datasets from a service
60
+ # @param [optional,String] uri URI of the dataset service, defaults to service specified in configuration
61
+ # @return [Array] Array of dataset object without data (use one of the load_* methods to pull data from the server)
62
+ def self.all(uri=CONFIG[:services]["opentox-dataset"])
63
+ RestClientWrapper.get(uri,:accept => "text/uri-list").to_s.each_line.collect{|u| Dataset.new(u)}
64
+ end
65
+
66
+ # Load YAML representation into the dataset
67
+ # @param [String] yaml YAML representation of the dataset
68
+ # @return [OpenTox::Dataset] Dataset object with YAML data
69
+ def load_yaml(yaml)
70
+ copy YAML.load(yaml)
71
+ end
72
+
73
+ def load_rdfxml(rdfxml)
74
+ load_rdfxml_file Tempfile.open("ot-rdfxml"){|f| f.write(rdfxml)}.path
75
+ end
76
+
77
+ # Load RDF/XML representation from a file
78
+ # @param [String] file File with RDF/XML representation of the dataset
79
+ # @return [OpenTox::Dataset] Dataset object with RDF/XML data
80
+ def load_rdfxml_file(file)
81
+ parser = Parser::Owl::Dataset.new @uri
82
+ parser.uri = file.path
83
+ copy parser.load_uri
84
+ end
85
+
86
+ # Load CSV string (format specification: http://toxcreate.org/help)
87
+ # - loads data_entries, compounds, features
88
+ # - sets metadata (warnings) for parser errors
89
+ # - you will have to set remaining metadata manually
90
+ # @param [String] csv CSV representation of the dataset
91
+ # @return [OpenTox::Dataset] Dataset object with CSV data
92
+ def load_csv(csv)
93
+ save unless @uri # get a uri for creating features
94
+ parser = Parser::Spreadsheets.new
95
+ parser.dataset = self
96
+ parser.load_csv(csv)
97
+ end
98
+
99
+ # Load Spreadsheet book (created with roo gem http://roo.rubyforge.org/, excel format specification: http://toxcreate.org/help)
100
+ # - loads data_entries, compounds, features
101
+ # - sets metadata (warnings) for parser errors
102
+ # - you will have to set remaining metadata manually
103
+ # @param [Excel] book Excel workbook object (created with roo gem)
104
+ # @return [OpenTox::Dataset] Dataset object with Excel data
105
+ def load_spreadsheet(book)
106
+ save unless @uri # get a uri for creating features
107
+ parser = Parser::Spreadsheets.new
108
+ parser.dataset = self
109
+ parser.load_spreadsheet(book)
94
110
  end
95
111
 
96
- # returns classification value
97
- def get_predicted_class(compound, feature)
98
- v = get_value(compound, feature)
99
- if v.is_a?(Hash)
100
- k = v.keys.grep(/classification/).first
101
- unless k.empty?
102
- #if v.has_key?(:classification)
103
- return v[k]
104
- else
105
- return "no classification key"
106
- end
107
- elsif v.is_a?(Array)
108
- raise "predicted class value is an array\n"+
109
- "value "+v.to_s+"\n"+
110
- "value-class "+v.class.to_s+"\n"+
111
- "dataset "+@uri.to_s+"\n"+
112
- "compound "+compound.to_s+"\n"+
113
- "feature "+feature.to_s+"\n"
112
+ # Load and return only metadata of a Dataset object
113
+ # @return [Hash] Metadata of the dataset
114
+ def load_metadata
115
+ add_metadata Parser::Owl::Dataset.new(@uri).load_metadata
116
+ self.uri = @uri if @uri # keep uri
117
+ @metadata
118
+ end
119
+
120
+ # Load all data (metadata, data_entries, compounds and features) from URI
121
+ def load_all
122
+ if (CONFIG[:yaml_hosts].include?(URI.parse(@uri).host))
123
+ copy YAML.load(RestClientWrapper.get(@uri, :accept => "application/x-yaml"))
114
124
  else
115
- return v
125
+ parser = Parser::Owl::Dataset.new(@uri)
126
+ copy parser.load_uri
116
127
  end
117
128
  end
118
-
119
- # returns regression value
120
- def get_predicted_regression(compound, feature)
121
- v = get_value(compound, feature)
122
- if v.is_a?(Hash)
123
- k = v.keys.grep(/regression/).first
124
- unless k.empty?
125
- return v[k]
126
- else
127
- return "no regression key"
128
- end
129
- elsif v.is_a?(Array)
130
- raise "predicted regression value is an array\n"+
131
- "value "+v.to_s+"\n"+
132
- "value-class "+v.class.to_s+"\n"+
133
- "dataset "+@uri.to_s+"\n"+
134
- "compound "+compound.to_s+"\n"+
135
- "feature "+feature.to_s+"\n"
136
- else
137
- return v
129
+
130
+ # Load and return only compound URIs from the dataset service
131
+ # @return [Array] Compound URIs in the dataset
132
+ def load_compounds
133
+ RestClientWrapper.get(File.join(uri,"compounds"),:accept=> "text/uri-list").to_s.each_line do |compound_uri|
134
+ @compounds << compound_uri.chomp
138
135
  end
136
+ @compounds.uniq!
139
137
  end
140
-
141
- # returns prediction confidence if available
142
- def get_prediction_confidence(compound, feature)
143
- v = get_value(compound, feature)
144
- if v.is_a?(Hash)
145
- k = v.keys.grep(/confidence/).first
146
- unless k.empty?
147
- #if v.has_key?(:confidence)
148
- return v[k].abs
149
- #return v["http://ot-dev.in-silico.ch/model/lazar#confidence"].abs
138
+
139
+ # Load and return only features from the dataset service
140
+ # @return [Hash] Features of the dataset
141
+ def load_features
142
+ parser = Parser::Owl::Dataset.new(@uri)
143
+ @features = parser.load_features
144
+ @features
145
+ end
146
+
147
+ # Detect feature type(s) in the dataset
148
+ # @return [String] `classification", "regression", "mixed" or unknown`
149
+ def feature_type
150
+ feature_types = @features.collect{|f,metadata| metadata[OT.isA]}.uniq
151
+ if feature_types.size > 1
152
+ "mixed"
153
+ else
154
+ case feature_types.first
155
+ when /NominalFeature/
156
+ "classification"
157
+ when /NumericFeature/
158
+ "regression"
150
159
  else
151
- # PENDING: return nil isntead of raising an exception
152
- raise "no confidence key"
160
+ "unknown"
153
161
  end
154
- else
155
- LOGGER.warn "no confidence for compound: "+compound.to_s+", feature: "+feature.to_s
156
- return 1
157
162
  end
158
163
  end
159
-
160
- # return compound-feature value
161
- def get_value(compound, feature)
162
- if (defined? @dirty_features) && @dirty_features.include?(feature)
163
- load_feature_values(feature)
164
- end
165
-
166
- v = @data[compound]
167
- return nil if v == nil # missing values for all features
168
- if v.is_a?(Array)
169
- # PENDING: why using an array here?
170
- v.each do |e|
171
- if e.is_a?(Hash)
172
- if e.has_key?(feature)
173
- return e[feature]
174
- end
175
- else
176
- raise "invalid internal value type"
177
- end
164
+
165
+ # Get Spreadsheet representation
166
+ # @return [Spreadsheet::Workbook] Workbook which can be written with the spreadsheet gem (data_entries only, metadata will will be discarded))
167
+ def to_spreadsheet
168
+ Serializer::Spreadsheets.new(self).to_spreadsheet
169
+ end
170
+
171
+ # Get Excel representation (alias for to_spreadsheet)
172
+ # @return [Spreadsheet::Workbook] Workbook which can be written with the spreadsheet gem (data_entries only, metadata will will be discarded))
173
+ def to_xls
174
+ to_spreadsheet
175
+ end
176
+
177
+ # Get CSV string representation (data_entries only, metadata will be discarded)
178
+ # @return [String] CSV representation
179
+ def to_csv
180
+ Serializer::Spreadsheets.new(self).to_csv
181
+ end
182
+
183
+ # Get OWL-DL in ntriples format
184
+ # @return [String] N-Triples representation
185
+ def to_ntriples
186
+ s = Serializer::Owl.new
187
+ s.add_dataset(self)
188
+ s.to_ntriples
189
+ end
190
+
191
+ # Get OWL-DL in RDF/XML format
192
+ # @return [String] RDF/XML representation
193
+ def to_rdfxml
194
+ s = Serializer::Owl.new
195
+ s.add_dataset(self)
196
+ s.to_rdfxml
197
+ end
198
+
199
+ # Get name (DC.title) of a feature
200
+ # @param [String] feature Feature URI
201
+ # @return [String] Feture title
202
+ def feature_name(feature)
203
+ @features[feature][DC.title]
204
+ end
205
+
206
+ def title
207
+ @metadata[DC.title]
208
+ end
209
+
210
+ # Insert a statement (compound_uri,feature_uri,value)
211
+ # @example Insert a statement (compound_uri,feature_uri,value)
212
+ # dataset.add "http://webservices.in-silico.ch/compound/InChI=1S/C6Cl6/c7-1-2(8)4(10)6(12)5(11)3(1)9", "http://webservices.in-silico.ch/dataset/1/feature/hamster_carcinogenicity", true
213
+ # @param [String] compound Compound URI
214
+ # @param [String] feature Compound URI
215
+ # @param [Boolean,Float] value Feature value
216
+ def add (compound,feature,value)
217
+ @compounds << compound unless @compounds.include? compound
218
+ @features[feature] = {} unless @features[feature]
219
+ @data_entries[compound] = {} unless @data_entries[compound]
220
+ @data_entries[compound][feature] = [] unless @data_entries[compound][feature]
221
+ @data_entries[compound][feature] << value
222
+ end
223
+
224
+ # Add/modify metadata, existing entries will be overwritten
225
+ # @example
226
+ # dataset.add_metadata({DC.title => "any_title", DC.creator => "my_email"})
227
+ # @param [Hash] metadata Hash mapping predicate_uris to values
228
+ def add_metadata(metadata)
229
+ metadata.each { |k,v| @metadata[k] = v }
230
+ end
231
+
232
+ # Add a feature
233
+ # @param [String] feature Feature URI
234
+ # @param [Hash] metadata Hash with feature metadata
235
+ def add_feature(feature,metadata={})
236
+ @features[feature] = metadata
237
+ end
238
+
239
+ # Add/modify metadata for a feature
240
+ # @param [String] feature Feature URI
241
+ # @param [Hash] metadata Hash with feature metadata
242
+ def add_feature_metadata(feature,metadata)
243
+ metadata.each { |k,v| @features[feature][k] = v }
244
+ end
245
+
246
+ # Save dataset at the dataset service
247
+ # - creates a new dataset if uri is not set
248
+ # - overwrites dataset if uri exists
249
+ # @return [String] Dataset URI
250
+ def save
251
+ # TODO: rewrite feature URI's ??
252
+ @compounds.uniq!
253
+ if @uri
254
+ if (CONFIG[:yaml_hosts].include?(URI.parse(@uri).host))
255
+ RestClientWrapper.post(@uri,{:content_type => "application/x-yaml"},self.to_yaml)
256
+ else
257
+ File.open("ot-post-file.rdf","w+") { |f| f.write(self.to_rdfxml); @path = f.path }
258
+ task_uri = RestClient.post(@uri, {:file => File.new(@path)},{:accept => "text/uri-list"}).to_s.chomp
259
+ #task_uri = `curl -X POST -H "Accept:text/uri-list" -F "file=@#{@path};type=application/rdf+xml" http://apps.ideaconsult.net:8080/ambit2/dataset`
260
+ Task.find(task_uri).wait_for_completion
261
+ self.uri = RestClientWrapper.get(task_uri,:accept => 'text/uri-list')
178
262
  end
179
- return nil #missing value
180
263
  else
181
- raise "value is not an array\n"+
182
- "value "+v.to_s+"\n"+
183
- "value-class "+v.class.to_s+"\n"+
184
- "dataset "+@uri.to_s+"\n"+
185
- "compound "+compound.to_s+"\n"+
186
- "feature "+feature.to_s+"\n"
264
+ # create dataset if uri is empty
265
+ self.uri = RestClientWrapper.post(CONFIG[:services]["opentox-dataset"],{}).to_s.chomp
187
266
  end
267
+ @uri
268
+ end
269
+
270
+ # Delete dataset at the dataset service
271
+ def delete
272
+ RestClientWrapper.delete @uri
188
273
  end
189
274
 
190
- # loads specified feature and removes dirty-flag, loads all features if feature is nil
191
- def load_feature_values(feature=nil)
192
- if feature
193
- raise "feature already loaded" unless @dirty_features.include?(feature)
194
- @owl.load_dataset_feature_values(@compounds, @data, [feature])
195
- @dirty_features.delete(feature)
275
+ private
276
+ # Copy a dataset (rewrites URI)
277
+ def copy(dataset)
278
+ @metadata = dataset.metadata
279
+ @data_entries = dataset.data_entries
280
+ @compounds = dataset.compounds
281
+ @features = dataset.features
282
+ if @uri
283
+ self.uri = @uri
196
284
  else
197
- @data = {} unless @data
198
- @owl.load_dataset_feature_values(@compounds, @data, @dirty_features)
199
- @dirty_features.clear
285
+ @uri = dataset.metadata[XSD.anyURI]
200
286
  end
201
287
  end
202
-
203
- # overwrite to yaml:
204
- # in case dataset is loaded from owl:
205
- # * load all values
206
- def to_yaml
207
- # loads all features
208
- if ((defined? @dirty_features) && @dirty_features.size > 0)
209
- load_feature_values
210
- end
211
- super
288
+ end
289
+
290
+ # Class with special methods for lazar prediction datasets
291
+ class LazarPrediction < Dataset
292
+
293
+ # Find a prediction dataset and load all data.
294
+ # @param [String] uri Prediction dataset URI
295
+ # @return [OpenTox::Dataset] Prediction dataset object with all data
296
+ def self.find(uri)
297
+ prediction = LazarPrediction.new(uri)
298
+ prediction.load_all
299
+ prediction
212
300
  end
213
-
214
- # * remove @owl from yaml, not necessary
215
- def to_yaml_properties
216
- super - ["@owl"]
301
+
302
+ def value(compound)
303
+ @data_entries[compound.uri].collect{|f,v| v.first if f.match(/prediction/)}.compact.first
217
304
  end
218
305
 
219
- # saves (changes) as new dataset in dataset service
220
- # returns uri
221
- # uses to yaml method (which is overwritten)
222
- def save
223
- OpenTox::RestClientWrapper.post(@@config[:services]["opentox-dataset"],{:content_type => "application/x-yaml"},self.to_yaml).strip
306
+ def confidence(compound)
307
+ feature_uri = @data_entries[compound.uri].collect{|f,v| f if f.match(/prediction/)}.compact.first
308
+ @features[feature_uri][OT.confidence]
224
309
  end
310
+
311
+ def descriptors(compound)
312
+ @data_entries[compound.uri].collect{|f,v| @features[f] if f.match(/descriptor/)}.compact if @data_entries[compound.uri]
313
+ end
314
+
315
+ def measured_activities(compound)
316
+ source = @metadata[OT.hasSource]
317
+ @data_entries[compound.uri].collect{|f,v| v if f.match(/#{source}/)}.compact.flatten
318
+ end
319
+
320
+ def neighbors(compound)
321
+ @data_entries[compound.uri].collect{|f,v| @features[f] if f.match(/neighbor/)}.compact
322
+ end
323
+
324
+ # def errors(compound)
325
+ # features = @data_entries[compound.uri].keys
326
+ # features.collect{|f| @features[f][OT.error]}.join(" ") if features
327
+ # end
328
+
225
329
  end
226
330
  end
data/lib/environment.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "ot-logger"
2
1
  # set default environment
3
2
  ENV['RACK_ENV'] = 'production' unless ENV['RACK_ENV']
4
3
 
@@ -12,8 +11,8 @@ TMP_DIR = File.join(basedir, "tmp")
12
11
  LOG_DIR = File.join(basedir, "log")
13
12
 
14
13
  if File.exist?(config_file)
15
- @@config = YAML.load_file(config_file)
16
- raise "could not load config, config file: "+config_file.to_s unless @@config
14
+ CONFIG = YAML.load_file(config_file)
15
+ raise "could not load config, config file: "+config_file.to_s unless CONFIG
17
16
  else
18
17
  FileUtils.mkdir_p TMP_DIR
19
18
  FileUtils.mkdir_p LOG_DIR
@@ -24,20 +23,20 @@ else
24
23
  end
25
24
 
26
25
  # database
27
- if @@config[:database]
26
+ if CONFIG[:database]
28
27
  ['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations', 'dm-validations' ].each{|lib| require lib }
29
- case @@config[:database][:adapter]
28
+ case CONFIG[:database][:adapter]
30
29
  when /sqlite/i
31
30
  db_dir = File.join(basedir, "db")
32
31
  FileUtils.mkdir_p db_dir
33
32
  DataMapper::setup(:default, "sqlite3://#{db_dir}/opentox.sqlite3")
34
33
  else
35
34
  DataMapper.setup(:default, {
36
- :adapter => @@config[:database][:adapter],
37
- :database => @@config[:database][:database],
38
- :username => @@config[:database][:username],
39
- :password => @@config[:database][:password],
40
- :host => @@config[:database][:host]})
35
+ :adapter => CONFIG[:database][:adapter],
36
+ :database => CONFIG[:database][:database],
37
+ :username => CONFIG[:database][:username],
38
+ :password => CONFIG[:database][:password],
39
+ :host => CONFIG[:database][:host]})
41
40
  end
42
41
  end
43
42
 
@@ -45,33 +44,49 @@ end
45
44
  load File.join config_dir,"mail.rb" if File.exists?(File.join config_dir,"mail.rb")
46
45
 
47
46
  logfile = "#{LOG_DIR}/#{ENV["RACK_ENV"]}.log"
48
- #LOGGER = MyLogger.new(logfile,'daily') # daily rotation
49
- LOGGER = MyLogger.new(logfile) # no rotation
47
+ #LOGGER = OTLogger.new(logfile,'daily') # daily rotation
48
+ LOGGER = OTLogger.new(logfile) # no rotation
50
49
  LOGGER.formatter = Logger::Formatter.new #this is neccessary to restore the formating in case active-record is loaded
51
- if @@config[:logger] and @@config[:logger] == "debug"
50
+ if CONFIG[:logger] and CONFIG[:logger] == "debug"
52
51
  LOGGER.level = Logger::DEBUG
53
52
  else
54
53
  LOGGER.level = Logger::WARN
55
54
  end
56
55
 
57
- if File.exist?(user_file)
58
- @@users = YAML.load_file(user_file)
59
- else
60
- FileUtils.cp(File.join(File.dirname(__FILE__), 'templates/users.yaml'), user_file)
61
- puts "Please edit #{user_file} and restart your application."
62
- exit
63
- end
64
-
65
- begin
66
- 0 < @@users[:users].keys.length
67
- rescue
68
- raise "Please edit #{user_file} and restart your application. Create at least one user with password."
69
- end
70
-
71
56
  # Regular expressions for parsing classification data
72
57
  TRUE_REGEXP = /^(true|active|1|1.0)$/i
73
58
  FALSE_REGEXP = /^(false|inactive|0|0.0)$/i
74
59
 
75
60
  # Task durations
76
- DEFAULT_TASK_MAX_DURATION = 3600
77
- EXTERNAL_TASK_MAX_DURATION = 3600
61
+ DEFAULT_TASK_MAX_DURATION = 36000
62
+ #EXTERNAL_TASK_MAX_DURATION = 36000
63
+
64
+ # OWL Namespaces
65
+ class OwlNamespace
66
+
67
+ attr_accessor :uri
68
+ def initialize(uri)
69
+ @uri = uri
70
+ end
71
+
72
+ def [](property)
73
+ @uri+property.to_s
74
+ end
75
+
76
+ def type # for RDF.type
77
+ "#{@uri}type"
78
+ end
79
+
80
+ def method_missing(property)
81
+ @uri+property.to_s
82
+ end
83
+
84
+ end
85
+
86
+ RDF = OwlNamespace.new 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
87
+ OWL = OwlNamespace.new 'http://www.w3.org/2002/07/owl#'
88
+ DC = OwlNamespace.new 'http://purl.org/dc/elements/1.1/'
89
+ OT = OwlNamespace.new 'http://www.opentox.org/api/1.1#'
90
+ OTA = OwlNamespace.new 'http://www.opentox.org/algorithmTypes.owl#'
91
+ XSD = OwlNamespace.new 'http://www.w3.org/2001/XMLSchema#'
92
+
data/lib/feature.rb ADDED
@@ -0,0 +1,15 @@
1
+ module OpenTox
2
+ class Feature
3
+ include OpenTox
4
+
5
+ def self.find(uri)
6
+ feature = Feature.new uri
7
+ if (CONFIG[:yaml_hosts].include?(URI.parse(uri).host))
8
+ feature.add_metadata YAML.load(RestClientWrapper.get(uri,:accept => "application/x-yaml"))
9
+ else
10
+ feature.add_metadata Parser::Owl::Dataset.new(uri).load_metadata
11
+ end
12
+ feature
13
+ end
14
+ end
15
+ end