diff options
author | mguetlein <martin.guetlein@gmail.com> | 2010-08-11 10:58:59 +0200 |
---|---|---|
committer | mguetlein <martin.guetlein@gmail.com> | 2010-08-11 10:58:59 +0200 |
commit | 566786bdd7e253880b7fe6c00cb40fbc46f771a2 (patch) | |
tree | 69cf68c7b479b8f99b9248d92ae91a4f7f24cd34 /reach_reports | |
parent | 148e4eaccf2e406586914150cf2f953fa5f12ece (diff) |
move to wrapper 1.6.2, remove report-dir-check, initial commit of reach reporting stuff
Diffstat (limited to 'reach_reports')
-rw-r--r-- | reach_reports/reach_application.rb | 69 | ||||
-rw-r--r-- | reach_reports/reach_persistance.rb | 47 | ||||
-rw-r--r-- | reach_reports/reach_properties.rb | 158 | ||||
-rw-r--r-- | reach_reports/reach_service.rb | 125 | ||||
-rw-r--r-- | reach_reports/reach_test.rb | 62 | ||||
-rw-r--r-- | reach_reports/reach_to_xml.rb | 60 |
6 files changed, 521 insertions, 0 deletions
diff --git a/reach_reports/reach_application.rb b/reach_reports/reach_application.rb new file mode 100644 index 0000000..96b6b37 --- /dev/null +++ b/reach_reports/reach_application.rb @@ -0,0 +1,69 @@ + +[ 'rubygems', 'sinatra', 'sinatra/url_for', 'active_record', 'ar-extensions', 'opentox-ruby-api-wrapper' ].each do |lib| + require lib +end + +require 'reach_reports/reach_properties.rb' +require 'reach_reports/reach_persistance.rb' +require 'reach_reports/reach_service.rb' +require 'reach_reports/reach_to_xml.rb' + + +require "lib/format_util.rb" + +def extract_type(params) + halt 400, "illegal type, neither QMRF nor QPRF: "+params[:type] unless params[:type] && params[:type] =~ /(?i)Q(M|P)RF/ + params.delete("type") +end + +get '/reach_report/:type' do + content_type "text/uri-list" + type = extract_type(params) + LOGGER.info "list all "+type+" reports" + ReachReports.list_reports(type) +end + +post '/reach_report/:type' do + content_type "text/uri-list" + type = extract_type(params) + LOGGER.info "creating "+type+" report "+params.inspect + ReachReports.create_report(type,params) +end + +get '/reach_report/:type/:id' do + + type = extract_type(params) + LOGGER.info "get "+type+" report with id "+params[:id].to_s+"' "+request.env['HTTP_ACCEPT'].to_s+"'" + rep = ReachReports.get_report(type, params[:id]) + + case request.env['HTTP_ACCEPT'].to_s + when "application/rdf+xml" + owl = OpenTox::Owl.create(rep.type+"Report",rep.report_uri) + owl.set_data( rep.get_content.keys_to_rdf_format ) + result = owl.rdf + when "application/qmrf-xml" + content_type "application/qmrf-xml" + result = ReachReports.reach_report_to_xml(rep) + when /application\/x-yaml|\*\/\*|^$/ # matches 'application/x-yaml', '*/*', '' + content_type "application/x-yaml" + result = rep.get_content.to_yaml + else + halt 400, "MIME type '"+request.env['HTTP_ACCEPT'].to_s+"' not supported, valid Accept-Headers are \"application/rdf+xml\", \"application/x-yaml\", \"application/qmrf-xml\"." + end + result +end + +get '/reach_report/:type/:id/:section' do + + type = extract_type(params) + LOGGER.info "get "+type+" report section '"+params[:section].to_s+"', with id "+params[:id].to_s+"' "+request.env['HTTP_ACCEPT'].to_s+"'" + ReachReports.get_report(type, params[:id], params[:section]).to_yaml +end + +get '/reach_report/:type/:id/:section/:subsection' do + + type = extract_type(params) + LOGGER.info "get "+type+" report subsection '"+params[:subsection].to_s+"', section '"+params[:section].to_s+"', with id "+params[:id].to_s+"' "+request.env['HTTP_ACCEPT'].to_s+"'" + ReachReports.get_report(type, params[:id], params[:section], params[:subsection]).to_yaml +end + diff --git a/reach_reports/reach_persistance.rb b/reach_reports/reach_persistance.rb new file mode 100644 index 0000000..786c48f --- /dev/null +++ b/reach_reports/reach_persistance.rb @@ -0,0 +1,47 @@ + +module ReachReports + + def self.get_uri( report ) + raise "internal error, id not set "+to_yaml if report.id==nil + return $sinatra.url_for("/"+File.join(report.type,report.id.to_s), :full).to_s + end + + class QmrfReport < ActiveRecord::Base + + alias_attribute :date, :created_at + + QmrfProperties.serialized_properties.each do |p| + serialize p + end + + def type + "QMRF" + end + + def report_uri + ReachReports.get_uri(self) + end + + def get_content + hash = {} + [ :model_uri, :date ].each{ |p| hash[p] = self.send(p) } + QmrfProperties.properties.each{ |p| hash[p] = self.send(p) } + return hash + end + end + + + class QprfReport < ActiveRecord::Base + + alias_attribute :date, :created_at + + def report_uri + ReachReports.get_uri(self) + end + + def type + "QPRF" + end + end + +end
\ No newline at end of file diff --git a/reach_reports/reach_properties.rb b/reach_reports/reach_properties.rb new file mode 100644 index 0000000..5397206 --- /dev/null +++ b/reach_reports/reach_properties.rb @@ -0,0 +1,158 @@ + +module ReachReports + + class QmrfProperties + + private + PROPS = { + "QSAR_title" => "1.1", "QSAR_models" => "1.2", "QSAR_software" => "1.3", + "QMRF_date" => "2.1", "QMRF_authors" => "2.2", "QMRF_date_revision" => "2.3", "QMRF_revision" => "2.4", + "model_authors" => "2.5", "model_date" => "2.6", "references" => "2.7", "info_availability" => "2.8", + "related_models" => "2.9", + "model_species" => "3.1", "model_endpoint" => "3.2", "endpoint_comments" => "3.3", "endpoint_units" => "3.4", + "endpoint_variable" => "3.5", "endpoint_protocol" => "3.6", "endpoint_data_quality" => "3.7", + "algorithm_type" => "4.1", "algorithm_explicit" => "4.2", "algorithms_descriptors" => "4.3", + "descriptors_selection" => "4.4", "descriptors_generation" => "4.5", "descriptors_generation_software" => "4.6", + "descriptors_chemicals_ratio" => "4.7", + "app_domain_description" => "5.1", "app_domain_method" => "5.2", "app_domain_software" => "5.3", + "applicability_limits" => "5.4", + "training_set_availability" => "6.1", "training_set_data" => "6.2","training_set_descriptors" => "6.3", + "dependent_var_availability" => "6.4", "other_info" => "6.5", "preprocessing" => "6.6", "goodness_of_fit" => "6.7", + "loo" => "6.8", "lmo" => "6.9", "yscrambling" => "6.10", "bootstrap" => "6.11", "other_statistics" => "6.12", + "validation_set_availability" => "7.1", "validation_set_data" => "7.2", "validation_set_descriptors" => "7.3", + "validation_dependent_var_availability" => "7.4", "validation_other_info" => "7.5", "experimental_design" => "7.6", + "validation_predictivity" => "7.7", "validation_assessment" => "7.8", "validation_comments" => "7.9", + "mechanistic_basis" => "8.1", "mechanistic_basis_comments" => "8.2", "mechanistic_basis_info" => "8.3", + "comments" => "9.1", "bibliography" => "9.2", "attachments" => "9.3", + "QMRF_number" => "10.1", "date_publication" => "10.2", "keywords" => "10.3", "summary_comments" => "10.4", + } + + CHAPTER = { + "QSAR_identifier" => 1, + "QSAR_General_information" => 2, + "QSAR_Endpoint" => 3, + "QSAR_Algorithm" => 4, + "QSAR_Applicability_domain" => 5, + "QSAR_Robustness" => 6, + "QSAR_Predictivity" => 7, + "QSAR_Interpretation" => 8, + "QSAR_Miscelaneous" => 9, + "QMRF_Summary" => 10 } + + CATALOGS = { + "software_catalog" => + { :element => "software", + :fields => ["contact", "description", "name", "number", "url"] }, + "authors_catalog" => { + :element => "author", + :fields => ["affiliation", "contact", "email", "name", "number", "url"]}, + "algorithms_catalog" => { + :element => "algorithm", + :fields => ["definition", "description", "publication_ref"] }, + "descriptors_catalog" => { + :element => "descriptor", + :fields => [ "description", "name", "publication_ref", "units"] }, + "endpoints_catalog" => { + :element => "endpoint", + :fields => [ "group", "name", "subgroup" ]}, + "publications_catalog" => { + :element => "publication", + :fields => [ "title", "url"]}, + } + + CATALOG_REFERENCES = { + "QSAR_software" => "software_catalog", + "references" => "publications_catalog", + "QMRF_authors" => "authors_catalog", + "algorithm_explicit" => "algorithms_catalog", + "descriptors_generation_software" => "descriptors_catalog", + "model_endpoint" => "endpoints_catalog", + "bibliography" => "publications_catalog", + } + + SUBSUBSECTIONS = { + "algorithm_explicit" => [ "equation" ] + } + + #"attachment_training_data", "attachment_validation_data, "attachment_documents", + + public + def self.serialized_properties + return CATALOG_REFERENCES.keys | SUBSUBSECTIONS.keys + end + + def self.properties + return PROPS.keys + end + + def self.chapter_number( chapter ) + CHAPTER[chapter] + end + + def self.chapter_properties( chapter ) + chapter_number = CHAPTER[chapter] + unsorted_chapter_props = [] + PROPS.each do |k,v| + chapter_nr = v.split(".")[0].to_i + next unless chapter_number == chapter_nr + unsorted_chapter_props << [ k, v.split(".")[1].to_i ] + end + unsorted_chapter_props.sort{|a,b| a[1]<=>b[1]}.collect{ |a| a[0] } + end + + def self.chapters() + #h = { "a" => 20, "b" => 30, "c" => 10 } + # h.sort {|a,b| a[1]<=>b[1]} #=> [["c", 10], ["a", 20], ["b", 30]] + CHAPTER.sort{|a,b| a[1]<=>b[1]}.collect{ |a| a[0] } + end + + def self.to_xml(property, content, catalogs_node) + node = REXML::Element.new(property) + node.add_attribute "chapter",PROPS[property] + + return node unless content + + unless serialized_properties.include?(property) + node.text = content + else + if content[:text] + node.text = content.text + end + if SUBSUBSECTIONS.has_key?(property) + SUBSUBSECTIONS[property].each do |p| + subsubsection_node = REXML::Element.new(p) + subsubsection_node.text = content[p] + node << subsubsection_node + end + end + if CATALOG_REFERENCES.has_key?(property) and content[CATALOG_REFERENCES[property]] + catalog_prop = CATALOG_REFERENCES[property] + catalog_content = content[catalog_prop] + catalog_attributes = CATALOGS[catalog_prop] + catalog_node = REXML::Element.new(catalog_prop) + + catalog_content.each do |element| + ref_node = REXML::Element.new(catalog_attributes[:element]+"_ref") + id = catalog_attributes[:element]+"_"+(catalog_content.index(element)+1).to_s + ref_node.add_attribute "idref",id + ref_node.add_attribute "catalog",catalog_prop + node << ref_node + element_node = REXML::Element.new(catalog_attributes[:element]) + element_node.add_attribute "id",id + catalog_attributes[:fields].each do |k| + element_node.add_attribute k,element[k.to_sym] + end + catalog_node << element_node + end + catalogs_node << catalog_node + end + end + + node + end + end + +end + + + diff --git a/reach_reports/reach_service.rb b/reach_reports/reach_service.rb new file mode 100644 index 0000000..cdc0f9c --- /dev/null +++ b/reach_reports/reach_service.rb @@ -0,0 +1,125 @@ +module ReachReports + + def self.list_reports(type) + case type + when /(?i)QMRF/ + ReachReports::QmrfReport.all.collect{ |r| r.report_uri }.join("\n") + when /(?i)QPRF/ + ReachReports::QprfReport.all.collect{ |r| r.report_uri }.join("\n") + end + end + + def self.create_report( type, params ) + + #content_type "text/uri-list" + #task_uri = OpenTox::Task.as_task do |task| + + case type + when /(?i)QMRF/ + if params[:model_uri] + report = ReachReports::QmrfReport.new :model_uri => params[:model_uri] + build_qmrf_report(report) + else + $sinatra.halt 400, "illegal parameters for qmrf-report, use either\n"+ + "* model_uri\n"+ + "params given: "+params.inspect + end + when /(?i)QPRF/ + if params[:compound_uri] + report = ReachReports::QprfReport.new :compound_uri => params[:compound_uri] + else + $sinatra.halt 400, "illegal parameters for qprf-report, use either\n"+ + "* compound-uri\n"+ + "params given: "+params.inspect + end + end + + report.report_uri + + #end + #halt 202,task_uri + end + + def self.build_qmrf_report(r) + + model = OpenTox::Model::Generic.find(r.model_uri) + + # chapter 1 + r.QSAR_title = model.title + # TODO + # QSAR_models -> sparql same endpoint + software = [] + software << { :url => model.uri, :name => model.title, :contact => model.creator } + algorithm = OpenTox::Algorithm::Generic.find(model.algorithm) if model.algorithm + software << { :url => algorithm.uri, :name => algorithm.title } + r.QSAR_software = {"software_catalog" => software} + #chpater 2 + r.QMRF_date = DateTime.now.to_s + # EMPTY: QMRF_authors, QMRF_date_revision, QMRF_revision + # TODO: model_authors ? + r.model_date = model.date.to_s + # TODO: references? + # EMPTY: info_availablity + # TODO: related_models = find qmrf reports for QSAR_models + + # chapter 3 + # TODO "model_species" ? + endpoints = [] + model.predictedVariables.each do |p| + endpoints << { :name => p } # TODO :group, :subgroup ? + end + r.model_endpoint = { "endpoints_catalog" => endpoints } + # TODO "endpoint_comments" => "3.3", "endpoint_units" => "3.4", + r.endpoint_variable = model.dependentVariables + # TODO "endpoint_protocol" => "3.6", "endpoint_data_quality" => "3.7", + + # chapter 4 + # TODO algorithm_type (='type of model') + # TODO algorithm_explicit.equation + # TODO algorithm_explicit.algorithms_catalog + # TODO algorithms_descriptors, descriptors_selection, descriptors_generation, descriptors_generation_software, descriptors_chemicals_ratio + + # chapter 5 + # TODO app_domain_description, app_domain_method, app_domain_software, applicability_limits + + # chapter 6 + # "training_set_availability" => "6.1", "training_set_data" => "6.2","training_set_descriptors" => "6.3", + # "dependent_var_availability" => "6.4", "other_info" => "6.5", "preprocessing" => "6.6", "goodness_of_fit" => "6.7", + # "loo" => "6.8", "lmo" => "6.9", "yscrambling" => "6.10", "bootstrap" => "6.11", "other_statistics" => "6.12", + + # chapter 7 + # "validation_set_availability" => "7.1", "validation_set_data" => "7.2", "validation_set_descriptors" => "7.3", + # "validation_dependent_var_availability" => "7.4", "validation_other_info" => "7.5", "experimental_design" => "7.6", + # "validation_predictivity" => "7.7", "validation_assessment" => "7.8", "validation_comments" => "7.9", + + # chapter 8 + # "mechanistic_basis" => "8.1", "mechanistic_basis_comments" => "8.2", "mechanistic_basis_info" => "8.3", + + # chapter 9 + # "comments" => "9.1", "bibliography" => "9.2", "attachments" => "9.3", + + r.save! + end + + def self.get_report_content(type, id, *keys) + + report_content = get_report(type, id).get_content + keys.each do |k| + $sinatra.halt 400, type+" unknown report property '#{key}'" unless report_content.is_a?(Hash) and report_content.has_key?(k) + report_content = report_content[k] + end + report_content + end + + def self.get_report(type, id) + + case type + when /(?i)QMRF/ + report = ReachReports::QmrfReport.find(id) + when /(?i)QPRF/ + report = ReachReports::QprfReport.find(id) + end + $sinatra.halt 404, type+" report with id '#{id}' not found." unless report + return report + end +end
\ No newline at end of file diff --git a/reach_reports/reach_test.rb b/reach_reports/reach_test.rb new file mode 100644 index 0000000..c96340a --- /dev/null +++ b/reach_reports/reach_test.rb @@ -0,0 +1,62 @@ +require "uri" +require "yaml" +ENV['RACK_ENV'] = 'test' +require 'application.rb' +require 'test/unit' +require 'rack/test' +require 'lib/test_util.rb' +require 'test/test_examples.rb' + +LOGGER = MyLogger.new(STDOUT) +LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S " +LOGGER.formatter = Logger::Formatter.new + + +class ReachTest < Test::Unit::TestCase + include Rack::Test::Methods + include Lib::TestUtil + + + def app + Sinatra::Application + end + + def test_it + #$test_case = self + + post '/reach_report/qmrf',:model_uri=>"http://localhost/model/16" + ##post '/reach_report/qprf',:compound_uri=>"http://localhost/compound/XYZ" + uri = last_response.body + id = uri.split("/")[-1] + puts uri + + #get '/reach_report/qmrf' + #puts last_response.body + + get '/reach_report/qmrf/'+id.to_s,nil,'HTTP_ACCEPT'=>"application/x-yaml" + puts "YAML" + puts last_response.body + +# get '/reach_report/qmrf/'+id.to_s,nil,'HTTP_ACCEPT'=>"application/rdf+xml" +# puts "RDF" +# puts last_response.body + + get '/reach_report/qmrf/'+id,nil,'HTTP_ACCEPT' => "application/qmrf-xml" + puts "XML" + puts last_response.body + + + end +end + + +# query = <<EOF +#PREFIX ot:<http://www.opentox.org/api/1.1#> +#PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> +#select ?model +#where { +#?model rdf:type ot:Model +#} +#EOF +# puts OpenTox::RestClientWrapper.post("http://apps.ideaconsult.net:8080/ontology/",{:accept => "application/rdf+xml", :query => query}) +# exit
\ No newline at end of file diff --git a/reach_reports/reach_to_xml.rb b/reach_reports/reach_to_xml.rb new file mode 100644 index 0000000..311f59f --- /dev/null +++ b/reach_reports/reach_to_xml.rb @@ -0,0 +1,60 @@ + +module ReachReports include REXML + + def self.reach_report_to_xml( report ) + + @@info = {} + if report.type=="QMRF" + @@info[:type ] = "QMRF" + @@info[:dtd_full ] = "http://ambit.sourceforge.net/qmrf/jws/qmrf.dtd" + @@info[:dtd ] = "qmrf.dtd" + @@info[:version ] = 1.2 + @@info[:schema_version] = 0.9 + @@info[:name ] = "(Q)SAR Model Reporting Format" + elsif report.type=="QPRF" + @@info[:type ] = "QPRF" + @@info[:dtd_full ] = "not-yet-defined/qprf.dtd" + @@info[:dtd ] = "qprf.dtd" + @@info[:version ] = 0.1 + @@info[:schema_version] = 0.1 + @@info[:name ] = "(Q)SAR Prediction Reporting Format" + end + @@info[:author] ="Joint Research Centre, European Commission" + @@info[:contact] ="Joint Research Centre, European Commission" + @@info[:date ] = Time.new.to_s + @@info[:email] ="qsardb@jrc.it" + @@info[:schema_version] ="0.9" + @@info[:url ] = "http://ecb.jrc.ec.europa.eu/qsar/" + + doc = Document.new + decl = XMLDecl.new + doc << decl + type = DocType.new(@@info[:type]+' PUBLIC "'+@@info[:dtd_full]+'" "'+@@info[:dtd]+'"') + doc << type + + main = Element.new(@@info[:type]) + main.add_attributes( Hash[*[:version, :schema_version, :name, :author, :contact, + :date, :email, :schema_version, :url].collect { |v| [v.to_s, @@info[v]]}.flatten] ) + + catalogs = Element.new("Catalogs") + chapters = Element.new(@@info[:type]+"_chapters") + + QmrfProperties.chapters.each do |c| + chapter = Element.new(c) + chapter.add_attribute("chapter",QmrfProperties.chapter_number(c)) + QmrfProperties.chapter_properties(c).each do |p| + chapter << QmrfProperties.to_xml(p, report.send(p), catalogs) + end + chapters << chapter + end + + main << chapters + main << catalogs + doc << main + + s = "" + doc.write(s, 2, false, false) + return s + end + +end
\ No newline at end of file |