summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirte Kristina Friesel <birte.friesel@uos.de>2024-02-09 09:41:26 +0100
committerBirte Kristina Friesel <birte.friesel@uos.de>2024-02-09 09:41:26 +0100
commitcfc77a403e9487580a966669cc4be0f90d464d62 (patch)
tree7134b0787808094d182ea3223c64a723517ff734
parentc806d27c1d5d2495096be83911d84ea5ed43d0ee (diff)
filter-param: support basic numeric operations and ∈ conditions
-rwxr-xr-xbin/analyze-archive.py2
-rwxr-xr-xbin/analyze-kconfig.py2
-rwxr-xr-xbin/analyze-log.py2
-rw-r--r--lib/cli.py27
-rw-r--r--lib/utils.py27
5 files changed, 47 insertions, 13 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py
index d397893..e79d690 100755
--- a/bin/analyze-archive.py
+++ b/bin/analyze-archive.py
@@ -285,7 +285,7 @@ def main():
if args.filter_param:
args.filter_param = list(
- map(lambda x: x.split("="), args.filter_param.split(","))
+ map(dfatool.cli.parse_filter_string, args.filter_param.split(";"))
)
else:
args.filter_param = list()
diff --git a/bin/analyze-kconfig.py b/bin/analyze-kconfig.py
index 4a1cb8c..3187609 100755
--- a/bin/analyze-kconfig.py
+++ b/bin/analyze-kconfig.py
@@ -295,7 +295,7 @@ def main():
if args.filter_param:
args.filter_param = list(
- map(lambda x: x.split("="), args.filter_param.split(","))
+ map(dfatool.cli.parse_filter_string, args.filter_param.split(";"))
)
dfatool.utils.filter_aggregate_by_param(
by_name, parameter_names, args.filter_param
diff --git a/bin/analyze-log.py b/bin/analyze-log.py
index b3c4fba..6fa279a 100755
--- a/bin/analyze-log.py
+++ b/bin/analyze-log.py
@@ -63,7 +63,7 @@ def main():
if args.filter_param:
args.filter_param = list(
- map(lambda x: x.split("="), args.filter_param.split(","))
+ map(dfatool.cli.parse_filter_string, args.filter_param.split(";"))
)
else:
args.filter_param = list()
diff --git a/lib/cli.py b/lib/cli.py
index fb1e722..4fd292b 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -416,8 +416,8 @@ def boxplot_param(args, model):
title = None
param_is_filtered = dict()
if args.filter_param:
- title = "filter: " + ", ".join(
- map(lambda kv: f"{kv[0]}={kv[1]}", args.filter_param)
+ title = "filter: " + " && ".join(
+ map(lambda kv: f"{kv[0]} {kv[1]} {kv[2]}", args.filter_param)
)
for param_name, _ in args.filter_param:
param_is_filtered[param_name] = True
@@ -595,9 +595,11 @@ def add_standard_arguments(parser):
)
parser.add_argument(
"--filter-param",
- metavar="<parameter name>=<parameter value>[,<parameter name>=<parameter value>...]",
+ metavar="<parameter name><condition>[;<parameter name><condition>...]",
type=str,
- help="Only consider measurements where <parameter name> is <parameter value>. "
+ help="Only consider measurements where <parameter name> satisfies <condition>. "
+ "<condition> may be <operator><parameter value> with operator being < / <= / = / >= / >, "
+ "or ∈<parameter value>[,<parameter value>...]. "
"All other measurements (including those where it is None, that is, has not been set yet) are discarded. "
"Note that this may remove entire function calls from the model.",
)
@@ -668,6 +670,23 @@ def add_standard_arguments(parser):
)
+def parse_filter_string(filter_string):
+ if "<=" in filter_string:
+ p, v = filter_string.split("<=")
+ return (p, "≤", v)
+ if ">=" in filter_string:
+ p, v = filter_string.split(">=")
+ return (p, "≥", v)
+ if "!=" in filter_string:
+ p, v = filter_string.split("!=")
+ return (p, "≠", v)
+ for op in ("<", ">", "≤", "≥", "=", "∈", "≠"):
+ if op in filter_string:
+ p, v = filter_string.split(op)
+ return (p, op, v)
+ raise ValueError(f"Cannot parse '{filter_string}'")
+
+
def parse_shift_function(param_name, param_shift):
if param_shift.startswith("+"):
param_shift_value = float(param_shift[1:])
diff --git a/lib/utils.py b/lib/utils.py
index 4282a14..989c830 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -608,14 +608,29 @@ def filter_aggregate_by_param(aggregate, parameters, parameter_filter):
:param parameters: list of parameters, used to map parameter index to parameter name. parameters=['foo', ...] means 'foo' is the first parameter
:param parameter_filter: [[name, value], [name, value], ...] list of parameter values to keep, all others are removed. Values refer to normalizad parameter data.
"""
- for param_name_and_value in parameter_filter:
- param_index = parameters.index(param_name_and_value[0])
- param_value = soft_cast_int(param_name_and_value[1])
+ for param_name, condition, param_value in parameter_filter:
+ param_index = parameters.index(param_name)
+ param_value = soft_cast_int(param_value)
names_to_remove = set()
+
+ if condition == "<":
+ condf = lambda x: x[param_index] < param_value
+ elif condition == "≤":
+ condf = lambda x: x[param_index] <= param_value
+ elif condition == "=":
+ condf = lambda x: x[param_index] == param_value
+ elif condition == "≠":
+ condf = lambda x: x[param_index] != param_value
+ elif condition == "≥":
+ condf = lambda x: x[param_index] >= param_value
+ elif condition == ">":
+ condf = lambda x: x[param_index] > param_value
+ elif condition == "∈":
+ param_values = tuple(map(soft_cast_int, param_value.split(",")))
+ condf = lambda x: x[param_index] in param_values
+
for name in aggregate.keys():
- indices_to_keep = list(
- map(lambda x: x[param_index] == param_value, aggregate[name]["param"])
- )
+ indices_to_keep = list(map(condf, aggregate[name]["param"]))
aggregate[name]["param"] = list(
map(
lambda iv: iv[1],