From 49e3249f6a61ebd1765d0e2483a8bf5d3d919943 Mon Sep 17 00:00:00 2001 From: Kristina Thieme Date: Mon, 22 Jan 2024 15:28:54 +0100 Subject: [PATCH] plugin docstrings revised --- deepcave/plugins/__init__.py | 162 ++++++++++-------- deepcave/plugins/budget/budget_correlation.py | 2 - deepcave/plugins/dynamic.py | 24 ++- deepcave/plugins/static.py | 33 +++- deepcave/plugins/summary/__init__.py | 2 +- deepcave/plugins/summary/configurations.py | 2 - deepcave/plugins/summary/footprint.py | 77 ++++++--- deepcave/plugins/summary/overview.py | 27 +-- 8 files changed, 200 insertions(+), 129 deletions(-) diff --git a/deepcave/plugins/__init__.py b/deepcave/plugins/__init__.py index b0463ef4..f7ee665f 100644 --- a/deepcave/plugins/__init__.py +++ b/deepcave/plugins/__init__.py @@ -51,13 +51,15 @@ class Plugin(Layout, ABC): outputs : List[Tuple[str, str, bool]] The registered outputs. previous_inputs : Dict[str, Dict[str, str]] - The previous inputs for the runtime. + The previous inputs. raw_outputs : Optional[Dict[str, Any]] The raw outputs. activate_run_selection : bool - Whether to activate the run selection. + Shows a dropdown to select a run in the inputs layout. + This feature is useful if only one run could be viewed at a time. + Moreover, it prevents the plugin to calculate results across all runs. id : str - The id of the plugin. + The unique identifier for the plugin. runs : List[AbstractRun] A list of the abstract runs. groups : List[Group] @@ -66,8 +68,9 @@ class Plugin(Layout, ABC): The path to the documentation. name : str The name of the plugin. + It is shown in the navigation and title. button_caption : str - The caption of the plugin button. + Caption of the button. Shown only, if `StaticPlugin` is used. """ id: str @@ -177,7 +180,7 @@ def register_input( id : str Specifies the id of the input. attributes : Union[str, List[str]], optional - Attributes which should be passed to the (dash) component, by default ("value",) + Attributes which should be passed to the (dash) component, by default ("value",). filter : bool, optional Specifies if the input is a filter. By default False. type : Any, optional @@ -286,21 +289,7 @@ def register_callbacks(self) -> None: @app.callback(outputs, inputs) # type: ignore def plugin_input_update(pathname: str, *inputs_list: str) -> List[Optional[str]]: - """ - Update the input of the plugin. - - Parameters - ---------- - pathname : str - The name of the path for the passed inputs. - *inputs_list : str - The list of the inputs to check if the page was loaded for the first time. - - Returns - ------- - List[str] - The list of the cast inputs. - """ + """Update the input of the plugin.""" # Simple check if page was loaded for the first time init = all(input is None for input in inputs_list) @@ -442,21 +431,7 @@ def plugin_input_update(pathname: str, *inputs_list: str) -> List[Optional[str]] State(self.get_internal_id("raw_data"), "is_open"), ) def toggle_raw_data_modal(n: Optional[int], is_open: bool) -> Tuple[bool, str]: - """ - Toggle the raw data modal. - - Parameters - ---------- - n : Optional[int] - A condition. - is_open : bool - Whether the raw data modal is open or not. - - Returns - ------- - Tuple[bool, str] - A tuple containing the is open information and the code. - """ + """Toggle the raw data modal.""" code = "" if n: if (out := self.raw_outputs) is not None: @@ -476,21 +451,7 @@ def toggle_raw_data_modal(n: Optional[int], is_open: bool) -> Tuple[bool, str]: State(self.get_internal_id("help"), "is_open"), ) def toggle_help_modal(n: Optional[int], is_open: bool) -> bool: - """ - Toggle the help modal. - - Parameters - ---------- - n : Optional[int] - A condition. - is_open : bool - Whether the help modal is open or not. - - Returns - ------- - Tuple[bool, str] - A tuple containing the is open information and the code. - """ + """Toggle the help modal.""" if n: return not is_open return is_open @@ -504,14 +465,7 @@ def toggle_help_modal(n: Optional[int], is_open: bool) -> bool: Input(internal_id, "clickData"), ) # type: ignore def go_to_configuration(click_data: Any): - """ - Go to the configuration described in the hovertext. - - Parameters - ---------- - click_data : Any - The data describing the click. - """ + """Open link from hovertext.""" if click_data is not None: # Get hovertext try: @@ -759,7 +713,7 @@ def _dict_as_key(self, d: Dict[str, Any], remove_filters: bool = False) -> str: def _cast_inputs(self, inputs: Dict[str, Dict[str, str]]) -> Dict[str, Dict[str, str]]: """ - Casts the inputs based on `self.inputs`. + Cast the inputs based on `self.inputs`. Background is that dash always casts integers/booleans to strings. This method ensures that the correct types are returned. @@ -810,7 +764,8 @@ def _clean_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: Parameters ---------- - inputs (dict): Inputs to clean. + inputs : Dict[str, Any] + Inputs to clean. Returns ------- @@ -839,7 +794,14 @@ def _clean_inputs(self, inputs: Dict[str, Any]) -> Dict[str, Any]: @property @interactive def runs(self) -> List[AbstractRun]: - """Get the runs as a list.""" + """ + Get the runs as a list. + + Returns + ------- + List[AbstractRun] + The list with the runs. + """ from deepcave import run_handler return run_handler.get_runs() @@ -847,7 +809,14 @@ def runs(self) -> List[AbstractRun]: @property @interactive def groups(self) -> List[Group]: - """Get the groups as a list.""" + """ + Get the groups as a list. + + Returns + ------- + List[Group] + The list with the groups. + """ from deepcave import run_handler return run_handler.get_groups() @@ -855,7 +824,14 @@ def groups(self) -> List[Group]: @property @interactive def all_runs(self) -> List[AbstractRun]: - """Get all runs and include the groups as a list.""" + """ + Get all runs and include the groups as a list. + + Returns + ------- + List[AbstractRun] + The list with all runs and included groups. + """ from deepcave import run_handler return run_handler.get_runs(include_groups=True) @@ -863,7 +839,7 @@ def all_runs(self) -> List[AbstractRun]: @interactive def __call__(self, render_button: bool = False) -> List[Component]: """ - Create and return the components for the plugin. + Return the components for the plugin. Basically, all blocks and elements of the plugin are stacked-up here. @@ -880,9 +856,9 @@ def __call__(self, render_button: bool = False) -> List[Component]: Raises ------ NotMergeableError - If runs are not compatible, an error is thrown. + If runs are not compatible. FileNotFoundError - If the help file is not found, an error is thrown. + If the help file can not be found. """ from deepcave import c, notification @@ -981,7 +957,25 @@ def __call__(self, render_button: bool = False) -> List[Component]: ] def register_in(a: str, b: Union[List[str], str]) -> str: - """Register the given input.""" + """ + Register the given input. + + Note + ---- + For more information, see 'register_input'. + + Parameters + ---------- + a : str + Specifies the id of the input. + b : Union[List[str], str] + Attributes which should be passed to the (dash) component, by default ("value",). + + Returns + ------- + str + Unique id for the input and plugin. This is necessary because ids are defined globally. + """ return self.register_input(a, b, filter=True) filter_layout = self.__class__.get_filter_layout(register_in) @@ -1006,7 +1000,25 @@ def register_in(a: str, b: Union[List[str], str]) -> str: ] def register_out(a: str, b: Union[List[str], str]) -> str: - """Register the output.""" + """ + Register the output. + + Note + ---- + For more information, see 'register_output' + + Parameters + ---------- + a : str + Specifies the id of the output. + b : Union[List[str], str] + Attribute. + + Returns + ------- + str + Unique id for the output and plugin. This is necessary because ids are defined globally. + """ return self.register_output(a, b, mpl=True) output_layout = self.__class__.get_mpl_output_layout(register_out) @@ -1077,7 +1089,7 @@ def get_run_input_layout(register: Callable) -> Component: ---------- register : Callable The register method to register (user) variables. - The register_input function is located in the Plugin superclass. + For more information, see 'register_input'. Returns ------- @@ -1253,7 +1265,7 @@ def get_input_layout(register: Callable) -> List[Component]: ---------- register : Callable The register method to register (user) variables. - The register_input function is located in the Plugin superclass. + For more information, see 'register_input'. Returns ------- @@ -1269,9 +1281,9 @@ def get_filter_layout(register: Callable) -> List[Component]: Parameters ---------- - register : Callable[ + register : Callable The register method to register (user) variables. - The register_input function is located in the Plugin superclass. + For more information, see 'register_input'. Returns ------- @@ -1289,7 +1301,7 @@ def get_output_layout(register: Callable) -> Optional[Union[Component, List[Comp ---------- register : Callable The register method to register outputs. - The register_input function is located in the Plugin superclass. + For more information, see 'register_input'. Returns ------- @@ -1307,7 +1319,7 @@ def get_mpl_output_layout(register: Callable) -> Optional[Union[Component, List[ ---------- register : Callable The register method to register outputs. - The register_input function is located in the Plugin superclass. + For more information, see 'register_input'. Returns ------- @@ -1323,7 +1335,7 @@ def load_outputs( outputs: Dict[str, Union[str, Dict[str, str]]], ) -> Union[Component, List[Component]]: """ - Read in the raw data and prepares them for the layout. + Read in the raw data and prepare them for the layout. Note ---- diff --git a/deepcave/plugins/budget/budget_correlation.py b/deepcave/plugins/budget/budget_correlation.py index f758d8a5..7ac9cc3d 100644 --- a/deepcave/plugins/budget/budget_correlation.py +++ b/deepcave/plugins/budget/budget_correlation.py @@ -242,8 +242,6 @@ def load_outputs(run, _, outputs) -> List[Any]: compared to 'load_inputs' or 'load_dependency_inputs'. Please see '_clean_inputs' for more information. - The returned components must be in the same position as defined in 'get_output_layout'. - Parameters ---------- run diff --git a/deepcave/plugins/dynamic.py b/deepcave/plugins/dynamic.py index a0cab471..edbc1e8d 100644 --- a/deepcave/plugins/dynamic.py +++ b/deepcave/plugins/dynamic.py @@ -49,7 +49,13 @@ def __init__(self) -> None: @interactive def register_callbacks(self) -> None: - """Register the callbacks and update the outputs from the inputs.""" + """ + Register basic callbacks for the plugin. + Following callbacks are registered: + - If inputs changes, the changes are pasted back. This is in particular interest if input dependencies are used. + - Raw data dialog to display raw data. + - Callback to be redirected to the config if clicked on it. + """ super().register_callbacks() from deepcave import app, c, rc @@ -65,12 +71,12 @@ def register_callbacks(self) -> None: @app.callback(outputs, inputs) # type: ignore def plugin_output_update(_: Any, *inputs_list: str) -> Any: """ - Update the outputs from the inputs. + Update the outputs. Parameters ---------- *inputs_list - Values from user. + Input values from user. Returns ------- @@ -111,5 +117,15 @@ def plugin_output_update(_: Any, *inputs_list: str) -> Any: @interactive # Return type does not match the superclass - def __call__(self) -> List[Component]: # noqa: D102 + def __call__(self) -> List[Component]: + """ + Return the components for the plugin. + + Basically, all blocks and elements of the plugin are stacked-up here. + + Returns + ------- + List[Component] + Layout as list of components. + """ return super().__call__(False) diff --git a/deepcave/plugins/static.py b/deepcave/plugins/static.py index 373a03af..482454ff 100644 --- a/deepcave/plugins/static.py +++ b/deepcave/plugins/static.py @@ -44,7 +44,9 @@ def _process( process: Callable[[AbstractRun, Any], None], run: AbstractRun, inputs: Dict[str, Any] ) -> None: """ - Process the run if possible. + Process the run with the input data if possible. + + Return raw data based on a run and input data. Parameters ---------- @@ -53,7 +55,7 @@ def _process( run : AbstractRun The run. inputs : Dict[str, Any] - The inputs as a dictionary + The inputs as a dictionary. Raises ------ @@ -71,6 +73,7 @@ class StaticPlugin(Plugin, ABC): """ Provide a static plugin object. + Calculation with queue. Made for time-consuming tasks. Register and handle callbacks. Properties @@ -88,7 +91,7 @@ class StaticPlugin(Plugin, ABC): name : str The name of the plugin. process : Callable - Returns raw data based on a run and input data. + Return raw data based on a run and input data. button_caption : str The caption for the button. """ @@ -280,7 +283,14 @@ def _callback_loop_trigger_main_loop(self) -> None: # prevent output updates from previous callback calls. @app.callback(output, inputs) # type: ignore def plugin_check_blocked(_: Any, data: Any) -> Any: - """Check if blocked.""" + """ + Check if blocked. + + Raises + ------ + PreventUpdate + If '_blocked' is True. + """ if self._blocked: raise PreventUpdate @@ -289,7 +299,6 @@ def plugin_check_blocked(_: Any, data: Any) -> Any: @interactive def _callback_loop_update_status_label(self) -> None: - """Set up a callback function that indirectly influences the behavior of the main loop.""" from deepcave import app, notification output = [ @@ -357,7 +366,7 @@ def _get_job_id(self, run_name: str, inputs_key: str) -> str: Parameters ---------- run_name : str - The run name. + The name of the run. inputs_key : str The inputs key. @@ -370,7 +379,17 @@ def _get_job_id(self, run_name: str, inputs_key: str) -> str: @interactive # Return type does not match the superclass - def __call__(self) -> List[Component]: # noqa: D102 + def __call__(self) -> List[Component]: + """ + Return the components for the plugin. + + Basically, all blocks and elements of the plugin are stacked-up here. + + Returns + ------- + List[Component] + Layout as list of components. + """ from deepcave import config self._setup() diff --git a/deepcave/plugins/summary/__init__.py b/deepcave/plugins/summary/__init__.py index 79491477..2a11ffac 100644 --- a/deepcave/plugins/summary/__init__.py +++ b/deepcave/plugins/summary/__init__.py @@ -9,5 +9,5 @@ footprint This module provides utilities to visualize a configuration footprint. overview - This module provides utilities for visualizing an overview of an optimization run. + This module provides utilities for visualizing an overview of the selected run. """ diff --git a/deepcave/plugins/summary/configurations.py b/deepcave/plugins/summary/configurations.py index e9bebf1a..1cf80a49 100644 --- a/deepcave/plugins/summary/configurations.py +++ b/deepcave/plugins/summary/configurations.py @@ -461,8 +461,6 @@ def load_outputs(run, inputs, outputs) -> List[Any]: The passed inputs are cleaned and therefore differs compared to 'load_inputs' or 'load_dependency_inputs'. Please see '_clean_inputs' for more information. - The returned components must be in the same position as defined in 'get_output_layout'. - Parameters ---------- run diff --git a/deepcave/plugins/summary/footprint.py b/deepcave/plugins/summary/footprint.py index e7cd428b..7e7c9c19 100644 --- a/deepcave/plugins/summary/footprint.py +++ b/deepcave/plugins/summary/footprint.py @@ -170,20 +170,27 @@ def load_inputs(self) -> Dict[str, Dict[str, Any]]: } # Types dont match superclass - def load_dependency_inputs(self, run, previous_inputs, inputs): + def load_dependency_inputs(self, run, previous_inputs, inputs) -> Dict[str, Any]: """ - Load the objectives, budgets and their attributes. + Same as 'load_inputs' but called after inputs have changed. + + Note + ---- + Only the changes have to be returned. The returned dictionary will be merged with the inputs. Parameters ---------- run : - The run(s) to be analyzed. + The selected run. + previous_inputs : + Previous content of the inputs. inputs : - Contains information about the objectives and budgets. + Current content of the inputs. Returns ------- - The objective, budgets and their attributes. + Dict[str, Any] + The dictionary with the changes. """ # Prepare objectives objective_names = run.get_objective_names() @@ -217,22 +224,30 @@ def load_dependency_inputs(self, run, previous_inputs, inputs): @staticmethod # Types dont match superclass - def process(run, inputs): + def process(run, inputs) -> Dict[str, Any]: """ - Process the data to create different data points. + Return raw data based on a run and input data. + + Warning + ------- + The returned data must be JSON serializable. - These points include, border, incumbent, support, performance, area and configurations. + Note + ---- + The passed inputs are cleaned and therefore differs compared to 'load_inputs' or 'load_dependency_inputs'. + Please see '_clean_inputs' for more information. Parameters ---------- run - The run to be analyzed. + The selected run. inputs - Containing budget, objective and details information. + The input data. Returns ------- - A dictionary of the different data points. + Dict[str, Any] + A serialized dictionary. """ budget = run.get_budget(inputs["budget_id"]) objective = run.get_objective(inputs["objective_id"]) @@ -261,18 +276,18 @@ def process(run, inputs): @staticmethod def get_output_layout(register: Callable) -> dbc.Tabs: """ - Get a dash bootstrap component (DBC) for the output layout. + Get the layout for the output block. Parameters ---------- register : Callable - Used for the id of the dash Graph. + Method for registering outputs. The register_output function is located in the Plugin superclass. Returns ------- dbc.Tabs - A dash bootstrap component (DBC) for the output layout. + The layout for the output block. """ return dbc.Tabs( [ @@ -295,23 +310,26 @@ def get_output_layout(register: Callable) -> dbc.Tabs: # Types dont match superclass def load_outputs(run, inputs, outputs) -> List[Any]: """ - Load and save the output plotly figure for visualizing the footprint of the run. + Read in the raw data and prepare them for the layout. - Get a heatmap for the performance and area data. + Note + ---- + The passed inputs are cleaned and therefore differs compared to 'load_inputs' or 'load_dependency_inputs'. + Please see '_clean_inputs' for more information. Parameters ---------- run - The run to be analyzed. + The selected run. inputs - Containing information about the objective, borders and supports visualization. + Input and filter values from the user. outputs - Containing information about the performance and area data. + Raw output from the run. Returns ------- List[Any] - The plotly figure of the footprint. + The plotly figure of the footprint performance and area. """ objective = run.get_objective(inputs["objective_id"]) show_borders = inputs["show_borders"] @@ -403,18 +421,18 @@ def load_outputs(run, inputs, outputs) -> List[Any]: @staticmethod def get_mpl_output_layout(register: Callable) -> List[dbc.Tabs]: """ - Get a dash bootstrap component (DBC) of the output layout. + Get the layout for the matplotlib output block. Parameters ---------- register : Callable - Used for the id of the html image container. + Method to register the outputs. The register_output function is located in the Plugin superclass. Returns ------- List[dbc.Tabs] - A dash bootstrap component (DBC) of the output layout + The layout for the output block. """ return [ dbc.Tabs( @@ -435,16 +453,21 @@ def get_mpl_output_layout(register: Callable) -> List[dbc.Tabs]: # Types dont match superclass def load_mpl_outputs(run, inputs, outputs): """ - Load the rendered matplotlib figure of the footprint. + Read in the raw data and prepare them for the layout. + + Note + ---- + The passed inputs are cleaned and therefore differs compared to 'load_inputs' or 'load_dependency_inputs'. + Please see '_clean_inputs' for more information. Parameters ---------- run - The run to be analyzed. + The selected run. inputs - Containing information about the objective, borders and supports visualization. + Input and filter values from the user. outputs - Containing information about the data. + Raw outputs from the run. Returns ------- diff --git a/deepcave/plugins/summary/overview.py b/deepcave/plugins/summary/overview.py index 38f65b52..a241d4af 100644 --- a/deepcave/plugins/summary/overview.py +++ b/deepcave/plugins/summary/overview.py @@ -2,12 +2,14 @@ """ # Overview -This module provides utilities for visualizing an overview of an optimization run. +This module provides utilities for visualizing an overview of the selected runs. + +It holds the most important information, e.g. meta data, objectives and statistics. The module includes a dynamic plugin for the overview. ## Classes - - Overview: Visualize an overall overview of a run. + - Overview: Visualize an overall overview of the selected run. """ from typing import Any, Callable, Dict, List @@ -37,7 +39,7 @@ class Overview(DynamicPlugin): - """Visualize an overall overview of a run.""" + """Visualize an overall overview of the selected run.""" id = "overview" name = "Overview" @@ -49,18 +51,18 @@ class Overview(DynamicPlugin): @staticmethod def get_output_layout(register: Callable) -> List[Any]: """ - Get an html container with the output layout. + Get the layout for the output block. Parameters ---------- register : Callable - Used for the id of the html Div object, as well as the dash Graph. + Method to register the outputs. The register_input function is located in the Plugin superclass. Returns ------- List[Any] - An html container with the output layout + The layouts for the output block. """ return [ html.Div( @@ -104,19 +106,22 @@ def get_output_layout(register: Callable) -> List[Any]: # Types dont match superclass def load_outputs(run, *_: Any) -> List[Any]: """ - Load the outputs for the overview of the run. - - A dash card for quick information is provided. + Read in the raw data and prepare them for the layout. + + Note + ---- + The passed inputs are cleaned and therefore differs compared to 'load_inputs' or 'load_dependency_inputs'. + Please see '_clean_inputs' for more information. Parameters ---------- run - The run to be analyzed for an overview. + The selected run. Returns ------- List[Any] - A list of dash figures and tables containing the overviews information. + A list of the created tables of the overview. """ # Get best cost across all objectives, highest budget incumbent, _ = run.get_incumbent()