first commit
This commit is contained in:
commit
cd1e91bb99
287 changed files with 86425 additions and 0 deletions
185
rasta_data_manipulation/rasta_triturage/utils.py
Normal file
185
rasta_data_manipulation/rasta_triturage/utils.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
"""
|
||||
Utils.
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt # type: ignore
|
||||
import numpy as np
|
||||
from slugify import slugify # type: ignore
|
||||
from typing import Any, Callable, Optional
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
|
||||
DENSE_DASH = (0, (5, 1))
|
||||
DENSE_DOT = (0, (1, 3))
|
||||
|
||||
MARKERS = {
|
||||
"adagio": ".",
|
||||
"amandroid": "o",
|
||||
"anadroid": "X",
|
||||
"androguard": "+",
|
||||
"androguard_dad": "v",
|
||||
"apparecium": "d",
|
||||
"blueseal": "^",
|
||||
"dialdroid": "<",
|
||||
"didfail": ">",
|
||||
"droidsafe": r"$\circ$",
|
||||
"flowdroid": r"$\boxplus$",
|
||||
"gator": r"$\otimes$",
|
||||
"ic3": "1",
|
||||
"ic3_fork": "s",
|
||||
"iccta": "P",
|
||||
"mallodroid": r"$\divideontimes$",
|
||||
"perfchecker": "*",
|
||||
"redexer": "x",
|
||||
"saaf": "D",
|
||||
"wognsen_et_al": r"$\rtimes$",
|
||||
}
|
||||
|
||||
COLORS = {
|
||||
"didfail": "#1f77b4",
|
||||
"adagio": "#ff7f0e",
|
||||
"iccta": "#2ca02c",
|
||||
"androguard": "#d62728",
|
||||
"gator": "#9467bd",
|
||||
"mallodroid": "#8c564b",
|
||||
"dialdroid": "#e377c2",
|
||||
"androguard_dad": "#7f7f7f",
|
||||
"wognsen_et_al": "#bcbd22",
|
||||
"perfchecker": "#17becf",
|
||||
"amandroid": "#1f77b4",
|
||||
"ic3": "#ff7f0e",
|
||||
"apparecium": "#2ca02c",
|
||||
"blueseal": "#d62728",
|
||||
"droidsafe": "#9467bd",
|
||||
"redexer": "#8c564b",
|
||||
"anadroid": "#e377c2",
|
||||
"saaf": "#7f7f7f",
|
||||
"ic3_fork": "#bcbd22",
|
||||
"flowdroid": "#17becf",
|
||||
"adagio": "#1f77b4",
|
||||
"androguard": "#ff7f0e",
|
||||
"mallodroid": "#2ca02c",
|
||||
"androguard_dad": "#d62728",
|
||||
"wognsen_et_al": "#9467bd",
|
||||
"amandroid": "#8c564b",
|
||||
"apparecium": "#e377c2",
|
||||
"redexer": "#7f7f7f",
|
||||
}
|
||||
|
||||
|
||||
def get_list_tools(db: Path) -> list[str]:
|
||||
"""Get the list of tool found in the database."""
|
||||
with sqlite3.connect(db) as con:
|
||||
cur = con.cursor()
|
||||
tools = cur.execute("SELECT DISTINCT tool_name FROM exec;")
|
||||
return [tool[0] for tool in tools]
|
||||
|
||||
|
||||
def radar_chart(
|
||||
axes: list[str],
|
||||
values: list[list[Any]],
|
||||
labels: list[str],
|
||||
title: str,
|
||||
interactive: bool,
|
||||
image_path: Path | None,
|
||||
):
|
||||
plt.rc("grid", linewidth=1, linestyle="-")
|
||||
plt.rc("xtick", labelsize=15)
|
||||
plt.rc("ytick", labelsize=15)
|
||||
angles = np.linspace(0, 2 * np.pi, len(axes), endpoint=False)
|
||||
angles = np.concatenate((angles, [angles[0]])) # type: ignore
|
||||
fig = plt.figure(figsize=(8, 8))
|
||||
ax = fig.add_subplot(111, polar=True)
|
||||
for label, vals in zip(labels, values):
|
||||
vals = vals + [vals[0]]
|
||||
ax.plot(angles, vals, label=label, marker=MARKERS.get(label, "."))
|
||||
ax.fill(angles, vals, alpha=0.25)
|
||||
ax.set_thetagrids(angles[:-1] * 180 / np.pi, axes)
|
||||
ax.set_ylim(bottom=0)
|
||||
ax.grid(True)
|
||||
ncol = min(5, len(labels))
|
||||
ax.legend(
|
||||
loc="lower left",
|
||||
bbox_to_anchor=(0.0, -0.2, ncol * 1.0 / 5, 0.102),
|
||||
ncol=ncol,
|
||||
mode="expand",
|
||||
borderaxespad=0.0,
|
||||
fancybox=True,
|
||||
shadow=True,
|
||||
fontsize="xx-small",
|
||||
)
|
||||
render(title, interactive, image_path)
|
||||
|
||||
|
||||
def render(
|
||||
title: str, interactive: bool, image_path: Path | None, tight_layout: bool = True
|
||||
):
|
||||
"""Render the figure. If `interactive`, display if, if `image_path`, save it."""
|
||||
# plt.title(title)
|
||||
if tight_layout:
|
||||
plt.tight_layout()
|
||||
if image_path is not None:
|
||||
if not image_path.exists():
|
||||
image_path.mkdir(parents=True, exist_ok=True)
|
||||
plt.savefig(image_path / (slugify(title) + ".pdf"), format="pdf")
|
||||
if interactive:
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
|
||||
def mean(field: str) -> Callable[[list[Any]], float]:
|
||||
def compute_mean(data: list[Any]) -> float:
|
||||
s = 0
|
||||
n = 0
|
||||
for e in data:
|
||||
n += 1
|
||||
s += e[field]
|
||||
return 0.0 if n == 0 else s / n
|
||||
|
||||
return compute_mean
|
||||
|
||||
|
||||
def median(field: str) -> Callable[[list[Any]], float]:
|
||||
def compute_median(data: list[Any]) -> float:
|
||||
l = [e[field] for e in data if e[field] is not None]
|
||||
l.sort()
|
||||
if not l:
|
||||
return 0.0
|
||||
return l[len(l) // 2]
|
||||
|
||||
return compute_median
|
||||
|
||||
|
||||
def plot_generic(
|
||||
data: list[list[tuple[Any, Any]]],
|
||||
meta: list[tuple[str, Any, Any, str]],
|
||||
x_label: str,
|
||||
y_label: str,
|
||||
title: str,
|
||||
ylim: Optional[tuple[int, int]] = None,
|
||||
interactive: bool = True,
|
||||
image_path: Path | None = None,
|
||||
):
|
||||
"""Plot a list of curve represented by list[(x, y)]. meta is the list of (label, linestyle)
|
||||
for each plot.
|
||||
"""
|
||||
plt.figure(figsize=(16, 9), dpi=80)
|
||||
for i, plot in enumerate(data):
|
||||
label, linestyle, marker, color = meta[i]
|
||||
plot.sort(key=lambda p: p[0])
|
||||
x_values = np.array([x for (x, _) in plot])
|
||||
y_values = np.array([y for (_, y) in plot])
|
||||
plt.plot(
|
||||
x_values[~np.isnan(y_values)],
|
||||
y_values[~np.isnan(y_values)],
|
||||
label=label,
|
||||
marker=marker,
|
||||
color=color,
|
||||
linestyle=linestyle,
|
||||
)
|
||||
if ylim is not None:
|
||||
plt.ylim(ylim)
|
||||
plt.legend(loc="upper center", ncol=4, bbox_to_anchor=(0.5, -0.1))
|
||||
plt.xlabel(x_label)
|
||||
plt.ylabel(y_label)
|
||||
render(title, interactive, image_path)
|
Loading…
Add table
Add a link
Reference in a new issue