PVNet 3.0.29__tar.gz → 3.0.35__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.
- {pvnet-3.0.29 → pvnet-3.0.35}/PKG-INFO +19 -10
- {pvnet-3.0.29 → pvnet-3.0.35}/PVNet.egg-info/PKG-INFO +19 -10
- {pvnet-3.0.29 → pvnet-3.0.35}/PVNet.egg-info/SOURCES.txt +1 -5
- {pvnet-3.0.29 → pvnet-3.0.35}/PVNet.egg-info/requires.txt +13 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/PVNet.egg-info/top_level.txt +0 -1
- {pvnet-3.0.29 → pvnet-3.0.35}/README.md +6 -6
- pvnet-3.0.35/pvnet/__init__.py +2 -0
- pvnet-3.0.35/pvnet/load_model.py +70 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/utils.py +3 -26
- pvnet-3.0.35/pyproject.toml +88 -0
- pvnet-3.0.29/pvnet/__init__.py +0 -2
- pvnet-3.0.29/pyproject.toml +0 -28
- pvnet-3.0.29/requirements-dev.txt +0 -8
- pvnet-3.0.29/requirements.txt +0 -27
- pvnet-3.0.29/setup.py +0 -33
- pvnet-3.0.29/tests/__init__.py +0 -0
- pvnet-3.0.29/tests/conftest.py +0 -305
- {pvnet-3.0.29 → pvnet-3.0.35}/LICENSE +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/MANIFEST.in +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/PVNet.egg-info/dependency_links.txt +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/callbacks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/base.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/datamodule.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/pv_site_datamodule.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/utils.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/data/wind_datamodule.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/base_model.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/baseline/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/baseline/last_value.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/baseline/single_value.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/ensemble.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/basic_blocks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/encoders/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/encoders/basic_blocks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/encoders/encoders2d.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/encoders/encoders3d.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/encoders/encodersRNN.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/linear_networks/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/linear_networks/basic_blocks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/linear_networks/networks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/multimodal.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/multimodal_base.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/site_encoders/__init__.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/site_encoders/basic_blocks.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/site_encoders/encoders.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/multimodal/unimodal_teacher.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/models/utils.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/optimizers.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/pvnet/training.py +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/setup.cfg +0 -0
- {pvnet-3.0.29 → pvnet-3.0.35}/tests/test_end2end.py +0 -0
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PVNet
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.35
|
|
4
4
|
Summary: PVNet
|
|
5
|
-
Author: Peter Dudfield
|
|
6
|
-
Author-email: info@openclimatefix.org
|
|
7
|
-
License: MIT
|
|
5
|
+
Author-email: Peter Dudfield <info@openclimatefix.org>
|
|
8
6
|
Description-Content-Type: text/markdown
|
|
9
7
|
License-File: LICENSE
|
|
10
8
|
Requires-Dist: ocf_datapipes>=3.3.6
|
|
@@ -33,9 +31,20 @@ Requires-Dist: python-dotenv
|
|
|
33
31
|
Requires-Dist: hydra-optuna-sweeper
|
|
34
32
|
Requires-Dist: rich
|
|
35
33
|
Requires-Dist: gcsfs
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pvlive-api; extra == "dev"
|
|
36
|
+
Requires-Dist: black; extra == "dev"
|
|
37
|
+
Requires-Dist: flake8; extra == "dev"
|
|
38
|
+
Requires-Dist: isort; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy; extra == "dev"
|
|
40
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
36
43
|
Provides-Extra: all-models
|
|
37
44
|
Requires-Dist: pytorch-tabnet; extra == "all-models"
|
|
38
45
|
Requires-Dist: efficientnet_pytorch; extra == "all-models"
|
|
46
|
+
Provides-Extra: all
|
|
47
|
+
Requires-Dist: PVNet[all_models,dev]; extra == "all"
|
|
39
48
|
|
|
40
49
|
# PVNet 2.1
|
|
41
50
|
|
|
@@ -70,7 +79,7 @@ Some slightly more structured notes on deliberate experiments we have performed
|
|
|
70
79
|
```bash
|
|
71
80
|
git clone https://github.com/openclimatefix/PVNet.git
|
|
72
81
|
cd PVNet
|
|
73
|
-
pip install
|
|
82
|
+
pip install .
|
|
74
83
|
```
|
|
75
84
|
|
|
76
85
|
The commit history is extensive. To save download time, use a depth of 1:
|
|
@@ -88,7 +97,7 @@ pip install -e .
|
|
|
88
97
|
### Additional development dependencies
|
|
89
98
|
|
|
90
99
|
```bash
|
|
91
|
-
pip install
|
|
100
|
+
pip install ".[dev]"
|
|
92
101
|
```
|
|
93
102
|
|
|
94
103
|
|
|
@@ -140,7 +149,7 @@ conda create -n ocf_datapipes python=3.10
|
|
|
140
149
|
Then go inside the ocf_datapipes repo to add packages
|
|
141
150
|
|
|
142
151
|
```bash
|
|
143
|
-
pip install
|
|
152
|
+
pip install ".[dev]"
|
|
144
153
|
```
|
|
145
154
|
|
|
146
155
|
Then exit this environment, and enter back into the pvnet conda environment and install ocf_datapies in editable mode (-e). This means the package is directly linked to the source code in the ocf_datapies repo.
|
|
@@ -184,7 +193,7 @@ For this example we will be using the `streamed_batches.yaml` config. Like befor
|
|
|
184
193
|
|
|
185
194
|
This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
|
|
186
195
|
|
|
187
|
-
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
|
|
196
|
+
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"`
|
|
188
197
|
`
|
|
189
198
|
|
|
190
199
|
Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
|
|
@@ -209,14 +218,14 @@ gcloud auth login
|
|
|
209
218
|
|
|
210
219
|
For files stored in multiple locations they can be added as list. For example from the gcp_configuration.yaml file we can change from satellite data stored on a bucket:
|
|
211
220
|
|
|
212
|
-
```
|
|
221
|
+
```yaml
|
|
213
222
|
satellite:
|
|
214
223
|
satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
|
|
215
224
|
```
|
|
216
225
|
|
|
217
226
|
To satellite data hosted by Google:
|
|
218
227
|
|
|
219
|
-
```
|
|
228
|
+
```yaml
|
|
220
229
|
satellite:
|
|
221
230
|
satellite_zarr_paths:
|
|
222
231
|
- "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PVNet
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.35
|
|
4
4
|
Summary: PVNet
|
|
5
|
-
Author: Peter Dudfield
|
|
6
|
-
Author-email: info@openclimatefix.org
|
|
7
|
-
License: MIT
|
|
5
|
+
Author-email: Peter Dudfield <info@openclimatefix.org>
|
|
8
6
|
Description-Content-Type: text/markdown
|
|
9
7
|
License-File: LICENSE
|
|
10
8
|
Requires-Dist: ocf_datapipes>=3.3.6
|
|
@@ -33,9 +31,20 @@ Requires-Dist: python-dotenv
|
|
|
33
31
|
Requires-Dist: hydra-optuna-sweeper
|
|
34
32
|
Requires-Dist: rich
|
|
35
33
|
Requires-Dist: gcsfs
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pvlive-api; extra == "dev"
|
|
36
|
+
Requires-Dist: black; extra == "dev"
|
|
37
|
+
Requires-Dist: flake8; extra == "dev"
|
|
38
|
+
Requires-Dist: isort; extra == "dev"
|
|
39
|
+
Requires-Dist: mypy; extra == "dev"
|
|
40
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
36
43
|
Provides-Extra: all-models
|
|
37
44
|
Requires-Dist: pytorch-tabnet; extra == "all-models"
|
|
38
45
|
Requires-Dist: efficientnet_pytorch; extra == "all-models"
|
|
46
|
+
Provides-Extra: all
|
|
47
|
+
Requires-Dist: PVNet[all_models,dev]; extra == "all"
|
|
39
48
|
|
|
40
49
|
# PVNet 2.1
|
|
41
50
|
|
|
@@ -70,7 +79,7 @@ Some slightly more structured notes on deliberate experiments we have performed
|
|
|
70
79
|
```bash
|
|
71
80
|
git clone https://github.com/openclimatefix/PVNet.git
|
|
72
81
|
cd PVNet
|
|
73
|
-
pip install
|
|
82
|
+
pip install .
|
|
74
83
|
```
|
|
75
84
|
|
|
76
85
|
The commit history is extensive. To save download time, use a depth of 1:
|
|
@@ -88,7 +97,7 @@ pip install -e .
|
|
|
88
97
|
### Additional development dependencies
|
|
89
98
|
|
|
90
99
|
```bash
|
|
91
|
-
pip install
|
|
100
|
+
pip install ".[dev]"
|
|
92
101
|
```
|
|
93
102
|
|
|
94
103
|
|
|
@@ -140,7 +149,7 @@ conda create -n ocf_datapipes python=3.10
|
|
|
140
149
|
Then go inside the ocf_datapipes repo to add packages
|
|
141
150
|
|
|
142
151
|
```bash
|
|
143
|
-
pip install
|
|
152
|
+
pip install ".[dev]"
|
|
144
153
|
```
|
|
145
154
|
|
|
146
155
|
Then exit this environment, and enter back into the pvnet conda environment and install ocf_datapies in editable mode (-e). This means the package is directly linked to the source code in the ocf_datapies repo.
|
|
@@ -184,7 +193,7 @@ For this example we will be using the `streamed_batches.yaml` config. Like befor
|
|
|
184
193
|
|
|
185
194
|
This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
|
|
186
195
|
|
|
187
|
-
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
|
|
196
|
+
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"`
|
|
188
197
|
`
|
|
189
198
|
|
|
190
199
|
Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
|
|
@@ -209,14 +218,14 @@ gcloud auth login
|
|
|
209
218
|
|
|
210
219
|
For files stored in multiple locations they can be added as list. For example from the gcp_configuration.yaml file we can change from satellite data stored on a bucket:
|
|
211
220
|
|
|
212
|
-
```
|
|
221
|
+
```yaml
|
|
213
222
|
satellite:
|
|
214
223
|
satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
|
|
215
224
|
```
|
|
216
225
|
|
|
217
226
|
To satellite data hosted by Google:
|
|
218
227
|
|
|
219
|
-
```
|
|
228
|
+
```yaml
|
|
220
229
|
satellite:
|
|
221
230
|
satellite_zarr_paths:
|
|
222
231
|
- "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
|
|
@@ -2,9 +2,6 @@ LICENSE
|
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.md
|
|
4
4
|
pyproject.toml
|
|
5
|
-
requirements-dev.txt
|
|
6
|
-
requirements.txt
|
|
7
|
-
setup.py
|
|
8
5
|
PVNet.egg-info/PKG-INFO
|
|
9
6
|
PVNet.egg-info/SOURCES.txt
|
|
10
7
|
PVNet.egg-info/dependency_links.txt
|
|
@@ -12,6 +9,7 @@ PVNet.egg-info/requires.txt
|
|
|
12
9
|
PVNet.egg-info/top_level.txt
|
|
13
10
|
pvnet/__init__.py
|
|
14
11
|
pvnet/callbacks.py
|
|
12
|
+
pvnet/load_model.py
|
|
15
13
|
pvnet/optimizers.py
|
|
16
14
|
pvnet/training.py
|
|
17
15
|
pvnet/utils.py
|
|
@@ -44,6 +42,4 @@ pvnet/models/multimodal/linear_networks/networks.py
|
|
|
44
42
|
pvnet/models/multimodal/site_encoders/__init__.py
|
|
45
43
|
pvnet/models/multimodal/site_encoders/basic_blocks.py
|
|
46
44
|
pvnet/models/multimodal/site_encoders/encoders.py
|
|
47
|
-
tests/__init__.py
|
|
48
|
-
tests/conftest.py
|
|
49
45
|
tests/test_end2end.py
|
|
@@ -31,7 +31,7 @@ Some slightly more structured notes on deliberate experiments we have performed
|
|
|
31
31
|
```bash
|
|
32
32
|
git clone https://github.com/openclimatefix/PVNet.git
|
|
33
33
|
cd PVNet
|
|
34
|
-
pip install
|
|
34
|
+
pip install .
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
The commit history is extensive. To save download time, use a depth of 1:
|
|
@@ -49,7 +49,7 @@ pip install -e .
|
|
|
49
49
|
### Additional development dependencies
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
pip install
|
|
52
|
+
pip install ".[dev]"
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
|
|
@@ -101,7 +101,7 @@ conda create -n ocf_datapipes python=3.10
|
|
|
101
101
|
Then go inside the ocf_datapipes repo to add packages
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
pip install
|
|
104
|
+
pip install ".[dev]"
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
Then exit this environment, and enter back into the pvnet conda environment and install ocf_datapies in editable mode (-e). This means the package is directly linked to the source code in the ocf_datapies repo.
|
|
@@ -145,7 +145,7 @@ For this example we will be using the `streamed_batches.yaml` config. Like befor
|
|
|
145
145
|
|
|
146
146
|
This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
|
|
147
147
|
|
|
148
|
-
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
|
|
148
|
+
`configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"`
|
|
149
149
|
`
|
|
150
150
|
|
|
151
151
|
Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
|
|
@@ -170,14 +170,14 @@ gcloud auth login
|
|
|
170
170
|
|
|
171
171
|
For files stored in multiple locations they can be added as list. For example from the gcp_configuration.yaml file we can change from satellite data stored on a bucket:
|
|
172
172
|
|
|
173
|
-
```
|
|
173
|
+
```yaml
|
|
174
174
|
satellite:
|
|
175
175
|
satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
|
|
176
176
|
```
|
|
177
177
|
|
|
178
178
|
To satellite data hosted by Google:
|
|
179
179
|
|
|
180
|
-
```
|
|
180
|
+
```yaml
|
|
181
181
|
satellite:
|
|
182
182
|
satellite_zarr_paths:
|
|
183
183
|
- "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
""" Load a model from its checkpoint directory """
|
|
2
|
+
import glob
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import hydra
|
|
6
|
+
import torch
|
|
7
|
+
from pyaml_env import parse_config
|
|
8
|
+
|
|
9
|
+
from pvnet.models.ensemble import Ensemble
|
|
10
|
+
from pvnet.models.multimodal.unimodal_teacher import Model as UMTModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_model_from_checkpoints(
|
|
14
|
+
checkpoint_dir_paths: list[str],
|
|
15
|
+
val_best: bool = True,
|
|
16
|
+
):
|
|
17
|
+
"""Load a model from its checkpoint directory"""
|
|
18
|
+
is_ensemble = len(checkpoint_dir_paths) > 1
|
|
19
|
+
|
|
20
|
+
model_configs = []
|
|
21
|
+
models = []
|
|
22
|
+
data_configs = []
|
|
23
|
+
|
|
24
|
+
for path in checkpoint_dir_paths:
|
|
25
|
+
# Load the model
|
|
26
|
+
model_config = parse_config(f"{path}/model_config.yaml")
|
|
27
|
+
|
|
28
|
+
model = hydra.utils.instantiate(model_config)
|
|
29
|
+
|
|
30
|
+
if val_best:
|
|
31
|
+
# Only one epoch (best) saved per model
|
|
32
|
+
files = glob.glob(f"{path}/epoch*.ckpt")
|
|
33
|
+
if len(files) != 1:
|
|
34
|
+
raise ValueError(
|
|
35
|
+
f"Found {len(files)} checkpoints @ {path}/epoch*.ckpt. Expected one."
|
|
36
|
+
)
|
|
37
|
+
checkpoint = torch.load(files[0], map_location="cpu")
|
|
38
|
+
else:
|
|
39
|
+
checkpoint = torch.load(f"{path}/last.ckpt", map_location="cpu")
|
|
40
|
+
|
|
41
|
+
model.load_state_dict(state_dict=checkpoint["state_dict"])
|
|
42
|
+
|
|
43
|
+
if isinstance(model, UMTModel):
|
|
44
|
+
model, model_config = model.convert_to_multimodal_model(model_config)
|
|
45
|
+
|
|
46
|
+
# Check for data config
|
|
47
|
+
data_config = f"{path}/data_config.yaml"
|
|
48
|
+
|
|
49
|
+
if os.path.isfile(data_config):
|
|
50
|
+
data_configs.append(data_config)
|
|
51
|
+
else:
|
|
52
|
+
data_configs.append(None)
|
|
53
|
+
|
|
54
|
+
model_configs.append(model_config)
|
|
55
|
+
models.append(model)
|
|
56
|
+
|
|
57
|
+
if is_ensemble:
|
|
58
|
+
model_config = {
|
|
59
|
+
"_target_": "pvnet.models.ensemble.Ensemble",
|
|
60
|
+
"model_list": model_configs,
|
|
61
|
+
}
|
|
62
|
+
model = Ensemble(model_list=models)
|
|
63
|
+
data_config = data_configs[0]
|
|
64
|
+
|
|
65
|
+
else:
|
|
66
|
+
model_config = model_configs[0]
|
|
67
|
+
model = models[0]
|
|
68
|
+
data_config = data_configs[0]
|
|
69
|
+
|
|
70
|
+
return model, model_config, data_config
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"""Utils"""
|
|
2
2
|
import logging
|
|
3
|
-
import os
|
|
4
3
|
import warnings
|
|
5
4
|
from collections.abc import Sequence
|
|
6
5
|
from typing import Optional
|
|
@@ -13,7 +12,6 @@ import pylab
|
|
|
13
12
|
import rich.syntax
|
|
14
13
|
import rich.tree
|
|
15
14
|
import xarray as xr
|
|
16
|
-
import yaml
|
|
17
15
|
from lightning.pytorch.loggers import Logger
|
|
18
16
|
from lightning.pytorch.utilities import rank_zero_only
|
|
19
17
|
from ocf_datapipes.batch import BatchKey
|
|
@@ -21,26 +19,6 @@ from ocf_datapipes.utils import Location
|
|
|
21
19
|
from ocf_datapipes.utils.geospatial import osgb_to_lon_lat
|
|
22
20
|
from omegaconf import DictConfig, OmegaConf
|
|
23
21
|
|
|
24
|
-
import pvnet
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def load_config(config_file):
|
|
28
|
-
"""
|
|
29
|
-
Open yam configruation file, and get rid eof '_target_' line
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
# get full path of config file
|
|
33
|
-
path = os.path.dirname(pvnet.__file__)
|
|
34
|
-
config_file = f"{path}/../{config_file}"
|
|
35
|
-
|
|
36
|
-
with open(config_file) as cfg:
|
|
37
|
-
config = yaml.load(cfg, Loader=yaml.FullLoader)
|
|
38
|
-
|
|
39
|
-
if "_target_" in config.keys():
|
|
40
|
-
config.pop("_target_") # This is only for Hydra
|
|
41
|
-
|
|
42
|
-
return config
|
|
43
|
-
|
|
44
22
|
|
|
45
23
|
def get_logger(name=__name__, level=logging.INFO) -> logging.Logger:
|
|
46
24
|
"""Initializes multi-GPU-friendly python logger."""
|
|
@@ -236,11 +214,10 @@ def finish(
|
|
|
236
214
|
"""Makes sure everything closed properly."""
|
|
237
215
|
|
|
238
216
|
# without this sweeps with wandb logger might crash!
|
|
239
|
-
for logger in loggers:
|
|
240
|
-
|
|
241
|
-
import wandb
|
|
217
|
+
if any([isinstance(logger, pl.loggers.wandb.WandbLogger) for logger in loggers]):
|
|
218
|
+
import wandb
|
|
242
219
|
|
|
243
|
-
|
|
220
|
+
wandb.finish()
|
|
244
221
|
|
|
245
222
|
|
|
246
223
|
def plot_batch_forecasts(
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name="PVNet"
|
|
3
|
+
description = "PVNet"
|
|
4
|
+
authors = [{name="Peter Dudfield", email="info@openclimatefix.org"}]
|
|
5
|
+
dynamic = ["version", "readme"]
|
|
6
|
+
license={file="LICENCE"}
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
"ocf_datapipes>=3.3.6",
|
|
10
|
+
"ocf_ml_metrics>=0.0.11",
|
|
11
|
+
"numpy",
|
|
12
|
+
"pandas",
|
|
13
|
+
"matplotlib",
|
|
14
|
+
"xarray",
|
|
15
|
+
"ipykernel",
|
|
16
|
+
"h5netcdf",
|
|
17
|
+
"torch>=2.0.0",
|
|
18
|
+
"lightning>=2.0.1",
|
|
19
|
+
"torchvision",
|
|
20
|
+
"pytest",
|
|
21
|
+
"pytest-cov",
|
|
22
|
+
"typer",
|
|
23
|
+
"sqlalchemy",
|
|
24
|
+
"fsspec[s3]",
|
|
25
|
+
"wandb",
|
|
26
|
+
"huggingface-hub",
|
|
27
|
+
"tensorboard",
|
|
28
|
+
"tqdm",
|
|
29
|
+
"omegaconf",
|
|
30
|
+
"hydra-core",
|
|
31
|
+
"python-dotenv",
|
|
32
|
+
"hydra-optuna-sweeper",
|
|
33
|
+
"rich",
|
|
34
|
+
"gcsfs",# gcsfs is only needed when getting data from Google Cloud Storage
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.dynamic]
|
|
38
|
+
version = {attr = "pvnet.__version__"}
|
|
39
|
+
readme = {file = "README.md", content-type = "text/markdown"}
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.package-dir]
|
|
42
|
+
"pvnet" = "pvnet"
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
dev=[
|
|
46
|
+
"pvlive-api",
|
|
47
|
+
"black",
|
|
48
|
+
"flake8",
|
|
49
|
+
"isort",
|
|
50
|
+
"mypy",
|
|
51
|
+
"pre-commit",
|
|
52
|
+
"pytest",
|
|
53
|
+
"pytest-cov",
|
|
54
|
+
]
|
|
55
|
+
all_models=[
|
|
56
|
+
"pytorch-tabnet",
|
|
57
|
+
"efficientnet_pytorch"
|
|
58
|
+
]
|
|
59
|
+
all=["PVNet[dev,all_models]"]
|
|
60
|
+
|
|
61
|
+
[tool.mypy]
|
|
62
|
+
exclude = [
|
|
63
|
+
"^tests/",
|
|
64
|
+
]
|
|
65
|
+
disallow_untyped_defs = true
|
|
66
|
+
disallow_any_unimported = true
|
|
67
|
+
no_implicit_optional = true
|
|
68
|
+
check_untyped_defs = true
|
|
69
|
+
warn_return_any = true
|
|
70
|
+
warn_unused_ignores = true
|
|
71
|
+
show_error_codes = true
|
|
72
|
+
warn_unreachable = true
|
|
73
|
+
|
|
74
|
+
[[tool.mypy.overrides]]
|
|
75
|
+
module = [
|
|
76
|
+
]
|
|
77
|
+
ignore_missing_imports = true
|
|
78
|
+
|
|
79
|
+
[tool.pytest.ini_options]
|
|
80
|
+
minversion = "6.0"
|
|
81
|
+
addopts = "-ra -q"
|
|
82
|
+
testpaths = [
|
|
83
|
+
"tests",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[tool.ruff]
|
|
87
|
+
line-length = 100
|
|
88
|
+
exclude = [".ipynb_checkpoints", "tests", "configs.example"]
|
pvnet-3.0.29/pvnet/__init__.py
DELETED
pvnet-3.0.29/pyproject.toml
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
[tool.mypy]
|
|
2
|
-
exclude = [
|
|
3
|
-
"^tests/",
|
|
4
|
-
]
|
|
5
|
-
disallow_untyped_defs = true
|
|
6
|
-
disallow_any_unimported = true
|
|
7
|
-
no_implicit_optional = true
|
|
8
|
-
check_untyped_defs = true
|
|
9
|
-
warn_return_any = true
|
|
10
|
-
warn_unused_ignores = true
|
|
11
|
-
show_error_codes = true
|
|
12
|
-
warn_unreachable = true
|
|
13
|
-
|
|
14
|
-
[[tool.mypy.overrides]]
|
|
15
|
-
module = [
|
|
16
|
-
]
|
|
17
|
-
ignore_missing_imports = true
|
|
18
|
-
|
|
19
|
-
[tool.pytest.ini_options]
|
|
20
|
-
minversion = "6.0"
|
|
21
|
-
addopts = "-ra -q"
|
|
22
|
-
testpaths = [
|
|
23
|
-
"tests",
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
[tool.ruff]
|
|
27
|
-
line-length = 100
|
|
28
|
-
exclude = [".ipynb_checkpoints", "tests", "configs.example"]
|
pvnet-3.0.29/requirements.txt
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
ocf_datapipes>=3.3.6
|
|
2
|
-
ocf_ml_metrics>=0.0.11
|
|
3
|
-
numpy
|
|
4
|
-
pandas
|
|
5
|
-
matplotlib
|
|
6
|
-
xarray
|
|
7
|
-
ipykernel
|
|
8
|
-
h5netcdf
|
|
9
|
-
torch>=2.0.0
|
|
10
|
-
lightning>=2.0.1
|
|
11
|
-
torchvision
|
|
12
|
-
pytest
|
|
13
|
-
pytest-cov
|
|
14
|
-
typer
|
|
15
|
-
sqlalchemy
|
|
16
|
-
fsspec[s3]
|
|
17
|
-
wandb
|
|
18
|
-
huggingface-hub
|
|
19
|
-
tensorboard
|
|
20
|
-
tqdm
|
|
21
|
-
omegaconf
|
|
22
|
-
hydra-core
|
|
23
|
-
python-dotenv
|
|
24
|
-
hydra-optuna-sweeper
|
|
25
|
-
rich
|
|
26
|
-
# gcsfs is only needed when getting data from Google Cloud Storage
|
|
27
|
-
gcsfs
|
pvnet-3.0.29/setup.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
""" Usual setup file for package """
|
|
2
|
-
# read the contents of your README file
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from setuptools import find_packages, setup
|
|
6
|
-
|
|
7
|
-
this_directory = Path(__file__).parent
|
|
8
|
-
long_description = (this_directory / "README.md").read_text()
|
|
9
|
-
install_requires = (this_directory / "requirements.txt").read_text().splitlines()
|
|
10
|
-
extras_require = {"all_models": ["pytorch-tabnet", "efficientnet_pytorch"]}
|
|
11
|
-
|
|
12
|
-
with open("pvnet/__init__.py") as f:
|
|
13
|
-
for line in f:
|
|
14
|
-
if line.startswith("__version__"):
|
|
15
|
-
_, _, version = line.replace("'", "").split()
|
|
16
|
-
version = version.replace('"', "")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
setup(
|
|
20
|
-
name="PVNet",
|
|
21
|
-
version=version,
|
|
22
|
-
license="MIT",
|
|
23
|
-
description="PVNet",
|
|
24
|
-
author="Peter Dudfield",
|
|
25
|
-
author_email="info@openclimatefix.org",
|
|
26
|
-
company="Open Climate Fix Ltd",
|
|
27
|
-
install_requires=install_requires,
|
|
28
|
-
extras_require=extras_require,
|
|
29
|
-
long_description=long_description,
|
|
30
|
-
long_description_content_type="text/markdown",
|
|
31
|
-
include_package_data=True,
|
|
32
|
-
packages=find_packages(),
|
|
33
|
-
)
|
pvnet-3.0.29/tests/__init__.py
DELETED
|
File without changes
|
pvnet-3.0.29/tests/conftest.py
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import glob
|
|
3
|
-
import tempfile
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
import pandas as pd
|
|
7
|
-
import numpy as np
|
|
8
|
-
import xarray as xr
|
|
9
|
-
import torch
|
|
10
|
-
import hydra
|
|
11
|
-
|
|
12
|
-
from ocf_datapipes.batch import BatchKey
|
|
13
|
-
from datetime import timedelta
|
|
14
|
-
|
|
15
|
-
import pvnet
|
|
16
|
-
from pvnet.data.datamodule import DataModule
|
|
17
|
-
from pvnet.data.wind_datamodule import WindDataModule
|
|
18
|
-
|
|
19
|
-
import pvnet.models.multimodal.encoders.encoders3d
|
|
20
|
-
import pvnet.models.multimodal.linear_networks.networks
|
|
21
|
-
import pvnet.models.multimodal.site_encoders.encoders
|
|
22
|
-
from pvnet.models.multimodal.multimodal import Model
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
xr.set_options(keep_attrs=True)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def time_before_present(dt: timedelta):
|
|
29
|
-
return pd.Timestamp.now(tz=None) - dt
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@pytest.fixture
|
|
33
|
-
def nwp_data():
|
|
34
|
-
# Load dataset which only contains coordinates, but no data
|
|
35
|
-
ds = xr.open_zarr(
|
|
36
|
-
f"{os.path.dirname(os.path.abspath(__file__))}/test_data/sample_data/nwp_shell.zarr"
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
# Last init time was at least 2 hours ago and hour to 3-hour interval
|
|
40
|
-
t0_datetime_utc = time_before_present(timedelta(hours=2)).floor(timedelta(hours=3))
|
|
41
|
-
ds.init_time.values[:] = pd.date_range(
|
|
42
|
-
t0_datetime_utc - timedelta(hours=3 * (len(ds.init_time) - 1)),
|
|
43
|
-
t0_datetime_utc,
|
|
44
|
-
freq=timedelta(hours=3),
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
# This is important to avoid saving errors
|
|
48
|
-
for v in list(ds.coords.keys()):
|
|
49
|
-
if ds.coords[v].dtype == object:
|
|
50
|
-
ds[v].encoding.clear()
|
|
51
|
-
|
|
52
|
-
for v in list(ds.variables.keys()):
|
|
53
|
-
if ds[v].dtype == object:
|
|
54
|
-
ds[v].encoding.clear()
|
|
55
|
-
|
|
56
|
-
# Add data to dataset
|
|
57
|
-
ds["UKV"] = xr.DataArray(
|
|
58
|
-
np.zeros([len(ds[c]) for c in ds.coords]),
|
|
59
|
-
coords=ds.coords,
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
# Add stored attributes to DataArray
|
|
63
|
-
ds.UKV.attrs = ds.attrs["_data_attrs"]
|
|
64
|
-
del ds.attrs["_data_attrs"]
|
|
65
|
-
|
|
66
|
-
return ds
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@pytest.fixture()
|
|
70
|
-
def sat_data():
|
|
71
|
-
# Load dataset which only contains coordinates, but no data
|
|
72
|
-
ds = xr.open_zarr(
|
|
73
|
-
f"{os.path.dirname(os.path.abspath(__file__))}/test_data/sample_data/non_hrv_shell.zarr"
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Change times so they lead up to present. Delayed by at most 1 hour
|
|
77
|
-
t0_datetime_utc = time_before_present(timedelta(minutes=0)).floor(timedelta(minutes=30))
|
|
78
|
-
t0_datetime_utc = t0_datetime_utc - timedelta(minutes=30)
|
|
79
|
-
ds.time.values[:] = pd.date_range(
|
|
80
|
-
t0_datetime_utc - timedelta(minutes=5 * (len(ds.time) - 1)),
|
|
81
|
-
t0_datetime_utc,
|
|
82
|
-
freq=timedelta(minutes=5),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
# Add data to dataset
|
|
86
|
-
ds["data"] = xr.DataArray(
|
|
87
|
-
np.zeros([len(ds[c]) for c in ds.coords]),
|
|
88
|
-
coords=ds.coords,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
# Add stored attributes to DataArray
|
|
92
|
-
ds.data.attrs = ds.attrs["_data_attrs"]
|
|
93
|
-
del ds.attrs["_data_attrs"]
|
|
94
|
-
|
|
95
|
-
return ds
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
@pytest.fixture()
|
|
99
|
-
def sample_train_val_datamodule():
|
|
100
|
-
# duplicate the sample batcnes for more training/val data
|
|
101
|
-
n_duplicates = 10
|
|
102
|
-
|
|
103
|
-
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
104
|
-
os.makedirs(f"{tmpdirname}/train")
|
|
105
|
-
os.makedirs(f"{tmpdirname}/val")
|
|
106
|
-
|
|
107
|
-
file_n = 0
|
|
108
|
-
|
|
109
|
-
for file in glob.glob("tests/test_data/sample_batches/train/*.pt"):
|
|
110
|
-
batch = torch.load(file)
|
|
111
|
-
|
|
112
|
-
for i in range(n_duplicates):
|
|
113
|
-
# Save fopr both train and val
|
|
114
|
-
torch.save(batch, f"{tmpdirname}/train/{file_n:06}.pt")
|
|
115
|
-
torch.save(batch, f"{tmpdirname}/val/{file_n:06}.pt")
|
|
116
|
-
|
|
117
|
-
file_n += 1
|
|
118
|
-
|
|
119
|
-
dm = DataModule(
|
|
120
|
-
configuration=None,
|
|
121
|
-
batch_size=2,
|
|
122
|
-
num_workers=0,
|
|
123
|
-
prefetch_factor=None,
|
|
124
|
-
train_period=[None, None],
|
|
125
|
-
val_period=[None, None],
|
|
126
|
-
test_period=[None, None],
|
|
127
|
-
batch_dir=f"{tmpdirname}",
|
|
128
|
-
)
|
|
129
|
-
yield dm
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
@pytest.fixture()
|
|
133
|
-
def sample_datamodule():
|
|
134
|
-
dm = DataModule(
|
|
135
|
-
configuration=None,
|
|
136
|
-
batch_size=2,
|
|
137
|
-
num_workers=0,
|
|
138
|
-
prefetch_factor=None,
|
|
139
|
-
train_period=[None, None],
|
|
140
|
-
val_period=[None, None],
|
|
141
|
-
test_period=[None, None],
|
|
142
|
-
batch_dir="tests/test_data/sample_batches",
|
|
143
|
-
)
|
|
144
|
-
return dm
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@pytest.fixture()
|
|
148
|
-
def sample_batch(sample_datamodule):
|
|
149
|
-
batch = next(iter(sample_datamodule.train_dataloader()))
|
|
150
|
-
return batch
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
@pytest.fixture()
|
|
154
|
-
def sample_satellite_batch(sample_batch):
|
|
155
|
-
sat_image = sample_batch[BatchKey.satellite_actual]
|
|
156
|
-
return torch.swapaxes(sat_image, 1, 2)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@pytest.fixture()
|
|
160
|
-
def sample_pv_batch(sample_batch):
|
|
161
|
-
pv_data = sample_batch[BatchKey.pv]
|
|
162
|
-
return pv_data
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
@pytest.fixture()
|
|
166
|
-
def sample_wind_batch():
|
|
167
|
-
dm = WindDataModule(
|
|
168
|
-
configuration=None,
|
|
169
|
-
batch_size=2,
|
|
170
|
-
num_workers=0,
|
|
171
|
-
prefetch_factor=None,
|
|
172
|
-
train_period=[None, None],
|
|
173
|
-
val_period=[None, None],
|
|
174
|
-
test_period=[None, None],
|
|
175
|
-
batch_dir="tests/test_data/sample_wind_batches",
|
|
176
|
-
)
|
|
177
|
-
batch = next(iter(dm.train_dataloader()))
|
|
178
|
-
return batch
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
@pytest.fixture()
|
|
182
|
-
def model_minutes_kwargs():
|
|
183
|
-
kwargs = dict(
|
|
184
|
-
forecast_minutes=480,
|
|
185
|
-
history_minutes=120,
|
|
186
|
-
)
|
|
187
|
-
return kwargs
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@pytest.fixture()
|
|
191
|
-
def encoder_model_kwargs():
|
|
192
|
-
# Used to test encoder model on satellite data
|
|
193
|
-
kwargs = dict(
|
|
194
|
-
sequence_length=(90 - 30) // 5 + 1,
|
|
195
|
-
image_size_pixels=24,
|
|
196
|
-
in_channels=11,
|
|
197
|
-
out_features=128,
|
|
198
|
-
)
|
|
199
|
-
return kwargs
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
@pytest.fixture()
|
|
203
|
-
def site_encoder_model_kwargs():
|
|
204
|
-
# Used to test site encoder model on PV data
|
|
205
|
-
kwargs = dict(
|
|
206
|
-
sequence_length=180 // 5 + 1,
|
|
207
|
-
num_sites=349,
|
|
208
|
-
out_features=128,
|
|
209
|
-
)
|
|
210
|
-
return kwargs
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
@pytest.fixture()
|
|
214
|
-
def site_encoder_sensor_model_kwargs():
|
|
215
|
-
# Used to test site encoder model on PV data
|
|
216
|
-
kwargs = dict(
|
|
217
|
-
sequence_length=180 // 5 + 1,
|
|
218
|
-
num_sites=26,
|
|
219
|
-
out_features=128,
|
|
220
|
-
num_channels=23,
|
|
221
|
-
target_key_to_use="wind",
|
|
222
|
-
input_key_to_use="sensor",
|
|
223
|
-
)
|
|
224
|
-
return kwargs
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
@pytest.fixture()
|
|
228
|
-
def raw_multimodal_model_kwargs(model_minutes_kwargs):
|
|
229
|
-
kwargs = dict(
|
|
230
|
-
sat_encoder=dict(
|
|
231
|
-
_target_=pvnet.models.multimodal.encoders.encoders3d.DefaultPVNet,
|
|
232
|
-
_partial_=True,
|
|
233
|
-
in_channels=11,
|
|
234
|
-
out_features=128,
|
|
235
|
-
number_of_conv3d_layers=6,
|
|
236
|
-
conv3d_channels=32,
|
|
237
|
-
image_size_pixels=24,
|
|
238
|
-
),
|
|
239
|
-
nwp_encoders_dict={
|
|
240
|
-
"ukv": dict(
|
|
241
|
-
_target_=pvnet.models.multimodal.encoders.encoders3d.DefaultPVNet,
|
|
242
|
-
_partial_=True,
|
|
243
|
-
in_channels=2,
|
|
244
|
-
out_features=128,
|
|
245
|
-
number_of_conv3d_layers=6,
|
|
246
|
-
conv3d_channels=32,
|
|
247
|
-
image_size_pixels=24,
|
|
248
|
-
),
|
|
249
|
-
},
|
|
250
|
-
add_image_embedding_channel=True,
|
|
251
|
-
pv_encoder=dict(
|
|
252
|
-
_target_=pvnet.models.multimodal.site_encoders.encoders.SingleAttentionNetwork,
|
|
253
|
-
_partial_=True,
|
|
254
|
-
num_sites=349,
|
|
255
|
-
out_features=40,
|
|
256
|
-
num_heads=4,
|
|
257
|
-
kdim=40,
|
|
258
|
-
id_embed_dim=20,
|
|
259
|
-
),
|
|
260
|
-
output_network=dict(
|
|
261
|
-
_target_=pvnet.models.multimodal.linear_networks.networks.ResFCNet2,
|
|
262
|
-
_partial_=True,
|
|
263
|
-
fc_hidden_features=128,
|
|
264
|
-
n_res_blocks=6,
|
|
265
|
-
res_block_layers=2,
|
|
266
|
-
dropout_frac=0.0,
|
|
267
|
-
),
|
|
268
|
-
embedding_dim=16,
|
|
269
|
-
include_sun=True,
|
|
270
|
-
include_gsp_yield_history=True,
|
|
271
|
-
sat_history_minutes=90,
|
|
272
|
-
nwp_history_minutes={"ukv": 120},
|
|
273
|
-
nwp_forecast_minutes={"ukv": 480},
|
|
274
|
-
pv_history_minutes=180,
|
|
275
|
-
min_sat_delay_minutes=30,
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
kwargs.update(model_minutes_kwargs)
|
|
279
|
-
|
|
280
|
-
return kwargs
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
@pytest.fixture()
|
|
284
|
-
def multimodal_model_kwargs(raw_multimodal_model_kwargs):
|
|
285
|
-
return hydra.utils.instantiate(raw_multimodal_model_kwargs)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
@pytest.fixture()
|
|
289
|
-
def multimodal_model(multimodal_model_kwargs):
|
|
290
|
-
model = Model(**multimodal_model_kwargs)
|
|
291
|
-
return model
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
@pytest.fixture()
|
|
295
|
-
def multimodal_quantile_model(multimodal_model_kwargs):
|
|
296
|
-
model = Model(output_quantiles=[0.1, 0.5, 0.9], **multimodal_model_kwargs)
|
|
297
|
-
return model
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
@pytest.fixture()
|
|
301
|
-
def multimodal_weighted_quantile_model(multimodal_model_kwargs):
|
|
302
|
-
model = Model(
|
|
303
|
-
output_quantiles=[0.1, 0.5, 0.9], **multimodal_model_kwargs, use_weighted_loss=True
|
|
304
|
-
)
|
|
305
|
-
return model
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|