zen-garden 2.9.0__py3-none-any.whl → 2.9.1__py3-none-any.whl

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.
@@ -142,7 +142,7 @@ class System(Subscriptable):
142
142
  knowledge_depreciation_rate: float = 0.1
143
143
  reference_year: int = 2024
144
144
  unaggregated_time_steps_per_year: int = 8760
145
- aggregated_time_steps_per_year: int = 10
145
+ aggregated_time_steps_per_year: int = 8760
146
146
  conduct_time_series_aggregation: bool = False
147
147
  optimized_years: int = 1
148
148
  interval_between_years: int = 1
@@ -76,7 +76,7 @@ class Results:
76
76
  if component_name not in scenario.components:
77
77
  logging.warning(f"Component {component_name} not found. If you expected this component to be present, the solution is probably empty and therefore skipped.")
78
78
  return pd.Series()
79
- component = scenario.components[component_name]
79
+ component = scenario.get_component(component_name)
80
80
  if data_type == "units" and not component.has_units:
81
81
  return None
82
82
  idx = reformat_slicing_index(index,component)
@@ -89,7 +89,7 @@ class Results:
89
89
  scenario = self.solution_loader.scenarios[scenario_name]
90
90
  if component_name not in scenario.components:
91
91
  continue
92
- component = scenario.components[component_name]
92
+ component = scenario.get_component(component_name)
93
93
  if data_type == "units" and not component.has_units:
94
94
  return None
95
95
  idx = reformat_slicing_index(index, component)
@@ -247,7 +247,7 @@ class Results:
247
247
  scenario = self.solution_loader.scenarios[scenario_name]
248
248
  if component_name not in scenario.components:
249
249
  continue
250
- component = scenario.components[component_name]
250
+ component = scenario.get_component(component_name)
251
251
  idx = reformat_slicing_index(index,component)
252
252
  scenarios_dict[scenario_name] = self.get_full_ts_per_scenario(
253
253
  scenario,
@@ -363,7 +363,7 @@ class Results:
363
363
  scenario = self.solution_loader.scenarios[scenario_name]
364
364
  if component_name not in scenario.components:
365
365
  continue
366
- component = scenario.components[component_name]
366
+ component = scenario.get_component(component_name)
367
367
  idx = reformat_slicing_index(index, component)
368
368
  current_total = self.get_total_per_scenario(
369
369
  scenario, component, year, keep_raw, index = idx
@@ -416,7 +416,7 @@ class Results:
416
416
  :return: annuity of the duals
417
417
  """
418
418
  system = scenario.system
419
- discount_rate_component = scenario.components["discount_rate"]
419
+ discount_rate_component = scenario.get_component("discount_rate")
420
420
  # calculate annuity
421
421
  discount_rate = self.solution_loader.get_component_data(
422
422
  scenario, discount_rate_component
@@ -553,7 +553,7 @@ class Results:
553
553
  component = None
554
554
  for s in self.solution_loader.scenarios:
555
555
  if component_name in self.solution_loader.scenarios[s].components:
556
- component = self.solution_loader.scenarios[s].components[component_name]
556
+ component = self.solution_loader.scenarios[s].get_component(component_name)
557
557
  break
558
558
  if component is None:
559
559
  return u
@@ -674,7 +674,7 @@ class Results:
674
674
  component = None
675
675
  for scenario in self.solution_loader.scenarios.values():
676
676
  if component_name in scenario.components:
677
- component = scenario.components[component_name]
677
+ component = scenario.get_component(component_name)
678
678
  break
679
679
  if component is None:
680
680
  logging.warning(f"Component {component_name} not found and the documentation cannot be returned.")
@@ -699,7 +699,7 @@ class Results:
699
699
  if component_name not in scenario.components:
700
700
  logging.warning(f"Component {component_name} not found and the index names cannot be returned.")
701
701
  return []
702
- component = scenario.components[component_name]
702
+ component = scenario.get_component(component_name)
703
703
  return component.index_names
704
704
 
705
705
  def get_years(self, scenario_name: Optional[str] = None) -> list[int]:
@@ -909,11 +909,9 @@ class Results:
909
909
  assert component_type in ComponentType.get_component_type_names(), f"Invalid component type: {component_type}. Valid types are: {ComponentType.get_component_type_names()}"
910
910
  list_names = []
911
911
  for scenario in self.solution_loader.scenarios:
912
- for component in self.solution_loader.scenarios[scenario].components:
913
- component_name = self.solution_loader.scenarios[scenario].components[component].name
914
- component_type_specific = self.solution_loader.scenarios[scenario].components[component].component_type.name
915
- if component_name not in list_names and component_type_specific == component_type:
916
- list_names.append(component)
912
+ for cn in self.solution_loader.scenarios[scenario].component_types[component_type]:
913
+ if cn not in list_names:
914
+ list_names.append(cn)
917
915
  return list_names
918
916
 
919
917
 
@@ -129,7 +129,7 @@ class Scenario():
129
129
  folder.
130
130
  """
131
131
 
132
- def __init__(self, path: str, name: str, base_scenario: str, default_ureg: pint.UnitRegistry) -> None:
132
+ def __init__(self, path: str, name: str, base_scenario: str) -> None:
133
133
  self.name = name
134
134
  self.base_name = base_scenario
135
135
  self._exists = True
@@ -138,8 +138,9 @@ class Scenario():
138
138
  self._system: System = self._read_system()
139
139
  self._solver: Solver = self._read_solver()
140
140
  self._benchmarking: dict[str,Any] = self._read_benchmarking()
141
- self._ureg = self._read_ureg(default_ureg)
142
- self._components: dict[str, Component] = self._read_components()
141
+ self._component_types: dict[str, list[str]] = None
142
+ self._components: dict[str, Component] = None
143
+ self._read_components()
143
144
 
144
145
  def _read_analysis(self) -> Analysis:
145
146
  analysis_path = os.path.join(self.path, "analysis.json")
@@ -177,12 +178,12 @@ class Scenario():
177
178
  else:
178
179
  return {}
179
180
 
180
- def _read_ureg(self,default_ureg) -> pint.UnitRegistry:
181
-
181
+ def _read_ureg(self) -> pint.UnitRegistry:
182
+
182
183
  # suppress pint output about redefining units
183
184
  logging.getLogger('pint').setLevel(logging.ERROR)
184
185
  # load ureg
185
- ureg = copy.copy(default_ureg)
186
+ ureg = copy.copy(pint.UnitRegistry())
186
187
  unit_path = os.path.join(self.path, "unit_definitions.txt")
187
188
  if os.path.exists(unit_path):
188
189
  ureg.load_definitions(unit_path)
@@ -220,7 +221,7 @@ class Scenario():
220
221
  raise KeyError(f"Year {year} not in optimized years {all_years}.")
221
222
  return ts
222
223
 
223
- def _read_components(self) -> dict[str, Component]:
224
+ def _read_components(self) -> dict[str, list[str]]:
224
225
  """
225
226
  Create the component instances.
226
227
 
@@ -228,8 +229,12 @@ class Scenario():
228
229
  the component. Furthermore, the timestep name and type are derived by checking
229
230
  if any of the defined time steps name is in the index of the dataframe.
230
231
  """
231
- ans: dict[str, Component] = {}
232
-
232
+ component_types: dict[str,list[str]] = {t: [] for t in ComponentType.get_component_type_names()}
233
+ components:dict[str,dict] = {}
234
+
235
+ if not self._exists:
236
+ return component_types
237
+
233
238
  if self.has_rh:
234
239
  mf_name = [i for i in os.listdir(self.path) if "MF_" in i][0]
235
240
  component_folder = os.path.join(self.path, mf_name)
@@ -241,36 +246,22 @@ class Scenario():
241
246
 
242
247
  if not os.path.exists(file_path):
243
248
  continue
244
-
249
+
245
250
  h5_file = h5py.File(file_path)
246
- version = get_solution_version(self)
247
- for component_name in h5_file.keys():
248
- index_names = get_index_names(h5_file,component_name,version)
249
- time_index = set(index_names).intersection(set(TimestepType.get_time_steps_names()))
250
- timestep_name = time_index.pop() if len(time_index) > 0 else None
251
- timestep_type = TimestepType.get_time_step_type(timestep_name)
252
-
253
- doc = get_doc(h5_file,component_name,version)
254
-
255
- has_units = get_has_units(h5_file,component_name,version)
256
-
257
- ans[component_name] = Component(
258
- component_name,
259
- component_type,
260
- index_names,
261
- timestep_type,
262
- timestep_name,
263
- file_name,
264
- doc,
265
- has_units
266
- )
251
+ component_types[component_type.value] = list(h5_file.keys())
252
+ components.update({cn: {"component_type": component_type, "file_name": file_name, "file_path": file_path} for cn in h5_file.keys()})
267
253
 
268
- return ans
254
+ self._component_types = component_types
255
+ self._components = components
269
256
 
270
257
  @property
271
- def components(self) -> dict[str, Component]:
258
+ def components(self) -> dict[str, dict]:
272
259
  return self._components
273
260
 
261
+ @property
262
+ def component_types(self) -> dict[str, list[str]]:
263
+ return self._component_types
264
+
274
265
  @property
275
266
  def analysis(self) -> Analysis:
276
267
  return self._analysis
@@ -297,11 +288,48 @@ class Scenario():
297
288
 
298
289
  @property
299
290
  def ureg(self) -> pint.UnitRegistry:
300
- return self._ureg
291
+ return self._read_ureg()
301
292
 
302
293
  @property
303
294
  def exists(self) -> bool:
304
295
  return self._exists
296
+
297
+ def get_component(self, component_name: str) -> Component:
298
+ """
299
+ Method that returns a component given its name.
300
+ :param component_name: The name of the component.
301
+ :return: The component.
302
+ """
303
+ if component_name not in self.components:
304
+ raise KeyError(f"Component {component_name} not found in scenario {self.name}. Available components: {list(self.components.keys())}")
305
+
306
+ component_info = self.components[component_name]
307
+ component_type = component_info["component_type"]
308
+ file_name = component_info["file_name"]
309
+
310
+ h5_file = h5py.File(component_info["file_path"])
311
+ version = get_solution_version(self)
312
+ index_names = get_index_names(h5_file,component_name,version)
313
+ time_index = set(index_names).intersection(set(TimestepType.get_time_steps_names()))
314
+ timestep_name = time_index.pop() if len(time_index) > 0 else None
315
+ timestep_type = TimestepType.get_time_step_type(timestep_name)
316
+
317
+ doc = get_doc(h5_file,component_name,version)
318
+
319
+ has_units = get_has_units(h5_file,component_name,version)
320
+
321
+ ans = Component(
322
+ component_name,
323
+ component_type,
324
+ index_names,
325
+ timestep_type,
326
+ timestep_name,
327
+ file_name,
328
+ doc,
329
+ has_units
330
+ )
331
+ return ans
332
+
305
333
 
306
334
  class SolutionLoader():
307
335
  """
@@ -312,6 +340,7 @@ class SolutionLoader():
312
340
  self.path = path
313
341
  assert len(os.listdir(path)) > 0, f"Path {path} is empty."
314
342
  self._scenarios: dict[str, Scenario] = self._read_scenarios()
343
+ self._ureg = get_first_scenario(self._scenarios).ureg
315
344
  self._series_cache: dict[str, "pd.Series[Any]"] = {}
316
345
  self.enable_cache = enable_cache
317
346
 
@@ -467,14 +496,13 @@ class SolutionLoader():
467
496
  """
468
497
  scenarios_json_path = os.path.join(self.path, "scenarios.json")
469
498
  ans: dict[str, Scenario] = {}
470
- default_ureg = pint.UnitRegistry()
471
499
  with open(scenarios_json_path, "r") as f:
472
500
  scenario_configs = json.load(f)
473
501
 
474
502
  if len(scenario_configs) == 1:
475
503
  scenario_name = "none"
476
504
  scenario_path = self.path
477
- ans[scenario_name] = Scenario(scenario_path, scenario_name, "",default_ureg)
505
+ ans[scenario_name] = Scenario(scenario_path, scenario_name, "")
478
506
  else:
479
507
  for scenario_id, scenario_config in scenario_configs.items():
480
508
  scenario_name = f"scenario_{scenario_id}"
@@ -494,7 +522,7 @@ class SolutionLoader():
494
522
  )
495
523
 
496
524
  scenario = Scenario(
497
- scenario_path, scenario_name, base_scenario, default_ureg
525
+ scenario_path, scenario_name, base_scenario
498
526
  )
499
527
 
500
528
  if scenario.exists:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zen_garden
3
- Version: 2.9.0
3
+ Version: 2.9.1
4
4
  Summary: ZEN-garden is an optimization model of energy systems and value chains.
5
5
  Author: Alissa Ganter, Johannes Burger, Francesco De Marco, Lukas Kunz, Lukas Schmidt-Engelbertz, Christoph Funke, Paolo Gabrielli, Giovanni Sansavini
6
6
  Author-email: Jacob Mannhardt <zen-garden@ethz.ch>
@@ -1,6 +1,6 @@
1
1
  zen_garden/__init__.py,sha256=vFEb5EpCLlaX_sxgqcwQge-HUzdq7nUGyXcol6F7dhE,722
2
2
  zen_garden/__main__.py,sha256=Zrz6zr81gXN3_NLPwWz3a-8HiiRgqGx_OzQHarBcxtQ,2508
3
- zen_garden/default_config.py,sha256=vys7xf_s0GrH9SSLCkDF3im6FONb15JE73wLT9yZ3_o,8426
3
+ zen_garden/default_config.py,sha256=Ti8MWdwB_9um5w8gk36vxUF3CVL5xYJAPMbhRqE8XYw,8428
4
4
  zen_garden/optimization_setup.py,sha256=--nxXr28v2p1EHwqFIREXAhesUg5MfOTPwHWImFSOnM,35441
5
5
  zen_garden/runner.py,sha256=8wGfLhevbeMMf5qDDsLdfI3fO78KCHFwSk23_xDcBVc,6739
6
6
  zen_garden/utils.py,sha256=GFR-LBIkMA7pDQ46J07mr0ujqyIfNPlI0UVnvBDfHRw,60529
@@ -28,8 +28,8 @@ zen_garden/postprocess/comparisons.py,sha256=uyEtV0Q8_YPzJi4b12DWiqYU-kKJz6I3Li-
28
28
  zen_garden/postprocess/postprocess.py,sha256=r8aQf1oXX2SwKj1tj_Wc186RQtAF-G4fKH_qBtTIFHg,28377
29
29
  zen_garden/postprocess/results/__init__.py,sha256=363lzC0uRJ5F42cOEhD9jxMPCioTt8WRt0qwZG0IizY,49
30
30
  zen_garden/postprocess/results/cache.py,sha256=t-1P7k9EVkSxR1oB1NIodux3JbfhBhxxwgRytcQ8vjQ,1592
31
- zen_garden/postprocess/results/results.py,sha256=S21h0Unf4l3a8WD0UFvn8IeMgDxKitZRaiX7iLvJnL0,41012
32
- zen_garden/postprocess/results/solution_loader.py,sha256=VfmkEipLG5im3wm0aYA5qqg1ZvRutfZbvFeUvwZRoh8,31700
31
+ zen_garden/postprocess/results/results.py,sha256=u1ZXkGrantxP6r3sj2Y2MNAtd7R4OotM_qd8OjA1iuE,40759
32
+ zen_garden/postprocess/results/solution_loader.py,sha256=23o2MBp_HPaF9IqJvgLqAii8_cYcAoHpTuyze8_ppBc,32764
33
33
  zen_garden/preprocess/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  zen_garden/preprocess/extract_input_data.py,sha256=PWKdel7s488SELseyAaoFkwXpzJU4MZg0pW0wO2ZHoI,51523
35
35
  zen_garden/preprocess/parameter_change_log.py,sha256=WNhLYTyuaFkUl_e4QH36W1chpqg00m7zg__PawPogAY,387
@@ -38,8 +38,8 @@ zen_garden/preprocess/unit_handling.py,sha256=08sFQMR6hjKos_ANgfGIc3BLm3lCMmpuu1
38
38
  zen_garden/wrapper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
39
  zen_garden/wrapper/operation_scenarios.py,sha256=qfEMqnEc5qA10lO-rVGzVqvz_6MBNDIjZlrCncCpNJo,8499
40
40
  zen_garden/wrapper/utils.py,sha256=YY-HSPQ2UPwws5PAumvBzq4tp-yUcbUqILkTyI_Z2TU,16352
41
- zen_garden-2.9.0.dist-info/entry_points.txt,sha256=xtDb4g8Mho0X9g55niFwiJlajN8XGdTrLkhgyBz5hhs,304
42
- zen_garden-2.9.0.dist-info/licenses/LICENSE.txt,sha256=_kEtxPe9gWOwMzdiy8nLzgABiPdMvUS0kaSCOIrEA_E,1101
43
- zen_garden-2.9.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
44
- zen_garden-2.9.0.dist-info/METADATA,sha256=cbzz6CgzUOOrk4tYepRyEAWhbUA3gpi8vwYglryQ8wQ,5796
45
- zen_garden-2.9.0.dist-info/RECORD,,
41
+ zen_garden-2.9.1.dist-info/entry_points.txt,sha256=xtDb4g8Mho0X9g55niFwiJlajN8XGdTrLkhgyBz5hhs,304
42
+ zen_garden-2.9.1.dist-info/licenses/LICENSE.txt,sha256=_kEtxPe9gWOwMzdiy8nLzgABiPdMvUS0kaSCOIrEA_E,1101
43
+ zen_garden-2.9.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
44
+ zen_garden-2.9.1.dist-info/METADATA,sha256=1nVRgcKuUZ_kfn0UzVHO26go9rTRCdP3HRCB52MYKFU,5796
45
+ zen_garden-2.9.1.dist-info/RECORD,,