summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/algorithm.rb11
-rw-r--r--lib/model.rb11
-rw-r--r--lib/task.rb1
-rw-r--r--lib/validation.rb144
4 files changed, 108 insertions, 59 deletions
diff --git a/lib/algorithm.rb b/lib/algorithm.rb
index bfa9860..af8dfaf 100644
--- a/lib/algorithm.rb
+++ b/lib/algorithm.rb
@@ -31,18 +31,15 @@ module OpenTox
class Generic
include Algorithm
- # Find Generic Opentox Algorithm via URI, and loads metadata
+ # Find Generic Opentox Algorithm via URI, and loads metadata, could raise NotFound/NotAuthorized error
# @param [String] uri Algorithm URI
- # @return [OpenTox::Algorithm::Generic] Algorithm instance, nil if alogrithm was not found
+ # @return [OpenTox::Algorithm::Generic] Algorithm instance
def self.find(uri, subjectid=nil)
return nil unless uri
alg = Generic.new(uri)
alg.load_metadata( subjectid )
- if alg.metadata==nil or alg.metadata.size==0
- nil
- else
- alg
- end
+ raise "cannot load algorithm metadata" if alg.metadata==nil or alg.metadata.size==0
+ alg
end
end
diff --git a/lib/model.rb b/lib/model.rb
index 7cf52ad..ae793e8 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -24,18 +24,15 @@ module OpenTox
class Generic
include Model
- # Find Generic Opentox Model via URI, and loads metadata
+ # Find Generic Opentox Model via URI, and loads metadata, could raise NotFound/NotAuthorized error
# @param [String] uri Model URI
- # @return [OpenTox::Model::Generic] Model instance, nil if model was not found
+ # @return [OpenTox::Model::Generic] Model instance
def self.find(uri,subjectid=nil)
return nil unless uri
model = Generic.new(uri)
model.load_metadata(subjectid)
- if model.metadata==nil or model.metadata.size==0
- nil
- else
- model
- end
+ raise "could not load model metadata" if model.metadata==nil or model.metadata.size==0
+ model
end
# provides feature type, possible types are "regression" or "classification"
diff --git a/lib/task.rb b/lib/task.rb
index 9c52299..73d880e 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -80,6 +80,7 @@ module OpenTox
return nil unless uri
task = Task.new(uri)
task.load_metadata
+ raise "could not load task metadata" if task.metadata==nil or task.metadata.size==0
task
end
diff --git a/lib/validation.rb b/lib/validation.rb
index c256d1d..f0c5297 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -1,4 +1,63 @@
module OpenTox
+ class Validation
+ include OpenTox
+
+ # find validation, raises error if not found
+ # @param [String] uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::Validation]
+ def self.find( uri, subjectid=nil )
+ val = Validation.new(uri)
+ val.load_metadata( subjectid )
+ val
+ 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
+ # @param [String,optional] subjectid
+ # @return [OpenTox::Validation]
+ def self.from_cv_statistics( crossvalidation_uri, subjectid=nil )
+ find( File.join(crossvalidation_uri, 'statistics'),subjectid )
+ end
+
+ # loads metadata via yaml from validation object
+ # fields (like for example the validated model) can be acces via validation.metadata[OT.model]
+ def load_metadata( subjectid=nil )
+ @metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
+ end
+
+ # PENDING: creates summary as used for ToxCreate
+ def summary
+ if @metadata[OT.classificationStatistics]
+ res = {
+ :nr_predictions => @metadata[OT.numInstances] - @metadata[OT.numUnpredicted],
+ :correct_predictions => @metadata[OT.classificationStatistics][OT.percentCorrect],
+ :weighted_area_under_roc => @metadata[OT.classificationStatistics][OT.weightedAreaUnderRoc],
+ }
+ @metadata[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
+ end
+ end
+ res
+ elsif @metadata[OT.regressionStatistics]
+ {
+ :nr_predictions => @metadata[OT.numInstances] - @metadata[OT.numUnpredicted],
+ :r_square => @metadata[OT.regressionStatistics][OT.rSquare],
+ :root_mean_squared_error => @metadata[OT.regressionStatistics][OT.rootMeanSquaredError],
+ :mean_absolute_error => @metadata[OT.regressionStatistics][OT.meanAbsoluteError],
+ }
+ end
+ end
+ end
+
class Crossvalidation
include OpenTox
@@ -9,9 +68,9 @@ module OpenTox
# @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)
+ cv = Crossvalidation.new(uri)
+ cv.load_metadata( subjectid )
+ cv
end
# creates a crossvalidations, waits until it finishes, may take some time
@@ -31,42 +90,37 @@ module OpenTox
# @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 = CrossvalidationReport.find_for_crossvalidation(@uri, subjectid) unless @report
+ @report = CrossvalidationReport.create(@uri, subjectid, waiting_task) unless @report
@report
end
-
+
+ # loads metadata via yaml from crossvalidation object
+ # fields (like for example the validations) can be acces via validation.metadata[OT.validation]
+ def load_metadata( subjectid=nil )
+ @metadata = YAML.load(OpenTox::RestClientWrapper.get(uri,{:subjectid => subjectid, :accept => "application/x-yaml"}))
+ 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
- end
- end
- res
- elsif v[OT.regressionStatistics]
- {
- :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
+ Validation.from_cv_statistics( @uri, subjectid ).summary
end
end
+
+ class ValidationReport
+ include OpenTox
+
+ # finds ValidationReport for a particular validation
+ # @param [String] crossvalidation uri
+ # @param [String,optional] subjectid
+ # @return [OpenTox::ValidationReport] nil if no report found
+ def self.find_for_validation( validation_uri, subjectid=nil )
+ uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
+ "/report/validation?validation="+validation_uri), {:subjectid => subjectid}).chomp.split("\n")
+ uris.size==0 ? nil : ValidationReport.new(uris[-1])
+ end
+
+ end
class CrossvalidationReport
include OpenTox
@@ -82,23 +136,23 @@ module OpenTox
end
# finds CrossvalidationReport for a particular crossvalidation
- # @param [OpenTox::Crossvalidation]
+ # @param [String] crossvalidation uri
# @param [String,optional] subjectid
# @return [OpenTox::CrossvalidationReport] nil if no report found
- def self.find_for_crossvalidation( crossvalidation, subjectid=nil )
+ def self.find_for_crossvalidation( crossvalidation_uri, subjectid=nil )
uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
- "/report/crossvalidation?crossvalidation="+crossvalidation.uri), {:subjectid => subjectid}).chomp.split("\n")
+ "/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] crossvalidation uri
# @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 )
+ def self.create( crossvalidation_uri, subjectid=nil, waiting_task=nil )
uri = RestClientWrapper.post(File.join(CONFIG[:services]["opentox-validation"],"/report/crossvalidation"),
- { :validation_uris => crossvalidation.uri, :subjectid => subjectid }, {}, waiting_task )
+ { :validation_uris => crossvalidation_uri, :subjectid => subjectid }, {}, waiting_task )
CrossvalidationReport.new(uri)
end
end
@@ -117,23 +171,23 @@ module OpenTox
end
# finds QMRF report for a particular model
- # @param [OpenTox::Crossvalidation]
+ # @param [String] model_uri
# @param [String,optional] subjectid
# @return [OpenTox::QMRFReport] nil if no report found
- def self.find_for_model( model, subjectid=nil )
+ def self.find_for_model( model_uri, subjectid=nil )
uris = RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
- "/reach_report/qmrf?model="+model.uri), {:subjectid => subjectid}).chomp.split("\n")
+ "/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] model_uri
# @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 )
+ def self.create( model_uri, 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 )
+ { :model_uri => model_uri, :subjectid => subjectid }, {}, waiting_task )
QMRFReport.new(uri)
end
end