summaryrefslogtreecommitdiff
path: root/reach_reports
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2011-03-11 14:29:13 +0100
committerChristoph Helma <helma@in-silico.ch>2011-03-11 14:29:13 +0100
commit96d500e9691eedbfdd57ec35a2572b59641377f3 (patch)
tree211391f36e269bf36ca09d54aab0d93ababfa412 /reach_reports
parent5f243f1e9e0a8e12cd8a2267bcec3140d21bf445 (diff)
parent7cd9c9656010b88b7e41477e1571cb7e722650c4 (diff)
Merge branch 'release/v1.0.1'v1.0.1
Diffstat (limited to 'reach_reports')
-rwxr-xr-xreach_reports/reach_application.rb242
-rwxr-xr-xreach_reports/reach_persistance.rb1209
-rwxr-xr-xreach_reports/reach_service.rb319
-rwxr-xr-xreach_reports/reach_test.rb284
4 files changed, 2054 insertions, 0 deletions
diff --git a/reach_reports/reach_application.rb b/reach_reports/reach_application.rb
new file mode 100755
index 0000000..cd0695c
--- /dev/null
+++ b/reach_reports/reach_application.rb
@@ -0,0 +1,242 @@
+
+[ 'rubygems', 'sinatra', 'sinatra/url_for', 'opentox-ruby' ].each do |lib|
+ require lib
+end
+
+QMRF_EDITOR_URI = "http://ortona.informatik.uni-freiburg.de/qmrfedit2/OT_QMRFEditor.jnlp"
+
+require 'reach_reports/reach_persistance.rb'
+require 'reach_reports/reach_service.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' do
+ uri_list = url_for('/reach_report/QMRF', :full)+"\n"+url_for('/reach_report/QPRF', :full)+"\n"
+ if request.env['HTTP_ACCEPT'] =~ /text\/html/
+ content_type "text/html"
+ related_links =
+ "All validations: "+url_for("/",:full)+"\n"+
+ "Validation reporting: "+url_for("/report",:full)
+ description =
+ "A list of all suported REACH reporting types."
+ OpenTox.text_to_html uri_list,related_links,description, @subjectid
+ else
+ content_type "text/uri-list"
+ uri_list
+ end
+end
+
+get '/reach_report/:type' do
+ type = extract_type(params)
+ LOGGER.info "list all "+type+" reports"
+ if request.env['HTTP_ACCEPT'] =~ /text\/html/
+ content_type "text/html"
+ related_links =
+ "All REACH reporting types: "+url_for("/reach_report",:full)
+ description =
+ "A list of "+type+" reports."
+ post_params = ""
+ case type
+ when /(?i)QMRF/
+ related_links += "\n"+
+ "OpenTox version of QMRF editor: "+QMRF_EDITOR_URI
+ description += "\n"+
+ "To create a QMRF report use the POST method."
+ post_params = [[[:model_uri]],[["Existing QMRF report, content-type application/qmrf-xml"]]]
+ when /(?i)QPRF/
+ #TODO
+ end
+ OpenTox.text_to_html ReachReports.list_reports(type),@subjectid,related_links,description,post_params
+ else
+ content_type "text/uri-list"
+ ReachReports.list_reports(type)
+ end
+end
+
+post '/reach_report/:type' do
+
+ type = extract_type(params)
+ content_type "text/uri-list"
+
+ LOGGER.info "creating "+type+" report "+params.inspect
+ #puts "creating "+type+" report "+params.inspect
+ result_uri = ReachReports.create_report(type,params,@subjectid,request.env["rack.input"])
+
+ if result_uri and result_uri.task_uri?
+ halt 202,result_uri+"\n"
+ else
+ result_uri+"\n"
+ end
+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"
+ halt 400, "application/rdf+xml not yet supported"
+ owl = OpenTox::Owl.create(type+"Report",rep.report_uri)
+ owl.set_data( rep.get_content.keys_to_rdf_format )
+ owl.rdf
+ when "application/qmrf-xml"
+ content_type "application/qmrf-xml"
+ rep.to_xml
+ #f = File.new("/home/martin/info_home/.public_html/qmrf.out.xml","w")
+ #f.puts result
+ when /text\/html/
+ content_type "text/html"
+ related_links =
+ "Open report in QMRF editor: "+rep.report_uri+"/editor"+"\n"+
+ "All "+type+" reports: "+url_for("/reach_report/"+type,:full)
+ description =
+ "A QMRF report."
+ OpenTox.text_to_html rep.to_yaml,@subjectid,related_links,description
+ when /application\/x-yaml|\*\/\*|^$/ # matches 'application/x-yaml', '*/*', ''
+ content_type "application/x-yaml"
+ rep.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
+end
+
+post '/reach_report/:type/:id' do
+
+ type = extract_type(params)
+ LOGGER.info "Post to "+type+" report with id "+params[:id].to_s+"' "+request.env['HTTP_ACCEPT'].to_s+"'"
+ rep = ReachReports.get_report(type, params[:id])
+
+ input = request.env["rack.input"].read
+ halt 400, "no xml data specified" unless input && input.to_s.size>0
+ LOGGER.debug "size of posted data: "+input.to_s.size.to_s
+
+ ReachReports::QmrfReport.from_xml(rep,input)
+
+ #f = File.new("/home/martin/info_home/.public_html/qmrf.out.xml","w")
+ #f.puts rep.to_xml
+end
+
+delete '/reach_report/:type/:id' do
+ type = extract_type(params)
+ LOGGER.info "delete "+type+" report with id '"+params[:id].to_s+"'"
+ ReachReports.delete_report(type, params[:id], @subjectid)
+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
+
+get '/reach_report/:type/:id/editor' do
+
+ type = extract_type(params)
+ LOGGER.info "editor for "+type+" report with id '"+params[:id].to_s+"' "+params.inspect
+
+ jnlp = <<EOF
+<?xml version ="1.0" encoding="utf-8"?>
+<jnlp spec="1.0+" codebase="http://opentox.informatik.uni-freiburg.de/" href="qmrfedit2/OT_QMRFEditor.jnlp" >
+<information>
+<title>QMRF Editor</title>
+<vendor>www.opentox.org</vendor>
+<description>(Q)SAR Model Reporting Format Editor</description>
+<description kind="short">(Q)SAR Model Reporting Format Editor</description>
+<icon href="qmrfedit2/OTLogo.png" />
+</information>
+<resources>
+<j2se version="1.6+" java-vm-args="-Xincgc"/>
+
+<jar href="qmrfedit2/OT_QMRFEditor.jar" download="eager" main="true"/>
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-applications.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-builder3d.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-charges.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-core.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-datadebug.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-data.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-experimental.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-extra.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-forcefield.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-interfaces.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-io.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-jchempaint.applet.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-jchempaint.application.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-jchempaint.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-libio-cml.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-libio-weka.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-nonotify.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-pdb-cml.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-pdb.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-qsar-cml.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-qsar.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/cdk-qsar-pdb.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/commons-cli-1.0.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/commons-io-1.1.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/commons-logging-1.0.4.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/commons-codec-1.3.jar" download="eager" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/fop.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/jai_codec.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/jai_core.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/jgrapht-0.6.0.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/jh.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/l2fprod-common-all.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/libfonts-0.1.4.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/log4j-1.2.8.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/log4j.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/mysql-connector-java-5.0.5-bin.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/naming-factory-dbcp.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/naming-factory.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/naming-resources.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/opsin-big-0.1.0.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/org.restlet.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/swing-layout-1.0.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/xmlgraphics-commons-1.1.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/xom-1.1b2.jar" download="lazy" />
+<jar href="qmrfedit2/OT_QMRFEditor_lib/xom-1.1.jar" download="lazy" />
+
+
+</resources>
+<application-desc main-class="ambit.applications.qmrf.QMRFEditor">
+<argument>-x
+EOF
+ jnlp.chomp!
+ jnlp += File.join(url_for("/reach_report/QMRF",:full),params[:id])
+
+ jnlp += <<EOF
+</argument>
+<argument>--subjectid=
+EOF
+ jnlp.chomp!
+ jnlp += @subjectid.to_s
+
+ jnlp += <<EOF
+</argument>
+<argument>-d http://opentox.informatik.uni-freiburg.de/qmrfedit2/qmrf.dtd</argument>
+<argument>-t http://opentox.informatik.uni-freiburg.de/qmrfedit2/verdana.ttf</argument>
+
+</application-desc>
+<security>
+ <all-permissions/>
+</security>
+</jnlp>
+EOF
+
+ content_type "application/x-java-jnlp-file"
+ jnlp
+end
+
diff --git a/reach_reports/reach_persistance.rb b/reach_reports/reach_persistance.rb
new file mode 100755
index 0000000..3118809
--- /dev/null
+++ b/reach_reports/reach_persistance.rb
@@ -0,0 +1,1209 @@
+
+require "dm-validations"
+
+DataMapper::Model.raise_on_save_failure = true
+
+module REXML
+
+ class Element
+ def self.find_or_create(parent_node, name)
+ if parent_node.elements[name]
+ parent_node.elements[name]
+ else
+ node = Element.new(name)
+ parent_node << node
+ node
+ end
+ end
+ end
+
+ class TextElement < Element
+ def initialize(name, text)
+ super(name)
+ self.text = text
+ end
+
+ def self.find_or_create(parent_node, name, text)
+ elem = Element.find_or_create(parent_node, name)
+ elem.text = text
+ elem
+ end
+ end
+end
+
+
+class Symbol
+
+ XML_ALIAS = {
+ :qsar_identifier => "QSAR_identifier", :qsar_title => "QSAR_title", :qsar_software => "QSAR_software",
+ :qsar_models => "QSAR_models", :qsar_general_information => "QSAR_General_information",
+ :qsar_endpoint => "QSAR_Endpoint", :qmrf_author => "qmrf_authors", :qsar_algorithm => "QSAR_Algorithm",
+ :qsar_applicability_domain => "QSAR_Applicability_domain", :qsar_robustness => "QSAR_Robustness",
+ :qsar_predictivity => "QSAR_Predictivity", :qsar_interpretation => "QSAR_Interpretation",
+ :qsar_miscellaneous => "QSAR_Miscelaneous", :qmrf_summary => "QMRF_Summary", :qmrf_number => "QMRF_number" }
+
+ def xml_alias
+ XML_ALIAS[self] ? XML_ALIAS[self] : self.to_s
+ end
+end
+
+class DataMapper::Associations::OneToMany::Relationship
+ def get_child_model
+ @child_model
+ end
+end
+
+module DataMapper::Resource
+
+ def association_class( property )
+ relationship = relationships[property]
+ raise "no relationship found for "+property.to_s+" "+relationships.inspect unless relationship
+ raise "not a many-to-one or one-to-one association for "+property.to_s+" "+relationship.inspect unless
+ relationship.is_a?(DataMapper::Associations::OneToMany::Relationship) or
+ relationship.is_a?(DataMapper::Associations::OneToOne::Relationship)
+ relationship.get_child_model
+ end
+
+ def from_xml(node)
+
+ raise "node is nil ("+self.class.to_s+".from_xml)" unless node
+ #puts "FROM xml: "+self.class.to_s #+", NODE: "+node.to_s
+
+ dbg_check = { :attributes => Set.new(), :nodes => Set.new(), :subnodes => Set.new() }
+
+ xml_infos.each do |xml_info|
+
+ if xml_info.is_a?(ReachReports::TextNodeProperty)
+ text_node = node.elements[ xml_info.xml_prop ]
+ raise "node not found: "+ xml_info.xml_prop+" ("+self.class.to_s+".from_xml)" unless text_node
+ self.send( xml_info.prop.to_s+"=", text_node.text )
+ dbg_check[:nodes] << text_node.name
+
+ elsif xml_info.is_a?(ReachReports::CatalogReference)
+ root_node = node.elements[ xml_info.xml_prop ]
+ raise "node not found: "+ xml_info.xml_prop+" ("+self.class.to_s+".from_xml)" unless root_node
+ dbg_check[:nodes] << root_node.name
+
+ self.send(xml_info.prop).each{ |s| s.destroy } if self.send(xml_info.prop)
+ self.send(xml_info.prop).clear() #otherwise the content is tmp still here
+
+ catalog_node = $catalogs_node.elements[xml_info.catalog_name]
+
+ root_node.each_element(xml_info.catalog_element+"_ref") do |n|
+ ref = nil
+ catalog_node.each_element_with_attribute("id", n.attribute("idref").to_s) do |e|
+ ref = e
+ break
+ end
+ raise "referenced node not found for "+xml_info.xml_prop+" in catalog "+xml_info.catalog_name+" ref-node was "+n.to_s unless ref
+ dbg_check[:subnodes] << n
+
+ entry = self.association_class(xml_info.prop).new
+ entry.from_xml( ref )
+ self.send(xml_info.prop) << entry
+ end
+
+ elsif xml_info.is_a?(ReachReports::AttributeProperty)
+ #puts "attr "+xml_info.prop.to_s
+ self.send(xml_info.prop.to_s+"=", node.attribute(xml_info.xml_prop))
+ dbg_check[:attributes] << xml_info.prop
+
+ elsif xml_info.is_a?(ReachReports::TextSubnodeProperty)
+ parent_node = node.elements[ xml_info.parent_prop.xml_alias ]
+ raise "parent node not found: '"+ xml_info.parent_prop.xml_alias+"' ("+self.class.to_s+".from_xml)" unless parent_node
+ text_node = parent_node.elements[ xml_info.xml_prop ]
+ raise "node not found: "+ xml_info.xml_prop+" ("+self.class.to_s+".from_xml)" unless text_node
+ self.send( xml_info.prop.to_s+"=", text_node.text )
+ dbg_check[:nodes] << parent_node.name
+ dbg_check[:subnodes] << text_node
+
+ elsif xml_info.is_a?(ReachReports::SingleAttributeNodeProperty)
+ attr_node = node.elements[ xml_info.xml_prop ]
+ self.send(xml_info.prop.to_s+"=", attr_node.attribute(xml_info.attribute))
+ dbg_check[:nodes] << attr_node.name
+
+ elsif xml_info.is_a?(ReachReports::AttributeNodeProperty)
+ attr_node = node.elements[ xml_info.xml_prop ]
+ entry = self.association_class( xml_info.prop ).new
+ entry.from_xml(attr_node)
+ self.send(xml_info.prop.to_s+"=",entry)
+ dbg_check[:nodes] << attr_node.name
+
+ elsif xml_info.is_a?(ReachReports::AttributeSubNodeListProperty)
+
+ parent_node = node.elements[ xml_info.parent_prop.xml_alias ]
+ raise "parent node not found: '"+ xml_info.parent_prop.xml_alias+"' ("+self.class.to_s+".from_xml)" unless parent_node
+ #puts "parent node "+xml_info.parent_prop.xml_alias
+ prop_node = parent_node.elements[ xml_info.xml_prop ]
+ if prop_node
+ #puts "prop node "+xml_info.xml_prop.to_s
+ prop_node.each_element do |n|
+ #puts "elem node "+n.name.to_s
+ raise "illegal node '"+n.name.to_s+"' should be '"+xml_info.list_element.to_s+"'" unless n.name==xml_info.list_element.to_s
+ entry = self.association_class( xml_info.prop ).new
+ entry.from_xml( n )
+ self.send(xml_info.prop) << entry
+ end
+ dbg_check[:subnodes] << prop_node
+ end
+ dbg_check[:nodes] << parent_node.name
+
+ else
+ raise "type not supported yet: "+xml_info.inspect
+ end
+ end
+
+ ##raise "not a qsar_identifier" unless qsar_identifier.is_a?(QsarIdentifier)
+
+ #puts node.elements.inspect
+ #puts "there we go: "+qsar_identifier.qsar_software.to_s
+ #qsar_identifier.qsar_software = QsarSoftware.new
+ #puts "there we go: "+qsar_identifier.qsar_software.to_s
+ #exit
+
+ # if defined?(self.class.text_properties)
+# self.class.text_properties.each do |p|
+# puts "set "+p.to_s
+# raise "node not found: "+p.xml_alias.to_s+" ("+self.class.to_s+".from_xml)" unless node.elements[p.xml_alias]
+# #puts "set "+p.to_s+" to: "+node.elements[p.xml_alias].text.to_s
+# self.send(p.to_s+"=", node.elements[p.xml_alias].text)
+# #qsar_identifier.qsar_models = node.elements["qsar_models".xml_alias].text
+# dbg_check[:nodes] << node.elements[p.xml_alias].name
+# end
+#
+
+
+# if defined?(self.class.subsection_properties)
+# self.class.subsection_properties.each do |section_p, subsection_p|
+# #puts "set "+p.to_s
+# #raise "node not found: "+p.xml_alias.to_s+" ("+self.class.to_s+".from_xml)" unless node.elements[p.xml_alias]
+# #puts "set "+p.to_s+" to: "+node.elements[p.xml_alias].text.to_s
+# section = node.elements[section_p.xml_alias]
+# subsection = section.elements[subsection_p.xml_alias]
+# self.send(subsection_p.to_s+"=", subsection.text)
+#
+# dbg_check[:nodes] << section.name
+# dbg_check[:subnodes] << subsection
+#
+# #qsar_identifier.qsar_models = node.elements["qsar_models".xml_alias].text
+# #dbg_check[:text_nodes] << node.elements[p.xml_alias].name
+# end
+# end
+
+# if defined?(self.class.attribute_properties)
+# self.class.attribute_properties.each do |p|
+# puts "read attribute "+p.to_s
+# #self.update(p => node.attribute(p.xml_alias))
+# self.send(p.to_s+"=", node.attribute(p.xml_alias))
+# dbg_check[:attributes] << p
+# #qsar_identifier.qsar_models = node.elements["qsar_models".xml_alias].text
+# end
+# end
+
+ #qsar_identifier.qsar_title = node.elements["qsar_title".xml_alias].text
+ #qsar_identifier.qsar_models = node.elements["qsar_models".xml_alias].text
+
+
+
+ ignore_attribs =[ "id", "name", "help", "chapter" ]
+ node.attributes.each do |a,v|
+ unless (ignore_attribs.include?(a.to_s)) || dbg_check[:attributes].include?(a.to_sym)
+ raise "not handled : attribute '"+a.to_s+"' -> '"+v.to_s+"'" +
+ "\n("+self.class.to_s+".from_xml)" +
+ "\nchecked:\n"+dbg_check[:attributes].to_yaml+
+ "\nnode-attribtues:\n"+node.attributes.to_yaml
+ end
+ end
+
+ node.each_element do |n|
+# if n.text!=nil and n.text.to_s.size>0 and
+# !dbg_check[:text_nodes].include?(n.name) and
+# (!dbg_check[:catalog_nodes].has_key?(n.name))
+
+ valid = dbg_check[:nodes].include?(n.name)
+ if (valid)
+ refs = dbg_check[:subnodes]
+ #puts "sub "+refs.inspect
+ n.each_element do |nn|
+ #puts "lookin for ref "+nn.to_s
+ unless refs.include?(nn)
+ valid = false
+ break
+ end
+ end
+ end
+
+ unless valid
+ raise puts "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nnot handled node : "+n.to_s+
+ "\n("+self.class.to_s+".from_xml)"
+# raise "not handled node : "+n.to_s+
+# "\n("+self.class.to_s+".from_xml)" +
+# "\nchecked text nodes:\n"+dbg_check[:text_nodes].to_yaml+
+# "\nchecked catalog nodes:\n"+dbg_check[:catalog_nodes].to_yaml+
+# "\nnode-attribtues:\n"+n.attributes.to_yaml
+ end
+ end
+
+
+ #self.save!
+ #self.reload
+# unless self.save
+# self.errors.each do |e|
+# puts "Error: "+e.to_s
+# end
+# end
+ #puts "self id: "+self.id.to_s
+
+# qsar_identifier.qsar_software.each{ |s| s.destroy } if qsar_identifier.qsar_software
+# qsar_identifier.qsar_software.update({}) #otherwise the content is tmp still here
+#
+# catalog_node = $catalogs_node.elements["software_catalog"]
+#
+# node.elements[:qsar_software.xml_alias].each_element do |n|
+#
+# puts "reading software ref "+n.to_s
+# ref = nil
+# catalog_node.each_element_with_attribute("id", n.attribute("idref").to_s) do |e|
+# ref = e
+# break
+# end
+# software = QsarSoftware.new
+# QsarSoftware.from_xml( software, ref )
+# qsar_identifier.qsar_software << software
+# end
+# #qsar_identifier.qsar_software = QsarSoftware.new unless qsar_identifier.qsar_software
+# #QsarSoftware.from_xml( qsar_identifier.qsar_software, node.elements["qsar_software".xml_alias] )
+
+ end
+
+ def to_XML(node, chapter=nil )
+
+ xml_infos.each do |xml_info|
+ if xml_info.is_a?(ReachReports::TextNodeProperty)
+ new_node = REXML::TextElement.find_or_create(node, xml_info.xml_prop,self.send(xml_info.prop))
+
+ elsif xml_info.is_a?(ReachReports::CatalogReference)
+
+ new_node = REXML::Element.find_or_create( node, xml_info.xml_prop )
+ catalog_node = $catalogs_node.elements[ xml_info.catalog_name ]
+
+ self.send(xml_info.prop.to_s+"=",[self.association_class(xml_info.prop).new]) unless self.send(xml_info.prop) and self.send(xml_info.prop).size>0
+
+ self.send( xml_info.prop ).each do |elem|
+ elem_node = REXML::Element.new(xml_info.catalog_element )
+ elem.to_XML( elem_node )
+ # if not saved, i.e. the element was only created for a complete xml, count elements in catalog for id
+ element_id = xml_info.catalog_element+"_"+(elem.id ? elem.id.to_s : (catalog_node.elements.size+1).to_s)
+ elem_node.add_attribute("id",element_id)
+ catalog_node << elem_node
+
+ ref_node = REXML::Element.new(xml_info.catalog_element+"_ref" )
+ ref_node.add_attributes("idref"=>element_id,"catalog"=>xml_info.catalog_name)
+ new_node << ref_node
+ end
+
+ elsif xml_info.is_a?(ReachReports::AttributeProperty)
+ node.add_attribute( xml_info.xml_prop, self.send(xml_info.prop).to_s )
+
+ elsif xml_info.is_a?(ReachReports::TextSubnodeProperty)
+ new_node = REXML::Element.find_or_create( node, xml_info.parent_prop.xml_alias)
+ REXML::TextElement.find_or_create( new_node, xml_info.xml_prop,self.send(xml_info.prop))
+
+ elsif xml_info.is_a?(ReachReports::SingleAttributeNodeProperty)
+ new_node = REXML::Element.find_or_create(node, xml_info.xml_prop)
+ new_node.add_attribute(xml_info.attribute, self.send(xml_info.prop).to_s)
+
+ elsif xml_info.is_a?(ReachReports::AttributeNodeProperty)
+ new_node = REXML::Element.find_or_create(node, xml_info.xml_prop)
+ self.send(xml_info.prop.to_s+"=",self.association_class(xml_info.prop).new) unless self.send(xml_info.prop)
+ self.send(xml_info.prop).to_XML(new_node)
+
+ elsif xml_info.is_a?(ReachReports::AttributeSubNodeListProperty)
+ new_node = REXML::Element.find_or_create( node, xml_info.parent_prop.xml_alias )
+ #puts "new parent "+xml_info.parent_prop.xml_alias
+ prop_node = REXML::Element.find_or_create( new_node, xml_info.xml_prop )
+ #puts "new prop "+xml_info.xml_prop
+ self.send( xml_info.prop ).each do |elem|
+ #puts "elem "+elem.to_yaml
+ elem_node = REXML::Element.new( xml_info.list_element.xml_alias )
+ elem.to_XML( elem_node )
+ prop_node << elem_node
+ end
+
+ else
+ raise "type not supported yet: "+xml_info.inspect
+ end
+
+ new_node.add_attribute("chapter", chapter.to_s+"."+node.elements.size.to_s) if chapter and new_node and new_node.attribute("chapter")==nil
+ end
+
+# if defined?(self.class.text_properties)
+# self.class.text_properties.each do |p|
+# node << REXML::TextElement.new(p.xml_alias,self.send(p))
+# end
+# end
+ #node << REXML::TextElement.new(:qsar_title.xml_alias,qsar_title)
+ #node << REXML::TextElement.new(:qsar_models.xml_alias,qsar_models)
+
+# if defined?(self.class.catalog_entries)
+# self.class.catalog_entries.each do |p| #,associatedClass|
+#
+# assoc_node = REXML::Element.new( p.xml_alias )
+# self.send(p).each{ |s| s.to_XML( assoc_node ) }
+# node << assoc_node
+# end
+# end
+#
+# if defined?(self.class.catalog_name)
+# catalog_node = $catalogs_node.elements[self.class.catalog_name]
+# node_ref = REXML::Element.new(self.class.catalog_element+"_ref")
+#
+# raise "id is nil" if self.id==nil || self.id.to_s.size==0
+# element_id = self.class.catalog_element+"_"+self.id.to_s
+# node_ref.add_attributes("idref"=>element_id,"catalog"=>self.class.catalog_name)
+#
+# content_node = REXML::Element.new(self.class.catalog_element)
+# content_node.add_attribute("id",element_id)
+# self.class.attribute_properties.each do |p|
+# content_node.add_attribute p.xml_alias,send(p)
+# end
+# catalog_node << content_node
+# node << node_ref
+#
+## def catalog_to_xml(node, catalog_name, element_name, attributes)
+## catalog_node = $catalogs_node.elements[catalog_name]
+## node_ref = REXML::Element.new(element_name+"_ref")
+## attributes["id"] = element_name+"_"+attributes.delete("id").to_s
+## node_ref.add_attributes("idref"=>attributes["id"],"catalog"=>catalog_name)
+## content_node = REXML::Element.new(element_name)
+## #puts "my attribts: "+attributes.inspect
+## attributes.each do |k,v|
+## content_node.add_attribute k,v.to_s
+## end
+## catalog_node << content_node
+## node << node_ref
+## end
+# end
+
+
+# node << REXML::TextElement.new(:qsar_title.xml_alias,qsar_title)
+# node << REXML::TextElement.new(:qsar_models.xml_alias,qsar_models)
+# qsar_software_node = REXML::Element.new(:qsar_software.xml_alias)
+# qsar_software.each{ |s| s.to_xml( qsar_software_node ) }
+# node << qsar_software_node
+ end
+
+end
+
+
+module ReachReports
+
+ def self.get_uri( report )
+ raise "internal error, id not set "+to_yaml if report.id==nil
+ return $url_provider.url_for("/"+File.join(report.type,report.id.to_s), :full).to_s
+ end
+
+
+
+
+# module CatalogEntry
+#
+# def catalog_to_xml(node, catalog_name, element_name, attributes)
+# catalog_node = $catalogs_node.elements[catalog_name]
+# node_ref = REXML::Element.new(element_name+"_ref")
+# attributes["id"] = element_name+"_"+attributes.delete("id").to_s
+# node_ref.add_attributes("idref"=>attributes["id"],"catalog"=>catalog_name)
+# content_node = REXML::Element.new(element_name)
+# #puts "my attribts: "+attributes.inspect
+# attributes.each do |k,v|
+# content_node.add_attribute k,v.to_s
+# end
+# catalog_node << content_node
+# node << node_ref
+# end
+# end
+
+# class QsarSoftware
+# include DataMapper::Resource #, CatalogEntry
+#
+# property :id, Serial
+# property :contact, String, :length => 255
+# property :description, String, :length => 255
+# property :name, String, :length => 255
+# property :number, String, :length => 255
+# property :url, String, :length => 255
+#
+# def self.attribute_properties
+# [ :contact, :description, :name, :number, :url ]
+# end
+#
+# def self.catalog_name
+# "software_catalog"
+# end
+#
+# def self.catalog_element
+# "software"
+# end
+#
+# belongs_to :qsar_identifier
+# end
+
+ class Software
+ include DataMapper::Resource #, CatalogEntry
+
+ property :id, Serial
+ property :contact, String, :length => 255
+ property :description, String, :length => 255
+ property :name, String, :length => 255
+ property :number, String, :length => 255
+ property :url, String, :length => 255
+
+ def xml_infos
+ [ AttributeProperty.new(:contact),
+ AttributeProperty.new(:description),
+ AttributeProperty.new(:name),
+ AttributeProperty.new(:number),
+ AttributeProperty.new(:url) ]
+ end
+ end
+
+ class QsarSoftware < Software
+ #belongs_to :qsar_identifier, :key => false
+ property :qsar_identifier_id, Integer
+ end
+
+ class XmlInfo
+
+ attr_accessor :prop
+
+ protected
+ def initialize( prop )
+ @prop = prop
+ end
+
+ public
+ def xml_prop
+ @prop.xml_alias
+ end
+ end
+
+ class TextNodeProperty < XmlInfo
+
+ end
+
+ class TextSubnodeProperty < XmlInfo
+ attr_accessor :parent_prop
+
+ def initialize( prop, parent_prop )
+ super(prop)
+ @parent_prop = parent_prop
+ end
+ end
+
+ class AttributeProperty < XmlInfo
+
+ end
+
+ class AttributeNodeProperty < XmlInfo
+
+ end
+
+ class AttributeSubNodeListProperty < XmlInfo
+
+ attr_accessor :list_element, :parent_prop
+
+ def initialize( prop, list_element, parent_prop )
+ super(prop)
+ @list_element = list_element
+ @parent_prop = parent_prop
+ end
+ end
+
+ class SingleAttributeNodeProperty < XmlInfo
+ attr_accessor :attribute
+
+ def initialize( prop, attribute )
+ super(prop)
+ @attribute = attribute
+ end
+ end
+
+ class CatalogReference < XmlInfo
+ attr_accessor :catalog_name, :catalog_element
+
+ def initialize( prop, catalog_name, catalog_element )
+ super(prop)
+ @catalog_name = catalog_name
+ @catalog_element = catalog_element
+ end
+ end
+
+
+ class QsarIdentifier
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :qsar_title, Text
+ property :qsar_models, Text
+
+ has n, :qsar_software
+
+ def xml_infos
+ [ TextNodeProperty.new(:qsar_title),
+ TextNodeProperty.new(:qsar_models),
+ CatalogReference.new(:qsar_software, "software_catalog", "software") ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class Author
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :affiliation, String, :length => 255
+ property :contact, String, :length => 255
+ property :email, String, :length => 255
+ property :name, String, :length => 255
+ property :number, String, :length => 255
+ property :url, String, :length => 255
+
+ def xml_infos
+ [ AttributeProperty.new(:affiliation),
+ AttributeProperty.new(:contact),
+ AttributeProperty.new(:email),
+ AttributeProperty.new(:name),
+ AttributeProperty.new(:number),
+ AttributeProperty.new(:url) ]
+ end
+
+ belongs_to :qsar_general_information
+ end
+
+ class QmrfAuthor < Author
+ property :type, String, :default => "QmrfAuthor"
+ end
+
+ class ModelAuthor < Author
+ property :type, String, :default => "ModelAuthor"
+ end
+
+ class Publication
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :title, Text
+ property :url, String, :length => 255
+
+ def xml_infos
+ [ AttributeProperty.new(:title),
+ AttributeProperty.new(:url) ]
+ end
+ end
+
+ class Reference < Publication
+ #belongs_to :qsar_general_information
+ property :qsar_general_information_id, Integer
+ end
+
+
+ class QsarGeneralInformation
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :qmrf_date, Text #String, :length => 255 #PENDING -> datetime
+ property :model_date, Text #String, :length => 255 #PENDING -> datetime
+ property :qmrf_date_revision, Text #String, :length => 255 #PENDING -> datetime
+ property :qmrf_revision, Text
+ property :model_date, Text
+ property :info_availability, Text
+ property :related_models, Text
+
+ # type is needed to distinguish between authors
+ # (the datamapper creates a table "Authors", the relation is defined by QsarGeneral.id and Author.id)
+ has n, :qmrf_authors, :type => "QmrfAuthor"
+ has n, :model_authors, :type => "ModelAuthor"
+ has n, :references
+
+ def xml_infos
+ [ TextNodeProperty.new(:qmrf_date),
+ CatalogReference.new(:qmrf_authors, "authors_catalog", "author"),
+ TextNodeProperty.new(:qmrf_date_revision),
+ TextNodeProperty.new(:qmrf_revision),
+ CatalogReference.new(:model_authors, "authors_catalog", "author"),
+ TextNodeProperty.new(:model_date),
+ CatalogReference.new(:references, "publications_catalog", "publication"),
+ TextNodeProperty.new(:info_availability),
+ TextNodeProperty.new(:related_models) ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class ModelEndpoint
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :group, String, :length => 255
+ property :name, String, :length => 255
+ property :subgroup, String, :length => 255
+
+ def xml_infos
+ [ AttributeProperty.new(:group),
+ AttributeProperty.new(:name),
+ AttributeProperty.new(:subgroup) ]
+ end
+
+ belongs_to :qsar_endpoint
+ end
+
+ class QsarEndpoint
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :endpoint_variable, Text
+ property :model_species, Text
+ property :endpoint_comments, Text
+ property :endpoint_units, Text
+ property :endpoint_protocol, Text
+ property :endpoint_data_quality, Text
+
+ has n, :model_endpoint
+
+ def xml_infos
+ [ TextNodeProperty.new(:model_species),
+ CatalogReference.new(:model_endpoint, "endpoints_catalog", "endpoint"),
+ TextNodeProperty.new(:endpoint_comments),
+ TextNodeProperty.new(:endpoint_units),
+ TextNodeProperty.new(:endpoint_variable),
+ TextNodeProperty.new(:endpoint_protocol),
+ TextNodeProperty.new(:endpoint_data_quality) ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class AlgorithmExplicit
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :definition, Text
+ property :description, Text
+ property :publication_ref, Text
+
+ def xml_infos
+ [ AttributeProperty.new(:definition),
+ AttributeProperty.new(:description),
+ AttributeProperty.new(:publication_ref) ]
+ end
+
+ belongs_to :qsar_algorithm
+ end
+
+ class AlgorithmsDescriptor
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :description, Text
+ property :name, Text
+ property :publication_ref, Text
+ property :units, Text
+
+ def xml_infos
+ [ AttributeProperty.new(:description),
+ AttributeProperty.new(:name),
+ AttributeProperty.new(:publication_ref),
+ AttributeProperty.new(:units) ]
+ end
+
+ belongs_to :qsar_algorithm
+ end
+
+ class DescriptorsGenerationSoftware < Software
+
+ #belongs_to :qsar_algorithm, :key => false
+ property :qsar_algorithm_id, Integer
+ end
+
+ class QsarAlgorithm
+ include DataMapper::Resource
+
+ property :id, Serial
+
+ property :algorithm_type, Text
+ property :descriptors_selection, Text
+ property :descriptors_generation, Text
+ property :descriptors_chemicals_ratio, Text
+ property :equation, Text
+
+ has n, :algorithm_explicit
+ has n, :algorithms_descriptors
+ has n, :descriptors_generation_software
+
+ def xml_infos
+ [ TextNodeProperty.new(:algorithm_type),
+ CatalogReference.new(:algorithm_explicit, "algorithms_catalog", "algorithm"),
+ TextSubnodeProperty.new(:equation, :algorithm_explicit),
+ CatalogReference.new(:algorithms_descriptors, "descriptors_catalog", "descriptor"),
+ TextNodeProperty.new(:descriptors_selection),
+ TextNodeProperty.new(:descriptors_generation),
+ CatalogReference.new(:descriptors_generation_software, "software_catalog", "software"),
+ TextNodeProperty.new(:descriptors_chemicals_ratio),
+ ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class AppDomainSoftware < Software
+
+ #belongs_to :qsar_algorithm, :key => false
+ property :qsar_applicability_domain_id, Integer
+ end
+
+ class QsarApplicabilityDomain
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :app_domain_description, Text
+ property :app_domain_method, Text
+ property :applicability_limits, Text
+
+ has n,:app_domain_software
+
+ def xml_infos
+ [ TextNodeProperty.new(:app_domain_description),
+ TextNodeProperty.new(:app_domain_method),
+ CatalogReference.new(:app_domain_software, "software_catalog", "software"),
+ TextNodeProperty.new(:applicability_limits), ]
+ end
+
+ belongs_to :qmrf_report
+
+ end
+
+ class DatasetData
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :chemname, String, :default => "No"
+ property :cas, String, :default => "No"
+ property :smiles, String, :default => "No"
+ property :inchi, String, :default => "No"
+ property :mol, String, :default => "No"
+ property :formula, String, :default => "No"
+
+ def xml_infos
+ [ AttributeProperty.new(:chemname),
+ AttributeProperty.new(:cas),
+ AttributeProperty.new(:smiles),
+ AttributeProperty.new(:inchi),
+ AttributeProperty.new(:mol),
+ AttributeProperty.new(:formula) ]
+ end
+
+ end
+
+ class TrainingSetData < DatasetData
+
+ #belongs_to :qsar_robustness
+ property :qsar_robustness_id, Integer
+ end
+
+
+ class QsarRobustness
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :training_set_availability, String, :default => "No"
+ property :training_set_descriptors, String, :default => "No"
+ property :dependent_var_availability, String, :default => "No"
+ property :other_info, Text
+ property :preprocessing, Text
+ property :goodness_of_fit, Text
+ property :loo, Text
+ property :lmo, Text
+ property :yscrambling, Text
+ property :bootstrap, Text
+ property :other_statistics, Text
+
+ has 1, :training_set_data, :model => "TrainingSetData"
+
+ def xml_infos
+ [ SingleAttributeNodeProperty.new(:training_set_availability, "answer"),
+ AttributeNodeProperty.new(:training_set_data),
+ SingleAttributeNodeProperty.new(:training_set_descriptors, "answer"),
+ SingleAttributeNodeProperty.new(:dependent_var_availability, "answer"),
+ TextNodeProperty.new(:other_info),
+ TextNodeProperty.new(:preprocessing),
+ TextNodeProperty.new(:goodness_of_fit),
+ TextNodeProperty.new(:loo),
+ TextNodeProperty.new(:lmo),
+ TextNodeProperty.new(:yscrambling),
+ TextNodeProperty.new(:bootstrap),
+ TextNodeProperty.new(:other_statistics),
+ ]
+ end
+
+ belongs_to :qmrf_report
+
+ end
+
+
+ class ValidationSetData < DatasetData
+
+ #belongs_to :qsar_predictivity
+ property :qsar_predictivity_id, Integer
+ end
+
+ class QsarPredictivity
+ include DataMapper::Resource
+
+ property :id, Serial
+
+ property :validation_set_availability, String, :default => "No"
+ property :validation_set_descriptors, String, :default => "No"
+ property :validation_dependent_var_availability, String, :default => "No"
+ property :validation_other_info, Text
+ property :experimental_design, Text
+ property :validation_predictivity, Text
+ property :validation_assessment, Text
+ property :validation_comments, Text
+
+ has 1, :validation_set_data, :model => "ValidationSetData"
+
+ def xml_infos
+ [ SingleAttributeNodeProperty.new(:validation_set_availability, "answer"),
+ AttributeNodeProperty.new(:validation_set_data),
+ SingleAttributeNodeProperty.new(:validation_set_descriptors, "answer"),
+ SingleAttributeNodeProperty.new(:validation_dependent_var_availability, "answer"),
+ TextNodeProperty.new(:validation_other_info),
+ TextNodeProperty.new(:experimental_design),
+ TextNodeProperty.new(:validation_predictivity),
+ TextNodeProperty.new(:validation_assessment),
+ TextNodeProperty.new(:validation_comments),
+ ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class QsarInterpretation
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :mechanistic_basis, Text
+ property :mechanistic_basis_comments, Text
+ property :mechanistic_basis_info, Text
+
+ def xml_infos
+ [ TextNodeProperty.new(:mechanistic_basis),
+ TextNodeProperty.new(:mechanistic_basis_comments),
+ TextNodeProperty.new(:mechanistic_basis_info),
+ ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class Bibliography < Publication
+
+ #belongs_to :qsar_miscellaneous
+ property :qsar_miscellaneous_id, Integer
+ end
+
+ class Attachment
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :description, Text
+ property :filetype, String
+ property :url, String, :length => 255
+
+ def xml_infos
+ [ AttributeProperty.new(:description),
+ AttributeProperty.new(:filetype),
+ AttributeProperty.new(:url),
+ ]
+ end
+
+ belongs_to :qsar_miscellaneous
+ end
+
+ class AttachmentTrainingData < Attachment
+ property :type, String, :default => "AttachmentTrainingData"
+ end
+
+ class AttachmentValidationData < Attachment
+ property :type, String, :default => "AttachmentValidationData"
+ end
+
+ class AttachmentDocument < Attachment
+ property :type, String, :default => "AttachmentDocument"
+ end
+
+
+ class QsarMiscellaneous
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :comments, Text
+
+ has n, :bibliography, Text
+
+ # type is needed to distinguish between attachments
+ # (the datamapper creates a table "Attachments", the relation is defined by QsarMisc.id and Attachment.id)
+ has n, :attachment_training_data, :model => "AttachmentValidationData", :type => "AttachmentTrainingData"
+ has n, :attachment_validation_data, :model => "AttachmentValidationData", :type => "AttachmentValidationData"
+ has n, :attachment_documents, :type => "AttachmentDocument"
+
+ def xml_infos
+ [ TextNodeProperty.new(:comments),
+ CatalogReference.new(:bibliography,"publications_catalog", "publication"),
+ AttributeSubNodeListProperty.new(:attachment_training_data, :molecules, :attachments),
+ AttributeSubNodeListProperty.new(:attachment_validation_data, :molecules, :attachments),
+ AttributeSubNodeListProperty.new(:attachment_documents, :documents, :attachments),
+ ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class QmrfSummary
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :qmrf_number, Text
+ property :date_publication, Text
+ property :keywords, Text
+ property :summary_comments, Text
+
+ def xml_infos
+ [ TextNodeProperty.new(:qmrf_number),
+ TextNodeProperty.new(:date_publication),
+ TextNodeProperty.new(:keywords),
+ TextNodeProperty.new(:summary_comments),
+ ]
+ end
+
+ belongs_to :qmrf_report
+ end
+
+ class QmrfReport
+ include DataMapper::Resource, REXML
+
+ property :id, Serial
+ property :model_uri, String, :length => 255
+
+ CHAPTERS = [ :qsar_identifier, :qsar_general_information, :qsar_endpoint, :qsar_algorithm,
+ :qsar_applicability_domain, :qsar_robustness, :qsar_predictivity, :qsar_interpretation,
+ :qsar_miscellaneous, :qmrf_summary ]
+
+ CHAPTERS.each{ |c,clazz| has 1, c }
+
+ attr_accessor :subjectid
+
+ after :save, :check_policy
+ private
+ def check_policy
+ raise "no id" unless @id
+ #raise "no subjectid" unless subjectid
+ OpenTox::Authorization.check_policy(report_uri, subjectid)
+ end
+
+ public
+ def to_yaml
+ super(:methods => CHAPTERS)
+ end
+
+ def report_uri
+ return $url_provider.url_for("/reach_report/QMRF/"+@id.to_s, :full).to_s
+ end
+
+ def self.from_xml(report, xml_data)
+
+ raise "xml data size < 255, probably no qmrf report : '"+xml_data.to_s+"'" if xml_data.to_s.size<255
+ doc = Document.new xml_data
+
+ root = doc.elements["QMRF"]
+ raise "no QMRF node found" unless root
+ chapters = root.elements["QMRF_chapters"]
+ raise "no chapter node found" unless chapters
+ $catalogs_node = root.elements["Catalogs"]
+ raise "catalogs not found" unless $catalogs_node
+
+ CHAPTERS.each do |p| #, chapterClass|
+ #unless report.send(p)
+ report.send(p).destroy if report.send(p)
+ c = report.association_class(p).new #chapterClass.new
+ #c.save
+ report.send(p.to_s+"=",c)
+ #end
+ report.send(p).from_xml( chapters.elements[p.xml_alias] )
+ end
+
+ #raise "already exists" if report.qsar_identifier
+ #report.qsar_general_information.destroy if report.qsar_general_information
+ #report.qsar_identifier.clear
+ #report.qsar_general_information = QsarGeneralInformation.new
+ #report.qsar_general_information.qmrf_date = "DateTime.now"
+ #report.qsar_general_information.model_authors << ModelAuthor.new
+ #report.qsar_general_information.qmrf_authors << QmrfAuthor.new
+
+ #report.qsar_identifier = QsarIdentifier.new unless report.qsar_identifier
+ #report.qsar_identifier.from_xml( chapters.elements[:qsar_identifier.xml_alias] )
+
+ #report.qsar_general_information = QsarGeneralInformation.new unless report.qsar_general_information
+ #report.qsar_general_information.from_xml( chapters.elements[:qsar_general_information.xml_alias] )
+
+
+ #QsarGeneralInformation.from_xml( report.qsar_general_information, chapters.elements["qsar_general_information".xml_alias] )
+
+ #puts "set qsar_identifier to "+report.qsar_identifier.class.to_s
+
+# begin
+ report.save
+# rescue DataObjects::SQLError => e
+# puts e.message
+# exit
+# rescue DataObjects::DataError => e
+# puts e.message
+# exit
+# rescue DataMapper::SaveFailureError => e
+# puts e.resource.errors.inspect
+# exit
+# end
+
+# puts "XXXXXXXxxxxx"
+#
+# puts "1"
+# puts report.qsar_miscellaneous.attachment_training_data.inspect
+# puts "2"
+# puts report.qsar_miscellaneous.attachment_validation_data.inspect
+# puts "3"
+# puts report.qsar_miscellaneous.attachment_documents.inspect
+#
+#
+# r = QmrfReport.get(report.id)
+#
+# puts "1"
+# puts r.qsar_miscellaneous.attachment_training_data.inspect
+# puts "2"
+# puts r.qsar_miscellaneous.attachment_validation_data.inspect
+# puts "3"
+# puts r.qsar_miscellaneous.attachment_documents.inspect
+#
+# exit
+
+
+ end
+
+ def to_xml
+ #puts "now qsar_identifier is "+self.qsar_identifier.class.to_s
+
+ doc = Document.new
+ decl = XMLDecl.new
+ decl.encoding = "UTF-8"
+ doc << decl
+ type = DocType.new('QMRF SYSTEM "http://ambit.sourceforge.net/qmrf/jws/qmrf.dtd"')
+ doc << type
+
+ root = Element.new("QMRF")
+ root.add_attributes( "version" => 1.2, "schema_version" => 1.0, "name" => "(Q)SAR Model Reporting Format",
+ "author" => "Joint Research Centre, European Commission", "contact" => "Joint Research Centre, European Commission",
+ "date" => "July 2007", "email" => "qsardb@jrc.it", "url" => "http://ecb.jrc.ec.europa.eu/qsar/" )
+
+ catalogs = Element.new("Catalogs")
+ [ "software_catalog", "algorithms_catalog", "descriptors_catalog",
+ "endpoints_catalog", "publications_catalog", "authors_catalog"].each do |c|
+ catalogs << Element.new(c)
+ end
+ $catalogs_node = catalogs
+
+ chapters = Element.new("QMRF_chapters")
+ chapter_count = 1
+
+ CHAPTERS.each do |p|
+ node = Element.new( p.xml_alias )
+ node.add_attribute("chapter",chapter_count)
+ self.send(p.to_s+"=", self.association_class(p).new) unless self.send(p) # create empy chapter, as xml must be complete
+ self.send(p).to_XML( node, chapter_count )
+ chapters << node
+ chapter_count += 1
+ end
+
+# qsar_identifier_node = Element.new(:qsar_identifier.xml_alias)
+# self.qsar_identifier.to_XML( qsar_identifier_node )
+# chapters << qsar_identifier_node
+#
+# qsar_general_information_node = Element.new(:qsar_general_information.xml_alias)
+# self.qsar_general_information.to_XML( qsar_general_information_node )
+# chapters << qsar_general_information_node
+
+
+
+# [ @qsar_identifier, @qsar_general_information, @qsar_endpoint ].each do |c|
+# n = c.to_xml
+# raise "no node "+n.to_s+" "+n.class.to_s unless n.is_a?(Element)
+# chapters << n
+# end
+
+ root << chapters
+ root << catalogs
+ doc << root
+
+ s = ""
+ doc.write(s, 2, false, false)
+ return s
+
+ end
+ end
+
+#Profile2.auto_upgrade!
+
+# 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
+
+ [ QsarSoftware, QsarIdentifier, QmrfAuthor, ModelAuthor, Reference, QsarGeneralInformation, ModelEndpoint, QsarEndpoint, AlgorithmExplicit,
+ AlgorithmsDescriptor, DescriptorsGenerationSoftware, QsarAlgorithm, AppDomainSoftware, QsarApplicabilityDomain, TrainingSetData,
+ QsarRobustness, ValidationSetData, QsarPredictivity, QsarInterpretation, Bibliography, AttachmentTrainingData, AttachmentValidationData,
+ AttachmentDocument, QsarMiscellaneous, QmrfSummary, QmrfReport ].each do |model|
+ model.auto_upgrade!
+ model.raise_on_save_failure = true
+ end
+end \ No newline at end of file
diff --git a/reach_reports/reach_service.rb b/reach_reports/reach_service.rb
new file mode 100755
index 0000000..53acb62
--- /dev/null
+++ b/reach_reports/reach_service.rb
@@ -0,0 +1,319 @@
+
+class Array
+
+ def to_html
+ return "" unless size>0
+ s = "<html>\n<head>\n</head>\n<body>\n"
+ s += join(" <br>\n")
+ s += "</body>\n</html>\n"
+ return s
+ end
+end
+
+module ReachReports
+
+ def self.list_reports(type)
+ case type
+ when /(?i)QMRF/
+ ReachReports::QmrfReport.all.collect{ |r| r.report_uri }.join("\n")+"\n"
+ when /(?i)QPRF/
+ ReachReports::QprfReport.all.collect{ |r| r.report_uri }.join("\n")+"\n"
+ end
+ end
+
+ def self.create_report( type, params, subjectid, xml_data=nil )
+
+ case type
+ when /(?i)QMRF/
+ if params[:model_uri]
+ task = OpenTox::Task.create( "Create "+type+" report",
+ $url_provider.url_for("/reach_report/"+type, :full) ) do |task| #, params
+
+ report = ReachReports::QmrfReport.new :model_uri => params[:model_uri]
+ report.subjectid = subjectid
+ build_qmrf_report(report, task)
+ report.report_uri
+ end
+ result_uri = task.uri
+ elsif xml_data and (input = xml_data.read).to_s.size>0
+ report = ReachReports::QmrfReport.new
+ report.subjectid = subjectid
+ ReachReports::QmrfReport.from_xml(report,input)
+ result_uri = report.report_uri
+ else
+ raise OpenTox::BadRequestError.new "illegal parameters for qmrf-report creation, either\n"+
+ "* give 'model_uri' as param\n"+
+ "* provide xml file\n"+
+ "params given: "+params.inspect
+ end
+ when /(?i)QPRF/
+ raise OpenTox::BadRequestError.new "qprf report creation not yet implemented"
+ if params[:compound_uri]
+ #report = ReachReports::QprfReport.new :compound_uri => params[:compound_uri]
+ else
+ raise OpenTox::BadRequestError.new "illegal parameters for qprf-report, use either\n"+
+ "* compound-uri\n"+
+ "params given: "+params.inspect
+ end
+ end
+ result_uri
+ end
+
+ def self.build_qmrf_report(r, task=nil)
+
+ #puts r.model_uri
+ model = OpenTox::Model::Generic.find(r.model_uri, r.subjectid)
+ feature_type = model.feature_type(r.subjectid)
+
+ # chapter 1
+ r.qsar_identifier = QsarIdentifier.new
+ r.qsar_identifier.qsar_title = model.metadata[DC.title]
+ # TODO QSAR_models -> sparql same endpoint
+ r.qsar_identifier.qsar_software << QsarSoftware.new( :url => model.uri,
+ :name => model.metadata[DC.title], :contact => model.metadata[DC.creator] )
+ algorithm = OpenTox::Algorithm::Generic.find(model.metadata[OT.algorithm], r.subjectid) if model.metadata[OT.algorithm]
+ r.qsar_identifier.qsar_software << QsarSoftware.new( :url => algorithm.uri, :name => algorithm.metadata[DC.title] )
+ task.progress(10) if task
+
+ #chpater 2
+ r.qsar_general_information = QsarGeneralInformation.new
+ r.qsar_general_information.qmrf_date = DateTime.now.to_s
+ # EMPTY: qmrf_authors, qmrf_date_revision, qmrf_revision
+ # TODO: model_authors ?
+ r.qsar_general_information.model_date = model.metadata[DC.date].to_s
+ # TODO: references?
+ # EMPTY: info_availablity
+ # TODO: related_models = find qmrf reports for QSAR_models
+ task.progress(20) if task
+
+ # chapter 3
+ # TODO "model_species" ?
+ r.qsar_endpoint = QsarEndpoint.new
+ model.metadata[OT.predictedVariables].each do |p|
+ r.qsar_endpoint.model_endpoint << ModelEndpoint.new( :name => p )
+ end if model.metadata[OT.predictedVariables]
+ # TODO "endpoint_comments" => "3.3", "endpoint_units" => "3.4",
+ r.qsar_endpoint.endpoint_variable = model.metadata[OT.dependentVariables] if model.metadata[OT.dependentVariables]
+ # TODO "endpoint_protocol" => "3.6", "endpoint_data_quality" => "3.7",
+ task.progress(30) if task
+
+ # 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
+ task.progress(40) if task
+
+ # chapter 5
+ # TODO app_domain_description, app_domain_method, app_domain_software, applicability_limits
+
+ #training_dataset = model.trainingDataset ? OpenTox::Dataset.find(model.trainingDataset+"/metadata") : nil
+ if ( OpenTox::Dataset.exist?(model.metadata[OT.trainingDataset]) )
+ training_dataset = OpenTox::Dataset.new( model.metadata[OT.trainingDataset] )
+ training_dataset.load_metadata( r.subjectid )
+ else
+ training_dataset = nil
+ LOGGER.warn "build qmrf: training_dataset not found "+model.metadata[OT.trainingDataset].to_s
+ end
+ task.progress(50) if task
+
+ # chapter 6
+ r.qsar_robustness = QsarRobustness.new
+ if training_dataset
+ r.qsar_robustness.training_set_availability = "Yes"
+ r.qsar_robustness.training_set_data = TrainingSetData.new(:chemname => "Yes", :cas => "Yes",
+ :smiles => "Yes", :inchi => "Yes", :mol => "Yes", :formula => "Yes")
+ end
+
+ #TODO "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",
+
+ val_datasets = []
+
+ if algorithm
+ cvs = Lib::Crossvalidation.find_all_uniq({:algorithm_uri => algorithm.uri, :finished => true},r.subjectid)
+ # PENDING: cv classification/regression hack
+ cvs = cvs.delete_if do |cv|
+ #val = Validation::Validation.first( :all, :conditions => { :crossvalidation_id => cv.id } )
+ val = Validation::Validation.first( :crossvalidation_id => cv.id )
+ raise "should not happen: no validations found for crossvalidation "+cv.id.to_s unless val
+ (val.classification_statistics!=nil) != (feature_type=="classification")
+ end
+
+ lmo = [ "found "+cvs.size.to_s+" crossvalidation/s for algorithm '"+algorithm.uri.to_s+"'" ]
+ if cvs.size>0
+ cvs_same_data = []
+ cvs_other_data = []
+ cvs.each do |cv|
+ if cv.dataset_uri == model.metadata[OT.trainingDataset]
+ cvs_same_data << cv
+ else
+ cvs_other_data << cv
+ end
+ end
+ lmo << cvs_same_data.size.to_s+" crossvalidations/s where performed on the training dataset of the model ("+
+ model.metadata[OT.trainingDataset].to_s+")"
+ lmo << cvs_other_data.size.to_s+" crossvalidations/s where performed on the other datasets"
+ lmo << ""
+
+ {cvs_same_data => "training dataset", cvs_other_data => "other datasets"}.each do |cvs,desc|
+ next if cvs.size==0
+ lmo << "crossvalidation/s on "+desc
+ cvs.each do |cv|
+ lmo << "crossvalidation: "+cv.crossvalidation_uri
+ lmo << "dataset (see 9.3 Validation data): "+cv.dataset_uri
+ val_datasets << cv.dataset_uri
+ lmo << "settings: num-folds="+cv.num_folds.to_s+", random-seed="+cv.random_seed.to_s+", stratified:"+cv.stratified.to_s
+
+ val = YAML.load( OpenTox::RestClientWrapper.get(File.join(cv.crossvalidation_uri,"statistics"),{:subjectid => r.subjectid}) )
+ case feature_type
+ when "classification"
+ lmo << "percent_correct: "+val[OT.classificationStatistics][OT.percentCorrect].to_s
+ lmo << "weighted AUC: "+val[OT.classificationStatistics][OT.weightedAreaUnderRoc].to_s
+ when "regression"
+ lmo << "root_mean_squared_error: "+val[OT.regressionStatistics][OT.rootMeanSquaredError].to_s
+ lmo << "r_square "+val[OT.regressionStatistics][OT.rSquare].to_s
+ end
+ reports = OpenTox::RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
+ "report/crossvalidation?crossvalidation_uris="+cv.crossvalidation_uri),{:subjectid => r.subjectid})
+ if reports and reports.chomp.size>0
+ lmo << "for more info see report: "+reports.split("\n")[0]
+ else
+ lmo << "for more info see report: not yet created for '"+cv.crossvalidation_uri+"'"
+ end
+ end
+ lmo << ""
+ end
+ end
+
+ else
+ lmo = [ "no prediction algortihm for model found, crossvalidation not possible" ]
+ end
+ r.qsar_robustness.lmo = lmo.to_html
+ # "lmo" => "6.9", "yscrambling" => "6.10", "bootstrap" => "6.11", "other_statistics" => "6.12",
+
+ LOGGER.debug "looking for validations with "+{:model_uri => model.uri}.inspect
+ #vals = Lib::Validation.find(:all, :conditions => {:model_uri => model.uri})
+ vals = Lib::Validation.all({:model_uri => model.uri})
+ uniq_vals = []
+ vals.each do |val|
+ match = false
+ uniq_vals.each do |val2|
+ if val.test_dataset_uri == val2.test_dataset_uri
+ match = true
+ break
+ end
+ end
+ uniq_vals << val unless match
+ end
+
+ r.qsar_predictivity = QsarPredictivity.new
+ if uniq_vals.size > 0
+ r.qsar_predictivity.validation_set_availability = "Yes"
+ r.qsar_predictivity.validation_set_data = ValidationSetData.new(:chemname => "Yes", :cas => "Yes",
+ :smiles => "Yes", :inchi => "Yes", :mol => "Yes", :formula => "Yes")
+
+ v = [ "found '"+uniq_vals.size.to_s+"' test-set validations of model '"+model.uri+"'" ]
+ v << ""
+ uniq_vals.each do |validation|
+ v << "validation: "+validation.validation_uri
+ v << "dataset (see 9.3 Validation data): "+validation.test_dataset_uri
+ val_datasets << validation.test_dataset_uri
+ case feature_type
+ when "classification"
+ v << "percent_correct: "+validation.classification_statistics[:percent_correct].to_s
+ v << "weighted AUC: "+validation.classification_statistics[:weighted_area_under_roc].to_s
+ when "regression"
+ v << "root_mean_squared_error: "+validation.regression_statistics[:root_mean_squared_error].to_s
+ v << "r_square "+validation.regression_statistics[:r_square].to_s
+ end
+ report = OpenTox::ValidationReport.find_for_validation(validation.validation_uri,r.subjectid)
+ #reports = OpenTox::RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"],
+ # "report/validation?validation_uris="+validation.validation_uri),{:subjectid => r.subjectid})
+ if report
+ v << "for more info see report: "+report.uri
+ else
+ v << "for more info see report: not yet created for '"+validation.validation_uri+"'"
+ end
+ v << ""
+ end
+ else
+ v = [ "no validation for model '"+model.uri+"' found" ]
+ end
+ r.qsar_predictivity.validation_predictivity = v.to_html
+ task.progress(60) if task
+
+ # 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",
+ task.progress(70) if task
+
+ # chapter 8
+ # "mechanistic_basis" => "8.1", "mechanistic_basis_comments" => "8.2", "mechanistic_basis_info" => "8.3",
+ task.progress(80) if task
+
+ # chapter 9
+ # "comments" => "9.1", "bibliography" => "9.2", "attachments" => "9.3",
+
+ r.qsar_miscellaneous = QsarMiscellaneous.new
+
+ r.qsar_miscellaneous.attachment_training_data << AttachmentTrainingData.new(
+ { :description => training_dataset.title,
+ :filetype => "owl-dl",
+ :url => training_dataset.uri} ) if training_dataset
+
+ val_datasets.each do |data_uri|
+ if OpenTox::Dataset.exist?(data_uri, r.subjectid)
+ d = OpenTox::Dataset.new(data_uri)
+ d.load_metadata( r.subjectid)
+ r.qsar_miscellaneous.attachment_validation_data << AttachmentValidationData.new(
+ { :description => d.title,
+ :filetype => "owl-dl",
+ :url => data_uri} )
+ end
+ end
+ task.progress(90) if task
+
+ r.save
+ task.progress(100) if task
+ 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.get(id)
+ when /(?i)QPRF/
+ report = ReachReports::QprfReport.get(id)
+ end
+ raise OpenTox::NotFoundError.new type+" report with id '#{id}' not found." unless report
+ return report
+ end
+
+ def self.delete_report(type, id, subjectid=nil)
+
+ case type
+ when /(?i)QMRF/
+ report = ReachReports::QmrfReport.get(id)
+ when /(?i)QPRF/
+ report = ReachReports::QprfReport.get(id)
+ end
+ raise OpenTox::NotFoundError.new type+" report with id '#{id}' not found." unless report
+ OpenTox::Authorization.delete_policies_from_uri(report.report_uri, subjectid) if subjectid
+ return report.destroy
+ end
+
+end
diff --git a/reach_reports/reach_test.rb b/reach_reports/reach_test.rb
new file mode 100755
index 0000000..87addfa
--- /dev/null
+++ b/reach_reports/reach_test.rb
@@ -0,0 +1,284 @@
+
+require "rubygems"
+require "sinatra"
+before {
+ request.env['HTTP_HOST']="local-ot/validation"
+ request.env["REQUEST_URI"]=request.env["PATH_INFO"]
+}
+
+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 = OTLogger.new(STDOUT)
+LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S "
+LOGGER.formatter = Logger::Formatter.new
+
+if AA_SERVER
+ #TEST_USER = "mgtest"
+ #TEST_PW = "mgpasswd"
+ TEST_USER = "guest"
+ TEST_PW = "guest"
+ SUBJECTID = OpenTox::Authorization.authenticate(TEST_USER,TEST_PW)
+ raise "could not log in" unless SUBJECTID
+ puts "logged in: "+SUBJECTID.to_s
+else
+ puts "AA disabled"
+ SUBJECTID = nil
+end
+
+#Rack::Test::DEFAULT_HOST = "local-ot/validation"
+module Sinatra
+ module UrlForHelper
+ BASE = "http://local-ot/validation"
+ def url_for url_fragment, mode=:path_only
+ case mode
+ when :path_only
+ raise "not impl"
+ when :full
+ end
+ "#{BASE}#{url_fragment}"
+ end
+ end
+ set :raise_errors, false
+ set :show_exceptions, false
+end
+
+
+#DataMapper::Model.raise_on_save_failure = true
+#
+#class TestResourceX
+# include DataMapper::Resource
+#
+# property :id, Serial
+#
+# has 1, :test_resource
+#end
+#
+#class DataMapper::Associations::ManyToOne::Relationship
+# def get_parent_model
+# @parent_model
+# end
+#end
+#
+#class TestResource
+# include DataMapper::Resource
+#
+# property :id, Serial
+# property :time, DateTime
+# property :body, Text
+#
+# def self.info
+# relationships.each do |k,v|
+# puts k
+# puts v.inspect
+# puts v.get_parent_model
+#
+# end
+# end
+# #validates_format_of :time
+# #validates_length_of :body, :minimum => 1000
+#
+# belongs_to :test_resource_x
+#end
+#
+#TestResourceX.auto_upgrade!
+#TestResource.auto_upgrade!
+
+class ReachTest < Test::Unit::TestCase
+ include Rack::Test::Methods
+ include Lib::TestUtil
+
+ def app
+ Sinatra::Application
+ end
+
+ def test_it
+
+ begin
+
+ # delete '/reach_report/QMRF/3'
+ # puts last_response.body
+
+ #exit
+# testResource = TestResource.new
+#
+# TestResource.info
+# exit
+
+# p = nil
+# #puts TestResource.properties.inspect
+# TestResource.properties.each do |pp|
+# p = pp if pp.name==:time
+# end
+# #puts p
+# val = "no time" #DateTime.new
+# testResource.time = val
+# #puts p.valid?(val)
+#
+# #puts "test restource: "+testResource.valid?.to_s
+#
+# #puts testResource.time.to_s + " " + testResource.time.class.to_s
+# begin
+# testResource.save
+# rescue DataMapper::SaveFailureError => e
+# puts e.message
+# puts e.resource.errors.inspect
+# end
+# exit
+
+ #$test_case = self
+
+# #file = File.new("qmrf-report.xml")
+# file = File.new("/home/martin/win/home/test2.xml")
+# raise "File not found: "+file.path.to_s unless File.exist?(file.path)
+# data = File.read(file.path)
+# #puts "data found "+data.to_s[0..1000]
+# puts OpenTox::RestClientWrapper.post("http://local-ot/validation/reach_report/qmrf/20",{:content_type => "application/qmrf-xml"},data).to_s.chomp
+
+# post "/reach_report/qmrf/8"
+# puts last_response.body
+
+ #model_uri = "http://ambit.uni-plovdiv.bg:8080/ambit2/model/173393"
+
+ #model_uri = "http://local-ot/majority/class/model/58"
+
+
+ #model_uri = "http://local-ot/model/104"
+ model_uri = "http://local-ot/majority/class/model/125"
+
+
+# m = OpenTox::Model::Generic.find(model_uri)
+# puts m.metadata[OT.algorithm] if m
+# a = OpenTox::Algorithm::Generic.find(m.metadata[OT.algorithm])
+# puts a.metadata.inspect
+# exit
+
+ puts SUBJECTID
+
+# model_uri = "http://local-ot/model/1"
+ #http://local-ot/majority/class/model/15
+ #model_uri = "http://local-ot/majority/class/model/15"
+ # model_uri = "http://local-ot/majority/class/model/91"
+ #model_uri = "http://apps.ideaconsult.net:8080/ambit2/model/2"
+ post '/reach_report/qmrf',{:model_uri=>model_uri, :subjectid => SUBJECTID} #http://local-ot/model/1"
+ ##post '/reach_report/qprf',:compound_uri=>"http://local-ot/compound/XYZ"
+ uri = last_response.body
+ puts "task: "+uri.to_s
+ uri = Lib::TestUtil.wait_for_task(uri)
+ if uri
+ id = uri.split("/")[-1]
+ puts uri
+ end
+
+# id = "8"
+
+ #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
+
+
+ #r = ReachReports::QmrfReport.find_like( :QSAR_title => "Hamster")
+ #puts r.collect{|rr| "report with id:"+rr.id.to_s}.inspect
+
+ #File.new("/home/martin/tmp/qmr_rep_del_me.xml","w").puts last_response.body
+ #File.new("/home/martin/win/home/qmr_rep_del_me.xml","w").puts last_response.body
+ #File.new("/home/martin/info_home/.public_html/qmr_rep_del_me.xml","w").puts last_response.body
+
+ rescue => ex
+ rep = OpenTox::ErrorReport.create(ex, "")
+ puts rep.to_yaml
+ end
+
+
+ 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
+
+#class Person
+# include DataMapper::Resource
+#
+# property :id, Serial
+#
+# has 1, :profile
+# has 1, :profile2
+# end
+#
+# class Profile
+# include DataMapper::Resource
+#
+# property :id, Serial
+# property :val, Text
+#
+# belongs_to :person
+# end
+#
+# class Profile2
+# include DataMapper::Resource
+#
+# property :id, Serial
+# property :val, Text
+#
+# belongs_to :person
+# end
+#
+#Person.auto_upgrade!
+#Profile.auto_upgrade!
+#Profile2.auto_upgrade!
+#
+# A.auto_upgrade!
+# ValTest.auto_upgrade!
+ #A.auto_migrate!
+ #ValTest.auto_migrate!
+
+# class ReachTest < Test::Unit::TestCase
+# include Rack::Test::Methods
+# include Lib::TestUtil
+#
+#
+# def app
+# Sinatra::Application
+# end
+#
+# def test_datamapper
+#
+# # Assigning a resource to a one-to-one relationship
+# puts Person.all.collect{|v| v.id}.inspect
+#
+# person = Person.create
+# person.profile = Profile.new
+# person.profile2 = Profile2.new
+# person.profile2.val = "bla"
+# person.save
+#
+# p = Person.get(11)
+## puts p.profile2
+# puts p.profile2.val
+