summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgebele <gebele@in-silico.ch>2019-08-01 16:48:14 +0000
committergebele <gebele@in-silico.ch>2019-08-01 16:48:14 +0000
commit1ffdd765fe4b4d9d80626070dea652fe467a2fa5 (patch)
treee3fa00d6a125f966b3f41068ffc9ed6955a0e328
parent807b87cf18b42c055e62c91e31b05a728a7fdd42 (diff)
introduce task for upload and parse to dataset
-rw-r--r--application.rb34
-rw-r--r--public/javascripts/lazar-gui.js86
-rw-r--r--views/batch.haml34
3 files changed, 102 insertions, 52 deletions
diff --git a/application.rb b/application.rb
index fa2a728..8872e5f 100644
--- a/application.rb
+++ b/application.rb
@@ -167,7 +167,7 @@ end
post '/predict/?' do
# process batch prediction
- if !params[:fileselect].blank?
+ unless params[:fileselect].blank?
if params[:fileselect][:filename] !~ /\.csv$/
bad_request_error "Wrong file extension for '#{params[:fileselect][:filename]}'. Please upload a CSV file."
end
@@ -175,9 +175,20 @@ post '/predict/?' do
File.open('tmp/' + params[:fileselect][:filename], "w") do |f|
f.write(params[:fileselect][:tempfile].read)
end
- input = Dataset.from_csv_file File.join("tmp", params[:fileselect][:filename])
- $logger.debug "Processing '#{params[:fileselect][:filename]}'"
- @compounds_size = input.compounds.size
+ uploadTask = Task.new
+ uploadTask.save
+ uploadDataset = Task.run do
+ t = uploadTask
+ t.update_percent(1)
+ $logger.debug "Processing '#{params[:fileselect][:filename]}'"
+ @input = Dataset.from_csv_file File.join("tmp", params[:fileselect][:filename])
+ t.update_percent(100)
+ t.save
+ end
+ @upid = uploadTask.id
+
+ #TODO route for compound size
+ @compounds_size = 0 #@input.compounds.size
@models = params[:selection].keys
@tasks = []
@models.each{|m| t = Task.new; t.save; @tasks << t}
@@ -190,6 +201,10 @@ post '/predict/?' do
prediction = {}
model = Model::Validation.find model_id
t.update_percent(10)
+ input = Dataset.find_by(:source => "tmp/"+@filename)
+ until input
+ sleep 1
+ end
prediction_dataset = model.predict input
t.update_percent(70)
t[:dataset_id] = prediction_dataset.id
@@ -232,10 +247,18 @@ post '/predict/?' do
end
get '/prediction/task/?' do
+ # returns task progress in percentage
if params[:turi]
task = Task.find(params[:turi].to_s)
response['Content-Type'] = "application/json"
- return JSON.pretty_generate(:percent => task.percent)
+ if task.dataset_id
+ d = Dataset.find task.dataset_id
+ size = d.compounds.size
+ return JSON.pretty_generate(:percent => task.percent, :size => size)
+ else
+ return JSON.pretty_generate(:percent => task.percent)
+ end
+ # kills task process id
elsif params[:ktpid]
begin
Process.kill(9,params[:ktpid].to_i) if !params[:ktpid].blank?
@@ -244,6 +267,7 @@ get '/prediction/task/?' do
end
response['Content-Type'] = "application/json"
return JSON.pretty_generate(:ktpid => params[:ktpid])
+ # returns task details
elsif params[:predictions]
task = Task.find(params[:predictions])
pageSize = params[:pageSize].to_i - 1
diff --git a/public/javascripts/lazar-gui.js b/public/javascripts/lazar-gui.js
index 214529b..dcbc4c5 100644
--- a/public/javascripts/lazar-gui.js
+++ b/public/javascripts/lazar-gui.js
@@ -204,6 +204,19 @@ var markers = [];
est.innerHTML = newtime;
};*/
+uploadDataset = function(task_uri) {
+ var uri = task_uri;
+ var aClient = new HttpClient();
+ aClient.get(uri, function(res) {
+ var response = JSON.parse(res);
+ if (response['percent'] == 100){
+ window.clearInterval(uploadInterval);
+ var element = document.getElementById("uploadDataset");
+ element.parentNode.removeChild(element);
+ };
+ });
+};
+
renderTask = function(task_uri,id) {
var uri = task_uri;
var aClient = new HttpClient();
@@ -232,39 +245,48 @@ simpleTemplating = function(data) {
return html;
};
-pagePredictions = function(task_uri,model_id,id,compoundsSize){
+pagePredictions = function(task_uri,model_id,id, compounds_uri){
button = document.getElementById("detailsbutton_"+id);
span = button.childNodes[1];
- if (span.className == "fa fa-caret-right"){
- span.className = "fa fa-caret-down";
- $('#data-container_'+id).removeClass("d-none");
- $('#data-container_'+id).show();
- $('#pager_'+id).show();
- $('#pager_'+id).pagination({
- dataSource: task_uri,
- locator: 'prediction',
- totalNumber: compoundsSize,
- pageSize: 1,
- showPageNumbers: true,
- showGoInput: true,
- formatGoInput: 'go to <%= input %>',
- formatAjaxError: function(jqXHR, textStatus, errorThrown) {
- $('#data-container_'+id).html(errorThrown);
- },
- /*ajax: {
- beforeSend: function() {
- $('#data-container_'+id).html('Loading content ...');
+ // get compounds size first
+ var compoundsSize = 0;
+ var aClient = new HttpClient();
+ aClient.get(compounds_uri, function(res) {
+ var response = JSON.parse(res);
+ compoundsSize = response['size']
+ // handle pager in callback function
+ // ensures compoundsSize is > 0
+ if (span.className == "fa fa-caret-right"){
+ span.className = "fa fa-caret-down";
+ $('#data-container_'+id).removeClass("d-none");
+ $('#data-container_'+id).show();
+ $('#pager_'+id).show();
+ $('#pager_'+id).pagination({
+ dataSource: task_uri,
+ locator: 'prediction',
+ totalNumber: compoundsSize,
+ pageSize: 1,
+ showPageNumbers: true,
+ showGoInput: true,
+ formatGoInput: 'go to <%= input %>',
+ formatAjaxError: function(jqXHR, textStatus, errorThrown) {
+ $('#data-container_'+id).html(errorThrown);
+ },
+ /*ajax: {
+ beforeSend: function() {
+ $('#data-container_'+id).html('Loading content ...');
+ }
+ },*/
+ callback: function(data, pagination) {
+ var html = simpleTemplating(data);
+ $('#data-container_'+id).html(html);
+ //$('#data-container_'+id).css("min-height", $(window).height() + "px" );
}
- },*/
- callback: function(data, pagination) {
- var html = simpleTemplating(data);
- $('#data-container_'+id).html(html);
- //$('#data-container_'+id).css("min-height", $(window).height() + "px" );
- }
- });
- } else if (span.className = "fa fa-caret-down"){
- span.className = "fa fa-caret-right";
- $('#data-container_'+id).hide();
- $('#pager_'+id).hide();
- };
+ });
+ } else if (span.className = "fa fa-caret-down"){
+ span.className = "fa fa-caret-right";
+ $('#data-container_'+id).hide();
+ $('#pager_'+id).hide();
+ };
+ });
};
diff --git a/views/batch.haml b/views/batch.haml
index efb9b71..2e48ec0 100644
--- a/views/batch.haml
+++ b/views/batch.haml
@@ -11,24 +11,26 @@
%a.btn.btn-outline-info{:href => to("/predict?tpid=#{@pid}")}
%span.fa.fa-caret-left{:aria=>{:hidden=>"true"}}
New Prediction
+%div.card.bg-light{:id=>"uploadDataset"}
+ %div.card-body
+ %h3.card-title="Processing file #{@filename} to dataset."
+ %img.h2{:src=>"/images/wait30trans.gif", :id=>"circle_upload", :class=>"circle", :alt=>"processing"}
+ :javascript
+ uploadInterval = setInterval(function(){
+ uploadDataset('#{to("/prediction/task/?turi=#{@upid}")}');
+ }, 1000 );
+
%div.card.bg-light
%div.card-body
%h3.card-title="Batch prediction results for: #{@filename}"
// prepare variable values for javascript
// increase timer interval for large datasets
- - ctimer = ((@compounds_size/1000) == 0 ? 1000 : ((@compounds_size/1000)*1000))
- //- approx = {}
- //- sum_approx = 0
+ - ctimer = 1000#((@compounds_size/1000) == 0 ? 1000 : ((@compounds_size/1000)*1000))
// process batch predictions
- @models.each_with_index do |model,idx|
- m = Model::Validation.find model
- task = @tasks[idx].id
- //- tasktime = task.generation_time.to_i
- // assume single compound prediction time: classification=0.1s,regression=0.5s
- //- task_approx = m.classification? ? (tasktime*1000 + @compounds_size*100) : (tasktime*1000 + @compounds_size*500)
- //- approx[idx] = task_approx + sum_approx
- //- sum_approx += (m.classification? ? @compounds_size*100 : @compounds_size*500)
#result.card.bg-light{:id=>idx}
%div.card-body
%div.row
@@ -36,14 +38,12 @@
%h5.card-title="#{m.endpoint} (#{m.species})"
#pager{:id=>idx}
%div.col-6
- %a.btn.btn-outline-info.btn-sm.disabled{:id => "detailsbutton_#{idx}", :data=>{:toggle=>"collapse"}, :href=>"javascript:void(0)", :onclick=>"pagePredictions('#{to("/prediction/task/?predictions=#{task}")}','#{model}','#{idx}','#{@compounds_size}')"}
+ %a.btn.btn-outline-info.btn-sm.disabled{:id => "detailsbutton_#{idx}", :data=>{:toggle=>"collapse"}, :href=>"javascript:void(0)", :onclick=>"pagePredictions('#{to("/prediction/task/?predictions=#{task}")}','#{model}','#{idx}','#{to("/prediction/task/?turi=#{task}")}')"}
%span.fa.fa-caret-right
Details
%a.btn.btn-outline-info.btn-sm.disabled{:id => "downbutton_#{idx}", :href=>"#{to("/predict/batch/download?tid=#{task}")}", :title=>"download"}
%span.fa.fa-download
CSV
- -#%div{:id=>"progress_#{idx}", :style=>"width:100%;height:3px;position:relative;background-color:#ccc;"}
- %div{:id=>"bar_#{idx}", :style=>"background-color: #4CAF50;width:10px;height:3px;position:absolute;"}
%p{:id=>"est_#{idx}"}
waiting ...
%img.h2{:src=>"/images/wait30trans.gif", :id=>"circle_#{idx}", :class=>"circle", :alt=>"wait", :style=>"display:none;"}
@@ -60,7 +60,6 @@
var button = document.getElementById("detailsbutton_"+(idx-1));
if(!button.classList.contains('disabled')){
renderTask(task_uri,idx);
- //remaining(idx,approximate);
$("#est_"+idx).hide();
$("#circle_"+idx).show();
}
@@ -68,9 +67,14 @@
}else{
markers[idx] = setInterval(function(){
renderTask(task_uri,idx);
- //remaining(idx,approximate);
- $("#est_"+idx).hide();
- $("#circle_"+idx).show();
+ // check that dataset parsing is completed
+ if (document.getElementById("uploadDataset")){
+ $("#est_"+idx).show();
+ $("#circle_"+idx).hide();
+ } else {
+ $("#est_"+idx).hide();
+ $("#circle_"+idx).show();
+ }
}, timer );
};
};