zen-garden 2.7.9__tar.gz → 2.7.10__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 (36) hide show
  1. {zen_garden-2.7.9 → zen_garden-2.7.10}/PKG-INFO +1 -1
  2. {zen_garden-2.7.9 → zen_garden-2.7.10}/pyproject.toml +1 -1
  3. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/__main__.py +5 -7
  4. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/_internal.py +2 -1
  5. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/postprocess.py +11 -4
  6. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/results/results.py +65 -9
  7. {zen_garden-2.7.9 → zen_garden-2.7.10}/LICENSE.txt +0 -0
  8. {zen_garden-2.7.9 → zen_garden-2.7.10}/README.md +0 -0
  9. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/__init__.py +0 -0
  10. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/default_config.py +0 -0
  11. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/__init__.py +0 -0
  12. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/carrier/__init__.py +0 -0
  13. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/carrier/carrier.py +0 -0
  14. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/component.py +0 -0
  15. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/element.py +0 -0
  16. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/energy_system.py +0 -0
  17. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/__init__.py +0 -0
  18. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/conversion_technology.py +0 -0
  19. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/retrofitting_technology.py +0 -0
  20. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/storage_technology.py +0 -0
  21. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/technology.py +0 -0
  22. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/technology/transport_technology.py +0 -0
  23. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/model/time_steps.py +0 -0
  24. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/optimization_setup.py +0 -0
  25. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/.gitkeep +0 -0
  26. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/__init__.py +0 -0
  27. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/comparisons.py +0 -0
  28. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/results/__init__.py +0 -0
  29. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/postprocess/results/solution_loader.py +0 -0
  30. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/preprocess/__init__.py +0 -0
  31. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/preprocess/extract_input_data.py +0 -0
  32. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/preprocess/parameter_change_log.py +0 -0
  33. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/preprocess/time_series_aggregation.py +0 -0
  34. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/preprocess/unit_handling.py +0 -0
  35. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/utils.py +0 -0
  36. {zen_garden-2.7.9 → zen_garden-2.7.10}/zen_garden/visualization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zen_garden
3
- Version: 2.7.9
3
+ Version: 2.7.10
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, Paolo Gabrielli, Giovanni Sansavini
6
6
  Author-email: Jacob Mannhardt <zen-garden@ethz.ch>
@@ -15,7 +15,7 @@ authors = [
15
15
  {name = "Giovanni Sansavini"},
16
16
  ]
17
17
  # do not change version manually! Done by bump2version
18
- version = "2.7.9"
18
+ version = "2.7.10"
19
19
  requires-python= ">=3.11,<3.14"
20
20
  description="ZEN-garden is an optimization model of energy systems and value chains."
21
21
  readme = "README.md"
@@ -10,6 +10,7 @@ import os
10
10
  import zen_garden.default_config as default_config
11
11
  import json
12
12
  from zen_garden.utils import copy_dataset_example
13
+ from pathlib import Path
13
14
 
14
15
  def run_module(args=None, config = "./config.py", dataset = None,
15
16
  folder_output = None, job_index = None, job_index_var = "SLURM_ARRAY_TASK_ID",
@@ -32,7 +33,7 @@ def run_module(args=None, config = "./config.py", dataset = None,
32
33
  parser.add_argument("--config", required=False, type=str, default=config, help="Path to the config file used to run the pipeline (e.g., `./config.json`). Alternatively, if the config file is located in the current working directory, then the file name is alone is also acceptable (e.g. `config.json`).")
33
34
  parser.add_argument("--dataset", required=False, type=str, default=dataset, help="Path to the dataset (e.g. `./<dataset_name>`). Alternatively, if the dataset is located in the current working directory, then the folder name alone is also acceptable (e.g. `<dataset_name>`). IMPORTANT: This will overwrite the config.analysis.dataset attribute of the config file!")
34
35
  parser.add_argument("--folder_output", required=False, type=str, default=folder_output, help="Path to the folder where results of the run are stored. IMPORTANT: This will overwrite the "
35
- "config.analysis.folder_output attribute of the config file!")
36
+ "config.analysis.folder_output attribute and the config.solver.solver_dir attribute of the config file!")
36
37
  parser.add_argument("--job_index", required=False, type=str, default=job_index, help="A comma separated list (no spaces) of indices of the scenarios to run, if None, all scenarios are run in sequence")
37
38
  parser.add_argument("--job_index_var", required=False, type=str, default=job_index_var, help="Try to read out the job index from the environment variable specified here. "
38
39
  "If both --job_index and --job_index_var are specified, --job_index will be used.")
@@ -48,18 +49,15 @@ def run_module(args=None, config = "./config.py", dataset = None,
48
49
  if not os.path.exists(args.config):
49
50
  args.config = args.config.replace(".py", ".json")
50
51
 
51
- # change working directory to the directory of the config file
52
-
53
- config_path, config_file = os.path.split(os.path.abspath(args.config))
54
- os.chdir(config_path)
55
52
  ### import the config
53
+ config_path, config_file = os.path.split(os.path.abspath(args.config))
56
54
  if config_file.endswith(".py"):
57
- spec = importlib.util.spec_from_file_location("module", config_file)
55
+ spec = importlib.util.spec_from_file_location("module", Path(config_path) / config_file)
58
56
  module = importlib.util.module_from_spec(spec)
59
57
  spec.loader.exec_module(module)
60
58
  config = module.config
61
59
  else:
62
- with open(args.config, "r") as f:
60
+ with open(Path(config_path) / config_file, "r") as f:
63
61
  config = default_config.Config(**json.load(f))
64
62
 
65
63
  ### get the job index
@@ -37,7 +37,8 @@ def main(config, dataset_path=None, job_index=None, folder_output_path=None):
37
37
  # logging.info(f"Overwriting dataset to: {dataset_path}")
38
38
  config.analysis.dataset = dataset_path
39
39
  if folder_output_path is not None:
40
- config.analysis.folder_output = folder_output_path
40
+ config.analysis.folder_output = os.path.abspath(folder_output_path)
41
+ config.solver.solver_dir = os.path.abspath(folder_output_path)
41
42
  logging.info(f"Optimizing for dataset {config.analysis.dataset}")
42
43
  # get the abs path to avoid working dir stuff
43
44
  config.analysis.dataset = os.path.abspath(config.analysis.dataset)
@@ -434,8 +434,9 @@ class Postprocess:
434
434
  fname = self.name_dir.joinpath('analysis')
435
435
  # remove cwd path part to avoid saving the absolute path
436
436
  if os.path.isabs(self.analysis.dataset):
437
- self.analysis.dataset = os.path.split(Path(self.analysis.dataset))[-1]
438
- self.analysis.folder_output = os.path.split(Path(self.analysis.folder_output))[-1]
437
+ cwd = os.getcwd()
438
+ self.analysis.dataset = os.path.relpath(self.analysis.dataset,cwd)
439
+ self.analysis.folder_output = os.path.relpath(self.analysis.folder_output, cwd)
439
440
  self.write_file(fname, self.analysis, format="json")
440
441
 
441
442
  def save_solver(self):
@@ -447,6 +448,12 @@ class Postprocess:
447
448
  fname = self.name_dir.parent.joinpath('solver')
448
449
  else:
449
450
  fname = self.name_dir.joinpath('solver')
451
+
452
+ # remove cwd path part to avoid saving the absolute path
453
+ if os.path.isabs(self.solver.solver_dir):
454
+ cwd = os.getcwd()
455
+ self.solver.solver_dir = os.path.relpath(self.solver.solver_dir,cwd)
456
+ # save
450
457
  self.write_file(fname, self.solver, format="json")
451
458
 
452
459
  def save_scenarios(self):
@@ -454,8 +461,8 @@ class Postprocess:
454
461
  Saves the scenario dict as json
455
462
  """
456
463
  # only save the scenarios at the highest level
457
- root_path = Path(self.analysis.folder_output).joinpath(self.model_name)
458
- fname = root_path.joinpath('scenarios')
464
+ root_dir = Path(self.analysis.folder_output).joinpath(self.model_name)
465
+ fname = root_dir.joinpath('scenarios')
459
466
  self.write_file(fname, self.scenarios, format="json")
460
467
 
461
468
  def save_unit_definitions(self):
@@ -569,10 +569,28 @@ class Results:
569
569
 
570
570
  def get_system(self, scenario_name: Optional[str] = None) -> System:
571
571
  """
572
- Extracts the System config of a given Scenario. If no scenario is given, a random one is taken.
572
+ Extract system configurations from a scenario.
573
+
574
+ Extracts system configurations from the results of a scenario. This
575
+ ensures the tractability of model configurations. System configurations
576
+ are those specified in the ``system.json`` file of a given model.
577
+
578
+ Args:
579
+ scenario_name (str, optional): The name of the scenario for which
580
+ to extract the system configuration. If no value is given, then
581
+ the first scenario is used. Default value: ``None``.
582
+
583
+ Returns:
584
+ System: System configuration.
585
+
586
+ Examples:
587
+ Basic usage example:
588
+
589
+ >>> from zen_garden.postprocess.results.results import Results
590
+ >>> r = Results(path='<result_folder>')
591
+ >>> r.get_system() # system configurations of first scenario
592
+ >>> r.get_system('scenario_name') # system configuration of "scenario_name"
573
593
 
574
- :param scenario_name: Name of the scenario
575
- :return: The corresponding System config
576
594
  """
577
595
  if scenario_name is None:
578
596
  scenario_name = next(iter(self.solution_loader.scenarios.keys()))
@@ -580,10 +598,29 @@ class Results:
580
598
 
581
599
  def get_analysis(self, scenario_name: Optional[str] = None) -> Analysis:
582
600
  """
583
- Extracts the Analysis config of a given Scenario. If no scenario is given, a random one is taken.
601
+ Extract analysis configurations from a scenario.
602
+
603
+ Extracts analysis configurations from the results of a scenario. This
604
+ ensures the tractability of model configurations. Analysis configurations
605
+ are those specified under the ``analysis`` object in the ``config.json``
606
+ file.
607
+
608
+ Args:
609
+ scenario_name (str, optional): The name of the scenario for which
610
+ to extract the system configuration. If no value is given, then
611
+ the first scenario is used. Default value: ``None``.
612
+
613
+ Returns:
614
+ Analysis: Analysis configuration.
615
+
616
+ Examples:
617
+ Basic usage example:
618
+
619
+ >>> from zen_garden.postprocess.results.results import Results
620
+ >>> r = Results(path='<result_folder>')
621
+ >>> r.get_analysis() # analysis configurations of first scenario
622
+ >>> r.get_analysis('scenario_name') # analysis configuration of "scenario_name"
584
623
 
585
- :param scenario_name: Name of the scenario
586
- :return: The corresponding Analysis config
587
624
  """
588
625
  if scenario_name is None:
589
626
  scenario_name = next(iter(self.solution_loader.scenarios.keys()))
@@ -591,10 +628,29 @@ class Results:
591
628
 
592
629
  def get_solver(self, scenario_name: Optional[str] = None) -> Solver:
593
630
  """
594
- Extracts the Solver config of a given Scenario. If no scenario is given, a random one is taken.
631
+ Extract solver configurations from a scenario.
632
+
633
+ Extracts solver configurations from the results of a scenario. This
634
+ ensures the tractability of model configurations. Solver configurations
635
+ are those specified under the ``solver`` object in the ``config.json``
636
+ file.
637
+
638
+ Args:
639
+ scenario_name (str, optional): The name of the scenario for which
640
+ to extract the system configuration. If no value is given, then
641
+ the first scenario is used. Default value: ``None``.
642
+
643
+ Returns:
644
+ Solver: Solver configuration.
645
+
646
+ Examples:
647
+ Basic usage example:
648
+
649
+ >>> from zen_garden.postprocess.results.results import Results
650
+ >>> r = Results(path='<result_folder>')
651
+ >>> r.get_solver() # solver configurations of first scenario
652
+ >>> r.get_solver('scenario_name') # solver configuration of "scenario_name"
595
653
 
596
- :param scenario_name: Name of the scenario
597
- :return: The corresponding Solver config
598
654
  """
599
655
  if scenario_name is None:
600
656
  scenario_name = next(iter(self.solution_loader.scenarios.keys()))
File without changes
File without changes