PVNet 2.6.8__tar.gz → 2.6.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 (50) hide show
  1. {PVNet-2.6.8 → PVNet-2.6.10}/PKG-INFO +99 -97
  2. {PVNet-2.6.8 → PVNet-2.6.10}/PVNet.egg-info/PKG-INFO +99 -97
  3. {PVNet-2.6.8 → PVNet-2.6.10}/PVNet.egg-info/requires.txt +1 -0
  4. {PVNet-2.6.8 → PVNet-2.6.10}/README.md +97 -96
  5. PVNet-2.6.10/pvnet/__init__.py +2 -0
  6. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/data/datamodule.py +3 -10
  7. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/data/wind_datamodule.py +3 -4
  8. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/base_model.py +6 -3
  9. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/multimodal.py +17 -3
  10. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/utils.py +2 -2
  11. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/training.py +6 -2
  12. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/utils.py +12 -8
  13. {PVNet-2.6.8 → PVNet-2.6.10}/requirements.txt +2 -0
  14. {PVNet-2.6.8 → PVNet-2.6.10}/tests/conftest.py +0 -2
  15. PVNet-2.6.8/pvnet/__init__.py +0 -2
  16. {PVNet-2.6.8 → PVNet-2.6.10}/LICENSE +0 -0
  17. {PVNet-2.6.8 → PVNet-2.6.10}/MANIFEST.in +0 -0
  18. {PVNet-2.6.8 → PVNet-2.6.10}/PVNet.egg-info/SOURCES.txt +0 -0
  19. {PVNet-2.6.8 → PVNet-2.6.10}/PVNet.egg-info/dependency_links.txt +0 -0
  20. {PVNet-2.6.8 → PVNet-2.6.10}/PVNet.egg-info/top_level.txt +0 -0
  21. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/callbacks.py +0 -0
  22. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/data/__init__.py +0 -0
  23. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/data/utils.py +0 -0
  24. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/__init__.py +0 -0
  25. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/baseline/__init__.py +0 -0
  26. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/baseline/last_value.py +0 -0
  27. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/baseline/single_value.py +0 -0
  28. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/__init__.py +0 -0
  29. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/basic_blocks.py +0 -0
  30. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/deep_supervision.py +0 -0
  31. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/encoders/__init__.py +0 -0
  32. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/encoders/basic_blocks.py +0 -0
  33. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/encoders/encoders2d.py +0 -0
  34. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/encoders/encoders3d.py +0 -0
  35. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/encoders/encodersRNN.py +0 -0
  36. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/linear_networks/__init__.py +0 -0
  37. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/linear_networks/basic_blocks.py +0 -0
  38. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/linear_networks/networks.py +0 -0
  39. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/nwp_weighting.py +0 -0
  40. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/site_encoders/__init__.py +0 -0
  41. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/site_encoders/basic_blocks.py +0 -0
  42. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/site_encoders/encoders.py +0 -0
  43. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/models/multimodal/weather_residual.py +0 -0
  44. {PVNet-2.6.8 → PVNet-2.6.10}/pvnet/optimizers.py +0 -0
  45. {PVNet-2.6.8 → PVNet-2.6.10}/pyproject.toml +0 -0
  46. {PVNet-2.6.8 → PVNet-2.6.10}/requirements-dev.txt +0 -0
  47. {PVNet-2.6.8 → PVNet-2.6.10}/setup.cfg +0 -0
  48. {PVNet-2.6.8 → PVNet-2.6.10}/setup.py +0 -0
  49. {PVNet-2.6.8 → PVNet-2.6.10}/tests/__init__.py +0 -0
  50. {PVNet-2.6.8 → PVNet-2.6.10}/tests/test_end2end.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PVNet
3
- Version: 2.6.8
3
+ Version: 2.6.10
4
4
  Summary: PVNet
5
5
  Author: Peter Dudfield
6
6
  Author-email: info@openclimatefix.org
@@ -32,6 +32,7 @@ Requires-Dist: hydra-core
32
32
  Requires-Dist: python-dotenv
33
33
  Requires-Dist: hydra-optuna-sweeper
34
34
  Requires-Dist: rich
35
+ Requires-Dist: gcsfs
35
36
  Provides-Extra: all-models
36
37
  Requires-Dist: pytorch-tabnet; extra == "all-models"
37
38
  Requires-Dist: efficientnet_pytorch; extra == "all-models"
@@ -66,12 +67,26 @@ cd PVNet
66
67
  pip install -r requirements.txt
67
68
  ```
68
69
 
70
+ The commit history is extensive. To save download time, use a depth of 1:
71
+ ```bash
72
+ git clone --depth 1 https://github.com/openclimatefix/PVNet.git
73
+ ```
74
+ This means only the latest commit and its associated files will be downloaded.
75
+
76
+ Next, in the PVNet repo, install PVNet as an editable package:
77
+
78
+ ```bash
79
+ pip install -e .
80
+ ```
81
+
69
82
  ### Additional development dependencies
70
83
 
71
84
  ```bash
72
85
  pip install -r requirements-dev.txt
73
86
  ```
74
87
 
88
+
89
+
75
90
  ## Getting started with running PVNet
76
91
 
77
92
  Before running any code in within PVNet, copy the example configuration to a
@@ -107,116 +122,103 @@ https://huggingface.co/datasets/openclimatefix/dwd-icon-eu which includes the UK
107
122
  OCF maintains a dataset of PV generation from 1311 private PV installations
108
123
  here: https://huggingface.co/datasets/openclimatefix/uk_pv
109
124
 
110
- ### Generating pre-made batches of data for training/validation of PVNet
111
125
 
112
- PVNet contains a script for generating batches of data suitable for training the
113
- PVNet models.
126
+ ### Connecting with ocf_datapipes for batch creation
114
127
 
115
- To run the script you will need to make some modifications to the datamodule
116
- configuration.
128
+ Outside the PVNet repo, clone the ocf-datapipes repo and exit the conda env created for PVNet: https://github.com/openclimatefix/ocf_datapipes
129
+ ```bash
130
+ git clone --depth 1 https://github.com/openclimatefix/ocf_datapipes.git
131
+ conda create -n ocf_datapipes python=3.10
132
+ ```
117
133
 
118
- 1. First, create your new configuration file in
119
- `./configs/datamodule/configiration/local_configuration.yaml` and paste the
120
- sample config (shown below)
121
- 2. Duplicate the `./configs/datamodule/ocf_datapipes.yaml` to
122
- `./configs/datamodule/_local_ocf_datapipes.yaml` and ensure the
123
- `configuration` key points to your newly created configuration file in
124
- step 1.
125
- 3. Also in this file, update the train, val & test periods to cover the data you
126
- have access to.
127
- 4. To get you started with your own configuration file, see the sample config
128
- below. Update the data paths to the location of your local GSP, NWP and PV
129
- datasets:
134
+ Then go inside the ocf_datapipes repo to add packages
130
135
 
131
- ```yaml
132
- general:
133
- description: Demo config
134
- name: demo_datamodule_config
135
-
136
- input_data:
137
- default_history_minutes: 60
138
- default_forecast_minutes: 120
139
-
140
- gsp:
141
- gsp_zarr_path: /path/to/gsp-data.zarr
142
- history_minutes: 60
143
- forecast_minutes: 120
144
- time_resolution_minutes: 30
145
- start_datetime: "2019-01-01T00:00:00"
146
- end_datetime: "2019-01-08T00:00:00"
147
- metadata_only: false
148
-
149
- nwp:
150
- ukv:
151
- nwp_zarr_path: /path/to/nwp-data.zarr
152
- history_minutes: 60
153
- forecast_minutes: 120
154
- time_resolution_minutes: 60
155
- nwp_channels: # comment out channels as appropriate
156
- - t # 2-metre temperature
157
- - dswrf # downwards short-wave radiation flux
158
- - dlwrf # downwards long-wave radiation flux
159
- - hcc # high cloud cover
160
- - mcc # medium cloud cover
161
- - lcc # low cloud cover
162
- - vis # visability
163
- - r # relative humidity
164
- - prate # precipitation rate
165
- - si10 # 10-metre wind speed | live = unknown
166
- nwp_image_size_pixels_height: 24
167
- nwp_image_size_pixels_width: 24
168
- nwp_provider: ukv
169
-
170
- pv:
171
- pv_files_groups:
172
- - label: pvoutput.org
173
- pv_filename: /path/to/pv-data/pv.netcdf
174
- pv_metadata_filename: /path/to/pv-data/metadata.csv
175
- history_minutes: 60
176
- forecast_minutes: 0 # PVNet assumes no future PV generation
177
- time_resolution_minutes: 5
178
- start_datetime: "2019-01-01T00:00:00"
179
- end_datetime: "2019-01-08T00:00:00"
180
- pv_image_size_meters_height: 24
181
- pv_image_size_meters_width: 24
182
- pv_ml_ids: [154,155,156,158,159,160,162,164,165,166,167,168,169,171,173,177,178,179,181,182,185,186,187,188,189,190,191,192,193,197,198,199,200,202,204,205,206,208,209,211,214,215,216,217,218,219,220,221,225,229,230,232,233,234,236,242,243,245,252,254,255,256,257,258,260,261,262,265,267,268,272,273,275,276,277,280,281,282,283,287,289,291,292,293,294,295,296,297,298,301,302,303,304,306,307,309,310,311,317,318,319,320,321,322,323,325,326,329,332,333,335,336,338,340,342,344,345,346,348,349,352,354,355,356,357,360,362,363,368,369,370,371,372,374,375,376,378,380,382,384,385,388,390,391,393,396,397,398,399,400,401,403,404,405,406,407,409,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,429,431,435,437,438,440,441,444,447,450,451,453,456,457,458,459,464,465,466,467,468,470,471,473,474,476,477,479,480,481,482,485,486,488,490,491,492,493,496,498,501,503,506,507,508,509,510,511,512,513,515,516,517,519,520,521,522,524,526,527,528,531,532,536,537,538,540,541,542,543,544,545,549,550,551,552,553,554,556,557,560,561,563,566,568,571,572,575,576,577,579,580,581,582,584,585,588,590,594,595,597,600,602,603,604,606,611,613,614,616,618,620,622,623,624,625,626,628,629,630,631,636,637,638,640,641,642,644,645,646,650,651,652,653,654,655,657,660,661,662,663,666,667,668,670,675,676,679,681,683,684,685,687,696,698,701,702,703,704,706,710,722,723,724,725,727,728,729,730,732,733,734,735,736,737,]
183
- n_pv_systems_per_example: 128
184
- get_center: false
185
- is_live: false
186
-
187
- satellite:
188
- satellite_zarr_path: "" # Left empty to avoid using satellite data
189
- history_minutes: 60
190
- forecast_minutes: 0
191
- live_delay_minutes: 30
192
- time_resolution_minutes: 5
193
- satellite_channels:
194
- - IR_016
195
- - IR_039
196
- - IR_087
197
- - IR_097
198
- - IR_108
199
- - IR_120
200
- - IR_134
201
- - VIS006
202
- - VIS008
203
- - WV_062
204
- - WV_073
205
- satellite_image_size_pixels_height: 24
206
- satellite_image_size_pixels_width: 24
136
+ ```bash
137
+ pip install -r requirements.txt requirements-dev.txt
207
138
  ```
208
139
 
140
+ 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.
141
+
142
+ ```bash
143
+ pip install -e <PATH-TO-ocf_datapipes-REPO>
144
+ ```
145
+
146
+ ## Generating pre-made batches of data for training/validation of PVNet
147
+
148
+ PVNet contains a script for generating batches of data suitable for training the PVNet models. To run the script you will need to make some modifications to the datamodule configuration.
149
+
150
+ Make sure you have copied the example configs (as already stated above):
151
+ ```
152
+ cp -r configs.example configs
153
+ ```
154
+
155
+ ### Set up and config example for batch creation
156
+
157
+ We will use the example of creating batches using data from gcp:
158
+ `/PVNet/configs/datamodule/configuration/gcp_configuration.yaml`
159
+ Ensure that the file paths are set to the correct locations in
160
+ `gcp_configuration.yaml`.
161
+
162
+ `PLACEHOLDER` is used to indcate where to input the location of the files.
163
+
164
+ For OCF use cases, file locations can be found in `template_configuration.yaml` located alongside `gcp_configuration.yaml`.
165
+
166
+ In these configurations you can update the train, val & test periods to cover the data you have access to.
167
+
168
+
209
169
  With your configuration in place, you can proceed to create batches. PVNet uses
210
170
  [hydra](https://hydra.cc/) which enables us to pass variables via the command
211
171
  line that will override the configuration defined in the `./configs` directory.
212
172
 
213
- Run the save_batches.py script to create batches with the following arguments as
214
- a minimum:
173
+ When creating batches, an additional config is used which is passed into the batch creation script. This is the datamodule config located `PVNet/configs/datamodule`.
174
+
175
+ For this example we will be using the `streamed_batches.yaml` config. Like before, a placeholder variable is used when specifing which configuration to use:
176
+
177
+ `configuration: "PLACEHOLDER.yaml"`
178
+
179
+ This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
180
+
181
+ `configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
182
+ `
183
+
184
+ Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
185
+
186
+ ### Running the batch creation script
187
+
188
+ Run the save_batches.py script to create batches with the following example arguments as:
215
189
 
216
190
  ```
217
- python scripts/save_batches.py datamodule=local_ocf_datapipes +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
191
+ python scripts/save_batches.py datamodule=streamed_batches +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
218
192
  ```
219
193
 
194
+ In this function the datamodule argument looks for a config under `PVNet/configs/datamodule`. The examples here are either to use "premade_batches" or "streamed_batches".
195
+
196
+ Its important that the dates set for the training, validation and testing in the datamodule (`streamed_batches.yaml`) config are within the ranges of the dates set for the input features in the configuration (`gcp_configuration.yaml`).
197
+
198
+ If downloading private data from a gcp bucket make sure to authenticate gcloud (the public satellite data does not need authentication):
199
+
200
+ ```
201
+ gcloud auth login
202
+ ```
203
+
204
+ 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:
205
+
206
+ ```
207
+ satellite:
208
+ satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
209
+ ```
210
+
211
+ To satellite data hosted by Google:
212
+
213
+ ```
214
+ satellite:
215
+ satellite_zarr_paths:
216
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
217
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2021_nonhrv.zarr"
218
+ ```
219
+ Datapipes is currently set up to use 11 channels from the satellite data, the 12th of which is HRV and is not included in these.
220
+
221
+
220
222
  ### Training PVNet
221
223
 
222
224
  How PVNet is run is determined by the extensive configuration in the config
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PVNet
3
- Version: 2.6.8
3
+ Version: 2.6.10
4
4
  Summary: PVNet
5
5
  Author: Peter Dudfield
6
6
  Author-email: info@openclimatefix.org
@@ -32,6 +32,7 @@ Requires-Dist: hydra-core
32
32
  Requires-Dist: python-dotenv
33
33
  Requires-Dist: hydra-optuna-sweeper
34
34
  Requires-Dist: rich
35
+ Requires-Dist: gcsfs
35
36
  Provides-Extra: all-models
36
37
  Requires-Dist: pytorch-tabnet; extra == "all-models"
37
38
  Requires-Dist: efficientnet_pytorch; extra == "all-models"
@@ -66,12 +67,26 @@ cd PVNet
66
67
  pip install -r requirements.txt
67
68
  ```
68
69
 
70
+ The commit history is extensive. To save download time, use a depth of 1:
71
+ ```bash
72
+ git clone --depth 1 https://github.com/openclimatefix/PVNet.git
73
+ ```
74
+ This means only the latest commit and its associated files will be downloaded.
75
+
76
+ Next, in the PVNet repo, install PVNet as an editable package:
77
+
78
+ ```bash
79
+ pip install -e .
80
+ ```
81
+
69
82
  ### Additional development dependencies
70
83
 
71
84
  ```bash
72
85
  pip install -r requirements-dev.txt
73
86
  ```
74
87
 
88
+
89
+
75
90
  ## Getting started with running PVNet
76
91
 
77
92
  Before running any code in within PVNet, copy the example configuration to a
@@ -107,116 +122,103 @@ https://huggingface.co/datasets/openclimatefix/dwd-icon-eu which includes the UK
107
122
  OCF maintains a dataset of PV generation from 1311 private PV installations
108
123
  here: https://huggingface.co/datasets/openclimatefix/uk_pv
109
124
 
110
- ### Generating pre-made batches of data for training/validation of PVNet
111
125
 
112
- PVNet contains a script for generating batches of data suitable for training the
113
- PVNet models.
126
+ ### Connecting with ocf_datapipes for batch creation
114
127
 
115
- To run the script you will need to make some modifications to the datamodule
116
- configuration.
128
+ Outside the PVNet repo, clone the ocf-datapipes repo and exit the conda env created for PVNet: https://github.com/openclimatefix/ocf_datapipes
129
+ ```bash
130
+ git clone --depth 1 https://github.com/openclimatefix/ocf_datapipes.git
131
+ conda create -n ocf_datapipes python=3.10
132
+ ```
117
133
 
118
- 1. First, create your new configuration file in
119
- `./configs/datamodule/configiration/local_configuration.yaml` and paste the
120
- sample config (shown below)
121
- 2. Duplicate the `./configs/datamodule/ocf_datapipes.yaml` to
122
- `./configs/datamodule/_local_ocf_datapipes.yaml` and ensure the
123
- `configuration` key points to your newly created configuration file in
124
- step 1.
125
- 3. Also in this file, update the train, val & test periods to cover the data you
126
- have access to.
127
- 4. To get you started with your own configuration file, see the sample config
128
- below. Update the data paths to the location of your local GSP, NWP and PV
129
- datasets:
134
+ Then go inside the ocf_datapipes repo to add packages
130
135
 
131
- ```yaml
132
- general:
133
- description: Demo config
134
- name: demo_datamodule_config
135
-
136
- input_data:
137
- default_history_minutes: 60
138
- default_forecast_minutes: 120
139
-
140
- gsp:
141
- gsp_zarr_path: /path/to/gsp-data.zarr
142
- history_minutes: 60
143
- forecast_minutes: 120
144
- time_resolution_minutes: 30
145
- start_datetime: "2019-01-01T00:00:00"
146
- end_datetime: "2019-01-08T00:00:00"
147
- metadata_only: false
148
-
149
- nwp:
150
- ukv:
151
- nwp_zarr_path: /path/to/nwp-data.zarr
152
- history_minutes: 60
153
- forecast_minutes: 120
154
- time_resolution_minutes: 60
155
- nwp_channels: # comment out channels as appropriate
156
- - t # 2-metre temperature
157
- - dswrf # downwards short-wave radiation flux
158
- - dlwrf # downwards long-wave radiation flux
159
- - hcc # high cloud cover
160
- - mcc # medium cloud cover
161
- - lcc # low cloud cover
162
- - vis # visability
163
- - r # relative humidity
164
- - prate # precipitation rate
165
- - si10 # 10-metre wind speed | live = unknown
166
- nwp_image_size_pixels_height: 24
167
- nwp_image_size_pixels_width: 24
168
- nwp_provider: ukv
169
-
170
- pv:
171
- pv_files_groups:
172
- - label: pvoutput.org
173
- pv_filename: /path/to/pv-data/pv.netcdf
174
- pv_metadata_filename: /path/to/pv-data/metadata.csv
175
- history_minutes: 60
176
- forecast_minutes: 0 # PVNet assumes no future PV generation
177
- time_resolution_minutes: 5
178
- start_datetime: "2019-01-01T00:00:00"
179
- end_datetime: "2019-01-08T00:00:00"
180
- pv_image_size_meters_height: 24
181
- pv_image_size_meters_width: 24
182
- pv_ml_ids: [154,155,156,158,159,160,162,164,165,166,167,168,169,171,173,177,178,179,181,182,185,186,187,188,189,190,191,192,193,197,198,199,200,202,204,205,206,208,209,211,214,215,216,217,218,219,220,221,225,229,230,232,233,234,236,242,243,245,252,254,255,256,257,258,260,261,262,265,267,268,272,273,275,276,277,280,281,282,283,287,289,291,292,293,294,295,296,297,298,301,302,303,304,306,307,309,310,311,317,318,319,320,321,322,323,325,326,329,332,333,335,336,338,340,342,344,345,346,348,349,352,354,355,356,357,360,362,363,368,369,370,371,372,374,375,376,378,380,382,384,385,388,390,391,393,396,397,398,399,400,401,403,404,405,406,407,409,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,429,431,435,437,438,440,441,444,447,450,451,453,456,457,458,459,464,465,466,467,468,470,471,473,474,476,477,479,480,481,482,485,486,488,490,491,492,493,496,498,501,503,506,507,508,509,510,511,512,513,515,516,517,519,520,521,522,524,526,527,528,531,532,536,537,538,540,541,542,543,544,545,549,550,551,552,553,554,556,557,560,561,563,566,568,571,572,575,576,577,579,580,581,582,584,585,588,590,594,595,597,600,602,603,604,606,611,613,614,616,618,620,622,623,624,625,626,628,629,630,631,636,637,638,640,641,642,644,645,646,650,651,652,653,654,655,657,660,661,662,663,666,667,668,670,675,676,679,681,683,684,685,687,696,698,701,702,703,704,706,710,722,723,724,725,727,728,729,730,732,733,734,735,736,737,]
183
- n_pv_systems_per_example: 128
184
- get_center: false
185
- is_live: false
186
-
187
- satellite:
188
- satellite_zarr_path: "" # Left empty to avoid using satellite data
189
- history_minutes: 60
190
- forecast_minutes: 0
191
- live_delay_minutes: 30
192
- time_resolution_minutes: 5
193
- satellite_channels:
194
- - IR_016
195
- - IR_039
196
- - IR_087
197
- - IR_097
198
- - IR_108
199
- - IR_120
200
- - IR_134
201
- - VIS006
202
- - VIS008
203
- - WV_062
204
- - WV_073
205
- satellite_image_size_pixels_height: 24
206
- satellite_image_size_pixels_width: 24
136
+ ```bash
137
+ pip install -r requirements.txt requirements-dev.txt
207
138
  ```
208
139
 
140
+ 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.
141
+
142
+ ```bash
143
+ pip install -e <PATH-TO-ocf_datapipes-REPO>
144
+ ```
145
+
146
+ ## Generating pre-made batches of data for training/validation of PVNet
147
+
148
+ PVNet contains a script for generating batches of data suitable for training the PVNet models. To run the script you will need to make some modifications to the datamodule configuration.
149
+
150
+ Make sure you have copied the example configs (as already stated above):
151
+ ```
152
+ cp -r configs.example configs
153
+ ```
154
+
155
+ ### Set up and config example for batch creation
156
+
157
+ We will use the example of creating batches using data from gcp:
158
+ `/PVNet/configs/datamodule/configuration/gcp_configuration.yaml`
159
+ Ensure that the file paths are set to the correct locations in
160
+ `gcp_configuration.yaml`.
161
+
162
+ `PLACEHOLDER` is used to indcate where to input the location of the files.
163
+
164
+ For OCF use cases, file locations can be found in `template_configuration.yaml` located alongside `gcp_configuration.yaml`.
165
+
166
+ In these configurations you can update the train, val & test periods to cover the data you have access to.
167
+
168
+
209
169
  With your configuration in place, you can proceed to create batches. PVNet uses
210
170
  [hydra](https://hydra.cc/) which enables us to pass variables via the command
211
171
  line that will override the configuration defined in the `./configs` directory.
212
172
 
213
- Run the save_batches.py script to create batches with the following arguments as
214
- a minimum:
173
+ When creating batches, an additional config is used which is passed into the batch creation script. This is the datamodule config located `PVNet/configs/datamodule`.
174
+
175
+ For this example we will be using the `streamed_batches.yaml` config. Like before, a placeholder variable is used when specifing which configuration to use:
176
+
177
+ `configuration: "PLACEHOLDER.yaml"`
178
+
179
+ This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
180
+
181
+ `configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
182
+ `
183
+
184
+ Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
185
+
186
+ ### Running the batch creation script
187
+
188
+ Run the save_batches.py script to create batches with the following example arguments as:
215
189
 
216
190
  ```
217
- python scripts/save_batches.py datamodule=local_ocf_datapipes +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
191
+ python scripts/save_batches.py datamodule=streamed_batches +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
218
192
  ```
219
193
 
194
+ In this function the datamodule argument looks for a config under `PVNet/configs/datamodule`. The examples here are either to use "premade_batches" or "streamed_batches".
195
+
196
+ Its important that the dates set for the training, validation and testing in the datamodule (`streamed_batches.yaml`) config are within the ranges of the dates set for the input features in the configuration (`gcp_configuration.yaml`).
197
+
198
+ If downloading private data from a gcp bucket make sure to authenticate gcloud (the public satellite data does not need authentication):
199
+
200
+ ```
201
+ gcloud auth login
202
+ ```
203
+
204
+ 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:
205
+
206
+ ```
207
+ satellite:
208
+ satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
209
+ ```
210
+
211
+ To satellite data hosted by Google:
212
+
213
+ ```
214
+ satellite:
215
+ satellite_zarr_paths:
216
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
217
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2021_nonhrv.zarr"
218
+ ```
219
+ Datapipes is currently set up to use 11 channels from the satellite data, the 12th of which is HRV and is not included in these.
220
+
221
+
220
222
  ### Training PVNet
221
223
 
222
224
  How PVNet is run is determined by the extensive configuration in the config
@@ -23,6 +23,7 @@ hydra-core
23
23
  python-dotenv
24
24
  hydra-optuna-sweeper
25
25
  rich
26
+ gcsfs
26
27
 
27
28
  [all_models]
28
29
  pytorch-tabnet
@@ -28,12 +28,26 @@ cd PVNet
28
28
  pip install -r requirements.txt
29
29
  ```
30
30
 
31
+ The commit history is extensive. To save download time, use a depth of 1:
32
+ ```bash
33
+ git clone --depth 1 https://github.com/openclimatefix/PVNet.git
34
+ ```
35
+ This means only the latest commit and its associated files will be downloaded.
36
+
37
+ Next, in the PVNet repo, install PVNet as an editable package:
38
+
39
+ ```bash
40
+ pip install -e .
41
+ ```
42
+
31
43
  ### Additional development dependencies
32
44
 
33
45
  ```bash
34
46
  pip install -r requirements-dev.txt
35
47
  ```
36
48
 
49
+
50
+
37
51
  ## Getting started with running PVNet
38
52
 
39
53
  Before running any code in within PVNet, copy the example configuration to a
@@ -69,116 +83,103 @@ https://huggingface.co/datasets/openclimatefix/dwd-icon-eu which includes the UK
69
83
  OCF maintains a dataset of PV generation from 1311 private PV installations
70
84
  here: https://huggingface.co/datasets/openclimatefix/uk_pv
71
85
 
72
- ### Generating pre-made batches of data for training/validation of PVNet
73
86
 
74
- PVNet contains a script for generating batches of data suitable for training the
75
- PVNet models.
87
+ ### Connecting with ocf_datapipes for batch creation
76
88
 
77
- To run the script you will need to make some modifications to the datamodule
78
- configuration.
89
+ Outside the PVNet repo, clone the ocf-datapipes repo and exit the conda env created for PVNet: https://github.com/openclimatefix/ocf_datapipes
90
+ ```bash
91
+ git clone --depth 1 https://github.com/openclimatefix/ocf_datapipes.git
92
+ conda create -n ocf_datapipes python=3.10
93
+ ```
79
94
 
80
- 1. First, create your new configuration file in
81
- `./configs/datamodule/configiration/local_configuration.yaml` and paste the
82
- sample config (shown below)
83
- 2. Duplicate the `./configs/datamodule/ocf_datapipes.yaml` to
84
- `./configs/datamodule/_local_ocf_datapipes.yaml` and ensure the
85
- `configuration` key points to your newly created configuration file in
86
- step 1.
87
- 3. Also in this file, update the train, val & test periods to cover the data you
88
- have access to.
89
- 4. To get you started with your own configuration file, see the sample config
90
- below. Update the data paths to the location of your local GSP, NWP and PV
91
- datasets:
95
+ Then go inside the ocf_datapipes repo to add packages
92
96
 
93
- ```yaml
94
- general:
95
- description: Demo config
96
- name: demo_datamodule_config
97
-
98
- input_data:
99
- default_history_minutes: 60
100
- default_forecast_minutes: 120
101
-
102
- gsp:
103
- gsp_zarr_path: /path/to/gsp-data.zarr
104
- history_minutes: 60
105
- forecast_minutes: 120
106
- time_resolution_minutes: 30
107
- start_datetime: "2019-01-01T00:00:00"
108
- end_datetime: "2019-01-08T00:00:00"
109
- metadata_only: false
110
-
111
- nwp:
112
- ukv:
113
- nwp_zarr_path: /path/to/nwp-data.zarr
114
- history_minutes: 60
115
- forecast_minutes: 120
116
- time_resolution_minutes: 60
117
- nwp_channels: # comment out channels as appropriate
118
- - t # 2-metre temperature
119
- - dswrf # downwards short-wave radiation flux
120
- - dlwrf # downwards long-wave radiation flux
121
- - hcc # high cloud cover
122
- - mcc # medium cloud cover
123
- - lcc # low cloud cover
124
- - vis # visability
125
- - r # relative humidity
126
- - prate # precipitation rate
127
- - si10 # 10-metre wind speed | live = unknown
128
- nwp_image_size_pixels_height: 24
129
- nwp_image_size_pixels_width: 24
130
- nwp_provider: ukv
131
-
132
- pv:
133
- pv_files_groups:
134
- - label: pvoutput.org
135
- pv_filename: /path/to/pv-data/pv.netcdf
136
- pv_metadata_filename: /path/to/pv-data/metadata.csv
137
- history_minutes: 60
138
- forecast_minutes: 0 # PVNet assumes no future PV generation
139
- time_resolution_minutes: 5
140
- start_datetime: "2019-01-01T00:00:00"
141
- end_datetime: "2019-01-08T00:00:00"
142
- pv_image_size_meters_height: 24
143
- pv_image_size_meters_width: 24
144
- pv_ml_ids: [154,155,156,158,159,160,162,164,165,166,167,168,169,171,173,177,178,179,181,182,185,186,187,188,189,190,191,192,193,197,198,199,200,202,204,205,206,208,209,211,214,215,216,217,218,219,220,221,225,229,230,232,233,234,236,242,243,245,252,254,255,256,257,258,260,261,262,265,267,268,272,273,275,276,277,280,281,282,283,287,289,291,292,293,294,295,296,297,298,301,302,303,304,306,307,309,310,311,317,318,319,320,321,322,323,325,326,329,332,333,335,336,338,340,342,344,345,346,348,349,352,354,355,356,357,360,362,363,368,369,370,371,372,374,375,376,378,380,382,384,385,388,390,391,393,396,397,398,399,400,401,403,404,405,406,407,409,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,429,431,435,437,438,440,441,444,447,450,451,453,456,457,458,459,464,465,466,467,468,470,471,473,474,476,477,479,480,481,482,485,486,488,490,491,492,493,496,498,501,503,506,507,508,509,510,511,512,513,515,516,517,519,520,521,522,524,526,527,528,531,532,536,537,538,540,541,542,543,544,545,549,550,551,552,553,554,556,557,560,561,563,566,568,571,572,575,576,577,579,580,581,582,584,585,588,590,594,595,597,600,602,603,604,606,611,613,614,616,618,620,622,623,624,625,626,628,629,630,631,636,637,638,640,641,642,644,645,646,650,651,652,653,654,655,657,660,661,662,663,666,667,668,670,675,676,679,681,683,684,685,687,696,698,701,702,703,704,706,710,722,723,724,725,727,728,729,730,732,733,734,735,736,737,]
145
- n_pv_systems_per_example: 128
146
- get_center: false
147
- is_live: false
148
-
149
- satellite:
150
- satellite_zarr_path: "" # Left empty to avoid using satellite data
151
- history_minutes: 60
152
- forecast_minutes: 0
153
- live_delay_minutes: 30
154
- time_resolution_minutes: 5
155
- satellite_channels:
156
- - IR_016
157
- - IR_039
158
- - IR_087
159
- - IR_097
160
- - IR_108
161
- - IR_120
162
- - IR_134
163
- - VIS006
164
- - VIS008
165
- - WV_062
166
- - WV_073
167
- satellite_image_size_pixels_height: 24
168
- satellite_image_size_pixels_width: 24
97
+ ```bash
98
+ pip install -r requirements.txt requirements-dev.txt
169
99
  ```
170
100
 
101
+ 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.
102
+
103
+ ```bash
104
+ pip install -e <PATH-TO-ocf_datapipes-REPO>
105
+ ```
106
+
107
+ ## Generating pre-made batches of data for training/validation of PVNet
108
+
109
+ PVNet contains a script for generating batches of data suitable for training the PVNet models. To run the script you will need to make some modifications to the datamodule configuration.
110
+
111
+ Make sure you have copied the example configs (as already stated above):
112
+ ```
113
+ cp -r configs.example configs
114
+ ```
115
+
116
+ ### Set up and config example for batch creation
117
+
118
+ We will use the example of creating batches using data from gcp:
119
+ `/PVNet/configs/datamodule/configuration/gcp_configuration.yaml`
120
+ Ensure that the file paths are set to the correct locations in
121
+ `gcp_configuration.yaml`.
122
+
123
+ `PLACEHOLDER` is used to indcate where to input the location of the files.
124
+
125
+ For OCF use cases, file locations can be found in `template_configuration.yaml` located alongside `gcp_configuration.yaml`.
126
+
127
+ In these configurations you can update the train, val & test periods to cover the data you have access to.
128
+
129
+
171
130
  With your configuration in place, you can proceed to create batches. PVNet uses
172
131
  [hydra](https://hydra.cc/) which enables us to pass variables via the command
173
132
  line that will override the configuration defined in the `./configs` directory.
174
133
 
175
- Run the save_batches.py script to create batches with the following arguments as
176
- a minimum:
134
+ When creating batches, an additional config is used which is passed into the batch creation script. This is the datamodule config located `PVNet/configs/datamodule`.
135
+
136
+ For this example we will be using the `streamed_batches.yaml` config. Like before, a placeholder variable is used when specifing which configuration to use:
137
+
138
+ `configuration: "PLACEHOLDER.yaml"`
139
+
140
+ This should be given the whole path to the config on your local machine, such as for our example it should be changed to:
141
+
142
+ `configuration: "/FULL-PATH-TO-REPO/PVNet/configs/datamodule/configuration/gcp_configuration.yaml"
143
+ `
144
+
145
+ Where `FULL-PATH-TO-REPO` represent the whole path to the PVNet repo on your local machine.
146
+
147
+ ### Running the batch creation script
148
+
149
+ Run the save_batches.py script to create batches with the following example arguments as:
177
150
 
178
151
  ```
179
- python scripts/save_batches.py datamodule=local_ocf_datapipes +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
152
+ python scripts/save_batches.py datamodule=streamed_batches +batch_output_dir="./output" +num_train_batches=10 +num_val_batches=5
180
153
  ```
181
154
 
155
+ In this function the datamodule argument looks for a config under `PVNet/configs/datamodule`. The examples here are either to use "premade_batches" or "streamed_batches".
156
+
157
+ Its important that the dates set for the training, validation and testing in the datamodule (`streamed_batches.yaml`) config are within the ranges of the dates set for the input features in the configuration (`gcp_configuration.yaml`).
158
+
159
+ If downloading private data from a gcp bucket make sure to authenticate gcloud (the public satellite data does not need authentication):
160
+
161
+ ```
162
+ gcloud auth login
163
+ ```
164
+
165
+ 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:
166
+
167
+ ```
168
+ satellite:
169
+ satellite_zarr_path: gs://solar-pv-nowcasting-data/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr
170
+ ```
171
+
172
+ To satellite data hosted by Google:
173
+
174
+ ```
175
+ satellite:
176
+ satellite_zarr_paths:
177
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2020_nonhrv.zarr"
178
+ - "gs://public-datasets-eumetsat-solar-forecasting/satellite/EUMETSAT/SEVIRI_RSS/v4/2021_nonhrv.zarr"
179
+ ```
180
+ Datapipes is currently set up to use 11 channels from the satellite data, the 12th of which is HRV and is not included in these.
181
+
182
+
182
183
  ### Training PVNet
183
184
 
184
185
  How PVNet is run is determined by the extensive configuration in the config
@@ -0,0 +1,2 @@
1
+ """PVNet"""
2
+ __version__ = "2.6.10"
@@ -23,7 +23,6 @@ class DataModule(LightningDataModule):
23
23
  train_period=[None, None],
24
24
  val_period=[None, None],
25
25
  test_period=[None, None],
26
- block_nwp_and_sat=False,
27
26
  batch_dir=None,
28
27
  ):
29
28
  """Datamodule for training pvnet and using pvnet pipeline in `ocf_datapipes`.
@@ -39,8 +38,6 @@ class DataModule(LightningDataModule):
39
38
  train_period: Date range filter for train dataloader.
40
39
  val_period: Date range filter for val dataloader.
41
40
  test_period: Date range filter for test dataloader.
42
- block_nwp_and_sat: If True, the dataloader does not load the requested NWP and sat data.
43
- It instead returns an zero-array of the required shape. Useful for pretraining.
44
41
  batch_dir: Path to the directory of pre-saved batches. Cannot be used together with
45
42
  `configuration` or 'train/val/test_period'.
46
43
 
@@ -48,7 +45,6 @@ class DataModule(LightningDataModule):
48
45
  super().__init__()
49
46
  self.configuration = configuration
50
47
  self.batch_size = batch_size
51
- self.block_nwp_and_sat = block_nwp_and_sat
52
48
  self.batch_dir = batch_dir
53
49
 
54
50
  if not ((batch_dir is not None) ^ (configuration is not None)):
@@ -69,7 +65,6 @@ class DataModule(LightningDataModule):
69
65
  ]
70
66
 
71
67
  self._common_dataloader_kwargs = dict(
72
- shuffle=False, # shuffled in datapipe step
73
68
  batch_size=None, # batched in datapipe step
74
69
  sampler=None,
75
70
  batch_sampler=None,
@@ -88,8 +83,6 @@ class DataModule(LightningDataModule):
88
83
  self.configuration,
89
84
  start_time=start_time,
90
85
  end_time=end_time,
91
- block_sat=self.block_nwp_and_sat,
92
- block_nwp=self.block_nwp_and_sat,
93
86
  )
94
87
 
95
88
  data_pipeline = (
@@ -131,7 +124,7 @@ class DataModule(LightningDataModule):
131
124
  datapipe = self._get_premade_batches_datapipe("train", shuffle=True)
132
125
  else:
133
126
  datapipe = self._get_datapipe(*self.train_period)
134
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
127
+ return DataLoader(datapipe, shuffle=True, **self._common_dataloader_kwargs)
135
128
 
136
129
  def val_dataloader(self):
137
130
  """Construct val dataloader"""
@@ -139,7 +132,7 @@ class DataModule(LightningDataModule):
139
132
  datapipe = self._get_premade_batches_datapipe("val")
140
133
  else:
141
134
  datapipe = self._get_datapipe(*self.val_period)
142
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
135
+ return DataLoader(datapipe, shuffle=False, **self._common_dataloader_kwargs)
143
136
 
144
137
  def test_dataloader(self):
145
138
  """Construct test dataloader"""
@@ -147,4 +140,4 @@ class DataModule(LightningDataModule):
147
140
  datapipe = self._get_premade_batches_datapipe("test")
148
141
  else:
149
142
  datapipe = self._get_datapipe(*self.test_period)
150
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
143
+ return DataLoader(datapipe, shuffle=False, **self._common_dataloader_kwargs)
@@ -61,7 +61,6 @@ class WindDataModule(LightningDataModule):
61
61
  ]
62
62
 
63
63
  self._common_dataloader_kwargs = dict(
64
- shuffle=False, # shuffled in datapipe step
65
64
  batch_size=None, # batched in datapipe step
66
65
  sampler=None,
67
66
  batch_sampler=None,
@@ -123,7 +122,7 @@ class WindDataModule(LightningDataModule):
123
122
  datapipe = self._get_premade_batches_datapipe("train", shuffle=True)
124
123
  else:
125
124
  datapipe = self._get_datapipe(*self.train_period)
126
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
125
+ return DataLoader(datapipe, shuffle=True, **self._common_dataloader_kwargs)
127
126
 
128
127
  def val_dataloader(self):
129
128
  """Construct val dataloader"""
@@ -131,7 +130,7 @@ class WindDataModule(LightningDataModule):
131
130
  datapipe = self._get_premade_batches_datapipe("val")
132
131
  else:
133
132
  datapipe = self._get_datapipe(*self.val_period)
134
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
133
+ return DataLoader(datapipe, shuffle=False, **self._common_dataloader_kwargs)
135
134
 
136
135
  def test_dataloader(self):
137
136
  """Construct test dataloader"""
@@ -139,4 +138,4 @@ class WindDataModule(LightningDataModule):
139
138
  datapipe = self._get_premade_batches_datapipe("test")
140
139
  else:
141
140
  datapipe = self._get_datapipe(*self.test_period)
142
- return DataLoader(datapipe, **self._common_dataloader_kwargs)
141
+ return DataLoader(datapipe, shuffle=False, **self._common_dataloader_kwargs)
@@ -234,6 +234,7 @@ class BaseModel(pl.LightningModule, PVNetModelHubMixin):
234
234
  forecast_minutes: int,
235
235
  optimizer: AbstractOptimizer,
236
236
  output_quantiles: Optional[list[float]] = None,
237
+ target_key: BatchKey = BatchKey.gsp,
237
238
  ):
238
239
  """Abtstract base class for PVNet submodels.
239
240
 
@@ -243,10 +244,12 @@ class BaseModel(pl.LightningModule, PVNetModelHubMixin):
243
244
  optimizer (AbstractOptimizer): Optimizer
244
245
  output_quantiles: A list of float (0.0, 1.0) quantiles to predict values for. If set to
245
246
  None the output is a single value.
247
+ target_key: The key of the target variable in the batch
246
248
  """
247
249
  super().__init__()
248
250
 
249
251
  self._optimizer = optimizer
252
+ self._target_key = target_key
250
253
 
251
254
  # Model must have lr to allow tuning
252
255
  # This setting is only used when lr is tuned with callback
@@ -424,7 +427,7 @@ class BaseModel(pl.LightningModule, PVNetModelHubMixin):
424
427
  def training_step(self, batch, batch_idx):
425
428
  """Run training step"""
426
429
  y_hat = self(batch)
427
- y = batch[BatchKey.gsp][:, -self.forecast_len_30 :, 0]
430
+ y = batch[self._target_key][:, -self.forecast_len_30 :, 0]
428
431
 
429
432
  losses = self._calculate_common_losses(y, y_hat)
430
433
  losses = {f"{k}/train": v for k, v in losses.items()}
@@ -440,7 +443,7 @@ class BaseModel(pl.LightningModule, PVNetModelHubMixin):
440
443
  def validation_step(self, batch: dict, batch_idx):
441
444
  """Run validation step"""
442
445
  y_hat = self(batch)
443
- y = batch[BatchKey.gsp][:, -self.forecast_len_30 :, 0]
446
+ y = batch[self._target_key][:, -self.forecast_len_30 :, 0]
444
447
 
445
448
  losses = self._calculate_common_losses(y, y_hat)
446
449
  losses.update(self._calculate_val_losses(y, y_hat))
@@ -484,7 +487,7 @@ class BaseModel(pl.LightningModule, PVNetModelHubMixin):
484
487
  def test_step(self, batch, batch_idx):
485
488
  """Run test step"""
486
489
  y_hat = self(batch)
487
- y = batch[BatchKey.gsp][:, -self.forecast_len_30 :, 0]
490
+ y = batch[self._target_key][:, -self.forecast_len_30 :, 0]
488
491
 
489
492
  losses = self._calculate_common_losses(y, y_hat)
490
493
  losses.update(self._calculate_val_losses(y, y_hat))
@@ -54,6 +54,7 @@ class Model(BaseModel):
54
54
  nwp_history_minutes: Optional[int] = None,
55
55
  pv_history_minutes: Optional[int] = None,
56
56
  optimizer: AbstractOptimizer = pvnet.optimizers.Adam(),
57
+ target_key: str = "gsp",
57
58
  ):
58
59
  """Neural network which combines information from different sources.
59
60
 
@@ -94,6 +95,7 @@ class Model(BaseModel):
94
95
  pv_history_minutes: Length of recent site-level PV data data used as input. Defaults to
95
96
  `history_minutes` if not provided.
96
97
  optimizer: Optimizer factory function used for network.
98
+ target_key: The key of the target variable in the batch.
97
99
  """
98
100
 
99
101
  self.include_gsp_yield_history = include_gsp_yield_history
@@ -103,8 +105,15 @@ class Model(BaseModel):
103
105
  self.include_sun = include_sun
104
106
  self.embedding_dim = embedding_dim
105
107
  self.add_image_embedding_channel = add_image_embedding_channel
106
-
107
- super().__init__(history_minutes, forecast_minutes, optimizer, output_quantiles)
108
+ self.target_key_name = target_key
109
+
110
+ super().__init__(
111
+ history_minutes=history_minutes,
112
+ forecast_minutes=forecast_minutes,
113
+ optimizer=optimizer,
114
+ output_quantiles=output_quantiles,
115
+ target_key=BatchKey.gsp if target_key == "gsp" else BatchKey.pv,
116
+ )
108
117
 
109
118
  # Number of features expected by the output_network
110
119
  # Add to this as network pices are constructed
@@ -228,7 +237,12 @@ class Model(BaseModel):
228
237
  # *********************** PV Data *************************************
229
238
  # Add site-level PV yield
230
239
  if self.include_pv:
231
- modes["pv"] = self.pv_encoder(x)
240
+ if self.target_key_name != "pv":
241
+ modes["pv"] = self.pv_encoder(x)
242
+ else:
243
+ # Target is PV, so only take the history
244
+ pv_history = x[BatchKey.pv][:, : self.history_len_30].float()
245
+ modes["pv"] = self.pv_encoder(pv_history)
232
246
 
233
247
  # *********************** GSP Data ************************************
234
248
  # add gsp yield history
@@ -27,7 +27,7 @@ class PredAccumulator:
27
27
 
28
28
  def append(self, y_hat: torch.Tensor):
29
29
  """Append a sub-batch of predictions"""
30
- self._y_hats += [y_hat]
30
+ self._y_hats.append(y_hat)
31
31
 
32
32
  def flush(self) -> torch.Tensor:
33
33
  """Return all appended predictions as single tensor and remove from accumulated store."""
@@ -42,7 +42,7 @@ class DictListAccumulator:
42
42
  @staticmethod
43
43
  def _dict_list_append(d1, d2):
44
44
  for k, v in d2.items():
45
- d1[k] += [v]
45
+ d1[k].append(v)
46
46
 
47
47
  @staticmethod
48
48
  def _dict_init_list(d):
@@ -139,12 +139,16 @@ def train(config: DictConfig) -> Optional[float]:
139
139
 
140
140
  if should_pretrain:
141
141
  # Pre-train the model
142
- datamodule.block_nwp_and_sat = True
142
+ raise NotImplementedError("Pre-training is not yet supported")
143
+ # The parameter `block_nwp_and_sat` has been removed from datapipes
144
+ # If pretraining is re-supported in the future it is likely any pre-training logic should
145
+ # go here or perhaps in the callbacks
146
+ # datamodule.block_nwp_and_sat = True
147
+
143
148
  trainer.fit(model=model, datamodule=datamodule)
144
149
 
145
150
  _callbacks_to_phase(callbacks, "main")
146
151
 
147
- datamodule.block_nwp_and_sat = False
148
152
  trainer.should_stop = False
149
153
 
150
154
  # Train the model completely
@@ -242,22 +242,26 @@ def finish(
242
242
  wandb.finish()
243
243
 
244
244
 
245
- def plot_batch_forecasts(batch, y_hat, batch_idx=None, quantiles=None):
245
+ def plot_batch_forecasts(batch, y_hat, batch_idx=None, quantiles=None, key_to_plot: str = "gsp"):
246
246
  """Plot a batch of data and the forecast from that batch"""
247
247
 
248
248
  def _get_numpy(key):
249
249
  return batch[key].cpu().numpy().squeeze()
250
250
 
251
- y = batch[BatchKey.gsp].cpu().numpy()
251
+ y_key = BatchKey.gsp if key_to_plot == "gsp" else BatchKey.pv
252
+ y_id_key = BatchKey.gsp_id if key_to_plot == "gsp" else BatchKey.pv_id
253
+ t0_idx_key = BatchKey.gsp_t0_idx if key_to_plot == "gsp" else BatchKey.pv_t0_idx
254
+ time_utc_key = BatchKey.gsp_time_utc if key_to_plot == "gsp" else BatchKey.pv_time_utc
255
+ plotting_name = key_to_plot.upper()
256
+ y = batch[y_key].cpu().numpy()
252
257
  y_hat = y_hat.cpu().numpy()
253
258
 
254
- gsp_ids = batch[BatchKey.gsp_id].cpu().numpy().squeeze()
255
- t0_idx = batch[BatchKey.gsp_t0_idx]
259
+ gsp_ids = batch[y_id_key].cpu().numpy().squeeze()
260
+ batch[t0_idx_key]
256
261
 
257
- times_utc = batch[BatchKey.gsp_time_utc].cpu().numpy().squeeze().astype("datetime64[s]")
262
+ times_utc = batch[time_utc_key].cpu().numpy().squeeze().astype("datetime64[s]")
258
263
  times_utc = [pd.to_datetime(t) for t in times_utc]
259
264
 
260
- len(times_utc[0]) - t0_idx - 1
261
265
  batch_size = y.shape[0]
262
266
 
263
267
  fig, axes = plt.subplots(4, 4, figsize=(8, 8))
@@ -295,9 +299,9 @@ def plot_batch_forecasts(batch, y_hat, batch_idx=None, quantiles=None):
295
299
  ax.set_xlabel("Time (hour of day)")
296
300
 
297
301
  if batch_idx is not None:
298
- title = f"Normed GSP output : batch_idx={batch_idx}"
302
+ title = f"Normed {plotting_name} output : batch_idx={batch_idx}"
299
303
  else:
300
- title = "Normed GSP output"
304
+ title = f"Normed {plotting_name} output"
301
305
  plt.suptitle(title)
302
306
  plt.tight_layout()
303
307
 
@@ -23,3 +23,5 @@ hydra-core
23
23
  python-dotenv
24
24
  hydra-optuna-sweeper
25
25
  rich
26
+ # gcsfs is only needed when getting data from Google Cloud Storage
27
+ gcsfs
@@ -123,7 +123,6 @@ def sample_train_val_datamodule():
123
123
  train_period=[None, None],
124
124
  val_period=[None, None],
125
125
  test_period=[None, None],
126
- block_nwp_and_sat=False,
127
126
  batch_dir=f"{tmpdirname}",
128
127
  )
129
128
  yield dm
@@ -139,7 +138,6 @@ def sample_datamodule():
139
138
  train_period=[None, None],
140
139
  val_period=[None, None],
141
140
  test_period=[None, None],
142
- block_nwp_and_sat=False,
143
141
  batch_dir="tests/test_data/sample_batches",
144
142
  )
145
143
  return dm
@@ -1,2 +0,0 @@
1
- """PVNet"""
2
- __version__ = "2.6.8"
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