rtc-tools-interface 0.4.4__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/PKG-INFO +1 -1
  2. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/README.md +13 -0
  3. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtc_tools_interface.egg-info/PKG-INFO +1 -1
  4. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtc_tools_interface.egg-info/SOURCES.txt +1 -0
  5. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/_version.py +3 -3
  6. rtc-tools-interface-0.5.0/rtctools_interface/optimization/goal_generator_mixin.py +96 -0
  7. rtc-tools-interface-0.5.0/rtctools_interface/optimization/goal_performance_metrics.py +117 -0
  8. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plot_goals_mixin.py +38 -99
  9. rtc-tools-interface-0.4.4/rtctools_interface/optimization/goal_generator_mixin.py +0 -46
  10. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/COPYING.LESSER +0 -0
  11. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtc_tools_interface.egg-info/dependency_links.txt +0 -0
  12. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtc_tools_interface.egg-info/requires.txt +0 -0
  13. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtc_tools_interface.egg-info/top_level.txt +0 -0
  14. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/__init__.py +0 -0
  15. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/__init__.py +0 -0
  16. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/base_goal.py +0 -0
  17. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/base_optimization_problem.py +0 -0
  18. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/goal_table_schema.py +0 -0
  19. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plot_and_goal_schema.py +0 -0
  20. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plot_table_schema.py +0 -0
  21. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plotting/__init__.py +0 -0
  22. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plotting/plot_tools.py +0 -0
  23. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/plotting/subplot_classes.py +0 -0
  24. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/read_goals.py +0 -0
  25. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/read_plot_table.py +0 -0
  26. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/optimization/type_definitions.py +0 -0
  27. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/rtctools_interface/utils/__init__.py +0 -0
  28. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/setup.cfg +0 -0
  29. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/setup.py +0 -0
  30. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/__init__.py +0 -0
  31. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/__init__.py +0 -0
  32. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/get_test.py +0 -0
  33. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/test_base_optimization_problem.py +0 -0
  34. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/test_passing_goals_directly.py +0 -0
  35. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/test_plot_goals_mixin.py +0 -0
  36. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/tests/optimization/test_read_goals.py +0 -0
  37. {rtc-tools-interface-0.4.4 → rtc-tools-interface-0.5.0}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rtc-tools-interface
3
- Version: 0.4.4
3
+ Version: 0.5.0
4
4
  Summary: Toolbox for user interfaces for RTC-Tools
5
5
  Home-page: UNKNOWN
6
6
  Author: Deltares
@@ -96,6 +96,19 @@ See the table below for an example content of the `goal_table.csv`.
96
96
  | goal_2 | reservoir_2_waterlevel | 1 | range | 0 | 15 | 10 | timeseries | "target_series" | "target_series" | 10 | | |
97
97
  | goal_3 | electricity_cost | 1 | minimization_path | | | | | | | 20 | | |
98
98
 
99
+ ## Goal performance metrics
100
+ For all goals defined with the goal generator this rtc-tools-interface module will also calculate performance metrics. By default, these performance metrics are saved to a .csv in the folder `output/perfomance_metrics`, with one csv file per goal. With the class variable `calculate_performance_metrics` this functionality can be disabled (by default it is enabled).
101
+
102
+ The calculated metrics are:
103
+ - `timeseries_sum`: The sum of the state variable over all timesteps.
104
+ - `timeseries_min`: The minimum of the state variable.
105
+ - `timeseries_max`: The maximum of the state variable.
106
+ - `timeseries_avg`: The average of the state variable.
107
+ - `max_difference`: The maximum difference in one timestep.
108
+ - `mean_absolute_percentual_difference`: The mean of the absolute percentual difference per timestep over all timesteps (only for range goals).
109
+ - `mean_absolute_difference`: The mean absolute difference per timestep of the state variable over all timesteps (only for range goals).
110
+
111
+
99
112
  ## Automatic plotting of results
100
113
  With the `PlotGoalsMixin` one can easily make plots of the results of rtc-tools. To utilize this functionality, import the mixin as follows:
101
114
  ```python
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rtc-tools-interface
3
- Version: 0.4.4
3
+ Version: 0.5.0
4
4
  Summary: Toolbox for user interfaces for RTC-Tools
5
5
  Home-page: UNKNOWN
6
6
  Author: Deltares
@@ -14,6 +14,7 @@ rtctools_interface/optimization/__init__.py
14
14
  rtctools_interface/optimization/base_goal.py
15
15
  rtctools_interface/optimization/base_optimization_problem.py
16
16
  rtctools_interface/optimization/goal_generator_mixin.py
17
+ rtctools_interface/optimization/goal_performance_metrics.py
17
18
  rtctools_interface/optimization/goal_table_schema.py
18
19
  rtctools_interface/optimization/plot_and_goal_schema.py
19
20
  rtctools_interface/optimization/plot_goals_mixin.py
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2023-10-26T13:39:40+0000",
11
+ "date": "2023-10-30T13:58:13+0000",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "efe92f22d84650bb8f0d7caa0c9357809d5b34f9",
15
- "version": "0.4.4"
14
+ "full-revisionid": "34cc7954ac465b9eedd42d7efdea2bf42d26ac19",
15
+ "version": "0.5.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,96 @@
1
+ """Module for a basic optimization problem."""
2
+ from pathlib import Path
3
+ from typing import Dict, Union
4
+ import logging
5
+ import os
6
+ import pandas as pd
7
+
8
+ from rtctools_interface.optimization.base_goal import BaseGoal
9
+ from rtctools_interface.optimization.goal_performance_metrics import get_performance_metrics
10
+ from rtctools_interface.optimization.helpers.statistics_mixin import StatisticsMixin
11
+ from rtctools_interface.optimization.read_goals import read_goals
12
+
13
+ logger = logging.getLogger("rtctools")
14
+
15
+
16
+ def write_performance_metrics(performance_metrics: Dict[str, pd.DataFrame], output_path: Union[str, Path]):
17
+ """Write the performance metrics for each goal to a csv file."""
18
+ output_path = Path(output_path) / "performance_metrics"
19
+ output_path.mkdir(parents=True, exist_ok=True)
20
+ for goal_id, performance_metric_table in performance_metrics.items():
21
+ performance_metric_table.to_csv(output_path / f"{goal_id}.csv")
22
+
23
+
24
+ class GoalGeneratorMixin(StatisticsMixin):
25
+ # TODO: remove pylint disable below once we have more public functions.
26
+ # pylint: disable=too-few-public-methods
27
+ """Add path goals as specified in the goal_table.
28
+
29
+ By default, the mixin looks for the csv in the in the default input
30
+ folder. One can also set the path to the goal_table_file manually
31
+ with the `goal_table_file` class variable.
32
+ """
33
+ calculate_performance_metrics = True
34
+
35
+ def __init__(self, **kwargs):
36
+ super().__init__(**kwargs)
37
+ self.goals_to_generate = kwargs.get("goals_to_generate", [])
38
+ self.read_from = kwargs.get("read_goals_from", "csv_table")
39
+ if not hasattr(self, "goal_table_file"):
40
+ self.goal_table_file = os.path.join(self._input_folder, "goal_table.csv")
41
+
42
+ self._goal_generator_path_goals = read_goals(
43
+ self.goal_table_file, path_goal=True, read_from=self.read_from, goals_to_generate=self.goals_to_generate
44
+ )
45
+ self._goal_generator_non_path_goals = read_goals(
46
+ self.goal_table_file, path_goal=False, read_from=self.read_from, goals_to_generate=self.goals_to_generate
47
+ )
48
+ self._all_goal_generator_goals = self._goal_generator_path_goals + self._goal_generator_non_path_goals
49
+
50
+ if self.calculate_performance_metrics:
51
+ # A dataframe for each goal defined by the goal generator
52
+ self.performance_metrics = {}
53
+ for goal in self._all_goal_generator_goals:
54
+ self.performance_metrics[goal.goal_id] = pd.DataFrame()
55
+
56
+ def path_goals(self):
57
+ """Return the list of path goals."""
58
+ goals = super().path_goals()
59
+ new_goals = self._goal_generator_path_goals
60
+ if new_goals:
61
+ goals = goals + [BaseGoal(optimization_problem=self, **goal.__dict__) for goal in new_goals]
62
+ return goals
63
+
64
+ def goals(self):
65
+ """Return the list of goals."""
66
+ goals = super().goals()
67
+ new_goals = self._goal_generator_non_path_goals
68
+ if new_goals:
69
+ goals = goals + [BaseGoal(optimization_problem=self, **goal.__dict__) for goal in new_goals]
70
+ return goals
71
+
72
+ def store_performance_metrics(self, label):
73
+ """Calculate and store performance metrics."""
74
+ results = self.extract_results()
75
+ goal_generator_goals = self._all_goal_generator_goals
76
+ targets = self.collect_range_target_values(goal_generator_goals)
77
+ for goal in goal_generator_goals:
78
+ next_row = get_performance_metrics(results, goal, targets.get(goal.goal_id))
79
+ if next_row is not None:
80
+ next_row.rename(label, inplace=True)
81
+ self.performance_metrics[goal.goal_id] = pd.concat(
82
+ [self.performance_metrics[goal.goal_id].T, next_row], axis=1
83
+ ).T
84
+
85
+ def priority_completed(self, priority):
86
+ """Tasks after priority optimization."""
87
+ super().priority_completed(priority)
88
+ if self.calculate_performance_metrics:
89
+ self.store_performance_metrics(priority)
90
+
91
+ def post(self):
92
+ """Tasks after all optimization steps."""
93
+ super().post()
94
+ if self.calculate_performance_metrics:
95
+ self.store_performance_metrics("final_results")
96
+ write_performance_metrics(self.performance_metrics, self._output_folder)
@@ -0,0 +1,117 @@
1
+ """This file contains functions to get performance metrics for the BaseGoal."""
2
+ import logging
3
+ from typing import Dict, Optional
4
+
5
+ import pandas as pd
6
+ import numpy as np
7
+
8
+ from rtctools_interface.optimization.goal_table_schema import (
9
+ BaseGoalModel,
10
+ MaximizationGoalModel,
11
+ MinimizationGoalModel,
12
+ RangeGoalModel,
13
+ RangeRateOfChangeGoalModel,
14
+ )
15
+ from rtctools_interface.optimization.type_definitions import TargetDict
16
+
17
+
18
+ logger = logging.getLogger("rtctools")
19
+
20
+ ABS_TOL = 0.001
21
+
22
+
23
+ def get_mean_absolute_percentual_difference(timeseries: np.ndarray) -> float:
24
+ """Calculate the mean absolute percentual difference."""
25
+ differences = np.diff(timeseries)
26
+ mapd = np.mean(np.abs(differences / timeseries[:-1]))
27
+ return mapd
28
+
29
+
30
+ def get_absolute_sum_difference(timeseries: np.ndarray) -> float:
31
+ """Calculate the mean of absolute first-order difference."""
32
+ mad = np.mean(np.abs(np.diff(timeseries)))
33
+ return mad
34
+
35
+
36
+ def get_max_difference(timeseries: np.ndarray) -> float:
37
+ """Get maximum one step difference"""
38
+ return max(np.diff(timeseries))
39
+
40
+
41
+ def get_basic_metrics(timeseries: np.ndarray) -> dict[str, float]:
42
+ """Get general metrics applicable for each goal type."""
43
+ metrics = {
44
+ "timeseries_sum": sum(timeseries),
45
+ "timeseries_min": min(timeseries),
46
+ "timeseries_max": max(timeseries),
47
+ "timeseries_avg": np.mean(timeseries),
48
+ "mean_absolute_percentual_difference": get_mean_absolute_percentual_difference(timeseries),
49
+ "mean_absolute_difference": get_absolute_sum_difference(timeseries),
50
+ "max_difference": get_max_difference(timeseries),
51
+ }
52
+ return metrics
53
+
54
+
55
+ def performance_metrics_minmaximization(results: Dict[str, np.ndarray], goal: MinimizationGoalModel) -> pd.Series:
56
+ """Get all relevant statistics for a min/maximization goal."""
57
+ state_timeseries = results[goal.state]
58
+ metrics = get_basic_metrics(state_timeseries)
59
+ return pd.Series(metrics)
60
+
61
+
62
+ def get_range_percentual_exceedance(
63
+ timeseries: np.ndarray, goal: RangeGoalModel, targets: TargetDict
64
+ ) -> Optional[dict[str, float]]:
65
+ """Calculate percentage of timesteps in which target is exceeded"""
66
+ if goal.goal_type not in ["range", "range_rate_of_change"]:
67
+ below_target = None
68
+ above_target = None
69
+ else:
70
+ below_target = sum(np.where(timeseries + ABS_TOL < targets["target_min"], 1, 0)) / len(timeseries)
71
+ above_target = sum(np.where(timeseries - ABS_TOL > targets["target_max"], 1, 0)) / len(timeseries)
72
+ return {"perc_below_target": below_target, "perc_above_target": above_target}
73
+
74
+
75
+ def get_range_total_exceedance(
76
+ timeseries: np.ndarray, goal: RangeGoalModel, targets: TargetDict
77
+ ) -> Optional[dict[str, float]]:
78
+ """Calculate sum of absolute exceedances of the target"""
79
+ if goal.goal_type not in ["range", "range_rate_of_change"]:
80
+ below_target = None
81
+ above_target = None
82
+ else:
83
+ below_target = sum(np.abs(np.where(timeseries < targets["target_min"], timeseries - targets["target_min"], 0)))
84
+ above_target = sum(np.abs(np.where(timeseries > targets["target_max"], timeseries - targets["target_max"], 0)))
85
+ return {"sum_below_target": below_target, "sum_above_target": above_target}
86
+
87
+
88
+ def performance_metrics_range(results: Dict[str, np.ndarray], goal: RangeGoalModel, targets: TargetDict) -> pd.Series:
89
+ """Get all relevant statistics for a range goal."""
90
+ metrics = {}
91
+ state_timeseries = results[goal.state]
92
+ metrics = metrics | get_basic_metrics(state_timeseries)
93
+ metrics = metrics | get_range_percentual_exceedance(state_timeseries, goal, targets)
94
+ metrics = metrics | get_range_total_exceedance(state_timeseries, goal, targets)
95
+ return pd.Series(metrics)
96
+
97
+
98
+ def performance_metrics_rangerateofchange(
99
+ results: Dict[str, np.ndarray], goal: RangeGoalModel, _targets: TargetDict
100
+ ) -> pd.Series:
101
+ """Get all relevant statistics for a range-rate-of-change goal."""
102
+ metrics = {}
103
+ state_timeseries = results[goal.state]
104
+ metrics = metrics | get_basic_metrics(state_timeseries)
105
+ return pd.Series(metrics)
106
+
107
+
108
+ def get_performance_metrics(results, goal: BaseGoalModel, targets: TargetDict) -> Optional[pd.Series]:
109
+ """Returns a series with performance metrics for each goal."""
110
+ if type(goal) in [MinimizationGoalModel, MaximizationGoalModel]: # pylint: disable=unidiomatic-typecheck
111
+ return performance_metrics_minmaximization(results, goal)
112
+ if type(goal) in [RangeGoalModel]:
113
+ return performance_metrics_range(results, goal, targets)
114
+ if type(goal) in [RangeRateOfChangeGoalModel]:
115
+ return performance_metrics_rangerateofchange(results, goal, targets)
116
+ logger.info("No performance metrics are implemented for goal of type: %s", str(type(goal)))
117
+ return None
@@ -5,17 +5,11 @@ import copy
5
5
  from pathlib import Path
6
6
  import pickle
7
7
  import time
8
- from typing import Union, List, Dict, Optional
8
+ from typing import Optional
9
+
10
+ from rtctools_interface.optimization.helpers.statistics_mixin import StatisticsMixin
9
11
 
10
- import numpy as np
11
12
 
12
- from rtctools_interface.optimization.plot_and_goal_schema import (
13
- MinimizationGoalCombinedModel,
14
- MaximizationGoalCombinedModel,
15
- RangeGoalCombinedModel,
16
- RangeRateOfChangeGoalCombinedModel,
17
- )
18
- from rtctools_interface.optimization.plot_table_schema import PlotTableRow
19
13
  from rtctools_interface.optimization.plotting.plot_tools import create_plot_each_priority, create_plot_final_results
20
14
 
21
15
  from rtctools_interface.optimization.read_plot_table import get_joined_plot_config
@@ -23,7 +17,6 @@ from rtctools_interface.optimization.type_definitions import (
23
17
  PlotDataAndConfig,
24
18
  PlotOptions,
25
19
  PrioIndependentData,
26
- TargetDict,
27
20
  )
28
21
 
29
22
  logger = logging.getLogger("rtctools")
@@ -75,7 +68,7 @@ def read_cache_file_from_folder(cache_folder: Path) -> Optional[PlotDataAndConfi
75
68
  return loaded_data
76
69
 
77
70
 
78
- class PlotGoalsMixin:
71
+ class PlotGoalsMixin(StatisticsMixin):
79
72
  """
80
73
  Class for plotting results.
81
74
  """
@@ -131,98 +124,44 @@ class PlotGoalsMixin:
131
124
  self.intermediate_results.append(to_store)
132
125
  super().priority_completed(priority)
133
126
 
134
- def collect_range_target_values(
135
- self,
136
- all_goals: List[
137
- Union[
138
- MinimizationGoalCombinedModel,
139
- MaximizationGoalCombinedModel,
140
- RangeGoalCombinedModel,
141
- RangeRateOfChangeGoalCombinedModel,
142
- PlotTableRow,
143
- ]
144
- ],
145
- ) -> Dict[str, TargetDict]:
146
- """For the goals with targets, collect the actual timeseries with these targets."""
147
- t = self.times()
148
-
149
- def get_parameter_ranges(goal):
150
- try:
151
- target_min = np.full_like(t, 1) * self.parameters(0)[goal.target_min]
152
- target_max = np.full_like(t, 1) * self.parameters(0)[goal.target_max]
153
- except TypeError:
154
- target_min = np.full_like(t, 1) * self.io.get_parameter(goal.target_min)
155
- target_max = np.full_like(t, 1) * self.io.get_parameter(goal.target_max)
156
- return target_min, target_max
157
-
158
- def get_value_ranges(goal):
159
- target_min = np.full_like(t, 1) * float(goal.target_min)
160
- target_max = np.full_like(t, 1) * float(goal.target_max)
161
- return target_min, target_max
162
-
163
- def get_timeseries_ranges(goal):
164
- if isinstance(goal.target_min, str):
165
- target_min = self.get_timeseries(goal.target_min).values
166
- else:
167
- target_min = np.full_like(t, 1) * goal.target_min
168
- if isinstance(goal.target_max, str):
169
- target_max = self.get_timeseries(goal.target_max).values
170
- else:
171
- target_max = np.full_like(t, 1) * goal.target_max
172
- return target_min, target_max
173
-
174
- target_series: Dict[str, TargetDict] = {}
175
- for goal in all_goals:
176
- if not goal.specified_in == "python" and goal.goal_type in ["range", "range_rate_of_change"]:
177
- if goal.target_data_type == "parameter":
178
- target_min, target_max = get_parameter_ranges(goal)
179
- elif goal.target_data_type == "value":
180
- target_min, target_max = get_value_ranges(goal)
181
- elif goal.target_data_type == "timeseries":
182
- target_min, target_max = get_timeseries_ranges(goal)
183
- else:
184
- message = "Target type {} not known.".format(goal.target_data_type)
185
- logger.error(message)
186
- raise ValueError(message)
187
- target_series[goal.goal_id] = {"target_min": target_min, "target_max": target_max}
188
- return target_series
189
-
190
127
  def post(self):
191
128
  """Tasks after optimizing. Creates a plot for for each priority."""
192
129
  super().post()
193
- prio_independent_data: PrioIndependentData = {
194
- "io_datetimes": self.io.datetimes,
195
- "times": self.times(),
196
- "target_series": self.collect_range_target_values(self.plot_config),
197
- "all_goals": self.goals() + self.path_goals(),
198
- }
199
-
200
- plot_options: PlotOptions = {
201
- "plot_config": self.plot_config,
202
- "plot_max_rows": self.plot_max_rows,
203
- "output_folder": self._output_folder,
204
- "save_plot_to": self.save_plot_to,
205
- }
206
-
207
- current_run: PlotDataAndConfig = {
208
- "intermediate_results": self.intermediate_results,
209
- "plot_options": plot_options,
210
- "prio_independent_data": prio_independent_data,
211
- }
212
-
213
- self.plot_data = {}
214
- if self.plot_results_each_priority:
215
- self.plot_data = self.plot_data | create_plot_each_priority(
216
- current_run, plotting_library=self.plotting_library
217
- )
218
-
219
- if self.plot_final_results:
220
- self.plot_data = self.plot_data | create_plot_final_results(
221
- current_run, self._previous_run, plotting_library=self.plotting_library
222
- )
223
130
 
224
- # Cache results, such that in a next run they can be used for comparison
225
- self._store_current_results(self._cache_folder, current_run)
131
+ if self.solver_stats["success"]:
132
+ prio_independent_data: PrioIndependentData = {
133
+ "io_datetimes": self.io.datetimes,
134
+ "times": self.times(),
135
+ "target_series": self.collect_range_target_values(self.plot_config),
136
+ "all_goals": self.goals() + self.path_goals(),
137
+ }
138
+
139
+ plot_options: PlotOptions = {
140
+ "plot_config": self.plot_config,
141
+ "plot_max_rows": self.plot_max_rows,
142
+ "output_folder": self._output_folder,
143
+ "save_plot_to": self.save_plot_to,
144
+ }
145
+
146
+ current_run: PlotDataAndConfig = {
147
+ "intermediate_results": self.intermediate_results,
148
+ "plot_options": plot_options,
149
+ "prio_independent_data": prio_independent_data,
150
+ }
151
+
152
+ self.plot_data = {}
153
+ if self.plot_results_each_priority:
154
+ self.plot_data = self.plot_data | create_plot_each_priority(
155
+ current_run, plotting_library=self.plotting_library
156
+ )
157
+
158
+ if self.plot_final_results:
159
+ self.plot_data = self.plot_data | create_plot_final_results(
160
+ current_run, self._previous_run, plotting_library=self.plotting_library
161
+ )
162
+
163
+ # Cache results, such that in a next run they can be used for comparison
164
+ self._store_current_results(self._cache_folder, current_run)
226
165
 
227
166
  def _store_current_results(self, cache_folder, results_to_store):
228
167
  write_cache_file(cache_folder, results_to_store)
@@ -1,46 +0,0 @@
1
- """Module for a basic optimization problem."""
2
- import logging
3
- import os
4
-
5
- from rtctools_interface.optimization.base_goal import BaseGoal
6
- from rtctools_interface.optimization.read_goals import read_goals
7
-
8
- logger = logging.getLogger("rtctools")
9
-
10
-
11
- class GoalGeneratorMixin:
12
- # TODO: remove pylint disable below once we have more public functions.
13
- # pylint: disable=too-few-public-methods
14
- """Add path goals as specified in the goal_table.
15
-
16
- By default, the mixin looks for the csv in the in the default input
17
- folder. One can also set the path to the goal_table_file manually
18
- with the `goal_table_file` class variable.
19
- """
20
-
21
- def __init__(self, **kwargs):
22
- super().__init__(**kwargs)
23
- self.goals_to_generate = kwargs.get("goals_to_generate", [])
24
- self.read_from = kwargs.get("read_goals_from", "csv_table")
25
- if not hasattr(self, "goal_table_file"):
26
- self.goal_table_file = os.path.join(self._input_folder, "goal_table.csv")
27
-
28
- def path_goals(self):
29
- """Return the list of path goals."""
30
- goals = super().path_goals()
31
- new_goals = read_goals(
32
- self.goal_table_file, path_goal=True, read_from=self.read_from, goals_to_generate=self.goals_to_generate
33
- )
34
- if new_goals:
35
- goals = goals + [BaseGoal(optimization_problem=self, **goal.__dict__) for goal in new_goals]
36
- return goals
37
-
38
- def goals(self):
39
- """Return the list of goals."""
40
- goals = super().goals()
41
- new_goals = read_goals(
42
- self.goal_table_file, path_goal=False, read_from=self.read_from, goals_to_generate=self.goals_to_generate
43
- )
44
- if new_goals:
45
- goals = goals + [BaseGoal(optimization_problem=self, **goal.__dict__) for goal in new_goals]
46
- return goals