zen-garden 2.7.18__tar.gz → 2.7.20__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.
- {zen_garden-2.7.18 → zen_garden-2.7.20}/PKG-INFO +1 -1
- {zen_garden-2.7.18 → zen_garden-2.7.20}/pyproject.toml +4 -3
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/__init__.py +6 -1
- zen_garden-2.7.20/zen_garden/__main__.py +71 -0
- zen_garden-2.7.20/zen_garden/cli/zen_example.py +43 -0
- zen_garden-2.7.20/zen_garden/cli/zen_garden.py +165 -0
- zen_garden-2.7.20/zen_garden/cli/zen_visualization.py +24 -0
- zen_garden-2.7.20/zen_garden/preprocess/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/preprocess/unit_handling.py +1 -1
- zen_garden-2.7.18/zen_garden/_internal.py → zen_garden-2.7.20/zen_garden/runner.py +59 -13
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/utils.py +88 -23
- zen_garden-2.7.18/zen_garden/__main__.py +0 -77
- zen_garden-2.7.18/zen_garden/visualization.py +0 -4
- {zen_garden-2.7.18 → zen_garden-2.7.20}/LICENSE.txt +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/README.md +0 -0
- {zen_garden-2.7.18/zen_garden/postprocess → zen_garden-2.7.20/zen_garden/cli}/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/default_config.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/carrier/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/carrier/carrier.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/component.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/element.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/energy_system.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/conversion_technology.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/retrofitting_technology.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/storage_technology.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/technology.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/transport_technology.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/time_steps.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/optimization_setup.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/.gitkeep +0 -0
- {zen_garden-2.7.18/zen_garden/preprocess → zen_garden-2.7.20/zen_garden/postprocess}/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/comparisons.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/postprocess.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/results/__init__.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/results/results.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/postprocess/results/solution_loader.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/preprocess/extract_input_data.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/preprocess/parameter_change_log.py +0 -0
- {zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/preprocess/time_series_aggregation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zen_garden
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.20
|
|
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>
|
|
@@ -16,7 +16,7 @@ authors = [
|
|
|
16
16
|
{name = "Giovanni Sansavini"},
|
|
17
17
|
]
|
|
18
18
|
# do not change version manually! Done by bump2version
|
|
19
|
-
version = "2.7.
|
|
19
|
+
version = "2.7.20"
|
|
20
20
|
requires-python= ">=3.11,<3.14"
|
|
21
21
|
description="ZEN-garden is an optimization model of energy systems and value chains."
|
|
22
22
|
readme = "README.md"
|
|
@@ -78,5 +78,6 @@ Zenodo = "https://zenodo.org/api/records/13385110"
|
|
|
78
78
|
addopts = "-n auto"
|
|
79
79
|
|
|
80
80
|
[project.scripts]
|
|
81
|
-
zen-garden = "zen_garden.
|
|
82
|
-
zen-visualization = "zen_garden.
|
|
81
|
+
zen-garden = "zen_garden.cli.zen_garden:cli_zen_garden"
|
|
82
|
+
zen-visualization = "zen_garden.cli.zen_visualization:cli_zen_visualization"
|
|
83
|
+
zen-example = "zen_garden.cli.zen_example:cli_zen_example"
|
|
@@ -2,9 +2,14 @@ from . import model
|
|
|
2
2
|
from . import postprocess
|
|
3
3
|
from . import preprocess
|
|
4
4
|
from .utils import get_inheritors
|
|
5
|
-
|
|
6
5
|
from .model.element import Element
|
|
7
6
|
from .optimization_setup import OptimizationSetup
|
|
7
|
+
from .runner import run
|
|
8
|
+
from .postprocess.results.results import Results
|
|
9
|
+
from .utils import download_example_dataset
|
|
10
|
+
|
|
11
|
+
__all__ = ["run", "Results", "download_example_dataset"]
|
|
12
|
+
|
|
8
13
|
|
|
9
14
|
# set the element classes of the EnergySystem class
|
|
10
15
|
inheritors = get_inheritors(Element)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runs the main function of ZEN-Garden.
|
|
3
|
+
Compilation of the optimization problem.
|
|
4
|
+
"""
|
|
5
|
+
from .runner import run
|
|
6
|
+
from .cli.zen_garden import cli_zen_garden
|
|
7
|
+
import warnings
|
|
8
|
+
|
|
9
|
+
def run_module(config = "./config.py", dataset = None,
|
|
10
|
+
folder_output = None, job_index = None):
|
|
11
|
+
"""
|
|
12
|
+
Deprecated wrapper for ``zen_garden.runner.run()``.
|
|
13
|
+
|
|
14
|
+
This function mirrors the behavior of
|
|
15
|
+
``zen_garden.runner.run()`` and exists solely for backward
|
|
16
|
+
compatibility with older versions of ZEN_garden, where
|
|
17
|
+
``zen_garden.__main__.run_module()`` served as the primary entry point.
|
|
18
|
+
|
|
19
|
+
This function is deprecated and will be removed in ZEN-garden v3.0.0.
|
|
20
|
+
Users should migrate to ``zen_garden.runner.run()``.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
config (str): Path to the configuration file (e.g. ``config.json``).
|
|
24
|
+
If the file is located in the current working directory, the
|
|
25
|
+
filename alone may be specified. Defaults to ``"./config.py"``.
|
|
26
|
+
dataset (str): Path to the folder containing the input dataset
|
|
27
|
+
(e.g. ``"./1_base_case"``). If located in the current working
|
|
28
|
+
directory, the folder name alone may be used. Defaults to the
|
|
29
|
+
``dataset`` value specified in the configuration file.
|
|
30
|
+
folder_output (str): Path to the folder where outputs will be saved.
|
|
31
|
+
Defaults to ``"./outputs"``.
|
|
32
|
+
job_index (list[int] | None): Indices of jobs (scenarios) to run.
|
|
33
|
+
For example, ``job_index=[1]`` runs only the first scenario.
|
|
34
|
+
Defaults to ``None`` (run all jobs).
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
DeprecationWarning: This function will be removed in ZEN-garden v3.0.0.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
OptimizationSetup: The fully set up and solved optimization problem.
|
|
41
|
+
|
|
42
|
+
See Also:
|
|
43
|
+
zen_garden.runner.run: Replacement function.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
>>> from zen_garden import run, copy_example_dataset
|
|
47
|
+
>>> download_example_dataset("1_base_case")
|
|
48
|
+
>>> run("1_base_case")
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# throw deprecation warning
|
|
53
|
+
warnings.warn(
|
|
54
|
+
"zen_garden.__main__.run_module() is deprecated and will be removed " \
|
|
55
|
+
"in ZEN-garden v3.0.0. Please use the new version " \
|
|
56
|
+
"zen_garden.runner.run() instead.",
|
|
57
|
+
DeprecationWarning,
|
|
58
|
+
stacklevel=2
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# run new function
|
|
62
|
+
return run(
|
|
63
|
+
config = config,
|
|
64
|
+
dataset = dataset,
|
|
65
|
+
folder_output=folder_output,
|
|
66
|
+
job_index=job_index
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
|
|
71
|
+
cli_zen_garden()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
from zen_garden.utils import download_example_dataset
|
|
4
|
+
|
|
5
|
+
def cli_zen_example():
|
|
6
|
+
"""
|
|
7
|
+
Entry point for the `zen-example` command-line interface.
|
|
8
|
+
|
|
9
|
+
Creates a command line interface for downloading the dataset examples.
|
|
10
|
+
The function parses a single required argument ``--dataset`` that
|
|
11
|
+
specifies the name of the dataset to be downloaded. It then invokes
|
|
12
|
+
the function function ``download_example_dataset`` with that argument.
|
|
13
|
+
|
|
14
|
+
The ``[project.scripts]`` section of the pyproject.toml declares that
|
|
15
|
+
this function will be called whenever a user enters ``zen-example`` into
|
|
16
|
+
the command prompt. This function is therefore creates the ``zen-example``
|
|
17
|
+
command line entry point.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
Basic usage in a command line prompt:
|
|
21
|
+
|
|
22
|
+
>>> zen-example --dataset="1_base_case"
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
# parse the args
|
|
26
|
+
description = "Downloads an example dataset for ZEN-garden to the current" \
|
|
27
|
+
"working directory"
|
|
28
|
+
|
|
29
|
+
parser = argparse.ArgumentParser(
|
|
30
|
+
description=description,
|
|
31
|
+
add_help=True,
|
|
32
|
+
usage="usage: zen-example [--dataset DATASET]")
|
|
33
|
+
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
"--dataset",
|
|
36
|
+
required=True,
|
|
37
|
+
type=str,
|
|
38
|
+
help="Name of the dataset to download, e.g. '1_base_case'")
|
|
39
|
+
|
|
40
|
+
args = parser.parse_args(sys.argv[1:])
|
|
41
|
+
|
|
42
|
+
# download the example
|
|
43
|
+
download_example_dataset(args.dataset)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from zen_garden.runner import run
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
# ---------------------------------------------------------------------------
|
|
6
|
+
# Command-line interface
|
|
7
|
+
# ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
10
|
+
"""Build the command-line argument parser for ZEN-garden.
|
|
11
|
+
|
|
12
|
+
This function defines all supported command-line options for running
|
|
13
|
+
ZEN-garden. The parser handles configuration file selection, dataset and
|
|
14
|
+
output directory overrides, and job indexing for array or batch execution.
|
|
15
|
+
|
|
16
|
+
Command Line Flags:
|
|
17
|
+
--config (str, optional):
|
|
18
|
+
Path to a Python or JSON configuration file. If not provided, the
|
|
19
|
+
configuration is read from the current working directory.
|
|
20
|
+
|
|
21
|
+
--dataset (str, optional):
|
|
22
|
+
Path to the dataset directory. Overrides
|
|
23
|
+
``config.analysis.dataset`` in the configuration file.
|
|
24
|
+
|
|
25
|
+
--folder_output (str, optional):
|
|
26
|
+
Path to the output directory. Overrides output-related settings in
|
|
27
|
+
the configuration file. If not specified, output is written to the
|
|
28
|
+
current working directory.
|
|
29
|
+
|
|
30
|
+
--job_index (str, optional):
|
|
31
|
+
Comma-separated list of scenario or job indices to execute. If not
|
|
32
|
+
provided, the value is read from the environment variable specified
|
|
33
|
+
by ``--job_index_var``.
|
|
34
|
+
|
|
35
|
+
--job_index_var (str, optional):
|
|
36
|
+
Name of the environment variable containing the job index.
|
|
37
|
+
Defaults to ``SLURM_ARRAY_TASK_ID``.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
argparse.ArgumentParser: An argument parser configured for the
|
|
41
|
+
ZEN-Garden command-line interface.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
description = (
|
|
45
|
+
"Run ZEN-Garden with a given config file. By default, the config file "
|
|
46
|
+
"is read from the current working directory. You may specify a config "
|
|
47
|
+
"file with --config. Output is always written to the current working "
|
|
48
|
+
"directory unless overridden."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
parser = argparse.ArgumentParser(
|
|
52
|
+
description=description,
|
|
53
|
+
add_help=True,
|
|
54
|
+
usage="zen_garden [options]"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"--config", type=str, required=False, default=None,
|
|
59
|
+
help="Path to a Python or JSON config file."
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
"--dataset", type=str, required=False, default=None,
|
|
63
|
+
help="Path to the dataset directory. Overrides config.analysis.dataset."
|
|
64
|
+
)
|
|
65
|
+
parser.add_argument(
|
|
66
|
+
"--folder_output", type=str, required=False, default=None,
|
|
67
|
+
help="Path to the output directory. Overrides output settings in config."
|
|
68
|
+
)
|
|
69
|
+
parser.add_argument(
|
|
70
|
+
"--job_index", type=str, required=False, default=None,
|
|
71
|
+
help="Comma-separated list of scenario indices. If omitted, the "
|
|
72
|
+
"environment variable specified by --job_index_var is used."
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--job_index_var", type=str, required=False,
|
|
76
|
+
default="SLURM_ARRAY_TASK_ID",
|
|
77
|
+
help="Environment variable for job index."
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return parser
|
|
81
|
+
|
|
82
|
+
def resolve_job_index(job_index:str, job_index_var:str) -> list[int]:
|
|
83
|
+
"""
|
|
84
|
+
Resolves the job index when running ZEN-garden from the command line.
|
|
85
|
+
|
|
86
|
+
If the job index is directly specified using the ``job_index`` command-line
|
|
87
|
+
flag, those values are used. Otherwise, the job index is extracted from the
|
|
88
|
+
environment variable specified by the ``job_index_var`` command-line flag.
|
|
89
|
+
If neither is defined, ``None`` is returned.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
job_index (str): Value of the ``job_index`` command-line flag provided
|
|
93
|
+
by the user.
|
|
94
|
+
job_index_var (str): Value of the ``job_index_var`` command-line flag
|
|
95
|
+
provided by the user.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
list[int] | None: List of job indices to run in the current instance of
|
|
99
|
+
ZEN-garden, or ``None`` if no job index is specified.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
if job_index:
|
|
103
|
+
return [int(i) for i in job_index.split(",")]
|
|
104
|
+
elif ((env_value := os.environ.get(job_index_var)) is not None):
|
|
105
|
+
return [int(env_value)]
|
|
106
|
+
else:
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def cli_zen_garden():
|
|
111
|
+
"""
|
|
112
|
+
Entry point for the `zen-garden` command-line interface.
|
|
113
|
+
|
|
114
|
+
This function creates the command-line interface for running ZEN-garden.
|
|
115
|
+
It first sets up an argument parser; extracts the job index (either from
|
|
116
|
+
the input flax directly or from an environment variable), and then
|
|
117
|
+
calls the ``zen_garden.run()`` function.
|
|
118
|
+
|
|
119
|
+
The ``[project.scripts]`` section of the pyproject.toml declares that
|
|
120
|
+
this function will be called whenever a user enters ``zen-garden`` into
|
|
121
|
+
the command prompt.
|
|
122
|
+
|
|
123
|
+
Command Line Flags:
|
|
124
|
+
--config (str, optional):
|
|
125
|
+
Path to a Python or JSON configuration file. If not provided, the
|
|
126
|
+
configuration is read from the current working directory.
|
|
127
|
+
|
|
128
|
+
--dataset (str, optional):
|
|
129
|
+
Path to the dataset directory. Overrides
|
|
130
|
+
``config.analysis.dataset`` in the configuration file.
|
|
131
|
+
|
|
132
|
+
--folder_output (str, optional):
|
|
133
|
+
Path to the output directory. Overrides output-related settings in
|
|
134
|
+
the configuration file. If not specified, output is written to the
|
|
135
|
+
current working directory.
|
|
136
|
+
|
|
137
|
+
--job_index (str, optional):
|
|
138
|
+
Comma-separated list of scenario or job indices to execute. If not
|
|
139
|
+
provided, the value is read from the environment variable specified
|
|
140
|
+
by ``--job_index_var``.
|
|
141
|
+
|
|
142
|
+
--job_index_var (str, optional):
|
|
143
|
+
Name of the environment variable containing the job index.
|
|
144
|
+
Defaults to ``SLURM_ARRAY_TASK_ID``.
|
|
145
|
+
Examples:
|
|
146
|
+
Basic usage in a command line prompt:
|
|
147
|
+
|
|
148
|
+
>>> zen-garden --config=".\config.json" --dataset="1_base_case"
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
None
|
|
152
|
+
"""
|
|
153
|
+
# parse command line arguments
|
|
154
|
+
parser = build_parser()
|
|
155
|
+
args = parser.parse_args()
|
|
156
|
+
|
|
157
|
+
### get the job index
|
|
158
|
+
job_index = resolve_job_index(args.job_index, args.job_index_var)
|
|
159
|
+
|
|
160
|
+
run(
|
|
161
|
+
config=args.config,
|
|
162
|
+
dataset = args.dataset,
|
|
163
|
+
folder_output = args.folder_output,
|
|
164
|
+
job_index = job_index,
|
|
165
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from zen_temple.main import parse_arguments_and_run
|
|
2
|
+
|
|
3
|
+
def cli_zen_visualization():
|
|
4
|
+
"""
|
|
5
|
+
Entry point for the `zen-visualization` command-line interface.
|
|
6
|
+
|
|
7
|
+
This function initializes and runs the command-line interface (CLI)
|
|
8
|
+
for the ZEN-garden visualization platform. It delegates argument parsing
|
|
9
|
+
and command execution to the `parse_arguments_and_run` command of
|
|
10
|
+
the ``ZEN-temple`` package.
|
|
11
|
+
|
|
12
|
+
The ``[project.scripts]`` section of the pyproject.toml declares that
|
|
13
|
+
this function will be called whenever a user enters ``zen-visualization``
|
|
14
|
+
into the command prompt.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
None
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
Basic usage in a command line prompt:
|
|
21
|
+
|
|
22
|
+
>>> zen-visualization
|
|
23
|
+
"""
|
|
24
|
+
parse_arguments_and_run()
|
|
File without changes
|
|
@@ -729,7 +729,7 @@ class Scaling:
|
|
|
729
729
|
|
|
730
730
|
def run_scaling(self):
|
|
731
731
|
"""
|
|
732
|
-
Runs the scaling algorithm. Function called in
|
|
732
|
+
Runs the scaling algorithm. Function called in runner.py.
|
|
733
733
|
"""
|
|
734
734
|
logging.info(f"\n--- Start Scaling ---\n")
|
|
735
735
|
t0 = time.perf_counter()
|
|
@@ -3,26 +3,52 @@ This function runs ZEN garden,it is executed in the __main__.py script.
|
|
|
3
3
|
Compilation of the optimization problem.
|
|
4
4
|
"""
|
|
5
5
|
import importlib.util
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
import logging
|
|
7
8
|
import os
|
|
8
9
|
import importlib
|
|
9
10
|
from .optimization_setup import OptimizationSetup
|
|
10
11
|
from .postprocess.postprocess import Postprocess
|
|
11
12
|
from .utils import setup_logger, InputDataChecks, StringUtils, ScenarioUtils
|
|
13
|
+
import zen_garden.default_config as default_config
|
|
14
|
+
import json
|
|
15
|
+
import warnings
|
|
12
16
|
|
|
13
17
|
# we setup the logger here
|
|
14
18
|
setup_logger()
|
|
15
19
|
|
|
16
20
|
|
|
17
|
-
def
|
|
21
|
+
def run(config = "./config.json", dataset=None, job_index=None,
|
|
22
|
+
folder_output=None):
|
|
18
23
|
"""
|
|
19
|
-
|
|
20
|
-
it is executed in the __main__.py script
|
|
24
|
+
Run ZEN-garden.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
This function is the primary programmatic entry point for running
|
|
27
|
+
ZEN-garden. When called, it reads the configuration, loads the model
|
|
28
|
+
input data, constructs and solves the optimization problem, and saves
|
|
29
|
+
the results.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
config (str): Path to the configuration file (e.g. ``config.json``).
|
|
33
|
+
If the file is located in the current working directory, the
|
|
34
|
+
filename alone may be specified. Defaults to ``"./config.json"``.
|
|
35
|
+
dataset (str): Path to the folder containing the input dataset
|
|
36
|
+
(e.g. ``"./1_base_case"``). If located in the current working
|
|
37
|
+
directory, the folder name alone may be used. Defaults to the
|
|
38
|
+
``dataset`` value specified in the configuration file.
|
|
39
|
+
folder_output (str): Path to the folder where outputs will be saved.
|
|
40
|
+
Defaults to ``"./outputs"``.
|
|
41
|
+
job_index (list[int] | None): Indices of jobs (scenarios) to run.
|
|
42
|
+
For example, ``job_index=[1]`` runs only the first scenario.
|
|
43
|
+
Defaults to ``None`` (run all jobs).
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
OptimizationSetup: The fully set up and solved optimization problem.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> from zen_garden import run, download_example_dataset
|
|
50
|
+
>>> download_example_dataset("1_base_case")
|
|
51
|
+
>>> run("1_base_case")
|
|
26
52
|
"""
|
|
27
53
|
|
|
28
54
|
# print the version
|
|
@@ -32,13 +58,33 @@ def main(config, dataset_path=None, job_index=None, folder_output_path=None):
|
|
|
32
58
|
# prevent double printing
|
|
33
59
|
logging.propagate = False
|
|
34
60
|
|
|
61
|
+
### import the config
|
|
62
|
+
if not os.path.exists(config):
|
|
63
|
+
config = config.replace(".py", ".json")
|
|
64
|
+
config_path, config_file = os.path.split(os.path.abspath(config))
|
|
65
|
+
if config_file.endswith(".py"):
|
|
66
|
+
spec = importlib.util.spec_from_file_location("module", Path(config_path) / config_file)
|
|
67
|
+
module = importlib.util.module_from_spec(spec)
|
|
68
|
+
spec.loader.exec_module(module)
|
|
69
|
+
config = module.config
|
|
70
|
+
warnings.warn(
|
|
71
|
+
"Use of the `config.py` file is deprecated and will be removed " \
|
|
72
|
+
"in ZEN-garden v3.0.0. Please switch to using a `config.json` " \
|
|
73
|
+
"file instead.",
|
|
74
|
+
DeprecationWarning,
|
|
75
|
+
stacklevel=2
|
|
76
|
+
)
|
|
77
|
+
else:
|
|
78
|
+
with open(Path(config_path) / config_file, "r") as f:
|
|
79
|
+
config = default_config.Config(**json.load(f))
|
|
80
|
+
|
|
35
81
|
# overwrite the path if necessary
|
|
36
|
-
if
|
|
82
|
+
if dataset is not None:
|
|
37
83
|
# logging.info(f"Overwriting dataset to: {dataset_path}")
|
|
38
|
-
config.analysis.dataset =
|
|
39
|
-
if
|
|
40
|
-
config.analysis.folder_output = os.path.abspath(
|
|
41
|
-
config.solver.solver_dir = os.path.abspath(
|
|
84
|
+
config.analysis.dataset = dataset
|
|
85
|
+
if folder_output is not None:
|
|
86
|
+
config.analysis.folder_output = os.path.abspath(folder_output)
|
|
87
|
+
config.solver.solver_dir = os.path.abspath(folder_output)
|
|
42
88
|
logging.info(f"Optimizing for dataset {config.analysis.dataset}")
|
|
43
89
|
# get the abs path to avoid working dir stuff
|
|
44
90
|
config.analysis.dataset = os.path.abspath(config.analysis.dataset)
|
|
@@ -101,4 +147,4 @@ def main(config, dataset_path=None, job_index=None, folder_output_path=None):
|
|
|
101
147
|
Postprocess(optimization_setup, scenarios=config.scenarios, subfolder=subfolder,
|
|
102
148
|
model_name=model_name, scenario_name=scenario_name, param_map=param_map)
|
|
103
149
|
logging.info("--- Optimization finished ---")
|
|
104
|
-
return optimization_setup
|
|
150
|
+
return optimization_setup
|
|
@@ -17,6 +17,10 @@ import shutil
|
|
|
17
17
|
from copy import deepcopy
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from zen_garden.default_config import Subscriptable
|
|
20
|
+
import requests
|
|
21
|
+
from importlib.metadata import metadata
|
|
22
|
+
import zipfile
|
|
23
|
+
import io
|
|
20
24
|
|
|
21
25
|
def setup_logger(level=logging.INFO):
|
|
22
26
|
""" set up logger
|
|
@@ -45,74 +49,135 @@ def get_inheritors(klass):
|
|
|
45
49
|
work.append(child)
|
|
46
50
|
return subclasses
|
|
47
51
|
|
|
52
|
+
def download_example_dataset(dataset):
|
|
53
|
+
"""
|
|
54
|
+
Downloads a dataset example to the current working directory. The function
|
|
55
|
+
downloads the ZEN-garden dataset examples from the ZEN-garden Zenodo
|
|
56
|
+
repository. It then extracts the dataset specified by the user and saves
|
|
57
|
+
it to the current working directory. In addition, it also downloads a
|
|
58
|
+
``config.json`` file and a Jupyter notebook demonstrating how to analyze
|
|
59
|
+
the results of a model.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
dataset (str): Name of the dataset to be downloaded. The following
|
|
63
|
+
options are currently available: "1_base_case",
|
|
64
|
+
"2_multi_year_optimization", "3_reduced_import_availability",
|
|
65
|
+
"4_PWA_nonlinear_capex", "5_multiple_time_steps_per_year",
|
|
66
|
+
"6_reduced_import_availability_yearly", "7_time_series_aggregation",
|
|
67
|
+
"8_yearly_variation", "9_myopic_foresight", "10_brown_field",
|
|
68
|
+
"11_multi_scenario", "12_multiple_in_output_carriers_conversion",
|
|
69
|
+
"13_yearly_interpolation", "14_retrofitting_and_fuel_substitution",
|
|
70
|
+
"15_unit_consistency_expected_error"
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
tuple:
|
|
74
|
+
str: The local path of the copied example
|
|
75
|
+
str: The local path of the copied config.json
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
FileNotFoundError: If either the dataset or the config file could not
|
|
79
|
+
be found in the Zenodo repository.
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
Basic usage example:
|
|
83
|
+
|
|
84
|
+
>>> from zen_garden.dataset_examples import download_dataset_example
|
|
85
|
+
>>> download_dataset_example("1_base_case")
|
|
48
86
|
|
|
49
|
-
def copy_dataset_example(example):
|
|
50
|
-
""" copies a dataset example to the current working directory
|
|
51
|
-
|
|
52
|
-
:param example: The name of the example to copy
|
|
53
|
-
:return: The local path of the copied example
|
|
54
|
-
:return: The local path of the copied config.json
|
|
55
87
|
"""
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
import zipfile
|
|
59
|
-
import io
|
|
88
|
+
|
|
89
|
+
# retrieve Zenodo metadata
|
|
60
90
|
url = metadata("zen_garden").get_all("Project-URL")
|
|
61
91
|
url = [u.split(", ")[1] for u in url if u.split(", ")[0] == "Zenodo"][0]
|
|
62
|
-
|
|
92
|
+
|
|
93
|
+
# fetch Zenodo metadata
|
|
94
|
+
zenodo_meta = requests.get(url, allow_redirects=True)
|
|
63
95
|
zenodo_meta.raise_for_status()
|
|
64
96
|
zenodo_data = zenodo_meta.json()
|
|
65
97
|
zenodo_zip_url = zenodo_data["files"][0]["links"]["self"]
|
|
98
|
+
|
|
99
|
+
# download ZIP file from Zenodo
|
|
66
100
|
zenodo_zip = requests.get(zenodo_zip_url)
|
|
67
101
|
zenodo_zip = zipfile.ZipFile(io.BytesIO(zenodo_zip.content))
|
|
102
|
+
|
|
103
|
+
# define relevant paths
|
|
68
104
|
base_path = zenodo_zip.filelist[0].filename
|
|
69
|
-
example_path = f"{base_path}docs/dataset_examples/{
|
|
105
|
+
example_path = f"{base_path}docs/dataset_examples/{dataset}/"
|
|
70
106
|
config_path = f"{base_path}docs/dataset_examples/config.json"
|
|
71
107
|
notebook_path = f"{base_path}docs/dataset_examples/example_notebook.ipynb"
|
|
72
|
-
|
|
108
|
+
|
|
109
|
+
# create local directories
|
|
73
110
|
local_dataset_path = os.getcwd()
|
|
74
111
|
if not os.path.exists(local_dataset_path):
|
|
75
112
|
os.mkdir(local_dataset_path)
|
|
76
|
-
local_example_path = os.path.join(local_dataset_path,
|
|
113
|
+
local_example_path = os.path.join(local_dataset_path, dataset)
|
|
77
114
|
if not os.path.exists(local_example_path):
|
|
78
115
|
os.mkdir(local_example_path)
|
|
116
|
+
|
|
117
|
+
# initialize flags for extracting files
|
|
79
118
|
example_found = False
|
|
80
119
|
config_found = False
|
|
81
120
|
notebook_found = False
|
|
121
|
+
|
|
122
|
+
# search for example within ZIP file
|
|
82
123
|
for file in zenodo_zip.filelist:
|
|
124
|
+
|
|
125
|
+
# download all files in dataset example
|
|
83
126
|
if file.filename.startswith(example_path):
|
|
84
127
|
filename_ending = file.filename.split(example_path)[1]
|
|
85
|
-
local_folder_path = os.path.join(
|
|
128
|
+
local_folder_path = os.path.join(
|
|
129
|
+
local_example_path, filename_ending)
|
|
86
130
|
if file.is_dir():
|
|
87
131
|
if not os.path.exists(local_folder_path):
|
|
88
132
|
os.mkdir(os.path.join(local_example_path, filename_ending))
|
|
89
133
|
else:
|
|
90
|
-
local_file_path = os.path.join(
|
|
134
|
+
local_file_path = os.path.join(
|
|
135
|
+
local_example_path, filename_ending)
|
|
91
136
|
with open(local_file_path, "wb") as f:
|
|
92
137
|
f.write(zenodo_zip.read(file))
|
|
93
138
|
example_found = True
|
|
139
|
+
|
|
140
|
+
# download config.json
|
|
94
141
|
elif file.filename == config_path:
|
|
95
142
|
with open(os.path.join(local_dataset_path, "config.json"), "wb") as f:
|
|
96
143
|
f.write(zenodo_zip.read(file))
|
|
97
144
|
config_found = True
|
|
145
|
+
|
|
146
|
+
# download jupyter notebook
|
|
98
147
|
elif file.filename == notebook_path:
|
|
99
|
-
notebook_path_local = os.path.join(
|
|
148
|
+
notebook_path_local = os.path.join(
|
|
149
|
+
local_dataset_path, "example_notebook.ipynb")
|
|
100
150
|
notebook = json.loads(zenodo_zip.read(file))
|
|
101
151
|
for cell in notebook['cells']:
|
|
102
152
|
if cell['cell_type'] == 'code': # Check only code cells
|
|
103
153
|
for i, line in enumerate(cell['source']):
|
|
104
154
|
if "<dataset_name>" in line:
|
|
105
|
-
cell['source'][i] = line.replace(
|
|
155
|
+
cell['source'][i] = line.replace(
|
|
156
|
+
"<dataset_name>", dataset)
|
|
106
157
|
with open(notebook_path_local, "w") as f:
|
|
107
158
|
json.dump(notebook, f)
|
|
108
159
|
notebook_found = True
|
|
109
|
-
|
|
110
|
-
|
|
160
|
+
|
|
161
|
+
# display status, errors, and warnings
|
|
162
|
+
if not example_found:
|
|
163
|
+
raise FileNotFoundError(
|
|
164
|
+
f"Example {dataset} could not be found in the dataset examples!"
|
|
165
|
+
)
|
|
166
|
+
if not config_found:
|
|
167
|
+
raise FileNotFoundError(
|
|
168
|
+
"Config.json file could not be downloaded from the dataset "
|
|
169
|
+
"examples!"
|
|
170
|
+
)
|
|
111
171
|
if not notebook_found:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
172
|
+
warnings.warn(
|
|
173
|
+
"Example jupyter notebook could not be downloaded from the "
|
|
174
|
+
"dataset examples!")
|
|
175
|
+
|
|
176
|
+
# print output
|
|
177
|
+
print(f"Example dataset {dataset} downloaded to {local_example_path}")
|
|
115
178
|
|
|
179
|
+
# return
|
|
180
|
+
return local_example_path, os.path.join(local_dataset_path, "config.json")
|
|
116
181
|
|
|
117
182
|
# linopy helpers
|
|
118
183
|
# --------------
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Runs the main function of ZEN-Garden.
|
|
3
|
-
Compilation of the optimization problem.
|
|
4
|
-
"""
|
|
5
|
-
from ._internal import main
|
|
6
|
-
import importlib.util
|
|
7
|
-
import argparse
|
|
8
|
-
import sys
|
|
9
|
-
import os
|
|
10
|
-
import zen_garden.default_config as default_config
|
|
11
|
-
import json
|
|
12
|
-
from zen_garden.utils import copy_dataset_example
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
|
|
15
|
-
def run_module(args=None, config = "./config.py", dataset = None,
|
|
16
|
-
folder_output = None, job_index = None, job_index_var = "SLURM_ARRAY_TASK_ID",
|
|
17
|
-
download_example = None):
|
|
18
|
-
"""
|
|
19
|
-
Runs the main function of ZEN-Garden
|
|
20
|
-
|
|
21
|
-
:param args: Arguments to parse
|
|
22
|
-
"""
|
|
23
|
-
if args is None:
|
|
24
|
-
args = sys.argv[1:]
|
|
25
|
-
|
|
26
|
-
# parse the args
|
|
27
|
-
description = "Run ZEN garden with a given config file. Per default, the config file will be read out from the " \
|
|
28
|
-
"current working directory. You can specify a config file with the --config argument. However, " \
|
|
29
|
-
"note that the output directory will always be the current working directory, independent of the " \
|
|
30
|
-
"dataset specified in the config file."
|
|
31
|
-
parser = argparse.ArgumentParser(description=description, add_help=True, usage="usage: zen-garden [-h] [--config CONFIG] [--dataset DATASET] [--job_index JOB_INDEX] [--job_index_var JOB_INDEX_VAR] [-- download_example EXAMPLE_NAME]")
|
|
32
|
-
# TODO make json config default
|
|
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`).")
|
|
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!")
|
|
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 "
|
|
36
|
-
"config.analysis.folder_output attribute and the config.solver.solver_dir attribute of the config file!")
|
|
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")
|
|
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. "
|
|
39
|
-
"If both --job_index and --job_index_var are specified, --job_index will be used.")
|
|
40
|
-
parser.add_argument("--download_example", required=False, type=str, default=download_example, help="Downloads an example data set to the current working directory. The argument should be the name of a dataset example in documentation/dataset_examples. This command will copy the dataset and the config to the current folder. It will not run ZEN-garden.")
|
|
41
|
-
|
|
42
|
-
args = parser.parse_args(args)
|
|
43
|
-
|
|
44
|
-
# copy example dataset and run example
|
|
45
|
-
if args.download_example is not None:
|
|
46
|
-
example_path_cwd,config_path_cwd = copy_dataset_example(args.download_example)
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
if not os.path.exists(args.config):
|
|
50
|
-
args.config = args.config.replace(".py", ".json")
|
|
51
|
-
|
|
52
|
-
### import the config
|
|
53
|
-
config_path, config_file = os.path.split(os.path.abspath(args.config))
|
|
54
|
-
if config_file.endswith(".py"):
|
|
55
|
-
spec = importlib.util.spec_from_file_location("module", Path(config_path) / config_file)
|
|
56
|
-
module = importlib.util.module_from_spec(spec)
|
|
57
|
-
spec.loader.exec_module(module)
|
|
58
|
-
config = module.config
|
|
59
|
-
else:
|
|
60
|
-
with open(Path(config_path) / config_file, "r") as f:
|
|
61
|
-
config = default_config.Config(**json.load(f))
|
|
62
|
-
|
|
63
|
-
### get the job index
|
|
64
|
-
job_index = args.job_index
|
|
65
|
-
if job_index is None:
|
|
66
|
-
if (job_index := os.environ.get(args.job_index_var)) is not None:
|
|
67
|
-
job_index = int(job_index)
|
|
68
|
-
else:
|
|
69
|
-
job_index = [int(i) for i in job_index.split(",")]
|
|
70
|
-
|
|
71
|
-
### run
|
|
72
|
-
main(config=config, dataset_path=args.dataset, job_index=job_index, folder_output_path=args.folder_output)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if __name__ == "__main__":
|
|
76
|
-
|
|
77
|
-
run_module()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/conversion_technology.py
RENAMED
|
File without changes
|
{zen_garden-2.7.18 → zen_garden-2.7.20}/zen_garden/model/technology/retrofitting_technology.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{zen_garden-2.7.18/zen_garden/preprocess → zen_garden-2.7.20/zen_garden/postprocess}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|