lazar-gui 1.3.1 → 1.4.0.pre.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/FAQ.md +9 -6
  4. data/Gemfile +2 -2
  5. data/README.md +19 -8
  6. data/VERSION +1 -1
  7. data/api/api.json +1000 -0
  8. data/application.rb +269 -206
  9. data/config.ru +7 -2
  10. data/docker/Dockerfile +73 -0
  11. data/docker/start.sh +12 -0
  12. data/docker/swagger.html +107 -0
  13. data/helper.rb +46 -1
  14. data/lazar-gui.gemspec +6 -6
  15. data/lib/api.rb +29 -0
  16. data/lib/compound.rb +68 -0
  17. data/lib/dataset.rb +33 -0
  18. data/lib/endpoint.rb +23 -0
  19. data/lib/feature.rb +29 -0
  20. data/lib/model.rb +152 -0
  21. data/lib/report.rb +29 -0
  22. data/lib/substance.rb +34 -0
  23. data/lib/swagger.rb +3 -0
  24. data/lib/validation.rb +67 -0
  25. data/public/fonts/FontAwesome.otf +0 -0
  26. data/public/fonts/fontawesome-webfont.eot +0 -0
  27. data/public/fonts/fontawesome-webfont.svg +2671 -0
  28. data/public/fonts/fontawesome-webfont.ttf +0 -0
  29. data/public/fonts/fontawesome-webfont.woff +0 -0
  30. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  31. data/public/images/orn-logo.jpg +0 -0
  32. data/public/javascripts/bootstrap.js +3944 -0
  33. data/public/javascripts/google_analytics_lazar.js +2 -2
  34. data/public/javascripts/jquery.min.js +2 -0
  35. data/public/javascripts/lazar-gui.js +313 -0
  36. data/public/javascripts/pagination.min.js +11 -0
  37. data/public/javascripts/popper.min.js +5 -0
  38. data/public/stylesheets/bootstrap.min.css +7 -0
  39. data/public/stylesheets/bootstrap.min.css.map +1 -0
  40. data/public/stylesheets/font-awesome.min.css +4 -0
  41. data/public/stylesheets/pagination.css +1 -0
  42. data/qmrf_report.rb +64 -14
  43. data/task.rb +68 -0
  44. data/unicorn.rb +0 -1
  45. data/views/batch.haml +48 -107
  46. data/views/details.haml +10 -2
  47. data/views/error.haml +4 -5
  48. data/views/faq.haml +6 -2
  49. data/views/help.haml +68 -0
  50. data/views/info.haml +3 -2
  51. data/views/layout.haml +68 -78
  52. data/views/model_details.haml +179 -144
  53. data/views/neighbors.haml +98 -80
  54. data/views/predict.haml +43 -178
  55. data/views/prediction.haml +109 -102
  56. data/views/style.scss +44 -37
  57. data/views/upload.haml +28 -0
  58. metadata +51 -105
  59. data/public/css/bootstrap-theme.min.css +0 -5
  60. data/public/css/bootstrap.min.css +0 -5
  61. data/public/css/bootstrap.vertical-tabs.min.css +0 -1
  62. data/public/css/images/black-asc.gif +0 -0
  63. data/public/css/images/black-desc.gif +0 -0
  64. data/public/css/images/black-unsorted.gif +0 -0
  65. data/public/css/images/bootstrap-black-unsorted.png +0 -0
  66. data/public/css/images/bootstrap-white-unsorted.png +0 -0
  67. data/public/css/images/dragtable-handle.png +0 -0
  68. data/public/css/images/dragtable-handle.svg +0 -7
  69. data/public/css/images/dropbox-asc-hovered.png +0 -0
  70. data/public/css/images/dropbox-asc.png +0 -0
  71. data/public/css/images/dropbox-desc-hovered.png +0 -0
  72. data/public/css/images/dropbox-desc.png +0 -0
  73. data/public/css/images/first.png +0 -0
  74. data/public/css/images/green-asc.gif +0 -0
  75. data/public/css/images/green-desc.gif +0 -0
  76. data/public/css/images/green-header.gif +0 -0
  77. data/public/css/images/green-unsorted.gif +0 -0
  78. data/public/css/images/ice-asc.gif +0 -0
  79. data/public/css/images/ice-desc.gif +0 -0
  80. data/public/css/images/ice-unsorted.gif +0 -0
  81. data/public/css/images/last.png +0 -0
  82. data/public/css/images/loading.gif +0 -0
  83. data/public/css/images/metro-black-asc.png +0 -0
  84. data/public/css/images/metro-black-desc.png +0 -0
  85. data/public/css/images/metro-loading.gif +0 -0
  86. data/public/css/images/metro-unsorted.png +0 -0
  87. data/public/css/images/metro-white-asc.png +0 -0
  88. data/public/css/images/metro-white-desc.png +0 -0
  89. data/public/css/images/next.png +0 -0
  90. data/public/css/images/prev.png +0 -0
  91. data/public/css/images/white-asc.gif +0 -0
  92. data/public/css/images/white-desc.gif +0 -0
  93. data/public/css/images/white-unsorted.gif +0 -0
  94. data/public/css/jquery-ui.css +0 -1225
  95. data/public/css/jquery-ui.theme.min.css +0 -5
  96. data/public/css/theme.bootstrap.css +0 -158
  97. data/public/css/theme.bootstrap.min.css +0 -1
  98. data/public/css/theme.default.min.css +0 -1
  99. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  100. data/public/fonts/glyphicons-halflings-regular.svg +0 -288
  101. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  102. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  103. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  104. data/public/images/Email.png +0 -0
  105. data/public/images/Facebook.png +0 -0
  106. data/public/images/Google+.png +0 -0
  107. data/public/images/LinkedIn.png +0 -0
  108. data/public/images/OpenToxEuro2013_small.png +0 -0
  109. data/public/images/Twitter.png +0 -0
  110. data/public/images/arrow_down_float.png +0 -0
  111. data/public/images/arrow_left_float.png +0 -0
  112. data/public/images/arrow_right_float.png +0 -0
  113. data/public/images/arrow_up_float.png +0 -0
  114. data/public/images/asc.gif +0 -0
  115. data/public/images/bg.gif +0 -0
  116. data/public/images/desc.gif +0 -0
  117. data/public/images/gray_jean.png +0 -0
  118. data/public/images/info_white.png +0 -0
  119. data/public/javascripts/bootstrap.min.js +0 -7
  120. data/public/javascripts/jquery-1.11.2.min.js +0 -4
  121. data/public/javascripts/jquery-1.8.3.min.js +0 -2
  122. data/public/javascripts/jquery-ui-1.10.3.custom.min.js +0 -6
  123. data/public/javascripts/jquery.bpopup.min.js +0 -7
  124. data/public/javascripts/jquery.tablesorter.min.js +0 -2
  125. data/public/javascripts/jquery.tablesorter.widgets.js +0 -2678
  126. data/public/javascripts/jquery.tools.min.js +0 -5
  127. data/public/rect.png +0 -0
  128. data/test/lazarweb.rb +0 -193
  129. data/test/setup.rb +0 -7
  130. data/views/significant_fragments.haml +0 -66
@@ -1,7 +1,6 @@
1
- %div.panel.panel-default
2
- %div.panel-heading
3
- %b Model:
4
- %div.panel-body
1
+ %div.card.bg-light
2
+ %div.card-body
3
+ %h6.card-title Model:
5
4
  Source:
6
5
  %a{:href=>model.source, :rel=>"external"}
7
6
  = model.source
@@ -10,152 +9,188 @@
10
9
  = "Type:\t"
11
10
  = type
12
11
  %br
13
- - training_dataset = OpenTox::Dataset.find model.model.training_dataset_id
14
12
  = "Training compounds:\t"
15
- = training_dataset.data_entries.size
13
+ = data_entries.count/3
16
14
  %br
17
15
  = "Training dataset:\t"
18
- %a{:href=>"#{to("/predict/dataset/#{training_dataset.name}")}"}
16
+ %a{:href=>"//#{$host_with_port}/predict/dataset/#{training_dataset.name}"}
19
17
  = training_dataset.name
20
18
 
21
- %div.panel.panel-default
22
- %div.panel-heading
23
- %b Algorithms:
24
- %div.panel-body
25
- Similarity:
26
- %a{:href=> "http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["similarity"]["method"].sub("::", "%2F")}", :rel=>"external"}
27
- = model.model.algorithms["similarity"]["method"]
28
- = ", min: #{model.model.algorithms["similarity"]["min"]}"
29
- %br
30
- Prediction:
31
- - if model.model.algorithms["prediction"]["method"] !~ /Caret/
32
- %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
33
- = model.model.algorithms["prediction"]["method"]
19
+ %div.card.bg-light
20
+ %div.card-body
21
+ %h6.card-title Algorithms:
22
+ %p.card-text
23
+ Similarity:
24
+ %a.card-link{:href=> "http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["similarity"]["method"].sub("::", "%2F")}", :rel=>"external"}
25
+ = model.model.algorithms["similarity"]["method"]
26
+ = ", min: #{model.model.algorithms["similarity"]["min"]}"
27
+ %br
28
+ Prediction:
29
+ - if model.model.algorithms["prediction"]["method"] !~ /Caret/
30
+ %a.card-link{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
31
+ = model.model.algorithms["prediction"]["method"]
32
+ - else
33
+ %a.card-link{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox/Algorithm/Caret", :rel=>"external"}
34
+ = model.model.algorithms["prediction"]["method"]
35
+
36
+ %br
37
+ Descriptors:
38
+ = model.model.algorithms["descriptors"]["method"]+","
39
+ = model.model.algorithms["descriptors"]["type"]
40
+
41
+ %div.card.bg-light
42
+ %div.card-body
43
+ - if type == "Classification"
44
+ %h6.card-title #{crossvalidations.size} independent 10-fold crossvalidations:
34
45
  - else
35
- %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox/Algorithm/Caret", :rel=>"external"}
36
- = model.model.algorithms["prediction"]["method"]
46
+ %h6.card-title #{crossvalidations.size} independent 10-fold crossvalidations (-log10 transformed):
47
+ - crossvalidations.each_with_index do |cv,idx|
48
+ %p.card-text
49
+ - if model.classification?
50
+ / accuracy, confusion matrixes
51
+ - accept_values = cv.accept_values
52
+ - av = []
53
+ - if accept_values[1] =~ /^non/
54
+ - av << accept_values[0]
55
+ - av << accept_values[1]
56
+ - else
57
+ - av = accept_values
58
+ - keys = cv.accuracy.collect{|key, value| key}
59
+ - acc = cv.accuracy.collect{|key, value| value.signif(3)}
60
+ - tpr = cv.true_rate.collect{|key, hash| hash[av[0]].signif(3)}
61
+ - fpr = cv.true_rate.collect{|key, hash| hash[av[1]].signif(3)}
62
+ - pp = cv.predictivity.collect{|key, hash| hash[av[0]].signif(3)}
63
+ - np = cv.predictivity.collect{|key, hash| hash[av[1]].signif(3)}
64
+ %table.table.table-bordered.table-responsive.text-center.bg-white
65
+ %tr
66
+ %td.text-center.bg-light
67
+ = "Nr.#{idx+1}"
68
+ %td
69
+ %a{:href=>"https://en.wikipedia.org/wiki/Accuracy_and_precision", :rel=>"external"}
70
+ Accuracy
71
+ %td
72
+ %a{:href=>"https://en.wikipedia.org/wiki/Sensitivity_and_specificity", :rel=>"external"}
73
+ True positive rate (Sensitivity, Recall)
74
+ %td
75
+ %a{:href=>"https://en.wikipedia.org/wiki/Sensitivity_and_specificity", :rel=>"external"}
76
+ True negative rate (Specificity)
77
+ %td
78
+ %a{:href=>"https://en.wikipedia.org/wiki/Positive_and_negative_predictive_values", :rel=>"external"}
79
+ Positive predictive value (Precision)
80
+ %td
81
+ %a{:href=>"https://en.wikipedia.org/wiki/Positive_and_negative_predictive_values", :rel=>"external"}
82
+ Negative predictive value
83
+ - keys.each_with_index do |key,idx|
84
+ %tr
85
+ / keys
86
+ %td.fit.text-right= key.gsub("_", " ")
87
+ / acc,accuray value:
88
+ %td= acc[idx]
89
+ / tpr,true positive rate
90
+ %td= tpr[idx]
91
+ / fpr,false positive rate
92
+ %td= fpr[idx]
93
+ / pp,positive predictions
94
+ %td= pp[idx]
95
+ / np,negative predictions
96
+ %td= np[idx]
97
+ %div.row.justify-content-center
98
+ %h6 Confusion matrix
99
+ %div.row{:id=>"matrix#{model.id}#{idx}"}
100
+ %table.table.table-borderless.table-responsive
101
+ %tr
102
+ %td.fit.text-center all
103
+ %td.fit.text-center confidence high
104
+ %td.fit.text-center confidence low
105
+ %tr.justify-content-around
106
+ / confusion matrix
107
+ - keys.each do |key|
108
+ - matrix = cv.confusion_matrix[key]
109
+ %td
110
+ %table.table-sm.text-center
111
+ %tr
112
+ %td
113
+ %td
114
+ %td{:colspan=>"2"} measured
115
+ %td
116
+ %tr
117
+ %td
118
+ %td
119
+ %td.border.bg-secondary.text-white active
120
+ %td.border.bg-secondary.text-white inactive
121
+ %tr
122
+ %td.align-middle{:rowspan=>"2"} predicted
123
+ %td.border.bg-secondary.text-white active
124
+ %td.border.bg-white
125
+ %b= matrix[0][0]
126
+ %td.border.bg-white
127
+ = matrix[0][1]
128
+ %tr
129
+ //%td
130
+ %td.border.bg-secondary.text-white inactive
131
+ %td.border.bg-white
132
+ = matrix[1][0]
133
+ %td.border.bg-white
134
+ %b= matrix[1][1]
135
+ %div.row.justify-content-center
136
+ %h6 Probability plot
137
+ %div.row
138
+ %div.plot.mx-auto{:id=>"pplot#{model.id}#{idx}"}
139
+ %img{:src=>"/#{cv.id}.png", :alt=>"#{cv.id}.png"}
37
140
 
38
- %br
39
- Descriptors:
40
- = model.model.algorithms["descriptors"]["method"]+","
41
- = model.model.algorithms["descriptors"]["type"]
141
+ / regression
142
+ - if model.regression?
143
+ / rmse, mae, r_squared, pred nr, within intv, out intv
144
+ - keys = cv.rmse.collect{|key, value| key}
145
+ - rmse = cv.rmse.collect{|key, value| value.signif(3)}
146
+ - mae = cv.mae.collect{|key, value| value.signif(3)}
147
+ - rsq = cv.r_squared.collect{|key, value| value.signif(3)}
148
+ - nrp = cv.nr_predictions.collect{|key,value| value}
149
+ - wpi = cv.within_prediction_interval.collect{|key,value| value}
150
+ - opi = cv.out_of_prediction_interval.collect{|key,value| value}
151
+ %table.table.table-bordered.table-responsive.text-center.bg-white
152
+ %tr
153
+ %td.text-center.bg-light
154
+ = "Nr.#{idx+1}"
155
+ %td
156
+ %a{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"}
157
+ RMSE
158
+ %td
159
+ %a{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"}
160
+ MAE
161
+ %td
162
+ %a{:href=>"https://en.wikipedia.org/wiki/Coefficient_of_determination", :rel=>"external"}= "R"+"<sup>2</sup>"
163
+ %td Number of predictions
164
+ %td Within prediction interval
165
+ %td Out of prediction interval
166
+ - keys.each_with_index do |key,idx|
167
+ %tr
168
+ / keys
169
+ %td.fit.text-right= key.gsub("_", " ")
170
+ / rsme:
171
+ %td= rmse[idx]
172
+ / mae:
173
+ %td= mae[idx]
174
+ / r_squared:
175
+ %td= rsq[idx]
176
+ / Predictions number:
177
+ %td= nrp[idx]
178
+ / Within prediction interval:
179
+ %td= wpi[idx]
180
+ / Out of prediction interval:
181
+ %td= opi[idx]
182
+ %div.row.justify-content-center
183
+ %h6 Correlation plot
184
+ %div.row
185
+ %div.plot.mx-auto{:id=>"cplot#{model.id}#{idx}"}
186
+ %img{:src=>"/#{cv.id}.png", :alt=>"#{cv.id}.png"}
187
+ - unless idx == crossvalidations.size-1
188
+ %hr
42
189
 
43
- %div.panel.panel-default
44
- - if type == "Classification"
45
- %div.panel-heading
46
- %b Independent crossvalidations:
47
- - else
48
- %div.panel-heading
49
- %b Independent crossvalidations (-log10 transformed):
50
- %div.panel-body
51
- /%div.row{:id=>"validations#{model.id}", :style=>"background-color:#f5f5f5;"}
52
- %div.row{:id=>"validations#{model.id}"}
53
- - crossvalidations.each do |cv|
54
- %span.col-xs-4.col-sm-4.col-md-4.col-lg-4
55
- = "Num folds:\t"
56
- = cv.folds
57
- %br
58
- = "Num instances:\t"
59
- = cv.nr_instances
60
- %br
61
- = "Num unpredicted"
62
- = cv.nr_unpredicted
63
- - if model.classification?
64
- %br
65
- = "Accuracy:\t"
66
- = cv.accuracy.round(3) if cv.accuracy
67
- %br
68
- = "Weighted accuracy:\t"
69
- = cv.weighted_accuracy.round(3) if cv.weighted_accuracy
70
- - if cv.true_rate
71
- %br
72
- = "True positive rate:\t"
73
- = cv.true_rate[cv.accept_values[0]].round(3)
74
- %br
75
- = "True negative rate:\t"
76
- = cv.true_rate[cv.accept_values[1]].round(3)
77
- - if cv.predictivity
78
- %br
79
- = "Positive predictive value:\t"
80
- = cv.predictivity[cv.accept_values[0]].round(3)
81
- %br
82
- = "Negative predictive value:\t"
83
- = cv.predictivity[cv.accept_values[1]].round(3)
84
- %p
85
- - ["confusion_matrix", "weighted_confusion_matrix"].each_with_index do |matrix,idx|
86
- %b= (idx == 0 ? "Confusion Matrix" : "Weighted Confusion Matrix")
87
- %table.table.table-condensed.table-borderless{:style=>"width:20%;"}
88
- %tbody
89
- %tr
90
- %td
91
- %td
92
- %td
93
- %b actual
94
- %td
95
- %td
96
- %tr
97
- %td
98
- %td
99
- %td active
100
- %td inactive
101
- -#%td total
102
- %tr
103
- %td
104
- %b predicted
105
- %td active
106
- %td
107
- =( idx == 1 ? cv.send(matrix)[0][0].round(3) : cv.send(matrix)[0][0])
108
- %td
109
- =( idx == 1 ? cv.send(matrix)[0][1].round(3) : cv.send(matrix)[0][1])
110
- -#%td
111
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[0][1]
112
- %tr
113
- %td
114
- %td inactive
115
- %td
116
- =( idx == 1 ? cv.send(matrix)[1][0].round(3) : cv.send(matrix)[1][0])
117
- %td
118
- =( idx == 1 ? cv.send(matrix)[1][1].round(3) : cv.send(matrix)[1][1])
119
- -#%td
120
- =cv.confusion_matrix[1][0]+cv.confusion_matrix[1][1]
121
- -#%tr
122
- %td
123
- %td total
124
- %td
125
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[1][0]
126
- %td
127
- =cv.confusion_matrix[0][1]+cv.confusion_matrix[1][1]
128
- %td
129
- -#= "Confusion Matrix:\t"
130
- -#= cv.confusion_matrix
131
- %br
132
- %br
133
- /= "Confidence plot:"
134
- /%p.plot
135
- / %img{:src=>"confp#{cv.id}.svg"}
136
- - if model.regression?
137
- %br
138
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"} RMSE:
139
- = cv.rmse.round(3) if cv.rmse
140
- %br
141
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"} MAE:
142
- = cv.mae.round(3) if cv.mae
143
- %br
144
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Coefficient_of_determination", :rel=>"external"}= "R"+"<sup>2</sup>"+":"
145
- = cv.r_squared.round(3) if cv.r_squared
146
- %br
147
- /= "Confidence plot:"
148
- /%p.plot
149
- / %img{:src=>"/confp#{cv.id}.svg"}
150
- /%br
151
- /= "Correlation plot"
152
- /%p.plot
153
- / %img{:src=>"/corrp#{cv.id}.svg"}
154
-
155
- %div.panel.panel-default
156
- %div.panel-heading
157
- %b QMRF:
158
- %div.panel-body
159
- %a.btn.btn-default.btn-xs{:href=>"#{to("/report/#{model.id}")}", :id=>"report#{model.id}", :style=>"font-size:small;"}
160
- %span.glyphicon.glyphicon-download-alt
190
+ %div.card.bg-light
191
+ %div.card-body
192
+ %h6.card-title QMRF:
193
+ %a.btn.btn-outline-info{:href=>"//#{$host_with_port}/predict/report/#{model.id}", :id=>"report#{model.id}", :style=>"font-size:small;"}
194
+ %span.fa.fa-download
161
195
  XML
196
+ %br
data/views/neighbors.haml CHANGED
@@ -1,83 +1,101 @@
1
- %div.results
2
- %h3 Neighbors:
3
- / tabs div
4
- #tabs
5
- %ul.nav.nav-tabs.nav-justified{:id=>"neighborTabs", :role=>"tablist", :style=>"width:100%;overflow-x:auto;"}
6
- - @models.each_with_index do |model,i|
7
- / get predictionFeature type
8
- - m = Model::Lazar.find model.model_id.to_s
9
- %li{:class => ("active" if i == 0)}
10
- %a{:href => "#results_#{i+1}", :id => "linkTab#{i+1}", data: {toggle:"tab"}}
11
- = "#{model.endpoint} (#{model.species})"
12
- %div.tab-content
13
- - @predictions.each_with_index do |prediction,j|
14
- #results.tab-pane{:id=>"#{j+1}", :class => ("active" if j == 0)}
15
- :javascript
16
- $(document).ready(function(){
17
- $("table##{j+1}").tablesorter({
18
- debug: false,
19
- theme: "bootstrap",
20
- headerTemplate: '',
21
- widgets: ['columns', 'uitheme', 'stickyHeaders'],
22
- widgetOptions: {
23
- stickyHeaders_attachTo : '.tab-content',
24
- stickyHeaders : '',
25
- stickyHeaders_offset : 0,
26
- stickyHeaders_cloneId : '-sticky',
27
- stickyHeaders_addResizeEvent : true,
28
- stickyHeaders_includeCaption : true,
29
- stickyHeaders_zIndex : 2,
30
- stickyHeaders_attachTo : null,
31
- stickyHeaders_xScroll : null,
32
- stickyHeaders_yScroll : null,
33
- stickyHeaders_filteredToTop: true
34
- },
35
- sortList: [[2,1]],
36
- headers: {sorter: false},
37
- widthFixed: false
38
- });
39
- });
40
- - if prediction[:neighbors]
41
- %div.table-responsive
42
- %table{:id=>"#{j+1}", :style=>"border-style: solid;"}
43
- %thead
44
- %tr
45
- %th.sorter-false{:style =>"vertical-align:middle;"}
46
- Compound
47
- %th.sorter-false{:style =>"vertical-align:middle;"}
48
- Measured Activity
49
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Measured Activity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
50
- %th.sorter-false{:style =>"vertical-align:middle;"}
51
- Similarity
52
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"<a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://en.wikipedia.org/wiki/Jaccard_index\">Tanimoto/Jaccard</a> similarity based on <a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://openbabel.org/docs/dev/FileFormats/MolPrint2D_format.html\">Molprint2D</a> fingerprints."}, :style=>"z-index:auto+10;"}
53
- %tbody
54
- - type = @model_types[j]
55
- - unit = @models[j].unit
56
- - prediction[:neighbors].uniq.each_with_index do |neighbor,count|
57
- %tr
58
- / Compound
59
- - c = Compound.find(neighbor)
60
- %td{:style =>"vertical-align:middle;padding-left:1em;width:50%;"}
61
- %a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: to("/prediction/#{CGI.escape(c.id.to_s)}/details"), :id=>"link#{j+1}#{count}"}}
62
- = c.svg
63
- %p= c.smiles
64
-
65
- / Measured Activity
66
- %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;white-space:nowrap;"}
67
- - if neighbor[:measurement].is_a?(Array)
68
- = (type == "Regression") ? neighbor[:measurement].collect{|value| "#{value.delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : neighbor[:measurement].join(", ")
69
- - else
70
- - if !neighbor[:measurement].nil?
71
- = (type == "Regression") ? "#{neighbor[:measurement].delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(neighbor[:measurement].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : neighbor[:measurement]
72
- / Similarity = tanimoto
73
- %td{:style =>"vertical-align:middle;padding-left:1em;width:20%;"}
74
- = neighbor[:similarity].round(3)
1
+ %div.card.bg-light
2
+ %div.card-body
3
+ %div.card-title
4
+ %h3 Neighbors:
5
+ #tabs
6
+ %ul.nav.nav-pills.nav-justified{:id=>"neighborTabs", :role=>"tablist"}
7
+ - @models.each_with_index do |model,i|
8
+ / get predictionFeature type
9
+ - m = Model::Lazar.find model.model_id.to_s
10
+ %li.nav-item
11
+ %a.nav-link{:class => ("active" if i ==0), :href => "#results_#{i+1}", :id => "linkTab#{i+1}", data: {toggle:"tab"}}
12
+ = "#{model.endpoint} (#{model.species})"
13
+ %div.tab-content
14
+ - @predictions.each_with_index do |prediction,j|
15
+ #results.tab-pane{:id=>"#{j+1}", :class => ("active" if j == 0)}
16
+ - if prediction[:neighbors]
17
+ %div.table-responsive
18
+ %table.table.table-bordered.table-hover{:id=>"nTable#{j+1}"}
19
+ %thead
20
+ %tr
21
+ %th{:scope=>"col"}
22
+ Compound
23
+ %th{:scope=>"col"}
24
+ Measured Activity
25
+ %a.btn.fa.fa-info-circle{:href=>"javascript:void(0)", :title=>"Measured Activity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"Experimental result(s) from the training dataset."}, :style=>"z-index:auto+10;"}
26
+ %th{:scope=>"col"}
27
+ Similarity
28
+ %a.btn.fa.fa-info-circle{:href=>"javascript:void(0)", :title=>"Similarity", :tabindex=>"0", data: {trigger:"focus", container:"body", toggle:"popover", placement:"auto", html:"true", content:"<a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://en.wikipedia.org/wiki/Jaccard_index\">Tanimoto/Jaccard</a> similarity based on <a alt=\"Link opens in new window.\" title=\"Link opens in new window.\" target=\"_blank\" href=\"https://openbabel.org/docs/dev/FileFormats/MolPrint2D_format.html\">Molprint2D</a> fingerprints."}, :style=>"z-index:auto+10;"}
29
+ %tbody
30
+ - type = @model_types[j]
31
+ - unit = @models[j].unit
32
+ - prediction[:neighbors].uniq.each_with_index do |neighbor,count|
33
+ %tr
34
+ / Compound
35
+ - c = Compound.find(neighbor)
36
+ %td
37
+ %a.btn.btn-link{:href => "#details#{j+1}", data: { toggle: "modal", remote: "//#{$host_with_port}/prediction/#{CGI.escape(c.id.to_s)}/details", :id=>"link#{j+1}#{count}"}}
38
+ = embedded_svg(c.svg, :title=>"click for details")
39
+
40
+ / Measured Activity
41
+ %td
42
+ - if neighbor[:measurement].is_a?(Array)
43
+ = (type == "Regression") ? neighbor[:measurement].collect{|value| "#{value.delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : neighbor[:measurement].join(", ")
44
+ - else
45
+ - if !neighbor[:measurement].nil?
46
+ = (type == "Regression") ? "#{neighbor[:measurement].delog10.signif(3)} (#{unit})</br>#{c.mmol_to_mg(neighbor[:measurement].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : neighbor[:measurement]
47
+ - if c.cid && c.cid != "0"
48
+ %p
49
+ %a{:href=>PUBCHEM_CID_URI+c.cid, :rel => "external"}
50
+ PubChem
51
+ %span.fa.fa-xs.fa-external-link
52
+ / Similarity = tanimoto
53
+ %td
54
+ = neighbor[:similarity].round(3)
75
55
 
76
- - else
77
- %span.btn.btn-default.disabled
78
- = "Not enough similar compounds in training dataset"
56
+ - else
57
+ %span.btn.btn-default.disabled
58
+ = "Not enough similar compounds in training dataset"
79
59
 
80
- %div.modal.fade{:id=>"details#{j+1}", :role=>"dialog"}
81
- %div.modal-dialog.modal-lg
82
- %div.modal-content
60
+ %div.modal.fade{:id=>"details#{j+1}", :role=>"dialog"}
61
+ %div.modal-dialog.modal-lg{:role=>"document"}
62
+ %div.modal-content
63
+ - @models.each_with_index do |model,i|
64
+ :javascript
65
+ // sort all neighbors tables by similarity
66
+ document.addEventListener('DOMContentLoaded', function() {
67
+ var id = '#{i+1}';
68
+ var table, rows, switching, i, x, y, shouldSwitch;
69
+ table = document.getElementById("nTable"+id);
70
+ switching = true;
71
+ /* Make a loop that will continue until
72
+ no switching has been done: */
73
+ while (switching) {
74
+ // Start by saying: no switching is done:
75
+ switching = false;
76
+ rows = table.rows;
77
+ /* Loop through all table rows (except the
78
+ first, which contains table headers): */
79
+ for (i = 1; i < (rows.length - 1); i++) {
80
+ // Start by saying there should be no switching:
81
+ shouldSwitch = false;
82
+ /* Get the two elements you want to compare,
83
+ one from current row and one from the next: */
84
+ x = rows[i].getElementsByTagName("TD")[2];
85
+ y = rows[i + 1].getElementsByTagName("TD")[2];
86
+ // Check if the two rows should switch place:
87
+ if (parseFloat(x.innerHTML) < parseFloat(y.innerHTML)) {
88
+ // If so, mark as a switch and break the loop:
89
+ shouldSwitch = true;
90
+ break;
91
+ }
92
+ }
93
+ if (shouldSwitch) {
94
+ /* If a switch has been marked, make the switch
95
+ and mark that a switch has been done: */
96
+ rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
97
+ switching = true;
98
+ }
99
+ }
100
+ }, false);
83
101