From 3c5d86730bbd4e87d659a01896925628d06e26ff Mon Sep 17 00:00:00 2001 From: mguetlein Date: Fri, 8 Apr 2011 15:39:55 +0200 Subject: =?UTF-8?q?re=C3=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Rakefile | 11 ++- application.rb | 14 +-- data/EPAFHM.mini.csv | 21 +++++ example.rb | 24 ++--- lib/merge.rb | 14 +-- lib/ot_predictions.rb | 4 +- lib/validation_db.rb | 116 +++++++++++++----------- reach_reports/reach_persistance.rb | 5 +- reach_reports/reach_service.rb | 6 +- reach_reports/reach_test.rb | 2 +- report/environment.rb | 2 +- report/report_factory.rb | 6 +- report/report_persistance.rb | 49 +++++----- report/validation_access.rb | 20 ++--- report/validation_data.rb | 50 +++++------ test/test_examples.rb | 2 +- test/unit_test.rb | 170 +++++++++++++++++++---------------- validation/validation_application.rb | 63 +++++++------ validation/validation_format.rb | 21 ++--- validation/validation_service.rb | 53 ++++++----- validation/validation_test.rb | 20 +++-- 21 files changed, 363 insertions(+), 310 deletions(-) create mode 100644 data/EPAFHM.mini.csv diff --git a/Rakefile b/Rakefile index e8e2a92..de1e69d 100755 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,11 @@ require 'rubygems' require 'rake' -REPORT_GEMS = [ 'opentox-ruby', 'mime-types', 'ruby-plot', 'rinruby'] #'ar-extensions', 'activerecord', 'activesupport', -VALIDATION_GEMS = [ 'opentox-ruby', 'ruby-plot'] #'ar-extensions', 'activerecord', 'activesupport', + + +REPORT_GEMS = [ 'opentox-ruby', 'ruby-plot', 'rinruby', 'dm-core', 'dm-serializer', 'dm-timestamps', + 'dm-types', 'dm-migrations', 'dm-validations', 'dm-sqlite-adapter', 'benchmark'] +VALIDATION_GEMS = [ 'opentox-ruby', 'ruby-plot'] GEM_VERSIONS = { "ruby-plot" => "= 0.0.2" } GEM_INSTALL_OPTIONS = {} @@ -11,7 +14,6 @@ GEM_INSTALL_OPTIONS = {} ## this is needed because otherwihse ar-extensions adds activesupport 3.0.0 which confuses things #GEM_INSTALL_OPTIONS = { "ar-extensions" => "--ignore-dependencies" } - desc "Install required gems" task :install_gems do (REPORT_GEMS + VALIDATION_GEMS).uniq.each do |g| @@ -29,7 +31,8 @@ task :install_gems do options = "" options += "--version '"+GEM_VERSIONS[g]+"' " if GEM_VERSIONS.has_key?(g) options += GEM_INSTALL_OPTIONS[g]+" " if GEM_INSTALL_OPTIONS.has_key?(g) - cmd = "sudo env PATH=$PATH gem install "+options+" "+g + #cmd = "sudo env PATH=$PATH gem install "+options+" "+g + cmd = "gem install "+options+" "+g puts "installing gem, this may take some time..." puts cmd IO.popen(cmd){ |f| puts f.gets } diff --git a/application.rb b/application.rb index ad9653a..10c8fe6 100755 --- a/application.rb +++ b/application.rb @@ -1,16 +1,8 @@ require 'rubygems' -gem "opentox-ruby", "~> 0" -[ 'sinatra', 'sinatra/url_for', 'opentox-ruby' ].each do |lib| +gem "opentox-ruby" +[ 'sinatra', 'sinatra/url_for', 'opentox-ruby', 'benchmark' ].each do |lib| require lib end -['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations', 'dm-validations' ].each{|lib| require lib } -DataMapper.setup(:default, { - :adapter => CONFIG[:database][:adapter], - :database => CONFIG[:database][:database], - :username => CONFIG[:database][:username], - :password => CONFIG[:database][:password], - :host => CONFIG[:database][:host]}) -set :lock, true #unless(defined? LOGGER) #LOGGER = Logger.new(STDOUT) @@ -37,7 +29,7 @@ end get '/prepare_examples/?' do LOGGER.info "prepare examples" content_type "text/plain" - Example.prepare_example_resources + return_task(Example.prepare_example_resources) end post '/test_examples/?' do diff --git a/data/EPAFHM.mini.csv b/data/EPAFHM.mini.csv new file mode 100644 index 0000000..c86cd33 --- /dev/null +++ b/data/EPAFHM.mini.csv @@ -0,0 +1,21 @@ +"STRUCTURE_SMILES","LC50_mmol" +"C1=CC(C=O)=CC(OC)=C1OCCCCCC",1.13E-02 +"C1(OC)=C([N+]([O-])=O)C(C=O)=CC(Br)=C1O",2.66E-01 +"CCCCCCCCOC(=O)C1=CC=CC(C(=O)OCCCCCCCC)=C1", +"C1=CC(Cl)=CC=C1OC2=C([N+](=O)[O-])C=CC=C2",7.69E-03 +"CC1=C(NC=O)C=CC=C1Cl",2.75E-01 +"CCCCOC(=O)C1=CC=CC(C(=O)OCCCC)=C1",3.23E-03 +"C(C1=CC=CC=C1)(C2=CC=CC=C2)(O)C#C",5.33E-02 +"CCCSCCSCCC",4.22E-02 +"CCCCCCCCOC(=O)C1=CC=C(C(=O)OCCCCCCCC)C=C1", +"OCCCCOC(=O)C1=CC=CC=C1C(=O)OCCCCOC(=O)C2=CC=CC=C2C(=O)OCCCCO", +"CCCSCCCCSCCC",1.45E-02 +"C1([N+](=O)[O-])=CC=C(C)C=C1OP(=O)(OC2=C([N+](=O)[O-])C=CC(C)=C2)OC3=C([N+]([O-])=O)C=CC(C)=C3", +"C1=C([N+]([O-])=O)C=CC=C1P(=O)(C2=CC([N+](=O)[O-])=CC=C2)C3=CC([N+](=O)[O-])=CC=C3", +"ClCCOC(=O)NC1CCCCC1",1.70E-01 +"O=C1C(C2=CC=CC=C2)(C(=O)NC(=O)N1)CC",2.08E+00 +"OC1=C(C=C(C=C1)[N+](=O)[O-])[N+](=O)[O-]",5.92E-02 +"NC(=O)OCC",5.88E+01 +"[O-]C(C1=CC=CC=C1O)=O.[Na+]",1.25E+01 +"C1=CC=CC=C1C(=O)N",5.46E+00 +"CC[N+](CC)(CC)CC1(=CC=CC=C1).[Cl-]",7.07E-01 diff --git a/example.rb b/example.rb index 07151a8..b0b591e 100755 --- a/example.rb +++ b/example.rb @@ -3,11 +3,11 @@ require 'lib/test_util.rb' class Example - @@file=File.new("data/hamster_carcinogenicity.yaml","r") + @@file=File.new("data/hamster_carcinogenicity.csv","r") @@file_type="text/x-yaml" @@model=File.join CONFIG[:services]["opentox-model"],"1" #@@feature= URI.encode("http://local-ot/toxmodel/feature#Hamster%20Carcinogenicity%20(DSSTOX/CPDB)") - @@feature= File.join CONFIG[:services]["opentox-dataset"],"1/feature/hamster_carcinogenicity" + @@feature= File.join CONFIG[:services]["opentox-dataset"],"1/feature/Hamster%2520Carcinogenicity" #@@predicted_feature= URI.encode("http://local-ot/toxmodel/feature#Hamster%20Carcinogenicity%20(DSSTOX/CPDB)_lazar_classification") @@alg = File.join CONFIG[:services]["opentox-algorithm"],"lazar" @@alg_params = "feature_generation_uri="+File.join(CONFIG[:services]["opentox-algorithm"],"fminer/bbrc") @@ -58,12 +58,15 @@ class Example #TODO subjectid = nil + Ohm.flush + task = OpenTox::Task.create("prepare examples", "n/a") do |task| @@summary = "" + #delete validations - log "delete validations" - Lib::Validation.auto_migrate! - Lib::Crossvalidation.auto_migrate! + #log "delete validations" + #Lib::Validation.auto_migrate! + #Lib::Crossvalidation.auto_migrate! #ActiveRecord::Base.logger = Logger.new("/dev/null") #ActiveRecord::Migrator.migrate('db/migrate', 0 ) #ActiveRecord::Migrator.migrate('db/migrate', 1 ) @@ -80,10 +83,7 @@ class Example halt 400,"File not found: "+@@file.path.to_s unless File.exist?(@@file.path) #data = File.read(@@file.path) #data_uri = OpenTox::RestClientWrapper.post(CONFIG[:services]["opentox-dataset"],{:content_type => @@file_type},data).chomp("\n") - data = File.read(@@file.path) - dataset = OpenTox::Dataset.create - dataset.load_yaml(data) - dataset.save + dataset = OpenTox::Dataset.create_from_csv_file(@@file.path,nil) data_uri = dataset.uri log "-> "+data_uri task.progress(20) @@ -92,7 +92,7 @@ class Example #delete_all(CONFIG[:services]["opentox-model"]) OpenTox::RestClientWrapper.delete CONFIG[:services]["opentox-model"] - split_params = Validation::Util.train_test_dataset_split(data_uri, URI.decode(@@feature), 0.9, 1) + split_params = Validation::Util.train_test_dataset_split(data_uri, URI.decode(@@feature), nil, 0.9, 1) v = Validation::Validation.new :training_dataset_uri => split_params[:training_dataset_uri], :validation_type => "test_set_validation", :test_dataset_uri => split_params[:test_dataset_uri], @@ -102,7 +102,7 @@ class Example v.validate_algorithm( @@alg_params, OpenTox::SubTask.new(task, 20, 40) ) log "crossvalidation" - cv = Validation::Crossvalidation.new({ :dataset_uri => data_uri, :algorithm_uri => @@alg, :num_folds => 5, :stratified => false }) + cv = Validation::Crossvalidation.create({ :dataset_uri => data_uri, :algorithm_uri => @@alg, :num_folds => 5, :stratified => false }) cv.perform_cv( URI.decode(@@feature), @@alg_params, OpenTox::SubTask.new(task, 40, 70) ) log "create validation report" @@ -124,7 +124,7 @@ class Example log "done" @@summary end - return_task(task) + task end # performs all curl calls listed in examples after ">>>", next line is added if line ends with "\" diff --git a/lib/merge.rb b/lib/merge.rb index 527415e..ecbe133 100644 --- a/lib/merge.rb +++ b/lib/merge.rb @@ -20,8 +20,7 @@ module Lib def self.merge_array_objects( array ) return nil if array.size == nil return array[0] if array.size==1 - - m = self.merge_objects(array[0], array[1] ) + m = self.merge_objects(array[0], array[1]) (2..array.size-1).each do |i| m = self.merge_objects(m, array[i] ) end @@ -33,8 +32,7 @@ module Lib end def self.merge_objects( object1, object2 ) - - raise "classes not equal" if object1.class != object2.class + raise "classes not equal : "+object1.class.to_s+" != "+object2.class.to_s if object1.class != object2.class object_class = object1.class raise "register which attributes to merge first, nothing found for class "+object_class.to_s unless merge_attributes_registered?(object_class) raise "not supported, successivly add unmerged object to a merge object" if merge_count(object2)>1 @@ -71,6 +69,11 @@ module Lib variance = nil if (avg=avg_attribute?(object_class, attribute)) || sum_attribute?(object_class, attribute) + # we string to numerics if wanted, value1 is no string anymore if weight>1 + if value2.is_a?(String) and ((weight1==1 and value1.is_a?(String)) or (weight1>1 and value1.is_a?(Numeric))) + value1 = value1.to_f + value2 = value2.to_f + end if (value1==nil and value2==nil ) #do nothing elsif value1.is_a?(Numeric) and value2.is_a?(Numeric) @@ -104,7 +107,8 @@ module Lib end end else - raise "invalid, cannot avg/sum non-numeric content for attribute: "+attribute.to_s+" contents: '"+value1.to_s+"', '"+value2.to_s+"'" + raise "invalid, cannot avg/sum non-numeric content for attribute: "+attribute.to_s+" contents: '"+value1.to_s+"' ("+ + value1.class.to_s+"), '"+value2.to_s+"' ("+value2.class.to_s+")" end elsif non_numeric_attribute?(object_class, attribute) if (value1.is_a?(Hash) and value2.is_a?(Hash)) diff --git a/lib/ot_predictions.rb b/lib/ot_predictions.rb index f812854..5033425 100755 --- a/lib/ot_predictions.rb +++ b/lib/ot_predictions.rb @@ -184,9 +184,9 @@ module Lib res = {} case @feature_type when "classification" - (Lib::VAL_CLASS_PROPS).each{ |s| res[s] = send(s)} + (Validation::VAL_CLASS_PROPS).each{ |s| res[s] = send(s)} when "regression" - (Lib::VAL_REGR_PROPS).each{ |s| res[s] = send(s) } + (Validation::VAL_REGR_PROPS).each{ |s| res[s] = send(s) } end return res end diff --git a/lib/validation_db.rb b/lib/validation_db.rb index 0d5db21..0beb73d 100755 --- a/lib/validation_db.rb +++ b/lib/validation_db.rb @@ -4,7 +4,7 @@ #end require "lib/merge.rb" -module Lib +module Validation VAL_PROPS_GENERAL = [ :validation_uri, :validation_type, :model_uri, :algorithm_uri, :training_dataset_uri, :prediction_feature, :test_dataset_uri, :test_target_dataset_uri, :prediction_dataset_uri, :date ] @@ -48,42 +48,53 @@ module Lib VAL_MERGE_AVG = VAL_PROPS_AVG + VAL_CLASS_PROPS_SINGLE_AVG + VAL_CLASS_PROPS_PER_CLASS_AVG + VAL_REGR_PROPS -# class Validation < ActiveRecord::Base -# serialize :classification_statistics -# serialize :regression_statistics -# -# alias_attribute :date, :created_at - - class Validation - include DataMapper::Resource + class Validation < Ohm::Model - property :id, Serial - property :validation_type, String, :length => 512 - property :model_uri, String, :length => 512 - property :algorithm_uri, String, :length => 512 - property :training_dataset_uri, String, :length => 512 - property :test_target_dataset_uri, String, :length => 512 - property :test_dataset_uri, String, :length => 512 - property :prediction_dataset_uri, String, :length => 512 - property :prediction_feature, String, :length => 512 - property :created_at, DateTime - property :num_instances, Integer - property :num_without_class, Integer - property :num_unpredicted, Integer - property :crossvalidation_id, Integer - property :crossvalidation_fold, Integer - property :real_runtime, Float - property :percent_without_class, Float - property :percent_unpredicted, Float - property :classification_statistics, Object - property :regression_statistics, Object - property :finished, Boolean, :default => false + attribute :validation_type + attribute :model_uri + attribute :algorithm_uri + attribute :training_dataset_uri + attribute :test_target_dataset_uri + attribute :test_dataset_uri + attribute :prediction_dataset_uri + attribute :prediction_feature + attribute :created_at + attribute :num_instances + attribute :num_without_class + attribute :num_unpredicted + attribute :crossvalidation_id + attribute :crossvalidation_fold + attribute :real_runtime + attribute :percent_without_class + attribute :percent_unpredicted + attribute :classification_statistics_yaml + attribute :regression_statistics_yaml + attribute :finished + + index :model_uri + index :validation_type + index :crossvalidation_id attr_accessor :subjectid - after :save, :check_policy - private - def check_policy + def classification_statistics + YAML.load(self.classification_statistics_yaml) if self.classification_statistics_yaml + end + + def classification_statistics=(cs) + self.classification_statistics_yaml = cs.to_yaml + end + + def regression_statistics + YAML.load(self.regression_statistics_yaml) if self.regression_statistics_yaml + end + + def regression_statistics=(rs) + self.regression_statistics_yaml = rs.to_yaml + end + + def save + super OpenTox::Authorization.check_policy(validation_uri, subjectid) end @@ -115,25 +126,27 @@ module Lib end -# class Crossvalidation < ActiveRecord::Base -# alias_attribute :date, :created_at - class Crossvalidation - include DataMapper::Resource + class Crossvalidation < Ohm::Model - property :id, Serial - property :algorithm_uri, String, :length => 512 - property :dataset_uri, String, :length => 512 - property :created_at, DateTime - property :num_folds, Integer, :default => 10 - property :random_seed, Integer, :default => 1 - property :finished, Boolean, :default => false - property :stratified, Boolean, :default => false + attribute :algorithm_uri + attribute :dataset_uri + attribute :created_at + attribute :num_folds + attribute :random_seed + attribute :finished + attribute :stratified attr_accessor :subjectid + + index :algorithm_uri + index :dataset_uri + index :num_folds + index :random_seed + index :stratified + index :finished - after :save, :check_policy - private - def check_policy + def save + super OpenTox::Authorization.check_policy(crossvalidation_uri, subjectid) end @@ -152,7 +165,7 @@ module Lib # further conditions can be specified in __conditions__ def self.find_all_uniq(conditions={}, subjectid=nil ) #cvs = Lib::Crossvalidation.find(:all, :conditions => conditions) - cvs = Lib::Crossvalidation.all(:conditions => conditions) + cvs = Crossvalidation.find( conditions ) uniq = [] cvs.each do |cv| next if AA_SERVER and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",subjectid) @@ -171,8 +184,3 @@ module Lib end end - -Lib::Validation.auto_upgrade! -Lib::Validation.raise_on_save_failure = true -Lib::Crossvalidation.auto_upgrade! -Lib::Crossvalidation.raise_on_save_failure = true diff --git a/reach_reports/reach_persistance.rb b/reach_reports/reach_persistance.rb index 3118809..b90778b 100755 --- a/reach_reports/reach_persistance.rb +++ b/reach_reports/reach_persistance.rb @@ -1,5 +1,8 @@ -require "dm-validations" +['dm-core', 'dm-serializer', 'dm-timestamps', 'dm-types', 'dm-migrations', 'dm-validations' ].each{|lib| require lib } +db_dir = File.join(File.join(ENV['HOME'], ".opentox"), "db") +FileUtils.mkdir_p db_dir +DataMapper::setup(:default, "sqlite3://#{db_dir}/reach_reports.sqlite3") DataMapper::Model.raise_on_save_failure = true diff --git a/reach_reports/reach_service.rb b/reach_reports/reach_service.rb index 53acb62..0cf4172 100755 --- a/reach_reports/reach_service.rb +++ b/reach_reports/reach_service.rb @@ -133,11 +133,11 @@ module ReachReports val_datasets = [] if algorithm - cvs = Lib::Crossvalidation.find_all_uniq({:algorithm_uri => algorithm.uri, :finished => true},r.subjectid) + cvs = Validation::Crossvalidation.find_all_uniq({:algorithm_uri => algorithm.uri, :finished => true},r.subjectid) # PENDING: cv classification/regression hack cvs = cvs.delete_if do |cv| #val = Validation::Validation.first( :all, :conditions => { :crossvalidation_id => cv.id } ) - val = Validation::Validation.first( :crossvalidation_id => cv.id ) + val = Validation::Validation.find( :crossvalidation_id => cv.id ).first raise "should not happen: no validations found for crossvalidation "+cv.id.to_s unless val (val.classification_statistics!=nil) != (feature_type=="classification") end @@ -196,7 +196,7 @@ module ReachReports LOGGER.debug "looking for validations with "+{:model_uri => model.uri}.inspect #vals = Lib::Validation.find(:all, :conditions => {:model_uri => model.uri}) - vals = Lib::Validation.all({:model_uri => model.uri}) + vals = Validation::Validation.find({:model_uri => model.uri}) uniq_vals = [] vals.each do |val| match = false diff --git a/reach_reports/reach_test.rb b/reach_reports/reach_test.rb index 87addfa..43aec28 100755 --- a/reach_reports/reach_test.rb +++ b/reach_reports/reach_test.rb @@ -150,7 +150,7 @@ class ReachTest < Test::Unit::TestCase #model_uri = "http://local-ot/model/104" - model_uri = "http://local-ot/majority/class/model/125" + model_uri = "http://local-ot/model/72" # m = OpenTox::Model::Generic.find(model_uri) diff --git a/report/environment.rb b/report/environment.rb index 12e3272..aa8ab56 100755 --- a/report/environment.rb +++ b/report/environment.rb @@ -13,7 +13,7 @@ end require "lib/ot_predictions.rb" #require "lib/active_record_setup.rb" -require "lib/data_mapper_util.rb" +#require "lib/data_mapper_util.rb" require "report/plot_factory.rb" require "report/xml_report.rb" diff --git a/report/report_factory.rb b/report/report_factory.rb index e770d2f..f48d11a 100755 --- a/report/report_factory.rb +++ b/report/report_factory.rb @@ -76,7 +76,7 @@ module Reports::ReportFactory end task.progress(90) if task - report.add_result(validation_set, Lib::ALL_PROPS, "All Results", "All Results") + report.add_result(validation_set, Validation::ALL_PROPS, "All Results", "All Results") report.add_predictions( validation_set ) task.progress(100) if task report @@ -89,7 +89,7 @@ module Reports::ReportFactory validation_set.get_values(:crossvalidation_id,false).inspect) if validation_set.unique_value(:crossvalidation_id)==nil validation_set.load_cv_attributes raise OpenTox::BadRequestError.new("num validations ("+validation_set.size.to_s+") is not equal to num folds ("+ - validation_set.unique_value(:num_folds).to_s+")") unless validation_set.unique_value(:num_folds)==validation_set.size + validation_set.unique_value(:num_folds).to_s+")") unless validation_set.unique_value(:num_folds).to_i==validation_set.size raise OpenTox::BadRequestError.new("num different folds is not equal to num validations") unless validation_set.num_different_values(:crossvalidation_fold)==validation_set.size raise OpenTox::BadRequestError.new("validations must have unique feature type, i.e. must be either all regression, "+ +"or all classification validations") unless validation_set.unique_feature_type @@ -116,7 +116,7 @@ module Reports::ReportFactory end task.progress(90) if task - report.add_result(validation_set, Lib::ALL_PROPS, "All Results", "All Results") + report.add_result(validation_set, Validation::ALL_PROPS, "All Results", "All Results") report.add_predictions( validation_set ) #, [:crossvalidation_fold] ) task.progress(100) if task report diff --git a/report/report_persistance.rb b/report/report_persistance.rb index df4930c..9097fa3 100755 --- a/report/report_persistance.rb +++ b/report/report_persistance.rb @@ -188,22 +188,21 @@ module Reports # serialize :model_uris # alias_attribute :date, :created_at - class ReportData - include DataMapper::Resource + class ReportData < Ohm::Model - property :id, Serial - property :report_type, String, :length => 255 - property :created_at, DateTime - property :validation_uris, Object - property :crossvalidation_uris, Object - property :model_uris, Object - property :algorithm_uris, Object + attribute :report_type + attribute :created_at + attribute :validation_uris + attribute :crossvalidation_uris + attribute :model_uris + attribute :algorithm_uris + + index :report_type attr_accessor :subjectid - after :save, :check_policy - private - def check_policy + def save + super OpenTox::Authorization.check_policy(report_uri, subjectid) end @@ -245,32 +244,30 @@ module Reports report.subjectid = subjectid report.report_type = type report.save + OpenTox::Authorization.check_policy(report.report_uri, subjectid) new_report_with_id(report_content, type, report.id) end def list_reports(type, filter_params={}) - filter_params["report_type"]=type unless filter_params.has_key?("report_type") - #ReportData.find_like(filter_params).delete_if{|r| r.report_type!=type}.collect{ |r| r.id } - - filter_params = Lib::DataMapperUtil.check_params(ReportData, filter_params) + LOGGER.debug "find reports for params: "+filter_params.inspect # unfortunately, datamapper does not allow searching in Objects # do filtering for list = Object params manually list_params = {} [:validation_uris, :crossvalidation_uris, :algorithm_uris, :model_uris].each do |l| list_params[l] = filter_params.delete(l) if filter_params.has_key?(l) end - - reports = ReportData.all(filter_params).delete_if{|r| r.report_type!=type} + reports = ReportData.find( :report_type => type ) list_params.each do |k,v| - reports = reports.delete_if{ |r| !r.send(k).include?(v) } + reports = reports.collect{|x| x}.delete_if{ |r| !r.send(k).include?(v) } end reports.collect{ |r| r.id } end def get_report(type, id, format, force_formating, params) - report = ReportData.first({:id => id, :report_type => type}) - raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") unless report + report = ReportData[id] + raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") if + report==nil or report.report_type!=type # begin # report = ReportData.find(:first, :conditions => {:id => id, :report_type => type}) # rescue ActiveRecord::RecordNotFound @@ -294,9 +291,10 @@ module Reports # raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") # end # ReportData.delete(id) - report = ReportData.first({:id => id, :report_type => type}) - raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") unless report - report.destroy + report = ReportData[id] + raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") if + report==nil || report.report_type!=type + report.delete if (subjectid) begin res = OpenTox::Authorization.delete_policies_from_uri(report.report_uri, subjectid) @@ -310,9 +308,6 @@ module Reports end end -Reports::ReportData.auto_upgrade! -Reports::ReportData.raise_on_save_failure = true - #module Reports # def self.check_filter_params(model, filter_params) # prop_names = model.properties.collect{|p| p.name.to_s} diff --git a/report/validation_access.rb b/report/validation_access.rb index 53ecc46..96dfbf3 100755 --- a/report/validation_access.rb +++ b/report/validation_access.rb @@ -21,11 +21,11 @@ class Reports::ValidationDB # rescue => ex # raise "could not access crossvalidation with id "+validation_id.to_s+", error-msg: "+ex.message # end - cv = Lib::Crossvalidation.get( cv_id ) + cv = Validation::Crossvalidation.get( cv_id ) raise OpenTox::NotFoundError.new "crossvalidation with id "+cv_id.to_s+" not found" unless cv raise OpenTox::BadRequestError.new("crossvalidation with id '"+cv_id.to_s+"' not finished") unless cv.finished - #res += Lib::Validation.find( :all, :conditions => { :crossvalidation_id => cv_id } ).collect{|v| v.validation_uri.to_s} - res += Lib::Validation.all( :crossvalidation_id => cv_id ).collect{|v| v.validation_uri.to_s } + #res += Validation::Validation.find( :all, :conditions => { :crossvalidation_id => cv_id } ).collect{|v| v.validation_uri.to_s} + res += Validation::Validation.find( :crossvalidation_id => cv_id ).collect{|v| v.validation_uri.to_s } else res += [u.to_s] end @@ -42,16 +42,16 @@ class Reports::ValidationDB v = nil raise OpenTox::NotAuthorizedError.new "Not authorized: GET "+uri.to_s if AA_SERVER and !OpenTox::Authorization.authorized?(uri,"GET",subjectid) - v = Lib::Validation.get(validation_id) + v = Validation::Validation.get(validation_id) raise OpenTox::NotFoundError.new "validation with id "+validation_id.to_s+" not found" unless v raise OpenTox::BadRequestError.new "validation with id "+validation_id.to_s+" is not finished yet" unless v.finished - (Lib::VAL_PROPS + Lib::VAL_CV_PROPS).each do |p| + (Validation::VAL_PROPS + Validation::VAL_CV_PROPS).each do |p| validation.send("#{p.to_s}=".to_sym, v.send(p)) end - {:classification_statistics => Lib::VAL_CLASS_PROPS, - :regression_statistics => Lib::VAL_REGR_PROPS}.each do |subset_name,subset_props| + {:classification_statistics => Validation::VAL_CLASS_PROPS, + :regression_statistics => Validation::VAL_REGR_PROPS}.each do |subset_name,subset_props| subset = v.send(subset_name) subset_props.each{ |prop| validation.send("#{prop.to_s}=".to_sym, subset[prop]) } if subset end @@ -60,11 +60,11 @@ class Reports::ValidationDB def init_cv(validation) #cv = Lib::Crossvalidation.find(validation.crossvalidation_id) - cv = Lib::Crossvalidation.get(validation.crossvalidation_id) + cv = Validation::Crossvalidation.get(validation.crossvalidation_id) raise OpenTox::BadRequestError.new "no crossvalidation found with id "+validation.crossvalidation_id.to_s unless cv - Lib::CROSS_VAL_PROPS.each do |p| - validation.send("#{p.to_s}=".to_sym, cv[p]) + Validation::CROSS_VAL_PROPS.each do |p| + validation.send("#{p.to_s}=".to_sym, cv.send(p.to_s)) end end diff --git a/report/validation_data.rb b/report/validation_data.rb index 15d51ec..9212c98 100755 --- a/report/validation_data.rb +++ b/report/validation_data.rb @@ -51,13 +51,13 @@ end module Reports - # = Reports::Validation + # = ReportValidation # # contains all values of a validation object # - class Validation + class ReportValidation - @@validation_access = Reports::ValidationDB.new + @@validation_access = ValidationDB.new # for overwriting validation source (other than using webservices) def self.reset_validation_access(validation_access) @@ -69,7 +69,7 @@ module Reports end # create member variables for all validation properties - @@validation_attributes = Lib::ALL_PROPS + + @@validation_attributes = Validation::ALL_PROPS + VAL_ATTR_VARIANCE.collect{ |a| (a.to_s+"_variance").to_sym } + VAL_ATTR_RANKING.collect{ |a| (a.to_s+"_ranking").to_sym } @@validation_attributes.each{ |a| attr_accessor a } @@ -85,7 +85,7 @@ module Reports # returns/creates predictions, cache to save rest-calls/computation time # # call-seq: - # get_predictions => Reports::Predictions + # get_predictions => Predictions # def get_predictions( task=nil ) if @predictions @@ -127,13 +127,13 @@ module Reports @@validation_access.init_cv(self) end - @@persistance = Reports::ReportService.persistance + @@persistance = ReportService.persistance def validation_report_uri #puts "searching for validation report: "+self.validation_uri.to_s return @validation_report_uri if @validation_report_uri!=nil ids = @@persistance.list_reports("validation",{:validation_uris=>validation_uri }) - @validation_report_uri = Reports::ReportService.instance.get_uri("validation",ids[-1]) if ids and ids.size>0 + @validation_report_uri = ReportService.instance.get_uri("validation",ids[-1]) if ids and ids.size>0 end def cv_report_uri @@ -142,7 +142,7 @@ module Reports raise "no cv uri "+to_yaml unless self.crossvalidation_uri ids = @@persistance.list_reports("crossvalidation",{:crossvalidation=>self.crossvalidation_uri.to_s }) #puts "-> "+ids.inspect - @cv_report_uri = Reports::ReportService.instance.get_uri("crossvalidation",ids[-1]) if ids and ids.size>0 + @cv_report_uri = ReportService.instance.get_uri("crossvalidation",ids[-1]) if ids and ids.size>0 end def clone_validation @@ -160,9 +160,9 @@ module Reports def initialize(validation_uris=nil, subjectid=nil) @unique_values = {} - validation_uris = Reports::Validation.resolve_cv_uris(validation_uris, subjectid) if validation_uris + validation_uris = ReportValidation.resolve_cv_uris(validation_uris, subjectid) if validation_uris @validations = Array.new - validation_uris.each{|u| @validations.push(Reports::Validation.new(u, subjectid))} if validation_uris + validation_uris.each{|u| @validations.push(ReportValidation.new(u, subjectid))} if validation_uris end @@ -249,12 +249,12 @@ module Reports def get_domain_for_attr( attribute ) class_domain = get_class_domain() - if Lib::Validation.classification_property?(attribute) and - !Lib::Validation.depends_on_class_value?(attribute) + if Validation::Validation.classification_property?(attribute) and + !Validation::Validation.depends_on_class_value?(attribute) [ nil ] - elsif Lib::Validation.classification_property?(attribute) and + elsif Validation::Validation.classification_property?(attribute) and class_domain.size==2 and - Lib::Validation.complement_exists?(attribute) + Validation::Validation.complement_exists?(attribute) [ class_domain[0] ] else class_domain @@ -270,10 +270,10 @@ module Reports # returns a new set with all validation that have values as specified in the map # # call-seq: - # filter(map) => Reports::ValidationSet + # filter(map) => ValidationSet # def filter(map) - new_set = Reports::ValidationSet.new + new_set = ValidationSet.new validations.each{ |v| new_set.validations.push(v) if v.has_values?(map) } return new_set end @@ -282,10 +282,10 @@ module Reports # e.g. create set with predictions: collect{ |validation| validation.get_predictions!=null } # # call-seq: - # filter_proc(proc) => Reports::ValidationSet + # filter_proc(proc) => ValidationSet # def collect - new_set = Reports::ValidationSet.new + new_set = ValidationSet.new validations.each{ |v| new_set.validations.push(v) if yield(v) } return new_set end @@ -398,19 +398,19 @@ module Reports # to_array(attributes) => array # def merge(equal_attributes) - new_set = Reports::ValidationSet.new + new_set = ValidationSet.new # unique values stay unique when merging # derive unique values before, because model dependent props cannot be accessed later (when mergin validations from different models) new_set.unique_values = @unique_values #compute grouping - grouping = Reports::Util.group(@validations, equal_attributes) + grouping = Util.group(@validations, equal_attributes) #puts "groups "+grouping.size.to_s - Lib::MergeObjects.register_merge_attributes( Reports::Validation, - Lib::VAL_MERGE_AVG,Lib::VAL_MERGE_SUM,Lib::VAL_MERGE_GENERAL) unless - Lib::MergeObjects.merge_attributes_registered?(Reports::Validation) + Lib::MergeObjects.register_merge_attributes( ReportValidation, + Validation::VAL_MERGE_AVG,Validation::VAL_MERGE_SUM,Validation::VAL_MERGE_GENERAL) unless + Lib::MergeObjects.merge_attributes_registered?(ReportValidation) #merge grouping.each do |g| @@ -438,12 +438,12 @@ module Reports def compute_ranking(equal_attributes, ranking_attribute, class_value=nil ) #puts "compute_ranking("+equal_attributes.inspect+", "+ranking_attribute.inspect+", "+class_value.to_s+" )" - new_set = Reports::ValidationSet.new + new_set = ValidationSet.new (0..@validations.size-1).each do |i| new_set.validations.push(@validations[i].clone_validation) end - grouping = Reports::Util.group(new_set.validations, equal_attributes) + grouping = Util.group(new_set.validations, equal_attributes) grouping.each do |group| # put indices and ranking values for current group into hash diff --git a/test/test_examples.rb b/test/test_examples.rb index 3c6f00e..49d7838 100755 --- a/test/test_examples.rb +++ b/test/test_examples.rb @@ -85,7 +85,7 @@ module ValidationExamples class EPAFHMCrossvalidation < CrossValidation def initialize - @dataset_file = File.new("data/EPAFHM.csv","r") + @dataset_file = File.new("data/EPAFHM.mini.csv","r") #@prediction_feature = "http://ot-dev.in-silico.ch/toxcreate/feature#IRIS%20unit%20risk" @num_folds = 10 end diff --git a/test/unit_test.rb b/test/unit_test.rb index 11b0759..c5a4a62 100644 --- a/test/unit_test.rb +++ b/test/unit_test.rb @@ -1,6 +1,6 @@ #TEST_USER = "mgtest" #TEST_PW = "mgpasswd" -#ENV['RACK_ENV'] = 'test' +ENV['RACK_ENV'] = 'production' require "rubygems" require "sinatra" @@ -44,108 +44,124 @@ class ValidationTest < Test::Unit::TestCase puts "AA disabled" @@subjectid = nil end - f = File.new("data/hamster_carcinogenicity.mini.csv") - @@data_class_mini = ValidationExamples::Util.upload_dataset(f, @@subjectid) - @@feat_class_mini = ValidationExamples::Util.prediction_feature_for_file(f) + + files = [ + File.new("data/hamster_carcinogenicity.mini.csv"), + File.new("data/EPAFHM.mini.csv") + ] + @@data = {} + files.each do |f| + d = ValidationExamples::Util.upload_dataset(f, @@subjectid) + @@data[d] = ValidationExamples::Util.prediction_feature_for_file(f) + end end def global_teardown puts "delete and logout" - OpenTox::Dataset.find(@@data_class_mini,@@subjectid).delete(@@subjectid) if defined?@@data_class_mini - @@cv.delete(@@subjectid) if defined?@@cv - @@report.delete(@@subjectid) if defined?@@report - @@qmrfReport.delete(@@subjectid) if defined?@@qmrfReport + #OpenTox::Dataset.find(@@data,@@subjectid).delete(@@subjectid) if defined?@@data + @@cvs.each{|cv| cv.delete(@@subjectid)} if defined?@@cvs + @@reports.each{|report| report.delete(@@subjectid)} if defined?@@reports + @@qmrfReports.each{|qmrfReport| qmrfReport.delete(@@subjectid)} if defined?@@qmrfReports OpenTox::Authorization.logout(@@subjectid) if AA_SERVER end def test_crossvalidation - puts "test_crossvalidation" + #assert_rest_call_error OpenTox::NotFoundError do # OpenTox::Crossvalidation.find(File.join(CONFIG[:services]["opentox-validation"],"crossvalidation/noexistingid")) #end - p = { - :dataset_uri => @@data_class_mini, - :algorithm_uri => File.join(CONFIG[:services]["opentox-algorithm"],"lazar"), - :algorithm_params => "feature_generation_uri="+File.join(CONFIG[:services]["opentox-algorithm"],"fminer/bbrc"), - :prediction_feature => @@feat_class_mini, - :num_folds => 2 } - t = OpenTox::SubTask.new(nil,0,1) - def t.progress(pct) - if !defined?@last_msg or @last_msg+3 data, + :algorithm_uri => File.join(CONFIG[:services]["opentox-algorithm"],"lazar"), + :algorithm_params => "feature_generation_uri="+File.join(CONFIG[:services]["opentox-algorithm"],"fminer/bbrc"), + :prediction_feature => feat, + :num_folds => 2 } + t = OpenTox::SubTask.new(nil,0,1) + def t.progress(pct) + if !defined?@last_msg or @last_msg+3 params[:dataset_uri], :algorithm_uri => params[:algorithm_uri] } [ :num_folds, :random_seed, :stratified ].each{ |sym| cv_params[sym] = params[sym] if params[sym] } - cv = Validation::Crossvalidation.new cv_params + cv = Validation::Crossvalidation.create cv_params cv.subjectid = @subjectid cv.perform_cv( params[:prediction_feature], params[:algorithm_params], task ) cv.crossvalidation_uri @@ -62,7 +63,7 @@ post '/crossvalidation/cleanup/?' do deleted << cv.crossvalidation_uri #Validation::Crossvalidation.delete(cv.id) cv.subjectid = @subjectid - cv.delete + cv.delete_crossvalidation #end end LOGGER.info "crossvalidation cleanup, deleted "+deleted.size.to_s+" cvs" @@ -124,13 +125,19 @@ get '/crossvalidation/:id/statistics' do raise OpenTox::BadRequestError.new "Crossvalidation '"+params[:id].to_s+"' not finished" unless crossvalidation.finished Lib::MergeObjects.register_merge_attributes( Validation::Validation, - Lib::VAL_MERGE_AVG,Lib::VAL_MERGE_SUM,Lib::VAL_MERGE_GENERAL-[:date,:validation_uri,:crossvalidation_uri]) unless + Validation::VAL_MERGE_AVG,Validation::VAL_MERGE_SUM,Validation::VAL_MERGE_GENERAL-[:date,:validation_uri,:crossvalidation_uri]) unless Lib::MergeObjects.merge_attributes_registered?(Validation::Validation) #v = Lib::MergeObjects.merge_array_objects( Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ) ) - v = Lib::MergeObjects.merge_array_objects( Validation::Validation.all( :crossvalidation_id => params[:id] ) ) + # convert ohm:set into array, as ohm:set[0]=nil(!) + vals = Validation::Validation.find( :crossvalidation_id => params[:id] ).collect{|x| x} +# LOGGER.debug vals.collect{|v| v.validation_uri}.join("\n") +# LOGGER.debug vals.size +# LOGGER.debug vals.class + + v = Lib::MergeObjects.merge_array_objects( vals ) v.created_at = nil - v.id = nil + #v.id = nil case request.env['HTTP_ACCEPT'].to_s when /text\/html/ @@ -159,7 +166,7 @@ delete '/crossvalidation/:id/?' do cv = Validation::Crossvalidation.get(params[:id]) cv.subjectid = @subjectid raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." unless cv - cv.delete + cv.delete_crossvalidation end #get '/crossvalidation/:id/validations' do @@ -208,8 +215,8 @@ get '/?' do LOGGER.info "list all validations, params: "+params.inspect #uri_list = Validation::Validation.find_like(params).collect{ |v| v.validation_uri }.join("\n")+"\n" #uri_list = Validation::Validation.all(params).collect{ |v| v.validation_uri }.join("\n")+"\n" - uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" - + #uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + uri_list = Validation::Validation.all.collect{|v| v.validation_uri}.join("\n") + "\n" if request.env['HTTP_ACCEPT'] =~ /text\/html/ related_links = @@ -241,7 +248,7 @@ post '/test_set_validation' do LOGGER.info "creating test-set-validation "+params.inspect if params[:model_uri] and params[:test_dataset_uri] and !params[:training_dataset_uri] and !params[:algorithm_uri] task = OpenTox::Task.create( "Perform test-set-validation", url_for("/", :full) ) do |task| #, params - v = Validation::Validation.new :validation_type => "test_set_validation", + v = Validation::Validation.create :validation_type => "test_set_validation", :model_uri => params[:model_uri], :test_dataset_uri => params[:test_dataset_uri], :test_target_dataset_uri => params[:test_target_dataset_uri], @@ -262,8 +269,9 @@ get '/test_set_validation' do #uri_list = Validation::Validation.find( :all, :conditions => { :validation_type => "test_set_validation" } ).collect{ |v| v.validation_uri }.join("\n")+"\n" #uri_list = Validation::Validation.all( :validation_type => "test_set_validation" ).collect{ |v| v.validation_uri }.join("\n")+"\n" - params[:validation_type] = "test_set_validation" - uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + #params[:validation_type] = "test_set_validation" + #uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + uri_list = Validation::Validation.find(:validation_type => "test_set_validation").collect{|v| v.validation_uri}.join("\n") + "\n" if request.env['HTTP_ACCEPT'] =~ /text\/html/ related_links = @@ -285,7 +293,7 @@ post '/training_test_validation/?' do LOGGER.info "creating training-test-validation "+params.inspect if params[:algorithm_uri] and params[:training_dataset_uri] and params[:test_dataset_uri] and params[:prediction_feature] and !params[:model_uri] task = OpenTox::Task.create( "Perform training-test-validation", url_for("/", :full) ) do |task| #, params - v = Validation::Validation.new :validation_type => "training_test_validation", + v = Validation::Validation.create :validation_type => "training_test_validation", :algorithm_uri => params[:algorithm_uri], :training_dataset_uri => params[:training_dataset_uri], :test_dataset_uri => params[:test_dataset_uri], @@ -306,8 +314,9 @@ get '/training_test_validation' do LOGGER.info "list all training-test-validations, params: "+params.inspect #uri_list = Validation::Validation.find( :all, :conditions => { :validation_type => "training_test_validation" } ).collect{ |v| v.validation_uri }.join("\n")+"\n" #uri_list = Validation::Validation.all( :validation_type => "training_test_validation" ).collect{ |v| v.validation_uri }.join("\n")+"\n" - params[:validation_type] = "training_test_validation" - uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + #params[:validation_type] = "training_test_validation" + #uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + uri_list = Validation::Validation.find(:validation_type => "training_test_validation").collect{|v| v.validation_uri}.join("\n") + "\n" if request.env['HTTP_ACCEPT'] =~ /text\/html/ related_links = @@ -340,7 +349,7 @@ post '/bootstrapping' do params.merge!( Validation::Util.bootstrapping( params[:dataset_uri], params[:prediction_feature], @subjectid, params[:random_seed], OpenTox::SubTask.create(task,0,33)) ) - v = Validation::Validation.new :validation_type => "bootstrapping", + v = Validation::Validation.create :validation_type => "bootstrapping", :test_target_dataset_uri => params[:dataset_uri], :prediction_feature => params[:prediction_feature], :algorithm_uri => params[:algorithm_uri] @@ -355,8 +364,9 @@ get '/bootstrapping' do LOGGER.info "list all bootstrapping-validations, params: "+params.inspect #uri_list = Validation::Validation.find( :all, :conditions => { :validation_type => "bootstrapping" } ).collect{ |v| v.validation_uri }.join("\n")+"\n" #uri_list = Validation::Validation.all( :validation_type => "bootstrapping" ).collect{ |v| v.validation_uri }.join("\n")+"\n" - params[:validation_type] = "bootstrapping" - uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + #params[:validation_type] = "bootstrapping" + #uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + uri_list = Validation::Validation.find(:validation_type => "bootstrapping").collect{|v| v.validation_uri}.join("\n") + "\n" if request.env['HTTP_ACCEPT'] =~ /text\/html/ related_links = @@ -388,7 +398,7 @@ post '/training_test_split' do params.merge!( Validation::Util.train_test_dataset_split(params[:dataset_uri], params[:prediction_feature], @subjectid, params[:split_ratio], params[:random_seed], OpenTox::SubTask.create(task,0,33))) - v = Validation::Validation.new :validation_type => "training_test_split", + v = Validation::Validation.create :validation_type => "training_test_split", :training_dataset_uri => params[:training_dataset_uri], :test_dataset_uri => params[:test_dataset_uri], :test_target_dataset_uri => params[:dataset_uri], @@ -406,8 +416,9 @@ get '/training_test_split' do LOGGER.info "list all training-test-split-validations, params: "+params.inspect #uri_list = Validation::Validation.find( :all, :conditions => { :validation_type => "training_test_split" } ).collect{ |v| v.validation_uri }.join("\n")+"\n" #uri_list = Validation::Validation.all( :validation_type => "training_test_split" ).collect{ |v| v.validation_uri }.join("\n")+"\n" - params[:validation_type] = "training_test_split" - uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + #params[:validation_type] = "training_test_split" + #uri_list = Lib::DataMapperUtil.all(Validation::Validation,params).collect{ |v| v.validation_uri }.join("\n")+"\n" + uri_list = Validation::Validation.find(:validation_type => "training_test_split").collect{|v| v.validation_uri}.join("\n") + "\n" if request.env['HTTP_ACCEPT'] =~ /text\/html/ related_links = @@ -440,7 +451,7 @@ post '/cleanup/?' do deleted << val.validation_uri #Validation::Validation.delete(val.id) val.subjectid = @subjectid - val.delete + val.delete_validation end LOGGER.info "validation cleanup, deleted "+deleted.size.to_s+" validations" deleted.join("\n")+"\n" @@ -463,7 +474,7 @@ post '/validate_datasets' do params[:validation_type] = "validate_datasets" if params[:model_uri] - v = Validation::Validation.new params + v = Validation::Validation.create params v.subjectid = @subjectid v.compute_validation_stats_with_model(nil,false,task) else @@ -475,7 +486,7 @@ post '/validate_datasets' do predicted_feature = params.delete("predicted_feature") feature_type = "classification" if params.delete("classification")!=nil feature_type = "regression" if params.delete("regression")!=nil - v = Validation::Validation.new params + v = Validation::Validation.create params v.subjectid = @subjectid v.compute_validation_stats(feature_type,predicted_feature,nil,nil,false,task) end @@ -532,7 +543,7 @@ get '/:id' do # rescue ActiveRecord::RecordNotFound => ex # raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." # end - validation = Validation::Validation.get(params[:id]) + validation = Validation::Validation[params[:id]] raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation case request.env['HTTP_ACCEPT'].to_s @@ -566,5 +577,5 @@ delete '/:id' do validation.subjectid = @subjectid raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation content_type "text/plain" - validation.delete + validation.delete_validation end \ No newline at end of file diff --git a/validation/validation_format.rb b/validation/validation_format.rb index f69ceac..6fdea61 100755 --- a/validation/validation_format.rb +++ b/validation/validation_format.rb @@ -4,15 +4,15 @@ require "lib/format_util.rb" module Validation # adding to_yaml and to_rdf functionality to validation - class Validation < Lib::Validation + class Validation # builds hash for valiation, as the internal presentation differs from the owl-object # the hash is directly printed in to_yaml, or added to the owl-structure def get_content_as_hash() h = {} - (Lib::VAL_PROPS - [:validation_uri]).each do |p| - h[p] = self.send(p) + (VAL_PROPS - [:validation_uri]).each do |p| + h[p] = self.send(p.to_s) end if crossvalidation_id!=nil cv = {:type => OT.CrossvalidationInfo} @@ -22,13 +22,14 @@ module Validation h[:crossvalidation_info] = cv end if classification_statistics - raise "classification_statistics is no has: "+classification_statistics.class.to_s unless classification_statistics.is_a?(Hash) + raise "classification_statistics is no hash: "+classification_statistics.class.to_s+" -> '"+ + classification_statistics.to_s+"'" unless classification_statistics.is_a?(Hash) clazz = { :type => OT.ClassificationStatistics } - Lib::VAL_CLASS_PROPS_SINGLE.each{ |p| clazz[p] = classification_statistics[p] } + VAL_CLASS_PROPS_SINGLE.each{ |p| clazz[p] = classification_statistics[p] } # transpose results per class class_values = {} - Lib::VAL_CLASS_PROPS_PER_CLASS.each do |p| + VAL_CLASS_PROPS_PER_CLASS.each do |p| raise "missing classification statitstics: "+p.to_s+" "+classification_statistics.inspect if classification_statistics[p]==nil classification_statistics[p].each do |class_value, property_value| class_values[class_value] = {:class_value => class_value, :type => OT.ClassValueStatistics} unless class_values.has_key?(class_value) @@ -54,7 +55,7 @@ module Validation h[:classification_statistics] = clazz elsif regression_statistics regr = {:type => OT.RegressionStatistics } - Lib::VAL_REGR_PROPS.each{ |p| regr[p] = regression_statistics[p]} + VAL_REGR_PROPS.each{ |p| regr[p] = regression_statistics[p]} h[:regression_statistics] = regr end return h @@ -72,17 +73,17 @@ module Validation end - class Crossvalidation < Lib::Crossvalidation + class Crossvalidation def get_content_as_hash h = {} - (Lib::CROSS_VAL_PROPS_REDUNDANT - [:crossvalidation_uri]).each do |p| + (CROSS_VAL_PROPS_REDUNDANT - [:crossvalidation_uri]).each do |p| h[p] = self.send(p) end v = [] #Validation.find( :all, :conditions => { :crossvalidation_id => self.id } ).each do |val| - Validation.all( :crossvalidation_id => self.id ).each do |val| + Validation.find( :crossvalidation_id => self.id ).each do |val| v.push( val.validation_uri.to_s ) end h[:validation_uris] = v diff --git a/validation/validation_service.rb b/validation/validation_service.rb index a1efba5..93c167f 100755 --- a/validation/validation_service.rb +++ b/validation/validation_service.rb @@ -30,7 +30,7 @@ end module Validation - class Validation < Lib::Validation + class Validation # constructs a validation object, Rsets id und uri #def initialize( params={} ) @@ -43,7 +43,7 @@ module Validation # deletes a validation # PENDING: model and referenced datasets are deleted as well, keep it that way? - def delete( delete_all=true ) + def delete_validation( delete_all=true ) if (delete_all) to_delete = [:model_uri, :training_dataset_uri, :test_dataset_uri, :test_target_dataset_uri, :prediction_dataset_uri ] case self.validation_type @@ -72,7 +72,7 @@ module Validation end end end - self.destroy + self.delete if (subjectid) begin res = OpenTox::Authorization.delete_policies_from_uri(validation_uri, subjectid) @@ -222,17 +222,13 @@ module Validation # :percent_unpredicted => prediction.percent_unpredicted, # :finished => true} # self.save! - self.attributes= {:num_instances => prediction.num_instances, + self.update :num_instances => prediction.num_instances, :num_without_class => prediction.num_without_class, :percent_without_class => prediction.percent_without_class, :num_unpredicted => prediction.num_unpredicted, :percent_unpredicted => prediction.percent_unpredicted, - :finished => true} - begin - self.save - rescue DataMapper::SaveFailureError => e - raise "could not save validation: "+e.resource.errors.inspect - end + :finished => true + raise unless self.valid? end task.progress(100) if task @@ -240,7 +236,7 @@ module Validation end end - class Crossvalidation < Lib::Crossvalidation + class Crossvalidation # constructs a crossvalidation, id and uri are set #def initialize( params={} ) @@ -262,12 +258,12 @@ module Validation end # deletes a crossvalidation, all validations are deleted as well - def delete - Validation.all(:crossvalidation_id => self.id).each do |v| + def delete_crossvalidation + Validation.find(:crossvalidation_id => self.id).each do |v| v.subjectid = self.subjectid - v.delete + v.delete_validation end - self.destroy + self.delete if (subjectid) begin res = OpenTox::Authorization.delete_policies_from_uri(crossvalidation_uri, subjectid) @@ -281,6 +277,9 @@ module Validation # creates the cv folds def create_cv_datasets( prediction_feature, task=nil ) + self.random_seed = 1 unless self.random_seed + self.num_folds = 10 unless self.num_folds + self.stratified = false unless self.stratified if copy_cv_datasets( prediction_feature ) # dataset folds of a previous crossvalidaiton could be used task.progress(100) if task @@ -296,7 +295,7 @@ module Validation i = 0 task_step = 100 / self.num_folds.to_f; @tmp_validations.each do | val | - validation = Validation.new val + validation = Validation.create val validation.subjectid = self.subjectid validation.validate_algorithm( algorithm_params, OpenTox::SubTask.create(task, i * task_step, ( i + 1 ) * task_step) ) @@ -316,8 +315,7 @@ module Validation # copies datasets from an older crossvalidation on the same dataset and the same folds # returns true if successfull, false otherwise def copy_cv_datasets( prediction_feature ) - - cvs = Crossvalidation.all( { + cvs = Crossvalidation.find( { :dataset_uri => self.dataset_uri, :num_folds => self.num_folds, :stratified => self.stratified, @@ -332,7 +330,7 @@ module Validation OpenTox::Dataset.exist?(v.training_dataset_uri,self.subjectid) and OpenTox::Dataset.exist?(v.test_dataset_uri,self.subjectid) #make sure self.id is set - self.save if self.new? + #self.save if self.new? tmp_val << { :validation_type => "crossvalidation", :training_dataset_uri => v.training_dataset_uri, :test_dataset_uri => v.test_dataset_uri, @@ -354,16 +352,14 @@ module Validation # creates cv folds (training and testdatasets) # stores uris in validation objects def create_new_cv_datasets( prediction_feature, task = nil ) - - raise "random seed not set "+self.inspect unless self.random_seed LOGGER.debug "creating datasets for crossvalidation" orig_dataset = OpenTox::Dataset.find(self.dataset_uri,self.subjectid) raise OpenTox::NotFoundError.new "Dataset not found: "+self.dataset_uri.to_s unless orig_dataset shuffled_compounds = orig_dataset.compounds.shuffle( self.random_seed ) - unless self.stratified - split_compounds = shuffled_compounds.chunk( self.num_folds ) + unless self.stratified + split_compounds = shuffled_compounds.chunk( self.num_folds.to_i ) else class_compounds = {} # "inactive" => compounds[], "active" => compounds[] .. shuffled_compounds.each do |c| @@ -406,7 +402,7 @@ module Validation @tmp_validations = [] - (1..self.num_folds).each do |n| + (1..self.num_folds.to_i).each do |n| datasetname = 'cv'+self.id.to_s + #'_d'+orig_dataset.name.to_s + @@ -418,7 +414,7 @@ module Validation test_compounds = [] train_compounds = [] - (1..self.num_folds).each do |nn| + (1..self.num_folds.to_i).each do |nn| compounds = split_compounds.at(nn-1) if n == nn @@ -428,7 +424,7 @@ module Validation end end - raise "internal error, num test compounds not correct" unless (shuffled_compounds.size/self.num_folds - test_compounds.size).abs <= 1 + raise "internal error, num test compounds not correct" unless (shuffled_compounds.size/self.num_folds.to_i - test_compounds.size).abs <= 1 raise "internal error, num train compounds not correct" unless shuffled_compounds.size - test_compounds.size == train_compounds.size LOGGER.debug "training set: "+datasetname+"_train, compounds: "+train_compounds.size.to_s @@ -442,7 +438,7 @@ module Validation { DC.title => datasetname + '_test', DC.creator => source }, self.subjectid ).uri #make sure self.id is set - self.save if self.new? + #self.save if self.new? tmp_validation = { :validation_type => "crossvalidation", :training_dataset_uri => train_dataset_uri, :test_dataset_uri => test_dataset_uri, @@ -551,9 +547,10 @@ module Validation # splits a dataset into test and training dataset # returns map with training_dataset_uri and test_dataset_uri def self.train_test_dataset_split( orig_dataset_uri, prediction_feature, subjectid, split_ratio=nil, random_seed=nil, task=nil ) - split_ratio=0.67 unless split_ratio + split_ratio = split_ratio.to_f random_seed=1 unless random_seed + random_seed = random_seed.to_i orig_dataset = OpenTox::Dataset.find orig_dataset_uri, subjectid orig_dataset.load_all subjectid diff --git a/validation/validation_test.rb b/validation/validation_test.rb index ffb25c4..efa8ad5 100755 --- a/validation/validation_test.rb +++ b/validation/validation_test.rb @@ -184,13 +184,13 @@ class ValidationTest < Test::Unit::TestCase #ambit_service = "https://ambit.uni-plovdiv.bg:8443/ambit2" #https%3A%2F%2Fambit.uni-plovdiv.bg%3A8443%2Fambit2 - + # post "/validate_datasets",{ -# :test_dataset_uri=>ambit_service+"/dataset/R401577?max=50", -# :prediction_dataset_uri=>ambit_service+"/dataset/R401577?max=50&feature_uris[]="+CGI.escape(ambit_service)+"%2Fmodel%2F35194%2Fpredicted", -# #:test_target_dataset_uri=>ambit_service+"/dataset/R401560", -# :prediction_feature=>ambit_service+"/feature/26221", -# :predicted_feature=>ambit_service+"/feature/218699", +# :test_dataset_uri=>"http://local-ot/dataset/94", +# :prediction_dataset_uri=>'http://local-ot/dataset/96', +# :test_target_dataset_uri=>'http://local-ot/dataset/92', +# :prediction_feature=>'http://local-ot/dataset/92/feature/Hamster%20Carcinogenicity', +# :predicted_feature=>"", # :classification=>"true", # :subjectid=>SUBJECTID} # #:model_uri=>"http://local-ot/model/31"} @@ -199,8 +199,8 @@ class ValidationTest < Test::Unit::TestCase # uri = last_response.body # val = wait_for_task(uri) # puts val -# #get "/"+val.split("/")[-1] - +# get "/"+val.split("/")[-1] +# puts last_response.body # d = OpenTox::Dataset.find("https://ambit.uni-plovdiv.bg:8443/ambit2/dataset/R545",SUBJECTID) # puts d.compounds.inspect @@ -257,7 +257,9 @@ class ValidationTest < Test::Unit::TestCase #delete "/1",:subjectid=>SUBJECTID - run_test("19i") + prepare_examples() + + #run_test("1a") #,{:validation_uri => "http://local-ot/validation/crossvalidation/1"}) #run_test("3a","http://local-ot/validation/crossvalidation/4") #run_test("3b","http://local-ot/validation/crossvalidation/3") -- cgit v1.2.3