ocf-data-sampler 0.0.44__py3-none-any.whl → 0.0.45__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ocf-data-sampler might be problematic. Click here for more details.
- ocf_data_sampler/numpy_sample/__init__.py +1 -0
- ocf_data_sampler/numpy_sample/datetime_features.py +46 -0
- ocf_data_sampler/torch_datasets/process_and_combine.py +1 -0
- ocf_data_sampler/torch_datasets/site.py +21 -3
- {ocf_data_sampler-0.0.44.dist-info → ocf_data_sampler-0.0.45.dist-info}/METADATA +3 -2
- {ocf_data_sampler-0.0.44.dist-info → ocf_data_sampler-0.0.45.dist-info}/RECORD +11 -9
- tests/numpy_sample/test_datetime_features.py +47 -0
- tests/torch_datasets/test_site.py +3 -1
- {ocf_data_sampler-0.0.44.dist-info → ocf_data_sampler-0.0.45.dist-info}/LICENSE +0 -0
- {ocf_data_sampler-0.0.44.dist-info → ocf_data_sampler-0.0.45.dist-info}/WHEEL +0 -0
- {ocf_data_sampler-0.0.44.dist-info → ocf_data_sampler-0.0.45.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Conversion from Xarray to NumpySample"""
|
|
2
2
|
|
|
3
|
+
from .datetime_features import make_datetime_numpy_dict
|
|
3
4
|
from .gsp import convert_gsp_to_numpy_sample, GSPSampleKey
|
|
4
5
|
from .nwp import convert_nwp_to_numpy_sample, NWPSampleKey
|
|
5
6
|
from .satellite import convert_satellite_to_numpy_sample, SatelliteSampleKey
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Functions to create trigonometric date and time inputs"""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from numpy.typing import NDArray
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _get_date_time_in_pi(
|
|
9
|
+
dt: pd.DatetimeIndex,
|
|
10
|
+
) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
|
|
11
|
+
"""
|
|
12
|
+
Change the datetimes, into time and date scaled in radians
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
day_of_year = dt.dayofyear
|
|
16
|
+
minute_of_day = dt.minute + dt.hour * 60
|
|
17
|
+
|
|
18
|
+
# converting into positions on sin-cos circle
|
|
19
|
+
time_in_pi = (2 * np.pi) * (minute_of_day / (24 * 60))
|
|
20
|
+
date_in_pi = (2 * np.pi) * (day_of_year / 365)
|
|
21
|
+
|
|
22
|
+
return date_in_pi, time_in_pi
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def make_datetime_numpy_dict(datetimes: pd.DatetimeIndex, key_prefix: str = "wind") -> dict:
|
|
26
|
+
""" Make dictionary of datetime features"""
|
|
27
|
+
|
|
28
|
+
if datetimes.empty:
|
|
29
|
+
raise ValueError("Input datetimes is empty for 'make_datetime_numpy_dict' function")
|
|
30
|
+
|
|
31
|
+
time_numpy_sample = {}
|
|
32
|
+
|
|
33
|
+
date_in_pi, time_in_pi = _get_date_time_in_pi(datetimes)
|
|
34
|
+
|
|
35
|
+
# Store
|
|
36
|
+
date_sin_batch_key = key_prefix + "_date_sin"
|
|
37
|
+
date_cos_batch_key = key_prefix + "_date_cos"
|
|
38
|
+
time_sin_batch_key = key_prefix + "_time_sin"
|
|
39
|
+
time_cos_batch_key = key_prefix + "_time_cos"
|
|
40
|
+
|
|
41
|
+
time_numpy_sample[date_sin_batch_key] = np.sin(date_in_pi)
|
|
42
|
+
time_numpy_sample[date_cos_batch_key] = np.cos(date_in_pi)
|
|
43
|
+
time_numpy_sample[time_sin_batch_key] = np.sin(time_in_pi)
|
|
44
|
+
time_numpy_sample[time_cos_batch_key] = np.cos(time_in_pi)
|
|
45
|
+
|
|
46
|
+
return time_numpy_sample
|
|
@@ -10,6 +10,7 @@ from ocf_data_sampler.numpy_sample import (
|
|
|
10
10
|
convert_satellite_to_numpy_sample,
|
|
11
11
|
convert_gsp_to_numpy_sample,
|
|
12
12
|
make_sun_position_numpy_sample,
|
|
13
|
+
|
|
13
14
|
)
|
|
14
15
|
from ocf_data_sampler.numpy_sample.gsp import GSPSampleKey
|
|
15
16
|
from ocf_data_sampler.numpy_sample.nwp import NWPSampleKey
|
|
@@ -22,7 +22,9 @@ from ocf_data_sampler.torch_datasets.process_and_combine import merge_dicts, fil
|
|
|
22
22
|
from ocf_data_sampler.numpy_sample import (
|
|
23
23
|
convert_site_to_numpy_sample,
|
|
24
24
|
convert_satellite_to_numpy_sample,
|
|
25
|
-
convert_nwp_to_numpy_sample
|
|
25
|
+
convert_nwp_to_numpy_sample,
|
|
26
|
+
make_datetime_numpy_dict,
|
|
27
|
+
make_sun_position_numpy_sample,
|
|
26
28
|
)
|
|
27
29
|
from ocf_data_sampler.numpy_sample import NWPSampleKey
|
|
28
30
|
from ocf_data_sampler.constants import NWP_MEANS, NWP_STDS
|
|
@@ -234,10 +236,26 @@ class SitesDataset(Dataset):
|
|
|
234
236
|
da_sites = dataset_dict["site"]
|
|
235
237
|
da_sites = da_sites / da_sites.capacity_kwp
|
|
236
238
|
data_arrays.append(("site", da_sites))
|
|
237
|
-
|
|
239
|
+
|
|
238
240
|
combined_sample_dataset = self.merge_data_arrays(data_arrays)
|
|
239
241
|
|
|
240
|
-
#
|
|
242
|
+
# add datetime features
|
|
243
|
+
datetimes = pd.DatetimeIndex(combined_sample_dataset.site__time_utc.values)
|
|
244
|
+
datetime_features = make_datetime_numpy_dict(datetimes=datetimes, key_prefix="site")
|
|
245
|
+
datetime_features_xr = xr.Dataset(datetime_features, coords={"site__time_utc": datetimes})
|
|
246
|
+
combined_sample_dataset = xr.merge([combined_sample_dataset, datetime_features_xr])
|
|
247
|
+
|
|
248
|
+
# add sun features
|
|
249
|
+
sun_position_features = make_sun_position_numpy_sample(
|
|
250
|
+
datetimes=datetimes,
|
|
251
|
+
lon=combined_sample_dataset.site__longitude.values,
|
|
252
|
+
lat=combined_sample_dataset.site__latitude.values,
|
|
253
|
+
key_prefix="site",
|
|
254
|
+
)
|
|
255
|
+
sun_position_features_xr = xr.Dataset(
|
|
256
|
+
sun_position_features, coords={"site__time_utc": datetimes}
|
|
257
|
+
)
|
|
258
|
+
combined_sample_dataset = xr.merge([combined_sample_dataset, sun_position_features_xr])
|
|
241
259
|
|
|
242
260
|
# Fill any nan values
|
|
243
261
|
return combined_sample_dataset.fillna(0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: ocf_data_sampler
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.45
|
|
4
4
|
Summary: Sample from weather data for renewable energy prediction
|
|
5
5
|
Author: James Fulton, Peter Dudfield, and the Open Climate Fix team
|
|
6
6
|
Author-email: info@openclimatefix.org
|
|
@@ -56,7 +56,7 @@ Requires-Dist: mkdocs-material>=8.0; extra == "docs"
|
|
|
56
56
|
# ocf-data-sampler
|
|
57
57
|
|
|
58
58
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
59
|
-
[](#contributors-)
|
|
60
60
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
61
61
|
|
|
62
62
|
[](https://github.com/openclimatefix/ocf-data-sampler/tags)
|
|
@@ -135,6 +135,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
135
135
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/felix-e-h-p"><img src="https://avatars.githubusercontent.com/u/137530077?v=4?s=100" width="100px;" alt="Felix"/><br /><sub><b>Felix</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=felix-e-h-p" title="Code">💻</a></td>
|
|
136
136
|
<td align="center" valign="top" width="14.28%"><a href="https://timothyajaniportfolio-b6v3zq29k-timthegreat.vercel.app/"><img src="https://avatars.githubusercontent.com/u/60073728?v=4?s=100" width="100px;" alt="Ajani Timothy"/><br /><sub><b>Ajani Timothy</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=Tim1119" title="Code">💻</a></td>
|
|
137
137
|
<td align="center" valign="top" width="14.28%"><a href="https://rupeshmangalam.vercel.app/"><img src="https://avatars.githubusercontent.com/u/91172425?v=4?s=100" width="100px;" alt="Rupesh Mangalam"/><br /><sub><b>Rupesh Mangalam</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=RupeshMangalam21" title="Code">💻</a></td>
|
|
138
|
+
<td align="center" valign="top" width="14.28%"><a href="http://siddharth7113.github.io"><img src="https://avatars.githubusercontent.com/u/114160268?v=4?s=100" width="100px;" alt="Siddharth"/><br /><sub><b>Siddharth</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=siddharth7113" title="Code">💻</a></td>
|
|
138
139
|
</tr>
|
|
139
140
|
</tbody>
|
|
140
141
|
</table>
|
|
@@ -18,8 +18,9 @@ ocf_data_sampler/load/nwp/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
18
18
|
ocf_data_sampler/load/nwp/providers/ecmwf.py,sha256=2iR1Iy542lo51rC6XFLV-3pbUE68dWjlHa6TVJzx3ac,1280
|
|
19
19
|
ocf_data_sampler/load/nwp/providers/ukv.py,sha256=79Bm7q-K_GJPYMy62SUIZbRWRF4-tIaB1dYPEgLD9vo,1207
|
|
20
20
|
ocf_data_sampler/load/nwp/providers/utils.py,sha256=Sy2exG1wpXLLhMXYdsfR-DZMR3txG1_bBmBdchlc-yA,848
|
|
21
|
-
ocf_data_sampler/numpy_sample/__init__.py,sha256=
|
|
21
|
+
ocf_data_sampler/numpy_sample/__init__.py,sha256=nY5C6CcuxiWZ_jrXRzWtN7WyKXhJImSiVTIG6Rz4B_4,401
|
|
22
22
|
ocf_data_sampler/numpy_sample/collate.py,sha256=y8QFUhskaAfOMP22aVkexwyGAwLHbNE-q1pOZ6txWKA,2227
|
|
23
|
+
ocf_data_sampler/numpy_sample/datetime_features.py,sha256=U-9uRplfZ7VYFA4qBduI8OkG2x_65RYIP8wrLG4i-Nw,1441
|
|
23
24
|
ocf_data_sampler/numpy_sample/gsp.py,sha256=5UaWO_aGRRVQo82wnDaT4zBKHihOnIsXiwgPjM8vGFM,1005
|
|
24
25
|
ocf_data_sampler/numpy_sample/nwp.py,sha256=_seQNWsut3IzPsrpipqImjnaM3XNHZCy5_5be6syivk,1297
|
|
25
26
|
ocf_data_sampler/numpy_sample/satellite.py,sha256=8OaTvkPjzSjotcdKsa6BKmmlBKDBunbhDN4Pjo0Grxs,910
|
|
@@ -36,9 +37,9 @@ ocf_data_sampler/select/select_time_slice.py,sha256=D5P_cSvnv8Qs49K5au7lPxDr9U_V
|
|
|
36
37
|
ocf_data_sampler/select/spatial_slice_for_dataset.py,sha256=3tRrMBXr7s4CnClbVSIq7hpls3H4Y3qYTDwswcxCCCE,1763
|
|
37
38
|
ocf_data_sampler/select/time_slice_for_dataset.py,sha256=LMw8KnOCKnPjD0m4UubAWERpaiQtzRKkI2cSh5a0A-M,4335
|
|
38
39
|
ocf_data_sampler/torch_datasets/__init__.py,sha256=nJUa2KzVa84ZoM0PT2AbDz26ennmAYc7M7WJVfypPMs,85
|
|
39
|
-
ocf_data_sampler/torch_datasets/process_and_combine.py,sha256=
|
|
40
|
+
ocf_data_sampler/torch_datasets/process_and_combine.py,sha256=BaZZwGUKQf--X-3cNHcxZRn6iTNXg-sZyaYeRzQ7V68,4306
|
|
40
41
|
ocf_data_sampler/torch_datasets/pvnet_uk_regional.py,sha256=QRFqbdfNchVWj4y70n-rJdFvFGvQj-WpZLdFqWjnOTw,5543
|
|
41
|
-
ocf_data_sampler/torch_datasets/site.py,sha256=
|
|
42
|
+
ocf_data_sampler/torch_datasets/site.py,sha256=bBqKQt0lhk90-d1ZkBCeHHEIAFCnoQbRs2AQYyulW40,15381
|
|
42
43
|
ocf_data_sampler/torch_datasets/valid_time_periods.py,sha256=Qo65qUHtle_bW5tLTYr7empHTRv-lpjvfx_6GNJj3Xg,4371
|
|
43
44
|
scripts/refactor_site.py,sha256=asZ27hQ4IyXgCCUaFJqcz1ObBNcV2W3ywqHBpSXA_fc,1728
|
|
44
45
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -50,6 +51,7 @@ tests/load/test_load_nwp.py,sha256=3qyyDkB1q9t3tyAwogfotNrxqUOpXXimco1CImoEWGg,7
|
|
|
50
51
|
tests/load/test_load_satellite.py,sha256=STX5AqqmOAgUgE9R1xyq_sM3P1b8NKdGjO-hDhayfxM,524
|
|
51
52
|
tests/load/test_load_sites.py,sha256=T9lSEnGPI8FQISudVYHHNTHeplNS62Vrx48jaZ6J_Jo,364
|
|
52
53
|
tests/numpy_sample/test_collate.py,sha256=oWVNRR0LyF0iqaxjsq6hPMmkSGIyvGVlAM6q2rqvXqQ,840
|
|
54
|
+
tests/numpy_sample/test_datetime_features.py,sha256=o4t3KeKFdGrOBQ77rNFcDuDMQSD23ileCS5T5AP3wG4,1769
|
|
53
55
|
tests/numpy_sample/test_gsp.py,sha256=FLlq4SlJ-9cSRAepf4_ksA6PsUVKegnKEAc5pUojCJ0,1458
|
|
54
56
|
tests/numpy_sample/test_nwp.py,sha256=yf4u7mAU0E3FQ4xAH6YjuHuHBzzFoXjHSFNkOVJUdSM,1455
|
|
55
57
|
tests/numpy_sample/test_satellite.py,sha256=cCqtn5See-uSNfh89COGTUQNuFm6sIZ8QmBVHsuUeRI,1189
|
|
@@ -63,9 +65,9 @@ tests/select/test_select_time_slice.py,sha256=K1EJR5TwZa9dJf_YTEHxGtvs398iy1xS2l
|
|
|
63
65
|
tests/torch_datasets/conftest.py,sha256=eRCzHE7cxS4AoskExkCGFDBeqItktAYNAdkfpMoFCeE,629
|
|
64
66
|
tests/torch_datasets/test_process_and_combine.py,sha256=mbjQdqzLhox-U2sc1Ec68xLz95b3XOyPa7WchgxUM88,4256
|
|
65
67
|
tests/torch_datasets/test_pvnet_uk_regional.py,sha256=dLY861PMyQ_buTksP8d0UXzfKsZ_CFNgceSYVGXRIRs,2134
|
|
66
|
-
tests/torch_datasets/test_site.py,sha256=
|
|
67
|
-
ocf_data_sampler-0.0.
|
|
68
|
-
ocf_data_sampler-0.0.
|
|
69
|
-
ocf_data_sampler-0.0.
|
|
70
|
-
ocf_data_sampler-0.0.
|
|
71
|
-
ocf_data_sampler-0.0.
|
|
68
|
+
tests/torch_datasets/test_site.py,sha256=PGsGgg4jCDasxBg09hW9DA6rOGf60ECIh5YnBWyyzDE,4675
|
|
69
|
+
ocf_data_sampler-0.0.45.dist-info/LICENSE,sha256=F-Q3UFCR-BECSocV55BFDpn4YKxve9PKrm-lTt6o_Tg,1073
|
|
70
|
+
ocf_data_sampler-0.0.45.dist-info/METADATA,sha256=5QNcC3hPXLfehwBcxUVlidlPwSlMEoQWp5ln9JE_mzQ,11788
|
|
71
|
+
ocf_data_sampler-0.0.45.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
72
|
+
ocf_data_sampler-0.0.45.dist-info/top_level.txt,sha256=Faob6N6cFdPc5eUpCTYcXgCaNhi4XLLteUL5W5ayYmg,31
|
|
73
|
+
ocf_data_sampler-0.0.45.dist-info/RECORD,,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from ocf_data_sampler.numpy_sample.datetime_features import make_datetime_numpy_dict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_calculate_azimuth_and_elevation():
|
|
9
|
+
|
|
10
|
+
# Pick the day of the summer solstice
|
|
11
|
+
datetimes = pd.to_datetime(["2024-06-20 12:00", "2024-06-20 12:30", "2024-06-20 13:00"])
|
|
12
|
+
|
|
13
|
+
# Calculate sun angles
|
|
14
|
+
datetime_features = make_datetime_numpy_dict(datetimes)
|
|
15
|
+
|
|
16
|
+
assert len(datetime_features) == 4
|
|
17
|
+
|
|
18
|
+
assert len(datetime_features["wind_date_sin"]) == len(datetimes)
|
|
19
|
+
assert (datetime_features["wind_date_cos"] != datetime_features["wind_date_sin"]).all()
|
|
20
|
+
|
|
21
|
+
# assert all values are between -1 and 1
|
|
22
|
+
assert all(np.abs(datetime_features["wind_date_sin"]) <= 1)
|
|
23
|
+
assert all(np.abs(datetime_features["wind_date_cos"]) <= 1)
|
|
24
|
+
assert all(np.abs(datetime_features["wind_time_sin"]) <= 1)
|
|
25
|
+
assert all(np.abs(datetime_features["wind_time_cos"]) <= 1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_make_datetime_numpy_batch_custom_key_prefix():
|
|
29
|
+
# Test function correctly applies custom prefix to dict keys
|
|
30
|
+
datetimes = pd.to_datetime(["2024-06-20 12:00", "2024-06-20 12:30", "2024-06-20 13:00"])
|
|
31
|
+
key_prefix = "solar"
|
|
32
|
+
|
|
33
|
+
datetime_features = make_datetime_numpy_dict(datetimes, key_prefix=key_prefix)
|
|
34
|
+
|
|
35
|
+
# Assert dict contains expected quantity of keys and verify starting with custom prefix
|
|
36
|
+
assert len(datetime_features) == 4
|
|
37
|
+
assert all(key.startswith(key_prefix) for key in datetime_features.keys())
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_make_datetime_numpy_batch_empty_input():
|
|
41
|
+
# Verification that function raises error for empty input
|
|
42
|
+
datetimes = pd.DatetimeIndex([])
|
|
43
|
+
|
|
44
|
+
with pytest.raises(
|
|
45
|
+
ValueError, match="Input datetimes is empty for 'make_datetime_numpy_dict' function"
|
|
46
|
+
):
|
|
47
|
+
make_datetime_numpy_dict(datetimes)
|
|
@@ -22,7 +22,9 @@ def test_site(site_config_filename):
|
|
|
22
22
|
# Expected dimensions and data variables
|
|
23
23
|
expected_dims = {'satellite__x_geostationary', 'site__time_utc', 'nwp-ukv__target_time_utc',
|
|
24
24
|
'nwp-ukv__x_osgb', 'satellite__channel', 'satellite__y_geostationary',
|
|
25
|
-
'satellite__time_utc', 'nwp-ukv__channel', 'nwp-ukv__y_osgb'
|
|
25
|
+
'satellite__time_utc', 'nwp-ukv__channel', 'nwp-ukv__y_osgb', 'site_solar_azimuth',
|
|
26
|
+
'site_solar_elevation', 'site_date_cos', 'site_time_cos', 'site_time_sin', 'site_date_sin'}
|
|
27
|
+
|
|
26
28
|
expected_data_vars = {"nwp-ukv", "satellite", "site"}
|
|
27
29
|
|
|
28
30
|
# Check dimensions
|
|
File without changes
|
|
File without changes
|
|
File without changes
|