OpenSimula 0.5.1__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 (60) hide show
  1. opensimula-0.5.1/LICENSE +21 -0
  2. opensimula-0.5.1/PKG-INFO +49 -0
  3. opensimula-0.5.1/README.md +25 -0
  4. opensimula-0.5.1/pyproject.toml +37 -0
  5. opensimula-0.5.1/setup.cfg +4 -0
  6. opensimula-0.5.1/src/opensimula/Child.py +19 -0
  7. opensimula-0.5.1/src/opensimula/Component.py +214 -0
  8. opensimula-0.5.1/src/opensimula/Iterative_process.py +47 -0
  9. opensimula-0.5.1/src/opensimula/Message.py +19 -0
  10. opensimula-0.5.1/src/opensimula/Parameter_container.py +80 -0
  11. opensimula-0.5.1/src/opensimula/Parameters.py +755 -0
  12. opensimula-0.5.1/src/opensimula/Project.py +674 -0
  13. opensimula-0.5.1/src/opensimula/Simulation.py +212 -0
  14. opensimula-0.5.1/src/opensimula/Variable.py +37 -0
  15. opensimula-0.5.1/src/opensimula/__init__.py +8 -0
  16. opensimula-0.5.1/src/opensimula/components/Building.py +511 -0
  17. opensimula-0.5.1/src/opensimula/components/Building_surface.py +318 -0
  18. opensimula-0.5.1/src/opensimula/components/Calculator.py +51 -0
  19. opensimula-0.5.1/src/opensimula/components/Construction.py +309 -0
  20. opensimula-0.5.1/src/opensimula/components/Day_schedule.py +64 -0
  21. opensimula-0.5.1/src/opensimula/components/File_data.py +117 -0
  22. opensimula-0.5.1/src/opensimula/components/File_met.py +1035 -0
  23. opensimula-0.5.1/src/opensimula/components/Frame.py +35 -0
  24. opensimula-0.5.1/src/opensimula/components/Glazing.py +122 -0
  25. opensimula-0.5.1/src/opensimula/components/HVAC_DX_equipment.py +210 -0
  26. opensimula-0.5.1/src/opensimula/components/HVAC_DX_system.py +254 -0
  27. opensimula-0.5.1/src/opensimula/components/HVAC_MZW_system.py +554 -0
  28. opensimula-0.5.1/src/opensimula/components/HVAC_SZW_system.py +338 -0
  29. opensimula-0.5.1/src/opensimula/components/HVAC_coil_equipment.py +206 -0
  30. opensimula-0.5.1/src/opensimula/components/HVAC_fan_equipment.py +44 -0
  31. opensimula-0.5.1/src/opensimula/components/HVAC_perfect_system.py +137 -0
  32. opensimula-0.5.1/src/opensimula/components/Material.py +14 -0
  33. opensimula-0.5.1/src/opensimula/components/Opening.py +409 -0
  34. opensimula-0.5.1/src/opensimula/components/Opening_type.py +90 -0
  35. opensimula-0.5.1/src/opensimula/components/Solar_surface.py +114 -0
  36. opensimula-0.5.1/src/opensimula/components/Space.py +388 -0
  37. opensimula-0.5.1/src/opensimula/components/Space_type.py +81 -0
  38. opensimula-0.5.1/src/opensimula/components/Surface.py +129 -0
  39. opensimula-0.5.1/src/opensimula/components/Test_component.py +76 -0
  40. opensimula-0.5.1/src/opensimula/components/Week_schedule.py +30 -0
  41. opensimula-0.5.1/src/opensimula/components/Year_schedule.py +65 -0
  42. opensimula-0.5.1/src/opensimula/components/__init__.py +40 -0
  43. opensimula-0.5.1/src/opensimula/visual_3D/Environment_3D.py +257 -0
  44. opensimula-0.5.1/src/opensimula/visual_3D/Polygon_3D.py +262 -0
  45. opensimula-0.5.1/src/opensimula.egg-info/PKG-INFO +49 -0
  46. opensimula-0.5.1/src/opensimula.egg-info/SOURCES.txt +58 -0
  47. opensimula-0.5.1/src/opensimula.egg-info/dependency_links.txt +1 -0
  48. opensimula-0.5.1/src/opensimula.egg-info/requires.txt +14 -0
  49. opensimula-0.5.1/src/opensimula.egg-info/top_level.txt +1 -0
  50. opensimula-0.5.1/test/test_Calculator.py +40 -0
  51. opensimula-0.5.1/test/test_Case_600FF.py +323 -0
  52. opensimula-0.5.1/test/test_Case_610.py +354 -0
  53. opensimula-0.5.1/test/test_Construction.py +129 -0
  54. opensimula-0.5.1/test/test_File_data.py +71 -0
  55. opensimula-0.5.1/test/test_File_met.py +99 -0
  56. opensimula-0.5.1/test/test_HVAC_DX_Equipment.py +49 -0
  57. opensimula-0.5.1/test/test_HVAC_DX_system.py +408 -0
  58. opensimula-0.5.1/test/test_Iterative_process.py +13 -0
  59. opensimula-0.5.1/test/test_Project.py +122 -0
  60. opensimula-0.5.1/test/test_Schedules.py +81 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Juan F. Coronel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: opensimula
3
+ Version: 0.5.1
4
+ Summary: Component-based time simulation environment in Python
5
+ Author-email: "Juan F. Coronel" <jfc@us.es>
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: dash>=3.2.0
10
+ Requires-Dist: dash-ag-grid>=32.3.2
11
+ Requires-Dist: dash-bootstrap-components>=2.0.4
12
+ Requires-Dist: nbformat>=5.10.4
13
+ Requires-Dist: numpy>=2.3.3
14
+ Requires-Dist: openpyxl>=3.1.5
15
+ Requires-Dist: pandas>=2.3.2
16
+ Requires-Dist: plotly>=6.3.0
17
+ Requires-Dist: psychrolib>=2.5.0
18
+ Requires-Dist: scipy>=1.16.2
19
+ Requires-Dist: shapely>=2.1.1
20
+ Requires-Dist: tqdm>=4.67.1
21
+ Requires-Dist: triangle>=20250106
22
+ Requires-Dist: vedo>=2025.5.4
23
+ Dynamic: license-file
24
+
25
+ ![Logo](https://jfcoronel.github.io/opensimula/img/logo_opensimula.png)
26
+ Component-based time simulation environment in Python
27
+
28
+ [Documentation page](https://jfcoronel.github.io/opensimula/)
29
+
30
+ ## Main Developers
31
+
32
+ * [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
33
+
34
+ ## Package dependencies
35
+ - numpy
36
+ - pandas
37
+ - scipy
38
+ - shapely
39
+ - psychrolib
40
+ - plotly
41
+ - dash
42
+ - dash_bootstrap_components
43
+ - dash_ag_grid
44
+ - pyvista
45
+ - trame
46
+ - trame-vtk
47
+ - trame-vuetify
48
+ - ipywidgets
49
+
@@ -0,0 +1,25 @@
1
+ ![Logo](https://jfcoronel.github.io/opensimula/img/logo_opensimula.png)
2
+ Component-based time simulation environment in Python
3
+
4
+ [Documentation page](https://jfcoronel.github.io/opensimula/)
5
+
6
+ ## Main Developers
7
+
8
+ * [Juan F. Coronel](http://jfc.us.es), Universidad de Sevilla
9
+
10
+ ## Package dependencies
11
+ - numpy
12
+ - pandas
13
+ - scipy
14
+ - shapely
15
+ - psychrolib
16
+ - plotly
17
+ - dash
18
+ - dash_bootstrap_components
19
+ - dash_ag_grid
20
+ - pyvista
21
+ - trame
22
+ - trame-vtk
23
+ - trame-vuetify
24
+ - ipywidgets
25
+
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "opensimula"
3
+ version = "0.5.1"
4
+ requires-python = ">=3.12"
5
+ authors = [
6
+ { name="Juan F. Coronel", email="jfc@us.es" },
7
+ ]
8
+ description = "Component-based time simulation environment in Python"
9
+ readme = "README.md"
10
+ dependencies = [
11
+ "dash>=3.2.0",
12
+ "dash-ag-grid>=32.3.2",
13
+ "dash-bootstrap-components>=2.0.4",
14
+ "nbformat>=5.10.4",
15
+ "numpy>=2.3.3",
16
+ "openpyxl>=3.1.5",
17
+ "pandas>=2.3.2",
18
+ "plotly>=6.3.0",
19
+ "psychrolib>=2.5.0",
20
+ "scipy>=1.16.2",
21
+ "shapely>=2.1.1",
22
+ "tqdm>=4.67.1",
23
+ "triangle>=20250106",
24
+ "vedo>=2025.5.4",
25
+ ]
26
+
27
+ [dependency-groups]
28
+ dev = [
29
+ "ipykernel>=6.30.1",
30
+ "mkdocs>=1.6.1",
31
+ "pytest>=8.4.2",
32
+ ]
33
+
34
+ [build-system]
35
+ requires = ["setuptools>=61.2", "wheel"]
36
+
37
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ # ____________ Child ________________________
2
+
3
+
4
+ class Child():
5
+ """Objects with parent
6
+
7
+ Superclass for Paramaters an Variables
8
+ """
9
+
10
+ def __init__(self, parent=None):
11
+ self._parent_ = parent
12
+
13
+ @property
14
+ def parent(self):
15
+ return self._parent_
16
+
17
+ @parent.setter
18
+ def parent(self, parent):
19
+ self._parent_ = parent
@@ -0,0 +1,214 @@
1
+ import pandas as pd
2
+ from opensimula.Parameter_container import Parameter_container
3
+ from opensimula.Parameters import Parameter_string
4
+ from opensimula.Variable import Variable
5
+
6
+
7
+ class Component(Parameter_container):
8
+ """Base Class for all the components"""
9
+
10
+ def __init__(self, name, proj):
11
+ Parameter_container.__init__(self, proj._sim_)
12
+ self._variables_ = {}
13
+ self.add_parameter(Parameter_string("type", "Component"))
14
+ self.parameter("name").value = name
15
+ self.parameter("description").value = "Description of the component"
16
+ self._project_ = proj
17
+
18
+ def project(self):
19
+ return self._project_
20
+
21
+ def add_variable(self, variable):
22
+ """add new Variable"""
23
+ variable.parent = self
24
+ variable._sim_ = self._sim_
25
+ self._variables_[variable.key] = variable
26
+
27
+ def del_variable(self, variable):
28
+ self._variables_.pop(variable.key,None)
29
+
30
+ def variable(self, key):
31
+ return self._variables_[key]
32
+
33
+ def variable_dict(self):
34
+ return self._variables_
35
+
36
+ def variable_dataframe(self, units=False, frequency=None, value="mean", interval=None, pos_neg_columns=[]):
37
+ """_summary_
38
+
39
+ Args:
40
+ units (bool, optional): Includes unit in the name of the variable. Defaults to True.
41
+ frequency (None or str, optional): frequency of the values: None, "H" Hour, "D" Day, "M" Month, "Y" Year . Defaults to None.
42
+ value (str, optional): "mean", "sum", "sum_pos", "sum_neg", "max" or "min". Defaults to "mean".
43
+ interval (None or list of two dates): List with the start and end dates of the period to be included in the dataframe, if the value is None all values are included.
44
+ pos_neg_columns (list of str, optional): List of variables that will be included in separate columns positive and negative values. Defaults to [].
45
+
46
+ Returns:
47
+ pandas DataFrame: Returns all the variables
48
+ """
49
+ series = {}
50
+ series["date"] = self.project().dates()
51
+ for key, var in self._variables_.items():
52
+ if var.unit == "":
53
+ series[key] = var.values
54
+ else:
55
+ if units:
56
+ series[key + " [" + var.unit + "]"] = var.values
57
+ else:
58
+ series[key] = var.values
59
+ data = pd.DataFrame(series)
60
+ if pos_neg_columns != []:
61
+ for col in pos_neg_columns:
62
+ data[col + "_pos"] = data[col].apply(lambda x: x if x > 0 else 0)
63
+ data[col + "_neg"] = data[col].apply(lambda x: x if x < 0 else 0)
64
+ if frequency is not None:
65
+ if value == "mean":
66
+ data = data.resample(frequency, on='date').mean()
67
+ elif value == "sum":
68
+ data = data.resample(frequency, on='date').sum()
69
+ elif value == "max":
70
+ data = data.resample(frequency, on='date').max()
71
+ elif value == "min":
72
+ data = data.resample(frequency, on='date').min()
73
+ if interval is not None:
74
+ data = data[(data['date'] > interval[0]) &
75
+ (data['date'] < interval[1])]
76
+ return data
77
+
78
+ # ____________ Functions that must be overwriten for time simulation _________________
79
+
80
+ def get_all_referenced_components(self):
81
+ """Get list of all referenced components, first itself. Look recursively at the referenced components
82
+
83
+ Returns:
84
+ component_list (component[])
85
+ """
86
+ comp_list = []
87
+ for key, value in self.parameter_dict().items():
88
+ if value.type == "Parameter_component":
89
+ if value.component is not None:
90
+ sublist = value.component.get_all_referenced_components()
91
+ for subcomp in sublist:
92
+ comp_list.append(subcomp)
93
+ elif value.type == "Parameter_component_list":
94
+ for comp in value.component:
95
+ if comp is not None:
96
+ sublist = comp.get_all_referenced_components()
97
+ for subcomp in sublist:
98
+ comp_list.append(subcomp)
99
+ if value.type == "Parameter_variable":
100
+ if value.variable is not None:
101
+ sublist = value.variable.parent.get_all_referenced_components()
102
+ for subcomp in sublist:
103
+ comp_list.append(subcomp)
104
+ elif value.type == "Parameter_variable_list":
105
+ for var in value.variable:
106
+ if var is not None:
107
+ sublist = var.parent.get_all_referenced_components()
108
+ for subcomp in sublist:
109
+ comp_list.append(subcomp)
110
+ comp_list.append(self)
111
+ return comp_list
112
+
113
+ def check(self):
114
+ """Check if all is correct
115
+
116
+ Returns:
117
+ errors (string list): List of errors
118
+ """
119
+ errors = []
120
+ # Parameter errors
121
+ for key, value in self.parameter_dict().items():
122
+ param_error = value.check()
123
+ for e in param_error:
124
+ errors.append(e)
125
+ # Create variables in paramater_variable
126
+ if value.type == "Parameter_variable":
127
+ if value.variable is not None:
128
+ if (value.symbol in self._variables_): # Delete
129
+ self.del_variable(self.variable(value.symbol))
130
+ self.add_variable(
131
+ Variable(value.symbol, value.variable.unit))
132
+ if value.type == "Parameter_variable_list":
133
+ for i in range(len(value.variable)):
134
+ if value.variable[i] is not None:
135
+ if (value.symbol[i] in self._variables_): # Delete
136
+ self.del_variable(self.variable(value.symbol[i]))
137
+ self.add_variable(
138
+ Variable(value.symbol[i], value.variable[i].unit))
139
+
140
+ return errors
141
+
142
+ def get_parameter_variable_dictionary(self,time_index):
143
+ # variables dictonary
144
+ var_dic = {}
145
+ for i in range(len(self._var_from_parameter_symbol)):
146
+ var_dic[self._var_from_parameter_symbol[i]] = self._var_from_parameter_variable[i].values[time_index]
147
+ return var_dic
148
+
149
+ def pre_simulation(self, n_time_steps, delta_t):
150
+ # Create variables from paramater "Parameter_variable" and "Parameter_variable_list"
151
+ self._var_from_parameter_symbol = []
152
+ self._var_from_parameter_variable = []
153
+ for param in self.parameter_dict().values():
154
+ if param.type == "Parameter_variable":
155
+ self._var_from_parameter_symbol.append(param.symbol)
156
+ self._var_from_parameter_variable.append(param.variable)
157
+ elif param.type == "Parameter_variable_list":
158
+ for i in range(len(param.variable)):
159
+ self._var_from_parameter_symbol.append(param.symbol[i])
160
+ self._var_from_parameter_variable.append(param.variable[i])
161
+
162
+ # Initilise all variables to 0
163
+ for key, var in self._variables_.items():
164
+ var.initialise(n_time_steps)
165
+
166
+ def post_simulation(self):
167
+ pass
168
+
169
+ def pre_iteration(self, time_index, date, daylight_saving):
170
+ # Initilise all variables to 0
171
+ for key, value in self.parameter_dict().items():
172
+ # Copy variables in paramater_variable
173
+ if value.type == "Parameter_variable":
174
+ if value.variable is not None:
175
+ self.variable(
176
+ value.symbol).values[time_index] = value.variable.values[time_index]
177
+ if value.type == "Parameter_variable_list":
178
+ for i in range(len(value.variable)):
179
+ if value.variable[i] is not None:
180
+ self.variable(
181
+ value.symbol[i]).values[time_index] = value.variable[i].values[time_index]
182
+
183
+ def iteration(self, time_index, date, daylight_saving, n_iter):
184
+ return True
185
+
186
+ def post_iteration(self, time_index, date, daylight_saving, converged):
187
+ pass
188
+
189
+ def _repr_html_(self):
190
+ html = f"<h3>Component: {self.parameter('name').value}</h3><p><strong>Desciption: </strong>{self.parameter('description').value}</p>"
191
+ html += "<strong>Parameters:</strong>"
192
+ html += self.parameter_dataframe().to_html()
193
+ if (len(self._variables_) > 0):
194
+ html += "<br/><strong>Variables:</strong>"
195
+ html += self.variable_html()
196
+ return html
197
+
198
+ def variable_html(self):
199
+ keys = []
200
+ descriptions = []
201
+ units = []
202
+ for key, var in self._variables_.items():
203
+ keys.append(key)
204
+ descriptions.append(var.description)
205
+ units.append(var.unit)
206
+
207
+ data = pd.DataFrame(
208
+ {"key": keys, "description": descriptions, "unit": units}
209
+ )
210
+ return data.to_html()
211
+
212
+ def function_html(self):
213
+ html = "<p><strong>parameter_dataframe():</strong> Return pandas DataFrame with the component parametes.</p>"
214
+ html += "<p><strong>variable_dataframe():</strong> Return pandas DataFrame with the component variables.</p>"
@@ -0,0 +1,47 @@
1
+ import math
2
+
3
+ class Iterative_process:
4
+ def __init__(self, x_0, tol = 1e-5, lambda_min=0.1, lambda_max=1.0, n_ini_relax=2,rel_vel = 0.9):
5
+ """
6
+ Iterative process using the fixed-point method with adaptive relaxation coefficient
7
+
8
+ Parameters:
9
+ x_0: Initial value
10
+ tol: convergence tolerance
11
+ lambda_min, lambda_max: relaxation coefficient range
12
+ n_ini_relax: Number of iterations in which adaptive relaxation is initiated, must be greater than 1
13
+ """
14
+ self.x = [x_0]
15
+ self.tol = tol
16
+ self.lambda_min = lambda_min
17
+ self.lambda_max = lambda_max
18
+ self.lambda_i = lambda_max
19
+ self.n_ini_relax = n_ini_relax
20
+ self.rel_vel = rel_vel
21
+
22
+
23
+ def converged(self):
24
+ if len(self.x) == 1:
25
+ return False
26
+ else:
27
+ if abs(self.x[-1]-self.x[-2]) < self.tol:
28
+ return True
29
+ else:
30
+ return False
31
+
32
+ def estimate_next_x(self, proposed_x):
33
+ x_next = (1 - self.lambda_i) * self.x[-1] + self.lambda_i * proposed_x
34
+
35
+ # Ajuste dinámico de lambda (reduce si hay oscilaciones)
36
+ if len(self.x)>self.n_ini_relax:
37
+ #if abs(x_next - self.x[-1]) > abs(self.x[-1]- self.x[-2]):
38
+ self.lambda_i = max(self.lambda_min, self.lambda_i * self.rel_vel) # Reducimos lambda
39
+ #else:
40
+ #self.lambda_i = min(self.lambda_max, self.lambda_i * 1/self.rel_vel) # Aumentamos lambda
41
+
42
+ self.x.append(x_next)
43
+ return x_next
44
+
45
+ def set_next_x(self, next_x):
46
+ self.x.append(next_x)
47
+
@@ -0,0 +1,19 @@
1
+ class Message:
2
+ def __init__(self, text, level="ERROR"):
3
+ self._text_ = text
4
+ self._level_ = level # ERROR, WARNING, INFO, CONSOLE
5
+
6
+ @property
7
+ def text(self):
8
+ return self._text_
9
+
10
+ @property
11
+ def level(self):
12
+ return self._level_
13
+
14
+ def print(self):
15
+ if self.level == "CONSOLE":
16
+ print(self.text)
17
+ else:
18
+ print(self.level + ": " + self.text)
19
+
@@ -0,0 +1,80 @@
1
+ import pandas as pd
2
+ from opensimula.Parameters import Parameter_string
3
+ from opensimula.Message import Message
4
+
5
+ class Parameter_container:
6
+ """Class to manage a list of Paramaters
7
+
8
+ Superclass for Projects and Components
9
+
10
+ Default parameters included:
11
+ - name (string)
12
+ - description (string)
13
+
14
+ """
15
+
16
+ def __init__(self, sim):
17
+ self._sim_ = sim
18
+ self._parameters_ = {}
19
+ self.add_parameter(Parameter_string("name", "Name"))
20
+ self.add_parameter(Parameter_string("description", "Description"))
21
+
22
+ def add_parameter(self, param):
23
+ """add Parameter"""
24
+ param.parent = self
25
+ param._sim_ = self._sim_
26
+ self._parameters_[param.key] = param
27
+
28
+ def del_parameter(self, param):
29
+ """Deletet parameter"""
30
+ self._parameters_.remove(param)
31
+
32
+ def parameter(self, key):
33
+ return self._parameters_[key]
34
+
35
+ def parameter_dict(self):
36
+ return self._parameters_
37
+
38
+ def set_parameters(self, dictonary):
39
+ """Read parameters from dictonary"""
40
+ for key, value in dictonary.items():
41
+ if key in self._parameters_:
42
+ self.parameter(key).value = value
43
+ else:
44
+ self._sim_.message(Message("Component parameter " + key + " does not exist","ERROR"))
45
+
46
+ def parameter_dataframe(self, string_format=False):
47
+ keys = []
48
+ values = []
49
+ types = []
50
+ units = []
51
+ for key, par in self._parameters_.items():
52
+ keys.append(key)
53
+ if string_format:
54
+ values.append(str(par.value))
55
+ else:
56
+ values.append(par.value)
57
+ types.append(par.type)
58
+ if hasattr(par, "unit"):
59
+ units.append(par.unit)
60
+ else:
61
+ units.append("")
62
+
63
+ data = pd.DataFrame(
64
+ {"key": keys, "type": types, "value": values, "unit": units}
65
+ )
66
+ return data
67
+
68
+ def check_parameters(self):
69
+ """Check if all is correct
70
+
71
+ Returns:
72
+ errors (string list): List of errors
73
+ """
74
+ errors = []
75
+ for key, value in self._parameters_.items():
76
+ param_error = value.check()
77
+ if len(param_error) > 1:
78
+ for e in param_error:
79
+ errors.append(e)
80
+ return errors