summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2011-02-21 15:56:24 +0100
committerChristoph Helma <helma@in-silico.ch>2011-02-21 15:56:24 +0100
commit15923e2e9dbb810425067a96d0cc361309b26c29 (patch)
tree23b8c6e073c62f54ee194469724ff31890d9178a
parentc7fdbd935660ec29fed16646b2ac0c9fb585644a (diff)
parent86e652e6ebbf13e2385c2ce9114d92d3eaf9a87d (diff)
Merge branch 'development' of github.com:helma/opentox-toxcreate into development
Conflicts: application.rb views/lazar.haml
-rw-r--r--application.rb501
-rw-r--r--views/lazar.haml58
2 files changed, 0 insertions, 559 deletions
diff --git a/application.rb b/application.rb
deleted file mode 100644
index a892c03..0000000
--- a/application.rb
+++ /dev/null
@@ -1,501 +0,0 @@
-['rubygems', "haml", "sass", "rack-flash"].each do |lib|
- require lib
-end
-gem "opentox-ruby", "~> 0"
-require 'opentox-ruby'
-gem 'sinatra-static-assets'
-require 'sinatra/static_assets'
-require 'ftools'
-require File.join(File.dirname(__FILE__),'model.rb')
-require File.join(File.dirname(__FILE__),'helper.rb')
-#require File.join(File.dirname(__FILE__),'parser.rb')
-
-use Rack::Session::Cookie, :expire_after => 28800,
- :secret => "ui6vaiNi-change_me"
-use Rack::Flash
-
-helpers do
-
- def error(message)
- @model.error_messages = message
- LOGGER.error message
- @model.status = "Error"
- @model.save
- #@dataset.delete
- flash[:notice] = message
- redirect url_for('/create')
- end
-
- 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 "Can not cancel task #{model.task_uri}" end
- task.progress(15)
- delete_dependent(model.uri, subjectid) if model.uri
- task.progress(30)
- delete_dependent(model.validation_uri, subjectid) if model.validation_uri
- task.progress(45)
- delete_dependent(model.validation_report_uri, subjectid) if model.validation_report_uri
- task.progress(60)
- delete_dependent(model.validation_qmrf_uri, subjectid) if model.validation_qmrf_uri
- task.progress(75)
- delete_dependent(model.training_dataset, subjectid) if model.training_dataset
- task.progress(90)
- delete_dependent(model.feature_dataset, subjectid) if model.feature_dataset
- task.progress(100)
- ""
- end
- end
-
- def delete_dependent(uri, subjectid=nil)
- begin
- RestClient.delete(uri, :subjectid => subjectid) if subjectid
- RestClient.delete(uri) if !subjectid
- rescue
- LOGGER.warn "Can not delete uri: #{uri}"
- end
- end
-end
-
-before do
- #unless env['REQUEST_METHOD'] == "GET" or ( 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")
- #flash[:notice] = "You have to login first to do this."
- #redirect url_for('/login')
- end
- #end
-end
-
-get '/?' do
- redirect url_for('/create')
-end
-
-get '/login' do
- haml :login
-end
-
-get '/models/?' do
- @models = ToxCreateModel.all(:order => [ :created_at.desc ])
- subjectstring = session[:subjectid] ? "?subjectid=#{CGI.escape(session[:subjectid])}" : ""
- #@models.each { |model| model.process }
- haml :models, :locals=>{:models=>@models, :subjectstring => subjectstring}
-end
-
-get '/model/:id/status/?' do
- response['Content-Type'] = 'text/plain'
- model = ToxCreateModel.get(params[:id])
- #percentage_completed = task.metadata[OT.percentageCompleted] if (task = OpenTox::Task.exist?(model.task_uri))
- begin
- haml :model_status, :locals=>{:model=>model}, :layout => false
- rescue
- return "unavailable"
- end
-end
-
-get '/model/:id/progress/?' do
- response['Content-Type'] = 'text/plain'
- model = ToxCreateModel.get(params[:id])
- if model.task_uri
- if (OpenTox::Task.exist?(model.task_uri))
- task = OpenTox::Task.exist?(model.task_uri)
- percentage_completed = task.percentageCompleted
- end
- begin
- haml :model_progress, :locals=>{:percentage_completed=>percentage_completed}, :layout => false
- rescue
- return "unavailable"
- end
- else
- return ""
- end
-end
-
-get '/model/:id/name/?' do
- response['Content-Type'] = 'text/plain'
- model = ToxCreateModel.get(params[:id])
- begin
- case params[:mode]
- when 'edit'
- haml :model_name_edit, :locals=>{:model=>model}, :layout => false
- when 'show'
- haml :model_name, :locals=>{:model=>model}, :layout => false
- else
- params.inspect
- end
- rescue
- return "unavailable"
- end
-end
-
-put '/model/:id/?' do
- response['Content-Type'] = 'text/plain'
- model = ToxCreateModel.get(params[:id])
- begin
- if params[:name] && model.name != params[:name]
- model.name = params[:name]
- model.save
- end
- redirect url_for("/model/#{model.id}/name?mode=show")
- rescue
- return "unavailable"
- end
-end
-
-
-get '/model/:id/:view/?' do
- response['Content-Type'] = 'text/plain'
- model = ToxCreateModel.get(params[:id])
- subjectstring = session[:subjectid] ? "?subjectid=#{CGI.escape(session[:subjectid])}" : ""
- begin
- #model.process
- #model.save
- case params[:view]
- when "model"
- haml :model, :locals=>{:model=>model,:subjectstring => subjectstring}, :layout => false
- when /validation/
- haml :validation, :locals=>{:model=>model,:subjectstring => subjectstring}, :layout => false
- else
- return "unable to render model: id #{params[:id]}, view #{params[:view]}"
- end
- rescue
- return "unable to render model: id #{params[:id]}, view #{params[:view]}"
- end
-end
-
-get '/predict/?' do
- @models = ToxCreateModel.all(:order => [ :created_at.desc ])
- @models = @models.collect{|m| m if m.status == 'Completed'}.compact
- haml :predict
-end
-
-get '/create' do
- haml :create
-end
-
-get '/help' do
- haml :help
-end
-
-get "/confidence" do
- haml :confidence
-end
-
-# proxy to get data from compound service
-# (jQuery load does not work with external URIs)
-get %r{/compound/(.*)} do |inchi|
- inchi = URI.unescape request.env['REQUEST_URI'].sub(/^\//,'').sub(/.*compound\//,'')
- OpenTox::Compound.from_inchi(inchi).to_names.join(', ')
-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."
- redirect url_for('/create')
- end
-
- unless logged_in()
- logout
- 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)
- @model.update :web_uri => url_for("/model/#{@model.id}", :full), :warnings => ""
- @model.save
- task = OpenTox::Task.create("Uploading dataset and creating lazar model",url_for("/models",:full)) do |task|
-
- @model.update :status => "Uploading and saving dataset"
- 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
- LOGGER.debug csv
- @dataset.load_csv(csv, subjectid)
- when ".xls", ".xlsx"
- @dataset.load_spreadsheet(Excel.new params[:file][:tempfile].path, subjectid)
- else
- error "#{params[:file][:filename]} has a unsupported file type."
- 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."
- end
- @model.training_dataset = @dataset.uri
- @model.nr_compounds = @dataset.compounds.size
- @model.warnings = @dataset.metadata[OT.Warnings] unless @dataset.metadata[OT.Warnings].empty?
- @model.save
-
- @model.update :status => "Creating prediction model"
- task.progress(15)
- begin
- lazar = OpenTox::Model::Lazar.create(:dataset_uri => @dataset.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."
- end
- task.progress(25)
- @model.feature_dataset = lazar.metadata[OT.featureDataset]
- @model.uri = lazar.uri
- case lazar.metadata[OT.isA]
- when /Classification/
- @model.type = "classification"
- when /Regression/
- @model.type = "regression"
- else
- @model.type = "unknown"
- end
- @model.save
-
- unless url_for("",:full).match(/localhost/)
- @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))
- @model.update(:validation_uri => validation.uri)
- LOGGER.debug "Validation URI: #{@model.validation_uri}"
- rescue => e
- LOGGER.debug "Model validation failed with #{e.message}."
- @model.warnings += "Model validation failed with #{e.message}."
- end
- # create summary
- validation.summary(subjectid).each do |k,v|
- LOGGER.debug "mr ::: k: #{k.inspect} - v: #{v.inspect}"
- begin
- eval "@model.#{k.to_s} = v" if v
- rescue
- eval "@model.#{k.to_s} = 0"
- end
- end
- @model.save
-
- @model.update :status => "Creating validation report"
- begin
- @model.update(:validation_report_uri => validation.find_or_create_report(subjectid, OpenTox::SubTask.new(task,80,90))) unless @model.dirty?
- rescue => e
- LOGGER.debug "Validation report generation failed with #{e.message}."
- @model.warnings += "Validation report generation failed with #{e.message}."
- end
- @model.update :status => "Creating QMRF report"
- begin
- #@model.update(:validation_qmrf_report_uri => validation.create_qmrf_report(subjectid)) unless @model.dirty?
- qmrf_report = OpenTox::Crossvalidation::QMRFReport.create(@model.uri, subjectid, OpenTox::SubTask.new(task,90,99))
- @model.update(:validation_qmrf_uri => qmrf_report.uri)
- rescue => e
- LOGGER.debug "Validation QMRF report generation failed with #{e.message}."
- @model.warnings += "Validation QMRF report generation failed with #{e.message}."
- end
- 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?
- @model.update :status => "Completed"
- lazar.uri
- end
- @model.update(:task_uri => task.uri)
- @model.save
-
- 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')
-
-=begin
-=end
-end
-
-post '/predict/?' do # post chemical name to model
- subjectid = session[:subjectid] ? session[:subjectid] : nil
- @identifier = params[:identifier]
- unless params[:selection] and params[:identifier] != ''
- flash[:notice] = "Please enter a compound identifier and select an endpoint from the list."
- redirect url_for('/predict')
- end
- begin
- @compound = OpenTox::Compound.from_name(params[:identifier])
- rescue
- flash[:notice] = "Could not find a structure for '#{@identifier}'. Please try again."
- redirect url_for('/predict')
- end
- @predictions = []
- params[:selection].keys.each do |id|
- model = ToxCreateModel.get(id.to_i)
- #model.process unless model.uri
- prediction = nil
- confidence = nil
- title = nil
- db_activities = []
- lazar = OpenTox::Model::Lazar.new model.uri
- prediction_dataset_uri = lazar.run({:compound_uri => @compound.uri, :subjectid => subjectid})
- prediction_dataset = OpenTox::LazarPrediction.find(prediction_dataset_uri, subjectid)
- if prediction_dataset.metadata[OT.hasSource].match(/dataset/)
- @predictions << {
- :title => model.name,
- :measured_activities => prediction_dataset.measured_activities(@compound)
- }
- else
- predicted_feature = prediction_dataset.metadata[OT.dependentVariables]
- prediction = OpenTox::Feature.find(predicted_feature)
- LOGGER.debug prediction.to_yaml
- if prediction.metadata[OT.error]
- @predictions << {
- :title => model.name,
- :error => prediction.metadata[OT.error]
- }
- else
- @predictions << {
- :title => model.name,
- :model_uri => model.uri,
- :prediction => prediction.metadata[OT.prediction],
- :confidence => prediction.metadata[OT.confidence]
- }
- end
- end
- # TODO failed/unavailable predictions
-=begin
- source = prediction.creator
- if prediction.data[@compound.uri]
- if source.to_s.match(/model/) # real prediction
- prediction = prediction.data[@compound.uri].first.values.first
- #LOGGER.debug prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")]
- #LOGGER.debug prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
- if !prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")].nil?
- @predictions << {
- :title => model.name,
- :model_uri => model.uri,
- :prediction => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")],
- :confidence => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
- }
- elsif !prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#regression")].nil?
- @predictions << {
- :title => model.name,
- :model_uri => model.uri,
- :prediction => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#regression")],
- :confidence => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
- }
- end
- else # database value
- prediction = prediction.data[@compound.uri].first.values
- @predictions << {:title => model.name, :measured_activities => prediction}
- end
- else
- @predictions << {:title => model.name, :prediction => "not available (not enough similar compounds in the training dataset)"}
- end
-=end
- end
- LOGGER.debug @predictions.inspect
-
- haml :prediction
-end
-
-post "/lazar/?" do # get detailed prediction
- @page = 0
- @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 = OpenTox::LazarPrediction.find(prediction_dataset_uri, session[:subjectid])
- @compound = OpenTox::Compound.new(params[:compound_uri])
- #@title = prediction.metadata[DC.title]
- # TODO dataset activity
- #@activity = prediction.metadata[OT.prediction]
- #@confidence = prediction.metadata[OT.confidence]
- #@neighbors = []
- #@features = []
-# 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")]
-# @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 :lazar
-end
-
-post '/login' do
-=begin
- if session[:subjectid] != nil
- flash[:notice] = "You are already logged in as user: #{session[:username]}. Please log out first."
- redirect url_for('/login')
- end
-=end
- if params[:username] == '' || params[:password] == ''
- flash[:notice] = "Please enter username and password."
- redirect url_for('/login')
- end
- if login(params[:username], params[:password])
- flash[:notice] = "Welcome #{session[:username]}!"
- redirect url_for('/create')
- #haml :create
- else
- flash[:notice] = "Login failed. Please try again."
- haml :login
- end
-end
-
-post '/logout' do
- logout
- redirect url_for('/login')
-end
-
-delete '/model/:id/?' do
- model = ToxCreateModel.get(params[:id])
- raise OpenTox::NotFoundError.new("Model with id: #{params[:id]} not found!") unless model
- begin
- delete_model(model, @subjectid)
- model.destroy
- unless ToxCreateModel.get(params[:id])
- begin
- aa = OpenTox::Authorization.delete_policies_from_uri(model.web_uri, @subjectid)
- LOGGER.debug "Policy deleted for Dataset URI: #{uri} with result: #{aa}"
- rescue
- LOGGER.warn "Policy delete error for Dataset URI: #{uri}"
- end
- end
- flash[:notice] = "#{model.name} model deleted."
- rescue
- flash[:notice] = "#{model.name} model delete error."
- end
- redirect url_for('/models')
-end
-
-delete '/?' do
- DataMapper.auto_migrate!
- response['Content-Type'] = 'text/plain'
- "All Models deleted."
-end
-
-# SASS stylesheet
-get '/stylesheets/style.css' do
- headers 'Content-Type' => 'text/css; charset=utf-8'
- sass :style
-end
diff --git a/views/lazar.haml b/views/lazar.haml
deleted file mode 100644
index 9d9145e..0000000
--- a/views/lazar.haml
+++ /dev/null
@@ -1,58 +0,0 @@
-%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&regno=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