diff options
author | mguetlein <martin.guetlein@gmail.com> | 2011-02-07 15:38:33 +0100 |
---|---|---|
committer | mguetlein <martin.guetlein@gmail.com> | 2011-02-07 15:38:33 +0100 |
commit | d99823f61fc3b2f463bc1a51db0a952c965c2141 (patch) | |
tree | caf259594bc93a7f0eeaf14e217cc9c6a6ff06ae | |
parent | 67e72fe916dab5c0ee18e65d4cbc1f3e0ed64b99 (diff) |
add a&a to qmrf reports
-rwxr-xr-x | lib/validation_db.rb | 3 | ||||
-rwxr-xr-x | reach_reports/reach_application.rb | 7 | ||||
-rwxr-xr-x | reach_reports/reach_persistance.rb | 11 | ||||
-rwxr-xr-x | reach_reports/reach_service.rb | 42 | ||||
-rwxr-xr-x | reach_reports/reach_test.rb | 4 | ||||
-rwxr-xr-x | report/validation_access.rb | 219 | ||||
-rw-r--r-- | test/unit_test.rb | 35 | ||||
-rwxr-xr-x | validation/validation_service.rb | 1 | ||||
-rwxr-xr-x | validation/validation_test.rb | 61 |
9 files changed, 118 insertions, 265 deletions
diff --git a/lib/validation_db.rb b/lib/validation_db.rb index c4cb2a2..25f1d66 100755 --- a/lib/validation_db.rb +++ b/lib/validation_db.rb @@ -150,11 +150,12 @@ module Lib # convenience method to list all crossvalidations that are unique # in terms of dataset_uri,num_folds,stratified,random_seed # further conditions can be specified in __conditions__ - def self.find_all_uniq(conditions={}) + def self.find_all_uniq(conditions={}, subjectid=nil ) #cvs = Lib::Crossvalidation.find(:all, :conditions => conditions) cvs = Lib::Crossvalidation.all(:conditions => conditions) uniq = [] cvs.each do |cv| + next if AA_SERVER and !OpenTox::Authorization.authorized?(cv.crossvalidation_uri,"GET",subjectid) match = false uniq.each do |cv2| if cv.dataset_uri == cv2.dataset_uri and cv.num_folds == cv2.num_folds and diff --git a/reach_reports/reach_application.rb b/reach_reports/reach_application.rb index fd77078..969ce8b 100755 --- a/reach_reports/reach_application.rb +++ b/reach_reports/reach_application.rb @@ -65,7 +65,7 @@ post '/reach_report/:type' do LOGGER.info "creating "+type+" report "+params.inspect #puts "creating "+type+" report "+params.inspect - result_uri = ReachReports.create_report(type,params,request.env["rack.input"]) + 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" @@ -123,6 +123,11 @@ post '/reach_report/:type/:id' do #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 diff --git a/reach_reports/reach_persistance.rb b/reach_reports/reach_persistance.rb index ec45ba4..3118809 100755 --- a/reach_reports/reach_persistance.rb +++ b/reach_reports/reach_persistance.rb @@ -1001,6 +1001,17 @@ module ReachReports 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 diff --git a/reach_reports/reach_service.rb b/reach_reports/reach_service.rb index f5b4b12..028a53c 100755 --- a/reach_reports/reach_service.rb +++ b/reach_reports/reach_service.rb @@ -21,7 +21,7 @@ module ReachReports end end - def self.create_report( type, params, xml_data=nil ) + def self.create_report( type, params, subjectid, xml_data=nil ) case type when /(?i)QMRF/ @@ -30,12 +30,14 @@ module ReachReports $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 @@ -57,14 +59,11 @@ module ReachReports result_uri end - - def self.build_qmrf_report(r, task=nil) #puts r.model_uri - model = OpenTox::Model::Generic.find(r.model_uri) - raise "model not found "+r.model_uri.to_s unless model - feature_type = model.feature_type + model = OpenTox::Model::Generic.find(r.model_uri, r.subjectid) + feature_type = model.feature_type(r.subjectid) # chapter 1 r.qsar_identifier = QsarIdentifier.new @@ -132,7 +131,7 @@ module ReachReports val_datasets = [] if algorithm - cvs = Lib::Crossvalidation.find_all_uniq({:algorithm_uri => algorithm.uri, :finished => true}) + 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 } ) @@ -165,7 +164,8 @@ module ReachReports 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") ) + + 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 @@ -174,7 +174,8 @@ module ReachReports 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) + 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 @@ -226,10 +227,11 @@ module ReachReports 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 - reports = OpenTox::RestClientWrapper.get(File.join(CONFIG[:services]["opentox-validation"], - "report/validation?validation_uris="+validation.validation_uri)) - if reports and reports.size>0 - v << "for more info see report: "+reports.split("\n")[0] + 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 @@ -299,4 +301,18 @@ module ReachReports 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 index 9a354e7..7d1569d 100755 --- a/reach_reports/reach_test.rb +++ b/reach_reports/reach_test.rb @@ -76,6 +76,10 @@ class ReachTest < Test::Unit::TestCase def test_it + delete '/reach_report/QMRF/3' + puts last_response.body + + exit # testResource = TestResource.new # # TestResource.info diff --git a/report/validation_access.rb b/report/validation_access.rb index 83ca144..53ecc46 100755 --- a/report/validation_access.rb +++ b/report/validation_access.rb @@ -1,57 +1,11 @@ require "lib/validation_db.rb" -# = Reports::ValidationAccess +# = Reports::ValidationDB # -# service that connects (mainly) to the validation-service +# connects directly to the validation db, overwirte with restclient calls +# if reports/reach reports are seperated from validation someday # -class Reports::ValidationAccess - - # initialize Reports::Validation object with data from Lib:Validation object - # - def init_validation(validation, uri, subjectid=nil) - raise "not implemented" - end - - # sets cv-attributes in Reports::Validation object - # - def init_cv(validation) - raise "not implemented" - end - - # yields predictions (Lib::OTPredictions) if available - # - def get_predictions(validation, subjectid=nil, task=nil) - raise "not implemented" - end - - # replaces crossvalidations uris with corresponding validation uris, in-/output: array - # - def resolve_cv_uris(validation_uris,subjectid=nil) - raise "not implemented" - end - - # get domain/class values of prediction feature - # - def get_class_domain(validation) - raise "not implemented" - end - - # is validation classification/regression? - def feature_type(validation, subjectid=nil) - raise "not implemented" - end - - def predicted_variable(validation, subjectid=nil) - raise "not implemented" - end - -end - -class Reports::ValidationDB < Reports::ValidationAccess - -# def initialize() -# @model_store = {} -# end +class Reports::ValidationDB def resolve_cv_uris(validation_uris, subjectid=nil) res = [] @@ -150,168 +104,3 @@ class Reports::ValidationDB < Reports::ValidationAccess # end end - -# -# OUTDATED, please update before use -# -class Reports::ValidationWebservice < Reports::ValidationAccess - - def resolve_cv_uris(validation_uris) - res = [] - validation_uris.each do |u| - if u.to_s =~ /.*\/crossvalidation\/.*/ - uri = u.to_s+"/validations" - begin - vali_uri_list = RestClientWrapper.get uri - rescue => ex - raise OpenTox::BadRequestError.new "cannot get validations for cv at '"+uri.to_s+"', error msg: "+ex.message - end - res += vali_uri_list.split("\n") - else - res += [u.to_s] - end - end - res - end - - - def init_validation(validation, uri) - - begin - data = YAML.load(RestClient.get uri) - rescue => ex - raise OpenTox::BadRequestError.new "cannot get validation at '"+uri.to_s+"', error msg: "+ex.message - end - - Lib::VAL_PROPS.each do |p| - validation.send("#{p}=".to_sym, data[p]) - end - - #model = OpenTox::Model::LazarClassificationModel.new(v[:model_uri]) - #raise "cannot access model '"+v[:model_uri].to_s+"'" unless model - #validation.prediction_feature = model.get_prediction_feature - - {Lib::VAL_CV_PROP => Lib::VAL_CV_PROPS, - Lib::VAL_CLASS_PROP => Lib::VAL_CLASS_PROPS_EXTENDED}.each do |subset_name,subset_props| - subset = data[subset_name] - subset_props.each{ |prop| validation.send("#{prop}=".to_sym, subset[prop]) } if subset - end - end - - def init_cv(validation) - - raise "cv-uri not set" unless validation.crossvalidation_uri - - begin - data = YAML.load(RestClient.get validation.crossvalidation_uri) - rescue => ex - raise OpenTox::BadRequestError.new "cannot get crossvalidation at '"+validation.crossvalidation_uri.to_s+"', error msg: "+ex.message - end - - Lib::CROSS_VAL_PROPS.each do |p| - validation.send("#{p.to_s}=".to_sym, data[p]) - end - end - - def get_predictions(validation, subjectid=nil, task=nil) - Lib::Predictions.new( validation.prediction_feature, validation.test_dataset_uri, validation.prediction_dataset_uri) - end -end - -# = Reports::OTMockLayer -# -# OUTDATED, please update before use -# -# does not connect to other services, provides randomly generated data -# -class Reports::ValidationMockLayer < Reports::ValidationAccess - - NUM_DATASETS = 1 - NUM_ALGS = 4 - NUM_FOLDS = 5 - NUM_PREDICTIONS = 30 - ALGS = ["naive-bayes", "c4.5", "svm", "knn", "lazar", "id3"] - DATASETS = ["hamster", "mouse" , "rat", "dog", "cat", "horse", "bug", "ant", "butterfly", "rabbit", "donkey", "monkey", "dragonfly", "frog", "dragon", "dinosaur"] - FOLDS = [1,2,3,4,5,6,7,8,9,10] - - def initialize - - super - @algs = [] - @datasets = [] - @folds = [] - sum = NUM_DATASETS*NUM_ALGS*NUM_FOLDS - (0..sum-1).each do |i| - @folds[i] = FOLDS[i%NUM_FOLDS] - @algs[i] = ALGS[(i/NUM_FOLDS)%NUM_ALGS] - @datasets[i] = DATASETS[((i/NUM_FOLDS)/NUM_ALGS)%NUM_DATASETS] - end - @count = 0 - end - - def resolve_cv_uris(validation_uris) - res = [] - validation_uris.each do |u| - if u.to_s =~ /.*crossvalidation.*/ - res += ["validation_x"]*NUM_FOLDS - else - res += [u.to_s] - end - end - res - end - - def init_validation(validation, uri) - - validation.model_uri = @algs[@count] - validation.test_dataset_uri = @datasets[@count] - validation.prediction_dataset_uri = "bla" - - cv_id = @count/NUM_FOLDS - validation.crossvalidation_id = cv_id - validation.crossvalidation_fold = @folds[@count] - - validation.auc = 0.5 + cv_id*0.02 + rand/3.0 - validation.acc = 0.5 + cv_id*0.02 + rand/3.0 - validation.tp = 1 - validation.fp = 1 - validation.tn = 1 - validation.fn = 1 - - validation.algorithm_uri = @algs[@count] - validation.training_dataset_uri = @datasets[@count] - validation.test_dataset_uri = @datasets[@count] - - validation.prediction_feature = "classification" - - @count += 1 - end - - def init_cv(validation) - - raise "cv-id not set" unless validation.crossvalidation_id - - validation.num_folds = NUM_FOLDS - validation.algorithm_uri = @algs[validation.crossvalidation_id.to_i * NUM_FOLDS] - validation.dataset_uri = @datasets[validation.crossvalidation_id.to_i * NUM_FOLDS] - validation.stratified = true - validation.random_seed = 1 - #validation.CV_dataset_name = @datasets[validation.crossvalidation_id.to_i * NUM_FOLDS] - end - - def get_predictions(validation, task=nil) - - p = Array.new - c = Array.new - conf = Array.new - u = Array.new - (0..NUM_PREDICTIONS).each do |i| - p.push rand(2) - c.push rand(2) - conf.push rand - u.push("compound no"+(i+1).to_s) - end - Lib::MockPredictions.new( p, c, conf, u ) - end - - end diff --git a/test/unit_test.rb b/test/unit_test.rb index 8474dd2..bc5167e 100644 --- a/test/unit_test.rb +++ b/test/unit_test.rb @@ -49,9 +49,10 @@ class ValidationTest < Test::Unit::TestCase def global_teardown puts "delete and logout" - OpenTox::Dataset.find(@@data_class_mini,@@subjectid).delete(@@subjectid) + OpenTox::Dataset.find(@@data_class_mini,@@subjectid).delete(@@subjectid) if defined?@@data_class_mini @@cv.delete(@@subjectid) if defined?@@cv @@report.delete(@@subjectid) if defined?@@report + @@qmrfReport.delete(@@subjectid) if defined?@@qmrfReport OpenTox::Authorization.logout(@@subjectid) if AA_SERVER end @@ -86,18 +87,20 @@ class ValidationTest < Test::Unit::TestCase end def test_crossvalidation_report + #@@cv = OpenTox::Crossvalidation.find("http://local-ot/validation/crossvalidation/47", @@subjectid) + puts "test_crossvalidation_report" assert defined?@@cv,"no crossvalidation defined" assert_kind_of OpenTox::Crossvalidation,@@cv assert_rest_call_error OpenTox::NotFoundError do - OpenTox::CrossvalidationReport.find_for_crossvalidation(@@cv) + OpenTox::CrossvalidationReport.find_for_crossvalidation(@@cv.uri) end if @@subjectid assert_rest_call_error OpenTox::NotAuthorizedError do - OpenTox::CrossvalidationReport.create(@@cv) + OpenTox::CrossvalidationReport.create(@@cv.uri) end end - report = OpenTox::CrossvalidationReport.create(@@cv,@@subjectid) + report = OpenTox::CrossvalidationReport.create(@@cv.uri,@@subjectid) assert report.uri.uri? if @@subjectid assert_rest_call_error OpenTox::NotAuthorizedError do @@ -106,13 +109,35 @@ class ValidationTest < Test::Unit::TestCase end report = OpenTox::CrossvalidationReport.find(report.uri,@@subjectid) assert report.uri.uri? - report2 = OpenTox::CrossvalidationReport.find_for_crossvalidation(@@cv,@@subjectid) + report2 = OpenTox::CrossvalidationReport.find_for_crossvalidation(@@cv.uri,@@subjectid) assert_equal report.uri,report2.uri report3 = @@cv.find_or_create_report(@@subjectid) assert_equal report.uri,report3.uri @report = report end + def test_qmrf_report + #@@cv = OpenTox::Crossvalidation.find("http://local-ot/validation/crossvalidation/47", @@subjectid) + + puts "test_qmrf_report" + assert defined?@@cv,"no crossvalidation defined" + + validations = @@cv.metadata[OT.validation] + assert_kind_of Array,validations + assert validations.size==@@cv.metadata[OT.numFolds] + + val = OpenTox::Validation.find(validations[0], @@subjectid) + model_uri = val.metadata[OT.model] + model = OpenTox::Model::Generic.find(model_uri, @@subjectid) + assert model!=nil + + assert_rest_call_error OpenTox::NotFoundError do + OpenTox::QMRFReport.find_for_model(model_uri, @@subjectid) + end + + @@qmrfReport = OpenTox::QMRFReport.create(model_uri, @@subjectid) + end + ################### utils and overrides ########################## def app diff --git a/validation/validation_service.rb b/validation/validation_service.rb index 0ef01ae..944bed6 100755 --- a/validation/validation_service.rb +++ b/validation/validation_service.rb @@ -130,7 +130,6 @@ module Validation #model = OpenTox::Model::PredictionModel.find(self.model_uri) #raise OpenTox::NotFoundError.new "model not found: "+self.model_uri.to_s unless model model = OpenTox::Model::Generic.find(self.model_uri, self.subjectid) - raise OpenTox::NotFoundError.new "model not found: "+self.model_uri.to_s unless model unless self.algorithm_uri # self.attributes = { :algorithm_uri => model.algorithm } diff --git a/validation/validation_test.rb b/validation/validation_test.rb index 27fd6b1..bfdd563 100755 --- a/validation/validation_test.rb +++ b/validation/validation_test.rb @@ -20,10 +20,10 @@ 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" +# 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 @@ -63,7 +63,8 @@ class ValidationTest < Test::Unit::TestCase # begin # #OpenTox::RestClientWrapper.get "http://local-ot/validation/runtime-error",{:accept => "application/rdf+xml"} # puts OpenTox::RestClientWrapper.post "http://opentox.ntua.gr:4000/model/0d8a9a27-3481-4450-bca1-d420a791de9d", -# {:dataset=>"http://apps.ideaconsult.net:8080/ambit2/dataset/54"},{:accept => "text/uri-list", :subjectid => SUBJECTID} +# { :asdfasdf => "asdfasdf" } #{:dataset=>"http://apps.ideaconsult.net:8080/ambit2/dataset/54?max=2"}, +# { :accept => "text/uri-list", :subjectid => SUBJECTID } # #puts OpenTox::RestClientWrapper.post "http://opentox.ntua.gr:4000/model/0d8a9a27-3481-4450-bca1-d420a791de9d",{},{:accept => "text/uri-list", :subjectid => "AQIC5wM2LY4SfcwUNX97nTvaSTdYJ+nTUqZsR0UitJ4+jlc=@AAJTSQACMDE=#"} # rescue => err # rep = OpenTox::ErrorReport.create(err, "") @@ -151,27 +152,29 @@ class ValidationTest < Test::Unit::TestCase # puts val # get "/"+val.split("/")[-1] - #run_test("17a") #,"http://local-ot/validation/39",nil,false) #,"http://local-ot/validation/28")#,"http://local-ot/validation/394"); - + #run_test("1a",:validation_uri=>"http://local-ot/validation/119") #,"http://local-ot/validation/28")#,"http://local-ot/validation/394"); + + run_test("3b",:validation_uri=>"http://local-ot/validation/crossvalidation/45") #,{:dataset_uri => "http://local-ot/dataset/773", :prediction_feature => "http://local-ot/dataset/773/feature/Hamster%20Carcinogenicity"}) + # p = { -# :dataset_uri=>"http://local-ot/dataset/388", +# :dataset_uri=>"http://local-ot/dataset/527", # :algorithm_uri => "http://local-ot/majority/class/algorithm", -# :prediction_feature=>"http://local-ot/dataset/388/feature/repdose_classification", +# :prediction_feature=>"http://local-ot/dataset/527/feature/Hamster%20Carcinogenicity", # :num_folds => 2 } - #cv = OpenTox::Crossvalidation.create(p) -# cv = OpenTox::Crossvalidation.find("http://local-ot/validation/crossvalidation/14") + #cv = OpenTox::Crossvalidation.create(p, SUBJECTID) +# cv = OpenTox::Crossvalidation.find("http://local-ot/validation/crossvalidation/17", SUBJECTID) # puts cv.uri -# puts cv.find_or_create_report.uri -# puts cv.summary.inspect +## puts cv.find_or_create_report.uri +# puts cv.summary(SUBJECTID).inspect #puts OpenTox::Authorization.list_policy_uris(SUBJECTID).inspect #puts OpenTox::Authorization.list_policy_uris(SUBJECTID).inspect - #run_test("1b") #,{:dataset_uri => "http://local-ot/dataset/313", :prediction_feature => "http://local-ot/dataset/313/feature/repdose_classification"}) +# run_test("16b") #,{:dataset_uri => "http://local-ot/dataset/313", :prediction_feature => "http://local-ot/dataset/313/feature/repdose_classification"}) - model = OpenTox::Model::Generic.find("http://local-ot/majority/class/model/58") - OpenTox::QMRFReport.create(model) +# model = OpenTox::Model::Generic.find("http://local-ot/majority/class/model/58") +# OpenTox::QMRFReport.create(model) #get "/12123123123123123" @@ -242,23 +245,23 @@ class ValidationTest < Test::Unit::TestCase ex.validate LOGGER.debug "validation done '"+ex.validation_uri.to_s+"'" - if !delete and ex.validation_uri - if SUBJECTID - puts ex.validation_uri+"?subjectid="+CGI.escape(SUBJECTID) - else - puts ex.validation_uri - end + end + if !delete and ex.validation_uri + if SUBJECTID + puts ex.validation_uri+"?subjectid="+CGI.escape(SUBJECTID) + else + puts ex.validation_uri end - end + unless ex.report_uri ex.report - if !delete and ex.report_uri - if SUBJECTID - puts ex.report_uri+"?subjectid="+CGI.escape(SUBJECTID) - else - puts ex.report_uri - end + end + if !delete and ex.report_uri + if SUBJECTID + puts ex.report_uri+"?subjectid="+CGI.escape(SUBJECTID) + else + puts ex.report_uri end end ##ex.verify_yaml |