Skip to content

Commit

Permalink
Merge pull request #46 from siftech/develop
Browse files Browse the repository at this point in the history
1.9.0-rc
  • Loading branch information
danbryce authored Jul 31, 2024
2 parents d909110 + 5d42505 commit 553e8db
Show file tree
Hide file tree
Showing 155 changed files with 45,723 additions and 3,988 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,5 @@ notebooks/saved-results/out
**/*.bbl
**/*.blg
**/*.out
auxiliary_packages/ibex_tests/num_constraint_test
auxiliary_packages/ibex_tests/num_constraint_test.o
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Version information."""

# The following line *must* be the last in the module, exactly as formatted:
__version__ = "1.8.0"
__version__ = "1.9.0"
2 changes: 1 addition & 1 deletion auxiliary_packages/funman_demo/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
license="MIT",
packages=find_packages("src"),
package_dir={"": "src"},
install_requires=["funman", "matplotlib", "jupyter"],
install_requires=["funman", "matplotlib", "jupyter", "seaborn"],
tests_require=["unittest"],
zip_safe=False,
)
2 changes: 1 addition & 1 deletion auxiliary_packages/funman_demo/src/funman_demo/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Version information."""

# The following line *must* be the last in the module, exactly as formatted:
__version__ = "1.8.0"
__version__ = "1.9.0"
3 changes: 3 additions & 0 deletions auxiliary_packages/funman_demo/src/funman_demo/box_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def plot_add_patch(self, box: Box, color="r"):
linewidth=1,
edgecolor=color,
facecolor="none",
zorder=box.timestep().lb * box.timestep().lb,
)

# Add the patch to the Axes
Expand All @@ -235,6 +236,7 @@ def plot_add_point(self, point: Point, color="r", shape="x", alpha=0.2):
marker=shape,
alpha=alpha,
s=3,
zorder=point.timestep(),
)
self.fig.canvas.draw()
self.fig.canvas.flush_events()
Expand Down Expand Up @@ -311,6 +313,7 @@ def plotNDBox(self, box, color="g", alpha=0.2):
y_limits.ub,
color=color,
alpha=alpha,
zorder=box.timestep().lb * box.timestep().lb,
)
plt.show(block=False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import pandas as pd
import seaborn as sns
from IPython.display import HTML
from sklearn import preprocessing

from funman.server.query import FunmanResults

# from sklearn import preprocessing


def animate_heat_map(my_df, frames):
fig = plt.figure()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Dict
from typing import Dict, List

import matplotlib.pyplot as plt
import numpy as np
Expand All @@ -15,6 +15,7 @@ class ParameterSpacePlotter:
def __init__(
self,
parameter_space: ParameterSpace,
boxes: List[Box] = None,
plot_bounds: Box = None,
title: str = "Feasible Regions",
color_map: Dict[str, str] = {
Expand All @@ -27,23 +28,21 @@ def __init__(
plot_points=False,
parameters=None,
dpi=100,
synthesized_parameters=None,
):
if isinstance(parameter_space, ParameterSpace):
self.ps = parameter_space
else:
# FIXME this is a hack to accept ParameterSpace objects from the openapi client
self.ps = ParameterSpace.model_validate(parameter_space.to_dict())

# TODO this should be easier to access
values = []
true_points = self.ps.true_points()
false_points = self.ps.false_points()
if len(true_points) > 0:
values = true_points[0].values
elif len(false_points) > 0:
values = false_points[0].values
self.boxes = boxes

self.parameters = [k for k in values if parameters and k in parameters]
# Expect that parameters are available in the parameter space
self.parameters = parameters # [k for k in scenario_parameters if parameters and k in parameters]
self.synthesized_parameters = (
synthesized_parameters if synthesized_parameters else None
)
self.dim = len(self.parameters)
self.plot_points = plot_points

Expand Down Expand Up @@ -80,7 +79,7 @@ def initialize_figure(self, plot_diagonal):
dim_to_plot,
squeeze=False,
dpi=self.dpi,
figsize=(10, 10),
figsize=(20, 20),
)
self.fig = fig
self.axs = axs
Expand All @@ -90,15 +89,16 @@ def initialize_figure(self, plot_diagonal):
MEDIUM_SIZE = 10
BIGGER_SIZE = 12

plt.rc("font", size=SMALL_SIZE) # controls default text sizes
# plt.rc("font", size=SMALL_SIZE) # controls default text sizes
plt.rc("axes", titlesize=SMALL_SIZE) # fontsize of the axes title
plt.rc("axes", labelsize=TINY_SIZE) # fontsize of the x and y labels
plt.rc("xtick", labelsize=TINY_SIZE) # fontsize of the tick labels
plt.rc("ytick", labelsize=TINY_SIZE) # fontsize of the tick labels
plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title
# plt.rc("legend", fontsize=SMALL_SIZE) # legend fontsize
# plt.rc("figure", titlesize=BIGGER_SIZE) # fontsize of the figure title

self.fig.tight_layout(pad=3.0)
# self.fig.tight_layout(pad=3.0)
self.fig.tight_layout(pad=2)
self.data = [[None] * self.dim] * self.dim

for i in range(self.dim):
Expand All @@ -121,28 +121,44 @@ def initialize_figure(self, plot_diagonal):
plt.legend(self.custom_lines, ["true", "false"])

def plot(self, show=False, plot_diagonal=False):
self.initialize_figure(plot_diagonal)
self.initialize_figure((plot_diagonal or len(self.parameters) == 1))
t = "true"
f = "false"
for b in self.ps.false_boxes:
self.plotNDBox(b, self.color_map[f], plot_diagonal=plot_diagonal)
for b in self.ps.true_boxes:
self.plotNDBox(b, self.color_map[t], plot_diagonal=plot_diagonal)
if self.boxes:
for b in self.boxes:
self.plotNDBox(
b,
self.color_map[b.label],
plot_diagonal=(plot_diagonal or len(self.parameters) == 1),
)
else:
for b in self.ps.false_boxes:
self.plotNDBox(
b,
self.color_map[f],
plot_diagonal=(plot_diagonal or len(self.parameters) == 1),
)
for b in self.ps.true_boxes:
self.plotNDBox(
b,
self.color_map[t],
plot_diagonal=(plot_diagonal or len(self.parameters) == 1),
)
if self.plot_points:
for p in self.ps.false_points():
self.plot_add_point(
p,
self.color_map[f],
self.shape_map[f],
plot_diagonal=plot_diagonal,
plot_diagonal=(plot_diagonal or len(self.parameters) == 1),
)
true_points = self.ps.true_points()
for p in true_points:
self.plot_add_point(
p,
self.color_map[t],
self.shape_map[t],
plot_diagonal=plot_diagonal,
plot_diagonal=(plot_diagonal or len(self.parameters) == 1),
)
if show:
plt.show(block=False)
Expand Down Expand Up @@ -174,11 +190,14 @@ def plot_add_point(
marker=shape,
alpha=alpha,
s=10,
zorder=point.timestep(),
)
# self.fig.canvas.draw()
# self.fig.canvas.flush_events()

def plotNDBox(self, box, color="g", alpha=0.2, plot_diagonal=False):
def plotNDBox(
self, box, color="g", alpha=0.2, plot_diagonal=False, max_width=100000
):
for i in range(self.dim):
for j in range(self.dim):
i_coord, j_coord = self.map_param_idx_to_plot_loc(
Expand All @@ -189,6 +208,12 @@ def plotNDBox(self, box, color="g", alpha=0.2, plot_diagonal=False):
if j_coord > i_coord:
continue

if self.synthesized_parameters and (
self.parameters[i] not in self.synthesized_parameters
or self.parameters[j] not in self.synthesized_parameters
):
continue

x_limits = box.bounds[self.parameters[i]]
y_limits = box.bounds[self.parameters[j]]

Expand All @@ -204,16 +229,27 @@ def plotNDBox(self, box, color="g", alpha=0.2, plot_diagonal=False):
else:
# Plot a box
if (
abs(float(x_limits.lb)) < 1000
and abs(float(x_limits.ub)) < 1000
abs(float(x_limits.lb)) < max_width
and abs(float(x_limits.ub)) < max_width
):
x = np.linspace(
float(x_limits.lb), float(x_limits.ub), 1000
float(x_limits.lb), float(x_limits.ub), max_width
)
self.axs[i_coord, j_coord].fill_between(
x,
y_limits.lb,
y_limits.ub,
color=color,
alpha=alpha,
zorder=box.timestep().lb,
)
self.axs[i_coord, j_coord].text(
(x_limits.lb + x_limits.ub) / 2,
(y_limits.lb + y_limits.ub) / 2,
# f"[{box.timestep().lb}, {box.timestep().ub}]",
f"{box.timestep().lb}",
ha="center",
va="center",
fontsize=8,
color="blue",
)
66 changes: 51 additions & 15 deletions auxiliary_packages/funman_demo/src/funman_demo/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Dict

import matplotlib.pyplot as plt
from funman_demo.parameter_space_plotter import ParameterSpacePlotter
from IPython.display import clear_output
from matplotlib.lines import Line2D

Expand Down Expand Up @@ -68,17 +69,19 @@ def plot_cached_search(search_path, alpha: float = 0.2):
)


def summarize_results(variables, results, ylabel="Height"):
def summarize_results(
variables,
results,
ylabel="Height",
parameters_to_plot=None,
label_color={"true": "g", "false": "r"},
synthesized_parameters=None,
print_last_time=False,
) -> str:
points = results.points()
boxes = results.parameter_space.boxes()

l.info("*" * 80)
l.info("*" * 80)
l.info("* Analysis Summary ")
l.info("*" * 80)
l.info(
f"{len(points)} Points (+:{len(results.parameter_space.true_points())}, -:{len(results.parameter_space.false_points())}), {len(boxes)} Boxes (+:{len(results.parameter_space.true_boxes)}, -:{len(results.parameter_space.false_boxes)})"
)
point_info = ""
if points and len(points) > 0:
point: Point = points[-1]
parameters: Dict[Parameter, float] = results.point_parameters(point)
Expand All @@ -88,15 +91,48 @@ def summarize_results(variables, results, ylabel="Height"):
xlabel="Time",
ylabel=ylabel,
legend=variables,
label_color={"true": "g", "false": "r"},
label_color=label_color,
)
parameter_values = {p: point.values[p.name] for p in parameters}
l.info(f"Parameters = {parameter_values}")
l.info(parameters)
l.info(results.dataframe([point]))
point_info = f"""Parameters = {parameter_values}
# {parameters}
{results.dataframe([point])}
"""
else:
# if there are no points, then we have a box that we found without needing points
l.info(f"Found box with no points")
box = boxes[0]
l.info(json.dumps(box.explain(), indent=4))
l.info("*" * 80)
point_info = f"""Found box with no points
{json.dumps(box.explain(), indent=4)}
"""

boxes = (
results.parameter_space.boxes()
if not print_last_time
else results.parameter_space.last_boxes()
)

if parameters_to_plot is None:
parameters_to_plot = results.model._parameter_names()
if not print_last_time:
parameters_to_plot += ["timestep"]
if len(boxes) > 0 and len(parameters_to_plot) > 1:
ParameterSpacePlotter(
results.parameter_space,
parameters=parameters_to_plot,
dpi=len(parameters_to_plot) * 20,
plot_points=True,
synthesized_parameters=synthesized_parameters,
).plot(show=True)

divider = "*" * 80

summary = f"""{divider}
{divider}
* Analysis Summary
{divider}
{len(points)} Points (+:{len(results.parameter_space.true_points())}, -:{len(results.parameter_space.false_points())}), {len(boxes)} Boxes (+:{len(results.parameter_space.true_boxes)}, -:{len(results.parameter_space.false_boxes)})
{point_info}
{divider}
"""

return summary
2 changes: 1 addition & 1 deletion auxiliary_packages/funman_dreal/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
packages=find_packages("src"),
package_dir={"": "src"},
install_requires=["funman", "docker", "tenacity", "pyparsing"],
extras_require={"dreal": ["dreal"]},
# extras_require={"dreal": ["dreal"]},
tests_require=["unittest"],
zip_safe=False,
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Version information."""

# The following line *must* be the last in the module, exactly as formatted:
__version__ = "1.8.0"
__version__ = "1.9.0"
Loading

0 comments on commit 553e8db

Please sign in to comment.