From 13ffab048630cc30a4af9e9113c1843ae5af0a09 Mon Sep 17 00:00:00 2001 From: gebele Date: Wed, 25 Sep 2013 00:12:04 +0200 Subject: several major changes in code, several minor changes in style; prepared for OT meeting --- views/details.haml | 21 +++-- views/layout.haml | 4 +- views/neighbors.haml | 178 +++++++++++++++++++++------------------ views/predict.haml | 78 ++++++++++++++--- views/prediction.haml | 129 +++++++++++++++++++--------- views/significant_fragments.haml | 63 ++++++++++++++ 6 files changed, 330 insertions(+), 143 deletions(-) create mode 100644 views/significant_fragments.haml (limited to 'views') 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) + -- cgit v1.2.3