summaryrefslogtreecommitdiff
path: root/application.rb
diff options
context:
space:
mode:
Diffstat (limited to 'application.rb')
-rw-r--r--application.rb143
1 files changed, 89 insertions, 54 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