lazar-gui 1.1.3 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ *
2
+ !.gitignore
data/unicorn.rb CHANGED
@@ -1,7 +1,2 @@
1
- #worker_processes 4
1
+ worker_processes 4
2
2
  timeout 6000
3
- listen 8088
4
- log_dir = "#{ENV['HOME']}"
5
- log_file = File.join log_dir, "lazar.log"
6
- stderr_path log_file
7
- stdout_path log_file
@@ -2,11 +2,11 @@
2
2
  %a.btn.btn-warning{:href => to('/predict')}
3
3
  %span.glyphicon.glyphicon-menu-left{:aria=>{:hidden=>"true"}}
4
4
  New Prediction
5
- %a.btn.btn-success{:href=>"#{to("/predict/#{@filename}")}", :title=>"download"}
5
+ %a.btn.btn-success{:id => "downbutton", :href=>"#{to("/predict/#{@tmppath}/#{@filename}")}", :title=>"download"}
6
6
  %span.glyphicon.glyphicon-download-alt
7
- download CSV
7
+ Download CSV
8
8
 
9
- / show processed file name
9
+ / show file name
10
10
  %topline
11
11
  %div.row
12
12
  %div.col-md-4
@@ -18,83 +18,92 @@
18
18
  %div.table-responsive
19
19
  %table.table.table-bordered{:id=>"batch", :style=>"background-color:white;"}
20
20
  %tbody
21
- - if @warnings
22
- - @warnings.each do |warning|
21
+ - if @warnings
22
+ - @warnings.each do |warning|
23
+ %tr
24
+ %td
25
+ %b Warning
26
+ %td
27
+ = warning.sub(/\b(tmp\/)\b/,"")
28
+ - @view.each do |compound, array|
23
29
  %tr
24
- %td
25
- %b Warning
26
- %td
27
- = warning.sub(/\b(tmp\/)\b/,"")
28
- / key = compound, values = [model,prediction]
29
- - @batch.each do |key, values|
30
- - compound = key
31
- %tr
32
- %td{:style=>"vertical-align:top;"}
33
- %p= compound.svg
34
- %p= compound.smiles
35
-
36
- / array[0] = model, array[1] = prediction
37
- - values.each_with_index do |array,i|
38
- %td{:style=>"vertical-align:top;white-space:nowrap;"}
39
- - model = array[0]
40
- / model type (classification|regression)
41
- - model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression"
42
- - unit = model.unit
43
- - prediction = array[1]
44
-
45
- %b{:class => "title"}
46
- = "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
47
-
48
- / check for prediction
49
- - if prediction[:neighbors].size > 0
50
- %p
51
- / show model type (classification|regression)
52
- %b Type:
53
- = type
54
- %p
55
- / check for database hit
56
- - if prediction[:info] =~ /\b(identical)\b/i
57
-
58
- / show message about dbhit and measurements
30
+ %td{:style=>"vertical-align:top;"}
31
+ %p= compound.svg
32
+ %p= compound.smiles
33
+ - array.each do |model,prediction|
34
+ %td{:style=>"vertical-align:top;white-space:nowrap;"}
35
+ - model.model.class.to_s.match("Classification") ? type = "Classification" : type = "Regression"
36
+ - unit = model.unit
37
+
38
+ %b{:class => "title"}
39
+ = "#{model.endpoint.gsub('_', ' ')} (#{model.species})"
40
+
41
+ / check for prediction
42
+ - if prediction[:value]
59
43
  %p
60
- %b Compound is part of the training dataset
44
+ / show model type (classification|regression)
45
+ %b Type:
46
+ = type
47
+ %p
48
+ / check for database hit
49
+ - if prediction[:info] =~ /\b(identical)\b/i
50
+
51
+ / show message about dbhit and measurements
61
52
  %p
62
- %b Measured activity:
53
+ %b Compound is part of the training dataset
54
+ %p
55
+ %b Measured activity:
56
+ %br
57
+ - if prediction[:measurements].is_a?(Array)
58
+ = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10.signif(3)} (#{unit})</br>#{compound.mmol_to_mg(value.delog10).signif(3)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : prediction[:measurements].join(", ")
59
+ - else
60
+ = (type == "Regression") ? "#{prediction[:measurements].delog10.signif(3)} (#{unit})</br>#{compound.mmol_to_mg(prediction[:measurements].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
61
+
62
+
63
+ / show prediction
64
+ %p
65
+ %b Prediction:
63
66
  %br
64
- - if prediction[:measurements].is_a?(Array)
65
- = (type == "Regression") ? prediction[:measurements].collect{|value| "#{value.delog10} (#{unit})</br>#{compound.mmol_to_mg(value.delog10)} #{unit =~ /mmol\/L/ ? "(mg/L)" : "(mg/kg_bw/day)"}"}.join("</br>") : prediction[:measurements].join(", ")
67
+ = (type == "Regression") ? "#{prediction[:value].delog10.signif(3)} (#{unit})</br>#{compound.mmol_to_mg(prediction[:value].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
68
+
69
+ / show prediction interval or probability
70
+ %p
71
+ - if type == "Regression"
72
+ %b 95% Prediction interval:
73
+ - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
74
+ %br
75
+ = interval.nil? ? "" : "#{interval[1].delog10.signif(3)} - #{interval[0].delog10.signif(3)} (#{unit})"
76
+ %br
77
+ = "#{compound.mmol_to_mg(interval[1].delog10).signif(3)} - #{compound.mmol_to_mg(interval[0].delog10).signif(3)} #{(unit =~ /\b(mmol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil?
66
78
  - else
67
- = (type == "Regression") ? "#{prediction[:measurements].delog10} (#{unit})</br>#{compound.mmol_to_mg(prediction[:measurements].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:measurements]
68
-
69
-
70
- / show prediction
71
- %p
72
- %b Prediction:
73
- %br
74
- = (type == "Regression") ? "#{prediction[:value].delog10} (#{unit})</br>#{compound.mmol_to_mg(prediction[:value].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" : prediction[:value]
75
-
76
- / show prediction interval or probability
79
+ %b Probability:
80
+ - unless prediction[:probabilities].nil?
81
+ - probabilities = ""
82
+ - prediction[:probabilities].each{|k,v| probabilities += "#{k}: #{v.signif(3)}<br>"}
83
+ %br
84
+ = probabilities
85
+ / show warnings
77
86
  %p
78
- - if type == "Regression"
79
- %b 95% Prediction interval:
80
- - interval = (prediction[:prediction_interval].nil? ? nil : prediction[:prediction_interval])
87
+ - if !prediction[:info].blank?
88
+ %b Info:
81
89
  %br
82
- = interval.nil? ? "--" : "#{interval[1].delog10} - #{interval[0].delog10} (#{unit})"
83
- %br
84
- = "#{compound.mmol_to_mg(interval[1].delog10)} - #{compound.mmol_to_mg(interval[0].delog10)} #{(unit =~ /\b(mol\/L)\b/) ? "(mg/L)" : "(mg/kg_bw/day)"}" if !prediction[:prediction_interval].nil?
85
- - else
86
- %b Probability:
87
- - unless prediction[:probabilities].nil?
90
+ %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
91
+ - if !prediction[:warnings].blank?
92
+ %b Warnings:
93
+ - prediction[:warnings].uniq.each do |warning|
88
94
  %br
89
- = "#{prediction[:probabilities].keys[0]}: #{prediction[:probabilities].values[0]}"
95
+ %p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
96
+
97
+ / no prediction
98
+ - else
99
+ %br
100
+ - if !prediction[:info].blank?
101
+ %b Info:
102
+ %br
103
+ %p=prediction[:info].sub(/\'.*\'/,"").sub(/,/, ",<br>")
104
+ - if !prediction[:warnings].blank?
105
+ %b Warnings:
106
+ - prediction[:warnings].uniq.each do |warning|
90
107
  %br
91
- / show warnings
92
- %p
93
- - if !prediction[:warning].nil?
94
- %b Warnings:
95
- %a.btn.glyphicon.glyphicon-info-sign{:href=>"javascript:void(0)", :title=>"Warnings", :tabindex=>"0", data: {trigger:"focus", toggle:"popover", placement:"left", html:"true", content:"#{prediction[:warning]}"}}
96
-
97
- / no prediction
98
- - else
99
- %p
100
- = "Not enough similar compounds </br>in training dataset."
108
+ %p=warning.sub(/substances/, "substances<br>").sub(/prediction\:/, "prediction\:<br>")
109
+ %tr
@@ -4,5 +4,4 @@
4
4
  Back
5
5
  %hr
6
6
  %div.well{:style=>"width:100%;margin-bottom:2em;"}
7
- = @error_report
8
-
7
+ = @error
@@ -1,2 +1,2 @@
1
1
  %div.info
2
- currently no models available
2
+ We are rebuilding the models. It will take a while, please be patient and reload the page in some time.
@@ -16,6 +16,7 @@
16
16
  %script{:src=>"/javascripts/jquery.tablesorter.min.js"}
17
17
  %script{:src=>"/javascripts/jquery.tablesorter.widgets.js"}
18
18
  %script{:src=>"/javascripts/lazar-gui.js"}
19
+ %script{:src=>"/javascripts/google_analytics_lazar.js"}
19
20
  %body
20
21
  %noscript
21
22
  %div{ :style=>"width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif"}
@@ -31,7 +32,9 @@
31
32
  %div.col-md-3
32
33
  %h1.media-heading
33
34
  %small
34
- %a{:href=>"https://nano-lazar.in-silico.ch", :rel=>"external"} nano-lazar
35
+ %a.btn{:href=>"https://nano-lazar.in-silico.ch", :rel=>"external"}
36
+ nano-lazar
37
+ %span.glyphicon.glyphicon-new-window
35
38
 
36
39
  %div.container-fluid
37
40
  %topline.alert
@@ -86,16 +89,18 @@
86
89
  %a{:href => 'http://www.in-silico.ch', :rel => "external"} <i style="font-family: serife">in silico</i> toxicology gmbh 2004 - #{Time.now.year.to_s}
87
90
  |
88
91
  %a{:href => to("/license"), :rel => "external"} GPL3 License
89
- %supporters.col-md-12
90
- %p Financial support by
91
- %a{:href=>"http://www.bfr.bund.de/de/start.html", :rel=>"external"}
92
- %img{:src=>"/images/bfr_logo.gif"}
93
- %a{:href=>"http://www.opentox.org/", :rel=>"external"}
94
- %img{:src=>"/images/ot_logo.png"}
95
- %a{:href=>"https://enanomapper.net/", :rel=>"external"}
96
- %img{:src=>"/images/enm_logo.png"}
97
- %a{:href=>"https://www.researchgate.net/institution/Nestle_SA/department/Nestle_Research_Center", :rel=>"external"}
98
- %img{:src=>"/images/nestec.jpg"}
92
+ %supporters
93
+ %div.panel.panel-default
94
+ Financial support by
95
+ %div.panel-body
96
+ %a{:href=>"http://www.bfr.bund.de/de/start.html", :rel=>"external"}
97
+ %img{:src=>"/images/bfr_logo.gif"}
98
+ %a{:href=>"http://www.opentox.org/", :rel=>"external"}
99
+ %img{:src=>"/images/ot_logo.png"}
100
+ %a{:href=>"https://enanomapper.net/", :rel=>"external"}
101
+ %img{:src=>"/images/enm_logo.png"}
102
+ %a{:href=>"https://www.researchgate.net/institution/Nestle_SA/department/Nestle_Research_Center", :rel=>"external"}
103
+ %img{:src=>"/images/nestec.jpg"}
99
104
 
100
105
 
101
106
  #back-top{:style => "z-index:100;position:fixed;bottom:1%;right:1%;"}
@@ -1,141 +1,161 @@
1
- %b Model:
2
- %br
3
- Source:
4
- %a{:href=>model.source, :rel=>"external"}
5
- = model.source
6
- %br
7
- - model.classification? ? type = "Classification" : type = "Regression"
8
- = "Type:\t"
9
- = type
10
- %br
11
- - training_dataset = OpenTox::Dataset.find model.model.training_dataset_id
12
- = "Training compounds:\t"
13
- = training_dataset.data_entries.size
14
- %br
15
- = "Training dataset:\t"
16
- %a{:href=>"#{to("/predict/dataset/#{training_dataset.name}")}"}
17
- = training_dataset.name
18
- %br
19
- %b Algorithms:
20
- %br
21
- Similarity:
22
- %a{:href=> "http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["similarity"]["method"].sub("::", "%2F")}", :rel=>"external"}
23
- = model.model.algorithms["similarity"]["method"]
24
- = ", min: #{model.model.algorithms["similarity"]["min"]}"
25
- %br
26
- Prediction:
27
- %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox%2F#{model.model.algorithms["prediction"]["method"].sub("::","%2f")}", :rel=>"external"}
28
- = model.model.algorithms["prediction"]["method"]
29
- %br
30
- Descriptors:
31
- = model.model.algorithms["descriptors"]["method"]+","
32
- = model.model.algorithms["descriptors"]["type"]
33
- %p
34
- - if type == "Classification"
35
- %b Independent crossvalidations:
36
- - else
37
- %b Independent crossvalidations (-log10 transformed):
38
- %div.row{:id=>"validations#{model.id}", :style=>"background-color:#f5f5f5;"}
39
- - crossvalidations.each do |cv|
40
- %span.col-xs-4.col-sm-4.col-md-4.col-lg-4
41
- = "Num folds:\t"
42
- = cv.folds
43
- %br
44
- = "Num instances:\t"
45
- = cv.nr_instances
46
- %br
47
- = "Num unpredicted"
48
- = cv.nr_unpredicted
49
- - if model.classification?
50
- %br
51
- = "Accuracy:\t"
52
- = cv.accuracy.round(3) if cv.accuracy
53
- %br
54
- = "Weighted accuracy:\t"
55
- = cv.weighted_accuracy.round(3) if cv.weighted_accuracy
56
- - if cv.true_rate
1
+ %div.panel.panel-default
2
+ %div.panel-heading
3
+ %b Model:
4
+ %div.panel-body
5
+ Source:
6
+ %a{:href=>model.source, :rel=>"external"}
7
+ = model.source
8
+ %br
9
+ - model.classification? ? type = "Classification" : type = "Regression"
10
+ = "Type:\t"
11
+ = type
12
+ %br
13
+ - training_dataset = OpenTox::Dataset.find model.model.training_dataset_id
14
+ = "Training compounds:\t"
15
+ = training_dataset.data_entries.size
16
+ %br
17
+ = "Training dataset:\t"
18
+ %a{:href=>"#{to("/predict/dataset/#{training_dataset.name}")}"}
19
+ = training_dataset.name
20
+
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"]
34
+ - else
35
+ %a{:href=>"http://www.rubydoc.info/gems/lazar/OpenTox/Algorithm/Caret", :rel=>"external"}
36
+ = model.model.algorithms["prediction"]["method"]
37
+
38
+ %br
39
+ Descriptors:
40
+ = model.model.algorithms["descriptors"]["method"]+","
41
+ = model.model.algorithms["descriptors"]["type"]
42
+
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
57
  %br
58
- = "True positive rate:\t"
59
- = cv.true_rate[cv.accept_values[0]].round(3)
58
+ = "Num instances:\t"
59
+ = cv.nr_instances
60
60
  %br
61
- = "True negative rate:\t"
62
- = cv.true_rate[cv.accept_values[1]].round(3)
63
- - if cv.predictivity
64
- %br
65
- = "Positive predictive value:\t"
66
- = cv.predictivity[cv.accept_values[0]].round(3)
67
- %br
68
- = "Negative predictive value:\t"
69
- = cv.predictivity[cv.accept_values[1]].round(3)
70
- %p
71
- - ["confusion_matrix", "weighted_confusion_matrix"].each_with_index do |matrix,idx|
72
- %b= (idx == 0 ? "Confusion Matrix" : "Weighted Confusion Matrix")
73
- %table.table.table-condensed.table-borderless{:style=>"width:20%;"}
74
- %tbody
75
- %tr
76
- %td
77
- %td
78
- %td
79
- %b actual
80
- %td
81
- %td
82
- %tr
83
- %td
84
- %td
85
- %td active
86
- %td inactive
87
- -#%td total
88
- %tr
89
- %td
90
- %b predicted
91
- %td active
92
- %td
93
- =( idx == 1 ? cv.send(matrix)[0][0].round(3) : cv.send(matrix)[0][0])
94
- %td
95
- =( idx == 1 ? cv.send(matrix)[0][1].round(3) : cv.send(matrix)[0][1])
96
- -#%td
97
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[0][1]
98
- %tr
99
- %td
100
- %td inactive
101
- %td
102
- =( idx == 1 ? cv.send(matrix)[1][0].round(3) : cv.send(matrix)[1][0])
103
- %td
104
- =( idx == 1 ? cv.send(matrix)[1][1].round(3) : cv.send(matrix)[1][1])
105
- -#%td
106
- =cv.confusion_matrix[1][0]+cv.confusion_matrix[1][1]
107
- -#%tr
108
- %td
109
- %td total
110
- %td
111
- =cv.confusion_matrix[0][0]+cv.confusion_matrix[1][0]
112
- %td
113
- =cv.confusion_matrix[0][1]+cv.confusion_matrix[1][1]
114
- %td
115
- -#= "Confusion Matrix:\t"
116
- -#= cv.confusion_matrix
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)
117
81
  %br
118
- %br
119
- /= "Confidence plot:"
120
- /%p.plot
121
- / %img{:src=>"confp#{cv.id}.svg"}
122
- - if model.regression?
123
- %br
124
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Root-mean-square_deviation", :rel=>"external"} RMSE:
125
- = cv.rmse.round(3) if cv.rmse
126
- %br
127
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Mean_absolute_error", :rel=>"external"} MAE:
128
- = cv.mae.round(3) if cv.mae
129
- %br
130
- %a.ht5{:href=>"https://en.wikipedia.org/wiki/Coefficient_of_determination", :rel=>"external"}= "R"+"<sup>2</sup>"+":"
131
- = cv.r_squared.round(3) if cv.r_squared
132
- %br
133
- /= "Confidence plot:"
134
- /%p.plot
135
- / %img{:src=>"/confp#{cv.id}.svg"}
136
- /%br
137
- /= "Correlation plot"
138
- /%p.plot
139
- / %img{:src=>"/corrp#{cv.id}.svg"}
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"}
140
154
 
141
- %br
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
161
+ XML