diff options
author | mguetlein <martin.guetlein@gmail.com> | 2013-02-04 14:22:21 +0100 |
---|---|---|
committer | mguetlein <martin.guetlein@gmail.com> | 2013-02-04 14:22:21 +0100 |
commit | 3eaca7bfa04ad1dccc9127eea198bfc99d803eac (patch) | |
tree | 8d89905eb8b1ab41529523468b6b3856d1c44453 | |
parent | 46761d137dc470c6a4ab6b573bd99713a95103d2 (diff) |
a lot of adjustments to new arch
30 files changed, 1344 insertions, 1194 deletions
diff --git a/application.rb b/application.rb index 67771f9..02a1961 100755 --- a/application.rb +++ b/application.rb @@ -4,18 +4,8 @@ require 'rubygems' require lib end -class Sinatra::Base - helpers Sinatra::UrlForHelper -end - -#unless(defined? LOGGER) - #LOGGER = Logger.new(STDOUT) - #LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S " -#end - require "./test/test_application.rb" require "./report/report_application.rb" -#require "./reach_reports/reach_application.rb" require "./validation/validation_application.rb" diff --git a/bin/redirect.sh b/bin/redirect.sh deleted file mode 100755 index 0d34941..0000000 --- a/bin/redirect.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -OUTFILE="/tmp/tmp_redirect_out.txt" - -cmd="curl -v $1" -`$cmd &> $OUTFILE` - -ERR=`grep -a "< HTTP.*5[0-9][0-9]" $OUTFILE` -ERR=${ERR// /} # remove emtpy spaces - -if [ -z $ERR ]; then - ERR="no error" -else - echo "ERROR" 1>&2 - cmd="curl $1" - echo `$cmd 2> /dev/null` - exit 1 -fi - -RES=`grep -a "< HTTP.*30[0-9]" $OUTFILE` -RES=${RES// /} # remove emtpy spaces - -#echo $RES - -if [ -z $RES ]; then - exit 0 -else - #cat $OUTFILE - RES=`grep -a "< Location: " $OUTFILE` - RES=${RES//"< Location: "/} # remove lcoation spaces - echo $RES -fi - -#match301=$(expr index "$res" 301) -# -#echo -#echo "result:" -#echo -#cat $OUTFILE - -#echo $match301 - -#for testing try 301 instead of 303 with google.de/www.google.de
\ No newline at end of file @@ -1,5 +1,11 @@ SERVICE = "validation" + +require "rubygems" +require "ohm" + require 'bundler' Bundler.require + require './application.rb' -run run Sinatra::Application +run Validation::Application + diff --git a/data/hamster_carcinogenicity.csv b/data/hamster_carcinogenicity.csv index d314193..52d89a3 100644 --- a/data/hamster_carcinogenicity.csv +++ b/data/hamster_carcinogenicity.csv @@ -1,86 +1,86 @@ SMILES, Hamster Carcinogenicity
-CC=O,1
-C12C3=C(C=CC=C3)CC1=CC(=CC=2)NC(C)=O,1
-O=C(N)\C(C2=CC=CO2)=C/C1=CC=C([N+]([O-])=O)O1,1
-C1(N=CNN=1)N,0
-Br(=O)(=O)[O-].[K+],1
-[Cl-].[Cd+2].[Cl-],0
-O=S(=O)([O-])[O-].[Cd+2],0
-ClC1=CC(=NC(=N1)SCC(=O)O)NC2=CC=CC(=C2C)C,0
-ClCOC,1
-C=C(Cl)C=C,0
-Clc1ccc(cc1)c2ccc(COC(C)(C)C(O)=O)cc2,0
-O=C1OC2=C(C=CC=C2)C=C1,0
-ClC(=C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)Cl,1
-ClC(C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)(Cl)Cl,0
-C=CCN(CC=C)N=O,1
-Cl\C2=C(/Cl)C3(Cl)C1C4CC(C1C2(Cl)C3(Cl)Cl)C5OC45,0
-O=C(N(C)C)Cl,1
-CN(C)N,1
-N(NC)C.[H]Cl.[H]Cl,1
-CCO,0
-O=C(N(CC)N=O)NCCO,1
-O=C(N(CC)N=O)NCC(=O)C,1
-C=O,0
-[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NNC=O,1
-O=CC1=CC=CO1,0
-OCC1CO1,1
-O=C2C1=C(OC)C=C(OC)C(Cl)=C1O[C@]32C(OC)=CC(C[C@@](C)3[H])=O,0
-ClC1=C(C(=C(C(=C1Cl)Cl)Cl)Cl)Cl,1
-NN,1
-OS(=O)(=O)O.NN,1
-CC(=O)N(O)C1=CC2=C(C=C1)C3=CC=CC=C3C2,1
-OCCNN,0
-O=C(C1=CC=NC=C1)NN,0
-OC(=O)C1=CC=NC=C1,0
-O=C(NC1=CC=CC(=C1)Cl)OC(C)C,0
-O=C(NC1=CC=CC=C1)OC(C)C,0
-[O-]C(C)=O.[O-]C(C)=O.[Pb+2].[OH-].[OH-].[Pb+2].[OH-].[OH-].[Pb+2],0
-CN(C)CCN(CC2=CC=CS2)C1=NC=CC=C1.Cl,0
-NC1=C2C(=NC(=N1)N)N=CC(=N2)CN(C3=CC=C(C=C3)C(=O)N[C@@H](CCC(=O)O)C(=O)O)C,0
-CN(N)C=O,1
-O=C(C(=C)C)OC,0
-CNN,1
-O=C(C1=CC=CN=C1)CCCN(N=O)C,0
-CC1=CC(=O)NC(=S)N1,1
-CC(C(O)=O)(OC1=CC=C(C=C1)C2CCCC3=C2C=CC=C3)C,0
-O=N[O-].[Na+],0
-[O-][N+](C1=CC=C(C2=CSC(NC(C)=O)=N2)O1)=O,1
-[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NC=O,1
-O=[N+](C1=CC=C2C3=C1C=CC=C3CC2)[O-],0
-N(CC(CO)O)(CC(O)C)N=O,1
-N(CC(CO)O)(CC(C)=O)N=O,1
-N(CC(CO)O)(CCO)N=O,0
-O=C(C)CN(N=O)CCO,1
-C1C(N(C(CN1N=O)C)C)C,1
-N(CC(C)=O)(CC=C)N=O,1
-N(CC(CO)O)(C)N=O,1
-O=NN1CCOCC1,1
-N1C=CC=C(C=1)C2N(N=O)CCC2,1
-C1=CC=C(C=[N+]1[O-])C2CCCN2N=O,0
-O=NN1CCCCC1,1
-O=NN1CCCC1,1
-O=C(N(CC(C)=O)N=O)NCCCl,1
-N(C(=O)N)(N=O)CC(C)=O,1
-C1(CCN=C=S)=CC=CC=C1,0
-O=C1C(C2=CC=CC=C2)(C(=O)NC(=O)N1)CC,0
-C1=C2C(=CC=C1NC3=CC=CC=C3)C=CC=C2,0
-O=C1N2C(C3=C(C=CC=C3)CC2)CN(C1)C(=O)C4CCCCC4,0
-C1(=CC(=C(O)C=C1)O)C(O)=O,0
-O=C1C2=C(C=C(C=C2O)O)O/C(=C\1O)C3=CC(=C(C=C3)O)O.O.O,0
-C1=C(C=CC(=C1)C(C2=CC=C(N)C(=C2)C)=C3C=CC(=N)C=C3)N.[H]Cl,0
-C(C1=CC=C(C=C1)N)(C2=CC=C(C=C2)N)=C3C=CC(C=C3)=N.[H]Cl,0
-OC2=CC1=C(C(O)=C2)C(C(O[C@@H]4O[C@@H]([C@H]([C@H](O)[C@H]4O)O)CO[C@H]3[C@H](O)[C@H](O)[C@H]([C@H](C)O3)O)=C(C5=CC(O)=C(C=C5)O)O1)=O,0
-ClC(=CCl)Cl,0
-NC(=O)OCC,1
-C=CCl,1
-N#[N+]C1=CC=CC=C1.F[B-](F)(F)F,0
-C1(CN(CC(N1N=O)C)N=O)C,1
-N(CCN(C)C)(C)N=O,1
-C1(CN(N=O)CC(O1)C)C,1
-O1C(N(CC1C)N=O)=O,1
-CCOC(=O)N(C)N=O,1
-C1N(COC1)N=O,1
-O=C(N(CCC1=CC=CC=C1)N=O)N,1
-O=NN1CCC1,1
-F[B-](F)(F)F.[Na+],0
+CC=O,true
+C12C3=C(C=CC=C3)CC1=CC(=CC=2)NC(C)=O,true
+O=C(N)\C(C2=CC=CO2)=C/C1=CC=C([N+]([O-])=O)O1,true
+C1(N=CNN=1)N,false
+Br(=O)(=O)[O-].[K+],true
+[Cl-].[Cd+2].[Cl-],false
+O=S(=O)([O-])[O-].[Cd+2],false
+ClC1=CC(=NC(=N1)SCC(=O)O)NC2=CC=CC(=C2C)C,false
+ClCOC,true
+C=C(Cl)C=C,false
+Clc1ccc(cc1)c2ccc(COC(C)(C)C(O)=O)cc2,false
+O=C1OC2=C(C=CC=C2)C=C1,false
+ClC(=C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)Cl,true
+ClC(C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)(Cl)Cl,false
+C=CCN(CC=C)N=O,true
+Cl\C2=C(/Cl)C3(Cl)C1C4CC(C1C2(Cl)C3(Cl)Cl)C5OC45,false
+O=C(N(C)C)Cl,true
+CN(C)N,true
+N(NC)C.[H]Cl.[H]Cl,true
+CCO,false
+O=C(N(CC)N=O)NCCO,true
+O=C(N(CC)N=O)NCC(=O)C,true
+C=O,false
+[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NNC=O,true
+O=CC1=CC=CO1,false
+OCC1CO1,true
+O=C2C1=C(OC)C=C(OC)C(Cl)=C1O[C@]32C(OC)=CC(C[C@@](C)3[H])=O,false
+ClC1=C(C(=C(C(=C1Cl)Cl)Cl)Cl)Cl,true
+NN,true
+OS(=O)(=O)O.NN,true
+CC(=O)N(O)C1=CC2=C(C=C1)C3=CC=CC=C3C2,true
+OCCNN,false
+O=C(C1=CC=NC=C1)NN,false
+OC(=O)C1=CC=NC=C1,false
+O=C(NC1=CC=CC(=C1)Cl)OC(C)C,false
+O=C(NC1=CC=CC=C1)OC(C)C,false
+[O-]C(C)=O.[O-]C(C)=O.[Pb+2].[OH-].[OH-].[Pb+2].[OH-].[OH-].[Pb+2],false
+CN(C)CCN(CC2=CC=CS2)C1=NC=CC=C1.Cl,false
+NC1=C2C(=NC(=N1)N)N=CC(=N2)CN(C3=CC=C(C=C3)C(=O)N[C@@H](CCC(=O)O)C(=O)O)C,false
+CN(N)C=O,true
+O=C(C(=C)C)OC,false
+CNN,true
+O=C(C1=CC=CN=C1)CCCN(N=O)C,false
+CC1=CC(=O)NC(=S)N1,true
+CC(C(O)=O)(OC1=CC=C(C=C1)C2CCCC3=C2C=CC=C3)C,false
+O=N[O-].[Na+],false
+[O-][N+](C1=CC=C(C2=CSC(NC(C)=O)=N2)O1)=O,true
+[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NC=O,true
+O=[N+](C1=CC=C2C3=C1C=CC=C3CC2)[O-],false
+N(CC(CO)O)(CC(O)C)N=O,true
+N(CC(CO)O)(CC(C)=O)N=O,true
+N(CC(CO)O)(CCO)N=O,false
+O=C(C)CN(N=O)CCO,true
+C1C(N(C(CN1N=O)C)C)C,true
+N(CC(C)=O)(CC=C)N=O,true
+N(CC(CO)O)(C)N=O,true
+O=NN1CCOCC1,true
+N1C=CC=C(C=1)C2N(N=O)CCC2,true
+C1=CC=C(C=[N+]1[O-])C2CCCN2N=O,false
+O=NN1CCCCC1,true
+O=NN1CCCC1,true
+O=C(N(CC(C)=O)N=O)NCCCl,true
+N(C(=O)N)(N=O)CC(C)=O,true
+C1(CCN=C=S)=CC=CC=C1,false
+O=C1C(C2=CC=CC=C2)(C(=O)NC(=O)N1)CC,false
+C1=C2C(=CC=C1NC3=CC=CC=C3)C=CC=C2,false
+O=C1N2C(C3=C(C=CC=C3)CC2)CN(C1)C(=O)C4CCCCC4,false
+C1(=CC(=C(O)C=C1)O)C(O)=O,false
+O=C1C2=C(C=C(C=C2O)O)O/C(=C\1O)C3=CC(=C(C=C3)O)O.O.O,false
+C1=C(C=CC(=C1)C(C2=CC=C(N)C(=C2)C)=C3C=CC(=N)C=C3)N.[H]Cl,false
+C(C1=CC=C(C=C1)N)(C2=CC=C(C=C2)N)=C3C=CC(C=C3)=N.[H]Cl,false
+OC2=CC1=C(C(O)=C2)C(C(O[C@@H]4O[C@@H]([C@H]([C@H](O)[C@H]4O)O)CO[C@H]3[C@H](O)[C@H](O)[C@H]([C@H](C)O3)O)=C(C5=CC(O)=C(C=C5)O)O1)=O,false
+ClC(=CCl)Cl,false
+NC(=O)OCC,true
+C=CCl,true
+N#[N+]C1=CC=CC=C1.F[B-](F)(F)F,false
+C1(CN(CC(N1N=O)C)N=O)C,true
+N(CCN(C)C)(C)N=O,true
+C1(CN(N=O)CC(O1)C)C,true
+O1C(N(CC1C)N=O)=O,true
+CCOC(=O)N(C)N=O,true
+C1N(COC1)N=O,true
+O=C(N(CCC1=CC=CC=C1)N=O)N,true
+O=NN1CCC1,true
+F[B-](F)(F)F.[Na+],false
diff --git a/lib/format_util.rb b/lib/format_util.rb index 3d3a3e6..d7b737e 100644 --- a/lib/format_util.rb +++ b/lib/format_util.rb @@ -24,11 +24,11 @@ class String def to_owl_uri if DC_KEYS.include?(self) - return DC.send(self) + DC[self].to_s elsif RDF_KEYS.include?(self) - return RDF.send(self) + RDF[self].to_s else - return OT.send(self) + OT[self].to_s end end end diff --git a/lib/ohm_util.rb b/lib/ohm_util.rb index 856f9d2..6e7a1b1 100644 --- a/lib/ohm_util.rb +++ b/lib/ohm_util.rb @@ -28,6 +28,8 @@ module Lib end def self.find(model, filter_params) + filter_params.delete('splat') + filter_params.delete('captures') params = check_params(model,filter_params) if (params.size==0) model.all diff --git a/lib/ot_predictions.rb b/lib/ot_predictions.rb index 8ddf364..357adeb 100755 --- a/lib/ot_predictions.rb +++ b/lib/ot_predictions.rb @@ -87,7 +87,7 @@ module Lib end if conf_column!=nil - LOGGER.debug "sort via confidence: "+res.collect{|n| n[conf_column]}.inspect + $logger.debug "sort via confidence: "+res.collect{|n| n[conf_column]}.inspect res = res.sort_by{ |n| n[conf_column] || 0 }.reverse if format res.each do |a| diff --git a/lib/prediction_data.rb b/lib/prediction_data.rb index f42cd9f..37d0d5a 100644 --- a/lib/prediction_data.rb +++ b/lib/prediction_data.rb @@ -4,7 +4,7 @@ module Lib class PredictionData - CHECK_VALUES = ENV['RACK_ENV'] =~ /debug|test/ + CHECK_VALUES = true #ENV['RACK_ENV'] =~ /debug|test/ def self.filter_data( data, compounds, min_confidence, min_num_predictions, max_num_predictions, prediction_index=nil ) @@ -15,9 +15,9 @@ module Lib (min_confidence==nil and min_num_predictions!=nil) min_num_predictions = 0 if min_num_predictions==nil - LOGGER.debug("filtering predictions, conf:'"+min_confidence.to_s+"' min_num_predictions: '"+ + $logger.debug("filtering predictions, conf:'"+min_confidence.to_s+"' min_num_predictions: '"+ min_num_predictions.to_s+"' max_num_predictions: '"+max_num_predictions.to_s+"' ") - #LOGGER.debug("to filter:\nconf: "+data[:confidence_values].inspect) + #$logger.debug("to filter:\nconf: "+data[:confidence_values].inspect) orig_size = data[:predicted_values].size valid_indices = [] @@ -41,7 +41,7 @@ module Lib new_compounds = [] valid_indices.each{|i| new_compounds << compounds[i]} end - LOGGER.debug("filtered predictions remaining: "+data[:predicted_values].size.to_s+"/"+orig_size.to_s) + $logger.debug("filtered predictions remaining: "+data[:predicted_values].size.to_s+"/"+orig_size.to_s) PredictionData.new(data, new_compounds) end @@ -61,11 +61,11 @@ module Lib prediction_dataset_uris = [prediction_dataset_uris] unless prediction_dataset_uris.is_a?(Array) predicted_variables = [predicted_variables] unless predicted_variables.is_a?(Array) predicted_confidences = [predicted_confidences] unless predicted_confidences.is_a?(Array) - LOGGER.debug "loading prediction -- test-dataset: "+test_dataset_uris.inspect - LOGGER.debug "loading prediction -- prediction-dataset: "+prediction_dataset_uris.inspect - LOGGER.debug "loading prediction -- predicted_variable: "+predicted_variables.inspect - LOGGER.debug "loading prediction -- predicted_confidence: "+predicted_confidences.inspect - LOGGER.debug "loading prediction -- prediction_feature: "+prediction_feature.to_s + $logger.debug "loading prediction -- test-dataset: "+test_dataset_uris.inspect + $logger.debug "loading prediction -- prediction-dataset: "+prediction_dataset_uris.inspect + $logger.debug "loading prediction -- predicted_variable: "+predicted_variables.inspect + $logger.debug "loading prediction -- predicted_confidence: "+predicted_confidences.inspect + $logger.debug "loading prediction -- prediction_feature: "+prediction_feature.to_s raise "prediction_feature missing" unless prediction_feature all_compounds = [] @@ -93,14 +93,14 @@ module Lib raise "prediction_feature not found in test_dataset\n"+ "prediction_feature: '"+prediction_feature.to_s+"'\n"+ - "test_dataset: '"+test_dataset_uri.to_s+"'\n"+ - "available features are: "+test_dataset.features.inspect if test_dataset.features.keys.index(prediction_feature)==nil + "test_dataset: '"+test_dataset_uri.to_s+"'\n"+ + "available features are: "+test_dataset.features.inspect if test_dataset.find_feature(prediction_feature)==nil - LOGGER.debug "test dataset size: "+test_dataset.compounds.size.to_s + $logger.debug "test dataset size: "+test_dataset.compounds.size.to_s raise "test dataset is empty "+test_dataset_uri.to_s unless test_dataset.compounds.size>0 if feature_type=="classification" - av = test_dataset.accept_values(prediction_feature) + av = OpenTox::Feature.find(prediction_feature).accept_values raise "'"+OT.acceptValue.to_s+"' missing/invalid for feature '"+prediction_feature.to_s+"' in dataset '"+ test_dataset_uri.to_s+"', acceptValues are: '"+av.inspect+"'" if av==nil or av.length<2 if accept_values==nil @@ -129,19 +129,20 @@ module Lib raise "predicted_variable not found in prediction_dataset\n"+ "predicted_variable '"+predicted_variable.to_s+"'\n"+ "prediction_dataset: '"+prediction_dataset_uri.to_s+"'\n"+ - "available features are: "+prediction_dataset.features.inspect if prediction_dataset.features.keys.index(predicted_variable)==nil and prediction_dataset.compounds.size>0 + "available features are: "+prediction_dataset.features.inspect if prediction_dataset.find_feature(predicted_variable)==nil and prediction_dataset.compounds.size>0 raise "predicted_confidence not found in prediction_dataset\n"+ "predicted_confidence '"+predicted_confidence.to_s+"'\n"+ "prediction_dataset: '"+prediction_dataset_uri.to_s+"'\n"+ - "available features are: "+prediction_dataset.features.inspect if predicted_confidence and prediction_dataset.features.keys.index(predicted_confidence)==nil and prediction_dataset.compounds.size>0 + "available features are: "+prediction_dataset.features.inspect if predicted_confidence and prediction_dataset.find_feature(predicted_confidence)==nil and prediction_dataset.compounds.size>0 - raise "more predicted than test compounds, #test: "+test_dataset.compounds.size.to_s+" < #prediction: "+ - prediction_dataset.compounds.size.to_s+", test-dataset: "+test_dataset_uri.to_s+", prediction-dataset: "+ - prediction_dataset_uri if test_dataset.compounds.size < prediction_dataset.compounds.size + #raise "more predicted than test compounds, #test: "+test_dataset.compounds.size.to_s+" < #prediction: "+ + # prediction_dataset.compounds.size.to_s+", test-dataset: "+test_dataset_uri.to_s+", prediction-dataset: "+ + # prediction_dataset_uri if test_dataset.compounds.size < prediction_dataset.compounds.size if CHECK_VALUES - prediction_dataset.compounds.each do |c| + prediction_dataset.compounds.size.times do |c_idx| + c = prediction_dataset.compounds[c_idx] raise "predicted compound not found in test dataset:\n"+c+"\ntest-compounds:\n"+ - test_dataset.compounds.collect{|c| c.to_s}.join("\n") unless test_dataset.compounds.include?(c) + test_dataset.compounds.collect{|c| c.to_s}.join("\n") if prediction_dataset.data_entry_value(c_idx,predicted_variable)!=nil and test_dataset.compounds.include?(c) end end @@ -149,14 +150,14 @@ module Lib confidence_values = [] test_dataset.compounds.size.times do |test_c_idx| - c = test_dataset.compounds[test_c_idx] + c = test_dataset.compounds[test_c_idx].uri pred_c_idx = prediction_dataset.compound_index(test_dataset,test_c_idx) if pred_c_idx==nil - raise "internal error: mapping failed" if prediction_dataset.compounds.include?(c) + raise "internal error: mapping failed" if prediction_dataset.compounds.collect{|c| c.uri}.include?(c) predicted_values << nil confidence_values << nil else - raise "internal error: mapping failed" unless c==prediction_dataset.compounds[pred_c_idx] + raise "internal error: mapping failed" unless c==prediction_dataset.compounds[pred_c_idx].uri case feature_type when "classification" predicted_values << classification_val(prediction_dataset, pred_c_idx, predicted_variable, accept_values) @@ -170,7 +171,7 @@ module Lib end end end - all_compounds += test_dataset.compounds + all_compounds += test_dataset.compounds.collect{|c| c.uri} all_predicted_values += predicted_values all_actual_values += actual_values all_confidence_values += confidence_values @@ -219,7 +220,7 @@ module Lib v = v.to_f unless v==nil or v.is_a?(Numeric) v rescue - LOGGER.warn "no numeric value for feature '#{feature}' : '#{v}'" + $logger.warn "no numeric value for feature '#{feature}' : '#{v}'" nil end end diff --git a/lib/predictions.rb b/lib/predictions.rb index 9f62d31..ba397da 100755 --- a/lib/predictions.rb +++ b/lib/predictions.rb @@ -293,7 +293,7 @@ module Lib class_index==nil return 0 unless confidence_values_available? - LOGGER.warn("TODO: implement approx computiation of AUC,"+ + $logger.warn("TODO: implement approx computiation of AUC,"+ "so far Wilcoxon-Man-Whitney is used (exponential)") if @predicted_values.size>1000 #puts "COMPUTING AUC "+class_index.to_s diff --git a/lib/test_util.rb b/lib/test_util.rb index 590d295..2d3b084 100755 --- a/lib/test_util.rb +++ b/lib/test_util.rb @@ -1,5 +1,26 @@ require 'test/unit' +require 'validation_util.rb' + +class String + def task_uri? + self.uri? && !self.match(/task/).nil? + end + + def validation_uri? + self.uri? && !self.match(/validation/).nil? + end + + def uri? + begin + u = URI::parse(self) + return (u.scheme!=nil and u.host!=nil) + rescue URI::InvalidURIError + return false + end + end + +end module Lib # test utitily, to be included rack unit tests @@ -14,7 +35,7 @@ module Lib task = OpenTox::Task.find(uri) task.wait_for_completion #raise "task failed: "+uri.to_s+", error is:\n"+task.description if task.error? - LOGGER.error "task failed :\n"+task.to_yaml if task.error? + $logger.error "task failed :\n"+task.to_yaml if task.error? uri = task.result_uri end return uri diff --git a/lib/validation_db.rb b/lib/validation_db.rb index e486a62..d2f8162 100755 --- a/lib/validation_db.rb +++ b/lib/validation_db.rb @@ -4,6 +4,9 @@ #end require "./lib/merge.rb" +Ohm.connect(:thread_safe => true, :port => 6379) + + module Validation VAL_PROPS_GENERAL = [ :validation_uri, :validation_type, :model_uri, :algorithm_uri, :algorithm_params, @@ -87,6 +90,7 @@ module Validation attr_accessor :subjectid def self.create(params={}) + Ohm.connect(:thread_safe => true, :port => 6379) params[:date] = Time.new super params end @@ -123,11 +127,11 @@ module Validation public def validation_uri raise "no id" if self.id==nil - $url_provider.url_for("/"+self.id.to_s, :full) + $url_provider.url_for("/validation/"+self.id.to_s, :full) end def crossvalidation_uri - $url_provider.url_for("/crossvalidation/"+self.crossvalidation_id.to_s, :full) if self.crossvalidation_id + $url_provider.url_for("/validation/crossvalidation/"+self.crossvalidation_id.to_s, :full) if self.crossvalidation_id end def self.classification_property?( property ) @@ -182,7 +186,7 @@ module Validation public def crossvalidation_uri raise "no id" if self.id==nil - $url_provider.url_for("/crossvalidation/"+self.id.to_s, :full) if self.id + $url_provider.url_for("/validation/crossvalidation/"+self.id.to_s, :full) if self.id end # convenience method to list all crossvalidations that are unique @@ -193,7 +197,7 @@ module Validation cvs = Crossvalidation.find( conditions ) uniq = [] cvs.each do |cv| - next if AA_SERVER and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",subjectid) + next if $aa[:uri] and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",subjectid) match = false uniq.each do |cv2| if cv.dataset_uri == cv2.dataset_uri and cv.num_folds == cv2.num_folds and diff --git a/report/plot_factory.rb b/report/plot_factory.rb index 6c90594..ddf111a 100644 --- a/report/plot_factory.rb +++ b/report/plot_factory.rb @@ -59,7 +59,7 @@ module Reports def self.create_regression_plot( out_files, validation_set, name_attribute, logscale=true ) out_files = [out_files] unless out_files.is_a?(Array) - LOGGER.debug "Creating regression plot, out-file:"+out_files.to_s + $logger.debug "Creating regression plot, out-file:"+out_files.to_s omit_count = 0 names = [] @@ -141,7 +141,7 @@ module Reports x_label="False positive rate", y_label="True Positive Rate" ) out_files = [out_files] unless out_files.is_a?(Array) - LOGGER.debug "creating roc plot for '"+validation_set.size.to_s+"' validations, out-files:"+out_files.inspect + $logger.debug "creating roc plot for '"+validation_set.size.to_s+"' validations, out-files:"+out_files.inspect data = [] if split_set_attribute @@ -151,7 +151,7 @@ module Reports data << transform_roc_predictions(validation_set.filter({split_set_attribute => value}), class_value, false ) data[-1].name = split_set_attribute.to_s.nice_attr+" "+value.to_s rescue - LOGGER.warn "could not create ROC plot for "+value.to_s + $logger.warn "could not create ROC plot for "+value.to_s end end else @@ -189,7 +189,7 @@ module Reports def self.create_confidence_plot( out_files, validation_set, performance_attribute, performance_accept_value, split_set_attribute=nil, show_single_curves=false ) out_files = [out_files] unless out_files.is_a?(Array) - LOGGER.debug "creating confidence plot for '"+validation_set.size.to_s+"' validations, out-file:"+out_files.inspect + $logger.debug "creating confidence plot for '"+validation_set.size.to_s+"' validations, out-file:"+out_files.inspect if split_set_attribute attribute_values = validation_set.get_values(split_set_attribute) @@ -203,7 +203,7 @@ module Reports confidence << data[:confidence][0] performance << data[:performance][0] rescue - LOGGER.warn "could not create confidence plot for "+value.to_s + $logger.warn "could not create confidence plot for "+value.to_s end end out_files.each do |out_file| @@ -224,7 +224,7 @@ module Reports def self.create_box_plot( out_files, validation_set, title_attribute, value_attribute, class_value ) out_files = [out_files] unless out_files.is_a?(Array) - LOGGER.debug "creating box plot, out-files:"+out_files.inspect + $logger.debug "creating box plot, out-files:"+out_files.inspect data = {} validation_set.validations.each do |v| @@ -251,7 +251,7 @@ module Reports def self.create_bar_plot( out_files, validation_set, title_attribute, value_attributes ) out_files = [out_files] unless out_files.is_a?(Array) - LOGGER.debug "creating bar plot, out-files:"+out_files.inspect + $logger.debug "creating bar plot, out-files:"+out_files.inspect data = [] titles = [] @@ -297,8 +297,8 @@ module Reports data[i] = [titles[i]] + data[i] end - LOGGER.debug "bar plot labels: "+labels.inspect - LOGGER.debug "bar plot data: "+data.inspect + $logger.debug "bar plot labels: "+labels.inspect + $logger.debug "bar plot data: "+data.inspect out_files.each do |out_file| RubyPlot::plot_bars('Bar plot', labels, data, out_file) @@ -343,7 +343,7 @@ module Reports cmd = "java -jar "+ENV['RANK_PLOTTER_JAR']+" "+tit+" -c '"+ comparables_array.join(",")+"' -r '"+ranks_array.join(",")+"' "+conf+" "+show #+" > /home/martin/tmp/test.svg" #puts "\nplotting: "+cmd - LOGGER.debug "Plotting ranks: "+cmd.to_s + $logger.debug "Plotting ranks: "+cmd.to_s res = "" IO.popen(cmd) do |f| @@ -411,7 +411,7 @@ module Reports confidence << perf_conf_rates[:confidence] faint << true rescue - LOGGER.warn "could not get confidence vals for fold "+i.to_s + $logger.warn "could not get confidence vals for fold "+i.to_s end end end diff --git a/report/report_application.rb b/report/report_application.rb index f7528b6..fae1366 100755 --- a/report/report_application.rb +++ b/report/report_application.rb @@ -1,151 +1,154 @@ require "./report/environment.rb" -def perform - @@report_service = Reports::ReportService.instance( url_for("/report", :full) ) unless defined?@@report_service - yield( @@report_service ) -end +class Validation::Application < OpenTox::Service -def get_docbook_resource(filepath) - perform do |rs| - raise OpenTox::NotFoundError.new"not found: "+filepath unless File.exist?(filepath) - types = MIME::Types.type_for(filepath) - content_type(types[0].content_type) if types and types.size>0 and types[0] - result = body(File.new(filepath)) + def perform + @@report_service = Reports::ReportService.instance( url_for("/validation/report", :full) ) unless defined?@@report_service + yield( @@report_service ) end -end - -get '/'+ENV['DOCBOOK_DIRECTORY']+'/:subdir/:resource' do - path_array = request.env['REQUEST_URI'].split("/") - get_docbook_resource ENV['DOCBOOK_DIRECTORY']+"/"+path_array[-2]+"/"+path_array[-1] -end - -get '/'+ENV['DOCBOOK_DIRECTORY']+'/:resource' do - get_docbook_resource ENV['DOCBOOK_DIRECTORY']+"/"+request.env['REQUEST_URI'].split("/")[-1] -end - -get '/resources/:resource' do - get_docbook_resource "resources/"+request.env['REQUEST_URI'].split("/")[-1] -end - -get '/report/:type/css_style_sheet/?' do - perform do |rs| - "@import \""+params[:css_style_sheet]+"\";" + + def get_docbook_resource(filepath) + perform do |rs| + raise OpenTox::NotFoundError.new"not found: "+filepath unless File.exist?(filepath) + types = MIME::Types.type_for(filepath) + content_type(types[0].content_type) if types and types.size>0 and types[0] + result = body(File.new(filepath)) + end end -end - -get '/report/?' do - perform do |rs| - case request.env['HTTP_ACCEPT'].to_s - when /text\/html/ - related_links = - "All validations: "+url_for("/",:full) - description = - "A list of all report types." - content_type "text/html" - OpenTox.text_to_html rs.get_report_types,@subjectid,related_links,description - else - content_type "text/uri-list" - rs.get_report_types + + get '/validation/'+ENV['DOCBOOK_DIRECTORY']+'/:subdir/:resource' do + path_array = request.env['REQUEST_URI'].split("/") + get_docbook_resource ENV['DOCBOOK_DIRECTORY']+"/"+path_array[-2]+"/"+path_array[-1] + end + + get '/validation/'+ENV['DOCBOOK_DIRECTORY']+'/:resource' do + get_docbook_resource ENV['DOCBOOK_DIRECTORY']+"/"+request.env['REQUEST_URI'].split("/")[-1] + end + + get '/validation/resources/:resource' do + get_docbook_resource "resources/"+request.env['REQUEST_URI'].split("/")[-1] + end + + get '/validation/report/:type/css_style_sheet/?' do + perform do |rs| + "@import \""+params[:css_style_sheet]+"\";" end end -end - -def wrap(s, width=78) - s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n") -end - -get '/report/:report_type' do - perform do |rs| - case request.env['HTTP_ACCEPT'].to_s - when /text\/html/ - related_links = - "Available report types: "+url_for("/report",:full)+"\n"+ - "Single validations: "+url_for("/",:full)+"\n"+ - "Crossvalidations: "+url_for("/crossvalidation",:full) - description = - "A list of all "+params[:report_type]+" reports. To create a report, use the POST method." - if params[:report_type]=="algorithm_comparison" - description += "\n\nThis report can be used to compare the validation results of different algorithms that have been validated on the same dataset." - description += "\nThe following attributes can be compared with the t-test:" - description += "\n\n* All validation types:\n"+wrap((Validation::VAL_PROPS_SUM+Validation::VAL_PROPS_AVG).join(", "),120) - description += "\n* Classification validations:\n"+wrap(Validation::VAL_CLASS_PROPS.join(", "),120) - description += "\n* Regresssion validations:\n"+wrap(Validation::VAL_REGR_PROPS.join(", "),120) - end - - post_params = [[:validation_uris]] - post_command = OpenTox::PostCommand.new request.url,"Create validation report" - val_uri_description = params[:report_type]=="algorithm_comparison" ? "Separate multiple uris with ','" : nil - # trick for easy report creation - # if searching for a report, ?validation="uri" or ?crossvalidaiton="uri" is given as search param - # use this (search param has equal name as report type) as default value for validation_uri - post_command.attributes << OpenTox::PostAttribute.new("validation_uris",true,params[params[:report_type]],val_uri_description) - if params[:report_type]=="algorithm_comparison" - post_command.attributes << OpenTox::PostAttribute.new("identifier",true,nil,"Specifiy one identifier for each uri, separated with ','") - post_command.attributes << OpenTox::PostAttribute.new("ttest_significance",false,"0.9","Significance level for t-tests (Set to '0' to disable t-test).") - post_command.attributes << OpenTox::PostAttribute.new("ttest_attributes",false,nil,"Attributes for t-test; default for classification: '"+ - VAL_ATTR_TTEST_CLASS.join(",")+"', default for regression: '"+VAL_ATTR_TTEST_REGR.join(",")+"'") + + get '/validation/report/?' do + perform do |rs| + case request.env['HTTP_ACCEPT'].to_s + when /text\/html/ + related_links = + "All validations: "+url_for("/validation/",:full) + description = + "A list of all report types." + content_type "text/html" + OpenTox.text_to_html rs.get_report_types,@subjectid,related_links,description + else + content_type "text/uri-list" + rs.get_report_types end - content_type "text/html" - OpenTox.text_to_html rs.get_all_reports(params[:report_type], params),@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - rs.get_all_reports(params[:report_type], params) end end -end - -post '/report/:type/:id/format_html' do - perform do |rs| - rs.get_report(params[:type],params[:id],"text/html",true,params) - content_type "text/uri-list" - rs.get_uri(params[:type],params[:id])+"\n" + + def wrap(s, width=78) + s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n") end -end - - -get '/report/:type/:id' do - perform do |rs| - - accept_header = request.env['HTTP_ACCEPT'] - report = rs.get_report(params[:type],params[:id],accept_header) - format = Reports::ReportFormat.get_format(accept_header) - content_type format - # default encoding is utf-8, html conversion produces iso-8859-1 encoding - content_type "text/html", 'charset' => 'ISO-8859-1' if format=="text/html" - #PENDING: get_report should return file or string, check for result.is_file instead of format - if format=="application/x-yaml" or format=="application/rdf+xml" - report - else - result = body(File.new(report)) + + get '/validation/report/:report_type' do + perform do |rs| + case request.env['HTTP_ACCEPT'].to_s + when /text\/html/ + related_links = + "Available report types: "+url_for("/validation/report",:full)+"\n"+ + "Single validations: "+url_for("/validation/",:full)+"\n"+ + "Crossvalidations: "+url_for("/validation/crossvalidation",:full) + description = + "A list of all "+params[:report_type]+" reports. To create a report, use the POST method." + if params[:report_type]=="algorithm_comparison" + description += "\n\nThis report can be used to compare the validation results of different algorithms that have been validated on the same dataset." + description += "\nThe following attributes can be compared with the t-test:" + description += "\n\n* All validation types:\n"+wrap((Validation::VAL_PROPS_SUM+Validation::VAL_PROPS_AVG).join(", "),120) + description += "\n* Classification validations:\n"+wrap(Validation::VAL_CLASS_PROPS.join(", "),120) + description += "\n* Regresssion validations:\n"+wrap(Validation::VAL_REGR_PROPS.join(", "),120) + end + + post_params = [[:validation_uris]] + #post_command = OpenTox::PostCommand.new request.url,"Create validation report" + #val_uri_description = params[:report_type]=="algorithm_comparison" ? "Separate multiple uris with ','" : nil + # trick for easy report creation + # if searching for a report, ?validation="uri" or ?crossvalidaiton="uri" is given as search param + # use this (search param has equal name as report type) as default value for validation_uri + # post_command.attributes << OpenTox::PostAttribute.new("validation_uris",true,params[params[:report_type]],val_uri_description) + # if params[:report_type]=="algorithm_comparison" + # post_command.attributes << OpenTox::PostAttribute.new("identifier",true,nil,"Specifiy one identifier for each uri, separated with ','") + # post_command.attributes << OpenTox::PostAttribute.new("ttest_significance",false,"0.9","Significance level for t-tests (Set to '0' to disable t-test).") + # post_command.attributes << OpenTox::PostAttribute.new("ttest_attributes",false,nil,"Attributes for t-test; default for classification: '"+ + # VAL_ATTR_TTEST_CLASS.join(",")+"', default for regression: '"+VAL_ATTR_TTEST_REGR.join(",")+"'") + # end + content_type "text/html" + OpenTox.text_to_html rs.get_all_reports(params[:report_type], params),@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + rs.get_all_reports(params[:report_type], params) + end end end -end - -#OpenTox::Authorization.whitelist( Regexp.new("/report/.*/[0-9]+/.*"),"GET") - -get '/report/:type/:id/:resource' do - perform do |rs| - filepath = rs.get_report_resource(params[:type],params[:id],params[:resource]) - types = MIME::Types.type_for(filepath) - content_type(types[0].content_type) if types and types.size>0 and types[0] - result = body(File.new(filepath)) + + post '/validation/report/:type/:id/format_html' do + perform do |rs| + rs.get_report(params[:type],params[:id],"text/html",true,params) + content_type "text/uri-list" + rs.get_uri(params[:type],params[:id])+"\n" + end end -end - -delete '/report/:type/:id' do - perform do |rs| - content_type "text/plain" - rs.delete_report(params[:type],params[:id],@subjectid) + + + get '/validation/report/:type/:id' do + perform do |rs| + + accept_header = request.env['HTTP_ACCEPT'] + report = rs.get_report(params[:type],params[:id],accept_header) + format = Reports::ReportFormat.get_format(accept_header) + content_type format + # default encoding is utf-8, html conversion produces iso-8859-1 encoding + content_type "text/html", 'charset' => 'ISO-8859-1' if format=="text/html" + #PENDING: get_report should return file or string, check for result.is_file instead of format + if format=="application/x-yaml" or format=="application/rdf+xml" + report + else + result = body(File.new(report)) + end + end end -end - -post '/report/:type' do - raise OpenTox::BadRequestError.new "validation_uris missing" unless params[:validation_uris].to_s.size>0 - task = OpenTox::Task.create("Create report",url_for("/report/"+params[:type], :full)) do |task| #,params + + #OpenTox::Authorization.whitelist( Regexp.new("/report/.*/[0-9]+/.*"),"GET") + + get '/validation/report/:type/:id/:resource' do perform do |rs| - rs.create_report(params[:type],params[:validation_uris]?params[:validation_uris].split(/\n|,/):nil, - params[:identifier]?params[:identifier].split(/\n|,/):nil,params,@subjectid,task) + filepath = rs.get_report_resource(params[:type],params[:id],params[:resource]) + types = MIME::Types.type_for(filepath) + content_type(types[0].content_type) if types and types.size>0 and types[0] + result = body(File.new(filepath)) + end + end + + delete '/validation/report/:type/:id' do + perform do |rs| + content_type "text/plain" + rs.delete_report(params[:type],params[:id],@subjectid) + end + end + + post '/validation/report/:type' do + raise OpenTox::BadRequestError.new "validation_uris missing" unless params[:validation_uris].to_s.size>0 + task = OpenTox::Task.run("Create report",url_for("/validation/report/"+params[:type], :full)) do |task| #,params + perform do |rs| + rs.create_report(params[:type],params[:validation_uris]?params[:validation_uris].split(/\n|,/):nil, + params[:identifier]?params[:identifier].split(/\n|,/):nil,params,@subjectid,task) + end end + return_task(task) end - return_task(task) end diff --git a/report/report_content.rb b/report/report_content.rb index 033b367..4130186 100755 --- a/report/report_content.rb +++ b/report/report_content.rb @@ -167,7 +167,7 @@ class Reports::ReportContent image_title_2 += " ("+omit_count.to_s+" datapoints omitted)" if omit_count>0 @xml_report.add_imagefigure(section_regr, image_title_2, plot_png[:name], "PNG", 100, plot_svg[:name]) rescue Exception => ex - LOGGER.error("Could not create regression plot: "+ex.message) + $logger.error("Could not create regression plot: "+ex.message) rm_tmp_file(plot_png[:name]) rm_tmp_file(plot_svg[:name]) @xml_report.add_paragraph(section_regr, "could not create regression plot: "+ex.message) @@ -204,7 +204,7 @@ class Reports::ReportContent end @xml_report.add_imagefigure(section_plot, image_title, plot_png[:name], "PNG", 100, plot_svg[:name]) rescue Exception => ex - LOGGER.error("Could not create train test plot: "+ex.message) + $logger.error("Could not create train test plot: "+ex.message) rm_tmp_file(plot_png[:name]) if plot_png rm_tmp_file(plot_svg[:name]) if plot_svg @xml_report.add_paragraph(section_plot, "could not create train test plot: "+ex.message) @@ -226,7 +226,7 @@ class Reports::ReportContent if prediction_set.size>0 if prediction_set.size!=validation_set.size section_text += "\nWARNING: roc plot information not available for all validation results" - LOGGER.error "WARNING: roc plot information not available for all validation results:\n"+ + $logger.error "WARNING: roc plot information not available for all validation results:\n"+ "validation set size: "+validation_set.size.to_s+", prediction set size: "+prediction_set.size.to_s end @xml_report.add_paragraph(section_roc, section_text) if section_text @@ -237,7 +237,7 @@ class Reports::ReportContent @xml_report.add_imagefigure(section_roc, image_title, plot_png[:name], "PNG", 100, plot_svg[:name]) rescue Exception => ex msg = "WARNING could not create roc plot for class value '"+accept_value.to_s+"': "+ex.message - LOGGER.error(msg) + $logger.error(msg) rm_tmp_file(plot_png[:name]) rm_tmp_file(plot_svg[:name]) @xml_report.add_paragraph(section_roc, msg) @@ -262,7 +262,7 @@ class Reports::ReportContent if prediction_set.size>0 if prediction_set.size!=validation_set.size section_text += "\nWARNING: plot information not available for all validation results" - LOGGER.error "WARNING: plot information not available for all validation results:\n"+ + $logger.error "WARNING: plot information not available for all validation results:\n"+ "validation set size: "+validation_set.size.to_s+", prediction set size: "+prediction_set.size.to_s end @xml_report.add_paragraph(section_conf, section_text) if section_text and section_text.size>0 @@ -275,7 +275,7 @@ class Reports::ReportContent @xml_report.add_imagefigure(section_conf, image_title, plot_png[:name], "PNG", 100, plot_svg[:name]) rescue Exception => ex msg = "WARNING could not create confidence plot: "+ex.message - LOGGER.error(msg) + $logger.error(msg) rm_tmp_file(plot_png[:name]) rm_tmp_file(plot_svg[:name]) @xml_report.add_paragraph(section_conf, msg) @@ -390,7 +390,7 @@ class Reports::ReportContent end rescue Exception => ex msg = "WARNING could not create box plot: "+ex.message - LOGGER.error(msg) + $logger.error(msg) rm_tmp_file(plot_png[:name]) if plot_png rm_tmp_file(plot_svg[:name]) if plot_svg @xml_report.add_paragraph(section_box, msg) diff --git a/report/report_factory.rb b/report/report_factory.rb index f73ffd9..7540db3 100755 --- a/report/report_factory.rb +++ b/report/report_factory.rb @@ -229,7 +229,7 @@ module Reports::ReportFactory # groups results into sets with equal dataset if (validation_set.num_different_values(:dataset_uri)>1) - LOGGER.debug "compare report -- num different datasets: "+validation_set.num_different_values(:dataset_uri).to_s + $logger.debug "compare report -- num different datasets: "+validation_set.num_different_values(:dataset_uri).to_s dataset_grouping = Reports::Util.group(validation_set.validations, [:dataset_uri]) # check if equal values in each group exist Reports::Util.check_group_matching(dataset_grouping, [:crossvalidation_fold, :num_folds, :stratified, :random_seed]) diff --git a/report/report_format.rb b/report/report_format.rb index d216782..ab745e8 100644 --- a/report/report_format.rb +++ b/report/report_format.rb @@ -70,11 +70,11 @@ module Reports::ReportFormat #cmd = "java -jar "+ENV['SAXON_JAR']+" -o:" + File.join(directory,html_filename.to_s)+ # " -s:"+File.join(directory,xml_filename.to_s)+" -xsl:"+ENV['REPORT_XSL']+" -versionmsg:off"+css.to_s - LOGGER.debug "Converting report to html: '"+cmd+"'" + $logger.debug "Converting report to html: '"+cmd+"'" IO.popen(cmd.to_s) do |f| while line = f.gets do - LOGGER.info "xsltproc> "+line - #LOGGER.info "saxon-xslt> "+line + $logger.info "xsltproc> "+line + #$logger.info "saxon-xslt> "+line end end raise "error during conversion" unless $?==0 diff --git a/report/report_persistance.rb b/report/report_persistance.rb index 447ea16..cd3cd64 100755 --- a/report/report_persistance.rb +++ b/report/report_persistance.rb @@ -72,7 +72,7 @@ class Reports::FileReportPersistance < Reports::ReportPersistance def initialize() FileUtils.mkdir REPORT_DIR unless File.directory?(REPORT_DIR) raise "report cannot be found nor created" unless File.directory?(REPORT_DIR) - LOGGER.debug "reports are stored in "+REPORT_DIR + $logger.debug "reports are stored in "+REPORT_DIR end def list_reports(type, filter_params=nil) @@ -126,7 +126,7 @@ class Reports::FileReportPersistance < Reports::ReportPersistance protected def new_report_with_id(report_content, type, force_id=nil) - LOGGER.debug "storing new report of type "+type.to_s + $logger.debug "storing new report of type "+type.to_s type_dir = type_directory(type) raise "type dir '"+type_dir+"' cannot be found nor created" unless File.directory?(type_dir) @@ -252,7 +252,7 @@ module Reports def list_reports(type, filter_params={}) filter_params[:report_type] = type - LOGGER.debug "find reports for params: "+filter_params.inspect + $logger.debug "find reports for params: "+filter_params.inspect reports = Lib::OhmUtil.find( ReportData, filter_params ) reports.collect{ |r| r.id } end @@ -292,9 +292,9 @@ module Reports if (subjectid) begin res = OpenTox::Authorization.delete_policies_from_uri(report.report_uri, subjectid) - LOGGER.debug "Deleted validation policy: #{res}" + $logger.debug "Deleted validation policy: #{res}" rescue - LOGGER.warn "Policy delete error for validation: #{report.report_uri}" + $logger.warn "Policy delete error for validation: #{report.report_uri}" end end super diff --git a/report/report_service.rb b/report/report_service.rb index f315b04..9944a38 100644 --- a/report/report_service.rb +++ b/report/report_service.rb @@ -25,7 +25,7 @@ module Reports def initialize(home_uri) raise "supposed to be a singleton" if defined?@@instance raise "plz specify home_uri" unless home_uri - LOGGER.info "init report service" + $logger.info "init report service" @home_uri = home_uri @@instance = self end @@ -38,7 +38,7 @@ module Reports # def get_report_types - LOGGER.info "list all report types" + $logger.info "list all report types" Reports::ReportFactory::REPORT_TYPES.collect{ |t| get_uri(t) }.join("\n")+"\n" end @@ -49,7 +49,7 @@ module Reports # def get_all_reports(type, filter_params) - LOGGER.info "get all reports of type '"+type.to_s+"', filter_params: '"+filter_params.inspect+"'" + $logger.info "get all reports of type '"+type.to_s+"', filter_params: '"+filter_params.inspect+"'" check_report_type(type) @@persistance.list_reports(type, filter_params).collect{ |id| get_uri(type,id) }.join("\n")+"\n" end @@ -63,13 +63,13 @@ module Reports def create_report(type, validation_uris, identifier=nil, params={}, subjectid=nil, task=nil) raise "params is no hash" unless params.is_a?(Hash) - LOGGER.info "create report of type '"+type.to_s+"'" + $logger.info "create report of type '"+type.to_s+"'" check_report_type(type) # step1: load validations raise OpenTox::BadRequestError.new("validation_uris missing") unless validation_uris - LOGGER.debug "validation_uri(s): '"+validation_uris.inspect+"'" - LOGGER.debug "identifier: '"+identifier.inspect+"'" + $logger.debug "validation_uri(s): '"+validation_uris.inspect+"'" + $logger.debug "identifier: '"+identifier.inspect+"'" raise "illegal num identifiers: "+identifier.size.to_s+" should be equal to num validation-uris ("+validation_uris.size.to_s+")" if identifier and identifier.size!=validation_uris.size @@ -82,19 +82,19 @@ module Reports end validation_set = Reports::ValidationSet.new(validation_uris, identifier, filter_params, subjectid) raise OpenTox::BadRequestError.new("cannot get validations from validation_uris '"+validation_uris.inspect+"'") unless validation_set and validation_set.size > 0 - LOGGER.debug "loaded "+validation_set.size.to_s+" validation/s" + $logger.debug "loaded "+validation_set.size.to_s+" validation/s" task.progress(10) if task #step 2: create report of type report_content = Reports::ReportFactory.create_report(type, validation_set, params, OpenTox::SubTask.create(task,10,90)) - LOGGER.debug "report created" + $logger.debug "report created" Reports::quit_r Reports.validation_access.delete_tmp_resources(subjectid) #step 3: persist report if creation not failed id = @@persistance.new_report(report_content, type, create_meta_data(type, validation_set, validation_uris), self, subjectid) - LOGGER.debug "report persisted with id: '"+id.to_s+"'" + $logger.debug "report persisted with id: '"+id.to_s+"'" task.progress(100) if task #HACK - format to html right after creation, as dynamically create html may cause deadlocks @@ -110,7 +110,7 @@ module Reports # def get_report( type, id, accept_header_value="text/xml", force_formating=false, params={} ) - LOGGER.info "get report '"+id.to_s+"' of type '"+type.to_s+"' (accept-header-value: '"+ + $logger.info "get report '"+id.to_s+"' of type '"+type.to_s+"' (accept-header-value: '"+ accept_header_value.to_s+"', force-formating:"+force_formating.to_s+" params: '"+params.inspect+"')" check_report_type(type) format = Reports::ReportFormat.get_format(accept_header_value) @@ -124,7 +124,7 @@ module Reports # def get_report_resource( type, id, resource ) - LOGGER.info "get resource '"+resource+"' for report '"+id.to_s+"' of type '"+type.to_s+"'" + $logger.info "get resource '"+resource+"' for report '"+id.to_s+"' of type '"+type.to_s+"'" check_report_type(type) return @@persistance.get_report_resource(type, id, resource) end @@ -137,7 +137,7 @@ module Reports # def delete_report( type, id, subjectid=nil ) - LOGGER.info "delete report '"+id.to_s+"' of type '"+type.to_s+"'" + $logger.info "delete report '"+id.to_s+"' of type '"+type.to_s+"'" check_report_type(type) @@persistance.delete_report(type, id, subjectid) end @@ -145,7 +145,7 @@ module Reports # no api-access for this method def delete_all_reports( type, subjectid=nil ) - LOGGER.info "deleting all reports of type '"+type.to_s+"'" + $logger.info "deleting all reports of type '"+type.to_s+"'" check_report_type(type) @@persistance.list_reports(type).each{ |id| @@persistance.delete_report(type, id, subjectid) } end diff --git a/report/report_test.rb b/report/report_test.rb index 6989896..7b8b77b 100755 --- a/report/report_test.rb +++ b/report/report_test.rb @@ -4,8 +4,8 @@ require './report/report_application.rb' require 'test/unit' require 'rack/test' require "./lib/test_util.rb" -LOGGER = Logger.new(STDOUT) -LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S " +$logger = Logger.new(STDOUT) +$logger.datetime_format = "%Y-%m-%d %H:%M:%S " class Reports::ApplicationTest < Test::Unit::TestCase include Rack::Test::Methods diff --git a/report/statistical_test.rb b/report/statistical_test.rb index 4b65f0a..757f082 100644 --- a/report/statistical_test.rb +++ b/report/statistical_test.rb @@ -10,7 +10,7 @@ module Reports raise "statistical-test: '"+test_method+"' does not exist" unless ReportStatisticalTest.respond_to?(test_method) grouped_validations = Reports::Util.group(validations, [group_attribute]) - LOGGER.debug "perfom test '"+test_method.to_s+"' for '"+test_attribute.to_s+"' for #"+grouped_validations.size.to_s+" "+group_attribute.to_s + $logger.debug "perfom test '"+test_method.to_s+"' for '"+test_attribute.to_s+"' for #"+grouped_validations.size.to_s+" "+group_attribute.to_s titles = [] matrix = [] @@ -39,7 +39,7 @@ module Reports array1 = validations1.collect{ |v| (v.send(attribute).is_a?(Hash) ? v.send(attribute)[class_value].to_f : v.send(attribute).to_f) } array2 = validations2.collect{ |v| (v.send(attribute).is_a?(Hash) ? v.send(attribute)[class_value].to_f : v.send(attribute).to_f) } - LOGGER.debug "paired-t-testing "+attribute.to_s+" "+array1.inspect+" vs "+array2.inspect + $logger.debug "paired-t-testing "+attribute.to_s+" "+array1.inspect+" vs "+array2.inspect Reports::r_util.paired_ttest(array1, array2, significance_level) end diff --git a/report/validation_access.rb b/report/validation_access.rb index a14b397..d51c99d 100755 --- a/report/validation_access.rb +++ b/report/validation_access.rb @@ -27,15 +27,15 @@ class Reports::ValidationDB if same_service?u raise OpenTox::NotAuthorizedError.new "Not authorized: GET "+u.to_s if - AA_SERVER and !OpenTox::Authorization.authorized?(u,"GET",subjectid) - cv = Validation::Crossvalidation.get( cv_id ) + $aa[:uri] and !OpenTox::Authorization.authorized?(u,"GET",subjectid) + cv = Validation::Crossvalidation[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 += Validation::Validation.find( :all, :conditions => { :crossvalidation_id => cv_id } ).collect{|v| v.validation_uri.to_s} val_uris = Validation::Validation.find( :crossvalidation_id => cv_id, :validation_type => "crossvalidation" ).collect{|v| v.validation_uri.to_s} else val_base_uri = u.gsub(/\/crossvalidation\/[0-9]+/,"") - val_uris = OpenTox::RestClientWrapper.get( val_base_uri+"?crossvalidation_id="+cv_id.to_s+"&validation_type=crossvalidation", {:subjectid => subjectid, :accept => "text/uri-list" }).split("\n") + val_uris = OpenTox::RestClientWrapper.get( val_base_uri+"?crossvalidation_id="+cv_id.to_s+"&validation_type=crossvalidation",nil,{:subjectid => subjectid, :accept => "text/uri-list" }).split("\n") end val_uris.each do |v_uri| @@ -60,10 +60,11 @@ class Reports::ValidationDB if same_service? uri raise OpenTox::NotAuthorizedError.new "Not authorized: GET "+uri.to_s if - AA_SERVER and !OpenTox::Authorization.authorized?(uri,"GET",subjectid) - v = Validation::Validation.get(validation_id) + $aa[:uri] and !OpenTox::Authorization.authorized?(uri,"GET",subjectid) + Ohm.connect(:thread_safe => true, :port => 6379) + v = Validation::Validation[validation_id] else - v = YAML::load(OpenTox::RestClientWrapper.get uri, {:subjectid=>subjectid, :accept=>"application/serialize"}) + v = YAML::load(OpenTox::RestClientWrapper.get uri,nil,{:subjectid=>subjectid, :accept=>"application/serialize"}) end v.subjectid = subjectid v.filter_predictions(filter_params[:min_confidence], filter_params[:min_num_predictions], filter_params[:max_num_predictions]) if @@ -88,19 +89,19 @@ class Reports::ValidationDB def init_validation_from_cv_statistics( validation, cv_uri, filter_params, subjectid ) - raise OpenTox::BadRequestError.new "not a crossvalidation uri: "+cv_uri.to_s unless cv_uri.uri? and cv_uri =~ /crossvalidation.*\/[0-9]+$/ + raise OpenTox::BadRequestError.new "not a crossvalidation uri: "+cv_uri.to_s unless cv_uri =~ /crossvalidation.*\/[0-9]+$/ if same_service?cv_uri cv_id = cv_uri.split("/")[-1] raise OpenTox::NotAuthorizedError.new "Not authorized: GET "+cv_uri.to_s if - AA_SERVER and !OpenTox::Authorization.authorized?(cv_uri,"GET",subjectid) - cv = Validation::Crossvalidation.get(cv_id) + $aa[:uri] and !OpenTox::Authorization.authorized?(cv_uri,"GET",subjectid) + cv = Validation::Crossvalidation[cv_id] raise OpenTox::NotFoundError.new "crossvalidation with id "+crossvalidation_id.to_s+" not found" unless cv raise OpenTox::BadRequestError.new "crossvalidation with id "+crossvalidation_id.to_s+" is not finished yet" unless cv.finished v = Validation::Validation.from_cv_statistics(cv_id, subjectid) else - cv = YAML::load(OpenTox::RestClientWrapper.get cv_uri, {:subjectid=>subjectid, :accept=>"application/serialize"}) - v = YAML::load(OpenTox::RestClientWrapper.get cv_uri+"/statistics", {:subjectid=>subjectid, :accept=>"application/serialize"}) + cv = YAML::load(OpenTox::RestClientWrapper.get cv_uri,nil,{:subjectid=>subjectid, :accept=>"application/serialize"}) + v = YAML::load(OpenTox::RestClientWrapper.get cv_uri+"/statistics",nil,{:subjectid=>subjectid, :accept=>"application/serialize"}) end v.filter_predictions(filter_params[:min_confidence], filter_params[:min_num_predictions], filter_params[:max_num_predictions]) if filter_params @@ -125,10 +126,10 @@ class Reports::ValidationDB cv = nil if same_service?validation.crossvalidation_uri - cv = Validation::Crossvalidation.get(validation.crossvalidation_id) + cv = Validation::Crossvalidation[validation.crossvalidation_id] raise OpenTox::BadRequestError.new "no crossvalidation found with id "+validation.crossvalidation_id.to_s unless cv else - cv = YAML::load(OpenTox::RestClientWrapper.get validation.crossvalidation_uri, {:subjectid=>subjectid, :accept=>"application/serialize"}) + cv = YAML::load(OpenTox::RestClientWrapper.get validation.crossvalidation_uri,nil,{:subjectid=>subjectid, :accept=>"application/serialize"}) end Validation::CROSS_VAL_PROPS.each do |p| validation.send("#{p.to_s}=".to_sym, cv.send(p.to_s)) @@ -148,15 +149,15 @@ class Reports::ValidationDB training_features = Lib::DatasetCache.find( training_feature_dataset_uri(validation,subjectid), subjectid ) test_dataset = Lib::DatasetCache.find( validation.test_dataset_uri, subjectid ) features_found = true - training_features.features.keys.each do |f| - unless test_dataset.features.keys.include?(f) + training_features.features.each do |f| + unless test_dataset.find_feature(f.uri) features_found = false - LOGGER.debug "training-feature are not in test-datset #{f}" + $logger.debug "training-feature are not in test-datset #{f}" break end end if features_found - LOGGER.debug "all training-features found in test-datset" + $logger.debug "all training-features found in test-datset" uri = test_dataset.uri else m = OpenTox::Model::Generic.find(validation.model_uri, subjectid) @@ -172,7 +173,7 @@ class Reports::ValidationDB uri = OpenTox::RestClientWrapper.post(feat_gen,{:subjectid => subjectid, :feature_dataset_uri=>training_feature_dataset_uri(validation,subjectid), :dataset_uri=>validation.test_dataset_uri}) - @@tmp_resources << uri + @@tmp_resources << OpenTox.wait_for_task(uri) end uri end @@ -202,9 +203,10 @@ class Reports::ValidationDB test_datasets.split(";").each do |test_dataset| d = Lib::DatasetCache.find( test_dataset, subjectid ) raise "cannot get test target dataset for accept values, dataset: "+test_dataset.to_s unless d - accept_values = d.accept_values(validation.prediction_feature) - raise "cannot get accept values from dataset "+test_dataset.to_s+" for feature "+ - validation.prediction_feature+":\n"+d.features[validation.prediction_feature].to_yaml unless accept_values!=nil + feature = OpenTox::Feature.find(validation.prediction_feature,subjectid) + accept_values = feature.accept_values + raise "cannot get accept values for feature "+ + validation.prediction_feature+":\n"+feature.to_yaml unless accept_values!=nil raise "different accept values" if res && res!=accept_values res = accept_values end @@ -212,20 +214,24 @@ class Reports::ValidationDB end def feature_type( validation, subjectid=nil ) - OpenTox::Model::Generic.new(validation.model_uri).feature_type(subjectid) + m = OpenTox::Model.new(validation.model_uri,subjectid) + m.get + m.feature_type(subjectid) #get_model(validation).classification? end def predicted_variable(validation, subjectid=nil) raise "cannot derive model depended props for merged validations" if Lib::MergeObjects.merged?(validation) - model = OpenTox::Model::Generic.find(validation.model_uri, subjectid) + model = OpenTox::Model.new(validation.model_uri,subjectid) + model.get raise OpenTox::NotFoundError.new "model not found '"+validation.model_uri+"'" unless model model.predicted_variable(subjectid) end def predicted_confidence(validation, subjectid=nil) raise "cannot derive model depended props for merged validations" if Lib::MergeObjects.merged?(validation) - model = OpenTox::Model::Generic.find(validation.model_uri, subjectid) + model = OpenTox::Model.new(validation.model_uri,subjectid) + model.get raise OpenTox::NotFoundError.new "model not found '"+validation.model_uri+"'" unless model model.predicted_confidence(subjectid) end diff --git a/report/validation_data.rb b/report/validation_data.rb index 3806fd7..c8023f1 100755 --- a/report/validation_data.rb +++ b/report/validation_data.rb @@ -130,7 +130,7 @@ module Reports @predictions else unless @prediction_dataset_uri - LOGGER.info("no predictions available, prediction_dataset_uri not set") + $logger.info("no predictions available, prediction_dataset_uri not set") task.progress(100) if task nil else diff --git a/report/xml_report.rb b/report/xml_report.rb index f610677..9c101d2 100755 --- a/report/xml_report.rb +++ b/report/xml_report.rb @@ -23,7 +23,7 @@ module Reports def self.dtd_directory if $url_provider - $url_provider.url_for('/'+ENV['DOCBOOK_DIRECTORY']+'/'+ENV['REPORT_DTD'], :full) + $url_provider.url_for("/validation/"+ENV['DOCBOOK_DIRECTORY']+'/'+ENV['REPORT_DTD'], :full) else f = File.expand_path(File.join(ENV['DOCBOOK_DIRECTORY'],ENV['REPORT_DTD'])) raise "cannot find dtd" unless File.exist?(f) diff --git a/test/test_application.rb b/test/test_application.rb index f255d1d..5f8607d 100755 --- a/test/test_application.rb +++ b/test/test_application.rb @@ -2,7 +2,7 @@ post '/test_validation/?' do validationExamples = ValidationExamples.select(params[:select]) return "please \"select\" a single validation example:\n"+ValidationExamples.list if validationExamples.size!=1 or validationExamples[0].size!=1 - task = OpenTox::Task.create("Test validation",url_for("/test_validation",:full)) do |task| + task = OpenTox::Task.run("Test validation",url_for("/validation/test_validation",:full)) do |task| v = validationExamples[0][0] ex = v.new ex.subjectid = @subjectid diff --git a/test/test_examples_util.rb b/test/test_examples_util.rb index a323703..2edd91a 100755 --- a/test/test_examples_util.rb +++ b/test/test_examples_util.rb @@ -18,22 +18,26 @@ module ValidationExamples @@prediction_features = {} def self.upload_dataset(file, subjectid=nil, dataset_service=$dataset[:uri]) #, file_type="application/x-yaml") + raise "File not found: "+file.path.to_s unless File.exist?(file.path) if @@dataset_uris[file.path.to_s]==nil - LOGGER.debug "uploading file: "+file.path.to_s + $logger.debug "uploading file: "+file.path.to_s if (file.path =~ /yaml$/) data = File.read(file.path) - #data_uri = OpenTox::RestClientWrapper.post(dataset_service,{:content_type => file_type},data).to_s.chomp + #data_uri = OpenTox::RestClientWrapper.post_wait(dataset_service,{:content_type => file_type},data).to_s.chomp #@@dataset_uris[file.path.to_s] = data_uri - #LOGGER.debug "uploaded dataset: "+data_uri + #$logger.debug "uploaded dataset: "+data_uri d = OpenTox::Dataset.create($dataset[:uri], subjectid) d.load_yaml(data) d.save( subjectid ) @@dataset_uris[file.path.to_s] = d.uri elsif (file.path =~ /csv$/) - d = OpenTox::Dataset.create_from_csv_file(file.path, subjectid) - raise "num features not 1 (="+d.features.keys.size.to_s+"), what to predict??" if d.features.keys.size != 1 - @@prediction_features[file.path.to_s] = d.features.keys[0] + d = OpenTox::Dataset.new nil, subjectid + d.upload file.path + d.get + #d = OpenTox::Dataset.create_from_csv_file(file.path, subjectid) + raise "num features not 1 (="+d.features.size.to_s+"), what to predict??" if d.features.size != 1 + @@prediction_features[file.path.to_s] = d.features[0].uri @@dataset_uris[file.path.to_s] = d.uri elsif (file.path =~ /rdf$/) d = OpenTox::Dataset.create($dataset[:uri], subjectid) @@ -43,10 +47,11 @@ module ValidationExamples else raise "unknown file type: "+file.path.to_s end - LOGGER.debug "uploaded dataset: "+d.uri + $logger.debug "uploaded dataset: "+d.uri else - LOGGER.debug "file already uploaded: "+@@dataset_uris[file.path.to_s] + $logger.debug "file already uploaded: "+@@dataset_uris[file.path.to_s] end + return @@dataset_uris[file.path.to_s] end @@ -70,15 +75,19 @@ module ValidationExamples #end end - def self.validation_post(uri, params, subjectid, waiting_task=nil ) + def self.validation_post(uri, params, subjectid, waiting_task=nil, accept_header='application/rdf+xml' ) params[:subjectid] = subjectid if subjectid if $test_case - $test_case.post uri,params - return wait($test_case.last_response.body) + $test_case.post '/validation'+uri,params,'HTTP_ACCEPT' => accept_header + uri = wait($test_case.last_response.body) else - return OpenTox::RestClientWrapper.post(File.join($validation[:uri],uri),params,nil,waiting_task).to_s + params[:accept] = accept_header + uri = OpenTox::RestClientWrapper.post(File.join($validation[:uri],uri),params,{},waiting_task).to_s + uri = OpenTox.wait_for_task(uri) end + raise "validation post result not a validation uri: #{uri}" unless uri.validation_uri? + uri end def self.validation_get(uri, subjectid, accept_header='application/rdf+xml') @@ -86,18 +95,18 @@ module ValidationExamples params[:subjectid] = subjectid if subjectid if $test_case #puts "getting "+uri+","+accept_header - $test_case.get uri,params,'HTTP_ACCEPT' => accept_header + $test_case.get '/validation'+uri,params,'HTTP_ACCEPT' => accept_header return wait($test_case.last_response.body) else params[:accept] = accept_header - return OpenTox::RestClientWrapper.get(File.join($validation[:uri],uri),params) + return OpenTox::RestClientWrapper.get(File.join($validation[:uri],uri),nil,params) end end def self.validation_delete(uri, accept_header='application/rdf+xml') if $test_case - $test_case.delete uri,{:subjectid => SUBJECTID},'HTTP_ACCEPT' => accept_header + $test_case.delete '/validation'+uri,{:subjectid => SUBJECTID},'HTTP_ACCEPT' => accept_header return wait($test_case.last_response.body) else return OpenTox::RestClientWrapper.delete(File.join($validation[:uri],uri),{:accept => accept_header,:subjectid => SUBJECTID}) @@ -110,7 +119,7 @@ module ValidationExamples task = OpenTox::Task.find(uri.to_s.chomp) task.wait_for_completion #raise "task failed: "+uri.to_s+", description: '"+task.description.to_s+"'" if task.error? - LOGGER.error "task failed :\n"+task.to_yaml if task.error? + $logger.error "task failed :\n"+task.to_yaml if task.error? uri = task.result_uri end uri @@ -323,7 +332,7 @@ module ValidationExamples #rescue => ex #puts "could not validate: "+ex.message #@validation_error = ex.message - #LOGGER.error ex.message + #$logger.error ex.message #end end diff --git a/validation.gemspec b/validation.gemspec index 2e12eed..8455238 100644 --- a/validation.gemspec +++ b/validation.gemspec @@ -22,6 +22,9 @@ Gem::Specification.new do |s| # specify any dependencies here; for example: s.add_runtime_dependency "opentox-server" + s.add_runtime_dependency "ohm" + s.add_runtime_dependency "ohm-contrib" + #s.add_runtime_dependency "asdfasdfasdfasdfasfasdfsadf" s.post_install_message = "Please configure your service in ~/.opentox/config/validation.rb" end diff --git a/validation/validation_application.rb b/validation/validation_application.rb index 37fea1e..0fc9fff 100755 --- a/validation/validation_application.rb +++ b/validation/validation_application.rb @@ -6,698 +6,713 @@ end require './lib/dataset_cache.rb' require './validation/validation_service.rb' -helpers do - def check_stratified(params) - params[:stratified] = "false" unless params[:stratified] - raise OpenTox::BadRequestError.new "stratified != true|false|super, is #{params[:stratified]}" unless - params[:stratified]=~/true|false|super/ - end -end - -get '/crossvalidation/?' do - LOGGER.info "list all crossvalidations "+params.inspect - model_uri = params.delete("model") || params.delete("model_uri") - if model_uri - model = OpenTox::Model::Generic.find(model_uri, @subjectid) - params[:algorithm] = model.metadata[OT.algorithm] - params[:dataset] = model.metadata[OT.trainingDataset] - end - uri_list = Lib::OhmUtil.find( Validation::Crossvalidation, params ).sort.collect{|v| v.crossvalidation_uri}.join("\n") + "\n" - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "Single validations: "+url_for("/",:full)+"\n"+ - "Leave-one-out crossvalidations: "+url_for("/crossvalidation/loo",:full)+"\n"+ - "Crossvalidation reports: "+url_for("/report/crossvalidation",:full) - description = - "A list of all crossvalidations.\n"+ - "Use the POST method to perform a crossvalidation." - post_command = OpenTox::PostCommand.new request.url,"Perform crossvalidation" - post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") - post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") - post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") - post_command.attributes << OpenTox::PostAttribute.new("num_folds",false,"10") - post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") - post_command.attributes << OpenTox::PostAttribute.new("stratified",false,"false","Stratification ensures an equal class-value spread in folds.") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end -end - -post '/crossvalidation/?' do - LOGGER.info "creating crossvalidation "+params.inspect - raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 - raise OpenTox::BadRequestError.new "illegal param-value num_folds: '"+params[:num_folds].to_s+"', must be integer >1" unless params[:num_folds]==nil or - params[:num_folds].to_i>1 - check_stratified(params) +class Validation::Application < OpenTox::Service - task = OpenTox::Task.create( "Perform crossvalidation", url_for("/crossvalidation", :full) ) do |task| #, params - cv_params = { :dataset_uri => params[:dataset_uri], - :algorithm_uri => params[:algorithm_uri], - :algorithm_params => params[:algorithm_params], - :prediction_feature => params[:prediction_feature], - :stratified => params[:stratified], - :loo => "false", - :subjectid => @subjectid } - [ :num_folds, :random_seed ].each{ |sym| cv_params[sym] = params[sym] if params[sym] } - cv = Validation::Crossvalidation.create cv_params - cv.subjectid = @subjectid - cv.perform_cv( OpenTox::SubTask.create(task,0,95) ) - # computation of stats is cheap as dataset are already loaded into the memory - Validation::Validation.from_cv_statistics( cv.id, @subjectid, OpenTox::SubTask.create(task,95,100) ) - cv.crossvalidation_uri - end - return_task(task) -end - -post '/crossvalidation/cleanup/?' do - LOGGER.info "crossvalidation cleanup, starting..." - content_type "text/uri-list" - deleted = [] - Validation::Crossvalidation.all.collect.delete_if{|cv| cv.finished}.each do |cv| - if OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"DELETE",@subjectid) - LOGGER.debug "delete cv with id:"+cv.id.to_s+", finished is false" - deleted << cv.crossvalidation_uri + helpers Sinatra::UrlForHelper + + helpers do + def check_stratified(params) + params[:stratified] = "false" unless params[:stratified] + raise OpenTox::BadRequestError.new "stratified != true|false|super, is #{params[:stratified]}" unless + params[:stratified]=~/true|false|super/ + end + end + + before do + $url_provider = self + end + + get '/validation/crossvalidation/?' do + $logger.info "list all crossvalidations "+params.inspect + model_uri = params.delete("model") || params.delete("model_uri") + if model_uri + model = OpenTox::Model::Generic.find(model_uri, @subjectid) + params[:algorithm] = model.metadata[OT.algorithm] + params[:dataset] = model.metadata[OT.trainingDataset] + end + uri_list = Lib::OhmUtil.find( Validation::Crossvalidation, params ).sort.collect{|v| v.crossvalidation_uri}.join("\n") + "\n" + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "Single validations: "+url_for("/validation/",:full)+"\n"+ + "Leave-one-out crossvalidations: "+url_for("/validation/crossvalidation/loo",:full)+"\n"+ + "Crossvalidation reports: "+url_for("/validation/report/crossvalidation",:full) + description = + "A list of all crossvalidations.\n"+ + "Use the POST method to perform a crossvalidation." + # post_command = OpenTox::PostCommand.new request.url,"Perform crossvalidation" + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") + # post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") + # post_command.attributes << OpenTox::PostAttribute.new("num_folds",false,"10") + # post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") + # post_command.attributes << OpenTox::PostAttribute.new("stratified",false,"false","Stratification ensures an equal class-value spread in folds.") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end + end + + post '/validation/crossvalidation/?' do + $logger.info "creating crossvalidation "+params.inspect + raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 + raise OpenTox::BadRequestError.new "illegal param-value num_folds: '"+params[:num_folds].to_s+"', must be integer >1" unless params[:num_folds]==nil or + params[:num_folds].to_i>1 + check_stratified(params) + + task = OpenTox::Task.run( "Perform crossvalidation", url_for("/validation/crossvalidation", :full) ) do |task| #, params + cv_params = { :dataset_uri => params[:dataset_uri], + :algorithm_uri => params[:algorithm_uri], + :algorithm_params => params[:algorithm_params], + :prediction_feature => params[:prediction_feature], + :stratified => params[:stratified], + :loo => "false", + :subjectid => @subjectid } + [ :num_folds, :random_seed ].each{ |sym| cv_params[sym] = params[sym] if params[sym] } + cv = Validation::Crossvalidation.create cv_params + cv.subjectid = @subjectid + cv.perform_cv( OpenTox::SubTask.create(task,0,95) ) + # computation of stats is cheap as dataset are already loaded into the memory + Validation::Validation.from_cv_statistics( cv.id, @subjectid, OpenTox::SubTask.create(task,95,100) ) + cv.crossvalidation_uri + end + return_task(task) + end + + post '/validation/crossvalidation/cleanup/?' do + $logger.info "crossvalidation cleanup, starting..." + content_type "text/uri-list" + deleted = [] + Validation::Crossvalidation.all.collect.delete_if{|cv| cv.finished}.each do |cv| + if OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"DELETE",@subjectid) + $logger.debug "delete cv with id:"+cv.id.to_s+", finished is false" + deleted << cv.crossvalidation_uri + cv.subjectid = @subjectid + cv.delete_crossvalidation + sleep 1 if $aa[:uri] + end + end + $logger.info "crossvalidation cleanup, deleted "+deleted.size.to_s+" cvs" + deleted.join("\n")+"\n" + end + + post '/validation/crossvalidation/loo/?' do + $logger.info "creating loo-crossvalidation "+params.inspect + raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 + raise OpenTox::BadRequestError.new "illegal param: num_folds, stratified, random_seed not allowed for loo-crossvalidation" if params[:num_folds] or + params[:stratified] or params[:random_seed] + task = OpenTox::Task.run( "Perform loo-crossvalidation", url_for("/validation/crossvalidation/loo", :full) ) do |task| #, params + cv_params = { :dataset_uri => params[:dataset_uri], + :algorithm_params => params[:algorithm_params], + :prediction_feature => params[:prediction_feature], + :algorithm_uri => params[:algorithm_uri], + :loo => "true" } + cv = Validation::Crossvalidation.create cv_params + cv.subjectid = @subjectid + cv.perform_cv( OpenTox::SubTask.create(task,0,95)) + # computation of stats is cheap as dataset are already loaded into the memory + Validation::Validation.from_cv_statistics( cv.id, @subjectid, OpenTox::SubTask.create(task,95,100) ) + cv.clean_loo_files( !(params[:algorithm_params] && params[:algorithm_params] =~ /feature_dataset_uri/) ) + cv.crossvalidation_uri + end + return_task(task) + end + + get '/validation/crossvalidation/loo/?' do + $logger.info "list all crossvalidations" + params[:loo]="true" + uri_list = Lib::OhmUtil.find( Validation::Crossvalidation, params ).sort.collect{|v| v.crossvalidation_uri}.join("\n") + "\n" + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "Single validations: "+url_for("/validation/",:full)+"\n"+ + "All crossvalidations: "+url_for("/validation/crossvalidation",:full)+"\n"+ + "Crossvalidation reports: "+url_for("/validation/report/crossvalidation",:full) + description = + "A list of all leave one out crossvalidations.\n"+ + "Use the POST method to perform a crossvalidation." + # post_command = OpenTox::PostCommand.new request.url,"Perform leave-one-out-crossvalidation" + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") + # post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end + + end + + get '/validation/crossvalidation/:id' do + $logger.info "get crossvalidation with id "+params[:id].to_s + # begin + # #crossvalidation = Validation::Crossvalidation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." + # end + crossvalidation = Validation::Crossvalidation[params[:id]] + raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." unless crossvalidation + + case request.env['HTTP_ACCEPT'].to_s + when "application/rdf+xml" + content_type "application/rdf+xml" + crossvalidation.to_rdf + when /text\/html/ + related_links = + "Search for corresponding cv report: "+url_for("/validation/report/crossvalidation?crossvalidation="+crossvalidation.crossvalidation_uri,:full)+"\n"+ + "Statistics for this crossvalidation: "+url_for("/validation/crossvalidation/"+params[:id]+"/statistics",:full)+"\n"+ + "Predictions of this crossvalidation: "+url_for("/validation/crossvalidation/"+params[:id]+"/predictions",:full)+"\n"+ + "All crossvalidations: "+url_for("/validation/crossvalidation",:full)+"\n"+ + "All crossvalidation reports: "+url_for("/validation/report/crossvalidation",:full) + description = + "A crossvalidation resource." + content_type "text/html" + OpenTox.text_to_html crossvalidation.to_rdf_yaml,@subjectid,related_links,description + when "application/serialize" + content_type "application/serialize" + crossvalidation.inspect # to load all the stuff + crossvalidation.to_yaml + when /application\/x-yaml|\*\/\*/ + content_type "application/x-yaml" + crossvalidation.to_rdf_yaml + else + raise OpenTox::BadRequestError.new "MIME type '"+request.env['HTTP_ACCEPT'].to_s+"' not supported, valid Accept-Headers: \"application/rdf+xml\", \"application/x-yaml\", \"text/html\"." + end + end + + get '/validation/crossvalidation/:id/statistics' do + + $logger.info "get crossvalidation statistics for crossvalidation with id "+params[:id].to_s + v = Validation::Validation.from_cv_statistics( params[:id], @subjectid ) + case request.env['HTTP_ACCEPT'].to_s + when /text\/html/ + related_links = + "The corresponding crossvalidation resource: "+url_for("/validation/crossvalidation/"+params[:id],:full) + description = + "The averaged statistics for the crossvalidation." + content_type "text/html" + OpenTox.text_to_html v.to_rdf_yaml,@subjectid,related_links,description + when "application/rdf+xml" + content_type "application/rdf+xml" + v.to_rdf + when "application/serialize" + content_type "application/serialize" + v.inspect # to load all the stuff + v.to_yaml + else + content_type "application/x-yaml" + v.to_rdf_yaml + end + end + + get '/validation/crossvalidation/:id/statistics/probabilities' do + + $logger.info "get crossvalidation statistics for crossvalidation with id "+params[:id].to_s + raise OpenTox::BadRequestError.new("Missing params, plz give confidence and prediction") unless params[:confidence] and params[:prediction] + v = Validation::Validation.from_cv_statistics( params[:id], @subjectid ) + props = v.probabilities(params[:confidence].to_s.to_f,params[:prediction].to_s) + content_type "text/x-yaml" + props.to_yaml + end + + delete '/validation/crossvalidation/:id/?' do + $logger.info "delete crossvalidation with id "+params[:id].to_s + content_type "text/plain" + # begin + #crossvalidation = Validation::Crossvalidation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." + # end + # Validation::Crossvalidation.delete(params[:id]) + + cv = Validation::Crossvalidation[params[:id]] + raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." unless cv cv.subjectid = @subjectid cv.delete_crossvalidation - sleep 1 if AA_SERVER end - end - LOGGER.info "crossvalidation cleanup, deleted "+deleted.size.to_s+" cvs" - deleted.join("\n")+"\n" -end - -post '/crossvalidation/loo/?' do - LOGGER.info "creating loo-crossvalidation "+params.inspect - raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 - raise OpenTox::BadRequestError.new "illegal param: num_folds, stratified, random_seed not allowed for loo-crossvalidation" if params[:num_folds] or - params[:stratified] or params[:random_seed] - task = OpenTox::Task.create( "Perform loo-crossvalidation", url_for("/crossvalidation/loo", :full) ) do |task| #, params - cv_params = { :dataset_uri => params[:dataset_uri], - :algorithm_params => params[:algorithm_params], - :prediction_feature => params[:prediction_feature], - :algorithm_uri => params[:algorithm_uri], - :loo => "true" } - cv = Validation::Crossvalidation.create cv_params - cv.subjectid = @subjectid - cv.perform_cv( OpenTox::SubTask.create(task,0,95)) - # computation of stats is cheap as dataset are already loaded into the memory - Validation::Validation.from_cv_statistics( cv.id, @subjectid, OpenTox::SubTask.create(task,95,100) ) - cv.clean_loo_files( !(params[:algorithm_params] && params[:algorithm_params] =~ /feature_dataset_uri/) ) - cv.crossvalidation_uri - end - return_task(task) -end - -get '/crossvalidation/loo/?' do - LOGGER.info "list all crossvalidations" - params[:loo]="true" - uri_list = Lib::OhmUtil.find( Validation::Crossvalidation, params ).sort.collect{|v| v.crossvalidation_uri}.join("\n") + "\n" - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "Single validations: "+url_for("/",:full)+"\n"+ - "All crossvalidations: "+url_for("/crossvalidation",:full)+"\n"+ - "Crossvalidation reports: "+url_for("/report/crossvalidation",:full) - description = - "A list of all leave one out crossvalidations.\n"+ - "Use the POST method to perform a crossvalidation." - post_command = OpenTox::PostCommand.new request.url,"Perform leave-one-out-crossvalidation" - post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") - post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") - post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end - -end - -get '/crossvalidation/:id' do - LOGGER.info "get crossvalidation with id "+params[:id].to_s -# begin -# #crossvalidation = Validation::Crossvalidation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." -# end - crossvalidation = Validation::Crossvalidation.get(params[:id]) - raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." unless crossvalidation - - case request.env['HTTP_ACCEPT'].to_s - when "application/rdf+xml" - content_type "application/rdf+xml" - crossvalidation.to_rdf - when /text\/html/ - related_links = - "Search for corresponding cv report: "+url_for("/report/crossvalidation?crossvalidation="+crossvalidation.crossvalidation_uri,:full)+"\n"+ - "Statistics for this crossvalidation: "+url_for("/crossvalidation/"+params[:id]+"/statistics",:full)+"\n"+ - "Predictions of this crossvalidation: "+url_for("/crossvalidation/"+params[:id]+"/predictions",:full)+"\n"+ - "All crossvalidations: "+url_for("/crossvalidation",:full)+"\n"+ - "All crossvalidation reports: "+url_for("/report/crossvalidation",:full) - description = - "A crossvalidation resource." - content_type "text/html" - OpenTox.text_to_html crossvalidation.to_rdf_yaml,@subjectid,related_links,description - when "application/serialize" - content_type "application/serialize" - crossvalidation.inspect # to load all the stuff - crossvalidation.to_yaml - when /application\/x-yaml|\*\/\*/ - content_type "application/x-yaml" - crossvalidation.to_rdf_yaml - else - raise OpenTox::BadRequestError.new "MIME type '"+request.env['HTTP_ACCEPT'].to_s+"' not supported, valid Accept-Headers: \"application/rdf+xml\", \"application/x-yaml\", \"text/html\"." - end -end - -get '/crossvalidation/:id/statistics' do - - LOGGER.info "get crossvalidation statistics for crossvalidation with id "+params[:id].to_s - v = Validation::Validation.from_cv_statistics( params[:id], @subjectid ) - case request.env['HTTP_ACCEPT'].to_s - when /text\/html/ - related_links = - "The corresponding crossvalidation resource: "+url_for("/crossvalidation/"+params[:id],:full) - description = - "The averaged statistics for the crossvalidation." - content_type "text/html" - OpenTox.text_to_html v.to_rdf_yaml,@subjectid,related_links,description - when "application/rdf+xml" - content_type "application/rdf+xml" - v.to_rdf - when "application/serialize" - content_type "application/serialize" - v.inspect # to load all the stuff - v.to_yaml - else - content_type "application/x-yaml" - v.to_rdf_yaml - end -end - -get '/crossvalidation/:id/statistics/probabilities' do - - LOGGER.info "get crossvalidation statistics for crossvalidation with id "+params[:id].to_s - raise OpenTox::BadRequestError.new("Missing params, plz give confidence and prediction") unless params[:confidence] and params[:prediction] - v = Validation::Validation.from_cv_statistics( params[:id], @subjectid ) - props = v.probabilities(params[:confidence].to_s.to_f,params[:prediction].to_s) - content_type "text/x-yaml" - props.to_yaml -end - -delete '/crossvalidation/:id/?' do - LOGGER.info "delete crossvalidation with id "+params[:id].to_s - content_type "text/plain" -# begin - #crossvalidation = Validation::Crossvalidation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." -# end -# Validation::Crossvalidation.delete(params[:id]) - - cv = Validation::Crossvalidation.get(params[:id]) - raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." unless cv - cv.subjectid = @subjectid - cv.delete_crossvalidation -end - -#get '/crossvalidation/:id/validations' do -# LOGGER.info "get all validations for crossvalidation with id "+params[:id].to_s -# begin -# crossvalidation = Validation::Crossvalidation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." -# end -# content_type "text/uri-list" -# Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ).collect{ |v| v.validation_uri.to_s }.join("\n")+"\n" -#end - -#get '/crossvalidation/:id/predictions' do -# LOGGER.info "get predictions for crossvalidation with id "+params[:id].to_s -# begin -# #crossvalidation = Validation::Crossvalidation.find(params[:id]) -# crossvalidation = Validation::Crossvalidation.get(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." -# end -# raise OpenTox::BadRequestError.new "Crossvalidation '"+params[:id].to_s+"' not finished" unless crossvalidation.finished -# -# content_type "application/x-yaml" -# validations = Validation::Validation.find( :crossvalidation_id => params[:id], :validation_type => "crossvalidation" ) -# p = Lib::OTPredictions.to_array( validations.collect{ |v| v.compute_validation_stats_with_model(nil, true) } ).to_yaml -# -# case request.env['HTTP_ACCEPT'].to_s -# when /text\/html/ -# content_type "text/html" -# description = -# "The crossvalidation predictions as (yaml-)array." -# related_links = -# "All crossvalidations: "+url_for("/crossvalidation",:full)+"\n"+ -# "Correspoding crossvalidation: "+url_for("/crossvalidation/"+params[:id],:full) -# OpenTox.text_to_html p,@subjectid, related_links, description -# else -# content_type "text/x-yaml" -# p -# end -#end - -get '/?' do - - LOGGER.info "list all validations, params: "+params.inspect - uri_list = Lib::OhmUtil.find( Validation::Validation, params ).sort.collect{|v| v.validation_uri}.join("\n") + "\n" - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "To perform a validation:\n"+ - "* "+url_for("/test_set_validation",:full)+"\n"+ - "* "+url_for("/training_test_validation",:full)+"\n"+ - "* "+url_for("/bootstrapping",:full)+"\n"+ - "* "+url_for("/training_test_split",:full)+"\n"+ - "* "+url_for("/crossvalidation",:full)+"\n"+ - "Validation reporting: "+url_for("/report",:full)+"\n"+ - "REACH relevant reporting: "+url_for("/reach_report",:full)+"\n"+ - "Examples for using this service: "+url_for("/examples",:full)+"\n" - description = - "A validation web service for the OpenTox project ( http://opentox.org ).\n"+ - "In the root directory (this is where you are now), a list of all validation resources is returned." - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description - else - content_type "text/uri-list" - uri_list - end -end - -post '/?' do - raise OpenTox::BadRequestError.new "Post not supported, to perfom a validation use '/test_set_validation', '/training_test_validation', 'bootstrapping', 'training_test_split'" -end - -post '/test_set_validation' do - LOGGER.info "creating test-set-validation "+params.inspect - if params[:model_uri].to_s.size>0 and params[:test_dataset_uri].to_s.size>0 and - params[:training_dataset_uri].to_s.size==0 and params[:algorithm_uri].to_s.size==0 - task = OpenTox::Task.create( "Perform test-set-validation", url_for("/", :full) ) do |task| #, params - v = Validation::Validation.create :validation_type => "test_set_validation", - :model_uri => params[:model_uri], - :test_dataset_uri => params[:test_dataset_uri], - :prediction_feature => params[:prediction_feature] - v.subjectid = @subjectid - v.validate_model( task ) - v.validation_uri + + #get '/validation/crossvalidation/:id/validations' do + # $logger.info "get all validations for crossvalidation with id "+params[:id].to_s + # begin + # crossvalidation = Validation::Crossvalidation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." + # end + # content_type "text/uri-list" + # Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ).collect{ |v| v.validation_uri.to_s }.join("\n")+"\n" + #end + + #get '/validation/crossvalidation/:id/predictions' do + # $logger.info "get predictions for crossvalidation with id "+params[:id].to_s + # begin + # #crossvalidation = Validation::Crossvalidation.find(params[:id]) + # crossvalidation = Validation::Crossvalidation[params[:id]] + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Crossvalidation '#{params[:id]}' not found." + # end + # raise OpenTox::BadRequestError.new "Crossvalidation '"+params[:id].to_s+"' not finished" unless crossvalidation.finished + # + # content_type "application/x-yaml" + # validations = Validation::Validation.find( :crossvalidation_id => params[:id], :validation_type => "crossvalidation" ) + # p = Lib::OTPredictions.to_array( validations.collect{ |v| v.compute_validation_stats_with_model(nil, true) } ).to_yaml + # + # case request.env['HTTP_ACCEPT'].to_s + # when /text\/html/ + # content_type "text/html" + # description = + # "The crossvalidation predictions as (yaml-)array." + # related_links = + # "All crossvalidations: "+url_for("/validation/crossvalidation",:full)+"\n"+ + # "Correspoding crossvalidation: "+url_for("/validation/crossvalidation/"+params[:id],:full) + # OpenTox.text_to_html p,@subjectid, related_links, description + # else + # content_type "text/x-yaml" + # p + # end + #end + + get '/validation/?' do + + $logger.info "list all validations, params: "+params.inspect+" #{Validation::Validation}" + uri_list = Lib::OhmUtil.find( Validation::Validation, params ).sort.collect{|v| v.validation_uri}.join("\n") + "\n" + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "To perform a validation:\n"+ + "* "+url_for("/validation/test_set_validation",:full)+"\n"+ + "* "+url_for("/validation/training_test_validation",:full)+"\n"+ + "* "+url_for("/validation/bootstrapping",:full)+"\n"+ + "* "+url_for("/validation/training_test_split",:full)+"\n"+ + "* "+url_for("/validation/crossvalidation",:full)+"\n"+ + "Validation reporting: "+url_for("/validation/report",:full)+"\n"+ + "REACH relevant reporting: "+url_for("/validation/reach_report",:full)+"\n"+ + "Examples for using this service: "+url_for("/validation/examples",:full)+"\n" + description = + "A validation web service for the OpenTox project ( http://opentox.org ).\n"+ + "In the root directory (this is where you are now), a list of all validation resources is returned." + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description + else + content_type "text/uri-list" + uri_list + end end - return_task(task) - else - raise OpenTox::BadRequestError.new "illegal parameters, pls specify model_uri and test_dataset_uri\n"+ - "params given: "+params.inspect - end -end - -get '/test_set_validation' do - LOGGER.info "list all test-set-validations, params: "+params.inspect - - #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" - uri_list = Validation::Validation.find(:validation_type => "test_set_validation").sort.collect{|v| v.validation_uri}.join("\n") + "\n" - - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "All validations: "+url_for("/",:full)+"\n"+ - "Validation reports: "+url_for("/report/validation",:full) - description = - "A list of all test-set-validations.\n"+ - "To perform a test-set-validation use the POST method." - post_command = OpenTox::PostCommand.new request.url,"Perform test-set-validation" - post_command.attributes << OpenTox::PostAttribute.new("model_uri") - post_command.attributes << OpenTox::PostAttribute.new("test_dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature",false,nil,"Default is 'dependentVariables' of the model.") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end -end - -post '/training_test_validation/?' do - LOGGER.info "creating training-test-validation "+params.inspect - if params[:algorithm_uri].to_s.size>0 and params[:training_dataset_uri].to_s.size>0 and - params[:test_dataset_uri].to_s.size>0 and params[:prediction_feature].to_s.size>0 and params[:model_uri].to_s.size==0 - task = OpenTox::Task.create( "Perform training-test-validation", url_for("/", :full) ) do |task| #, params - v = Validation::Validation.create :validation_type => "training_test_validation", - :algorithm_uri => params[:algorithm_uri], - :algorithm_params => params[:algorithm_params], - :training_dataset_uri => params[:training_dataset_uri], - :test_dataset_uri => params[:test_dataset_uri], - :prediction_feature => params[:prediction_feature] - v.subjectid = @subjectid - v.validate_algorithm( task ) - v.validation_uri + + post '/validation/?' do + raise OpenTox::BadRequestError.new "Post not supported, to perfom a validation use '/test_set_validation', '/training_test_validation', 'bootstrapping', 'training_test_split'" end - return_task(task) - else - raise OpenTox::BadRequestError.new "illegal parameters, pls specify algorithm_uri, training_dataset_uri, test_dataset_uri, prediction_feature\n"+ - "params given: "+params.inspect - end -end - -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" - uri_list = Validation::Validation.find(:validation_type => "training_test_validation").sort.collect{|v| v.validation_uri}.join("\n") + "\n" - - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "All validations: "+url_for("/",:full)+"\n"+ - "Validation reports: "+url_for("/report/validation",:full) - description = - "A list of all training-test-validations.\n"+ - "To perform a training-test-validation use the POST method." - post_command = OpenTox::PostCommand.new request.url,"Perform training-test-validation" - post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") - post_command.attributes << OpenTox::PostAttribute.new("training_dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("test_dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") - post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end -end - -post '/bootstrapping' do - LOGGER.info "performing bootstrapping validation "+params.inspect - raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 - task = OpenTox::Task.create( "Perform bootstrapping validation", url_for("/bootstrapping", :full) ) do |task| #, params - params.merge!( Validation::Util.bootstrapping( params[:dataset_uri], - params[:prediction_feature], @subjectid, - params[:random_seed], OpenTox::SubTask.create(task,0,33)) ) - LOGGER.info "params after bootstrapping: "+params.inspect - v = Validation::Validation.create :validation_type => "bootstrapping", - :prediction_feature => params[:prediction_feature], - :algorithm_uri => params[:algorithm_uri], - :algorithm_params => params[:algorithm_params], - :training_dataset_uri => params[:training_dataset_uri], - :test_dataset_uri => params[:test_dataset_uri] - v.subjectid = @subjectid - v.validate_algorithm( OpenTox::SubTask.create(task,33,100)) - v.validation_uri - end - return_task(task) -end - -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" - uri_list = Validation::Validation.find(:validation_type => "bootstrapping").sort.collect{|v| v.validation_uri}.join("\n") + "\n" - - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "All validations: "+url_for("/",:full)+"\n"+ - "Validation reports: "+url_for("/report/validation",:full) - description = - "A list of all bootstrapping-validations.\n\n"+ - "Bootstrapping performs sampling with replacement to create a training dataset and test dataset from the orignial dataset.\n"+ - "Subsequently, a model is built with the training dataset and validated on the test-dataset.\n\n"+ - "Quote from R Kohavi - A study of cross-validation and bootstrap for accuracy estimation and model selection,\n"+ - "International joint Conference on artificial intelligence, 1995:\n"+ - "'Given a dataset of size n, a bootstrap sample is created by sampling n instances uniformly from the data (with replacement).\n"+ - " Since the dataset is sampled with replacement, the probability of any given instance not being chosen after n samples is (1 - 1/n)^n = e^-1 = 0.368;\n"+ - " the expected number of distinct instances from the original dataset appearing in the test set is thus 0.632n.'\n\n"+ - "To perform a bootstrapping-validation use the POST method." - post_command = OpenTox::PostCommand.new request.url,"Perform bootstrapping-validation" - post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") - post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") - post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") - post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end -end - -post '/training_test_split' do - LOGGER.info "creating training test split "+params.inspect - raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 - raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 - check_stratified(params) - task = OpenTox::Task.create( "Perform training test split validation", url_for("/training_test_split", :full) ) do |task| #, params - params.merge!( Validation::Util.train_test_dataset_split(params[:dataset_uri], (params[:stratified].to_s=~/true/ ? params[:prediction_feature] : nil), - @subjectid, params[:stratified], params[:split_ratio], params[:random_seed], OpenTox::SubTask.create(task,0,33))) - v = Validation::Validation.create :validation_type => "training_test_split", - :training_dataset_uri => params[:training_dataset_uri], - :test_dataset_uri => params[:test_dataset_uri], - :prediction_feature => params[:prediction_feature], - :algorithm_uri => params[:algorithm_uri], - :algorithm_params => params[:algorithm_params] - v.subjectid = @subjectid - v.validate_algorithm( OpenTox::SubTask.create(task,33,100)) - v.validation_uri - end - return_task(task) - -end - -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" - uri_list = Validation::Validation.find(:validation_type => "training_test_split").sort.collect{|v| v.validation_uri}.join("\n") + "\n" - - if request.env['HTTP_ACCEPT'] =~ /text\/html/ - related_links = - "All validations: "+url_for("/",:full)+"\n"+ - "Validation reports: "+url_for("/report/validation",:full) - description = - "A list of all training-test-split-validations.\n"+ - "To perform a training-test-split-validation use the POST method." - post_command = OpenTox::PostCommand.new request.url,"Perform training-test-split-validation" - post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") - post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") - post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") - post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") - post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") - post_command.attributes << OpenTox::PostAttribute.new("split_ratio",false,"0.66","A split ratio of 0.66 implies that two thirds of the compounds are used for training.") - content_type "text/html" - OpenTox.text_to_html uri_list,@subjectid,related_links,description,post_command - else - content_type "text/uri-list" - uri_list - end -end - -post '/cleanup/?' do - LOGGER.info "validation cleanup, starting..." - content_type "text/uri-list" - deleted = [] - Validation::Validation.all.collect.delete_if{|val| val.finished}.each do |val| - if OpenTox::Authorization.authorized?(val.validation_uri,"DELETE",@subjectid) - LOGGER.debug "delete val with id:"+val.id.to_s+", finished is false" - deleted << val.validation_uri - val.subjectid = @subjectid - val.delete_validation - sleep 1 if AA_SERVER + + post '/validation/test_set_validation' do + $logger.info "creating test-set-validation "+params.inspect + if params[:model_uri].to_s.size>0 and params[:test_dataset_uri].to_s.size>0 and + params[:training_dataset_uri].to_s.size==0 and params[:algorithm_uri].to_s.size==0 + task = OpenTox::Task.run( "Perform test-set-validation", url_for("/validation/", :full) ) do |task| #, params + v = Validation::Validation.create :validation_type => "test_set_validation", + :model_uri => params[:model_uri], + :test_dataset_uri => params[:test_dataset_uri], + :prediction_feature => params[:prediction_feature] + v.subjectid = @subjectid + v.validate_model( task ) + v.validation_uri + end + return_task(task) + else + raise OpenTox::BadRequestError.new "illegal parameters, pls specify model_uri and test_dataset_uri\n"+ + "params given: "+params.inspect + end end - end - LOGGER.info "validation cleanup, deleted "+deleted.size.to_s+" validations" - deleted.join("\n")+"\n" -end - -post '/cleanup_datasets/?' do - LOGGER.info "dataset cleanup, starting..." - content_type "text/uri-list" - used_datasets = Set.new - Validation::Crossvalidation.all.each do |cv| - used_datasets << cv.dataset_uri - end - Validation::Validation.all.each do |val| - used_datasets << val.training_dataset_uri - used_datasets << val.test_dataset_uri - used_datasets << val.prediction_dataset_uri - end - deleted = [] - OpenTox::Dataset.all.each do |d| - if !used_datasets.include?(d.uri) and OpenTox::Authorization.authorized?(d.uri,"DELETE",@subjectid) - deleted << d.uri - d.delete(@subjectid) - sleep 1 if AA_SERVER + + get '/validation/test_set_validation' do + $logger.info "list all test-set-validations, params: "+params.inspect + + #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" + uri_list = Validation::Validation.find(:validation_type => "test_set_validation").sort.collect{|v| v.validation_uri}.join("\n") + "\n" + + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "All validations: "+url_for("/validation/",:full)+"\n"+ + "Validation reports: "+url_for("/validation/report/validation",:full) + description = + "A list of all test-set-validations.\n"+ + "To perform a test-set-validation use the POST method." + # post_command = OpenTox::PostCommand.new request.url,"Perform test-set-validation" + # post_command.attributes << OpenTox::PostAttribute.new("model_uri") + # post_command.attributes << OpenTox::PostAttribute.new("test_dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature",false,nil,"Default is 'dependentVariables' of the model.") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end end - end - LOGGER.info "dataset cleanup, deleted "+deleted.size.to_s+" datasets" - deleted.join("\n")+"\n" -end - -post '/plain_training_test_split' do - LOGGER.info "creating pure training test split "+params.inspect - raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri] - check_stratified(params) - task = OpenTox::Task.create( "Create data-split", url_for("/plain_training_test_split", :full) ) do |task| - result = Validation::Util.train_test_dataset_split(params[:dataset_uri], params[:prediction_feature], @subjectid, - params[:stratified], params[:split_ratio], params[:random_seed], task) - content_type "text/uri-list" - result[:training_dataset_uri]+"\n"+result[:test_dataset_uri]+"\n" - end - return_task(task) -end - -post '/validate_datasets' do - task = OpenTox::Task.create( "Perform dataset validation", url_for("/validate_datasets", :full) ) do |task| #, params - LOGGER.info "validating values "+params.inspect - raise OpenTox::BadRequestError.new "test_dataset_uri missing" unless params[:test_dataset_uri] - raise OpenTox::BadRequestError.new "prediction_datset_uri missing" unless params[:prediction_dataset_uri] - params[:validation_type] = "validate_datasets" - - if params[:model_uri] - raise OpenTox::BadRequestError.new "please specify 'model_uri' or set either 'classification' or 'regression' flag" if params[:classification] or params[:regression] - v = Validation::Validation.create params - v.subjectid = @subjectid - v.compute_validation_stats_with_model(nil,false,task) - else - raise OpenTox::BadRequestError.new "please specify 'model_uri' or 'prediction_feature'" unless params[:prediction_feature] - raise OpenTox::BadRequestError.new "please specify 'model_uri' or 'predicted_variable'" unless params[:predicted_variable] - raise OpenTox::BadRequestError.new "please specify 'model_uri' or set either 'classification' or 'regression' flag" unless - params[:classification] or params[:regression] - predicted_variable = params.delete("predicted_variable") - predicted_confidence = params.delete("predicted_confidence") - feature_type = "classification" if params.delete("classification")!=nil - feature_type = "regression" if params.delete("regression")!=nil - v = Validation::Validation.create params - v.subjectid = @subjectid - v.compute_prediction_data(feature_type,predicted_variable,predicted_confidence,v.prediction_feature,nil,task) - v.compute_validation_stats()#feature_type,predicted_variable,predicted_confidence,nil,nil,false,task) + + post '/validation/training_test_validation/?' do + $logger.info "creating training-test-validation "+params.inspect + if params[:algorithm_uri].to_s.size>0 and params[:training_dataset_uri].to_s.size>0 and + params[:test_dataset_uri].to_s.size>0 and params[:prediction_feature].to_s.size>0 and params[:model_uri].to_s.size==0 + task = OpenTox::Task.run( "Perform training-test-validation", url_for("/validation/", :full) ) do |task| #, params + v = Validation::Validation.create :validation_type => "training_test_validation", + :algorithm_uri => params[:algorithm_uri], + :algorithm_params => params[:algorithm_params], + :training_dataset_uri => params[:training_dataset_uri], + :test_dataset_uri => params[:test_dataset_uri], + :prediction_feature => params[:prediction_feature] + v.subjectid = @subjectid + v.validate_algorithm( task ) + v.validation_uri + end + return_task(task) + else + raise OpenTox::BadRequestError.new "illegal parameters, pls specify algorithm_uri, training_dataset_uri, test_dataset_uri, prediction_feature\n"+ + "params given: "+params.inspect + end end - v.validation_uri - end - return_task(task) -end - -get '/:id/probabilities' do - LOGGER.info "get validation probabilities "+params.inspect - - begin - validation = Validation::Validation.get(params[:id]) - rescue ActiveRecord::RecordNotFound => ex - raise OpenTox::NotFoundError.new("Validation '#{params[:id]}' not found.") - end - validation.subjectid = @subjectid - raise OpenTox::BadRequestError.new("Validation '"+params[:id].to_s+"' not finished") unless validation.finished - raise OpenTox::BadRequestError.new("Missing params, plz give confidence and prediction") unless params[:confidence] and params[:prediction] - props = validation.probabilities(params[:confidence].to_s.to_f,params[:prediction].to_s) - content_type "text/x-yaml" - props.to_yaml -end - - -#get '/:id/predictions' do -# LOGGER.info "get validation predictions "+params.inspect -# begin -# #validation = Validation::Validation.find(params[:id]) -# validation = Validation::Validation.get(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." -# end -# raise OpenTox::BadRequestError.new "Validation '"+params[:id].to_s+"' not finished" unless validation.finished -# p = validation.compute_validation_stats_with_model(nil, true) -# case request.env['HTTP_ACCEPT'].to_s -# when /text\/html/ -# content_type "text/html" -# description = -# "The validation predictions as (yaml-)array." -# related_links = -# "All validations: "+url_for("/",:full)+"\n"+ -# "Correspoding validation: "+url_for("/"+params[:id],:full) -# OpenTox.text_to_html p.to_array.to_yaml,@subjectid, related_links, description -# else -# content_type "text/x-yaml" -# p.to_array.to_yaml -# end -#end - -#get '/:id/:attribute' do -# LOGGER.info "access validation attribute "+params.inspect -# begin -# validation = Validation::Validation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." -# end -# begin -# raise unless validation.attribute_loaded?(params[:attribute]) -# rescue -# raise OpenTox::BadRequestError.new "Not a validation attribute: "+params[:attribute].to_s -# end -# content_type "text/plain" -# return validation.send(params[:attribute]) -#end - -get '/:id' do - LOGGER.info "get validation with id "+params[:id].to_s+" '"+request.env['HTTP_ACCEPT'].to_s+"'" -# begin - #validation = Validation::Validation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." -# end - validation = Validation::Validation[params[:id]] - raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation - - case request.env['HTTP_ACCEPT'].to_s - when "application/rdf+xml" - content_type "application/rdf+xml" - validation.to_rdf - when /text\/html/ - content_type "text/html" - description = - "A validation resource." - related_links = - "Search for corresponding report: "+url_for("/report/validation?validation="+validation.validation_uri,:full)+"\n"+ - "Get validation predictions: "+url_for("/"+params[:id]+"/predictions",:full)+"\n"+ - "All validations: "+url_for("/",:full)+"\n"+ - "All validation reports: "+url_for("/report/validation",:full) - OpenTox.text_to_html validation.to_rdf_yaml,@subjectid,related_links,description - when "application/serialize" - content_type "application/serialize" - validation.inspect # to load all the stuff - validation.to_yaml - else #default is yaml - content_type "application/x-yaml" - validation.to_rdf_yaml - end -end + + get '/validation/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" + uri_list = Validation::Validation.find(:validation_type => "training_test_validation").sort.collect{|v| v.validation_uri}.join("\n") + "\n" + + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "All validations: "+url_for("/validation/",:full)+"\n"+ + "Validation reports: "+url_for("/validation/report/validation",:full) + description = + "A list of all training-test-validations.\n"+ + "To perform a training-test-validation use the POST method." + # post_command = OpenTox::PostCommand.new request.url,"Perform training-test-validation" + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") + # post_command.attributes << OpenTox::PostAttribute.new("training_dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("test_dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end + end + + post '/validation/bootstrapping' do + $logger.info "performing bootstrapping validation "+params.inspect + raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 + task = OpenTox::Task.run( "Perform bootstrapping validation", url_for("/validation/bootstrapping", :full) ) do |task| #, params + params.merge!( Validation::Util.bootstrapping( params[:dataset_uri], + params[:prediction_feature], @subjectid, + params[:random_seed], OpenTox::SubTask.create(task,0,33)) ) + $logger.info "params after bootstrapping: "+params.inspect + v = Validation::Validation.create :validation_type => "bootstrapping", + :prediction_feature => params[:prediction_feature], + :algorithm_uri => params[:algorithm_uri], + :algorithm_params => params[:algorithm_params], + :training_dataset_uri => params[:training_dataset_uri], + :test_dataset_uri => params[:test_dataset_uri] + v.subjectid = @subjectid + v.validate_algorithm( OpenTox::SubTask.create(task,33,100)) + v.validation_uri + end + return_task(task) + end + + get '/validation/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" + uri_list = Validation::Validation.find(:validation_type => "bootstrapping").sort.collect{|v| v.validation_uri}.join("\n") + "\n" + + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "All validations: "+url_for("/validation/",:full)+"\n"+ + "Validation reports: "+url_for("/validation/report/validation",:full) + description = + "A list of all bootstrapping-validations.\n\n"+ + "Bootstrapping performs sampling with replacement to create a training dataset and test dataset from the orignial dataset.\n"+ + "Subsequently, a model is built with the training dataset and validated on the test-dataset.\n\n"+ + "Quote from R Kohavi - A study of cross-validation and bootstrap for accuracy estimation and model selection,\n"+ + "International joint Conference on artificial intelligence, 1995:\n"+ + "'Given a dataset of size n, a bootstrap sample is created by sampling n instances uniformly from the data (with replacement).\n"+ + " Since the dataset is sampled with replacement, the probability of any given instance not being chosen after n samples is (1 - 1/n)^n = e^-1 = 0.368;\n"+ + " the expected number of distinct instances from the original dataset appearing in the test set is thus 0.632n.'\n\n"+ + "To perform a bootstrapping-validation use the POST method." + # post_command = OpenTox::PostCommand.new request.url,"Perform bootstrapping-validation" + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") + # post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") + # post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end + end + + post '/validation/training_test_split' do + $logger.info "creating training test split "+params.inspect + raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "algorithm_uri missing" unless params[:algorithm_uri].to_s.size>0 + raise OpenTox::BadRequestError.new "prediction_feature missing" unless params[:prediction_feature].to_s.size>0 + check_stratified(params) + task = OpenTox::Task.run( "Perform training test split validation", url_for("/validation/training_test_split", :full) ) do |task| #, params + #task = OpenTox::Task.create( $task[:uri], nil, RDF::DC.description => "Perform training test split validation") do |task| #, params + $logger.debug "performing train test split" + params.merge!( Validation::Util.train_test_dataset_split(url_for("/validation/training_test_split", :full), params[:dataset_uri], + (params[:stratified].to_s=~/true/ ? params[:prediction_feature] : nil), @subjectid, params[:stratified], params[:split_ratio], + params[:random_seed], OpenTox::SubTask.create(task,0,33))) + $logger.debug "creating validation" + v = Validation::Validation.create :validation_type => "training_test_split", + :training_dataset_uri => params[:training_dataset_uri], + :test_dataset_uri => params[:test_dataset_uri], + :prediction_feature => params[:prediction_feature], + :algorithm_uri => params[:algorithm_uri], + :algorithm_params => params[:algorithm_params] + v.subjectid = @subjectid + $logger.debug "created validation, validating algorithm" + v.validate_algorithm( OpenTox::SubTask.create(task,33,100)) + v.validation_uri + end + return_task(task) + + end + + get '/validation/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" + uri_list = Validation::Validation.find(:validation_type => "training_test_split").sort.collect{|v| v.validation_uri}.join("\n") + "\n" + + if request.env['HTTP_ACCEPT'] =~ /text\/html/ + related_links = + "All validations: "+url_for("/validation/",:full)+"\n"+ + "Validation reports: "+url_for("/validation/report/validation",:full) + description = + "A list of all training-test-split-validations.\n"+ + "To perform a training-test-split-validation use the POST method." + # post_command = OpenTox::PostCommand.new request.url,"Perform training-test-split-validation" + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_uri") + # post_command.attributes << OpenTox::PostAttribute.new("dataset_uri") + # post_command.attributes << OpenTox::PostAttribute.new("prediction_feature") + # post_command.attributes << OpenTox::PostAttribute.new("algorithm_params",false,nil,"Params used for model building, separate with ';', example: param1=v1;param2=v2") + # post_command.attributes << OpenTox::PostAttribute.new("random_seed",false,"1","An equal random seed value ensures the excact same random dataset split.") + # post_command.attributes << OpenTox::PostAttribute.new("split_ratio",false,"0.66","A split ratio of 0.66 implies that two thirds of the compounds are used for training.") + content_type "text/html" + OpenTox.text_to_html uri_list,@subjectid,related_links,description#,post_command + else + content_type "text/uri-list" + uri_list + end + end + + post '/validation/cleanup/?' do + $logger.info "validation cleanup, starting..." + content_type "text/uri-list" + deleted = [] + Validation::Validation.all.collect.delete_if{|val| val.finished}.each do |val| + if OpenTox::Authorization.authorized?(val.validation_uri,"DELETE",@subjectid) + $logger.debug "delete val with id:"+val.id.to_s+", finished is false" + deleted << val.validation_uri + val.subjectid = @subjectid + val.delete_validation + sleep 1 if $aa[:uri] + end + end + $logger.info "validation cleanup, deleted "+deleted.size.to_s+" validations" + deleted.join("\n")+"\n" + end + + post '/validation/cleanup_datasets/?' do + $logger.info "dataset cleanup, starting..." + content_type "text/uri-list" + used_datasets = Set.new + Validation::Crossvalidation.all.each do |cv| + used_datasets << cv.dataset_uri + end + Validation::Validation.all.each do |val| + used_datasets << val.training_dataset_uri + used_datasets << val.test_dataset_uri + used_datasets << val.prediction_dataset_uri + end + deleted = [] + OpenTox::Dataset.all.each do |d| + if !used_datasets.include?(d.uri) and OpenTox::Authorization.authorized?(d.uri,"DELETE",@subjectid) + deleted << d.uri + d.delete(@subjectid) + sleep 1 if $aa[:uri] + end + end + $logger.info "dataset cleanup, deleted "+deleted.size.to_s+" datasets" + deleted.join("\n")+"\n" + end + + post '/validation/plain_training_test_split' do + $logger.info "creating pure training test split "+params.inspect + raise OpenTox::BadRequestError.new "dataset_uri missing" unless params[:dataset_uri] + check_stratified(params) + task = OpenTox::Task.run( "Create data-split", url_for("/validation/plain_training_test_split", :full) ) do |task| + result = Validation::Util.train_test_dataset_split(url_for("/validation/plain_training_test_split", :full), params[:dataset_uri], params[:prediction_feature], + @subjectid, params[:stratified], params[:split_ratio], params[:random_seed], task) + content_type "text/uri-list" + result[:training_dataset_uri]+"\n"+result[:test_dataset_uri]+"\n" + end + return_task(task) + end + + post '/validation/validate_datasets' do + task = OpenTox::Task.run( "Perform dataset validation", url_for("/validation/validate_datasets", :full) ) do |task| #, params + $logger.info "validating values "+params.inspect + raise OpenTox::BadRequestError.new "test_dataset_uri missing" unless params[:test_dataset_uri] + raise OpenTox::BadRequestError.new "prediction_datset_uri missing" unless params[:prediction_dataset_uri] + params[:validation_type] = "validate_datasets" + + if params[:model_uri] + raise OpenTox::BadRequestError.new "please specify 'model_uri' or set either 'classification' or 'regression' flag" if params[:classification] or params[:regression] + v = Validation::Validation.create params + v.subjectid = @subjectid + v.compute_validation_stats_with_model(nil,false,task) + else + raise OpenTox::BadRequestError.new "please specify 'model_uri' or 'prediction_feature'" unless params[:prediction_feature] + raise OpenTox::BadRequestError.new "please specify 'model_uri' or 'predicted_variable'" unless params[:predicted_variable] + raise OpenTox::BadRequestError.new "please specify 'model_uri' or set either 'classification' or 'regression' flag" unless + params[:classification] or params[:regression] + predicted_variable = params.delete("predicted_variable") + predicted_confidence = params.delete("predicted_confidence") + feature_type = "classification" if params.delete("classification")!=nil + feature_type = "regression" if params.delete("regression")!=nil + v = Validation::Validation.create params + v.subjectid = @subjectid + v.compute_prediction_data(feature_type,predicted_variable,predicted_confidence,v.prediction_feature,nil,task) + v.compute_validation_stats()#feature_type,predicted_variable,predicted_confidence,nil,nil,false,task) + end + v.validation_uri + end + return_task(task) + end + + get '/validation/:id/probabilities' do + $logger.info "get validation probabilities "+params.inspect + + begin + validation = Validation::Validation[params[:id]] + rescue ActiveRecord::RecordNotFound => ex + raise OpenTox::NotFoundError.new("Validation '#{params[:id]}' not found.") + end + validation.subjectid = @subjectid + raise OpenTox::BadRequestError.new("Validation '"+params[:id].to_s+"' not finished") unless validation.finished + raise OpenTox::BadRequestError.new("Missing params, plz give confidence and prediction") unless params[:confidence] and params[:prediction] + props = validation.probabilities(params[:confidence].to_s.to_f,params[:prediction].to_s) + content_type "text/x-yaml" + props.to_yaml + end + + + #get '/validation/:id/predictions' do + # $logger.info "get validation predictions "+params.inspect + # begin + # #validation = Validation::Validation.find(params[:id]) + # validation = Validation::Validation[params[:id]] + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." + # end + # raise OpenTox::BadRequestError.new "Validation '"+params[:id].to_s+"' not finished" unless validation.finished + # p = validation.compute_validation_stats_with_model(nil, true) + # case request.env['HTTP_ACCEPT'].to_s + # when /text\/html/ + # content_type "text/html" + # description = + # "The validation predictions as (yaml-)array." + # related_links = + # "All validations: "+url_for("/validation/",:full)+"\n"+ + # "Correspoding validation: "+url_for("/validation/"+params[:id],:full) + # OpenTox.text_to_html p.to_array.to_yaml,@subjectid, related_links, description + # else + # content_type "text/x-yaml" + # p.to_array.to_yaml + # end + #end + + #get '/validation/:id/:attribute' do + # $logger.info "access validation attribute "+params.inspect + # begin + # validation = Validation::Validation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." + # end + # begin + # raise unless validation.attribute_loaded?(params[:attribute]) + # rescue + # raise OpenTox::BadRequestError.new "Not a validation attribute: "+params[:attribute].to_s + # end + # content_type "text/plain" + # return validation.send(params[:attribute]) + #end + + get '/validation/:id' do + $logger.info "get validation with id "+params[:id].to_s+" '"+request.env['HTTP_ACCEPT'].to_s+"'" + # begin + #validation = Validation::Validation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." + # end + validation = Validation::Validation[params[:id]] + raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation + + case request.env['HTTP_ACCEPT'].to_s + when "application/rdf+xml" + content_type "application/rdf+xml" + validation.to_rdf + when /text\/html/ + content_type "text/html" + description = + "A validation resource." + related_links = + "Search for corresponding report: "+url_for("/validation/report/validation?validation="+validation.validation_uri,:full)+"\n"+ + "Get validation predictions: "+url_for("/validation/"+params[:id]+"/predictions",:full)+"\n"+ + "All validations: "+url_for("/validation/",:full)+"\n"+ + "All validation reports: "+url_for("/validation/report/validation",:full) + OpenTox.text_to_html validation.to_rdf_yaml,@subjectid,related_links,description + when "application/serialize" + content_type "application/serialize" + validation.inspect # to load all the stuff + validation.to_yaml + else #default is yaml + content_type "application/x-yaml" + validation.to_rdf_yaml + end + end + + delete '/validation/:id' do + $logger.info "delete validation with id "+params[:id].to_s + # begin + #validation = Validation::Validation.find(params[:id]) + # rescue ActiveRecord::RecordNotFound => ex + # raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." + # end + validation = Validation::Validation[params[:id]] + validation.subjectid = @subjectid + raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation + content_type "text/plain" + validation.delete_validation + end -delete '/:id' do - LOGGER.info "delete validation with id "+params[:id].to_s -# begin - #validation = Validation::Validation.find(params[:id]) -# rescue ActiveRecord::RecordNotFound => ex -# raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." -# end - validation = Validation::Validation.get(params[:id]) - validation.subjectid = @subjectid - raise OpenTox::NotFoundError.new "Validation '#{params[:id]}' not found." unless validation - content_type "text/plain" - validation.delete_validation end
\ No newline at end of file diff --git a/validation/validation_format.rb b/validation/validation_format.rb index 0594629..9a969fe 100755 --- a/validation/validation_format.rb +++ b/validation/validation_format.rb @@ -1,6 +1,7 @@ require "./lib/format_util.rb" + module Validation # adding to_yaml and to_rdf functionality to validation @@ -15,16 +16,16 @@ module Validation h[p] = self.send(p.to_s) end if crossvalidation_id!=nil - cv = {:type => OT.CrossvalidationInfo} + cv = {:type => OT.CrossvalidationInfo.to_s} #skip crossvalidation_id cv[:crossvalidation_fold] = self.crossvalidation_fold - cv[:crossvalidation_uri] = self.crossvalidation_uri + cv[:crossvalidation_uri] = self.crossvalidation_uri.force_encoding("UTF-8") h[:crossvalidation_info] = cv end if classification_statistics 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 } + clazz = { :type => OT.ClassificationStatistics.to_s } VAL_CLASS_PROPS_SINGLE.each{ |p| clazz[p] = classification_statistics[p] } # transpose results per class @@ -32,7 +33,7 @@ module Validation 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) + class_values[class_value] = {:class_value => class_value, :type => OT.ClassValueStatistics.to_s} unless class_values.has_key?(class_value) map = class_values[class_value] map[p] = property_value end @@ -43,18 +44,18 @@ module Validation cells = [] raise "confusion matrix missing" unless classification_statistics[:confusion_matrix]!=nil classification_statistics[:confusion_matrix].each do |k,v| - cell = { :type => OT.ConfusionMatrixCell } + cell = { :type => OT.ConfusionMatrixCell.to_s } # key in confusion matrix is map with predicted and actual attribute k.each{ |kk,vv| cell[kk] = vv } cell[:confusion_matrix_value] = v cells.push cell end - cm = { :confusion_matrix_cell => cells, :type => OT.ConfusionMatrix } + cm = { :confusion_matrix_cell => cells, :type => OT.ConfusionMatrix.to_s } clazz[:confusion_matrix] = cm h[:classification_statistics] = clazz elsif regression_statistics - regr = {:type => OT.RegressionStatistics } + regr = {:type => OT.RegressionStatistics.to_s } VAL_REGR_PROPS.each{ |p| regr[p] = regression_statistics[p]} h[:regression_statistics] = regr end @@ -63,7 +64,7 @@ module Validation def to_rdf s = OpenTox::Serializer::Owl.new - s.add_resource(validation_uri,OT.Validation,get_content_as_hash.keys_to_rdf_format.keys_to_owl_uris) + s.add_resource(validation_uri,OT.Validation.to_s,get_content_as_hash.keys_to_rdf_format.keys_to_owl_uris) s.to_rdfxml end @@ -77,22 +78,17 @@ module Validation def get_content_as_hash h = {} - (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.find( :crossvalidation_id => self.id, :validation_type => "crossvalidation" ).each do |val| - v.push( val.validation_uri.to_s ) - end + v = Validation.find( :crossvalidation_id => self.id, :validation_type => "crossvalidation" ).collect{|val| val.validation_uri.force_encoding("UTF-8")} h[:validation_uris] = v h end def to_rdf s = OpenTox::Serializer::Owl.new - s.add_resource(crossvalidation_uri,OT.Crossvalidation,get_content_as_hash.keys_to_rdf_format.keys_to_owl_uris) + s.add_resource(crossvalidation_uri,OT.Crossvalidation.to_s,get_content_as_hash.keys_to_rdf_format.keys_to_owl_uris) s.to_rdfxml end diff --git a/validation/validation_service.rb b/validation/validation_service.rb index de583f6..4df843c 100755 --- a/validation/validation_service.rb +++ b/validation/validation_service.rb @@ -11,8 +11,15 @@ class Array # cuts an array into <num-pieces> chunks def chunk(pieces) q, r = length.divmod(pieces) - (0..pieces).map { |i| i * q + [r, i].min }.enum_cons(2) \ - .map { |a, b| slice(a...b) } + res = self.each_slice(q).collect{|a| a} + if (r!=0) + leftover = res[pieces..-1].flatten + res = res[0..(pieces-1)] + leftover.size.times do |i| + res[i] << leftover[i] + end + end + res end # shuffles the elements of an array @@ -35,7 +42,7 @@ module Validation def self.from_cv_statistics( cv_id, subjectid=nil, waiting_task=nil ) v = Validation.find( :crossvalidation_id => cv_id, :validation_type => "crossvalidation_statistics" ).first unless v - crossvalidation = Crossvalidation.get(cv_id) + crossvalidation = Crossvalidation[cv_id] raise OpenTox::NotFoundError.new "Crossvalidation '#{cv_id}' not found." unless crossvalidation raise OpenTox::BadRequestError.new "Crossvalidation '"+cv_id.to_s+"' not finished" unless crossvalidation.finished vals = Validation.find( :crossvalidation_id => cv_id, :validation_type => "crossvalidation" ).collect{|x| x} @@ -86,12 +93,12 @@ module Validation Thread.new do # do deleting in background to not cause a timeout to_delete.each do |attr| uri = self.send(attr) - LOGGER.debug "also deleting "+attr.to_s+" : "+uri.to_s if uri + $logger.debug "also deleting "+attr.to_s+" : "+uri.to_s if uri begin OpenTox::RestClientWrapper.delete(uri, :subjectid => subjectid) if uri - sleep 1 if AA_SERVER # wait a second to not stress the a&a service too much + sleep 1 if $aa[:uri] # wait a second to not stress the a&a service too much rescue => ex - LOGGER.warn "could not delete "+uri.to_s+" : "+ex.message.to_s + $logger.warn "could not delete "+uri.to_s+" : "+ex.message.to_s end end end @@ -101,9 +108,9 @@ module Validation Thread.new do begin res = OpenTox::Authorization.delete_policies_from_uri(validation_uri, subjectid) - LOGGER.debug "Deleted validation policy: #{res}" + $logger.debug "Deleted validation policy: #{res}" rescue - LOGGER.warn "Policy delete error for validation: #{validation_uri}" + $logger.warn "Policy delete error for validation: #{validation_uri}" end end end @@ -120,14 +127,21 @@ module Validation self.algorithm_params.split(";").each do |alg_params| alg_param = alg_params.split("=",2) raise OpenTox::BadRequestError.new "invalid algorithm param: '"+alg_params.to_s+"'" unless alg_param.size==2 or alg_param[0].to_s.size<1 or alg_param[1].to_s.size<1 - LOGGER.warn "algorihtm param contains empty space, encode? "+alg_param[1].to_s if alg_param[1] =~ /\s/ + $logger.warn "algorihtm param contains empty space, encode? "+alg_param[1].to_s if alg_param[1] =~ /\s/ params[alg_param[0].to_sym] = alg_param[1] end end - algorithm = OpenTox::Algorithm::Generic.new(algorithm_uri) - params[:subjectid] = subjectid - self.model_uri = algorithm.run(params, OpenTox::SubTask.create(task, 0, 33)) + #$logger.warn "running alg" + #$logger.warn algorithm_uri + #$logger.warn params.inspect + self.model_uri = OpenTox::Algorithm.new(algorithm_uri).run(params) + #$logger.warn "algorithm run finished" + #$logger.warn "#{result}" + + #algorithm = OpenTox::Algorithm::Generic.new(algorithm_uri) + #params[:subjectid] = subjectid + #self.model_uri = algorithm.run(params, OpenTox::SubTask.create(task, 0, 33)) #model = OpenTox::Model::PredictionModel.build(algorithm_uri, params, # OpenTox::SubTask.create(task, 0, 33) ) @@ -150,28 +164,27 @@ module Validation def validate_model( task=nil ) raise "validation_type missing" unless self.validation_type - LOGGER.debug "validating model '"+self.model_uri+"'" + $logger.debug "validating model '"+self.model_uri+"'" #model = OpenTox::Model::PredictionModel.find(self.model_uri) #raise OpenTox::NotFoundError.new "model not found: "+self.model_uri.to_s unless model - model = OpenTox::Model::Generic.find(self.model_uri, self.subjectid) + model = OpenTox::Model.new(self.model_uri, self.subjectid) + model.get unless self.algorithm_uri - self.algorithm_uri = model.metadata[OT.algorithm] + self.algorithm_uri = model.metadata[OT.algorithm.to_s] end if self.prediction_feature.to_s.size==0 - dependentVariables = model.metadata[OT.dependentVariables] - raise OpenTox::NotFoundError.new "model has no dependentVariables specified, please give prediction_feature for model validation" unless dependentVariables - self.prediction_feature = model.metadata[OT.dependentVariables] + dependentVariables = model.metadata[OT.dependentVariables.to_s] + raise "model has no dependentVariables specified, please give prediction_feature for model validation" unless dependentVariables + self.prediction_feature = model.metadata[OT.dependentVariables.to_s] end prediction_dataset_uri = "" benchmark = Benchmark.measure do #prediction_dataset_uri = model.predict_dataset(self.test_dataset_uri, OpenTox::SubTask.create(task, 0, 50)) - prediction_dataset_uri = model.run( - {:dataset_uri => self.test_dataset_uri, :subjectid => self.subjectid}, - "text/uri-list", - OpenTox::SubTask.create(task, 0, 50)) + prediction_dataset_uri = model.run({:dataset_uri => self.test_dataset_uri, :subjectid => self.subjectid}) + #"text/uri-list",OpenTox::SubTask.create(task, 0, 50)) end # self.attributes = { :prediction_dataset_uri => prediction_dataset_uri, # :real_runtime => benchmark.real } @@ -186,7 +199,7 @@ module Validation end def compute_prediction_data_with_cv(cv_vals, waiting_task=nil) - models = cv_vals.collect{|v| OpenTox::Model::Generic.find(v.model_uri, subjectid)} + models = cv_vals.collect{|v| m = OpenTox::Model.new(v.model_uri, subjectid); m.get; m} feature_type = models.first.feature_type(subjectid) test_dataset_uris = cv_vals.collect{|v| v.test_dataset_uri} prediction_feature = cv_vals.first.prediction_feature @@ -200,13 +213,15 @@ module Validation end def compute_prediction_data_with_model(model=nil, task=nil) - model = OpenTox::Model::Generic.find(self.model_uri, self.subjectid) if model==nil and self.model_uri - raise OpenTox::NotFoundError.new "model not found: "+self.model_uri.to_s unless model - + #model = OpenTox::Model::Generic.find(self.model_uri, self.subjectid) if model==nil and self.model_uri + #raise OpenTox::NotFoundError.new "model not found: "+self.model_uri.to_s unless model + model = OpenTox::Model.new(self.model_uri, self.subjectid) if model==nil + model.get + feature_type = model.feature_type(self.subjectid) - dependentVariables = model.metadata[OT.dependentVariables] + dependentVariables = model.metadata[OT.dependentVariables.to_s] prediction_feature = self.prediction_feature ? nil : dependentVariables - algorithm_uri = self.algorithm_uri ? nil : model.metadata[OT.algorithm] + algorithm_uri = self.algorithm_uri ? nil : model.metadata[OT.algorithm.to_s] predicted_variable = model.predicted_variable(self.subjectid) predicted_confidence = model.predicted_confidence(self.subjectid) raise "cannot determine whether model '"+model.uri.to_s+"' performs classification or regression: '#{feature_type}', "+ @@ -222,7 +237,7 @@ module Validation self.prediction_feature = prediction_feature if self.prediction_feature==nil && prediction_feature self.algorithm_uri = algorithm_uri if self.algorithm_uri==nil && algorithm_uri - LOGGER.debug "computing prediction stats" + $logger.debug "computing prediction stats" p_data = Lib::PredictionData.create( feature_type, self.test_dataset_uri, self.prediction_feature, self.prediction_dataset_uri, predicted_variable, predicted_confidence, self.subjectid, @@ -307,14 +322,14 @@ module Validation def clean_loo_files( delete_feature_datasets ) Validation.find( :crossvalidation_id => self.id, :validation_type => "crossvalidation" ).each do |v| - LOGGER.debug "loo-cleanup> delete training dataset "+v.training_dataset_uri + $logger.debug "loo-cleanup> delete training dataset "+v.training_dataset_uri OpenTox::RestClientWrapper.delete v.training_dataset_uri,subjectid if (delete_feature_datasets) begin model = OpenTox::Model::Generic.find(v.model_uri) - if model.metadata[OT.featureDataset] - LOGGER.debug "loo-cleanup> delete feature dataset "+model.metadata[OT.featureDataset] - OpenTox::RestClientWrapper.delete model.metadata[OT.featureDataset],subjectid + if model.metadata[OT.featureDataset.to_s] + $logger.debug "loo-cleanup> delete feature dataset "+model.metadata[OT.featureDataset.to_s] + OpenTox::RestClientWrapper.delete model.metadata[OT.featureDataset.to_s],subjectid end rescue end @@ -328,9 +343,9 @@ module Validation Thread.new do # do deleting in background to not cause a timeout validations.each do |v| v.subjectid = self.subjectid - LOGGER.debug "deleting cv-validation "+v.validation_uri.to_s + $logger.debug "deleting cv-validation "+v.validation_uri.to_s v.delete_validation - sleep 1 if AA_SERVER # wait a second to not stress the a&a service too much + sleep 1 if $aa[:uri] # wait a second to not stress the a&a service too much end end self.delete @@ -338,9 +353,9 @@ module Validation Thread.new do begin res = OpenTox::Authorization.delete_policies_from_uri(crossvalidation_uri, subjectid) - LOGGER.debug "Deleted crossvalidation policy: #{res}" + $logger.debug "Deleted crossvalidation policy: #{res}" rescue - LOGGER.warn "Policy delete error for crossvalidation: #{crossvalidation_uri}" + $logger.warn "Policy delete error for crossvalidation: #{crossvalidation_uri}" end end end @@ -370,7 +385,7 @@ module Validation # executes the cross-validation (build models and validates them) def perform_cv_validations( task=nil ) - LOGGER.debug "perform cv validations" + $logger.debug "perform cv validations" i = 0 task_step = 100 / self.num_folds.to_f; @tmp_validations.each do | val | @@ -380,7 +395,7 @@ module Validation raise "validation '"+validation.validation_uri+"' for crossvaldation could not be finished" unless validation.finished i += 1 - LOGGER.debug "fold "+i.to_s+" done: "+validation.validation_uri.to_s + $logger.debug "fold "+i.to_s+" done: "+validation.validation_uri.to_s end # self.attributes = { :finished => true } @@ -405,7 +420,7 @@ module Validation (cv.prediction_feature && cv.prediction_feature != self.prediction_feature)) } cvs.each do |cv| - next if AA_SERVER and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",self.subjectid) + next if $aa[:uri] and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",self.subjectid) tmp_val = [] Validation.find( :crossvalidation_id => cv.id, :validation_type => "crossvalidation" ).each do |v| break unless @@ -425,7 +440,7 @@ module Validation end if tmp_val.size == self.num_folds.to_i @tmp_validations = tmp_val - LOGGER.debug "copied dataset uris from cv "+cv.crossvalidation_uri.to_s #+":\n"+tmp_val.inspect + $logger.debug "copied dataset uris from cv "+cv.crossvalidation_uri.to_s #+":\n"+tmp_val.inspect return true end end @@ -435,7 +450,7 @@ module Validation # creates cv folds (training and testdatasets) # stores uris in validation objects def create_new_cv_datasets( task = nil ) - LOGGER.debug "creating datasets for crossvalidation" + $logger.debug "creating datasets for crossvalidation" orig_dataset = Lib::DatasetCache.find(self.dataset_uri,self.subjectid) raise OpenTox::NotFoundError.new "Dataset not found: "+self.dataset_uri.to_s unless orig_dataset @@ -451,7 +466,7 @@ module Validation shuffled_compound_indices = (0..(orig_dataset.compounds.size-1)).to_a.shuffle( self.random_seed ) end split_compound_indices = shuffled_compound_indices.chunk( self.num_folds.to_i ) - LOGGER.debug "cv: num instances for each fold: "+split_compound_indices.collect{|c| c.size}.join(", ") + $logger.debug "cv: num instances for each fold: "+split_compound_indices.collect{|c| c.size}.join(", ") self.num_folds.to_i.times do |n| test_compound_indices = [] @@ -471,14 +486,12 @@ module Validation "', is '"+train_compound_indices.size.to_s+"'" unless shuffled_compound_indices.size - test_compound_indices.size == train_compound_indices.size datasetname = 'dataset fold '+(n+1).to_s+' of '+self.num_folds.to_s meta[DC.title] = "training "+datasetname - LOGGER.debug "training set: "+datasetname+"_train, compounds: "+train_compound_indices.size.to_s - train_dataset_uri = orig_dataset.split( train_compound_indices, orig_dataset.features.keys, - meta, self.subjectid ).uri + $logger.debug "training set: "+datasetname+"_train, compounds: "+train_compound_indices.size.to_s + train_dataset_uri = orig_dataset.split( train_compound_indices, orig_dataset.features, meta, self.subjectid ).uri train_dataset_uris << train_dataset_uri meta[DC.title] = "test "+datasetname - LOGGER.debug "test set: "+datasetname+"_test, compounds: "+test_compound_indices.size.to_s - test_dataset_uri = orig_dataset.split( test_compound_indices, orig_dataset.features.keys, - meta, self.subjectid ).uri + $logger.debug "test set: "+datasetname+"_test, compounds: "+test_compound_indices.size.to_s + test_dataset_uri = orig_dataset.split( test_compound_indices, orig_dataset.features, meta, self.subjectid ).uri test_dataset_uris << test_dataset_uri end when /true|super/ @@ -530,7 +543,7 @@ module Validation "' not found in dataset, features are: \n"+ orig_dataset.features.inspect unless orig_dataset.features.include?(prediction_feature) else - LOGGER.warn "no prediciton feature given, all features included in test dataset" + $logger.warn "no prediciton feature given, all features included in test dataset" end compound_indices = (0..(orig_dataset.compounds.size-1)).to_a @@ -553,33 +566,34 @@ module Validation end end - LOGGER.debug "bootstrapping on dataset "+orig_dataset_uri+ + $logger.debug "bootstrapping on dataset "+orig_dataset_uri+ " into training ("+training_compound_indices.size.to_s+") and test ("+test_compound_indices.size.to_s+")"+ ", duplicates in training dataset: "+test_compound_indices.size.to_s task.progress(33) if task result = {} - result[:training_dataset_uri] = orig_dataset.split( training_compound_indices, - orig_dataset.features.keys, + result[:training_dataset_uri] = orig_dataset.split( training_compound_indices, orig_dataset.features, { DC.title => "Bootstrapping training dataset of "+orig_dataset.title.to_s, - DC.creator => $url_provider.url_for('/bootstrapping',:full) }, + DC.creator => $url_provider.url_for('/validation/bootstrapping',:full) }, subjectid ).uri task.progress(66) if task - result[:test_dataset_uri] = orig_dataset.split( test_compound_indices, - orig_dataset.features.keys, + result[:test_dataset_uri] = orig_dataset.split( test_compound_indices, orig_dataset.features, { DC.title => "Bootstrapping test dataset of "+orig_dataset.title.to_s, - DC.creator => $url_provider.url_for('/bootstrapping',:full)} , + DC.creator => $url_provider.url_for('/validation/bootstrapping',:full)} , subjectid ).uri task.progress(100) if task - LOGGER.debug "bootstrapping done, training dataset: '"+result[:training_dataset_uri].to_s+"', test dataset: '"+result[:test_dataset_uri].to_s+"'" + $logger.debug "bootstrapping done, training dataset: '"+result[:training_dataset_uri].to_s+"', test dataset: '"+result[:test_dataset_uri].to_s+"'" return result end # 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, stratified="false", split_ratio=nil, random_seed=nil, task=nil ) + def self.train_test_dataset_split( creator_uri, orig_dataset_uri, prediction_feature, subjectid, stratified="false", split_ratio=nil, random_seed=nil, task=nil ) + + $logger.debug "train test split" + split_ratio=0.67 unless split_ratio split_ratio = split_ratio.to_f random_seed=1 unless random_seed @@ -588,22 +602,21 @@ module Validation raise OpenTox::NotFoundError.new "Split ratio invalid: "+split_ratio.to_s unless split_ratio and split_ratio=split_ratio.to_f raise OpenTox::NotFoundError.new "Split ratio not >0 and <1 :"+split_ratio.to_s unless split_ratio>0 && split_ratio<1 orig_dataset = Lib::DatasetCache.find orig_dataset_uri, subjectid - orig_dataset.load_all subjectid raise OpenTox::NotFoundError.new "Dataset not found: "+orig_dataset_uri.to_s unless orig_dataset if prediction_feature if stratified==/true/ raise OpenTox::NotFoundError.new "Prediction feature '"+prediction_feature.to_s+ - "' not found in dataset, features are: \n"+orig_dataset.features.keys.inspect unless orig_dataset.features.include?(prediction_feature) + "' not found in dataset, features are: \n"+orig_dataset.features.collect{|f| f.uri}.inspect unless orig_dataset.features.include?(prediction_feature) else - LOGGER.warn "prediction_feature argument is ignored for non-stratified splits" if prediction_feature + $logger.warn "prediction_feature argument is ignored for non-stratified splits" if prediction_feature prediction_feature=nil end elsif stratified==/true/ raise OpenTox::BadRequestError.new "prediction feature required for stratified splits" unless prediction_feature end - meta = { DC.creator => $url_provider.url_for('/training_test_split',:full) } + meta = { DC.creator => creator_uri } case stratified when /true|super/ @@ -622,7 +635,7 @@ module Validation split = (compound_indices.size*split_ratio).round split = [split,1].max split = [split,compound_indices.size-2].min - LOGGER.debug "splitting dataset "+orig_dataset_uri+ + $logger.debug "splitting dataset "+orig_dataset_uri+ " into train:0-"+split.to_s+" and test:"+(split+1).to_s+"-"+(compound_indices.size-1).to_s+ " (shuffled with seed "+random_seed.to_s+")" compound_indices.shuffle!( random_seed ) @@ -632,22 +645,22 @@ module Validation meta[DC.title] = "Training dataset split of "+orig_dataset.uri result = {} - train_data = orig_dataset.split( training_compound_indices, - orig_dataset.features.keys, meta, subjectid ) - raise "Train dataset num coumpounds != "+(orig_dataset.compounds.size*split_ratio).round.to_s+", instead: "+train_data.compounds.size.to_s unless - train_data.compounds.size==(orig_dataset.compounds.size*split_ratio).round + train_data = orig_dataset.split( training_compound_indices, orig_dataset.features, meta, subjectid ) + est_num_train_compounds = (orig_dataset.compounds.size*split_ratio).round + raise "Train dataset num coumpounds != #{est_num_train_compounds}, instead: "+train_data.compounds.size.to_s unless + train_data.compounds.size==est_num_train_compounds result[:training_dataset_uri] = train_data.uri task.progress(66) if task meta[DC.title] = "Test dataset split of "+orig_dataset.uri - test_data = orig_dataset.split( test_compound_indices, - orig_dataset.features.keys, meta, subjectid ) - raise "Test dataset num coumpounds != "+(orig_dataset.compounds.size*(1-split_ratio)).round.to_s+", instead: "+test_data.compounds.size.to_s unless - test_data.compounds.size==(orig_dataset.compounds.size*(1-split_ratio)).round + test_data = orig_dataset.split( test_compound_indices, orig_dataset.features, meta, subjectid ) + est_num_test_compounds = orig_dataset.compounds.size-est_num_train_compounds + raise "Test dataset num coumpounds != #{est_num_test_compounds}, instead: "+test_data.compounds.size.to_s unless + test_data.compounds.size==est_num_test_compounds result[:test_dataset_uri] = test_data.uri task.progress(100) if task - LOGGER.debug "split done, training dataset: '"+result[:training_dataset_uri].to_s+"', test dataset: '"+result[:test_dataset_uri].to_s+"'" + $logger.debug "split done, training dataset: '"+result[:training_dataset_uri].to_s+"', test dataset: '"+result[:test_dataset_uri].to_s+"'" else raise OpenTox::BadRequestError.new "stratified != false|true|super, is #{stratified}" end diff --git a/validation/validation_test.rb b/validation/validation_test.rb index 77a5415..5b658b9 100755 --- a/validation/validation_test.rb +++ b/validation/validation_test.rb @@ -1,25 +1,39 @@ +ENV['RACK_ENV'] = 'development' + require "rubygems" -require "sinatra" +require "ohm" + +SERVICE = "validation" +require 'bundler' +Bundler.require + +#exit + +#puts Ohm.connect(:thread_safe => true, :port => 6379) +#exit + +#require "rubygems" +#require "sinatra" before { - request.env['HTTP_HOST']="local-ot/validation" + request.env['HTTP_HOST']="localhost:8087/validation" request.env["REQUEST_URI"]=request.env["PATH_INFO"] } require "uri" require "yaml" -ENV['RACK_ENV'] = 'production' + require './application.rb' require 'test/unit' require 'rack/test' require './lib/test_util.rb' require './test/test_examples.rb' -LOGGER = OTLogger.new(STDOUT) -LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S " -LOGGER.formatter = Logger::Formatter.new +$logger = OTLogger.new(STDOUT) +$logger.datetime_format = "%Y-%m-%d %H:%M:%S " +$logger.formatter = Logger::Formatter.new -if AA_SERVER +if $aa[:uri] #TEST_USER = "mgtest" #TEST_PW = "mgpasswd" TEST_USER = "guest" @@ -33,13 +47,15 @@ else end #Rack::Test::DEFAULT_HOST = "local-ot" #"/validation" + +BASE = "http://localhost:8087/validation" + module Sinatra set :raise_errors, false set :show_exceptions, false module UrlForHelper - BASE = "http://local-ot/validation" def url_for url_fragment, mode=:path_only case mode when :path_only @@ -49,23 +65,131 @@ module Sinatra "#{BASE}#{url_fragment}" end end + end +$url_provider = Object.new +def $url_provider.url_for(url_fragment, mode=:path_only) + "#{BASE}#{url_fragment}" +end + class ValidationTest < Test::Unit::TestCase include Rack::Test::Methods include Lib::TestUtil + + def data_info(dataset_uri,title,feat=nil) + data = OpenTox::Dataset.find(dataset_uri) + puts "dataset: #{title}, #compounds #{data.compounds.size}, #features #{data.features.size}" + if feat + data.compounds.size.times do |c_idx| + puts "#{c_idx} #{data.compounds[c_idx]} #{feat.collect{|f| data.data_entry_value(c_idx,f)}.join(", ")}" + end + end + end def test_it - begin - $test_case = self - - post '/validate_datasets',{:test_dataset_uri=>"http://local-ot/dataset/14111", - :prediction_dataset_uri=>"http://local-ot/dataset/14113", - :prediction_feature=>"http://local-ot/dataset/14109/feature/Hamster%20Carcinogenicity", - :predicted_variable=>"http://local-ot/model/21/predicted/value", - :predicted_confidence=>"http://local-ot/model/21/predicted/confidence", - :classification=>"true"} + + + params={:validation_uris=>"http://localhost:8087/validation/crossvalidation/5"} + res = OpenTox::RestClientWrapper.post 'http://localhost:8087/validation/report/crossvalidation',params + puts res + exit + + prediction_feature = "http://localhost:8084/feature/426cf674-0019-4ec2-8c4d-9431b75e907a" + data = "http://localhost:8083/dataset/461c6ab1-272e-493f-83f7-a37e64b0f5fe"; + alg = "http://localhost:8081/algorithm/lazar" + alg_params = {:feature_generation_uri=>"http://localhost:8081/algorithm/fminer/bbrc"} + alg_params_str = "" + alg_params.each do |key,val| + alg_params_str << ";" if alg_params_str.size>0 + alg_params_str << key.to_s+"="+val + end + params={:algorithm_uri=>alg,:dataset_uri=>data, :prediction_feature=>prediction_feature, :algorithm_params=>alg_params_str, :num_folds=>3} + res = OpenTox::RestClientWrapper.post 'http://localhost:8087/validation/crossvalidation',params + puts res + exit + + params={:validation_uris=>"http://localhost:8087/validation/50"} + res = OpenTox::RestClientWrapper.post 'http://localhost:8087/validation/report/validation',params + puts res + exit + + prediction_feature = "http://localhost:8084/feature/426cf674-0019-4ec2-8c4d-9431b75e907a" + train = "http://localhost:8083/dataset/aec242bd-64c6-4fba-9277-659d1328661d"; + #data_info(train,"training",[prediction_feature]) + test = "http://localhost:8083/dataset/23ae2c24-9bff-43d0-bf6d-15f05f22241d" + #data_info(test,"test",[prediction_feature]) + alg = "http://localhost:8081/algorithm/lazar" + alg_params = {:feature_generation_uri=>"http://localhost:8081/algorithm/fminer/bbrc"} + + single_steps = false + if (single_steps) + build_model = false + if (build_model) + params = {:dataset_uri=>train, + :prediction_feature=>prediction_feature} + alg_params.each{ |k,v| params[k] = v } + model = OpenTox::Algorithm.new(alg).run(params) + else + model = "http://localhost:8085/model/ffb80776-2b11-468a-ace9-753b2ce3ec5b" + end + puts "model #{model}" + m = OpenTox::Model.new(model) + m.get + predicted_feature = m.predicted_variable + puts "predicted: #{predicted_feature}" + confidence_feature = m.predicted_confidence + puts "confidence: #{confidence_feature}" + + apply_model = false + if (apply_model) + params = {:dataset_uri=>test, + :prediction_feature=>prediction_feature} + pred = OpenTox::Model.new(model).run(params) + else + pred = "http://localhost:8083/dataset/354ccada-3b0c-4ceb-9acf-a0f7dc9c5e09" + end + puts "prediction dataset: #{pred}" + #data_info(pred,"prediction",[prediction_feature,predicted_feature,confidence_feature]) + + v = Validation::Validation.create({:validation_type=>"training_test_split", + :model_uri=>model, + :training_dataset_uri=>train, + :test_dataset_uri=>test, + :prediction_dataset_uri=>pred, + :prediction_feature=>prediction_feature}) + + puts "compute pred data" + data = v.compute_prediction_data_with_model(m) + #puts data.to_yaml + + puts "compute stats" + v.compute_validation_stats + else + alg_params_str = "" + alg_params.each do |key,val| + alg_params_str << ";" if alg_params_str.size>0 + alg_params_str << key.to_s+"="+val + end + params={:algorithm_uri=>alg,:training_dataset_uri=>train, :test_dataset_uri=>test, :prediction_feature=>prediction_feature, :algorithm_params=>alg_params_str} + res = OpenTox::RestClientWrapper.post 'http://localhost:8087/validation/training_test_validation',params + puts res + end + exit + + #begin + #$test_case = self + + #run_test("1a") + #exit + + # post '/validate_datasets',{:test_dataset_uri=>"http://local-ot/dataset/14111", + # :prediction_dataset_uri=>"http://local-ot/dataset/14113", + # :prediction_feature=>"http://local-ot/dataset/14109/feature/Hamster%20Carcinogenicity", + # :predicted_variable=>"http://local-ot/model/21/predicted/value", + # :predicted_confidence=>"http://local-ot/model/21/predicted/confidence", + # :classification=>"true"} #D, [2012-11-07T12:38:11.291069 #31035] DEBUG -- : validation :: loading prediction -- test-dataset: ["http://local-ot/dataset/14099"] :: /validation_service.rb:227:in `compute_prediction_data' # D, [2012-11-07T12:38:11.291174 #31035] DEBUG -- : validation :: loading prediction -- test-target-datset: ["http://local-ot/dataset/14097"] :: /validation_service.rb:227:in `compute_prediction_data' @@ -234,12 +358,12 @@ class ValidationTest < Test::Unit::TestCase #puts last_response.body - rescue => ex - rep = OpenTox::ErrorReport.create(ex, "") - puts rep.to_yaml - ensure - #OpenTox::Authorization.logout(SUBJECTID) if AA_SERVER - end + #rescue => ex + # rep = OpenTox::ErrorReport.create(ex, "") + # puts rep.to_yaml + #ensure + # #OpenTox::Authorization.logout(SUBJECTID) if $aa[:uri] + #end end def app @@ -248,7 +372,7 @@ class ValidationTest < Test::Unit::TestCase def run_test(select=nil, overwrite={}, delete=false ) - if AA_SERVER && SUBJECTID && delete + if $aa[:uri] && SUBJECTID && delete policies_before = OpenTox::Authorization.list_policy_uris(SUBJECTID) end @@ -268,7 +392,7 @@ class ValidationTest < Test::Unit::TestCase ex.check_requirements ex.validate - LOGGER.debug "validation done '"+ex.validation_uri.to_s+"'" + $logger.debug "validation done '"+ex.validation_uri.to_s+"'" end #ex.compute_dataset_size @@ -298,16 +422,16 @@ class ValidationTest < Test::Unit::TestCase end end - if AA_SERVER && SUBJECTID && delete + if $aa[:uri] && SUBJECTID && delete policies_after= OpenTox::Authorization.list_policy_uris(SUBJECTID) diff = policies_after.size - policies_before.size if (diff != 0) policies_before.each do |k,v| policies_after.delete(k) end - LOGGER.warn diff.to_s+" policies NOT deleted:\n"+policies_after.collect{|k,v| k.to_s+" => "+v.to_s}.join("\n") + $logger.warn diff.to_s+" policies NOT deleted:\n"+policies_after.collect{|k,v| k.to_s+" => "+v.to_s}.join("\n") else - LOGGER.debug "all policies deleted" + $logger.debug "all policies deleted" end end end |