From d420e64b3869130bc8526ff2659da6fd35bc6548 Mon Sep 17 00:00:00 2001 From: gebele Date: Tue, 20 Sep 2016 15:18:10 +0000 Subject: changed for two model selection --- Gemfile | 2 +- VERSION | 2 +- application.rb | 54 ++++++++++++++----- config.ru | 1 + nano-lazar.gemspec | 1 + public/images/wait30trans.gif | Bin 0 -> 6774 bytes views/layout.haml | 2 +- views/predict.haml | 123 ++++++++++++++++++++++++++++++++++-------- views/prediction.haml | 111 +++++++++++++++++--------------------- 9 files changed, 198 insertions(+), 98 deletions(-) create mode 100644 public/images/wait30trans.gif diff --git a/Gemfile b/Gemfile index 9ceb553..3cde411 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" gemspec +gem "lazar", :path => "../lazar" gem "sinatra" gem "haml" -gem "rserve-client" gem "rdiscount" diff --git a/VERSION b/VERSION index 4e379d2..bcab45a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.2 +0.0.3 diff --git a/application.rb b/application.rb index 1f7fa00..98e502f 100644 --- a/application.rb +++ b/application.rb @@ -1,23 +1,29 @@ -require 'json' require 'rdiscount' -require_relative './nanoparticles.rb' - $ambit_search = "http://data.enanomapper.net/substance?type=name&search=" configure :development do $logger = Logger.new(STDOUT) end +before do + @version = File.read("VERSION").chomp +end + get '/?' do redirect to('/predict') end get '/predict/?' do - @version = File.read("VERSION").chomp - data = JSON.parse(File.read("./data.json")) - query_features = JSON.parse(File.read("./query-features.json")) - @example = data[data.keys.sample]["physchem"].select{|f,v| query_features.include? f} - #@json_example = JSON.pretty_generate(@example) + @prediction_models = [] + prediction_models = OpenTox::Model::NanoPrediction.all + prediction_models.each{|m| m.model[:feature_selection_algorithm_parameters]["category"] == "P-CHEM" ? @prediction_models[0] = m : @prediction_models[1] = m} + @prediction_models.each_with_index{|m,idx| idx == 0 ? m[:pc_model] = true : m[:pcp_model] = true} + example = OpenTox::Nanoparticle.all.select{|n| n.core["name"] == "Au"}.sample + @example_pcp = example + example = OpenTox::Nanoparticle.all.select{|n| n.core["name"] == "Au"}.sample + example.physchem_descriptors.delete_if{|k,v| feature = OpenTox::Feature.find_by(:id => k); feature.category != "P-CHEM"} + @example_pc = example + haml :predict end @@ -27,10 +33,34 @@ get '/license' do end post '/predict/?' do + prediction_model = OpenTox::Model::NanoPrediction.find(params[:prediction_model]) size = params[:size].to_i - @input = [] - (1..size).each{|i| @input << [params["input_key_#{i}"], params["input_value_#{i}"].to_f]} - @params = Hash[*@input.flatten] - @prediction = predict @params + example_pc = eval(params[:example_pc]) + pc_descriptors = {} + (1..size).each{|i| pc_descriptors["#{params["input_key_#{i}"]}"] = [params["input_value_#{i}"].to_f]} + if example_pc == pc_descriptors + # unchanged input = database hit + nanoparticle = OpenTox::Nanoparticle.find_by(:id => params[:example_id]) + nanoparticle.physchem_descriptors = pc_descriptors + else + # changed input = create nanoparticle to predict + nanoparticle = OpenTox::Nanoparticle.new + nanoparticle.core = eval(params[:core]) + nanoparticle.coating = eval(params[:coating]) + nanoparticle.physchem_descriptors = pc_descriptors + end + # output + @input = pc_descriptors + @prediction = prediction_model.model.predict_substance nanoparticle + @match = true,@nanoparticle = nanoparticle,@name = nanoparticle.name if @prediction[:warning] =~ /identical/ + #@prediction[:neighbors].each do |n| + #puts n + #puts nano = OpenTox::Nanoparticle.find(n["_id"]) + #puts nano.name + #puts n["similarity"] + #puts n["measurements"] + #puts nano.physchem_descriptors.delete_if{|k,v| feature = OpenTox::Feature.find_by(:id => k); feature.category != "P-CHEM"}.size + #end + haml :prediction end diff --git a/config.ru b/config.ru index 1e7f981..4f8501e 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,4 @@ +ENV["LAZAR_ENV"] = "development" SERVICE = "nano-lazar-gui" require 'bundler' Bundler.require diff --git a/nano-lazar.gemspec b/nano-lazar.gemspec index c6ae2b1..6e322f3 100644 --- a/nano-lazar.gemspec +++ b/nano-lazar.gemspec @@ -15,6 +15,7 @@ Gem::Specification.new do |s| s.files = `git ls-files`.split("\n") s.required_ruby_version = '>= 2.0.0' + s.add_runtime_dependency "lazar" s.add_runtime_dependency "sinatra" s.add_runtime_dependency "rdiscount" s.add_runtime_dependency "haml" diff --git a/public/images/wait30trans.gif b/public/images/wait30trans.gif new file mode 100644 index 0000000..183fe6f Binary files /dev/null and b/public/images/wait30trans.gif differ diff --git a/views/layout.haml b/views/layout.haml index d924f95..f36bdf7 100644 --- a/views/layout.haml +++ b/views/layout.haml @@ -35,7 +35,7 @@ %div.col-md-2 %h1.media-heading{:style=>"margin: 0 0 0 1em;"} %small - %a{:href=>"https://lazar.in-silico.ch/predict"} lazar + %a{:href=>"https://lazar.in-silico.ch/predict", :rel=>"external"} lazar %div.container-fluid %topline diff --git a/views/predict.haml b/views/predict.haml index 7fa52ed..7c25def 100644 --- a/views/predict.haml +++ b/views/predict.haml @@ -1,23 +1,102 @@ +:javascript + function showcircle() { + $("img.circle").show(); + }; + %div.well - %form{:role=>"form", :action=> to("/predict"), :method=>"post"} - %h3.help-block - Please characterise a nanoparticle - %hr - #input - - size = @example.size - %div.form-group - %h5 Core - %input.input-sm.form-control{:id=>"Au",:type=>"text",:name=>"input_value_Au",:value=>"[Au]", :disabled=>"true"} - - @example.each_with_index do |v,id| - - id = id + 1 - - key = v[0] - - val = v[1] - %h5= key.gsub(/\sMean/, '') - %input.form-control{:id=>id,:type=>"hidden",:name=>"input_key_#{id}",:value=>key} - %input.input-sm.form-control{:id=>id,:type=>"text",:name=>"input_value_#{id}",:value=>val} - %input.form-control{:id=>"example",:type=>"hidden",:name=>"size",:value=>size} - %hr - #predict - %button.btn.btn-success{:type=>"submit"} - Find similar nano particles - %span.glyphicon.glyphicon-chevron-right + %h3.help-block + Select an endpoint: + #tabs + %ul.nav.nav-tabs{:id=>"modelTab", :role=>"tablist"} + - @prediction_models.each_with_index do |m, idx| + %li{:class => ("active" if idx == 0)} + %a{:href => "#model_#{idx}", :id => "linkTab#{idx}", data: {toggle:"tab"}} + = "#{idx+1}. #{m.model.feature_selection_algorithm_parameters[:category].nil? ? "P-CHEM & Proteomics" : "P-CHEM" }" + %div.tab-content + - @prediction_models.each_with_index do |m, idx| + - m[:pc_model] ? example = @example_pc : example = @example_pcp + #model.tab-pane{:id=>"#{idx}", :class => ("active" if idx == 0)} + %b Model: + %br + Name: + = m.model.name + %br + Type: regression + %br + Source: + %a{:href=>"#{m.source}", :alt=>"source", :rel=>"external"} + = m.source + %br + Species: + = m.species + %br + Training nanoparticles: + = m.model.training_dataset.nanoparticles.size + %br + Endpoint: + = m.endpoint + %br + Unit: + = m.unit + %p + - cv = OpenTox::CrossValidation.find(m.repeated_crossvalidation_id) + %b Independent crossvalidations (log2 transformed): + - crossvalidations =[] + - m.repeated_crossvalidation.crossvalidation_ids.each{|cv| c = OpenTox::Validation::CrossValidation.find(cv); crossvalidations << c} + %div.row{:id=>"validations#{m.id}", :style=>"background-color:#f5f5f5;"} + - crossvalidations.each do |cv| + %span.col-xs-4.col-sm-4.col-md-4.col-lg-4 + = "Num folds:\t" + = cv.folds + %br + = "Num instances:\t" + = cv.nr_instances + %br + = "Num unpredicted" + = cv.nr_unpredicted + %br + = "Root mean squared error:\t" + = cv.rmse.round(3) if cv.rmse + %br + = "Mean absolute error:\t" + = cv.mae.round(3) if cv.mae + %br + = "R square:\t" + = cv.r_squared.round(3) if cv.r_squared + %br + %hr + %form{:id=>idx, :role=>"form", :action=> to("/predict"), :method=>"post"} + %h3.help-block + Please characterise a nanoparticle: + #input + %div.form-group + %h5 Core + %input.input-sm.form-control{:id=>"core_name",:type=>"text",:name=>"core_name",:value=>example.core["name"], :disabled=>"true"} + - example.physchem_descriptors.each_with_index do |v,id| + - feature = OpenTox::Feature.find_by(:id => v[0]) + - name = feature.name + - if feature[:conditions] && !feature[:conditions]["MEDIUM"].blank? + - name = feature.name + " / " + feature[:conditions]["MEDIUM"] + - else + - name = feature.name + - val = v[1] + - id = id + 1 + %h5= name + %input.form-control{:id=>id,:type=>"hidden",:name=>"input_key_#{id}",:value=>v[0]} + %input.input-sm.form-control{:id=>id,:type=>"text",:name=>"input_value_#{id}",:value=>val[0]} + %input.form-control{:id=>id,:type=>"hidden",:name=>"input_key_#{id}",:value=>v[0]} + %input.input-sm.form-control{:id=>id,:type=>"hidden",:name=>"input_value_#{id}",:value=>val[0]} + %input.form-control{:id=>"example_id",:type=>"hidden",:name=>"example_id",:value=>example.id} + %input.form-control{:id=>"core",:type=>"hidden",:name=>"core",:value=>"#{example.core}"} + %input.form-control{:id=>"coating",:type=>"hidden",:name=>"coating",:value=>example.coating} + %input.form-control{:id=>"prediction_model",:type=>"hidden",:name=>"prediction_model",:value=>m.id} + - example_pc = example.physchem_descriptors + %input.form-control{:id=>"example_pc",:type=>"hidden",:name=>"example_pc",:value=>"#{example_pc}"} + - size = example.physchem_descriptors.size + %input.form-control{:id=>"size",:type=>"hidden",:name=>"size",:value=>size} + %hr + #predict + %button.btn.btn-success{:id=>"submitbutton", :type=>"submit", :onclick=>"showcircle();"} + Find similar nano particles + %span.glyphicon.glyphicon-chevron-right{:id=>"span"} + %img{:src=>"/images/wait30trans.gif", :id=>"circle", :class=>"circle", :alt=>"wait", :style=>"display:none;"} diff --git a/views/prediction.haml b/views/prediction.haml index d22960b..f8610f5 100644 --- a/views/prediction.haml +++ b/views/prediction.haml @@ -25,7 +25,7 @@ #neighbors.table-responsive - %table.tablesorter + %table.tablesorter{:style => "max-width:100%;white-space:nowrap;"} %thead %tr %th @@ -39,58 +39,60 @@ %br Net cell association [mL/ug(Mg)] - @input.each do |key| + - feature = OpenTox::Feature.find_by(:id=>key[0]) + - name = feature.name + - if !feature[:conditions]["MEDIUM"].blank? + - name = feature.name + " / " + feature[:conditions]["MEDIUM"] + - else + - name = feature.name %th.physchem - = key[0].gsub(/\sMean/, '') + = name %tbody / query and match combined %tr.static / id %td - - if @prediction[:match] - %a{:href=> $ambit_search+@prediction[:match].keys[0], :rel=>"external"} - %h5= @prediction[:match].keys[0] + - if @match + %a{:href=> $ambit_search+@name, :rel=>"external"} + %h5= @name - else %h5 Query / similarity %td - - if @prediction[:match] + - if @match %h5 1 - else %h5 x / composition %td - - if @prediction[:match] - - surfaceModifier = {} - - surfaceModifier["Surface modifier"] = [@prediction[:match].values[0]["composition"]["Surface modifier1"], @prediction[:match].values[0]["composition"]["Surface modifier2"]] - - @prediction[:match].values[0]["composition"].delete("Surface modifier1") - - @prediction[:match].values[0]["composition"].delete("Surface modifier2") - - @prediction[:match].values[0]["composition"].merge!(surfaceModifier) - - @prediction[:match].values[0]["composition"].each do |k,v| - %h5= k - - if v.class == Array - - v.compact.each do |value| - %p= value - - else - %p= v + - if @match + %h5 Core + = "["+@nanoparticle[:core]["name"]+"]" + %h5 Coating + = @nanoparticle[:coating][0]["name"] - else %h5 x / tox %td.tox - - if @prediction[:prediction] - - @prediction[:prediction].each do |k,v| - %h5 Prediction - -#%p= k.split.drop(1).join(" ")[1..-2] - - if v == nil - %p not available - - else - %h5= v.round(5) - - if @prediction[:match] - - @prediction[:match].values[0]["tox"].each do |k,v| - %hr - %h5 Measurement - -#%p= k.split.drop(1).join(" ")[1..-2] - %p= v.round(3) - - if !@prediction[:prediction] && !@prediction[:match] + - if @prediction[:value] + %h5 Prediction: + = @prediction[:value].round(3) + - if @prediction[:rmse] + %h5 Rmse: + = @prediction[:rmse].round(3) + - if @prediction[:r_squared] + %h5 R_squared: + = @prediction[:r_squared].round(3) + - if @prediction[:prediction_interval] + %h5 95% Prediction interval: + - interval = @prediction[:prediction_interval].nil? ? " - - " : @prediction[:prediction_interval].collect{|i| i.round(2)} + = "#{interval[0]} - #{interval[1]}" + - if @prediction[:measurements] + %hr + %h5 Measurement + - @prediction[:measurements].each do |m| + %p= m + - if !@prediction[:value] && !@prediction[:measurements] %h5 not available / physchem - if @prediction[:match] @@ -99,55 +101,42 @@ - sorted.each do |k,v| %td.physchem %div{:style=>"display:inline-block;padding-right:20px;"} - /= k.gsub(/\sMean/, '') - %p= v.round(3) + %p= v[0].round(3) - else - @input.each do |v| %td.physchem %div{:style=>"display:inline-block;padding-right:20px;"} - //= v[0].gsub(/\sMean/, '') - if v[1].nil? %p x - else - %p= v[1].round(3) + %p= v[1][0].round(3) / neighbors - if @prediction[:neighbors] - @prediction[:neighbors].each_with_index do |neighbor,idx| + - nano = OpenTox::Nanoparticle.find(neighbor["_id"]) + - pc_descriptors = nano.physchem_descriptors.delete_if{|k,v| feature = OpenTox::Feature.find_by(:id => k); feature.category != "P-CHEM"} %tr / ID %td - %a{:href=> $ambit_search+neighbor["id"], :rel=>"external"} - %h5= neighbor["id"] + %a{:href=> $ambit_search+nano.name, :rel=>"external"} + %h5= nano.name / Similarity %td %h5= neighbor["similarity"].round(3) / Composition %td - - surfaceModifier = {} - - surfaceModifier["Surface modifier"] = [neighbor["composition"]["Surface modifier1"], neighbor["composition"]["Surface modifier2"]] - - neighbor["composition"].delete("Surface modifier1") - - neighbor["composition"].delete("Surface modifier2") - - neighbor["composition"].merge!(surfaceModifier) - - neighbor["composition"].each do |k,v| - %h5= k - - if v.class == Array - - v.compact.each do |value| - %p= value - - else - %p= v + %h5 Core + = "["+nano[:core]["name"]+"]" + %h5 Coating + = nano[:coating][0]["name"] / Tox %td.tox - - neighbor["tox"].each do |k,v| - %h5 Measurement - -#%p= k.split.drop(1).join(" ")[1..-2] - %p= v.round(3) + %h5 Measurement + %p= neighbor["measurements"][0] / Physchem - - sorted = {} - - @input.each{|i| sorted[i[0]]=neighbor["physchem"][i[0]]} - - sorted.each do |k,v| + - @input.each do |k,v| %td.physchem %div %div{:style=>"display:inline-block;padding-right:20px;"} - /= k.gsub(/\sMean/, '') - %p= v.round(3) + %p= v[0].round(3) unless v.nil? -- cgit v1.2.3