summaryrefslogtreecommitdiff
path: root/report
diff options
context:
space:
mode:
Diffstat (limited to 'report')
-rwxr-xr-xreport/environment.rb5
-rw-r--r--report/plot_factory.rb166
-rwxr-xr-xreport/report_application.rb2
-rwxr-xr-xreport/report_content.rb82
-rwxr-xr-xreport/report_factory.rb46
-rwxr-xr-xreport/report_persistance.rb71
-rw-r--r--report/report_service.rb3
-rwxr-xr-xreport/validation_access.rb29
-rwxr-xr-xreport/validation_data.rb88
-rwxr-xr-xreport/xml_report.rb2
10 files changed, 351 insertions, 143 deletions
diff --git a/report/environment.rb b/report/environment.rb
index 12e3272..59465aa 100755
--- a/report/environment.rb
+++ b/report/environment.rb
@@ -4,7 +4,7 @@
'rexml/document', 'ruby-plot', 'opentox-ruby' ].each do |g|
require g
end
-gem 'ruby-plot', '= 0.0.2'
+gem 'ruby-plot', "~>0.4.0"
#R.quit
@@ -12,8 +12,7 @@ module Reports
end
require "lib/ot_predictions.rb"
-#require "lib/active_record_setup.rb"
-require "lib/data_mapper_util.rb"
+require "lib/ohm_util.rb"
require "report/plot_factory.rb"
require "report/xml_report.rb"
diff --git a/report/plot_factory.rb b/report/plot_factory.rb
index 43c45fc..a4e415a 100644
--- a/report/plot_factory.rb
+++ b/report/plot_factory.rb
@@ -77,8 +77,9 @@ module Reports
x << x_i
y << y_i
end
-
- RubyPlot::plot_points(out_file, "Regression plot", "Predicted values", "Actual values", names, x, y )
+
+ raise "no predictions performed" if x.size==0 || x[0].size==0
+ RubyPlot::regression_point_plot(out_file, "Regression plot", "Predicted values", "Actual values", names, x, y )
end
@@ -101,7 +102,7 @@ module Reports
tp_rates = []
attribute_values.each do |value|
begin
- data = transform_predictions(validation_set.filter({split_set_attribute => value}), class_value, false)
+ data = transform_roc_predictions(validation_set.filter({split_set_attribute => value}), class_value, false)
names << value.to_s
fp_rates << data[:fp_rate][0]
tp_rates << data[:tp_rate][0]
@@ -111,11 +112,50 @@ module Reports
end
RubyPlot::plot_lines(out_file, "ROC-Plot", "False positive rate", "True Positive Rate", names, fp_rates, tp_rates )
else
- data = transform_predictions(validation_set, class_value, show_single_curves)
+ data = transform_roc_predictions(validation_set, class_value, show_single_curves)
RubyPlot::plot_lines(out_file, "ROC-Plot", "False positive rate", "True Positive Rate", data[:names], data[:fp_rate], data[:tp_rate], data[:faint] )
end
end
+
+ def self.create_confidence_plot( out_file, validation_set, class_value, split_set_attribute=nil, show_single_curves=false )
+
+ LOGGER.debug "creating confidence plot for '"+validation_set.size.to_s+"' validations, out-file:"+out_file.to_s
+
+ if split_set_attribute
+ attribute_values = validation_set.get_values(split_set_attribute)
+ names = []
+ confidence = []
+ performance = []
+ attribute_values.each do |value|
+ begin
+ data = transform_confidence_predictions(validation_set.filter({split_set_attribute => value}), class_value, false)
+ names << value.to_s
+ confidence << data[:confidence][0]
+ performance << data[:performance][0]
+ rescue
+ LOGGER.warn "could not create confidence plot for "+value.to_s
+ end
+ end
+ #RubyPlot::plot_lines(out_file, "Percent Correct vs Confidence Plot", "Confidence", "Percent Correct", names, fp_rates, tp_rates )
+ case validation_set.unique_feature_type
+ when "classification"
+ RubyPlot::accuracy_confidence_plot(out_file, "Percent Correct vs Confidence Plot", "Confidence", "Percent Correct", names, confidence, performance)
+ when "regression"
+ RubyPlot::accuracy_confidence_plot(out_file, "RMSE vs Confidence Plot", "Confidence", "RMSE", names, confidence, performance, true)
+ end
+ else
+ data = transform_confidence_predictions(validation_set, class_value, show_single_curves)
+ case validation_set.unique_feature_type
+ when "classification"
+ RubyPlot::accuracy_confidence_plot(out_file, "Percent Correct vs Confidence Plot", "Confidence", "Percent Correct", data[:names], data[:confidence], data[:performance])
+ when "regression"
+ RubyPlot::accuracy_confidence_plot(out_file, "RMSE vs Confidence Plot", "Confidence", "RMSE", data[:names], data[:confidence], data[:performance], true)
+ end
+ end
+ end
+
+
def self.create_bar_plot( out_file, validation_set, title_attribute, value_attributes )
LOGGER.debug "creating bar plot, out-file:"+out_file.to_s
@@ -127,7 +167,7 @@ module Reports
validation_set.validations.each do |v|
values = []
value_attributes.each do |a|
- validation_set.get_domain_for_attr(a).each do |class_value|
+ validation_set.get_accept_values_for_attr(a).each do |class_value|
value = v.send(a)
if value.is_a?(Hash)
if class_value==nil
@@ -161,7 +201,7 @@ module Reports
end
- def self.create_ranking_plot( svg_out_file, validation_set, compare_attribute, equal_attribute, rank_attribute, class_value=nil )
+ def self.create_ranking_plot( out_file, validation_set, compare_attribute, equal_attribute, rank_attribute, class_value=nil )
#compute ranks
#puts "rank attibute is "+rank_attribute.to_s
@@ -184,14 +224,14 @@ module Reports
ranks,
nil, #0.1,
validation_set.num_different_values(equal_attribute),
- svg_out_file)
+ out_file)
end
protected
- def self.plot_ranking( title, comparables_array, ranks_array, confidence = nil, numdatasets = nil, svg_out_file = nil )
+ def self.plot_ranking( title, comparables_array, ranks_array, confidence = nil, numdatasets = nil, out_file = nil )
(confidence and numdatasets) ? conf = "-q "+confidence.to_s+" -k "+numdatasets.to_s : conf = ""
- svg_out_file ? show = "-o" : show = ""
+ out_file ? show = "-o" : show = ""
(title and title.length > 0) ? tit = '-t "'+title+'"' : tit = ""
#title = "-t \""+ranking_value_prop+"-Ranking ("+comparables.size.to_s+" "+comparable_prop+"s, "+num_groups.to_s+" "+ranking_group_prop+"s, p < "+p.to_s+")\" "
@@ -208,12 +248,12 @@ module Reports
end
raise "rank plot failed" unless $?==0
- if svg_out_file
- f = File.new(svg_out_file, "w")
+ if out_file
+ f = File.new(out_file, "w")
f.puts res
end
- svg_out_file ? svg_out_file : res
+ out_file ? out_file : res
end
def self.demo_ranking_plot
@@ -221,7 +261,7 @@ module Reports
end
private
- def self.transform_predictions(validation_set, class_value, add_single_folds=false)
+ def self.transform_roc_predictions(validation_set, class_value, add_single_folds=false)
if (validation_set.size > 1)
@@ -229,7 +269,7 @@ module Reports
sum_roc_values = { :predicted_values => [], :actual_values => [], :confidence_values => []}
(0..validation_set.size-1).each do |i|
- roc_values = validation_set.get(i).get_predictions.get_roc_values(class_value)
+ roc_values = validation_set.get(i).get_predictions.get_prediction_values(class_value)
sum_roc_values[:predicted_values] += roc_values[:predicted_values]
sum_roc_values[:confidence_values] += roc_values[:confidence_values]
sum_roc_values[:actual_values] += roc_values[:actual_values]
@@ -252,24 +292,118 @@ module Reports
faint << false
return { :names => names, :fp_rate => fp_rate, :tp_rate => tp_rate, :faint => faint }
else
- roc_values = validation_set.validations[0].get_predictions.get_roc_values(class_value)
+ roc_values = validation_set.validations[0].get_predictions.get_prediction_values(class_value)
tp_fp_rates = get_tp_fp_rates(roc_values)
return { :names => ["default"], :fp_rate => [tp_fp_rates[:fp_rate]], :tp_rate => [tp_fp_rates[:tp_rate]] }
end
end
+ def self.transform_confidence_predictions(validation_set, class_value, add_single_folds=false)
+
+ if (validation_set.size > 1)
+
+ names = []; performance = []; confidence = []; faint = []
+ sum_confidence_values = { :predicted_values => [], :actual_values => [], :confidence_values => []}
+
+ (0..validation_set.size-1).each do |i|
+ confidence_values = validation_set.get(i).get_predictions.get_prediction_values(class_value)
+ sum_confidence_values[:predicted_values] += confidence_values[:predicted_values]
+ sum_confidence_values[:confidence_values] += confidence_values[:confidence_values]
+ sum_confidence_values[:actual_values] += confidence_values[:actual_values]
+
+ if add_single_folds
+ begin
+ pref_conf_rates = get_performance_confidence_rates(confidence_values)
+ names << "fold "+i.to_s
+ performance << pref_conf_rates[:performance]
+ confidence << pref_conf_rates[:confidence]
+ faint << true
+ rescue
+ LOGGER.warn "could not get confidence vals for fold "+i.to_s
+ end
+ end
+ end
+ pref_conf_rates = get_performance_confidence_rates(sum_confidence_values, validation_set.unique_feature_type)
+ names << nil # "all"
+ performance << pref_conf_rates[:performance]
+ confidence << pref_conf_rates[:confidence]
+ faint << false
+ return { :names => names, :performance => performance, :confidence => confidence, :faint => faint }
+
+ else
+ confidence_values = validation_set.validations[0].get_predictions.get_prediction_values(class_value)
+ pref_conf_rates = get_performance_confidence_rates(confidence_values, validation_set.unique_feature_type)
+ return { :names => ["default"], :performance => [pref_conf_rates[:performance]], :confidence => [pref_conf_rates[:confidence]] }
+ end
+ end
+
def self.demo_rock_plot
roc_values = {:confidence_values => [0.1, 0.9, 0.5, 0.6, 0.6, 0.6],
:predicted_values => [1, 0, 0, 1, 0, 1],
:actual_values => [0, 1, 0, 0, 1, 1]}
tp_fp_rates = get_tp_fp_rates(roc_values)
data = { :names => ["default"], :fp_rate => [tp_fp_rates[:fp_rate]], :tp_rate => [tp_fp_rates[:tp_rate]] }
- RubyPlot::plot_lines("/tmp/plot.svg",
+ RubyPlot::plot_lines("/tmp/plot.png",
"ROC-Plot",
"False positive rate",
"True Positive Rate", data[:names], data[:fp_rate], data[:tp_rate], data[:faint] )
end
+ def self.get_performance_confidence_rates(roc_values, feature_type)
+
+ c = roc_values[:confidence_values]
+ p = roc_values[:predicted_values]
+ a = roc_values[:actual_values]
+ raise "no prediction values for roc-plot" if p.size==0
+
+ (0..p.size-2).each do |i|
+ ((i+1)..p.size-1).each do |j|
+ if c[i]<c[j]
+ c.swap!(i,j)
+ a.swap!(i,j)
+ p.swap!(i,j)
+ end
+ end
+ end
+ #puts c.inspect+"\n"+a.inspect+"\n"+p.inspect+"\n\n"
+
+ perf = []
+ conf = []
+
+ case feature_type
+ when "classification"
+ count = 0
+ correct = 0
+ (0..p.size-1).each do |i|
+ count += 1
+ correct += 1 if p[i]==a[i]
+ if i>0 && (c[i]>=conf[-1]-0.00001)
+ perf.pop
+ conf.pop
+ end
+ perf << correct/count.to_f * 100
+ conf << c[i]
+ end
+ when "regression"
+ count = 0
+ sum_squared_error = 0
+ (0..p.size-1).each do |i|
+ count += 1
+ sum_squared_error += (p[i]-a[i])**2
+ if i>0 && (c[i]>=conf[-1]-0.00001)
+ perf.pop
+ conf.pop
+ end
+ perf << Math.sqrt(sum_squared_error/count.to_f)
+ conf << c[i]
+ end
+ end
+ #puts perf.inspect
+
+ return {:performance => perf,:confidence => conf}
+ end
+
+
def self.get_tp_fp_rates(roc_values)
c = roc_values[:confidence_values]
diff --git a/report/report_application.rb b/report/report_application.rb
index 5a47063..258daa7 100755
--- a/report/report_application.rb
+++ b/report/report_application.rb
@@ -82,6 +82,8 @@ get '/report/:type/:id' do
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
diff --git a/report/report_content.rb b/report/report_content.rb
index 1345e6f..ca04f25 100755
--- a/report/report_content.rb
+++ b/report/report_content.rb
@@ -8,7 +8,7 @@ class Reports::ReportContent
attr_accessor :xml_report, :tmp_files
def initialize(title)
- @xml_report = Reports::XMLReport.new(title, Time.now.strftime("Created at %m.%d.%Y - %H:%M"))
+ @xml_report = Reports::XMLReport.new(title, Time.now.strftime("Created at %d.%m.%Y - %H:%M"))
@tmp_file_count = 0
@current_section = @xml_report.get_root_element
end
@@ -147,21 +147,21 @@ class Reports::ReportContent
image_caption=nil)
image_title = "Regression plot" unless image_title
-
- section_regr = @xml_report.add_section(@current_section, section_title)
+ #section_regr = @xml_report.add_section(@current_section, section_title)
+ section_regr = @current_section
prediction_set = validation_set.collect{ |v| v.get_predictions }
if prediction_set.size>0
section_text += "\nWARNING: regression plot information not available for all validation results" if prediction_set.size!=validation_set.size
@xml_report.add_paragraph(section_regr, section_text) if section_text
- plot_file_name = "regr_plot"+@tmp_file_count.to_s+".svg"
+ plot_file_name = "regr_plot"+@tmp_file_count.to_s+".png"
@tmp_file_count += 1
begin
plot_file_path = add_tmp_file(plot_file_name)
Reports::PlotFactory.create_regression_plot( plot_file_path, prediction_set, name_attribute )
- @xml_report.add_imagefigure(section_regr, image_title, plot_file_name, "SVG", 120, image_caption)
- rescue RuntimeError => ex
+ @xml_report.add_imagefigure(section_regr, image_title, plot_file_name, "PNG", 100, image_caption)
+ rescue Exception => ex
LOGGER.error("Could not create regression plot: "+ex.message)
rm_tmp_file(plot_file_name)
@xml_report.add_paragraph(section_regr, "could not create regression plot: "+ex.message)
@@ -178,7 +178,8 @@ class Reports::ReportContent
image_titles=nil,
image_captions=nil)
- section_roc = @xml_report.add_section(@current_section, section_title)
+ #section_roc = @xml_report.add_section(@current_section, section_title)
+ section_roc = @current_section
prediction_set = validation_set.collect{ |v| v.get_predictions && v.get_predictions.confidence_values_available? }
if prediction_set.size>0
@@ -189,18 +190,18 @@ class Reports::ReportContent
end
@xml_report.add_paragraph(section_roc, section_text) if section_text
- class_domain = validation_set.get_class_domain
- class_domain.size.times do |i|
- class_value = class_domain[i]
+ accept_values = validation_set.get_accept_values
+ accept_values.size.times do |i|
+ class_value = accept_values[i]
image_title = image_titles ? image_titles[i] : "ROC Plot for class-value '"+class_value.to_s+"'"
image_caption = image_captions ? image_captions[i] : nil
- plot_file_name = "roc_plot"+@tmp_file_count.to_s+".svg"
+ plot_file_name = "roc_plot"+@tmp_file_count.to_s+".png"
@tmp_file_count += 1
begin
plot_file_path = add_tmp_file(plot_file_name)
Reports::PlotFactory.create_roc_plot( plot_file_path, prediction_set, class_value, split_set_attribute, false )#prediction_set.size>1 )
- @xml_report.add_imagefigure(section_roc, image_title, plot_file_name, "SVG", 120, image_caption)
- rescue RuntimeError => ex
+ @xml_report.add_imagefigure(section_roc, image_title, plot_file_name, "PNG", 100, image_caption)
+ rescue Exception => ex
msg = "WARNING could not create roc plot for class value '"+class_value.to_s+"': "+ex.message
LOGGER.error(msg)
rm_tmp_file(plot_file_name)
@@ -213,6 +214,49 @@ class Reports::ReportContent
end
+ def add_confidence_plot( validation_set,
+ split_set_attribute = nil,
+ section_title="Confidence plots",
+ section_text=nil,
+ image_titles=nil,
+ image_captions=nil)
+
+ #section_conf = @xml_report.add_section(@current_section, section_title)
+ section_conf = @current_section
+ prediction_set = validation_set.collect{ |v| v.get_predictions && v.get_predictions.confidence_values_available? }
+
+ 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"+
+ "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
+
+ image_title = image_titles ? image_titles[i] : "Percent Correct vs Confidence Plot"
+ image_caption = image_captions ? image_captions[i] : nil
+ plot_file_name = "conf_plot"+@tmp_file_count.to_s+".png"
+ @tmp_file_count += 1
+
+ begin
+
+ plot_file_path = add_tmp_file(plot_file_name)
+ Reports::PlotFactory.create_confidence_plot( plot_file_path, prediction_set, nil, split_set_attribute, false )
+ @xml_report.add_imagefigure(section_conf, image_title, plot_file_name, "PNG", 100, image_caption)
+
+ rescue Exception => ex
+ msg = "WARNING could not create confidence plot: "+ex.message
+ LOGGER.error(msg)
+ rm_tmp_file(plot_file_name)
+ @xml_report.add_paragraph(section_conf, msg)
+ end
+
+ else
+ @xml_report.add_paragraph(section_conf, "No prediction-confidence info for confidence plot available.")
+ end
+
+ end
+
def add_ranking_plots( validation_set,
compare_attribute,
equal_attribute,
@@ -236,11 +280,11 @@ class Reports::ReportContent
image_titles=nil,
image_captions=nil)
- class_domain = validation_set.get_domain_for_attr(rank_attribute)
- puts "ranking plot for "+rank_attribute.to_s+", class values: "+class_domain.to_s
+ accept_values = validation_set.get_class_values_for(rank_attribute)
+ puts "ranking plot for "+rank_attribute.to_s+", class values: "+accept_values.to_s
- class_domain.size.times do |i|
- class_value = class_domain[i]
+ accept_values.size.times do |i|
+ class_value = accept_values[i]
if image_titles
image_title = image_titles[i]
else
@@ -270,11 +314,11 @@ class Reports::ReportContent
section_bar = @xml_report.add_section(@current_section, section_title)
@xml_report.add_paragraph(section_bar, section_text) if section_text
- plot_file_name = "bar_plot"+@tmp_file_count.to_s+".svg"
+ plot_file_name = "bar_plot"+@tmp_file_count.to_s+".png"
@tmp_file_count += 1
plot_file_path = add_tmp_file(plot_file_name)
Reports::PlotFactory.create_bar_plot(plot_file_path, validation_set, title_attribute, value_attributes )
- @xml_report.add_imagefigure(section_bar, image_title, plot_file_name, "SVG", 120, image_caption)
+ @xml_report.add_imagefigure(section_bar, image_title, plot_file_name, "PNG", 100, image_caption)
end
private
diff --git a/report/report_factory.rb b/report/report_factory.rb
index e770d2f..08d9418 100755
--- a/report/report_factory.rb
+++ b/report/report_factory.rb
@@ -68,15 +68,21 @@ module Reports::ReportFactory
case val.feature_type
when "classification"
report.add_result(validation_set, [:validation_uri] + VAL_ATTR_TRAIN_TEST + VAL_ATTR_CLASS, "Results", "Results")
- report.add_roc_plot(validation_set)
report.add_confusion_matrix(val)
+ report.add_section("Plots")
+ report.add_roc_plot(validation_set)
+ report.add_confidence_plot(validation_set)
+ report.end_section
when "regression"
report.add_result(validation_set, [:validation_uri] + VAL_ATTR_TRAIN_TEST + VAL_ATTR_REGR, "Results", "Results")
+ report.add_section("Plots")
report.add_regression_plot(validation_set, :model_uri)
+ report.add_confidence_plot(validation_set)
+ report.end_section
end
task.progress(90) if task
- report.add_result(validation_set, Lib::ALL_PROPS, "All Results", "All Results")
+ report.add_result(validation_set, Validation::ALL_PROPS, "All Results", "All Results")
report.add_predictions( validation_set )
task.progress(100) if task
report
@@ -89,7 +95,7 @@ module Reports::ReportFactory
validation_set.get_values(:crossvalidation_id,false).inspect) if validation_set.unique_value(:crossvalidation_id)==nil
validation_set.load_cv_attributes
raise OpenTox::BadRequestError.new("num validations ("+validation_set.size.to_s+") is not equal to num folds ("+
- validation_set.unique_value(:num_folds).to_s+")") unless validation_set.unique_value(:num_folds)==validation_set.size
+ validation_set.unique_value(:num_folds).to_s+")") unless validation_set.unique_value(:num_folds).to_i==validation_set.size
raise OpenTox::BadRequestError.new("num different folds is not equal to num validations") unless validation_set.num_different_values(:crossvalidation_fold)==validation_set.size
raise OpenTox::BadRequestError.new("validations must have unique feature type, i.e. must be either all regression, "+
+"or all classification validations") unless validation_set.unique_feature_type
@@ -104,19 +110,27 @@ module Reports::ReportFactory
case validation_set.unique_feature_type
when "classification"
report.add_result(merged, [:crossvalidation_uri]+VAL_ATTR_CV+VAL_ATTR_CLASS-[:crossvalidation_fold],"Mean Results","Mean Results")
- report.add_roc_plot(validation_set, nil, "ROC Plots over all folds")
- report.add_roc_plot(validation_set, :crossvalidation_fold)
report.add_confusion_matrix(merged.validations[0])
+ report.add_section("Plots")
+ report.add_roc_plot(validation_set)
+ report.add_roc_plot(validation_set, :crossvalidation_fold)
+ report.add_confidence_plot(validation_set)
+ report.add_confidence_plot(validation_set, :crossvalidation_fold)
+ report.end_section
report.add_result(validation_set, VAL_ATTR_CV+VAL_ATTR_CLASS-[:num_folds],
"Results","Results",nil,"validation")
when "regression"
report.add_result(merged, [:crossvalidation_uri]+VAL_ATTR_CV+VAL_ATTR_REGR-[:crossvalidation_fold],"Mean Results","Mean Results")
+ report.add_section("Plots")
report.add_regression_plot(validation_set, :crossvalidation_fold)
+ report.add_confidence_plot(validation_set)
+ report.add_confidence_plot(validation_set, :crossvalidation_fold)
+ report.end_section
report.add_result(validation_set, VAL_ATTR_CV+VAL_ATTR_REGR-[:num_folds], "Results","Results")
end
task.progress(90) if task
- report.add_result(validation_set, Lib::ALL_PROPS, "All Results", "All Results")
+ report.add_result(validation_set, Validation::ALL_PROPS, "All Results", "All Results")
report.add_predictions( validation_set ) #, [:crossvalidation_fold] )
task.progress(100) if task
report
@@ -194,7 +208,25 @@ module Reports::ReportFactory
end
when "regression"
- raise OpenTox::BadRequestError.new("algorithm comparison for regression not yet implemented")
+
+ attributes = VAL_ATTR_CV+VAL_ATTR_REGR-[:crossvalidation_fold]
+ attributes = ([ :dataset_uri ] + attributes).uniq
+
+ dataset_grouping.each do |validations|
+
+ set = Reports::ValidationSet.create(validations)
+
+ dataset = validations[0].dataset_uri
+ merged = set.merge([:algorithm_uri, :dataset_uri, :crossvalidation_id, :crossvalidation_uri])
+ merged.sort(:dataset_uri)
+
+ report.add_section("Dataset: "+dataset)
+ report.add_result(merged,attributes,
+ "Mean Results","Mean Results",nil,"crossvalidation")
+ report.add_paired_ttest_table(set, :algorithm_uri, :r_square)
+ report.end_section
+ end
+
end
task.progress(100) if task
report
diff --git a/report/report_persistance.rb b/report/report_persistance.rb
index df4930c..c85ad68 100755
--- a/report/report_persistance.rb
+++ b/report/report_persistance.rb
@@ -188,28 +188,29 @@ module Reports
# serialize :model_uris
# alias_attribute :date, :created_at
- class ReportData
- include DataMapper::Resource
+ class ReportData < Ohm::Model
- property :id, Serial
- property :report_type, String, :length => 255
- property :created_at, DateTime
- property :validation_uris, Object
- property :crossvalidation_uris, Object
- property :model_uris, Object
- property :algorithm_uris, Object
+ attribute :report_type
+ attribute :date
+ attribute :validation_uris
+ attribute :crossvalidation_uris
+ attribute :model_uris
+ attribute :algorithm_uris
+
+ index :report_type
+ index :validation_uris
+ index :crossvalidation_uris
attr_accessor :subjectid
- after :save, :check_policy
- private
- def check_policy
- OpenTox::Authorization.check_policy(report_uri, subjectid)
+ def self.create(params={})
+ params[:date] = Time.new
+ super params
end
- public
- def date
- created_at
+ def save
+ super
+ OpenTox::Authorization.check_policy(report_uri, subjectid)
end
def report_uri
@@ -241,36 +242,24 @@ module Reports
def new_report(report_content, type, meta_data, uri_provider, subjectid=nil)
raise "report meta data missing" unless meta_data
- report = ReportData.new(meta_data)
+ meta_data[:report_type] = type
+ report = ReportData.create(meta_data)
report.subjectid = subjectid
- report.report_type = type
- report.save
+ OpenTox::Authorization.check_policy(report.report_uri, subjectid)
new_report_with_id(report_content, type, report.id)
end
def list_reports(type, filter_params={})
- filter_params["report_type"]=type unless filter_params.has_key?("report_type")
- #ReportData.find_like(filter_params).delete_if{|r| r.report_type!=type}.collect{ |r| r.id }
-
- filter_params = Lib::DataMapperUtil.check_params(ReportData, filter_params)
- # unfortunately, datamapper does not allow searching in Objects
- # do filtering for list = Object params manually
- list_params = {}
- [:validation_uris, :crossvalidation_uris, :algorithm_uris, :model_uris].each do |l|
- list_params[l] = filter_params.delete(l) if filter_params.has_key?(l)
- end
-
- reports = ReportData.all(filter_params).delete_if{|r| r.report_type!=type}
- list_params.each do |k,v|
- reports = reports.delete_if{ |r| !r.send(k).include?(v) }
- end
+ LOGGER.debug "find reports for params: "+filter_params.inspect
+ reports = Lib::OhmUtil.find( ReportData, filter_params )
reports.collect{ |r| r.id }
end
def get_report(type, id, format, force_formating, params)
- report = ReportData.first({:id => id, :report_type => type})
- raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") unless report
+ report = ReportData[id]
+ raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") if
+ report==nil or report.report_type!=type
# begin
# report = ReportData.find(:first, :conditions => {:id => id, :report_type => type})
# rescue ActiveRecord::RecordNotFound
@@ -294,9 +283,10 @@ module Reports
# raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.")
# end
# ReportData.delete(id)
- report = ReportData.first({:id => id, :report_type => type})
- raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") unless report
- report.destroy
+ report = ReportData[id]
+ raise OpenTox::NotFoundError.new("Report with id='"+id.to_s+"' and type='"+type.to_s+"' not found.") if
+ report==nil || report.report_type!=type
+ report.delete
if (subjectid)
begin
res = OpenTox::Authorization.delete_policies_from_uri(report.report_uri, subjectid)
@@ -310,9 +300,6 @@ module Reports
end
end
-Reports::ReportData.auto_upgrade!
-Reports::ReportData.raise_on_save_failure = true
-
#module Reports
# def self.check_filter_params(model, filter_params)
# prop_names = model.properties.collect{|p| p.name.to_s}
diff --git a/report/report_service.rb b/report/report_service.rb
index 91eefe8..722c3d6 100644
--- a/report/report_service.rb
+++ b/report/report_service.rb
@@ -83,6 +83,9 @@ module Reports
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
+ get_report(type, id, "text/html")
+
return get_uri(type, id)
end
diff --git a/report/validation_access.rb b/report/validation_access.rb
index 53ecc46..e9b6e19 100755
--- a/report/validation_access.rb
+++ b/report/validation_access.rb
@@ -21,11 +21,11 @@ class Reports::ValidationDB
# rescue => ex
# raise "could not access crossvalidation with id "+validation_id.to_s+", error-msg: "+ex.message
# end
- cv = Lib::Crossvalidation.get( cv_id )
+ cv = Validation::Crossvalidation.get( cv_id )
raise OpenTox::NotFoundError.new "crossvalidation with id "+cv_id.to_s+" not found" unless cv
raise OpenTox::BadRequestError.new("crossvalidation with id '"+cv_id.to_s+"' not finished") unless cv.finished
- #res += Lib::Validation.find( :all, :conditions => { :crossvalidation_id => cv_id } ).collect{|v| v.validation_uri.to_s}
- res += Lib::Validation.all( :crossvalidation_id => cv_id ).collect{|v| v.validation_uri.to_s }
+ #res += Validation::Validation.find( :all, :conditions => { :crossvalidation_id => cv_id } ).collect{|v| v.validation_uri.to_s}
+ res += Validation::Validation.find( :crossvalidation_id => cv_id ).collect{|v| v.validation_uri.to_s }
else
res += [u.to_s]
end
@@ -42,16 +42,16 @@ class Reports::ValidationDB
v = nil
raise OpenTox::NotAuthorizedError.new "Not authorized: GET "+uri.to_s if
AA_SERVER and !OpenTox::Authorization.authorized?(uri,"GET",subjectid)
- v = Lib::Validation.get(validation_id)
+ v = Validation::Validation.get(validation_id)
raise OpenTox::NotFoundError.new "validation with id "+validation_id.to_s+" not found" unless v
raise OpenTox::BadRequestError.new "validation with id "+validation_id.to_s+" is not finished yet" unless v.finished
- (Lib::VAL_PROPS + Lib::VAL_CV_PROPS).each do |p|
+ (Validation::VAL_PROPS + Validation::VAL_CV_PROPS).each do |p|
validation.send("#{p.to_s}=".to_sym, v.send(p))
end
- {:classification_statistics => Lib::VAL_CLASS_PROPS,
- :regression_statistics => Lib::VAL_REGR_PROPS}.each do |subset_name,subset_props|
+ {:classification_statistics => Validation::VAL_CLASS_PROPS,
+ :regression_statistics => Validation::VAL_REGR_PROPS}.each do |subset_name,subset_props|
subset = v.send(subset_name)
subset_props.each{ |prop| validation.send("#{prop.to_s}=".to_sym, subset[prop]) } if subset
end
@@ -60,11 +60,11 @@ class Reports::ValidationDB
def init_cv(validation)
#cv = Lib::Crossvalidation.find(validation.crossvalidation_id)
- cv = Lib::Crossvalidation.get(validation.crossvalidation_id)
+ cv = Validation::Crossvalidation.get(validation.crossvalidation_id)
raise OpenTox::BadRequestError.new "no crossvalidation found with id "+validation.crossvalidation_id.to_s unless cv
- Lib::CROSS_VAL_PROPS.each do |p|
- validation.send("#{p.to_s}=".to_sym, cv[p])
+ Validation::CROSS_VAL_PROPS.each do |p|
+ validation.send("#{p.to_s}=".to_sym, cv.send(p.to_s))
end
end
@@ -74,8 +74,13 @@ class Reports::ValidationDB
validation.predicted_variable, subjectid, task)
end
- def get_class_domain( validation )
- OpenTox::Feature.new( validation.prediction_feature ).domain
+ def get_accept_values( validation, subjectid=nil )
+ # PENDING So far, one has to load the whole dataset to get the accept_value from ambit
+ d = OpenTox::Dataset.find( validation.test_target_dataset_uri, subjectid )
+ accept_values = d.features[validation.prediction_feature][OT.acceptValue]
+ raise "cannot get accept values from dataset "+validation.test_target_dataset_uri.to_s+" for feature "+
+ validation.prediction_feature+":\n"+d.features[validation.prediction_feature].to_yaml unless accept_values!=nil
+ accept_values
end
def feature_type( validation, subjectid=nil )
diff --git a/report/validation_data.rb b/report/validation_data.rb
index 15d51ec..42b179b 100755
--- a/report/validation_data.rb
+++ b/report/validation_data.rb
@@ -51,13 +51,13 @@ end
module Reports
- # = Reports::Validation
+ # = ReportValidation
#
# contains all values of a validation object
#
- class Validation
+ class ReportValidation
- @@validation_access = Reports::ValidationDB.new
+ @@validation_access = ValidationDB.new
# for overwriting validation source (other than using webservices)
def self.reset_validation_access(validation_access)
@@ -69,7 +69,7 @@ module Reports
end
# create member variables for all validation properties
- @@validation_attributes = Lib::ALL_PROPS +
+ @@validation_attributes = Validation::ALL_PROPS +
VAL_ATTR_VARIANCE.collect{ |a| (a.to_s+"_variance").to_sym } +
VAL_ATTR_RANKING.collect{ |a| (a.to_s+"_ranking").to_sym }
@@validation_attributes.each{ |a| attr_accessor a }
@@ -85,7 +85,7 @@ module Reports
# returns/creates predictions, cache to save rest-calls/computation time
#
# call-seq:
- # get_predictions => Reports::Predictions
+ # get_predictions => Predictions
#
def get_predictions( task=nil )
if @predictions
@@ -104,9 +104,9 @@ module Reports
# returns the predictions feature values (i.e. the domain of the class attribute)
#
- def get_class_domain()
- @class_domain = @@validation_access.get_class_domain(self) unless @class_domain
- @class_domain
+ def get_accept_values()
+ @accept_values = @@validation_access.get_accept_values(self, @subjectid) unless @accept_values
+ @accept_values
end
# is classification/regression validation? cache to save rest-calls
@@ -127,13 +127,13 @@ module Reports
@@validation_access.init_cv(self)
end
- @@persistance = Reports::ReportService.persistance
+ @@persistance = ReportService.persistance
def validation_report_uri
#puts "searching for validation report: "+self.validation_uri.to_s
return @validation_report_uri if @validation_report_uri!=nil
ids = @@persistance.list_reports("validation",{:validation_uris=>validation_uri })
- @validation_report_uri = Reports::ReportService.instance.get_uri("validation",ids[-1]) if ids and ids.size>0
+ @validation_report_uri = ReportService.instance.get_uri("validation",ids[-1]) if ids and ids.size>0
end
def cv_report_uri
@@ -142,7 +142,7 @@ module Reports
raise "no cv uri "+to_yaml unless self.crossvalidation_uri
ids = @@persistance.list_reports("crossvalidation",{:crossvalidation=>self.crossvalidation_uri.to_s })
#puts "-> "+ids.inspect
- @cv_report_uri = Reports::ReportService.instance.get_uri("crossvalidation",ids[-1]) if ids and ids.size>0
+ @cv_report_uri = ReportService.instance.get_uri("crossvalidation",ids[-1]) if ids and ids.size>0
end
def clone_validation
@@ -160,9 +160,9 @@ module Reports
def initialize(validation_uris=nil, subjectid=nil)
@unique_values = {}
- validation_uris = Reports::Validation.resolve_cv_uris(validation_uris, subjectid) if validation_uris
+ validation_uris = ReportValidation.resolve_cv_uris(validation_uris, subjectid) if validation_uris
@validations = Array.new
- validation_uris.each{|u| @validations.push(Reports::Validation.new(u, subjectid))} if validation_uris
+ validation_uris.each{|u| @validations.push(ReportValidation.new(u, subjectid))} if validation_uris
end
@@ -233,7 +233,7 @@ module Reports
# def get_true_prediction_feature_value
# if all_classification?
-# class_values = get_class_domain
+# class_values = get_accept_values
# if class_values.size == 2
# (0..1).each do |i|
# return class_values[i] if (class_values[i].to_s.downcase == "true" || class_values[i].to_s.downcase == "active")
@@ -243,21 +243,23 @@ module Reports
# return nil
# end
- def get_class_domain( )
- return unique_value("get_class_domain")
+ def get_accept_values( )
+ return unique_value("get_accept_values")
end
- def get_domain_for_attr( attribute )
- class_domain = get_class_domain()
- if Lib::Validation.classification_property?(attribute) and
- !Lib::Validation.depends_on_class_value?(attribute)
- [ nil ]
- elsif Lib::Validation.classification_property?(attribute) and
- class_domain.size==2 and
- Lib::Validation.complement_exists?(attribute)
- [ class_domain[0] ]
+ def get_accept_values_for_attr( attribute )
+ if !Validation::Validation.classification_property?(attribute)
+ []
else
- class_domain
+ accept_values = get_accept_values()
+ if !Validation::Validation.depends_on_class_value?(attribute)
+ [ nil ]
+ elsif accept_values.size==2 and
+ Validation::Validation.complement_exists?(attribute)
+ [ accept_values[0] ]
+ else
+ accept_values
+ end
end
end
@@ -270,10 +272,10 @@ module Reports
# returns a new set with all validation that have values as specified in the map
#
# call-seq:
- # filter(map) => Reports::ValidationSet
+ # filter(map) => ValidationSet
#
def filter(map)
- new_set = Reports::ValidationSet.new
+ new_set = ValidationSet.new
validations.each{ |v| new_set.validations.push(v) if v.has_values?(map) }
return new_set
end
@@ -282,10 +284,10 @@ module Reports
# e.g. create set with predictions: collect{ |validation| validation.get_predictions!=null }
#
# call-seq:
- # filter_proc(proc) => Reports::ValidationSet
+ # filter_proc(proc) => ValidationSet
#
def collect
- new_set = Reports::ValidationSet.new
+ new_set = ValidationSet.new
validations.each{ |v| new_set.validations.push(v) if yield(v) }
return new_set
end
@@ -298,10 +300,10 @@ module Reports
#puts col_values.inspect
# get domain for classification attribute, i.e. ["true","false"]
- class_domain = get_domain_for_attr(attribute_val)
+ accept_values = get_accept_values_for_attr(attribute_val)
# or the attribute has a complementary value, i.e. true_positive_rate
# -> domain is reduced to one class value
- first_value_elem = (class_domain.size==1 && class_domain[0]!=nil)
+ first_value_elem = (accept_values.size==1 && accept_values[0]!=nil)
cell_values = {}
row_values.each do |row|
@@ -311,7 +313,7 @@ module Reports
if v.send(attribute_row)==row and v.send(attribute_col)==col
raise "two validation have equal row and column values"if val!=nil
val = v.send(attribute_val)
- val = val[class_domain[0]] if first_value_elem
+ val = val[accept_values[0]] if first_value_elem
val = val.to_nice_s
end
end
@@ -357,13 +359,13 @@ module Reports
else
attribute_not_nil[index] = true if remove_nil_attributes
- class_domain = get_domain_for_attr(a)
+ accept_values = get_accept_values_for_attr(a)
# get domain for classification attribute, i.e. ["true","false"]
- if class_domain.size==1 && class_domain[0]!=nil
+ if accept_values.size==1 && accept_values[0]!=nil
# or the attribute has a complementary value, i.e. true_positive_rate
# -> domain is reduced to one class value
raise "illegal state, value for "+a.to_s+" is no hash: '"+val.to_s+"'" unless (val.is_a?(Hash))
- val = val[class_domain[0]]
+ val = val[accept_values[0]]
end
if variance
@@ -398,19 +400,19 @@ module Reports
# to_array(attributes) => array
#
def merge(equal_attributes)
- new_set = Reports::ValidationSet.new
+ new_set = ValidationSet.new
# unique values stay unique when merging
# derive unique values before, because model dependent props cannot be accessed later (when mergin validations from different models)
new_set.unique_values = @unique_values
#compute grouping
- grouping = Reports::Util.group(@validations, equal_attributes)
+ grouping = Util.group(@validations, equal_attributes)
#puts "groups "+grouping.size.to_s
- Lib::MergeObjects.register_merge_attributes( Reports::Validation,
- Lib::VAL_MERGE_AVG,Lib::VAL_MERGE_SUM,Lib::VAL_MERGE_GENERAL) unless
- Lib::MergeObjects.merge_attributes_registered?(Reports::Validation)
+ Lib::MergeObjects.register_merge_attributes( ReportValidation,
+ Validation::VAL_MERGE_AVG,Validation::VAL_MERGE_SUM,Validation::VAL_MERGE_GENERAL) unless
+ Lib::MergeObjects.merge_attributes_registered?(ReportValidation)
#merge
grouping.each do |g|
@@ -438,12 +440,12 @@ module Reports
def compute_ranking(equal_attributes, ranking_attribute, class_value=nil )
#puts "compute_ranking("+equal_attributes.inspect+", "+ranking_attribute.inspect+", "+class_value.to_s+" )"
- new_set = Reports::ValidationSet.new
+ new_set = ValidationSet.new
(0..@validations.size-1).each do |i|
new_set.validations.push(@validations[i].clone_validation)
end
- grouping = Reports::Util.group(new_set.validations, equal_attributes)
+ grouping = Util.group(new_set.validations, equal_attributes)
grouping.each do |group|
# put indices and ranking values for current group into hash
diff --git a/report/xml_report.rb b/report/xml_report.rb
index 4b9a11a..4fbfae3 100755
--- a/report/xml_report.rb
+++ b/report/xml_report.rb
@@ -184,7 +184,7 @@ module Reports
row = Element.new("row")
r.each do |v|
entry = Element.new("entry")
- if auto_link_urls && v.to_s =~ /depict/ || v.to_s =~ /image$/ #PENDING
+ if auto_link_urls && v.to_s =~ /depict/ || v.to_s =~ /image\/png$/ #PENDING
add_image(entry, v.to_s)
elsif auto_link_urls && v.to_s =~ /^http(s?):\/\//
add_url(entry, v.to_s, v.to_s)