summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py')
-rw-r--r--third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py b/third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py
new file mode 100644
index 0000000000..c425885b95
--- /dev/null
+++ b/third_party/libwebrtc/modules/audio_processing/test/py_quality_assessment/apm_quality_assessment_boxplot.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+"""Shows boxplots of given score for different values of selected
+parameters. Can be used to compare scores by audioproc_f flag.
+
+Usage: apm_quality_assessment_boxplot.py -o /path/to/output
+ -v polqa
+ -n /path/to/dir/with/apm_configs
+ -z audioproc_f_arg1 [arg2 ...]
+
+Arguments --config_names, --render_names, --echo_simulator_names,
+--test_data_generators, --eval_scores can be used to filter the data
+used for plotting.
+"""
+
+import collections
+import logging
+import matplotlib.pyplot as plt
+import os
+
+import quality_assessment.data_access as data_access
+import quality_assessment.collect_data as collect_data
+
+
+def InstanceArgumentsParser():
+ """Arguments parser factory.
+ """
+ parser = collect_data.InstanceArgumentsParser()
+ parser.description = (
+ 'Shows boxplot of given score for different values of selected'
+ 'parameters. Can be used to compare scores by audioproc_f flag')
+
+ parser.add_argument('-v',
+ '--eval_score',
+ required=True,
+ help=('Score name for constructing boxplots'))
+
+ parser.add_argument(
+ '-n',
+ '--config_dir',
+ required=False,
+ help=('path to the folder with the configuration files'),
+ default='apm_configs')
+
+ parser.add_argument('-z',
+ '--params_to_plot',
+ required=True,
+ nargs='+',
+ help=('audioproc_f parameter values'
+ 'by which to group scores (no leading dash)'))
+
+ return parser
+
+
+def FilterScoresByParams(data_frame, filter_params, score_name, config_dir):
+ """Filters data on the values of one or more parameters.
+
+ Args:
+ data_frame: pandas.DataFrame of all used input data.
+
+ filter_params: each config of the input data is assumed to have
+ exactly one parameter from `filter_params` defined. Every value
+ of the parameters in `filter_params` is a key in the returned
+ dict; the associated value is all cells of the data with that
+ value of the parameter.
+
+ score_name: Name of score which value is boxplotted. Currently cannot do
+ more than one value.
+
+ config_dir: path to dir with APM configs.
+
+ Returns: dictionary, key is a param value, result is all scores for
+ that param value (see `filter_params` for explanation).
+ """
+ results = collections.defaultdict(dict)
+ config_names = data_frame['apm_config'].drop_duplicates().values.tolist()
+
+ for config_name in config_names:
+ config_json = data_access.AudioProcConfigFile.Load(
+ os.path.join(config_dir, config_name + '.json'))
+ data_with_config = data_frame[data_frame.apm_config == config_name]
+ data_cell_scores = data_with_config[data_with_config.eval_score_name ==
+ score_name]
+
+ # Exactly one of `params_to_plot` must match:
+ (matching_param, ) = [
+ x for x in filter_params if '-' + x in config_json
+ ]
+
+ # Add scores for every track to the result.
+ for capture_name in data_cell_scores.capture:
+ result_score = float(data_cell_scores[data_cell_scores.capture ==
+ capture_name].score)
+ config_dict = results[config_json['-' + matching_param]]
+ if capture_name not in config_dict:
+ config_dict[capture_name] = {}
+
+ config_dict[capture_name][matching_param] = result_score
+
+ return results
+
+
+def _FlattenToScoresList(config_param_score_dict):
+ """Extracts a list of scores from input data structure.
+
+ Args:
+ config_param_score_dict: of the form {'capture_name':
+ {'param_name' : score_value,.. } ..}
+
+ Returns: Plain list of all score value present in input data
+ structure
+ """
+ result = []
+ for capture_name in config_param_score_dict:
+ result += list(config_param_score_dict[capture_name].values())
+ return result
+
+
+def main():
+ # Init.
+ # TODO(alessiob): INFO once debugged.
+ logging.basicConfig(level=logging.DEBUG)
+ parser = InstanceArgumentsParser()
+ args = parser.parse_args()
+
+ # Get the scores.
+ src_path = collect_data.ConstructSrcPath(args)
+ logging.debug(src_path)
+ scores_data_frame = collect_data.FindScores(src_path, args)
+
+ # Filter the data by `args.params_to_plot`
+ scores_filtered = FilterScoresByParams(scores_data_frame,
+ args.params_to_plot,
+ args.eval_score, args.config_dir)
+
+ data_list = sorted(scores_filtered.items())
+ data_values = [_FlattenToScoresList(x) for (_, x) in data_list]
+ data_labels = [x for (x, _) in data_list]
+
+ _, axes = plt.subplots(nrows=1, ncols=1, figsize=(6, 6))
+ axes.boxplot(data_values, labels=data_labels)
+ axes.set_ylabel(args.eval_score)
+ axes.set_xlabel('/'.join(args.params_to_plot))
+ plt.show()
+
+
+if __name__ == "__main__":
+ main()