visual_metrics.py : error catching, and order fixing
auto generate list of metrics stt file
Change-Id: Ic55b6b2b7fd7b0b9f75a5eeb349d385ab943d9c9
diff --git a/scripts/metrics_template.html b/scripts/metrics_template.html
index b10f307..72fd51f 100644
--- a/scripts/metrics_template.html
+++ b/scripts/metrics_template.html
@@ -126,7 +126,6 @@
span.google-visualization-table-sortind {
color: #000;
}
-
.header-style {
font-weight: bold;
border: 1px solid #fff;
@@ -145,7 +144,7 @@
background-color: #f0f0f0;
}
</style>
-<script type="text/javascript" src="https://www.google.com/jsapi"></script>
+<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
var chart_left = 40;
var chart_top = 6;
@@ -158,6 +157,7 @@
var filestable_avg = [];
// Python template code replaces the following 2 lines.
+//%%metrics_js%%//
//%%filestable_dpsnr%%//
//%%filestable_avg%%//
//%%filestable_drate%%//
@@ -169,12 +169,13 @@
var chart=0;
var better=0;
var metricdata=0;
-var metricview=0;
+var metricView=0;
var column=1;
var formatter=0;
function changeColumn(col) {
column = col;
+ console.log(col)
draw_files();
}
@@ -191,6 +192,20 @@
document.getElementById("bettertable"));
draw_files();
+ build_metrics_radio();
+}
+
+function build_metrics_radio() {
+ for (metric=1; metric < metrics.length; metric++) {
+ var rb = document.createElement('input');
+ var l = document.createElement('label');
+ rb.setAttribute('type','radio');
+ rb.setAttribute('name','metric');
+ rb.setAttribute('onClick', "changeColumn('"+metric.toString()+"')");
+ l.innerHTML = metrics[metric];
+ document.getElementById('metrics').appendChild(rb);
+ document.getElementById('metrics').appendChild(l);
+ }
}
function draw_files() {
@@ -221,10 +236,11 @@
imagestr = better.getFormattedValue(selected, 0)
var metricjson = eval('(' + snrs[column][selected] + ')');
metricdata = new google.visualization.DataTable(metricjson, 0.6);
- if( metricview != 0 ) delete metricview;
- metricview = new google.visualization.DataView(metricdata);
+ if( metricView != 0 ) delete metricView;
+ metricView = new google.visualization.DataView(metricdata);
- chart.draw(metricview, {curveType:'function',
+ chart.draw(metricView, {curveType:'function',
+ explorer: {},
chartArea:{left:chart_left, top:chart_top, width:chart_width,
height:chart_height-90},
hAxis:{title:"Datarate in kbps"}, vAxis:{title:"Quality in decibels"},
@@ -252,11 +268,12 @@
var cols = metricdata.getNumberOfColumns();
var rows = metricdata.getNumberOfRows();
- var sel_bitrate = metricview.getValue(row, 0 );
- var sel_metric = metricview.getValue(row, col);
+ var sel_bitrate = metricView.getValue(row, 0 );
+ var sel_metric = metricView.getValue(row, col);
- var message = "At " + sel_metric.toFixed(2) + " decibels, <em>"
- message = message + metricdata.getColumnLabel(col) + "</em> is <ul>"
+ var message = '<ul>' + metricView.getColumnLabel(col) +
+ ' (' + sel_bitrate.toFixed(0) + ' kbps, ' + sel_metric.toFixed(2) + ')' + ' is ';
+
// col 0 is datarate
for( var i=1;i<cols;++i) {
@@ -321,17 +338,17 @@
function chartSelect() {
var selection = chart.getSelection();
var message = '';
- var min = metricview.getFormattedValue(selection[0].row, 0);
- var max = metricview.getFormattedValue(selection[selection.length-1].row, 0);
- var val = metricview.getFormattedValue(selection[0].row,selection[0].column);
+ var min = metricView.getFormattedValue(selection[0].row, 0);
+ var max = metricView.getFormattedValue(selection[selection.length-1].row, 0);
+ var val = metricView.getFormattedValue(selection[0].row,selection[0].column);
pointDifference(selection[0].row, selection[0].column)
min = min / 3
max = max * 3
- metricview.setRows(metricdata.getFilteredRows(
+ metricView.setRows(metricdata.getFilteredRows(
[{column: 0,minValue: min, maxValue:max}]));
- chart.draw(metricview, {curveType:'function',
+ chart.draw(metricView, {curveType:'function',
chartArea:{left:40, top:10, width:chart_width, height:chart_height - 110},
hAxis:{title:"datarate in kbps"}, vAxis:{title:"quality in decibels"},
legend:{position:"in"}, title:imagestr, pointSize:2, lineWidth:1,
@@ -347,6 +364,7 @@
query_file()
}
+
google.load('visualization', '1', {'packages' : ['corechart','table']});
google.setOnLoadCallback(setup_vis);
</script>
@@ -372,12 +390,7 @@
onClick="changeMetric('filestable_drate')" />BDRATE
</form>
- <form name="myform">
- Average size reduction to get the same quality <input type="radio"
- checked name="column" value="1" onClick="changeColumn('1')" />Average
- PSNR <input type="radio" name="column" value="2"
- onClick="changeColumn('2')" />Global PSNR <input type="radio"
- name="column" value="3" onClick="changeColumn('5')" />SSIM
+ <form id="metrics" name="myform">
</form>
</div>
diff --git a/scripts/visual_metrics.py b/scripts/visual_metrics.py
index 29cecac..4a67b23 100755
--- a/scripts/visual_metrics.py
+++ b/scripts/visual_metrics.py
@@ -16,6 +16,7 @@
import string
import sys
import math
+import warnings
import gviz_api
@@ -39,28 +40,39 @@
psnr1 = [x[1] for x in metric_set1]
rate2 = [x[0] for x in metric_set2]
psnr2 = [x[1] for x in metric_set2]
+ if not psnr1 or not psnr2:
+ return 0.0
+
+ psnr1 = [100.0 if x == float('inf') else x for x in psnr1]
+ psnr2 = [100.0 if x == float('inf') else x for x in psnr2]
+
log_rate1 = map(lambda x: math.log(x), rate1)
log_rate2 = map(lambda x: math.log(x), rate2)
- # Best cubic poly fit for graph represented by log_ratex, psrn_x.
- p1 = numpy.polyfit(log_rate1, psnr1, 3)
- p2 = numpy.polyfit(log_rate2, psnr2, 3)
+ try:
+ # Best cubic poly fit for graph represented by log_ratex, psrn_x.
+ p1 = numpy.polyfit(log_rate1, psnr1, 3)
+ p2 = numpy.polyfit(log_rate2, psnr2, 3)
- # Integration interval.
- min_int = max([min(log_rate1),min(log_rate2)])
- max_int = min([max(log_rate1),max(log_rate2)])
+ # Integration interval.
+ min_int = max([min(log_rate1),min(log_rate2)])
+ max_int = min([max(log_rate1),max(log_rate2)])
- # Integrate p1, and p2.
- p_int1 = numpy.polyint(p1)
- p_int2 = numpy.polyint(p2)
+ # Integrate p1, and p2.
+ p_int1 = numpy.polyint(p1)
+ p_int2 = numpy.polyint(p2)
- # Calculate the integrated value over the interval we care about.
- int1 = numpy.polyval(p_int1, max_int) - numpy.polyval(p_int1, min_int)
- int2 = numpy.polyval(p_int2, max_int) - numpy.polyval(p_int2, min_int)
+ # Calculate the integrated value over the interval we care about.
+ int1 = numpy.polyval(p_int1, max_int) - numpy.polyval(p_int1, min_int)
+ int2 = numpy.polyval(p_int2, max_int) - numpy.polyval(p_int2, min_int)
- # Calculate the average improvement.
- avg_diff = (int2 - int1) / (max_int - min_int)
+ # Calculate the average improvement.
+ avg_diff = (int2 - int1) / (max_int - min_int)
+
+ except (TypeError, ZeroDivisionError, ValueError, numpy.RankWarning) as e:
+ return 0
+
return avg_diff
def bdrate(metric_set1, metric_set2):
@@ -80,27 +92,38 @@
rate2 = [x[0] for x in metric_set2]
psnr2 = [x[1] for x in metric_set2]
+ if not psnr1 or not psnr2:
+ return 0.0
+
+ psnr1 = [100.0 if x == float('inf') else x for x in psnr1]
+ psnr2 = [100.0 if x == float('inf') else x for x in psnr2]
+
log_rate1 = map(lambda x: math.log(x), rate1)
log_rate2 = map(lambda x: math.log(x), rate2)
- # Best cubic poly fit for graph represented by log_ratex, psrn_x.
- p1 = numpy.polyfit(psnr1, log_rate1, 3)
- p2 = numpy.polyfit(psnr2, log_rate2, 3)
+ try:
+ # Best cubic poly fit for graph represented by log_ratex, psrn_x.
+ p1 = numpy.polyfit(psnr1, log_rate1, 3)
+ p2 = numpy.polyfit(psnr2, log_rate2, 3)
- # Integration interval.
- min_int = max([min(psnr1),min(psnr2)])
- max_int = min([max(psnr1),max(psnr2)])
+ # Integration interval.
+ min_int = max([min(psnr1),min(psnr2)])
+ max_int = min([max(psnr1),max(psnr2)])
- # find integral
- p_int1 = numpy.polyint(p1)
- p_int2 = numpy.polyint(p2)
+ # find integral
+ p_int1 = numpy.polyint(p1)
+ p_int2 = numpy.polyint(p2)
- # Calculate the integrated value over the interval we care about.
- int1 = numpy.polyval(p_int1, max_int) - numpy.polyval(p_int1, min_int)
- int2 = numpy.polyval(p_int2, max_int) - numpy.polyval(p_int2, min_int)
+ # Calculate the integrated value over the interval we care about.
+ int1 = numpy.polyval(p_int1, max_int) - numpy.polyval(p_int1, min_int)
+ int2 = numpy.polyval(p_int2, max_int) - numpy.polyval(p_int2, min_int)
- # Calculate the average improvement.
- avg_exp_diff = (int2 - int1) / (max_int - min_int)
+ # Calculate the average improvement.
+ avg_exp_diff = (int2 - int1) / (max_int - min_int)
+
+ except (TypeError, ZeroDivisionError, ValueError, numpy.RankWarning) as e:
+ return 0
+
# In really bad formed data the exponent can grow too large.
# clamp it.
@@ -129,10 +152,18 @@
"""
The metrics files produced by vpxenc are started with a B for headers.
"""
- if line[0:1] != "B":
+ # If the first char of the first word on the line is a digit
+ if len(line) == 0:
+ return False
+ if len(line.split()) == 0:
+ return False
+ if line.split()[0][0:1].isdigit():
return True
return False
+def GetMetrics(file_name):
+ metric_file = open(file_name, "r")
+ return metric_file.readline().split();
def ParseMetricFile(file_name, metric_column):
metric_set1 = set([])
@@ -282,18 +313,22 @@
baseline_dir = variables[3]
snrs = ''
filestable = {}
+
filestable['dsnr'] = ''
filestable['drate'] = ''
filestable['avg'] = ''
- # Go through each metric in the list.
- for column in range(1, 6):
+ # Dirs is directories after the baseline to compare to the base.
+ dirs = variables[4:len(variables)]
- # Dirs is directories after the baseline to compare to the base.
- dirs = variables[4:len(variables)]
+ # Find the metric files in the baseline directory.
+ dir_list = sorted(fnmatch.filter(os.listdir(baseline_dir), file_pattern))
- # Find the metric files in the baseline directory.
- dir_list = sorted(fnmatch.filter(os.listdir(baseline_dir), file_pattern))
+ metrics = GetMetrics(baseline_dir + "/" + dir_list[0])
+
+ metrics_js = 'metrics = ["' + '", "'.join(metrics) + '"];'
+
+ for column in range(1, len(metrics)):
for metric in ['avg','dsnr','drate']:
description = {"file": ("string", "File")}
@@ -342,8 +377,8 @@
data_table.LoadData(data)
filestable[metric] = ( filestable[metric] + "filestable_" + metric +
- "[" + str(column) + "]=" + data_table.ToJSon()
- + "\n" )
+ "[" + str(column) + "]=" +
+ data_table.ToJSon(columns_order=["file"]+dirs) + "\n" )
filestable_avg = filestable['avg']
filestable_dpsnr = filestable['dsnr']
@@ -397,4 +432,4 @@
if len(sys.argv) < 3:
print HandleFiles.__doc__
else:
- HandleFiles(sys.argv)
\ No newline at end of file
+ HandleFiles(sys.argv)