diff options
-rw-r--r-- | application.rb | 33 | ||||
-rw-r--r-- | helper.rb | 42 | ||||
-rw-r--r-- | model.rb | 2 | ||||
-rwxr-xr-x | public/javascripts/toxcreate.js | 50 | ||||
-rw-r--r-- | views/create.haml | 30 | ||||
-rw-r--r-- | views/model.haml | 3 | ||||
-rw-r--r-- | views/model_echa.haml | 4 | ||||
-rw-r--r-- | views/models.haml | 1 | ||||
-rw-r--r-- | views/models_navigation.haml | 46 | ||||
-rw-r--r-- | views/models_navigation_bottom.haml | 42 | ||||
-rw-r--r-- | views/predict.haml | 5 | ||||
-rw-r--r-- | views/style.sass | 64 |
12 files changed, 251 insertions, 71 deletions
diff --git a/application.rb b/application.rb index defe377..e61e155 100644 --- a/application.rb +++ b/application.rb @@ -96,8 +96,22 @@ get '/models/?' do sort_by = params["sort_by"] if sort_by case sort_by - when "name", "created_at", "type" - @models = ToxCreateModel.all.sort_by(sort_by.to_sym, :order => "#{order} ALPHA") + when "created_at" + @models = ToxCreateModel.all.sort(:order => "#{order}") + when "name" + @models = ToxCreateModel.all.sort + if order == "ASC" + @models = @models.sort_by{|x| x.name.downcase} + else + @models = @models.sort{|x, y| y.name.downcase <=> x.name.downcase} + end + when "type", "endpoint" + @models = ToxCreateModel.all.sort + if order == "ASC" + @models = @models.sort_by{|x| [x.send(sort_by.to_sym),x.name.downcase]} + else + @models = @models.sort{|x,y|[y.send(sort_by.to_sym),x.name.downcase] <=> [x.send(sort_by.to_sym), y.name.downcase]} + end when "id" @models = ToxCreateModel.all.sort(:order => "#{order}") end @@ -186,9 +200,10 @@ get '/model/:id/:view/?' do end get '/predict/?' do - @models = ToxCreateModel.all.sort(:order => "DESC") + @models = ToxCreateModel.all.sort @models.delete_if{|m| !is_authorized(m.web_uri, "GET")} @models = @models.collect{|m| m if m.status == 'Completed'}.compact + @models = @models.sort_by{|x| [x.endpoint ? x.endpoint : "Without Endpoint",x.name.downcase]} haml :predict end =begin @@ -237,8 +252,8 @@ post '/models' do # create a new model flash[:notice] = "You do not have the permission to create a new model." redirect url_for('/models') end - 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." + unless (params[:dataset] and params[:prediction_feature]) or (params[:endpoint] and params[:file] and params[:file][:tempfile]) #params[:endpoint] and + flash[:notice] = "Please upload a Excel or CSV file and select an endpoint or select an AMBIT dataset." redirect url_for('/create') end @@ -285,6 +300,8 @@ post '/models' do # create a new model else raise "#{params[:file][:filename]} has an unsupported file type." end + @dataset.features[@dataset.features.keys.first][OWL.sameAs] = params[:endpoint].split(',').first if params[:endpoint] + @model.update :endpoint_uri => params[:endpoint].split(',').first, :endpoint => params[:endpoint].split(',')[1..99].to_s.gsub(/^"(.*?)"$/,'\1') if params[:endpoint] @dataset.save(@subjectid) rescue => e error "Dataset creation failed '#{e.message}'",e @@ -294,8 +311,12 @@ post '/models' do # create a new model else @prediction_feature = OpenTox::Feature.find(@dataset.features.keys.first,@subjectid) end + #else + # test when external dataset is enabled: + #if @dataset.features[@dataset.features.keys.first][OWL.sameAs] + # @model.update :endpoint_uri => @dataset.features[@dataset.features.keys.first][OWL.sameAs], :endpoint => OpenTox::Ontology::Echa.get_endpoint_name(@dataset.features[@dataset.features.keys.first][OWL.sameAs]) + #end end - 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", "/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." @@ -100,9 +100,14 @@ helpers do haml :models_navigation, :layout => false end + def models_navigation_bottom + @page = 0 unless @page + haml :models_navigation_bottom, :layout => false + end + def endpoint_option_list(max_time=3600) out = "" - tmpfile = File.join(TMP_DIR, "endpoint_option_list") + tmpfile = File.join(TMP_DIR, 'endpoint_option_list') if File.exists? tmpfile if Time.now-File.mtime(tmpfile) <= max_time f = File.open(tmpfile, 'r+') @@ -112,12 +117,39 @@ helpers do File.unlink(tmpfile) end end - result = OpenTox::Ontology::Echa.endpoint_option_list() + result = endpoint_selection() if result.lines.count > 3 - f = File.new(tmpfile,"w") + f = File.new(tmpfile,'w') f.print result f.close end - return result + result + end + + def endpoint_level(endpoint="Endpoints", level=1) + results = OpenTox::Ontology::Echa.echa_endpoints(endpoint) rescue results = [] + out = "" + out += "<ul id='list_#{endpoint}' class='endpoint level_#{level}'>\n" if results.size > 0 + results.each do |result| + r = result.split(',') + endpointname = CGI.escape(r.first.split("#").last).gsub(".","") + title = r[1..r.size-1].to_s + out += " <li class='level_#{level}'><input type='radio' name='endpoint' value='#{result}' id='#{endpointname}' class='endpoint_list' /><label for='#{endpointname}' id='label_#{endpointname}'>#{title.gsub("\"","")}</label>\n" + out += endpoint_level(endpointname, level + 1) + out += "</li>\n" + end + out += "</ul>\n" if results.size > 0 + return out end -end + + def endpoint_selection() + out = "<span id='endpoint_label'></span><input type='button' id='endpoint_list_button' value='Select endpoint' /> \n + <div id='div_endpoint'>\n" + out += "<b>Please select:</b>\n" + out += endpoint_level + js = "" + out += "</div>\n" + return out + end + +end
\ No newline at end of file @@ -19,6 +19,8 @@ class ToxCreateModel < Ohm::Model attribute :training_dataset attribute :feature_dataset + attribute :endpoint_uri + attribute :endpoint #attributey :validation_task_uri attribute :validation_uri diff --git a/public/javascripts/toxcreate.js b/public/javascripts/toxcreate.js index 0e82040..ef2a953 100755 --- a/public/javascripts/toxcreate.js +++ b/public/javascripts/toxcreate.js @@ -25,12 +25,12 @@ $(function() { $.each(stati, function(){ checkProgress(this); if(checkStatus(this) > 0) newstati.push(this); - }); + }); if (newstati.length > 0) var statusCheck = setTimeout('checkStati("' + newstati.join(", ") + '")',10000); }; - + checkStatus = function(id) { - if(id == "") return -1; + if(id == "") return -1; var opts = {method: 'get', action: 'model/' + id + '/status', id: id}; var status_changed = $.ajax({ type: opts.method, @@ -43,15 +43,15 @@ $(function() { success: function(data) { var status_before = ""; if ($("span#model_" + id + "_status") != null) status_before = $("span#model_" + id + "_status").html().trim(); - if (status_before == "Deleting") return -1; + if (status_before == "Deleting") return -1; var status_after = data.trim(); $("span#model_" + id + "_status").animate({"opacity": "0.2"},1000); $("span#model_" + id + "_status").animate({"opacity": "1"},1000); if( status_before != status_after) { - $("span#model_" + id + "_status").html(data); + $("span#model_" + id + "_status").html(data); loadModel(id, 'model'); if (status_after == "Completed" || status_after == "Error") id = -1; - } + } }, error: function(data) { //alert("status check error"); @@ -60,8 +60,8 @@ $(function() { }); return id; }; - - + + checkProgress = function(id) { var task = $("input#model_" + id + "_task").attr('value'); var opts = {action: task + "/percentageCompleted" , id: id}; @@ -74,9 +74,8 @@ $(function() { }, success: function(data) { var progress = data.trim(); - if (progress == "100") return -1; - - $("div#model_" + id + "_progress").progressbar("value", parseInt(progress)); + if (progress == "100") return -1; + $("div#model_" + id + "_progress").progressbar("value", parseInt(progress)); $("div#model_" + id + "_progress").attr({title: parseInt(progress) + "%"}); }, error: function(data) { @@ -84,10 +83,10 @@ $(function() { } }); return id; - }; + }; loadModel = function(id, view) { - if(id == "") return -1; + if(id == "") return -1; var opts = {method: 'get', action: 'model/' + id + '/' + view, view: view }; var out = id; $.ajax({ @@ -118,7 +117,7 @@ jQuery.fn.editModel = function(options) { trigger_on: 'click' }; var opts = $.extend(defaults, options); - this.bind(opts.trigger_on, function() { + this.bind(opts.trigger_on, function() { $.ajax({ type: opts.method, url: opts.action, @@ -126,7 +125,7 @@ jQuery.fn.editModel = function(options) { data: { '_method': 'get' }, - success: function(data) { + success: function(data) { $("div#model_" + opts.id + "_name").html(data); $("input#model_" + opts.id + "_name").focus(); }, @@ -145,8 +144,8 @@ jQuery.fn.cancelEdit = function(options) { trigger_on: 'click' }; var opts = $.extend(defaults, options); - - this.bind(opts.trigger_on, function() { + + this.bind(opts.trigger_on, function() { $.ajax({ type: opts.method, url: opts.action, @@ -154,7 +153,7 @@ jQuery.fn.cancelEdit = function(options) { data: { '_method': 'get' }, - success: function(data) { + success: function(data) { $("div#model_" + opts.id + "_name").html(data); }, error: function(data) { @@ -172,9 +171,9 @@ jQuery.fn.saveModel = function(options) { trigger_on: 'click' }; var opts = $.extend(defaults, options); - - this.bind(opts.trigger_on, function() { - var name = $("input#model_" + opts.id + "_name").val(); + + this.bind(opts.trigger_on, function() { + var name = $("input#model_" + opts.id + "_name").val(); $.ajax({ type: opts.method, url: opts.action, @@ -183,7 +182,7 @@ jQuery.fn.saveModel = function(options) { '_method': 'put', 'name': name }, - success: function(data) { + success: function(data) { $("div#model_" + opts.id + "_name").html(data); }, error: function(data) { @@ -215,7 +214,7 @@ jQuery.fn.deleteModel = function(type, options) { data: { '_method': 'delete' }, - success: function(data) { + success: function(data) { $("div#model_" + opts.id).fadeTo("slow",0).slideUp("slow").remove(); }, error: function(data) { @@ -236,9 +235,6 @@ addExternalLinks = 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; + $(this).attr('target', '_blank'); }); }; diff --git a/views/create.haml b/views/create.haml index da85382..a26ae05 100644 --- a/views/create.haml +++ b/views/create.haml @@ -1,3 +1,30 @@ +:javascript + $(document).ready(function() { + $(".endpoint_list").click(function() { + elem = this.id; + title = $("label#label_" + elem).html(); + if($("ul#list_" + elem)) { + if ($("ul#list_" + elem).is(":hidden")) { + $("ul#list_" + elem).slideDown("slow"); + } else { + $("ul#list_" + elem).slideUp("slow"); + } + } + $("span#endpoint_label").html(title); + }); + $("#endpoint_list_button").click(function() { + if ($("div#div_endpoint").is(":hidden")) { + $("div#div_endpoint").slideDown("slow"); + $("input#endpoint_list_button").val("Hide"); + $("input#endpoint_list_button").toggleClass("ok_button", true); + } else { + $("div#div_endpoint").slideUp("slow"); + $("input#endpoint_list_button").val("Select endpoint"); + $("input#endpoint_list_button").toggleClass("ok_button", false); + } + }); + }); + .input %p @@ -25,7 +52,8 @@ format: %input{:type => 'file', :name => 'file', :id => 'file', :size => '41'} %br - -# = haml :model_echa, :layout => false + = haml :model_echa, :layout => false + %br %input{ :type => "submit", :value => "Create model"} =# link_to "Cancel", '/create' diff --git a/views/model.haml b/views/model.haml index e88f9b4..0bb2be0 100644 --- a/views/model.haml +++ b/views/model.haml @@ -41,6 +41,9 @@ - if model.nr_compounds %dt Training compounds: %dd= model.nr_compounds + - if model.endpoint + %dt Endpoint: + %dd= model.endpoint - if model.error_messages %dt Errors: %dd= model.error_messages diff --git a/views/model_echa.haml b/views/model_echa.haml index 257a28a..4815c35 100644 --- a/views/model_echa.haml +++ b/views/model_echa.haml @@ -1,2 +1,2 @@ -Select an endpoint: -= endpoint_option_list
\ No newline at end of file +For endpoint: += endpoint_option_list()
\ No newline at end of file diff --git a/views/models.haml b/views/models.haml index 947e403..2e60fc6 100644 --- a/views/models.haml +++ b/views/models.haml @@ -26,3 +26,4 @@ = haml :model, :locals=>{:model=>model}, :layout => false -if @models.size == 0 .notice There are currently no models. You have to create a model first. += models_navigation_bottom if @models.size > 1
\ No newline at end of file diff --git a/views/models_navigation.haml b/views/models_navigation.haml index 0dc1f63..c5eda97 100644 --- a/views/models_navigation.haml +++ b/views/models_navigation.haml @@ -1,12 +1,12 @@ .models_navigation - + - js = "" %form{:name => "nav", :action => url_for('/models'), :method => "get", :id => "nav"} %input{:type => :hidden, :name => :sort_by, :id => "sort_by", :value => params[:sort_by]} %input{:type => :hidden, :name => :order, :id => "order", :value => params[:order]} %input{:type => :hidden, :name => :page, :id => "page", :value => params[:page]} Sort by: - - ["created_at","name","type"].each do |s| + - ["created_at","name","type","endpoint"].each do |s| - idname = s == "created_at" ? "date" : s - if params[:sort_by] == s %div{:id => idname, :class => "active"} @@ -22,32 +22,42 @@ - if @models.size > 5 | Models: - = "#{@models.size}" - - unless @page.to_i == 0 - #prev - %img{:src => "arrow_left.png", :alt => 'previous', :title => 'previous'}/ - -else - %img{:src => "arrow_left_inactive.png", :alt => '', :title => ''}/ - - if @models.size < 5*@page+5 - last = @models.size - else - last = 5*@page+5 - - = "(#{5*@page+1}-#{last}/#{@models.size})" + + = "#{5*@page+1}-#{last} / #{@models.size}" + + | Page: + - unless @page.to_i == 0 + #prev{:class => "link"} + %img{:src => "arrow_left.png", :alt => 'previous', :title => 'previous'}/ + -else + %img{:src => "arrow_left_inactive.png", :alt => '', :title => ''}/ + + - (0..(@models.size/5).to_f.ceil-1).each do |p| + -if p != @page.to_f + %a{:href => '#', :id => "page_link_#{p}", :class => "page page_link"} #{p+1} + - js += "$('#page_link_#{p}').click(function() \{ \n" + - js += " $('#page').val('#{p}');\n" + - js += " $('#nav').submit();\n" + - js += "});\n" + -else + %span{:class => "page page_active"} #{p+1} + - unless 5*@page.to_i+5 >= @models.size - #next + #next{:class => "link"} %img{:src => "arrow_right.png", :alt => 'next', :title => 'next'}/ -else %img{:src => "arrow_right_inactive.png", :alt => '', :title => ''}/ - - js = "" - - ["created_at","name","type"].each do |s| + - ["created_at","name","type","endpoint"].each do |s| - idname = s == "created_at" ? "date" : s - - js += "$('##{idname}').click(function() \{ \n " - - js += " $('#sort_by').val('#{s}');\n " - - js += " $('#nav').submit();\n " - - js += "});\n " + - js += "$('##{idname}').click(function() \{ \n" + - js += " $('#sort_by').val('#{s}');\n" + - js += " $('#nav').submit();\n" + - js += "});\n" :javascript $("#prev").click(function() { diff --git a/views/models_navigation_bottom.haml b/views/models_navigation_bottom.haml new file mode 100644 index 0000000..b2425fa --- /dev/null +++ b/views/models_navigation_bottom.haml @@ -0,0 +1,42 @@ +.models_navigation + - js = "" + - if @models.size > 5 + Models: + - if @models.size < 5*@page+5 + - last = @models.size + - else + - last = 5*@page+5 + = "#{5*@page+1}-#{last} / #{@models.size}" + | Page: + - unless @page.to_i == 0 + #prevbot{:class => "link"} + %img{:src => "arrow_left.png", :alt => 'previous', :title => 'previous'}/ + -else + %img{:src => "arrow_left_inactive.png", :alt => '', :title => ''}/ + + - (0..(@models.size/5).to_f.ceil-1).each do |p| + -if p != @page.to_f + %a{:href => '#', :id => "page_linkbot_#{p}", :class => "page page_link"} #{p+1} + - js += "$('#page_linkbot_#{p}').click(function() \{ \n" + - js += " $('#page').val('#{p}');\n" + - js += " $('#nav').submit();\n" + - js += "});\n" + -else + %span{:class => "page page_active"} #{p+1} + + - unless 5*@page.to_i+5 >= @models.size + #nextbot{:class => "link"} + %img{:src => "arrow_right.png", :alt => 'next', :title => 'next'}/ + -else + %img{:src => "arrow_right_inactive.png", :alt => '', :title => ''}/ + + :javascript + $("#prevbot").click(function() { + $("#page").val(#{@page-1}); + $("#nav").submit(); + }); + $("#nextbot").click(function() { + $("#page").val(#{@page+1}); + $("#nav").submit(); + }); + #{js}
\ No newline at end of file diff --git a/views/predict.haml b/views/predict.haml index fe84e89..f326bf8 100644 --- a/views/predict.haml +++ b/views/predict.haml @@ -41,7 +41,12 @@ 2. Select one or more toxic endpoints %br + - endpoint = '' - @models.each do |model| + -if model.endpoint != endpoint + -endpoint = model.endpoint + %b #{endpoint}: + %br %input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => "model#{model.id}", :disabled => false} %label{:for => "model#{model.id}"} = model.name diff --git a/views/style.sass b/views/style.sass index ab05d93..c146ba3 100644 --- a/views/style.sass +++ b/views/style.sass @@ -6,6 +6,7 @@ $ot_purple: #5d308a $body_color: white $text_color: black $notice_border: red +$mouseover: #FFFF69 body min-width: 30em @@ -283,14 +284,7 @@ dl float: left .models_navigation - #prev - @extend a - display: inline - cursor: pointer - #next - @extend a - display: inline - cursor: pointer + margin-top: 4px .link @extend a display: inline @@ -301,13 +295,59 @@ dl font-weight: bold .thin font-weight: 100 + .page + border: solid 1px #999 + background-color: #FFF + padding: 0px 3px + font-size: 94% + font-weight: bold + .page_link:hover + border-color: #000 + color: #000 + .page_active + background-color: #ccd2dc + color: #000 + font-weight: bold + border-right-color: #000 + border-bottom-color: #000 + +ul.endpoint + list-style-type: none + margin-left: 0px + padding-left: 0px + +ul.level_2 + display: none +ul.level_3 + display: none +ul.level_4 + display: none .level_1 - padding-left: 10px + margin-left: 0px font-weight: bold .level_2 - padding-left: 20px + margin-left: 20px + font-weight: normal .level_3 - padding-left: 30px + margin-left: 40px + font-weight: normal .level_4 - padding-left: 40px + margin-left: 60px + font-weight: normal + +#endpoint_label + font-weight: bold + margin: 0 10px + +ul.endpoint + label:hover, label:active + background-color: $mouseover + border-bottom: solid #999 1px + border-top: solid #999 1px + +#div_endpoint + display: none + +.ok_button + background-color: $mouseover |