From 69a69a4f470a8935069681207db9b531452fb595 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Mon, 19 Jul 2010 12:12:19 +0200 Subject: regression added --- application.rb | 15 +++++++++++ config.ru | 1 + environment.rb | 5 ---- lazar.rb | 78 +++++++++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 79 insertions(+), 20 deletions(-) delete mode 100644 environment.rb diff --git a/application.rb b/application.rb index 304f8c0..3992153 100644 --- a/application.rb +++ b/application.rb @@ -16,6 +16,21 @@ DataMapper.auto_upgrade! require 'lazar.rb' + +helpers do + def activity(a) + case a.to_s + when "true" + act = "active" + when "false" + act = "inactive" + else + act = "not available" + end + act + end +end + get '/?' do # get index of models response['Content-Type'] = 'text/uri-list' Model.all(params).collect{|m| m.uri}.join("\n") + "\n" diff --git a/config.ru b/config.ru index 489932f..6f5db40 100644 --- a/config.ru +++ b/config.ru @@ -1,5 +1,6 @@ require 'rubygems' require 'opentox-ruby-api-wrapper' require 'config/config_ru' +set :app_file, __FILE__ # to get the view path right run Sinatra::Application diff --git a/environment.rb b/environment.rb deleted file mode 100644 index 067fc18..0000000 --- a/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rubygems' -require 'opentox-ruby-api-wrapper' - -set :default_content, :yaml -load 'models.rb' diff --git a/lazar.rb b/lazar.rb index 3bc441e..7e0bb98 100755 --- a/lazar.rb +++ b/lazar.rb @@ -3,6 +3,7 @@ # avoids compiling R with X R = nil require ("rinruby") +require ("haml") class Lazar < Model @@ -21,6 +22,8 @@ class Lazar < Model conf = 0.0 similarities = {} + activities = {} + fragments = { :activating => {}, :deactivating => {} } regression = nil regr_occurrences = [] # occurrence vector with {0,1} entries @@ -36,6 +39,8 @@ class Lazar < Model lazar.activities[uri].each do |act| if sim > 0.3 similarities[uri] = sim + activities[uri] = [] unless activities[uri] + activities[uri] << act conf += OpenTox::Utils.gauss(sim) sims << OpenTox::Utils.gauss(sim) #TODO check for 0 s @@ -102,11 +107,13 @@ class Lazar < Model prediction.compounds << compound_uri prediction.features << feature_uri prediction.data[compound_uri] = [] unless prediction.data[compound_uri] + compound_matches.each { |m| fragments[lazar.effects[m].to_sym][m] = lazar.p_values[m] } tuple = { File.join(@@config[:services]["opentox-model"],"lazar#regression") => regression, - File.join(@@config[:services]["opentox-model"],"lazar#confidence") => conf + File.join(@@config[:services]["opentox-model"],"lazar#confidence") => conf, #File.join(@@config[:services]["opentox-model"],"lazar#similarities") => similarities, - #File.join(@@config[:services]["opentox-model"],"lazar#features") => compound_matches + #File.join(@@config[:services]["opentox-model"],"lazar#activities") => activities, + #File.join(@@config[:services]["opentox-model"],"lazar#features") => fragments } prediction.data[compound_uri] << {feature_uri => tuple} end @@ -124,6 +131,9 @@ class Lazar < Model conf = 0.0 similarities = {} + #activities = {} + fragments = { :activating => {}, :deactivating => {} } + neighbors = {} classification = nil lazar.fingerprints.each do |uri,matches| @@ -131,7 +141,22 @@ class Lazar < Model sim = OpenTox::Algorithm::Similarity.weighted_tanimoto(compound_matches,matches,lazar.p_values) if sim > 0.3 similarities[uri] = sim + neighbors[uri] = {:similarity => sim} + neighbors[uri][:features] = { :activating => [], :deactivating => [] } unless neighbors[uri][:features] + matches.each do |m| + if lazar.effects[m] == 'activating' + neighbors[uri][:features][:activating] << {:smarts => m, :p_value => lazar.p_values[m]} + elsif lazar.effects[m] == 'deactivating' + neighbors[uri][:features][:deactivating] << {:smarts => m, :p_value => lazar.p_values[m]} + end + end + #neighbors[uri][:features] = [] unless neighbors[uri][:features] + #neighbors[uri][:features] << matches lazar.activities[uri].each do |act| + #activities[uri] = [] unless activities[uri] + #activities[uri] << act + neighbors[uri][:activities] = [] unless neighbors[uri][:activities] + neighbors[uri][:activities] << act case act.to_s when 'true' conf += OpenTox::Utils.gauss(sim) @@ -153,11 +178,13 @@ class Lazar < Model prediction.compounds << compound_uri prediction.features << feature_uri prediction.data[compound_uri] = [] unless prediction.data[compound_uri] + compound_matches.each { |m| fragments[lazar.effects[m].to_sym][m] = lazar.p_values[m] } + #fragments[:activating] = fragments[:activating].sort{|a,b| b[1] <=> a[1]} tuple = { File.join(@@config[:services]["opentox-model"],"lazar#classification") => classification, - File.join(@@config[:services]["opentox-model"],"lazar#confidence") => conf - #File.join(@@config[:services]["opentox-model"],"lazar#similarities") => similarities, - #File.join(@@config[:services]["opentox-model"],"lazar#features") => compound_matches + File.join(@@config[:services]["opentox-model"],"lazar#confidence") => conf, + #File.join(@@config[:services]["opentox-model"],"lazar#neighbors") => neighbors, + #File.join(@@config[:services]["opentox-model"],"lazar#features") => fragments } prediction.data[compound_uri] << {feature_uri => tuple} end @@ -278,10 +305,10 @@ post '/:id/?' do # create prediction halt 404, "Model #{params[:id]} does not exist." unless lazar halt 404, "No compound_uri or dataset_uri parameter." unless compound_uri = params[:compound_uri] or dataset_uri = params[:dataset_uri] - prediction = OpenTox::Dataset.new - prediction.creator = lazar.uri + @prediction = OpenTox::Dataset.new + @prediction.creator = lazar.uri dependent_variable = YAML.load(lazar.yaml).dependentVariables - prediction.title = URI.decode(dependent_variable.split(/#/).last) + @prediction.title = URI.decode(dependent_variable.split(/#/).last) case dependent_variable when /classification/ prediction_type = "classification" @@ -292,18 +319,39 @@ post '/:id/?' do # create prediction if compound_uri # AM: switch here between regression and classification begin - eval "lazar.#{prediction_type}(compound_uri,prediction) unless lazar.database_activity?(compound_uri,prediction)" + eval "lazar.#{prediction_type}(compound_uri,@prediction) unless lazar.database_activity?(compound_uri,@prediction)" rescue LOGGER.error "#{prediction_type} failed for #{compound_uri} with #{$!} " halt 500, "Prediction of #{compound_uri} failed." end case request.env['HTTP_ACCEPT'] when /yaml/ - prediction.to_yaml + @prediction.to_yaml when 'application/rdf+xml' - prediction.to_owl - else - halt 404, "Content type #{request.env['HTTP_ACCEPT']} not available." + @prediction.to_owl + when /html/ + @compound = OpenTox::Compound.new(:uri => compound_uri) + @title = @prediction.title + if @prediction.data[@compound.uri] + if @prediction.creator.to_s.match(/model/) # real prediction + p = @prediction.data[@compound.uri].first.values.first + if !p[File.join(@@config[:services]["opentox-model"],"lazar#classification")].nil? + feature = File.join(@@config[:services]["opentox-model"],"lazar#classification") + elsif !p[File.join(@@config[:services]["opentox-model"],"lazar#regression")].nil? + feature = File.join(@@config[:services]["opentox-model"],"lazar#regression") + end + @activity = p[feature] + @confidence = p[File.join(@@config[:services]["opentox-model"],"lazar#confidence")] + @neighbors = p[File.join(@@config[:services]["opentox-model"],"lazar#neighbors")]#.sort{|a,b| b.last[:similarity] <=> a.last[:similarity]} + #@training_activities = p[File.join(@@config[:services]["opentox-model"],"lazar#activities")] + @features = p[File.join(@@config[:services]["opentox-model"],"lazar#features")] + else # database value + @measured_activities = @prediction.data[@compound.uri].first.values + end + else + @activity = "not available (no similar compounds in the training dataset)" + end + haml :prediction end elsif dataset_uri @@ -313,13 +361,13 @@ post '/:id/?' do # create prediction input_dataset.compounds.each do |compound_uri| # AM: switch here between regression and classification begin - eval "lazar.#{prediction_type}(compound_uri,prediction) unless lazar.database_activity?(compound_uri,prediction)" + eval "lazar.#{prediction_type}(compound_uri,@prediction) unless lazar.database_activity?(compound_uri,@prediction)" rescue LOGGER.error "#{prediction_type} failed for #{compound_uri} with #{$!} " end end begin - uri = prediction.save.chomp + uri = @prediction.save.chomp rescue halt 500, "Could not save prediction dataset" end -- cgit v1.2.3 From 42dbd3c3583bd9862d351e32f8446a75fab4a516 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Mon, 19 Jul 2010 12:13:18 +0200 Subject: html representation of prediction added --- views/prediction.haml | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 views/prediction.haml diff --git a/views/prediction.haml b/views/prediction.haml new file mode 100644 index 0000000..0187f87 --- /dev/null +++ b/views/prediction.haml @@ -0,0 +1,133 @@ +.predictions + %table + %tr + %th= @title.gsub(/_lazar_.*$/,' ').capitalize + %th Prediction + %th + %a{:href => "#", :id => "linkConfidence#{p.object_id}"} Confidence + :javascript + $("a#linkConfidence#{p.object_id}").click(function () { + $("dl#confidence").toggle(); + }); + %th Relevant features + %tr + %th + %img{:src => @compound.image_uri, :alt => @compound.smiles} + %td + - if @measured_activities + %br + - @measured_activities.each do |a| + - if activity(a) == 'active' + .active + = activity(a) + - elsif activity(a) == 'inactive' + .inactive + = activity(a) + - else + = a + %br + ( + %a{:href => "#", :id => "linkTrainingData#{p.object_id}"} Training data + :javascript + $("a#linkTrainingData#{p.object_id}").click(function () { + $("dl#training_data").toggle(); + }); + ) + + - else + - if activity(@activity) == 'active' + .active + = activity(@activity) + - elsif activity(@activity) == 'inactive' + .inactive + = activity(@activity) + - elsif @activity.is_a?(Float) + .other + = sprintf('%.03g', @activity) + - else + .other + %em= @activity.to_s + %td + = sprintf('%.03g', @confidence.to_f.abs) if @confidence + %td + %table + %tr + %th{:colspan => 2} activating + %th p value + - if @features[:activating] + - @features[:activating].sort{|a,b| b.last <=> a.last }.each do |f| + %tr + %th= f[0] + %td= f[1] + %tr + %th{:colspan => 2} deactivating + %th p value + - if @features[:deactivating] + - @features[:deactivating].sort{|a,b| b.last <=> a.last }.each do |f| + %tr + %th= f[0] + %td= f[1] + %tr + %th Neighbors + %th Activity + %th Similarity (activity specific) + %th Relevant features + - @neighbors.sort{|a,b| b.last[:similarity] <=> a.last[:similarity]}.each do |uri,data| + - c = OpenTox::Compound.new(:uri => uri) + %tr + %th + %br= c.smiles + %br + %a{:href => c.image_uri, :target => "_blank"} Image + %br + %img{:src => c.image_uri, :alt => c.smiles} + %td + - data[:activities].each do |act| + - if activity(act) == 'active' + .active + = activity(act) + - elsif activity(act) == 'inactive' + .inactive + = activity(act) + - elsif act.is_a?(Float) + .other + = sprintf('%.03g', act) + - else + .other + %em= act.to_s + %td + = sprintf('%.03g', data[:similarity]) + %td + %table + %tr + %th{:colspan => 2} activating + %th p value + -#%td= data[:features].inspect + -# data[:features][:activating].each do |f| + - data[:features][:activating].sort{|a,b| b.last[:p_value] <=> a.last[:p_value] }.each do |f| + -# f.inspect + %tr + %th= f[:smarts] + %td= f[:p_value] + %td=# f[:p_value] + %tr + %th{:colspan => 2} deactivating + %th p value + -# data[:features][:deactivating].sort{|a,b| b.last[:p_value] <=> a.last[:p_value] }.each do |f| + - data[:features][:deactivating].each do |f| + %tr + %th= f[:smarts] + %td= f[:p_value] + + + +%dl#confidence{ :style => "display: none;" } + %dt Confidence: + %dd Indicates the applicability domain of a model. Predictions with a high confidence can be expected to be more reliable than predictions with low confidence. Confidence values may take any value between 0 and 1. For most models confidence > 0.025 is a sensible (hard) cutoff to distiguish between reliable and unreliable predictions. + + +%dl#training_data{ :style => "display: none;" } + %dt Training data: + %dd Experimental result(s) from the training dataset are displayed here. + + -- cgit v1.2.3 From 26aa9a42990a958f53f326f3ccaed3848d21fd97 Mon Sep 17 00:00:00 2001 From: Christoph Helma Date: Mon, 19 Jul 2010 12:20:37 +0200 Subject: opentox-api-wrapper bumped to 1.6.0 --- application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application.rb b/application.rb index 3992153..b573314 100644 --- a/application.rb +++ b/application.rb @@ -1,5 +1,5 @@ require 'rubygems' -gem "opentox-ruby-api-wrapper", "= 1.5.7" +gem "opentox-ruby-api-wrapper", "= 1.6.0" require 'opentox-ruby-api-wrapper' LOGGER.progname = File.expand_path(__FILE__) -- cgit v1.2.3