Commit 61bf5f1b authored by Jan Kiene's avatar Jan Kiene
Browse files

remove old histogram script

parent cab4e0f4
Loading
Loading
Loading
Loading
Loading
+0 −184
Original line number Diff line number Diff line
#!/usr/bin/env python3

import argparse
import math
import numpy as np

# These next three lines are added as a precaution in case the gitlab runner
# needs DISPLAY to render the plots, even if they are written to file.
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import csv
import os
from parse_xml_report import IVAS_FORMATS, EVS_FORMATS, IVAS_CATEGORIES, EVS_CATEGORIES

"""
Parses a CSV report and creates a summary report.
"""


# Main routine
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Parses a CSV report and creates a summary report."
    )
    parser.add_argument(
        "csv_report",
        type=str,
        help="CSV report file of test cases, e.g. report.csv",
    )
    parser.add_argument(
        "csv_summary", type=str, help="Output CSV file, e.g. summary.csv"
    )
    parser.add_argument(
        "csv_image",
        type=str,
        nargs="?",
        help="Summary image file, e.g. summary.png",
        default=None,
    )
    parser.add_argument(
        "--measure",
        type=str,
        nargs=1,
        help="Measure, any of: MLD, DIFF, SSNR, ODG, default: MLD",
        default=["MLD"],
    )
    parser.add_argument(
        "--evs",
        action="store_true",
        help="Parse using EVS 26.444 formats",
        default=False,
    )
    parser.add_argument(
        "--diff",
        action="store_true",
        help="Use limits for diff scores",
        default=False,
    )
    args = parser.parse_args()
    csv_report = args.csv_report
    csv_summary = args.csv_summary
    csv_image = args.csv_image
    measure = args.measure[0]
    if args.evs:
        FORMATS = EVS_FORMATS
        CATEGORIES = EVS_CATEGORIES
    else:
        FORMATS = IVAS_FORMATS
        CATEGORIES = IVAS_CATEGORIES
    if args.diff:
        limits_per_measure = {
            "MLD": ("MLD", None),
            "DIFF": ("MAXIMUM ABS DIFF", None),
            "SSNR": ("MIN_SSNR", None),
            "ODG": ("MIN_ODG", None),
            "DELTA_ODG": ("DELTA_ODG", None),
        }
    else:
        limits_per_measure = {
            "MLD": ("MLD", [0, 1, 2, 3, 4, 5, 10, 20, math.inf]),
            "DIFF": (
                "MAXIMUM ABS DIFF",
                [0, 16, 256, 1024, 2048, 4096, 8192, 16384, 32769],
            ),
            "SSNR": ("MIN_SSNR", [-math.inf, 0, 10, 20, 30, 40, 40, 50, 60, 100]),
            "ODG": (
                "MIN_ODG",
                [-5, -4, -3, -2, -1, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.5],
            ),
            "DELTA_ODG": (
                "DELTA_ODG",
                [-5, -4, -3, -2, -1, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.5],
            ),
        }
    (measure_label, limits) = limits_per_measure[measure]

    # Load CSV report
    results_sorted = {}
    with open(csv_report, "r") as fp:
        reader = csv.reader(fp, delimiter=";")
        header = next(reader)
        keys = header[1:]
        for row in reader:
            testcase = row[0]
            results_sorted[testcase] = {}
            for k, val in zip(keys, row[1:]):
                results_sorted[testcase][k] = val

    if limits is None:
        vals = [
            float(x)
            for x in [
                m[measure_label]
                for m in results_sorted.values()
                if m[measure_label] != "None" and m[measure_label] != ""
            ]
        ]
        start = min(vals)
        f = 10 ** (2 - int(np.floor(np.log10(abs(start)))) - 1)
        start = np.floor(start * f) / f
        step = (max(vals) - start) / 10
        f = 10 ** (2 - int(np.floor(np.log10(abs(step)))) - 1)
        step = np.ceil(step * f) / f
        limits = np.arange(start, 10 * step, step)

    # Output CSV file
    with open(csv_summary, "w") as fp:
        limits_labels = [f"{a:g}" for a in limits] + [
            "",
            "None",
        ]  # Put None cases in separate bin
        headerline = f"Format;Category;" + ";".join(limits_labels) + "\n"
        fp.write(headerline)

        for fmt in FORMATS:
            fig, ax = plt.subplots()
            bottom = np.zeros(len(limits_labels))
            for cat in CATEGORIES:
                values = [
                    x
                    for x in [
                        m[measure_label]
                        for m in results_sorted.values()
                        if m["Format"] == fmt and m["Category"] == cat
                    ]
                ]
                # Create separate bin for None (errors)
                val = [float(x) for x in values if x != "None" and x != ""]
                none = [sum([1 for x in values if x == "None" or x == ""])]
                hist, _ = np.histogram(val, limits)
                data = np.array(list(hist) + [0] + none + [0])

                # CSV output
                line = f"{fmt};{cat};{'; '.join(map(str,data))}\n"
                fp.write(line)

                # Matplotlib histogram
                ax.bar(
                    limits_labels,
                    data,
                    1,
                    align="edge",
                    edgecolor="black",
                    linewidth=0.5,
                    label=cat,
                    bottom=bottom,
                )
                bottom += data

            # Histogram layout
            ax.set_title(fmt)
            ax.legend(loc="best")
            ax.set_xlabel(measure_label)
            if "DIFF" in measure_label:
                ax.set_xticks(range(len(limits_labels)), limits_labels, rotation=35)
            ax.set_ylabel("Number of test cases")

            fig.set_figheight(4)
            fig.set_figwidth(6)
            if csv_image:
                base, ext = os.path.splitext(csv_image)
                plt.savefig(f"{base}_{fmt}{ext}")