ocf-data-sampler 0.0.44__tar.gz → 0.0.45__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.

Potentially problematic release.


This version of ocf-data-sampler might be problematic. Click here for more details.

Files changed (79) hide show
  1. {ocf_data_sampler-0.0.44/ocf_data_sampler.egg-info → ocf_data_sampler-0.0.45}/PKG-INFO +3 -2
  2. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/README.md +2 -1
  3. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/__init__.py +1 -0
  4. ocf_data_sampler-0.0.45/ocf_data_sampler/numpy_sample/datetime_features.py +46 -0
  5. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/torch_datasets/process_and_combine.py +1 -0
  6. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/torch_datasets/site.py +21 -3
  7. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45/ocf_data_sampler.egg-info}/PKG-INFO +3 -2
  8. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler.egg-info/SOURCES.txt +2 -0
  9. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/pyproject.toml +1 -1
  10. ocf_data_sampler-0.0.45/tests/numpy_sample/test_datetime_features.py +47 -0
  11. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/torch_datasets/test_site.py +3 -1
  12. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/LICENSE +0 -0
  13. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/MANIFEST.in +0 -0
  14. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/__init__.py +0 -0
  15. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/config/__init__.py +0 -0
  16. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/config/load.py +0 -0
  17. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/config/model.py +0 -0
  18. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/config/save.py +0 -0
  19. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/constants.py +0 -0
  20. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/data/uk_gsp_locations.csv +0 -0
  21. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/__init__.py +0 -0
  22. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/gsp.py +0 -0
  23. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/load_dataset.py +0 -0
  24. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/__init__.py +0 -0
  25. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/nwp.py +0 -0
  26. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/providers/__init__.py +0 -0
  27. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/providers/ecmwf.py +0 -0
  28. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/providers/ukv.py +0 -0
  29. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/nwp/providers/utils.py +0 -0
  30. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/satellite.py +0 -0
  31. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/site.py +0 -0
  32. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/load/utils.py +0 -0
  33. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/collate.py +0 -0
  34. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/gsp.py +0 -0
  35. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/nwp.py +0 -0
  36. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/satellite.py +0 -0
  37. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/site.py +0 -0
  38. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/numpy_sample/sun_position.py +0 -0
  39. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/__init__.py +0 -0
  40. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/dropout.py +0 -0
  41. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/fill_time_periods.py +0 -0
  42. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/find_contiguous_time_periods.py +0 -0
  43. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/geospatial.py +0 -0
  44. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/location.py +0 -0
  45. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/select_spatial_slice.py +0 -0
  46. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/select_time_slice.py +0 -0
  47. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/spatial_slice_for_dataset.py +0 -0
  48. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/select/time_slice_for_dataset.py +0 -0
  49. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/torch_datasets/__init__.py +0 -0
  50. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/torch_datasets/pvnet_uk_regional.py +0 -0
  51. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/torch_datasets/valid_time_periods.py +0 -0
  52. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler/utils.py +0 -0
  53. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler.egg-info/dependency_links.txt +0 -0
  54. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler.egg-info/requires.txt +0 -0
  55. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/ocf_data_sampler.egg-info/top_level.txt +0 -0
  56. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/scripts/refactor_site.py +0 -0
  57. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/setup.cfg +0 -0
  58. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/__init__.py +0 -0
  59. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/config/test_config.py +0 -0
  60. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/config/test_save.py +0 -0
  61. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/conftest.py +0 -0
  62. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/load/test_load_gsp.py +0 -0
  63. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/load/test_load_nwp.py +0 -0
  64. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/load/test_load_satellite.py +0 -0
  65. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/load/test_load_sites.py +0 -0
  66. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/numpy_sample/test_collate.py +0 -0
  67. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/numpy_sample/test_gsp.py +0 -0
  68. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/numpy_sample/test_nwp.py +0 -0
  69. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/numpy_sample/test_satellite.py +0 -0
  70. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/numpy_sample/test_sun_position.py +0 -0
  71. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_dropout.py +0 -0
  72. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_fill_time_periods.py +0 -0
  73. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_find_contiguous_time_periods.py +0 -0
  74. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_location.py +0 -0
  75. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_select_spatial_slice.py +0 -0
  76. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/select/test_select_time_slice.py +0 -0
  77. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/torch_datasets/conftest.py +0 -0
  78. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/torch_datasets/test_process_and_combine.py +0 -0
  79. {ocf_data_sampler-0.0.44 → ocf_data_sampler-0.0.45}/tests/torch_datasets/test_pvnet_uk_regional.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ocf_data_sampler
3
- Version: 0.0.44
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
- [![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-)
59
+ [![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-)
60
60
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
61
61
 
62
62
  [![tags badge](https://img.shields.io/github/v/tag/openclimatefix/ocf-data-sampler?include_prereleases&sort=semver&color=FFAC5F)](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>
@@ -1,7 +1,7 @@
1
1
  # ocf-data-sampler
2
2
 
3
3
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4
- [![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-)
4
+ [![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-)
5
5
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
6
6
 
7
7
  [![tags badge](https://img.shields.io/github/v/tag/openclimatefix/ocf-data-sampler?include_prereleases&sort=semver&color=FFAC5F)](https://github.com/openclimatefix/ocf-data-sampler/tags)
@@ -80,6 +80,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
80
80
  <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>
81
81
  <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>
82
82
  <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>
83
+ <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>
83
84
  </tr>
84
85
  </tbody>
85
86
  </table>
@@ -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
- # TODO add solar + time features for sites
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.44
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
- [![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-)
59
+ [![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-)
60
60
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
61
61
 
62
62
  [![tags badge](https://img.shields.io/github/v/tag/openclimatefix/ocf-data-sampler?include_prereleases&sort=semver&color=FFAC5F)](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>
@@ -29,6 +29,7 @@ ocf_data_sampler/load/nwp/providers/ukv.py
29
29
  ocf_data_sampler/load/nwp/providers/utils.py
30
30
  ocf_data_sampler/numpy_sample/__init__.py
31
31
  ocf_data_sampler/numpy_sample/collate.py
32
+ ocf_data_sampler/numpy_sample/datetime_features.py
32
33
  ocf_data_sampler/numpy_sample/gsp.py
33
34
  ocf_data_sampler/numpy_sample/nwp.py
34
35
  ocf_data_sampler/numpy_sample/satellite.py
@@ -59,6 +60,7 @@ tests/load/test_load_nwp.py
59
60
  tests/load/test_load_satellite.py
60
61
  tests/load/test_load_sites.py
61
62
  tests/numpy_sample/test_collate.py
63
+ tests/numpy_sample/test_datetime_features.py
62
64
  tests/numpy_sample/test_gsp.py
63
65
  tests/numpy_sample/test_nwp.py
64
66
  tests/numpy_sample/test_satellite.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ocf_data_sampler"
7
- version = "0.0.44"
7
+ version = "0.0.45"
8
8
  license = { file = "LICENSE" }
9
9
  readme = "README.md"
10
10
  description = "Sample from weather data for renewable energy prediction"
@@ -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