summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgebele <gebele@in-silico.ch>2013-09-25 00:12:04 +0200
committergebele <gebele@in-silico.ch>2013-09-25 00:12:04 +0200
commit13ffab048630cc30a4af9e9113c1843ae5af0a09 (patch)
tree7f8ad39ed45eac0c3cb11ece7928d3769c875d92
parent42a6facfda144d0ed70063fd5b3887697578faa3 (diff)
several major changes in code, several minor changes in style; prepared for OT meeting
-rw-r--r--application.rb146
-rw-r--r--prediction_models.csv0
-rw-r--r--public/images/OpenToxEuro2013.pngbin12922 -> 0 bytes
-rw-r--r--public/images/OpenToxEuro2013_small.pngbin0 -> 9022 bytes
-rw-r--r--public/images/favicon.icobin0 -> 1150 bytes
-rw-r--r--public/stylesheets/screen.css2
-rw-r--r--public/stylesheets/screen.sass113
-rw-r--r--unicorn.rb2
-rw-r--r--views/details.haml21
-rw-r--r--views/layout.haml4
-rw-r--r--views/neighbors.haml178
-rw-r--r--views/predict.haml78
-rw-r--r--views/prediction.haml129
-rw-r--r--views/significant_fragments.haml63
14 files changed, 552 insertions, 184 deletions
diff --git a/application.rb b/application.rb
index 925c208..5cd5093 100644
--- a/application.rb
+++ b/application.rb
@@ -8,10 +8,11 @@ require_relative 'helper.rb'
require File.join(ENV["HOME"],".opentox","config","lazar-gui.rb") # until added to ot-tools
helpers do
- # fetch models from uri-list
+ # get prediction models from text file, ignore validation models
+ # model uris must be manually added
@@models = []
- uris = `curl -Lk -X GET -H accept:text/uri-list #{$model[:uri]} `.chomp.split("\n")
- uris.each{|u| m = OpenTox::Model::Lazar.find u; @@models << m}
+ CSV.foreach("./prediction_models.csv"){|uri| m = OpenTox::Model::Lazar.find uri[0]; @@models << m}
+ #$logger.debug "model uris from csv file:\t#{@@models}\n"
end
get '/?' do
@@ -27,36 +28,126 @@ get '/jme_help/?' do
File.read(File.join('views','jme_help.html'))
end
-# best way to get individual compound uri for details
+# get individual compound details
get '/prediction/:neighbor/details/?' do
- @compound_uri = OpenTox::Compound.new params[:neighbor]
- @smiles = @compound_uri.smiles
+ @compound = OpenTox::Compound.new params[:neighbor]
+ @smiles = @compound.smiles
+
task = OpenTox::Task.run("look for names.") do
- names = @compound_uri.names
+ names = @compound.names
end
task.wait
+
case task[RDF::OT.hasStatus]
when "Error"
@names = "No names for this compound available."
when "Completed"
- @names = @compound_uri.names.join(",")
+ @names = @compound.names
end
- @inchi = @compound_uri.inchi.gsub("InChI=", "")
+ @inchi = @compound.inchi.gsub("InChI=", "")
+
haml :details, :layout => false
end
+# fingerprints for compound in predictions
+get '/prediction/:model_uri/:type/:compound_uri/fingerprints/?' do
+ @type = params[:type]
+ model = OpenTox::Model::Lazar.find params[:model_uri]
+ feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
+ @compound = OpenTox::Compound.new params[:compound_uri]
+
+ if @type =~ /classification/i
+ # collect all feature values with fingerprint
+ fingerprints = OpenTox::Algorithm::Descriptor.send("smarts_match", [@compound], feature_dataset.features.collect{ |f| f[RDF::DC.title]})[@compound.uri]
+ #$logger.debug "fingerprints:\t#{fingerprints}\n"
+
+ # collect fingerprints with value 1
+ @fingerprint_values = []
+ fingerprints.each{|smarts, value| @fingerprint_values << [smarts, value] if value > 0}
+
+ # collect all features from feature_dataset
+ @features = feature_dataset.features.collect{|f| f }
+
+ # search for each fingerprint in all features and collect feature values(smarts, pValue, effect)
+ @significant_fragments = []
+ @fingerprint_values.each{ |fi, v| @features.each{ |f| @significant_fragments << [f[RDF::OT.effect].to_i, f[RDF::OT.smarts], f[RDF::OT.pValue]] if fi == f[RDF::OT.smarts] } }
+ else #regression
+ @significant_fragments = []
+ end
+
+ haml :significant_fragments, :layout => false
+end
+
+get '/prediction/:model_uri/:type/:neighbor/significant_fragments/?' do
+ @type = params[:type]
+ #$logger.debug "sf type:\t#{@type}"
+ @compound = OpenTox::Compound.new params[:neighbor]
+ #$logger.debug "neighbor compound uri:\t#{@compound.uri}\n"
+
+ model = OpenTox::Model::Lazar.find params[:model_uri]
+ #$logger.debug "model for significant fragments:\t#{model.uri}"
+
+ feature_dataset = OpenTox::Dataset.find model[RDF::OT.featureDataset]
+ $logger.debug "fd :\t#{feature_dataset.uri}"
+
+ # load all compounds
+ feature_dataset.compounds
+
+ # load all features
+ @features = []
+ feature_dataset.features.each{|f| @features << f}
+ #$logger.debug "all features in fd:\t#{@features}\n"
+
+ # find all features and values for a neighbor compound
+ @significant_fragments = []
+ # check type first
+ if @type =~ /classification/i
+ @feat = []
+ # get compound index in feature dataset
+ c_idx = feature_dataset.compound_indices @compound.uri
+ #$logger.debug "compound idx:\t#{c_idx}\n"
+
+ # collect feature uris with value
+ @features.each{|f| @feat << [feature_dataset.data_entry_value(c_idx[0], f.uri), f.uri]}
+ #$logger.debug "collected features:\t#{@feat}\n"
+
+ # pass feature uris if value > 0
+ @feat.each do |f|
+ if f[0] > 0
+ f = OpenTox::Feature.find f[1]
+ @significant_fragments << [f[RDF::OT.effect].to_i, f[RDF::OT.smarts], f[RDF::OT.pValue].to_f.round(3)]
+ end
+ end
+ else # regression
+ # find a value in feature dataset by compound and feature
+ @values = []
+ @features.each{|f| @values << feature_dataset.values(@compound, f)}
+ #$logger.debug "values in fd:\t#{@values}"
+
+ count = 0
+ @features.each{|f| @significant_fragments << [f.description, @values[count]]; count +=1}
+ end
+ #$logger.debug "significant fragments:\t#{@significant_fragments}\n"
+
+ haml :significant_fragments, :layout => false
+end
+
post '/predict/?' do
# validate identifier input
task = OpenTox::Task.run("Validate SMILES string.") do
# transfered input
@identifier = params[:identifier]
+
# get compound from SMILES
@compound = OpenTox::Compound.from_smiles @identifier.to_s
+
# validate SMILES by converting to INCHI
inchi = @compound.inchi
end
+
# necessary to wait for task
task.wait
+
# case task fails return message smiles invalid
# case task completed go ahead
case task[RDF::OT.hasStatus]
@@ -66,30 +157,41 @@ post '/predict/?' do
when "Completed"
@identifier = params[:identifier]
@compound = OpenTox::Compound.from_smiles @identifier.to_s
- # init
- @@prediction_models = []
- @@predictions = []
+ # init arrays
+ @prediction_models = []
+ @predictions = []
# init lazar algorithm
lazar = OpenTox::Algorithm::Fminer.new File.join($algorithm[:uri],"lazar")
- # gather models from service and compare if selected
- #TODO compare selected by uri
+
+ # get selected models
+ #TODO compare if model is selected by uri not title
params[:selection].each do |model|
- @mselected = model[0]
- @mall = @@models
- @mall.each do |m|
- @@prediction_models << m if m.title =~ /#{@mselected}/
+ # selected model = model[0]
+ # compare selected with all models
+ @@models.each do |m|
+ @prediction_models << m if m.title =~ /#{model[0]}/
end
end
# predict with selected models
- # results in prediction variable
- # store prediction in array for better handling
- @@prediction_models.each do |m|
+ # one prediction in 'pa' array = OpenTox::Dataset
+ # all collected predictions in '@predictions' array
+ # init model_type array
+ @model_type = []
+ @prediction_models.each do |m|
+ # define type (classification|regression)
+ m.type.join =~ /classification/i ? (@model_type << "classification") : (@model_type << "regression")
+
+ #TODO each prediction get a task; load predictions page if first task finished and load results individually
+
+ # predict against compound
@prediction_uri = m.run :compound_uri => "#{@compound.uri}"
+ $logger.debug "prediction dataset:\t#{@prediction_uri}\n"
+
prediction = OpenTox::Dataset.new @prediction_uri
pa = []
pa << prediction
- @@predictions << pa
+ @predictions << pa
end
haml :prediction
diff --git a/prediction_models.csv b/prediction_models.csv
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/prediction_models.csv
diff --git a/public/images/OpenToxEuro2013.png b/public/images/OpenToxEuro2013.png
deleted file mode 100644
index 4fe1005..0000000
--- a/public/images/OpenToxEuro2013.png
+++ /dev/null
Binary files differ
diff --git a/public/images/OpenToxEuro2013_small.png b/public/images/OpenToxEuro2013_small.png
new file mode 100644
index 0000000..9613452
--- /dev/null
+++ b/public/images/OpenToxEuro2013_small.png
Binary files differ
diff --git a/public/images/favicon.ico b/public/images/favicon.ico
new file mode 100644
index 0000000..be19592
--- /dev/null
+++ b/public/images/favicon.ico
Binary files differ
diff --git a/public/stylesheets/screen.css b/public/stylesheets/screen.css
index c7cd00f..a81705c 100644
--- a/public/stylesheets/screen.css
+++ b/public/stylesheets/screen.css
@@ -1 +1 @@
-body{background-image:url("/images/gray_jean.png");background-color:#ccf;overflow:scroll;font-family:sans-serif}body a{text-decoration:none;font-weight:bold;color:#000}body img{border:0}.logo img{float:left;display:inline;margin-right:1em}.logo h1{display:inline;width:80%}.logo img.ote{width:100px;height:50px;display:inline;float:right}.logo hr{margin:0.5em}.content{background-image:url("/images/gray_jean.png")}.content h1{margin:0.3em;text-shadow:#fff 1px 1px 0;font-size:x-large;font-family:Verdana;display:inline}.content h2{text-shadow:#fff 1px 1px 0;font-size:x-large;color:#f55}.content .arrow{margin:5px 0px 5px 20px}.content .back{display:inline}.content #back-top{z-index:100;position:fixed;bottom:3%;margin-left:91%}.content #back-top a:hover{color:#bbb}.content fieldset#top{border:0;padding:10px;background-color:#c5c1e4;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset}.content fieldset#top a#linkInsert{display:block;width:100%;height:2em}.content fieldset#top #appletContainer{padding:10px}.content fieldset#middle{border:0;padding:10px;background-color:#c5c1e4;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset}.content fieldset#middle a#linkModels{display:block;width:100%;height:2em}.content fieldset#middle #endpoint{padding-top:2em}.content fieldset#middle #model a{display:inline;font-weight:normal}.content fieldset#bottom{border:0;background-color:#c5c1e4;padding:10px;margin-bottom:5em;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content fieldset#bottom input#predict{margin-left:1em}.content .predictions{background-color:#c5c1e4;padding:10px;text-align:justify;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .overview{background-image:url("/images/gray_jean.png");padding:12px;margin-top:1em;margin-bottom:1em;text-align:left;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .overview caption{text-align:left}.content .overview #overview tr td{background-color:#fff;border:1px solid #dad9c7;padding-left:1em;padding-top:0.5em}.content .overview #overview tr td #compound{width:200px}.content .overview #overview tr td b.c{color:#d42200}.content .overview #overview tr td b.n{color:#5c8533}.content .overview #overview tr td .confidence{display:inline}.content .error{background-color:#c5c1e4;padding:15px;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .error .message{margin-top:1em;padding:0.2em;border:2px solid #f55;background-color:#fff;color:#f55}.content #closebutton{margin-left:95%;padding:0;background-color:#c5c1e4;-moz-border-radius-bottomleft:5px;-webkit-border-bottom-left-radius:5px;border-bottom-left-radius:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-right-radius:5px;border-bottom-right-radius:5px}.details{margin-bottom:2em;background-image:url("/images/gray_jean.png");-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.results{background-image:url("/images/gray_jean.png");overflow-x:auto;overflow-y:hidden;margin-top:2em;margin-bottom:2em;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.results .tablesorter{width:100%}.results .tablesorter thead{background-color:#e6e5f3}.results .tablesorter thead tr th.header{background-image:url("/images/bg.gif");background-repeat:no-repeat;background-position:center left;cursor:pointer;padding-left:20px;border:1px solid #dad9c7;margin-left:-1px}.results .tablesorter thead tr th.headerSortDown{background-image:url("/images/desc.gif");background-color:#c5c1e4}.results .tablesorter thead tr th.headerSortUp{background-image:url("/images/asc.gif");background-color:#c5c1e4}.results .tablesorter tbody tr td{padding-left:1em;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.results .tablesorter tbody .compound{width:200px}.results .tablesorter tbody .n{color:#5c8533}.results .tablesorter tbody .c{color:#d42200}input#predict{border:0px;background-color:#c5c1e4;margin:0;padding:0}.tooltip{background-color:#fff;border:2px solid #ccc;font-size:0.5em;padding:1em;display:none;z-index:50}.footer{margin:20px 0 20px 0}
+body{background-image:url("/images/gray_jean.png");overflow:scroll;font-family:sans-serif}body a{text-decoration:none;font-weight:bold;color:#000}body img{border:0}body h2{padding-top:12px;text-shadow:#fff 1px 1px 0;font-size:x-large;color:#f55}.logo img{float:left;display:inline;margin-right:1em}.logo h1{display:inline;width:80%}.logo img.ote{width:100px;height:50px;display:inline;float:right}.logo hr{margin:0.5em}.content{background-image:url("/images/gray_jean.png")}.content h1{margin:0.3em;text-shadow:#fff 1px 1px 0;font-size:x-large;font-family:Verdana;display:inline}.content .arrow{margin:8px 0px 5px 20px}.content .back{display:inline}.content #back-top{z-index:100;position:fixed;bottom:3%;margin-left:91%}.content #back-top a:hover{color:#bbb}.content fieldset#top{border:0;padding:10px;background-color:#c5c1e4;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset}.content fieldset#top a#linkInsert{display:block;width:100%;height:2em}.content fieldset#top #appletContainer{padding:10px}.content fieldset#middle{border:0;padding:10px;background-color:#c5c1e4;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset}.content fieldset#middle a#linkModels{display:block;width:100%;height:2em}.content fieldset#middle #endpoint{padding-top:2em}.content fieldset#middle #model a{display:inline;font-weight:normal}.content fieldset#middle a#linkDetailsLC50_mmol{font-size:small}.content fieldset#middle a#linkDetailsHamster{font-size:small}.content fieldset#middle a#linkDetailsRodent{font-size:small}.content fieldset#middle #details_LC50_mmol{background-color:#e6e5f3;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;padding:1em}.content fieldset#middle #details_Hamster{background-color:#e6e5f3;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;padding:1em}.content fieldset#middle #details_Rodent{background-color:#e6e5f3;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;padding:1em}.content fieldset#bottom{border:0;background-color:#c5c1e4;padding:10px;margin-bottom:5em;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content fieldset#bottom input#predict{margin-left:1em}.content .predictions{background-color:#c5c1e4;padding:10px;text-align:justify;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .overview{background-image:url("/images/gray_jean.png");padding:12px;margin-top:1em;margin-bottom:1em;text-align:left;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .overview a:hover{color:#f55}.content .overview caption{text-align:left}.content .overview #overview tr td{background-color:#fff;border:1px solid #dad9c7;padding-left:1em;padding-top:0.5em}.content .overview #overview tr td #compound{width:200px}.content .overview #overview tr td b.c{color:#d42200}.content .overview #overview tr td b.n{color:#5c8533}.content .overview #overview tr td .confidence{display:inline}.content .error{background-color:#c5c1e4;padding:15px;-webkit-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,-1px -1px 5px rgba(0,0,0,0.3) inset;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content .error .message{margin-top:1em;padding:1em;border:2px solid #f55;background-color:#fff;color:#f55;-moz-border-radius-topleft:25px;-webkit-border-top-left-radius:25px;border-top-left-radius:25px;-moz-border-radius-bottomleft:25px;-webkit-border-bottom-left-radius:25px;border-bottom-left-radius:25px;-moz-border-radius-topright:25px;-webkit-border-top-right-radius:25px;border-top-right-radius:25px;-moz-border-radius-bottomright:25px;-webkit-border-bottom-right-radius:25px;border-bottom-right-radius:25px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box}.content #closebutton{color:#f55;margin-left:98%;padding:0}.details{width:98%;background-color:#c5c1e4;-moz-border-radius-bottomleft:5px;-webkit-border-bottom-left-radius:5px;border-bottom-left-radius:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-right-radius:5px;border-bottom-right-radius:5px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.details a:hover{color:#f55}.details img{display:inline;float:left;margin:0.5em}.significant_fragments{width:98%;margin-bottom:2em;background-color:#c5c1e4;-moz-border-radius-bottomleft:5px;-webkit-border-bottom-left-radius:5px;border-bottom-left-radius:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-right-radius:5px;border-bottom-right-radius:5px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.significant_fragments img{display:inline;float:left;margin:0.5em}.significant_fragments table#sf1{text-align:left}.significant_fragments table#sf1 td{padding:0.2em}.descriptors{width:98%;margin-bottom:2em;background-color:#c5c1e4;-moz-border-radius-bottomleft:5px;-webkit-border-bottom-left-radius:5px;border-bottom-left-radius:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-right-radius:5px;border-bottom-right-radius:5px;-webkit-background-clip:border;-moz-background-clip:border;background-clip:border-box;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.descriptors img{display:inline;float:left;margin:0.5em}.descriptors table#sf2{text-align:left}.descriptors table#sf2 td{padding:0.2em}.results{background-image:url("/images/gray_jean.png");overflow-x:auto;overflow-y:hidden;margin-top:2em;margin-bottom:2em;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.results a:hover{color:#f55}.results .tablesorter{width:100%;text-align:left}.results .tablesorter thead{background-color:#e6e5f3}.results .tablesorter thead tr th.header{background-image:url("/images/bg.gif");background-repeat:no-repeat;background-position:center left;cursor:pointer;padding-left:20px;border:1px solid #dad9c7;margin-left:-1px}.results .tablesorter thead tr th.headerSortDown{background-image:url("/images/desc.gif");background-color:#c5c1e4}.results .tablesorter thead tr th.headerSortUp{background-image:url("/images/asc.gif");background-color:#c5c1e4}.results .tablesorter tbody tr td{padding-left:1em;-webkit-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;-moz-box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset;box-shadow:1px 1px 1px #fff inset,0px -1px 2px rgba(0,0,0,0.3) inset}.results .tablesorter tbody .compound{width:200px;padding:0.2em}.results .tablesorter tbody .n{color:#5c8533}.results .tablesorter tbody .c{color:#d42200}input#predict{border:0px;background-color:#c5c1e4;margin:0;padding:0}.tooltip{background-color:#fff;border:2px solid #ccc;font-size:0.5em;padding:1em;display:none;z-index:50}.footer{margin:20px 0 20px 0}
diff --git a/public/stylesheets/screen.sass b/public/stylesheets/screen.sass
index cb6dcdf..bfbedc6 100644
--- a/public/stylesheets/screen.sass
+++ b/public/stylesheets/screen.sass
@@ -1,16 +1,14 @@
//@import compass/reset, compass/css3, compass/utilities, compass/layout
@import compass/css3
-$bg-color: #CCCCFF
+//$bg-color: #CCCCFF
$ist-color: #C5C1E4
body
background-image: url("/images/gray_jean.png")
- background-color: $bg-color
+ //background-color: $bg-color
overflow: scroll
font-family: sans-serif
- //min-width: 800px
- //min-heigth: 600px
a
text-decoration: none
font-weight: bold
@@ -18,6 +16,11 @@ body
//for IE
img
border: 0
+ h2
+ padding-top: 12px
+ text-shadow: #FFF 1px 1px 0
+ font-size: x-large
+ color: #FF5555
.logo
img
@@ -43,12 +46,8 @@ body
font-size: x-large
font-family: Verdana
display: inline
- h2
- text-shadow: #FFF 1px 1px 0
- font-size: x-large
- color: #FF5555
.arrow
- margin: 5px 0px 5px 20px
+ margin: 8px 0px 5px 20px
.back
display: inline
//.close
@@ -88,6 +87,28 @@ body
#model a
display: inline
font-weight: normal
+ a#linkDetailsLC50_mmol
+ font-size: small
+ a#linkDetailsHamster
+ font-size: small
+ a#linkDetailsRodent
+ font-size: small
+ #details_LC50_mmol
+ background-color: adjust-lightness($ist-color, 10%)
+ //background-image: url("/images/gray_jean.png")
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, -1px -1px 5px rgba(black, 0.3) inset)
+ padding: 1em
+ #details_Hamster
+ background-color: adjust-lightness($ist-color, 10%)
+ //background-image: url("/images/gray_jean.png")
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, -1px -1px 5px rgba(black, 0.3) inset)
+ padding: 1em
+ #details_Rodent
+ background-color: adjust-lightness($ist-color, 10%)
+ //background-image: url("/images/gray_jean.png")
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, -1px -1px 5px rgba(black, 0.3) inset)
+ padding: 1em
+
fieldset#bottom
border: 0
background-color: $ist-color
@@ -108,6 +129,8 @@ body
+border-right-radius(25px)
+background-clip(border-box)
.overview
+ a:hover
+ color: #FF5555
background-image: url("/images/gray_jean.png")
padding: 12px
margin-top: 1em
@@ -141,24 +164,74 @@ body
+background-clip(border-box)
.message
margin-top: 1em
- padding: 0.2em
+ padding: 1em
border: 2px solid #FF5555
background-color: #FFFFFF
color: #FF5555
+ +border-left-radius(25px)
+ +border-right-radius(25px)
+ +background-clip(border-box)
// close button for iframe also in content class
#closebutton
- margin-left: 95%
+ color: #FF5555
+ margin-left: 98%
padding: 0
- background-color: $ist-color
- +border-bottom-left-radius(5px)
- +border-bottom-right-radius(5px)
+ //background-color: $ist-color
+ //+border-bottom-left-radius(5px)
+ //+border-bottom-right-radius(5px)
.details
+ //height: 100%
+ width: 98%
+ background-color: $ist-color
+ +border-bottom-left-radius(5px)
+ +border-bottom-right-radius(5px)
+ +background-clip(border-box)
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, 0px -1px 2px rgba(black, 0.3) inset)
+ a:hover
+ color: #FF5555
+ img
+ display: inline
+ float: left
+ margin: 0.5em
+
+.significant_fragments
+ //height: 100%
+ width: 98%
margin-bottom: 2em
- background-image: url("/images/gray_jean.png")
- +border-bottom-left-radius(25px)
- +border-bottom-right-radius(25px)
+ background-color: $ist-color
+ //background-image: url("/images/gray_jean.png")
+ +border-bottom-left-radius(5px)
+ +border-bottom-right-radius(5px)
+ +background-clip(border-box)
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, 0px -1px 2px rgba(black, 0.3) inset)
+ img
+ display: inline
+ float: left
+ margin: 0.5em
+ table#sf1
+ text-align: left
+ td
+ padding: 0.2em
+
+.descriptors
+ //height: 100%
+ width: 98%
+ margin-bottom: 2em
+ background-color: $ist-color
+ //background-image: url("/images/gray_jean.png")
+ +border-bottom-left-radius(5px)
+ +border-bottom-right-radius(5px)
+background-clip(border-box)
+ +box-shadow(1px 1px 1px rgba(white, 1) inset, 0px -1px 2px rgba(black, 0.3) inset)
+ img
+ display: inline
+ float: left
+ margin: 0.5em
+ table#sf2
+ text-align: left
+ td
+ padding: 0.2em
.results
background-image: url("/images/gray_jean.png")
@@ -166,9 +239,12 @@ body
overflow-y: hidden
margin-top: 2em
margin-bottom: 2em
+ a:hover
+ color: #FF5555
+box-shadow(1px 1px 1px rgba(white, 1) inset, 0px -1px 2px rgba(black, 0.3) inset)
.tablesorter
width: 100%
+ text-align: left
thead
background-color: adjust-lightness($ist-color, 10%)
tr
@@ -191,7 +267,8 @@ body
padding-left: 1em
+box-shadow(1px 1px 1px rgba(white, 1) inset, 0px -1px 2px rgba(black, 0.3) inset)
.compound
- width: 200px
+ width: 200px
+ padding: 0.2em
.n
color: #5C8533
.c
diff --git a/unicorn.rb b/unicorn.rb
new file mode 100644
index 0000000..c0441ab
--- /dev/null
+++ b/unicorn.rb
@@ -0,0 +1,2 @@
+worker_processes 6
+timeout 6000
diff --git a/views/details.haml b/views/details.haml
index 931b0b2..5663c1f 100644
--- a/views/details.haml
+++ b/views/details.haml
@@ -1,15 +1,14 @@
%link{ :href=>"/stylesheets/screen.css", :media=>"screen, projection", :rel=>"stylesheet", :type=>"text/css"}
.content
- %button{:id=>"closebutton", :onclick=>"parent.$('#iframe').bPopup().close();parent.$('#iframe_overview').bPopup().close();"}
+ %button{:id=>"closebutton", :onclick=>"parent.$('#iframe_details').bPopup().close();parent.$('#iframe_overview').bPopup().close();"}
X
- .details
- %h2{:style=>"margin-top:0px"}
- Details:
- %img{:src=>"#{@compound_uri.uri}/image", :alt=>"Compound image not available", :width=>"300px", :heigth=>"300px"}
- %br
- %br
+ .details{:style=>"padding:0.5em;min-height:400px;"}
+ %h2{:style=>"margin:0px;margin-left:8px;"}
+ Names and synonyms:
+ %img{:src=>"#{@compound.uri}/image", :alt=>"Compound image not available", :width=>"300px", :heigth=>"300px"}
+ %p
%b="SMILES:"
%p= @smiles
%br
@@ -17,4 +16,10 @@
%p= @inchi
%br
%b="Names:"
- %p= @names.gsub(",", ";\t")
+ %p{:style=>"padding-left:0.5em;"}
+ = @names
+ %p{:style=>"padding-left:0.5em;"}
+ / pubchem link
+ %a{:href=>"http://aop.in-silico.ch/", :title=>"link opens in new tab", :alt=>"pubchem link", :target=>"_blank"} PubChem read across
+ %i (experimental)
+
diff --git a/views/layout.haml b/views/layout.haml
index c7f31b6..57c654a 100644
--- a/views/layout.haml
+++ b/views/layout.haml
@@ -3,6 +3,7 @@
%head
%meta{'http-equiv' => 'Content-Type', :content => 'text/html; charset=UTF-8'}
%title Lazar Toxicity Predictions
+ %link{:rel=>'icon', :type=>'image/x-icon', :href=>'/images/favicon.ico'}
%link{ :href=>"/stylesheets/screen.css", :media=>"screen, projection", :rel=>"stylesheet", :type=>"text/css"}
%link{ :href=>"/stylesheets/jquery-ui.css", :rel=>"stylesheet"}
%link{ :href=>"/jsme/jsa.css", :rel=>"stylesheet"}
@@ -23,8 +24,7 @@
%img{:src=>"/images/ist_logo.png", :alt=>"logo"}
%h1 Lazar Toxicity Predictions
- %a{:href=> "http://www.opentox.org/news/opentoxeu2013news1"}
- %img{:src=>"/images/OpenToxEuro2013.png", :alt=>"OpenToxEuro2013", :class => "ote"}
+ %img{:src=>"/images/OpenToxEuro2013_small.png", :alt=>"OpenToxEuro2013", :class => "ote"}
%hr
.content
diff --git a/views/neighbors.haml b/views/neighbors.haml
index 750b615..39f6272 100644
--- a/views/neighbors.haml
+++ b/views/neighbors.haml
@@ -10,7 +10,7 @@
#tabs
%ul
/ each endpoint becomes a tab head ;
- - @@prediction_models.each do |m|
+ - @prediction_models.each do |m|
- count_m += 1
- m_title = m.title.split(" ").first
%li
@@ -18,15 +18,19 @@
= m_title
- count_rs = 0
/ unpack to single arrays
- - @@predictions.each do |pa|
+ - @predictions.each do |pa|
+ / pass model type for significant fragments view
+ - @type = @model_type[count_rs]
- count_rs += 1
#results{:id=>"#{count_rs}"}
- pa.each do |p|
/ prepare dataset for neighbors table ;
- / delete first array which contains input compound prediction ;
- / keep the following arrays they are the neighbor predictions ;
+ / delete first array which contains prediction ;
+ / following arrays are the neighbor predictions ;
+ - @model_uri = p.metadata[RDF::OT.hasSource][0]
- p.data_entries.shift
- p.compounds.shift
+
/ call the tablesorter plugin ;
/ presort by similarity ;
:javascript
@@ -38,81 +42,95 @@
sortList: [[2,1]]
});
});
- / TODO catch table error if tbody is empty
%h2= "Neighbors: "
- %table{:id=>"#{count_rs}", :class=>"tablesorter", :cellspacing=>"1"}
- %thead
- %tr
- %th
- Compound
- %th
- %b Measured Activity
- / title must be empty for tooltip
- %a{:href=>"#", :title=>"", :id=>"measured_activity"}
- %img{:src=>"/images/info_white.png"}
- .tooltip{:style=>"font-weight: normal; font-size: 1em; text-align: left;"}
- %dt
- Measured Activity
- %dd
- Experimental result(s) from the training dataset.
- %th
- %b Similarity
- / title must be empty for tooltip
- %a{:href=>"#", :title=>"", :id=>"similarity"}
- %img{:src=>"/images/info_white.png"}
- .tooltip{:style=>"font-weight: normal; font-size: 1em; text-align: left;"}
- %dt
- Similarity
- %dd
- %code lazar
- calculates
- %em
- activity specific
- similarities based on the presence of statistically significant fragments.
- This procedure will
- %ul
- %li consider only those parts of a chemical structure that are relevant
- for a particular endpoint
- %li ignore inert parts of the structure
- %li lead to different similarities, depending on the toxic endpoint
- Similarities of 1 may be encountered even for structurally dissimilar
- compounds, because inert parts are ignored.
- %th
- Details
- -#%tbody
- - count = 0
- - p.compounds.each do |neighbor_compound|
- / prevent conversion of nil
- - c = p.data_entries[count][2] != nil ? p.data_entries[count][2] : ''
- - $logger.debug "inspect c :#{c}\n"
- - case c
- - when /(0|false)/
- - c = "non-carcinogen"
- - when /(1|true)/
- - c = "carcinogen"
- - else
- - c = Array.new
- - c[0] = p.data_entries[count][2]
- %tr
- %td.compound
- %img{:src=>"#{neighbor_compound.uri}/image", :alt=>"Compound image not available", :width=>"150px"}
- %td{:class => c[0]}
- - if c.class == String
- = c
- - else
- = c[0]
- %td{:class => c[0]}
- = p.data_entries[count][3] != nil ? p.data_entries[count][3].round(3) : "Not enough similar compounds in training dataset."
- %td
- %a{:href => to("/prediction/#{CGI.escape(neighbor_compound.uri)}/details"), :id=>"link#{count_rs}#{count}", :target=>"details"}
- %img{:src=>"/images/arrow_right_float.png", :alt=>">"}
- :javascript
- $(function() {
- $("a#link#{count_rs}#{count}").on('click', function(e) {
- $('#iframe').bPopup();
- });
- });
-
- - count += 1
+ - $logger.debug "neighbors compounds:\t#{p.data_entries[0]}\n"
+ - if p.data_entries[0][2] != nil && p.data_entries[0].size != 3
+ %table{:id=>"#{count_rs}", :class=>"tablesorter", :cellspacing=>"1"}
+ %thead
+ %tr
+ %th
+ Compound
+ %th
+ %b Measured Activity
+ / title must be empty for tooltip
+ %a{:href=>"#", :title=>"", :id=>"measured_activity"}
+ %img{:src=>"/images/info_white.png"}
+ .tooltip{:style=>"font-weight: normal; font-size: 1em; text-align: left;"}
+ %dt
+ Measured Activity
+ %dd
+ Experimental result(s) from the training dataset.
+ %th
+ %b Similarity
+ / title must be empty for tooltip
+ %a{:href=>"#", :title=>"", :id=>"similarity"}
+ %img{:src=>"/images/info_white.png"}
+ .tooltip{:style=>"font-weight: normal; font-size: 1em; text-align: left;"}
+ %dt
+ Similarity
+ %dd
+ %code lazar
+ calculates
+ %em
+ activity specific
+ similarities based on the presence of statistically significant fragments.
+ This procedure will
+ %ul
+ %li consider only those parts of a chemical structure that are relevant
+ for a particular endpoint
+ %li ignore inert parts of the structure
+ %li lead to different similarities, depending on the toxic endpoint
+ Similarities of 1 may be encountered even for structurally dissimilar
+ compounds, because inert parts are ignored.
+ %th
+ Supporting information
+ -#%tbody
+ - count = 0
+ - p.compounds.each do |neighbor_compound|
+ / prevent conversion of nil
+ - c = p.data_entries[count][2] != nil ? p.data_entries[count][2] : ''
+ - case c
+ - when /(0|false)/
+ - c = "non-carcinogen"
+ - when /(1|true)/
+ - c = "carcinogen"
+ - else
+ - c = Array.new
+ - c[0] = p.data_entries[count][2]
+ %tr
+ %td.compound
+ %img{:src=>"#{neighbor_compound.uri}/image", :alt=>"Compound image not available", :title=>"#{neighbor_compound.smiles}", :width=>"150px"}
+ %td{:class => c[0]}
+ - if c.class == String
+ = c
+ - else
+ = c[0]
+ %td{:class => c[0]}
+ = p.data_entries[count][3] != nil ? p.data_entries[count][3].round(3) : "Not enough similar compounds in training dataset."
+ %td
+ -#- if p.data_entries[count][3] != nil
+ %a{:href => to("/prediction/#{CGI.escape(neighbor_compound.uri)}/details"), :id=>"link#{count_rs}#{count}", :target=>"details"} Names and synonymes
+ %br
+ - if @type =~ /classification/i
+ - if p.data_entries[count][3] != nil
+ %a{:href => to("/prediction/#{CGI.escape(@model_uri)}/#{@type}/#{CGI.escape(neighbor_compound.uri)}/significant_fragments"), :id=>"link#{count_rs}#{count}sf", :target=>"details"} Significant fragments
+ - if @type =~ /regression/i
+ - if p.data_entries[count][3] != nil
+ %a{:href => to("/prediction/#{CGI.escape(@model_uri)}/#{@type}/#{CGI.escape(neighbor_compound.uri)}/significant_fragments"), :id=>"link#{count_rs}#{count}sf", :target=>"details"} Descriptors
+ :javascript
+ $(function() {
+ $("a#link#{count_rs}#{count}").on('click', function(e) {
+ $('#iframe_details').bPopup();
+ });
+ });
+ $(function() {
+ $("a#link#{count_rs}#{count}sf").on('click', function(e) {
+ $('#iframe_details').bPopup();
+ });
+ });
+ - count += 1
+ - else
+ %h3
+ Not enough similar compounds in training dataset
-%iframe{:id=>"iframe", :name=>"details", :height=>"90%", :width=>"90%", :style=>"display:none;border:0px"}
+%iframe{:id=>"iframe_details", :name=>"details", :height=>"95%", :width=>"95%", :style=>"display:none;border:0px"}
diff --git a/views/predict.haml b/views/predict.haml
index c37c61d..5641f6a 100644
--- a/views/predict.haml
+++ b/views/predict.haml
@@ -59,7 +59,7 @@
%fieldset#middle
%a{:href => "#models", :id => "linkModels"}
- %h1 2. Select one or more toxic endpoints
+ %h1 2. Select one or more endpoints
:javascript
$("a#linkModels").click(function () {
@@ -68,20 +68,74 @@
});
#models
- %i Please observe validation report for model details.
-
- // TODO order models by echa endpoint currently manually added and to find in model.type
+ // TODO order models by echa endpoint
#endpoint
- %b= "Carcinogenicity:"
+ %b Acute toxicity to fish (lethality):
+ - @models.each do |model|
+ - model_title = model.title.split(" ").first
+ - if model_title =~ /LC50/
+ %div{:id => model_title}
+ %input{:type => "checkbox", :name => "selection[#{model_title}]", :id => "selection[#{model_title}]", :value => true, :disabled => false}
+ %label{:for => "selection[#{model_title}]"}
+ = " EPA v4b Fathead Minnow Acute Toxicity "+model_title
+ %a{:href=>"#details", :id => "linkDetails#{model_title}", :title=>"#{model_title} details"}
+ [Details]
+
+ :javascript
+ $("a#linkDetails#{model_title}").click(function () {
+ $("#details_#{model_title}").toggle();
+ //document.location = document.location + "#" + "details";
+ });
+
+ #details{:id => "#{model_title}", :style=> "display:none;"}
+ %h3 Model Details:
+ //%p= "Training Dataset:\t#{model[RDF::OT.trainingDataset]}"
+ %p Algorithm: Lazar
+ %p Type: regression
+ %p Training compounds: integer
+ %p Descriptors: Fminer
+ //%p= "Training Dataset:\t#{model[RDF::OT.trainingDataset]}"
+ //%p= "Feature Dataset:\t#{model[RDF::OT.featureDataset]}"
+ %h3 Validation:
+ %a{:href => "#"}
+ Detailed report link
+ %p Number of predictions: integer
+ %p Correct predictions: %
+ %br
+ %b Carcinogenicity:
- @models.each do |model|
- model_title = model.title.split(" ").first
- %div{:id => model_title}
- %input{:type => "checkbox", :name => "selection[#{model_title}]", :id => "selection[#{model_title}]", :value => true, :disabled => false}
- %label{:for => "selection[#{model_title}]"}
- = "DSSTox Carcinogenic Potency DBS "+model_title
- %a{:href=>"#", :title=>"#{model_title} validation"}
- %i ( Validation report )
- %br
+ - if model_title =~ /hamster|rodent/i
+ %div{:id => model_title}
+ %input{:type => "checkbox", :name => "selection[#{model_title}]", :id => "selection[#{model_title}]", :value => true, :disabled => false}
+ %label{:for => "selection[#{model_title}]"}
+ = " DSSTox Carcinogenic Potency DBS "+model_title
+ %a{:href=>"#details", :id => "linkDetails#{model_title}", :title=>"#{model_title} details"}
+ [Details]
+
+ :javascript
+ $("a#linkDetails#{model_title}").click(function () {
+ $("#details_#{model_title}").toggle();
+ //document.location = document.location + "#" + "details";
+ });
+
+ #details{:id=>"#{model_title}", :style=> "display:none;"}
+ %h3 Model Details:
+ //%p= "Training Dataset:\t#{model[RDF::OT.trainingDataset]}"
+ %p Algorithm: Lazar
+ %p Type: classification
+ %p Training compounds: integer
+ %p Descriptors: Fminer
+ //%p= "Training Dataset:\t#{model[RDF::OT.trainingDataset]}"
+ //%p= "Feature Dataset:\t#{model[RDF::OT.featureDataset]}"
+ %h3 Validation:
+ %a{:href => "#"}
+ Detailed report link
+ %p Number of predictions: integer
+ %p Correct predictions: %
+ %br
+
+ %br
.arrow
%img{:src=>"/images/arrow_down_float.png", :alt=>"v", :class=> "arrow"}
diff --git a/views/prediction.haml b/views/prediction.haml
index f902504..4002cbd 100644
--- a/views/prediction.haml
+++ b/views/prediction.haml
@@ -4,7 +4,7 @@
%img{:src=>"/images/arrow_left_float.png", :alt=>"<"}
%a{:href => to('/predict')} New Prediction
- / displays all prediction results
+ / displays all prediction result in first table
.overview
%table{:width=>"100%", :cellspacing=>"1", :id=>"overview"}
%thead
@@ -17,9 +17,9 @@
%td{:id=>"compound"}
%a{:href => to("/prediction/#{CGI.escape(@compound.uri)}/details"), :id=>"linkCompound", :target=>"details_overview"}
%img{:src=>"#{@compound.uri}/image", :alt=>"Compound image not available", :width=>"150", :height=>"150"}
- %br
- %br
- %img{:src=>"/images/arrow_up_float.png", :alt=>"^"}
+ %p
+ %a{:href => to("/prediction/#{CGI.escape(@compound.uri)}/details"), :id=>"linkCompound", :target=>"details_overview"} Names and synonyms
+ %p
:javascript
$(function() {
$("a#linkCompound").on('click', function(e) {
@@ -27,18 +27,18 @@
});
});
- count=0
- / var for rule to load neighbors page.
- - @@neighbors_available = 1
- - @@predictions.each do |pa|
- / prediction of one model
+ - @predictions.each do |pa|
+ / unpack to single array/prediction
+ / if p.data_entries array[0].size == 3 -> database hit
+ / change 'result' if database hit
+ / change 'confidence' if database hit
- pa.each do |p|
- - $logger.debug "inspect p: #{p.inspect}\n"
- - $logger.debug "inspect data_entries: #{p.data_entries}\n"
- / p.data_entries > 1 = neighbors available
- - p.data_entries.length > 1 ? @@neighbors_available = p.data_entries.length : @@neighbors_available
/ prevent conversion of nil
+ /- $logger.debug "data entries in prediction array:\t#{p.data_entries}\n"
+ - database_hit = 0
+ - if p.data_entries[0].size == 3
+ - database_hit = 1
- c = p.data_entries[0][0] != nil ? p.data_entries[0][0] : ''
- - $logger.debug "inspect c: #{c.inspect}\n"
- case c
- when /(0|false)/
- c = "non-carcinogen"
@@ -46,15 +46,17 @@
- c = "carcinogen"
- else
- c = Array.new
- - c[0] = (p.data_entries[0][0].class == Float) ? p.data_entries[0][0].round(3) : (p.data_entries[0][0] != nil ? p.data_entries[0][0] : "no value")
+ - c[0] = (p.data_entries[0][0].class == Float) ? p.data_entries[0][0].round(3) : (p.data_entries[0][0] != nil ? p.data_entries[0][0] : "no prediction")
%td
%b{:class => "title"}
- = @@prediction_models[count].title.split(" ").first
- %br
- %br
- / classification, regression
- %b Type:
- %br
+ = @prediction_models[count].title.split(" ").first
+ - @model_uri = @prediction_models[count].uri
+ %p
+ / model type (classification|regression)
+ %b Type:
+ = @model_type[count]
+ %p
+ - unless database_hit > 0
%b Result:
%b{:class => c[0]}
- if c.class == String
@@ -76,18 +78,18 @@
%li a majority vote (weighted by compound similarity) for
%em classification
(
- %a{:href=>"http://www.in-silico.de/articles/modi020905.pdf"} original publication
+ %a{:href=>"http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract", :target=>"_blank"} original publication
)
%li a local QSAR model based on neighbors for
%em regression
(
- %a{:href=>"http://www.in-silico.de/articles/mh_tf.pdf"} original publication
+ %a{:href=>"http://www.frontiersin.org/Journal/10.3389/fphar.2013.00038/abstract", :target=>"_blank"} original publication
)
Please keep in mind that predictions are based on the measured activities of neighbors.
- %br
+ %p
.confidence
%b Confidence:
- = p.data_entries[0][1] != nil ? p.data_entries[0][1].round(3) : ""
+ = p.data_entries[0][1] != nil ? p.data_entries[0][1].round(3) : "-"
/ title must be empty for tooltip
%a{:href=>"#confidence", :title=>"", :id=>"confidence"}
%img{:src=>"/images/info_white.png"}
@@ -101,20 +103,65 @@
Confidence values may take any value between 0 and 1.
For most models confidence > 0.025 is a sensible (hard) cutoff to distiguish between
reliable and unreliable predictions.
- %br
- %a{:href=> "#tabs", :id=>"link#{count}"}
- %img{:src=>"/images/arrow_down_float.png", :alt=>"v"}
- :javascript
- $("a#link#{count}").click(function () {
- $(".results").show();
- document.getElementById('tabs').focus();
- $("#tabs").tabs({ active: "#{count}" });
- });
- - count+=1
-
- - if @@neighbors_available > 1
- = haml :neighbors, :layout => false
- - else
- %h2
- no neighbors available
-%iframe{:id=>"iframe_overview", :name=>"details_overview", :height=>"90%", :width=>"90%", :style=>"display:none;border:0px"}
+ %p
+ /TODO add tooltip for significant ftagments and descriptors
+ - if @model_type[count] =~ /classification/i
+ / Significant fragments:
+ %a{:href => to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[count]}/#{CGI.escape(@compound.uri)}/fingerprints"), :id=>"linkPredictionSf", :target=>"details_overview"}Significant fragments
+ :javascript
+ $(function() {
+ $("a#linkPredictionSf").on('click', function(e) {
+ $('#iframe_overview').bPopup();
+ });
+ });
+ - if @model_type[count] =~ /regression/i
+ / Descriptors
+ %a{:href => to("/prediction/#{CGI.escape(@model_uri)}/#{@model_type[count]}/#{CGI.escape(@compound.uri)}/fingerprints"), :id=>"linkPredictionSf", :target=>"details_overview"} Descriptors
+ :javascript
+ $(function() {
+ $("a#linkPredictionSf").on('click', function(e) {
+ $('#iframe_overview').bPopup();
+ });
+ });
+ / title must be empty for tooltip
+ -#%a{:href =>"#sfragments", :title=>"", :id=>"sfragments"}
+ %img{:src=>"/images/info_white.png"}
+ -#.tooltip{:style=>"font-weight: normal; font-size: 1em; width: 50%; text-align: left;"}
+ %dt
+ Significant fragments
+ %dd
+ Significant fragments are solely used to determine activity specific similarities of neighbors.
+ %p
+ %b Neighbors:
+ %a{:href=> "#tabs", :id=>"link#{count}"}
+ %img{:src=>"/images/arrow_down_float.png", :alt=>"v"}
+ :javascript
+ $("a#link#{count}").click(function () {
+ $(".results").show();
+ document.getElementById('tabs').focus();
+ $("#tabs").tabs({ active: "#{count}" });
+ });
+ %p
+ - count+=1
+ - else # database hit
+ %b Database hit:
+ %br Compound found in training dataset
+ %p
+ %b Measured activity:
+ = p.data_entries[0][2]
+ %p
+ %b Neighbors:
+ %a{:href=> "#tabs", :id=>"link#{count}"}
+ %img{:src=>"/images/arrow_down_float.png", :alt=>"v"}
+ :javascript
+ $("a#link#{count}").click(function () {
+ $(".results").show();
+ document.getElementById('tabs').focus();
+ $("#tabs").tabs({ active: "#{count}" });
+ });
+
+ - count+=1
+
+ / always show the neighbors table, message is given there
+ = haml :neighbors, :layout => false, :model_type => @model_type
+%iframe{:id=>"iframe_overview", :name=>"details_overview", :height=>"95%", :width=>"95%", :style=>"display:none;border:0px"}
diff --git a/views/significant_fragments.haml b/views/significant_fragments.haml
new file mode 100644
index 0000000..7d342d0
--- /dev/null
+++ b/views/significant_fragments.haml
@@ -0,0 +1,63 @@
+%link{ :href=>"/stylesheets/screen.css", :media=>"screen, projection", :rel=>"stylesheet", :type=>"text/css"}
+/TODO put smiles in div if compound image is not available, prevent overlay to table
+.content
+ %button{:id=>"closebutton", :onclick=>"parent.$('#iframe_details').bPopup().close();parent.$('#iframe_overview').bPopup().close();"}
+ X
+- if @type =~ /classification/i
+ .significant_fragments{:style=>"padding:0.5em;min-height:400px"}
+ %h2{:style=>"margin:0px;margin-left:8px;"}
+ Significant fragments:
+
+ %img{:src=>"#{@compound.uri}/image", :alt=>"#{@compound.smiles}", :title=>"#{@compound.smiles}", :width=>"300px", :heigth=>"300px"}
+ - if !@significant_fragments.empty?
+ %table{:id => "sf1"}
+ %tr
+ %th{:style=>"border:1px solid;"}
+ Predominantly in compounds with activity "non-carcinogen"
+ %th{:style=>"border:1px solid;"}
+ p value
+ - @significant_fragments.each do |fragments|
+ / fragments == [1||2, smarts, pValue]
+ - if fragments[0] == 1
+ %tr
+ %td
+ = fragments[1]
+ %td
+ = fragments[2]
+ %tr
+ %td
+ %br
+ %tr
+ %th{:style=>"border:1px solid;"}
+ Predominantly in compounds with activity "carcinogen"
+ %th{:style=>"border:1px solid;"}
+ p value
+ - @significant_fragments.each do |fragments|
+ / fragments == [1||2, smarts, pValue]
+ - if fragments[0] == 2
+ %tr
+ %td
+ = fragments[1]
+ %td
+ = fragments[2]
+
+- if @type =~ /regression/i
+ .descriptors{:style=>"padding:0.5em;min-height:400px"}
+ %h2{:style=>"margin:0px;margin-left:8px;"}
+ Descriptors:
+
+ %img{:src=>"#{@compound.uri}/image", :alt=>"#{@compound.smiles}", :title=>"#{@compound.smiles}", :width=>"300px", :heigth=>"300px"}
+ - if !@significant_fragments.empty?
+ %table{:id => "sf2"}
+ %tr
+ %th{:style=>"border:1px solid;"}
+ Descriptor
+ %th{:style=>"border:1px solid;"}
+ value
+ - @significant_fragments.each do |fragments|
+ %tr
+ %td
+ = fragments[0]
+ %td
+ = fragments[1][0].round(3)
+