Skip to content

Commit 7fa8cc4

Browse files
authored
Merge pull request #122 from RWTH-EBC/120_model_name_setting [PYPI-RELEASE]
fix: only set model name if the model really changes and refactor to cwd
2 parents 7a2cbac + 6a9b9ed commit 7fa8cc4

File tree

17 files changed

+191
-97
lines changed

17 files changed

+191
-97
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,11 @@
8888
- Fix bug in function clean_and_space_equally_time_series #111
8989
- v0.3.11
9090
- Add dymola_exe_path to set of kwargs in DymolaAPI #115
91+
- v0.3.12
92+
- Port handling Add dymola_exe_path to set of kwargs in DymolaAPI #118
93+
- v0.3.13
94+
- Fixes in simulate options and add Dymola CI tests #28, #113, #117
95+
- v0.3.14
96+
- Fix retranslation #121
97+
- refactor cd to working_directory #61
98+
- Propagate `names` of simres to TimeSeriesData to speed up mat-loading

ebcpy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
from .optimization import Optimizer
99

1010

11-
__version__ = '0.3.13'
11+
__version__ = '0.3.14'

ebcpy/data_types.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ class TimeSeriesData(pd.DataFrame):
8282
:keyword str engine:
8383
Chose the engine for reading .parquet files. Default is 'pyarrow'
8484
Other option is 'fastparquet' (python>=3.9).
85-
85+
:keyword list variable_names:
86+
List of variable names to load from .mat file. If you
87+
know which variables you want to plot, this may speed up
88+
loading significantly, and reduce memory size drastically.
8689
8790
Examples:
8891
@@ -317,7 +320,11 @@ def _load_df_from_file(self, file):
317320
header=self._loader_kwargs.get("header", _hea_def)
318321
)
319322
elif file.suffix == ".mat":
320-
df = sr.mat_to_pandas(fname=file, with_unit=False)
323+
df = sr.mat_to_pandas(
324+
fname=file,
325+
with_unit=False,
326+
names=self._loader_kwargs.get("variable_names")
327+
)
321328
elif file.suffix in ['.xlsx', '.xls', '.odf', '.ods', '.odt']:
322329
sheet_name = self._loader_kwargs.get("sheet_name")
323330
if sheet_name is None:

ebcpy/modelica/simres.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ def mat_to_pandas(fname='dsres.mat',
294294
if names:
295295
if 'Time' not in names:
296296
names.append('Time')
297+
non_existing_variables = list(set(names).difference(_variables.keys()))
298+
if non_existing_variables:
299+
raise KeyError(f"The following variable names are not in the given .mat file: "
300+
f"{', '.join(non_existing_variables)}")
297301
else:
298302
names = _variables.keys()
299303

ebcpy/optimization.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Calibrator."""
44

55
import os
6+
from pathlib import Path
7+
import warnings
68
from typing import List, Tuple, Union
79
from collections import namedtuple
810
from abc import abstractmethod
@@ -24,7 +26,7 @@ class Optimizer:
2426
self.optimize().
2527
2628
27-
:param str,os.path.normpath cd:
29+
:param str,Path working_directory:
2830
Directory for storing all output of optimization via a logger.
2931
:keyword list bounds:
3032
The boundaries for the optimization variables.
@@ -40,14 +42,17 @@ class Optimizer:
4042
# Can be used, but will enlarge runtime
4143
_obj_his = []
4244

43-
def __init__(self, cd=None, **kwargs):
45+
def __init__(self, working_directory: Union[Path, str] = None, **kwargs):
4446
"""Instantiate class parameters"""
45-
if cd is None:
46-
self._cd = None
47+
if working_directory is None and "cd" in kwargs:
48+
warnings.warn("cd was renamed to working_directory in all classes. Use working_directory instead.", category=DeprecationWarning)
49+
self.working_directory = kwargs["cd"]
50+
elif working_directory is None:
51+
self._working_directory = None
4752
else:
48-
self.cd = cd
53+
self.working_directory = working_directory
4954

50-
self.logger = setup_logger(cd=self.cd, name=self.__class__.__name__)
55+
self.logger = setup_logger(working_directory=self.working_directory, name=self.__class__.__name__)
5156
# Set kwargs
5257
self.bounds = kwargs.get("bounds", None)
5358

@@ -93,15 +98,27 @@ def supported_frameworks(self):
9398
"pymoo"]
9499

95100
@property
96-
def cd(self) -> str:
101+
def working_directory(self) -> Path:
97102
"""The current working directory"""
98-
return self._cd
103+
return self._working_directory
99104

100-
@cd.setter
101-
def cd(self, cd: str):
105+
@working_directory.setter
106+
def working_directory(self, working_directory: Union[Path, str]):
102107
"""Set current working directory"""
103-
os.makedirs(cd, exist_ok=True)
104-
self._cd = cd
108+
if isinstance(working_directory, str):
109+
working_directory = Path(working_directory)
110+
os.makedirs(working_directory, exist_ok=True)
111+
self._working_directory = working_directory
112+
113+
@property
114+
def cd(self) -> Path:
115+
warnings.warn("cd was renamed to working_directory in all classes. Use working_directory instead instead.", category=DeprecationWarning)
116+
return self.working_directory
117+
118+
@cd.setter
119+
def cd(self, cd: Union[Path, str]):
120+
warnings.warn("cd was renamed to working_directory in all classes. Use working_directory instead instead.", category=DeprecationWarning)
121+
self.working_directory = cd
105122

106123
@property
107124
def bounds(self) -> List[Union[Tuple, List]]:

ebcpy/simulationapi/__init__.py

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import sys
1111
import itertools
1212
import time
13+
from pathlib import Path
1314
from datetime import timedelta
1415
from typing import Dict, Union, TypeVar, Any, List
1516
from abc import abstractmethod
@@ -145,7 +146,7 @@ class SimulationAPI:
145146
"""Base-class for simulation apis. Every simulation-api class
146147
must inherit from this class. It defines the structure of each class.
147148
148-
:param str,os.path.normpath cd:
149+
:param str,Path working_directory:
149150
Working directory path
150151
:param str model_name:
151152
Name of the model being simulated.
@@ -162,13 +163,18 @@ class SimulationAPI:
162163
'pool',
163164
]
164165

165-
def __init__(self, cd, model_name, **kwargs):
166+
def __init__(self, working_directory: Union[Path, str], model_name: str, **kwargs):
166167
# Private helper attrs for multiprocessing
167168
self._n_sim_counter = 0
168169
self._n_sim_total = 0
169170
self._progress_int = 0
171+
# Handle deprecation warning
172+
self.working_directory = working_directory
173+
self.logger = setup_logger(
174+
working_directory=self.working_directory,
175+
name=self.__class__.__name__
176+
)
170177
# Setup the logger
171-
self.logger = setup_logger(cd=cd, name=self.__class__.__name__)
172178
self.logger.info(f'{"-" * 25}Initializing class {self.__class__.__name__}{"-" * 25}')
173179
# Check multiprocessing
174180
self.n_cpu = kwargs.get("n_cpu", 1)
@@ -185,7 +191,6 @@ def __init__(self, cd, model_name, **kwargs):
185191
self.use_mp = False
186192
# Setup the model
187193
self._sim_setup = self._sim_setup_class()
188-
self.cd = cd
189194
self.inputs: Dict[str, Variable] = {} # Inputs of model
190195
self.outputs: Dict[str, Variable] = {} # Outputs of model
191196
self.parameters: Dict[str, Variable] = {} # Parameter of model
@@ -258,7 +263,7 @@ def simulate(self,
258263
Only variables specified in result_names will be returned.
259264
- 'savepath': Returns the savepath where the results are stored.
260265
Depending on the API, different kwargs may be used to specify file type etc.
261-
:keyword str,os.path.normpath savepath:
266+
:keyword str,Path savepath:
262267
If path is provided, the relevant simulation results will be saved
263268
in the given directory. For multiple parameter variations also a list
264269
of savepaths for each parameterset can be specified.
@@ -302,14 +307,14 @@ def simulate(self,
302307
# Handle special case for saving files:
303308
if return_option == "savepath" and n_simulations > 1:
304309
savepath = kwargs.get("savepath", [])
305-
if isinstance(savepath, (str, os.PathLike)):
310+
if isinstance(savepath, (str, os.PathLike, Path)):
306311
savepath = [savepath] * n_simulations
307312
result_file_name = kwargs.get("result_file_name", [])
308313
if isinstance(result_file_name, str):
309314
result_file_name = [result_file_name] * n_simulations
310315
if len(savepath) != len(result_file_name):
311316
raise ValueError("Given savepath and result_file_name "
312-
"have not the same lenght.")
317+
"have not the same length.")
313318
joined_save_paths = []
314319
for _single_save_path, _single_result_name in zip(savepath, result_file_name):
315320
joined_save_paths.append(os.path.join(_single_save_path, _single_result_name))
@@ -318,7 +323,7 @@ def simulate(self,
318323
"Simulating multiple parameter set's on "
319324
"the same combination of savepath and result_file_name "
320325
"will override results or even cause errors. "
321-
"Specify a unqiue result_file_name-savepath combination "
326+
"Specify a unique result_file_name-savepath combination "
322327
"for each parameter combination"
323328
)
324329
for key, value in kwargs.items():
@@ -448,6 +453,9 @@ def model_name(self, model_name):
448453
Set new model_name and trigger further functions
449454
to load parameters etc.
450455
"""
456+
# Only update if the model_name actually changes
457+
if hasattr(self, "_model_name") and self._model_name == model_name:
458+
return
451459
self._model_name = model_name
452460
# Only update model if it's the first setup. On multiprocessing,
453461
# all objects are duplicated and thus this setter is triggered again.
@@ -478,20 +486,39 @@ def _update_model(self):
478486
raise NotImplementedError(f'{self.__class__.__name__}._update_model '
479487
f'function is not defined')
480488

481-
def set_cd(self, cd):
489+
def set_working_directory(self, working_directory: Union[Path, str]):
482490
"""Base function for changing the current working directory."""
483-
self.cd = cd
491+
self.working_directory = working_directory
484492

485493
@property
486-
def cd(self) -> str:
494+
def working_directory(self) -> Path:
487495
"""Get the current working directory"""
488-
return self._cd
496+
return self._working_directory
489497

490-
@cd.setter
491-
def cd(self, cd: str):
498+
@working_directory.setter
499+
def working_directory(self, working_directory: Union[Path, str]):
492500
"""Set the current working directory"""
493-
os.makedirs(cd, exist_ok=True)
494-
self._cd = cd
501+
if isinstance(working_directory, str):
502+
working_directory = Path(working_directory)
503+
os.makedirs(working_directory, exist_ok=True)
504+
self._working_directory = working_directory
505+
506+
def set_cd(self, cd: Union[Path, str]):
507+
warnings.warn("cd was renamed to working_directory in all classes. "
508+
"Use working_directory instead instead.", category=DeprecationWarning)
509+
self.working_directory = cd
510+
511+
@property
512+
def cd(self) -> Path:
513+
warnings.warn("cd was renamed to working_directory in all classes. "
514+
"Use working_directory instead instead.", category=DeprecationWarning)
515+
return self.working_directory
516+
517+
@cd.setter
518+
def cd(self, cd: Union[Path, str]):
519+
warnings.warn("cd was renamed to working_directory in all classes. "
520+
"Use working_directory instead instead.", category=DeprecationWarning)
521+
self.working_directory = cd
495522

496523
@property
497524
def result_names(self) -> List[str]:

0 commit comments

Comments
 (0)