diff --git a/deepcave/plugins/objective/cost_over_time.py b/deepcave/plugins/objective/cost_over_time.py index a4fbd30d..c505d5cb 100644 --- a/deepcave/plugins/objective/cost_over_time.py +++ b/deepcave/plugins/objective/cost_over_time.py @@ -6,9 +6,10 @@ from dash import dcc, html from dash.exceptions import PreventUpdate -from deepcave import config +from deepcave import config, notification from deepcave.plugins.dynamic import DynamicPlugin from deepcave.runs import AbstractRun, check_equality +from deepcave.runs.exceptions import NotMergeableError, RunInequality from deepcave.utils.layout import get_select_options, help_button from deepcave.utils.styled_plotty import ( get_color, @@ -24,8 +25,19 @@ class CostOverTime(DynamicPlugin): help = "docs/plugins/cost_over_time.rst" def check_runs_compatibility(self, runs: List[AbstractRun]) -> None: - check_equality(runs, objectives=True, budgets=True) - + try: + check_equality(runs, objectives=True, budgets=True) + except NotMergeableError as e: + run_inequality = e.args[1] + if run_inequality == RunInequality.INEQ_BUDGET: + notification.update("The budgets of the runs are not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_CONFIGSPACE: + notification.update("The configuration spaces of the runs are not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_META: + notification.update("The meta data of the runs is not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_OBJECTIVE: + notification.update("The objectives of the runs are not equal.", color="warning") + # Set some attributes here run = runs[0] diff --git a/deepcave/plugins/objective/pareto_front.py b/deepcave/plugins/objective/pareto_front.py index 17e55a39..7b148115 100644 --- a/deepcave/plugins/objective/pareto_front.py +++ b/deepcave/plugins/objective/pareto_front.py @@ -5,9 +5,10 @@ import plotly.graph_objs as go from dash import dcc, html -from deepcave import config +from deepcave import config, notification from deepcave.plugins.dynamic import DynamicPlugin from deepcave.runs import Status, check_equality +from deepcave.runs.exceptions import NotMergeableError, RunInequality from deepcave.utils.layout import get_select_options, help_button from deepcave.utils.styled_plot import plt from deepcave.utils.styled_plotty import ( @@ -24,7 +25,18 @@ class ParetoFront(DynamicPlugin): help = "docs/plugins/pareto_front.rst" def check_runs_compatibility(self, runs): - check_equality(runs, objectives=True, budgets=True) + try: + check_equality(runs, objectives=True, budgets=True) + except NotMergeableError as e: + run_inequality = e.args[1] + if run_inequality == RunInequality.INEQ_BUDGET: + notification.update("The budgets of the runs are not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_CONFIGSPACE: + notification.update("The configuration spaces of the runs are not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_META: + notification.update("The meta data of the runs is not equal.", color="warning") + elif run_inequality == RunInequality.INEQ_OBJECTIVE: + notification.update("The objectives of the runs are not equal.", color="warning") # Set some attributes here run = runs[0] diff --git a/deepcave/runs/__init__.py b/deepcave/runs/__init__.py index 7443f84f..fb69b3ad 100644 --- a/deepcave/runs/__init__.py +++ b/deepcave/runs/__init__.py @@ -20,7 +20,7 @@ CONSTANT_VALUE, NAN_VALUE, ) -from deepcave.runs.exceptions import NotMergeableError +from deepcave.runs.exceptions import NotMergeableError, RunInequality from deepcave.runs.objective import Objective from deepcave.runs.status import Status from deepcave.runs.trial import Trial @@ -919,6 +919,7 @@ def check_equality( Dict[str, Any] Dictionary containing the checked attributes. """ + result = {} if len(runs) == 0: @@ -938,7 +939,7 @@ def check_equality( continue if k not in m2 or m2[k] != v: - raise NotMergeableError("Meta data of runs are not equal.") + raise NotMergeableError("Meta data of runs are not equal.", RunInequality.INEQ_META) result["meta"] = m1 @@ -950,7 +951,7 @@ def check_equality( for run in runs: cs2 = run.configspace if cs1 != cs2: - raise NotMergeableError("Configspace of runs are not equal.") + raise NotMergeableError("Configspace of runs are not equal.", RunInequality.INEQ_CONFIGSPACE) result["configspace"] = cs1 @@ -960,7 +961,7 @@ def check_equality( for run in runs: b2 = run.get_budgets(include_combined=False) if b1 != b2: - raise NotMergeableError("Budgets of runs are not equal.") + raise NotMergeableError("Budgets of runs are not equal.", RunInequality.INEQ_BUDGET) result["budgets"] = b1 if meta: @@ -977,7 +978,7 @@ def check_equality( continue if len(o1) != len(o2): - raise NotMergeableError("Objectives of runs are not equal.") + raise NotMergeableError("Objectives of runs are not equal.", RunInequality.INEQ_OBJECTIVE) for o1_, o2_ in zip(o1, o2): o1_.merge(o2_) @@ -987,4 +988,4 @@ def check_equality( if meta: result["meta"]["objectives"] = serialized_objectives - return result + return result \ No newline at end of file diff --git a/deepcave/runs/exceptions.py b/deepcave/runs/exceptions.py index aefe3a20..14cd2ec3 100644 --- a/deepcave/runs/exceptions.py +++ b/deepcave/runs/exceptions.py @@ -1,3 +1,4 @@ +from enum import Enum class NotValidRunError(Exception): """Raised if directory is not a valid run.""" @@ -8,3 +9,13 @@ class NotMergeableError(Exception): """Raised if two or more runs are not mergeable""" pass + +class RunInequality(Enum): + """Check why runs were not compatible.""" + INEQ_META = 1 + INEQ_OBJECTIVE = 2 + INEQ_BUDGET = 3 + INEQ_CONFIGSPACE = 4 + + +