diff options
author | mr <mr@mrautenberg.de> | 2011-05-23 13:38:25 +0200 |
---|---|---|
committer | mr <mr@mrautenberg.de> | 2011-05-23 13:38:25 +0200 |
commit | 1b38f31db88255d90947ad5b4d2b088988ce8bbd (patch) | |
tree | b9e710986fd7e9cf00636c5a46a4fdfd4a99c037 | |
parent | 6f161255e47a2198624ae1bc7149b45a07a32bc9 (diff) | |
parent | cfa443a8e93bd6f0e574c7c96f4cb0895a17c6f4 (diff) |
Merge branch 'release/2.0.0'v2.0.0
29 files changed, 327 insertions, 225 deletions
diff --git a/application.rb b/application.rb index 7bf1059..60d50cd 100644 --- a/application.rb +++ b/application.rb @@ -1,7 +1,7 @@ ['rubygems', "haml", "sass", "rack-flash"].each do |lib| require lib end -gem "opentox-ruby", "~> 1" +gem "opentox-ruby", "~> 2" require 'opentox-ruby' gem 'sinatra-static-assets' require 'sinatra/static_assets' @@ -27,7 +27,7 @@ helpers do private def delete_model(model, subjectid=nil) task = OpenTox::Task.create("Deleting model: #{model.uri}",url_for("/delete",:full)) do |task| - begin RestClient.put(File.join(model.task_uri, 'Cancelled'),subjectid) if model.task_uri rescue LOGGER.warn "Cannot cancel task #{model.task_uri}" end + begin OpenTox::RestClientWrapper.put(File.join(model.task_uri, "Cancelled"), "Cancelled",{:subjectid => subjectid}) if model.task_uri rescue LOGGER.warn "Cannot cancel task #{model.task_uri}" end task.progress(15) delete_dependent(model.uri, subjectid) if model.uri task.progress(30) @@ -60,7 +60,7 @@ helpers do end before do - if !logged_in and !( env['REQUEST_URI'] =~ /\/login$/ and env['REQUEST_METHOD'] == "POST" ) #or !AA_SERVER + if !logged_in and !( env['REQUEST_URI'] =~ /\/login$/ and env['REQUEST_METHOD'] == "POST" ) or !AA_SERVER login("guest","guest") end end @@ -179,9 +179,30 @@ get %r{/compound/(.*)} do |inchi| OpenTox::Compound.from_inchi(inchi).to_names.join(', ') end +get '/echa' do + @endpoints = OpenTox::Ontology::Echa.endpoints + haml :echa +end + +post '/ambit' do + session[:echa] = params[:endpoint] + @datasets = OpenTox::Ontology::Echa.datasets(params[:endpoint]) + haml :ambit +end + +post '/feature' do + session[:dataset] = params[:dataset] + @features = [] + OpenTox::Dataset.new(params[:dataset]).load_features.each do |uri,metadata| + @features << OpenTox::Feature.find(uri, @subjectid) if metadata[OWL.sameAs].match(/#{session[:echa]}/) + end + haml :feature +end + post '/models' do # create a new model - unless params[:file] and params[:file][:tempfile] #params[:endpoint] and - flash[:notice] = "Please upload a Excel or CSV file." + + unless (params[:dataset] and params[:prediction_feature]) or (params[:file] and params[:file][:tempfile]) #params[:endpoint] and + flash[:notice] = "Please upload a Excel or CSV file or select an AMBIT dataset." redirect url_for('/create') end @@ -190,75 +211,93 @@ post '/models' do # create a new model flash[:notice] = "Please login to create a new model." redirect url_for('/create') end + subjectid = session[:subjectid] ? session[:subjectid] : nil - @model = ToxCreateModel.create(:name => params[:file][:filename].sub(/\..*$/,""), :subjectid => subjectid) + + if params[:dataset] and params[:prediction_feature] + @dataset = OpenTox::Dataset.new(params[:dataset],subjectid) + name = @dataset.load_metadata[DC.title] + @prediction_feature = OpenTox::Feature.find params[:prediction_feature], subjectid + @dataset.load_compounds + elsif params[:file][:filename] + name = params[:file][:filename].sub(/\..*$/,"") + end + + @model = ToxCreateModel.create(:name => name, :subjectid => subjectid) @model.update :web_uri => url_for("/model/#{@model.id}", :full), :warnings => "" task = OpenTox::Task.create("Uploading dataset and creating lazar model",url_for("/models",:full)) do |task| task.progress(5) @model.update :status => "Uploading and saving dataset", :task_uri => task.uri - begin - @dataset = OpenTox::Dataset.create(nil, subjectid) - # check format by extension - not all browsers provide correct content-type]) - case File.extname(params[:file][:filename]) - when ".csv" - csv = params[:file][:tempfile].read - @dataset.load_csv(csv, subjectid) - when ".xls", ".xlsx" - excel_file = params[:file][:tempfile].path + File.extname(params[:file][:filename]) - File.rename(params[:file][:tempfile].path, excel_file) # add extension, spreadsheet does not read files without extensions - @dataset.load_spreadsheet(Excel.new excel_file, subjectid) + + unless params[:dataset] and params[:prediction_feature] + begin + @dataset = OpenTox::Dataset.create(nil, subjectid) + # check format by extension - not all browsers provide correct content-type]) + case File.extname(params[:file][:filename]) + when ".csv" + csv = params[:file][:tempfile].read + @dataset.load_csv(csv, subjectid) + when ".xls", ".xlsx" + excel_file = params[:file][:tempfile].path + File.extname(params[:file][:filename]) + File.rename(params[:file][:tempfile].path, excel_file) # add extension, spreadsheet does not read files without extensions + @dataset.load_spreadsheet(Excel.new excel_file, subjectid) + if @dataset.metadata[OT.Errors] + error "Incorrect file format. Please follow the instructions for #{link_to "Excel", "/help"} or #{link_to "CSV", "/help"} formats." + end + else + error "#{params[:file][:filename]} has a unsupported file type." + end + @dataset.save(subjectid) + rescue => e + error "Dataset creation failed with #{e.message}" + end + if @dataset.features.keys.size != 1 + error "More than one feature in dataset #{params[:file][:filename]}. Please delete irrelvant columns and try again." else - error "#{params[:file][:filename]} has a unsupported file type." + @prediction_feature = OpenTox::Feature.find(@dataset.features.keys.first,subjectid) end - rescue => e - error "Dataset creation failed with #{e.message}" end - @dataset.save(subjectid) + task.progress(10) if @dataset.compounds.size < 10 - error "Too few compounds to create a prediction model. Did you provide compounds in SMILES format and classification activities as described in the #{link_to "instructions", "/excel_format"}? As a rule of thumb you will need at least 100 training compounds for nongeneric datasets. A lower number could be sufficient for congeneric datasets." - end - if @dataset.features.keys.size != 1 - error "More than one feature in dataset #{params[:file][:filename]}. Please delete irrelvant columns and try again." - end - if @dataset.metadata[OT.Errors] - error "Incorrect file format. Please follow the instructions for #{link_to "Excel", "/excel_format"} or #{link_to "CSV", "/csv_format"} formats." + error "Too few compounds to create a prediction model. Did you provide compounds in SMILES format and classification activities as described in the #{link_to "instructions", "/help"}? As a rule of thumb you will need at least 100 training compounds for nongeneric datasets. A lower number could be sufficient for congeneric datasets." end @model.update :training_dataset => @dataset.uri, :nr_compounds => @dataset.compounds.size, :status => "Creating prediction model" - @model.update :warnings => @dataset.metadata[OT.Warnings] unless @dataset.metadata[OT.Warnings].empty? + @model.update :warnings => @dataset.metadata[OT.Warnings] unless @dataset.metadata[OT.Warnings] and @dataset.metadata[OT.Warnings].empty? task.progress(15) begin - lazar = OpenTox::Model::Lazar.create(:dataset_uri => @dataset.uri, :subjectid => subjectid) + lazar = OpenTox::Model::Lazar.create(:dataset_uri => @dataset.uri, :prediction_feature => @prediction_feature.uri, :subjectid => subjectid) rescue => e - error "Model creation failed with '#{e.message}'. Please check if the input file is in a valid #{link_to "Excel", "/excel_format"} or #{link_to "CSV", "/csv_format"} format." + error "Model creation failed with '#{e.message}'."# Please check if the input file is in a valid #{link_to "Excel", "/help"} or #{link_to "CSV", "/help"} format." end task.progress(25) +=begin type = "unknown" - case lazar.metadata[OT.isA] - when /Classification/ + if lazar.metadata[RDF.type].grep(/Classification/) type = "classification" - when /Regression/ + elsif lazar.metadata[RDF.type].grep(/Regression/) type = "regression" end - @model.update :type => type, :feature_dataset => lazar.metadata[OT.featureDataset], :uri => lazar.uri +=end + @model.update :type => @prediction_feature.feature_type, :feature_dataset => lazar.metadata[OT.featureDataset], :uri => lazar.uri - unless url_for("",:full).match(/localhost/) + if CONFIG[:services]["opentox-validation"] @model.update :status => "Validating model" begin - validation = OpenTox::Crossvalidation.create( - {:algorithm_uri => lazar.metadata[OT.algorithm], - :dataset_uri => lazar.parameter("dataset_uri"), - :subjectid => subjectid, - :prediction_feature => lazar.parameter("prediction_feature"), - :algorithm_params => "feature_generation_uri=#{lazar.parameter("feature_generation_uri")}"}, - nil, OpenTox::SubTask.new(task,25,80)) + validation = OpenTox::Crossvalidation.create( { + :algorithm_uri => lazar.metadata[OT.algorithm], + :dataset_uri => lazar.parameter("dataset_uri"), + :subjectid => subjectid, + :prediction_feature => lazar.parameter("prediction_feature"), + :algorithm_params => "feature_generation_uri=#{lazar.parameter("feature_generation_uri")}" }, + nil, OpenTox::SubTask.new(task,25,80)) + @model.update(:validation_uri => validation.uri) LOGGER.debug "Validation URI: #{@model.validation_uri}" # create summary validation.summary(subjectid).each do |k,v| - #LOGGER.debug "mr ::: k: #{k.inspect} - v: #{v.inspect}" begin eval "@model.update :#{k.to_s} => v" if v rescue @@ -278,17 +317,13 @@ post '/models' do # create a new model @model.update :warnings => @model.warnings + "\nModel validation failed with #{e.message}.", :status => "Error", :error_messages => e.message end + else + @model.update(:status => "Completed") #, :warnings => @model.warnings + "\nValidation service cannot be accessed from localhost.") + task.progress(100) end - - - #@model.warnings += "<p>Incorrect Smiles structures (ignored):</p>" + parser.smiles_errors.join("<br/>") unless parser.smiles_errors.empty? - #@model.warnings += "<p>Irregular activities (ignored):</p>" + parser.activity_errors.join("<br/>") unless parser.activity_errors.empty? - #duplicate_warnings = '' - #parser.duplicates.each {|inchi,lines| duplicate_warnings += "<p>#{lines.join('<br/>')}</p>" if lines.size > 1 } - #@model.warnings += "<p>Duplicated structures (all structures/activities used for model building, please make sure, that the results were obtained from <em>independent</em> experiments):</p>" + duplicate_warnings unless duplicate_warnings.empty? lazar.uri end - @model.update(:task_uri => task.uri) + @model.update :task_uri => task.uri flash[:notice] = "Model creation and validation started - this may last up to several hours depending on the number and size of the training compounds." redirect url_for('/models') @@ -325,7 +360,7 @@ post '/predict/?' do # post chemical name to model } else predicted_feature = prediction_dataset.metadata[OT.dependentVariables] - prediction = OpenTox::Feature.find(predicted_feature) + prediction = OpenTox::Feature.find(predicted_feature, subjectid) if prediction.metadata[OT.error] @predictions << { :title => model.name, @@ -351,7 +386,7 @@ post "/lazar/?" do # get detailed prediction @page = params[:page].to_i if params[:page] @model_uri = params[:model_uri] lazar = OpenTox::Model::Lazar.new @model_uri - prediction_dataset_uri = lazar.run(:compound_uri => params[:compound_uri], :subjectid => params[:subjectid]) + prediction_dataset_uri = lazar.run(:compound_uri => params[:compound_uri], :subjectid => session[:subjectid]) @prediction = OpenTox::LazarPrediction.find(prediction_dataset_uri, session[:subjectid]) @compound = OpenTox::Compound.new(params[:compound_uri]) haml :lazar @@ -3,7 +3,7 @@ helpers do def login(username, password) logout session[:subjectid] = OpenTox::Authorization.authenticate(username, password) - LOGGER.debug "ToxCreate login user #{username} with subjectid: " + session[:subjectid].to_s + #LOGGER.debug "ToxCreate login user #{username} with subjectid: " + session[:subjectid].to_s if session[:subjectid] != nil session[:username] = username return true @@ -53,8 +53,7 @@ helpers do def sort(descriptors) features = {:activating => [], :deactivating => []} - - descriptors.each { |d| LOGGER.debug d.inspect; features[d[OT.effect].to_sym] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]} } + descriptors.each { |d| features[d[OT.effect].to_sym] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]} } features end @@ -1,13 +1,18 @@ require 'ohm' +require 'ohm/contrib' class ToxCreateModel < Ohm::Model + include Ohm::Callbacks + include Ohm::Typecast + include Ohm::Timestamping + attribute :name attribute :warnings attribute :error_messages attribute :type attribute :status - attribute :created_at + attribute :created_at, Date attribute :task_uri attribute :uri @@ -42,7 +47,7 @@ class ToxCreateModel < Ohm::Model attr_accessor :subjectid @subjectid = nil - #after :save, :check_policy + after :save, :check_policy def validation_status begin @@ -73,5 +78,4 @@ class ToxCreateModel < Ohm::Model OpenTox::Authorization.check_policy(web_uri, subjectid) end -end - +end
\ No newline at end of file diff --git a/public/external.gif b/public/external.gif Binary files differnew file mode 100644 index 0000000..6114959 --- /dev/null +++ b/public/external.gif diff --git a/public/hamster_carcinogenicity.csv b/public/hamster_carcinogenicity.csv index e9ca269..f087233 100644 --- a/public/hamster_carcinogenicity.csv +++ b/public/hamster_carcinogenicity.csv @@ -1,3 +1,4 @@ +SMILES, hamster_carcinogenicity
CC=O,1
C12C3=C(C=CC=C3)CC1=CC(=CC=2)NC(C)=O,1
O=C(N)\C(C2=CC=CO2)=C/C1=CC=C([N+]([O-])=O)O1,1
diff --git a/public/hamster_carcinogenicity.xls b/public/hamster_carcinogenicity.xls Binary files differindex 0015ac6..95e8fc4 100644 --- a/public/hamster_carcinogenicity.xls +++ b/public/hamster_carcinogenicity.xls diff --git a/public/javascripts/toxcreate.js b/public/javascripts/toxcreate.js index 94d944d..d9946c4 100755 --- a/public/javascripts/toxcreate.js +++ b/public/javascripts/toxcreate.js @@ -86,8 +86,6 @@ $(function() { }); return id; }; - - loadModel = function(id, view) { if(id == "") return -1; @@ -111,30 +109,9 @@ $(function() { return false; }; - checkValidation = function() { - var reload_id = ""; - $("input.model_validation_report").each(function(){ - if(!$(this).val().match(/Completed|Error/)) { - reload_id = this.id.replace("model_validation_report_",""); - if(/^\d+$/.test(reload_id)) loadModel(reload_id, 'validation'); - }; - }); -//<<<<<<< HEAD - //var validationCheck = setTimeout('checkValidation()',15000); - //var validationCheck = setTimeout('checkValidation()',5000); -//======= - $("input.model_validation_qmrf").each(function(){ - if(!$(this).val().match(/Completed|Error/)) { - reload_id = this.id.replace("model_validation_qmrf_",""); - if(/^\d+$/.test(reload_id)) loadModel(reload_id, 'model'); - }; - }); - var validationCheck = setTimeout('checkValidation()',15000); -//>>>>>>> d1ad229730f6e6043fe6e7a150e05ffa41e3cec2 - } }); -jQuery.fn.editModel = function(type, options) { +jQuery.fn.editModel = function(options) { var defaults = { method: 'get', action: this.attr('href'), @@ -161,7 +138,34 @@ jQuery.fn.editModel = function(type, options) { }); }; -jQuery.fn.saveModel = function(type, options) { +jQuery.fn.cancelEdit = function(options) { + var defaults = { + method: 'get', + action: 'model/' + options.id + '/name?mode=show', + trigger_on: 'click' + }; + var opts = $.extend(defaults, options); + + this.bind(opts.trigger_on, function() { + $.ajax({ + type: opts.method, + url: opts.action, + dataType: 'html', + data: { + '_method': 'get' + }, + success: function(data) { + $("div#model_" + opts.id + "_name").html(data); + }, + error: function(data) { + alert("model cancel error!"); + } + }); + return false; + }); +}; + +jQuery.fn.saveModel = function(options) { var defaults = { method: 'put', action: 'model/' + options.id, @@ -222,3 +226,15 @@ jQuery.fn.deleteModel = function(type, options) { return false; }); }; + +$(document).ready(function() { + $('A[rel="external"]').each(function() { + $(this).attr('alt', 'Link opens in new window.'); + $(this).attr('title', 'Link opens in new window.'); + }); + $('A[rel="external"]').click(function() { + window.open($(this).attr('href')); + return false; + }); +}); + diff --git a/public/progressbar/progressbar.css b/public/progressbar/progressbar.css index f3b4131..d19839d 100644 --- a/public/progressbar/progressbar.css +++ b/public/progressbar/progressbar.css @@ -11,9 +11,7 @@ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } -/* -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -*/ +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px, 1px, 1px, 1px); clip: rect(1px,1px,1px,1px); } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .ui-helper-clearfix { display: inline-block; } @@ -21,9 +19,8 @@ * html .ui-helper-clearfix { height:1%; } .ui-helper-clearfix { display:block; } /* end clearfix */ -/* -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } -*/ + +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; } /* Interaction Cues ----------------------------------*/ @@ -84,10 +81,8 @@ .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -/* -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } -*/ +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { background-image: none; } /* Icons ----------------------------------*/ @@ -283,6 +278,10 @@ /* Misc visuals ----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;}/* /* Corner radius */ /* .ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; } @@ -300,11 +299,7 @@ /* .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } -*/ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; } -/* * jQuery UI Progressbar 1.8.9 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) diff --git a/views/ambit.haml b/views/ambit.haml new file mode 100644 index 0000000..685c0dc --- /dev/null +++ b/views/ambit.haml @@ -0,0 +1,15 @@ +%b Select: += session[:echa].split('#').last += "->" +%b Dataset +%em= "-> Prediction Feature" + +%form{ :action => url_for('/feature'), :method => "post" } + %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} + + - @datasets.each do |dataset| + %br + %input{:type=>'radio', :name => "dataset", :value => dataset} #{OpenTox::Dataset.new(dataset).load_metadata[DC.title]} + + %p + %input{:type => 'submit', :value => 'Next'} diff --git a/views/compound_image.haml b/views/compound_image.haml index 18944dc..25e0dbf 100644 --- a/views/compound_image.haml +++ b/views/compound_image.haml @@ -1,2 +1 @@ %img{:src => compound.matching_smarts_image_uri(features[:activating].collect{|f| f[:smarts]},features[:deactivating].collect{|f| f[:smarts]}), :alt => compound.to_smiles} - diff --git a/views/create.haml b/views/create.haml index 5450ddf..0b299f5 100644 --- a/views/create.haml +++ b/views/create.haml @@ -17,18 +17,24 @@ = link_to "instructions for creating training datasets", '/help' before submitting. + %form{ :action => url_for('/models'), :method => "post", :enctype => "multipart/form-data" } %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} %fieldset %label{:for => 'file'} - Select training data in + Upload training data in = link_to "Excel", '/help' or = link_to "CSV", '/help' format: %input{:type => 'file', :name => 'file', :id => 'file', :size => '41'} %input{ :type => "submit", :value => "Create model"} - = link_to "Cancel", '/create' + =# link_to "Cancel", '/create' + + %p + or + %a{:href => "echa"} Select a AMBIT dataset + (experimental) -# explanations = haml :lazar_description, :layout => false @@ -45,5 +51,5 @@ and your models can be modified or deleted by other guests. Please = link_to "log in", "/login" with your - %a{:href => "www.opentox.org"} OpenTox + %a{:href => "http://www.opentox.org", :rel => "external"} OpenTox account to control your model permissions. diff --git a/views/echa.haml b/views/echa.haml new file mode 100644 index 0000000..1cabfa0 --- /dev/null +++ b/views/echa.haml @@ -0,0 +1,13 @@ +%b Select: +%b ECHA Endpoint +%em= "-> Dataset -> Prediction Feature" + +%form{ :action => url_for('/ambit'), :method => "post" } + %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} + + - @endpoints.each do |endpoint| + %br + %input{:type=>'radio', :name => "endpoint", :value => endpoint} #{endpoint.split('#').last} + + %p + %input{:type => 'submit', :value => "Next"} diff --git a/views/feature.haml b/views/feature.haml new file mode 100644 index 0000000..c5b8293 --- /dev/null +++ b/views/feature.haml @@ -0,0 +1,26 @@ +%b Select: += session[:echa].split('#').last += "->" += OpenTox::Dataset.new(session[:dataset]).load_metadata[DC.title] += "->" +%b Prediction feature + +%form{ :action => url_for('/models'), :method => "post" } + + %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} + %input{:type => 'hidden', :name => 'dataset', :id => 'dataset', :value => session[:dataset]} + + - @features.each do |feature| + -# type = "unknown" + -# if feature.metadata[RDF.type].include?(OT.NominalFeature) + - type = "classification" + -# elsif feature.metadata[RDF.type].include?(OT.NumericFeature) + - type = "regression" + + %br + %input{:type=>'radio', :name => "prediction_feature", :value => feature.uri} #{feature.metadata[DC.title]} (#{feature.feature_type}) + %br + =# feature.inspect + + %p + %input{:type => 'submit', :value => "Create model"} diff --git a/views/feature_table.haml b/views/feature_table.haml index 4fa927c..a8a153f 100644 --- a/views/feature_table.haml +++ b/views/feature_table.haml @@ -4,7 +4,7 @@ %th activating ( - %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html"} SMARTS + %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html", :rel => "external"} SMARTS ) %th p value - if features[:activating] @@ -17,7 +17,7 @@ %th deactivating ( - %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html"} SMARTS + %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html", :rel => "external"} SMARTS ) %th p value - if features[:deactivating] diff --git a/views/help.haml b/views/help.haml index da6495e..3d39641 100644 --- a/views/help.haml +++ b/views/help.haml @@ -1,7 +1,7 @@ = link_to "Back to model creation", '/create' %p Input files have two columns. Enter in the first column the chemical structure in - %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification"} SMILES + %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification", :rel => "external"} SMILES format, in the second column the toxic activity. The first line contains a description of the columns and is ignored. %dl %dt Classification datasets @@ -12,15 +12,15 @@ %ul %li use - %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)"} molar + %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)", :rel => "external"} molar units %li enter non-logarithmic values (logarithms are taken internally) %li avoid 0 activities (will be ignored) %p Input files are accepted in - %a{:href => "http://en.wikipedia.org/wiki/Microsoft_Excel"} Excel + %a{:href => "http://en.wikipedia.org/wiki/Microsoft_Excel", :rel => "external"} Excel and - %a{:href => "http://en.wikipedia.org/wiki/Comma-separated_values"} CSV + %a{:href => "http://en.wikipedia.org/wiki/Comma-separated_values", :rel => "external"} CSV formats. %h3 Excel example diff --git a/views/layout.haml b/views/layout.haml index cdabe43..174db9f 100644 --- a/views/layout.haml +++ b/views/layout.haml @@ -17,7 +17,7 @@ Create and evaluate models to predict toxicity .index %ul - %li{:class => ("selected" if /\/create/ =~ request.path )} + %li{:class => ("selected" if /\/create|echa|ambit|feature/ =~ request.path )} = link_to "Create", "/create" %li{:class => ("selected" if /models/ =~ request.path )} = link_to "Inspect", "/models" @@ -37,7 +37,7 @@ - if `hostname`.match(/ot-test/) .notice This service is for testing purposes only - once a week all models will be deleted. Please send bug reports and feature requests to our - %a{:href => 'http://github.com/opentox/toxcreate/issues'} issue tracker. + %a{:href => 'http://github.com/opentox/toxcreate/issues', :rel => "external"} issue tracker. - if flash[:notice] %p @@ -48,6 +48,6 @@ .footer © - %a{:href => 'http://www.in-silico.ch'} in silico toxicology - 2009-2010, powered by - %a{:href => 'http://www.opentox.org'} <span style="color:#5D308A;font-family:arial,sans-serif,helvetica;letter-spacing:-1px;">Open</span><span style="color:#000;font-family:arial,sans-serif,helvetica;font-weight:bold;letter-spacing:-1px;position:relative;">Tox</span> + %a{:href => 'http://www.in-silico.ch', :rel => "external"} in silico toxicology + 2009-2011, powered by + %a{:href => 'http://www.opentox.org', :rel => "external"} <span style="color:#5D308A;font-family:arial,sans-serif,helvetica;letter-spacing:-1px;">Open</span><span style="color:#000;font-family:arial,sans-serif,helvetica;font-weight:bold;letter-spacing:-1px;">Tox</span> diff --git a/views/lazar.haml b/views/lazar.haml index 3de7400..3f1d030 100644 --- a/views/lazar.haml +++ b/views/lazar.haml @@ -1,59 +1,47 @@ -%p= link_to "New prediction", "/predict"
-.lazar-predictions
-
- -# explanations
- = haml :lazar_algorithm, :layout => false
- = haml :confidence, :layout => false
- = haml :similarity, :layout => false
- = haml :significant_fragments, :layout => false
- = haml :training_data, :layout => false
-
- %a{:name => "prediction"}
- %table
- %thead
- %tr
- %th= @prediction.title
- %th= toggle_link("#lazar_algorithm","Prediction")
- %th= toggle_link("#confidence","Confidence")
- %th Supporting information
-
- %tr
- -# %td
- %img{:src => @compound.to_image_uri, :alt => @compound.to_smiles}
- %td.image= compound_image(@compound,@prediction.descriptors(@compound))
- %td= activity_markup(@prediction.value(@compound))
- %td= sprintf('%.03g', @prediction.confidence(@compound))
- -#%td= @prediction.confidence(@compound)
- %td
- %ul
- %li
- %a{:href => "#prediction", :id => "show_names"} Names and synonyms
- :javascript
- $("a#show_names").click(function () {
- $("#compound_names").load("#{File.join("/compound",@compound.inchi)}");
- $("tr#names").toggle();
- });
- %li= toggle_link("#fragments","Significant fragments")
- -# This does not work, ask nina/vedrin
- -# %li
- %a{:href => "http://ambit.uni-plovdiv.bg:8080/ambit2/query/structure/?search=#{@compound.smiles}"} Ambit data
- -# %li
- %a{:href => "http://www.ncbi.nlm.nih.gov/sites/entrez?cmd=PureSearch&db=pccompound&term=#{URI.encode('"'+@compound.inchi+'"[InChI]')}"} PubChem data
- (external)
- -# %li
- %a{:href => "http://chem.sis.nlm.nih.gov/chemidplus/direct.jsp?result=advanced&inchi=#{URI.encode @compound.inchi}"} ToxNet data
- -#http://chem.sis.nlm.nih.gov/chemidplus/direct.jsp?result=advanced®no=000143157
-
- %tr#names{ :style => "display: none;" }
- %td{:colspan => '4'}
- %a{:name => 'names'}
- = hide_link('#names')
- #compound_names
- %tr#fragments{ :style => "display: none;" }
- %td{:colspan => '4'}
- = hide_link('#fragments')
- = haml :feature_table, :locals => {:features => sort(@prediction.descriptors(@compound))}, :layout => false
-
- %tbody#neighbors
- = haml :neighbors, :locals => {:neighbors => @prediction.neighbors(@compound), :page => @page}, :layout => false
-
+%p= link_to "New prediction", "/predict" +.lazar-predictions + + -# explanations + = haml :lazar_algorithm, :layout => false + = haml :confidence, :layout => false + = haml :similarity, :layout => false + = haml :significant_fragments, :layout => false + = haml :training_data, :layout => false + + %a{:name => "prediction"} + %table + %thead + %tr + %th= @prediction.title + %th= toggle_link("#lazar_algorithm","Prediction") + %th= toggle_link("#confidence","Confidence") + %th Supporting information + + %tr + %td.image= compound_image(@compound,@prediction.descriptors(@compound)) + %td= activity_markup(@prediction.value(@compound)) + %td= sprintf('%.03g', @prediction.confidence(@compound)) + %td + %ul + %li + %a{:href => "#prediction", :id => "show_names"} Names and synonyms + :javascript + $("a#show_names").click(function () { + $("#compound_names").load("#{File.join("/compound",@compound.inchi)}"); + $("tr#names").toggle(); + }); + %li= toggle_link("#fragments","Significant fragments") + + %tr#names{ :style => "display: none;" } + %td{:colspan => '4'} + %a{:name => 'names'} + = hide_link('#names') + #compound_names + %tr#fragments{ :style => "display: none;" } + %td{:colspan => '4'} + = hide_link('#fragments') + = haml :feature_table, :locals => {:features => sort(@prediction.descriptors(@compound))}, :layout => false + + %tbody#neighbors + = haml :neighbors, :locals => {:neighbors => @prediction.neighbors(@compound), :page => @page}, :layout => false + diff --git a/views/lazar_algorithm.haml b/views/lazar_algorithm.haml index b83de6b..85823b5 100644 --- a/views/lazar_algorithm.haml +++ b/views/lazar_algorithm.haml @@ -20,13 +20,13 @@ a majority vote (weighted by compound similarity) for %em classification ( - %a{:href => "http://www.in-silico.de/articles/modi020905.pdf"} original publication + %a{:href => "http://www.in-silico.de/articles/modi020905.pdf", :rel => "external"} original publication ) %li a local QSAR model based on neighbors for %em regression ( - %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf"} original publication + %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf", :rel => "external"} original publication ) %p diff --git a/views/lazar_description.haml b/views/lazar_description.haml index d8e995d..3eee850 100644 --- a/views/lazar_description.haml +++ b/views/lazar_description.haml @@ -18,11 +18,11 @@ a majority vote (weighted by compound similarity) for %em= toggle_link("#classification","classification") ( - %a{:href => "http://www.in-silico.de/articles/modi020905.pdf"} original publication + %a{:href => "http://www.in-silico.de/articles/modi020905.pdf", :rel => "external"} original publication ) %li a local QSAR model based on neighbors for %em= toggle_link("#regression","regression") ( - %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf"} original publication + %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf", :rel => "external"} original publication ) diff --git a/views/login.haml b/views/login.haml index 6d15bb7..e944e77 100644 --- a/views/login.haml +++ b/views/login.haml @@ -7,15 +7,15 @@ and your models can be modified or deleted by other guests. To control models permissions you can log in with your - %a{:href => "http://www.opentox.org"} OpenTox - username/password below. If have no - %a{:href => "http://www.opentox.org"} OpenTox - account yet you can - %a{:href => "http://www.opentox.org/join_form"} register here. + %a{:href => "http://www.opentox.org", :rel => "external"} OpenTox + username/password below. If you don't have an + %a{:href => "http://www.opentox.org", :rel => "external"} OpenTox + account yet you could + %a{:href => "http://www.opentox.org/join_form", :rel => "external"} register here. - else %p Change - %a{:href => "http://www.opentox.org"} OpenTox + %a{:href => "http://www.opentox.org", :rel => "external"} OpenTox account: -# if !logged_in() @@ -33,15 +33,5 @@ %form{ :action => url_for('/login'), :method => "post" } %input{:type => 'hidden', :name => 'username', :id => 'username', :value => "guest"} %input{:type => 'hidden', :name => 'password', :id => 'password', :value => "guest"} - %input{ :type => "submit", :value => "Login as guest"} - -# else - %form{ :action => url_for('/logout'), :method => "post" } - -#%p - You are logged in as: - %b= session[:username] - -# if LOGGER.level == Logger::DEBUG - %br - = session[:subjectid] - %input{ :type => "submit", :value => "Switch user"} - = link_to "Cancel", '/login' - + %input{:type => "submit", :value => "Login as guest"} + diff --git a/views/model.haml b/views/model.haml index 91d7016..b4b3c59 100644 --- a/views/model.haml +++ b/views/model.haml @@ -18,7 +18,7 @@ - if (task = OpenTox::Task.exist?(model.task_uri)) %input{:type => 'hidden', :id => "model_#{model.id}_task", :value => "#{model.task_uri}"} - percentage_completed = task.metadata[OT.percentageCompleted].to_i - - js = "$('#model_#{model.id}_progress').progressbar({ value: #{percentage_completed} })"; + - js = "$('#model_#{model.id}_progress').progressbar({ value: #{percentage_completed} });" :javascript $(function() { #{js} @@ -28,15 +28,15 @@ //= haml :model_progress, :locals=>{:percentage_completed=>percentage_completed}, :layout => false - if is_authorized(model.web_uri, "DELETE") %a{:href => url_for("/model/#{model.id}"), :id => "delete_#{model.id}", :class => 'delete_link'} - - if model.status == "Completed" + - if model.status =~ /Completed|Error|Cancelled/ (delete) - else (stop) %span %br - -#%dt Started: - -#%dd= model.created_at.strftime("%m/%d/%Y - %I:%M:%S%p") + %dt Started: + %dd= Time.parse(model.created_at.to_s).strftime("%m/%d/%Y - %I:%M:%S%p") if model.created_at - if model.nr_compounds %dt Training compounds: %dd= model.nr_compounds @@ -54,16 +54,19 @@ %dd= toggle_link("##{model.type}","#{model.type}") %dt Descriptors: %dd - %a{:href => 'http://www.maunz.de/libfminer2-bbrc-doc/'} Fminer backbone refinement classes + %a{:href => 'http://www.maunz.de/libfminer2-bbrc-doc/', :rel => "external"} Fminer backbone refinement classes - if model.training_dataset %dt Training dataset: %dd - %a{:href => "#{model.training_dataset}.xls#{subjectstring}"} Excel sheet - , - -#%a{:href => "#{model.training_dataset}.rdf"} RDF/XML - -#%em (experts) , - %a{:href => "#{model.training_dataset}.yaml#{subjectstring}" } YAML - %em (experts) + - if model.training_dataset.match(/ambit/i) + %a{:href => "#{model.training_dataset}#{subjectstring}", :rel => "external"} Ambit database + - else + %a{:href => "#{model.training_dataset}.xls#{subjectstring}"} Excel sheet + , + -#%a{:href => "#{model.training_dataset}.rdf"} RDF/XML + -#%em (experts) , + %a{:href => "#{model.training_dataset}.yaml#{subjectstring}" } YAML + %em (experts) - if model.feature_dataset %dt Feature dataset: %dd diff --git a/views/model_name.haml b/views/model_name.haml index b1f6f10..91516ce 100644 --- a/views/model_name.haml +++ b/views/model_name.haml @@ -1,4 +1,4 @@ -- js = "$('#edit_#{model.id}').editModel('PUT', {id: '#{model.id}', mode: 'edit'});\n " +- js = "$('#edit_#{model.id}').editModel({id: '#{model.id}', mode: 'edit'});\n " :javascript $(function() { #{js} diff --git a/views/model_name_edit.haml b/views/model_name_edit.haml index aec59fc..d92c68a 100644 --- a/views/model_name_edit.haml +++ b/views/model_name_edit.haml @@ -1,5 +1,5 @@ -- js = "$('#cancel_#{model.id}').editModel('GET', {id: '#{model.id}', mode: 'show'});\n " -- js = "$('#save_#{model.id}').saveModel('POST', {id: '#{model.id}', mode: 'show'});\n " +- js = "$('#cancel_#{model.id}').cancelEdit({id: '#{model.id}', mode: 'show'});\n " +- js += "$('#save_#{model.id}').saveModel({id: '#{model.id}', mode: 'show'});\n " :javascript $(function() { #{js} @@ -10,5 +10,4 @@ %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} %input{ :type => "submit", :value => "Save", :id => "save_#{model.id}", :class => "edit_button"} %span{:class => "edit_button"} - %a{:href => url_for("/model/#{model.id}/name?mode=show"), :id => "cancel_#{model.id}"} Cancel - + %a{:href => "#", :id => "cancel_#{model.id}"} Cancel diff --git a/views/models.haml b/views/models.haml index 67c061c..6724807 100644 --- a/views/models.haml +++ b/views/models.haml @@ -6,18 +6,18 @@ setTimeout('checkStati("#{stati_to_check}", "#{subjectstring}")',5000); } var reload_validation = true; - //if(reload_validation) setTimeout('checkValidation()',15000); }); -# %p Get an overview about ToxCreate models. This page is refreshed every 15 seconds to update the model status. %p Get an overview about ToxCreate models. Parts of this page are refreshed every 5 seconds to update the model status. -# explanations -= haml :lazar_description, :layout => false = haml :classification, :layout => false += haml :lazar_description, :layout => false = haml :regression, :layout => false = haml :similarity, :layout => false = haml :significant_fragments, :layout => false -- @models.each do |model| - = haml :model, :locals=>{:model=>model,:subjectstring=>subjectstring}, :layout => false +- if @models + - @models.each do |model| + = haml :model, :locals=>{:model=>model,:subjectstring=>subjectstring}, :layout => false diff --git a/views/predict.haml b/views/predict.haml index d8c34a2..ec667e6 100644 --- a/views/predict.haml +++ b/views/predict.haml @@ -18,18 +18,25 @@ %param{ :name => "options", :value => "polarnitro"} Please enable Java and JavaScript in your browser to use the JME editor. + %jme_info + <span style="font-size:75%">© + %a{:href => 'http://www.molinspiration.com/jme/index.html', :rel => "external"} JME Editor + courtesy of Peter Ertl, Novartis</span> + %br %label{:for => 'identifier'} or enter a Name, InChI, Smiles, CAS, ... %input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'} + %br %fieldset %legend Choose one or more prediction models + %br - @models.each do |model| + %input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => "model#{model.id}", :disabled => false} %label{:for => "model#{model.id}"} = model.name - -#%input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => model.id, :disabled => !is_authorized(model.uri, "GET")} - %input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => "model#{model.id}", :disabled => false} + -#%input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => model.id, :disabled => !is_authorized(model.uri, "GET")} %br - + %br %input{:type => 'hidden', :name => 'subjectid', :id => 'subjectid', :value => session[:subjectid]} %input{ :type => "submit", :value => "Predict", :onclick => "getsmiles();"} = link_to 'Cancel', '/predict' diff --git a/views/regression_validation.haml b/views/regression_validation.haml index d5b3f6a..5b29d88 100644 --- a/views/regression_validation.haml +++ b/views/regression_validation.haml @@ -1,9 +1,9 @@ %dt - %a{:href => "http://en.wikipedia.org/wiki/R-squared"} R-squared + %a{:href => "http://en.wikipedia.org/wiki/R-squared", :rel => "external"} R-squared %dd= sprintf '%.03g', model.r_square.to_f %dt - %a{:href => "http://en.wikipedia.org/wiki/Root_mean_square_deviation"} Root Mean Square Error + %a{:href => "http://en.wikipedia.org/wiki/Root_mean_square_deviation", :rel => "external"} Root Mean Square Error %dd= sprintf '%.03g', model.root_mean_squared_error.to_f %dt - %a{:href => "http://en.wikipedia.org/wiki/Mean_absolute_error"} Mean Absolute Error + %a{:href => "http://en.wikipedia.org/wiki/Mean_absolute_error", :rel => "external"} Mean Absolute Error %dd= sprintf '%.03g', model.mean_absolute_error.to_f diff --git a/views/significant_fragments.haml b/views/significant_fragments.haml index 87cb113..bd39826 100644 --- a/views/significant_fragments.haml +++ b/views/significant_fragments.haml @@ -6,5 +6,5 @@ ) %dd Substructures that occur (statistically significant) more frequently in active or inactive compounds. Substuctures can take any shape (without cycles) and are determined with the - %a{:href => "http://www.maunz.de/libfminer2-bbrc-doc/"} fminer + %a{:href => "http://www.maunz.de/libfminer2-bbrc-doc/", :rel => "external"} fminer algorithm. diff --git a/views/style.sass b/views/style.sass index db1f1bf..ffae6a5 100644 --- a/views/style.sass +++ b/views/style.sass @@ -18,6 +18,9 @@ body color: $ot_purple a:hover color: black + a[rel="external"] + background: transparent url('../external.gif') center right no-repeat + padding-right: 15px .headline .logo @@ -90,6 +93,7 @@ body font-weight: bold color: $fg_color label + cursor: pointer //width: 28em //display: block //float: left @@ -127,7 +131,9 @@ body padding: 0.5em img padding: 0 - height: 100% + //height: 100% + width: 150px + height: 150px .lazar-predictions clear: both diff --git a/views/unit.haml b/views/unit.haml index a352599..88433b5 100644 --- a/views/unit.haml +++ b/views/unit.haml @@ -6,5 +6,5 @@ ) %dd Unit of measurement, e.g. mmol or mmol/kg-bodyweight. For optimal performance you should use - %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)"} molar + %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)", :rel => "external"} molar units. |