ocf-data-sampler 0.0.18__py3-none-any.whl → 0.0.21__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.

Files changed (32) hide show
  1. ocf_data_sampler/config/__init__.py +5 -0
  2. ocf_data_sampler/config/load.py +33 -0
  3. ocf_data_sampler/config/model.py +249 -0
  4. ocf_data_sampler/config/save.py +36 -0
  5. ocf_data_sampler/select/dropout.py +2 -2
  6. ocf_data_sampler/select/geospatial.py +118 -0
  7. ocf_data_sampler/select/location.py +62 -0
  8. ocf_data_sampler/select/select_spatial_slice.py +5 -14
  9. ocf_data_sampler/torch_datasets/pvnet_uk_regional.py +10 -5
  10. ocf_data_sampler-0.0.21.dist-info/METADATA +83 -0
  11. ocf_data_sampler-0.0.21.dist-info/RECORD +53 -0
  12. {ocf_data_sampler-0.0.18.dist-info → ocf_data_sampler-0.0.21.dist-info}/WHEEL +1 -1
  13. tests/config/test_config.py +152 -0
  14. tests/conftest.py +6 -1
  15. tests/load/test_load_gsp.py +15 -0
  16. tests/load/test_load_nwp.py +21 -0
  17. tests/load/test_load_satellite.py +17 -0
  18. tests/numpy_batch/test_gsp.py +23 -0
  19. tests/numpy_batch/test_nwp.py +54 -0
  20. tests/numpy_batch/test_satellite.py +42 -0
  21. tests/numpy_batch/test_sun_position.py +81 -0
  22. tests/select/test_dropout.py +75 -0
  23. tests/select/test_fill_time_periods.py +28 -0
  24. tests/select/test_find_contiguous_time_periods.py +202 -0
  25. tests/select/test_location.py +67 -0
  26. tests/select/test_select_spatial_slice.py +154 -0
  27. tests/select/test_select_time_slice.py +284 -0
  28. tests/torch_datasets/test_pvnet_uk_regional.py +72 -0
  29. ocf_data_sampler-0.0.18.dist-info/METADATA +0 -22
  30. ocf_data_sampler-0.0.18.dist-info/RECORD +0 -32
  31. {ocf_data_sampler-0.0.18.dist-info → ocf_data_sampler-0.0.21.dist-info}/LICENSE +0 -0
  32. {ocf_data_sampler-0.0.18.dist-info → ocf_data_sampler-0.0.21.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,284 @@
1
+ from ocf_data_sampler.select.select_time_slice import select_time_slice, select_time_slice_nwp
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ import xarray as xr
6
+ import pytest
7
+
8
+
9
+ NWP_FREQ = pd.Timedelta("3H")
10
+
11
+ @pytest.fixture(scope="module")
12
+ def da_sat_like():
13
+ """Create dummy data which looks like satellite data"""
14
+ x = np.arange(-100, 100)
15
+ y = np.arange(-100, 100)
16
+ datetimes = pd.date_range("2024-01-02 00:00", "2024-01-03 00:00", freq="5min")
17
+
18
+ da_sat = xr.DataArray(
19
+ np.random.normal(size=(len(datetimes), len(x), len(y))),
20
+ coords=dict(
21
+ time_utc=(["time_utc"], datetimes),
22
+ x_geostationary=(["x_geostationary"], x),
23
+ y_geostationary=(["y_geostationary"], y),
24
+ )
25
+ )
26
+ return da_sat
27
+
28
+
29
+ @pytest.fixture(scope="module")
30
+ def da_nwp_like():
31
+ """Create dummy data which looks like NWP data"""
32
+
33
+ x = np.arange(-100, 100)
34
+ y = np.arange(-100, 100)
35
+ datetimes = pd.date_range("2024-01-02 00:00", "2024-01-03 00:00", freq=NWP_FREQ)
36
+ steps = pd.timedelta_range("0H", "16H", freq="1H")
37
+ channels = ["t", "dswrf"]
38
+
39
+ da_nwp = xr.DataArray(
40
+ np.random.normal(size=(len(datetimes), len(steps), len(channels), len(x), len(y))),
41
+ coords=dict(
42
+ init_time_utc=(["init_time_utc"], datetimes),
43
+ step=(["step"], steps),
44
+ channel=(["channel"], channels),
45
+ x_osgb=(["x_osgb"], x),
46
+ y_osgb=(["y_osgb"], y),
47
+ )
48
+ )
49
+ return da_nwp
50
+
51
+
52
+ @pytest.mark.parametrize("t0_str", ["12:30", "12:40", "12:00"])
53
+ def test_select_time_slice(da_sat_like, t0_str):
54
+ """Test the basic functionality of select_time_slice"""
55
+
56
+ # Slice parameters
57
+ t0 = pd.Timestamp(f"2024-01-02 {t0_str}")
58
+ forecast_duration = pd.Timedelta("0min")
59
+ history_duration = pd.Timedelta("60min")
60
+ freq = pd.Timedelta("5min")
61
+
62
+ # Expect to return these timestamps from the selection
63
+ expected_datetimes = pd.date_range(t0 - history_duration, t0 + forecast_duration, freq=freq)
64
+
65
+ # Make the selection using the `[x]_duration` parameters
66
+ sat_sample = select_time_slice(
67
+ ds=da_sat_like,
68
+ t0=t0,
69
+ history_duration=history_duration,
70
+ forecast_duration=forecast_duration,
71
+ sample_period_duration=freq,
72
+ )
73
+
74
+ # Check the returned times are as expected
75
+ assert (sat_sample.time_utc == expected_datetimes).all()
76
+
77
+ # Make the selection using the `interval_[x]` parameters
78
+ sat_sample = select_time_slice(
79
+ ds=da_sat_like,
80
+ t0=t0,
81
+ interval_start=-history_duration,
82
+ interval_end=forecast_duration,
83
+ sample_period_duration=freq,
84
+ )
85
+
86
+ # Check the returned times are as expected
87
+ assert (sat_sample.time_utc == expected_datetimes).all()
88
+
89
+
90
+ @pytest.mark.parametrize("t0_str", ["00:00", "00:25", "11:00", "11:55"])
91
+ def test_select_time_slice_out_of_bounds(da_sat_like, t0_str):
92
+ """Test the behaviour of select_time_slice when the selection is out of bounds"""
93
+
94
+ # Slice parameters
95
+ t0 = pd.Timestamp(f"2024-01-02 {t0_str}")
96
+ forecast_duration = pd.Timedelta("30min")
97
+ history_duration = pd.Timedelta("60min")
98
+ freq = pd.Timedelta("5min")
99
+
100
+ # The data is available between these times
101
+ min_time = da_sat_like.time_utc.min()
102
+ max_time = da_sat_like.time_utc.max()
103
+
104
+ # Expect to return these timestamps from the selection
105
+ expected_datetimes = pd.date_range(t0 - history_duration, t0 + forecast_duration, freq=freq)
106
+
107
+ # Make the partially out of bounds selection
108
+ sat_sample = select_time_slice(
109
+ ds=da_sat_like,
110
+ t0=t0,
111
+ history_duration=history_duration,
112
+ forecast_duration=forecast_duration,
113
+ sample_period_duration=freq,
114
+ fill_selection=True
115
+ )
116
+
117
+ # Check the returned times are as expected
118
+ assert (sat_sample.time_utc == expected_datetimes).all()
119
+
120
+
121
+ # Check all the values before the first timestamp available in the data are NaN
122
+ all_nan_space = sat_sample.isnull().all(dim=("x_geostationary", "y_geostationary"))
123
+ if expected_datetimes[0] < min_time:
124
+ assert all_nan_space.sel(time_utc=slice(None, min_time-freq)).all(dim="time_utc")
125
+
126
+ # Check all the values before the first timestamp available in the data are NaN
127
+ if expected_datetimes[-1] > max_time:
128
+ assert all_nan_space.sel(time_utc=slice(max_time+freq, None)).all(dim="time_utc")
129
+
130
+ # Check that none of the values between the first and last available timestamp are NaN
131
+ any_nan_space = sat_sample.isnull().any(dim=("x_geostationary", "y_geostationary"))
132
+ assert not any_nan_space.sel(time_utc=slice(min_time, max_time)).any(dim="time_utc")
133
+
134
+
135
+ @pytest.mark.parametrize("t0_str", ["10:00", "11:00", "12:00"])
136
+ def test_select_time_slice_nwp_basic(da_nwp_like, t0_str):
137
+ """Test the basic functionality of select_time_slice_nwp"""
138
+
139
+ # Slice parameters
140
+ t0 = pd.Timestamp(f"2024-01-02 {t0_str}")
141
+ forecast_duration = pd.Timedelta("6H")
142
+ history_duration = pd.Timedelta("3H")
143
+ freq = pd.Timedelta("1H")
144
+
145
+ # Make the selection
146
+ da_slice = select_time_slice_nwp(
147
+ da_nwp_like,
148
+ t0,
149
+ sample_period_duration=freq,
150
+ history_duration=history_duration,
151
+ forecast_duration=forecast_duration,
152
+ dropout_timedeltas = None,
153
+ dropout_frac = 0,
154
+ accum_channels = [],
155
+ channel_dim_name = "channel",
156
+ )
157
+
158
+ # Check the target-times are as expected
159
+ expected_target_times = pd.date_range(t0 - history_duration, t0 + forecast_duration, freq=freq)
160
+ assert (da_slice.target_time_utc==expected_target_times).all()
161
+
162
+ # Check the init-times are as expected
163
+ # - Forecast frequency is `NWP_FREQ`, and we can't have selected future init-times
164
+ expected_init_times = pd.to_datetime(
165
+ [t if t<t0 else t0 for t in expected_target_times]
166
+ ).floor(NWP_FREQ)
167
+ assert (da_slice.init_time_utc==expected_init_times).all()
168
+
169
+
170
+ @pytest.mark.parametrize("dropout_hours", [1, 2, 5])
171
+ def test_select_time_slice_nwp_with_dropout(da_nwp_like, dropout_hours):
172
+ """Test the functionality of select_time_slice_nwp with dropout"""
173
+
174
+ t0 = pd.Timestamp("2024-01-02 12:00")
175
+ forecast_duration = pd.Timedelta("6H")
176
+ history_duration = pd.Timedelta("3H")
177
+ freq = pd.Timedelta("1H")
178
+ dropout_timedelta = pd.Timedelta(f"-{dropout_hours}H")
179
+
180
+ da_slice = select_time_slice_nwp(
181
+ da_nwp_like,
182
+ t0,
183
+ sample_period_duration=freq,
184
+ history_duration=history_duration,
185
+ forecast_duration=forecast_duration,
186
+ dropout_timedeltas = [dropout_timedelta],
187
+ dropout_frac = 1,
188
+ accum_channels = [],
189
+ channel_dim_name = "channel",
190
+ )
191
+
192
+ # Check the target-times are as expected
193
+ expected_target_times = pd.date_range(t0 - history_duration, t0 + forecast_duration, freq=freq)
194
+ assert (da_slice.target_time_utc==expected_target_times).all()
195
+
196
+ # Check the init-times are as expected considering the delay
197
+ t0_delayed = t0 + dropout_timedelta
198
+ expected_init_times = pd.to_datetime(
199
+ [t if t<t0_delayed else t0_delayed for t in expected_target_times]
200
+ ).floor(NWP_FREQ)
201
+ assert (da_slice.init_time_utc==expected_init_times).all()
202
+
203
+
204
+ @pytest.mark.parametrize("t0_str", ["10:00", "11:00", "12:00"])
205
+ def test_select_time_slice_nwp_with_dropout_and_accum(da_nwp_like, t0_str):
206
+ """Test the functionality of select_time_slice_nwp with dropout and accumulated variables"""
207
+
208
+ # Slice parameters
209
+ t0 = pd.Timestamp(f"2024-01-02 {t0_str}")
210
+ forecast_duration = pd.Timedelta("6H")
211
+ history_duration = pd.Timedelta("3H")
212
+ freq = pd.Timedelta("1H")
213
+ dropout_timedelta = pd.Timedelta("-2H")
214
+
215
+ t0_delayed = (t0 + dropout_timedelta).floor(NWP_FREQ)
216
+
217
+ da_slice = select_time_slice_nwp(
218
+ da_nwp_like,
219
+ t0,
220
+ sample_period_duration=freq,
221
+ history_duration=history_duration,
222
+ forecast_duration=forecast_duration,
223
+ dropout_timedeltas=[dropout_timedelta],
224
+ dropout_frac=1,
225
+ accum_channels=["dswrf"],
226
+ channel_dim_name="channel",
227
+ )
228
+
229
+ # Check the target-times are as expected
230
+ expected_target_times = pd.date_range(t0 - history_duration, t0 + forecast_duration, freq=freq)
231
+ assert (da_slice.target_time_utc==expected_target_times).all()
232
+
233
+ # Check the init-times are as expected considering the delay
234
+ expected_init_times = pd.to_datetime(
235
+ [t if t<t0_delayed else t0_delayed for t in expected_target_times]
236
+ ).floor(NWP_FREQ)
237
+ assert (da_slice.init_time_utc==expected_init_times).all()
238
+
239
+ # Check channels are as expected
240
+ assert (da_slice.channel.values == ["t", "diff_dswrf"]).all()
241
+
242
+ # Check the accummulated channel has been differenced correctly
243
+
244
+ # This part of the data is pulled from the init-time: t0_delayed
245
+ da_slice_accum = da_slice.sel(
246
+ target_time_utc=slice(t0_delayed, None),
247
+ channel="diff_dswrf"
248
+ )
249
+
250
+ # Get the original data for the t0_delayed init-time, and diff it along steps
251
+ # then select the steps which are expected to be used in the above slice
252
+ da_orig_diffed = (
253
+ da_nwp_like.sel(
254
+ init_time_utc=t0_delayed,
255
+ channel="dswrf",
256
+ ).diff(dim="step", label="lower")
257
+ .sel(step=slice(t0-t0_delayed - history_duration, t0-t0_delayed + forecast_duration))
258
+ )
259
+
260
+ # Check the values are the same
261
+ assert (da_slice_accum.values == da_orig_diffed.values).all()
262
+
263
+ # Check the non-accummulated channel has not been differenced
264
+
265
+ # This part of the data is pulled from the init-time: t0_delayed
266
+ da_slice_nonaccum = da_slice.sel(
267
+ target_time_utc=slice(t0_delayed, None),
268
+ channel="t"
269
+ )
270
+
271
+ # Get the original data for the t0_delayed init-time, and select the steps which are expected
272
+ # to be used in the above slice
273
+ da_orig = (
274
+ da_nwp_like.sel(
275
+ init_time_utc=t0_delayed,
276
+ channel="t",
277
+ )
278
+ .sel(step=slice(t0-t0_delayed - history_duration, t0-t0_delayed + forecast_duration))
279
+ )
280
+
281
+ # Check the values are the same
282
+ assert (da_slice_nonaccum.values == da_orig.values).all()
283
+
284
+
@@ -0,0 +1,72 @@
1
+ import pytest
2
+ import tempfile
3
+
4
+ from ocf_data_sampler.torch_datasets.pvnet_uk_regional import PVNetUKRegionalDataset
5
+ from ocf_data_sampler.config import load_yaml_configuration, save_yaml_configuration
6
+ from ocf_datapipes.batch import BatchKey, NWPBatchKey
7
+
8
+
9
+ @pytest.fixture()
10
+ def pvnet_config_filename(tmp_path, config_filename, nwp_ukv_zarr_path, uk_gsp_zarr_path, sat_zarr_path):
11
+
12
+ # adjust config to point to the zarr file
13
+ config = load_yaml_configuration(config_filename)
14
+ config.input_data.nwp['ukv'].nwp_zarr_path = nwp_ukv_zarr_path
15
+ config.input_data.satellite.satellite_zarr_path = sat_zarr_path
16
+ config.input_data.gsp.gsp_zarr_path = uk_gsp_zarr_path
17
+
18
+ filename = f"{tmp_path}/configuration.yaml"
19
+ save_yaml_configuration(config, filename)
20
+ return filename
21
+
22
+
23
+ def test_pvnet(pvnet_config_filename):
24
+
25
+ # Create dataset object
26
+ dataset = PVNetUKRegionalDataset(pvnet_config_filename)
27
+
28
+ assert len(dataset.locations) == 317 # no of GSPs not including the National level
29
+ # NB. I have not checked this value is in fact correct, but it does seem to stay constant
30
+ assert len(dataset.valid_t0_times) == 39
31
+ assert len(dataset) == 317*39
32
+
33
+ # Generate a sample
34
+ sample = dataset[0]
35
+
36
+ assert isinstance(sample, dict)
37
+
38
+ for key in [
39
+ BatchKey.nwp, BatchKey.satellite_actual, BatchKey.gsp,
40
+ BatchKey.gsp_solar_azimuth, BatchKey.gsp_solar_elevation,
41
+ ]:
42
+ assert key in sample
43
+
44
+ for nwp_source in ["ukv"]:
45
+ assert nwp_source in sample[BatchKey.nwp]
46
+
47
+ # check the shape of the data is correct
48
+ # 30 minutes of 5 minute data (inclusive), one channel, 2x2 pixels
49
+ assert sample[BatchKey.satellite_actual].shape == (7, 1, 2, 2)
50
+ # 3 hours of 60 minute data (inclusive), one channel, 2x2 pixels
51
+ assert sample[BatchKey.nwp]["ukv"][NWPBatchKey.nwp].shape == (4, 1, 2, 2)
52
+ # 3 hours of 30 minute data (inclusive)
53
+ assert sample[BatchKey.gsp].shape == (7,)
54
+ # Solar angles have same shape as GSP data
55
+ assert sample[BatchKey.gsp_solar_azimuth].shape == (7,)
56
+ assert sample[BatchKey.gsp_solar_elevation].shape == (7,)
57
+
58
+ def test_pvnet_no_gsp(pvnet_config_filename):
59
+
60
+ # load config
61
+ config = load_yaml_configuration(pvnet_config_filename)
62
+ # remove gsp
63
+ config.input_data.gsp.gsp_zarr_path = ''
64
+
65
+ # save temp config file
66
+ with tempfile.NamedTemporaryFile() as temp_config_file:
67
+ save_yaml_configuration(config, temp_config_file.name)
68
+ # Create dataset object
69
+ dataset = PVNetUKRegionalDataset(temp_config_file.name)
70
+
71
+ # Generate a sample
72
+ _ = dataset[0]
@@ -1,22 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: ocf_data_sampler
3
- Version: 0.0.18
4
- Summary: Sample from weather data for renewable energy prediction
5
- Author: James Fulton, Peter Dudfield, and the Open Climate Fix team
6
- Author-email: info@openclimatefix.org
7
- License: MIT
8
- Description-Content-Type: text/markdown
9
- License-File: LICENSE
10
- Requires-Dist: numpy
11
- Requires-Dist: pandas
12
- Requires-Dist: xarray
13
- Requires-Dist: zarr
14
- Requires-Dist: dask
15
- Requires-Dist: ocf-blosc2
16
- Requires-Dist: ocf-datapipes ==3.3.39
17
- Requires-Dist: pvlib
18
-
19
- # OCF Data Sampler
20
- [![ease of contribution: easy](https://img.shields.io/badge/ease%20of%20contribution:%20easy-32bd50)](https://github.com/openclimatefix/ocf-meta-repo?tab=readme-ov-file#overview-of-ocfs-nowcasting-repositories)
21
-
22
- A repo for sampling from weather data for renewable energy prediction
@@ -1,32 +0,0 @@
1
- ocf_data_sampler/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
2
- ocf_data_sampler/data/uk_gsp_locations.csv,sha256=RSh7DRh55E3n8lVAaWXGTaXXHevZZtI58td4d4DhGos,10415772
3
- ocf_data_sampler/load/__init__.py,sha256=MjgfxilTzyz1RYFoBEeAXmE9hyjknLvdmlHPmlAoiQY,44
4
- ocf_data_sampler/load/gsp.py,sha256=Gcr1JVUOPKhFRDCSHtfPDjxx0BtyyEhXrZvGEKLPJ5I,759
5
- ocf_data_sampler/load/satellite.py,sha256=3KlA1fx4SwxdzM-jC1WRaONXO0D6m0WxORnEnwUnZrA,2967
6
- ocf_data_sampler/load/utils.py,sha256=EQGvVWlGMoSOdbDYuMfVAa0v6wmAOPmHIAemdrTB5v4,1406
7
- ocf_data_sampler/load/nwp/__init__.py,sha256=SmcrnbygO5xtCKmGR4wtHrj-HI7nOAvnAtfuvRufBGQ,25
8
- ocf_data_sampler/load/nwp/nwp.py,sha256=O4QnajEZem8BvBgTcYYDBhRhgqPYuJkolHmpMRmrXEA,610
9
- ocf_data_sampler/load/nwp/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- ocf_data_sampler/load/nwp/providers/ecmwf.py,sha256=vW-p3vCyQ-CofKo555-gE7VDi5hlpjtjTLfHqWF0HEE,1175
11
- ocf_data_sampler/load/nwp/providers/ukv.py,sha256=79Bm7q-K_GJPYMy62SUIZbRWRF4-tIaB1dYPEgLD9vo,1207
12
- ocf_data_sampler/load/nwp/providers/utils.py,sha256=Sy2exG1wpXLLhMXYdsfR-DZMR3txG1_bBmBdchlc-yA,848
13
- ocf_data_sampler/numpy_batch/__init__.py,sha256=mrtqwbGik5Zc9MYP5byfCTBm08wMtS2XnTsypC4fPMo,245
14
- ocf_data_sampler/numpy_batch/gsp.py,sha256=3gwSj0k29JyA8_09zovB8f8Pr-dVhCuMSO1-k4QKAOg,668
15
- ocf_data_sampler/numpy_batch/nwp.py,sha256=Rv0yfDj902Z2oCwdlRjOs3Kh-F5Fgxjjylh99-lQ9ws,1105
16
- ocf_data_sampler/numpy_batch/satellite.py,sha256=e6eoNmiiHtzZbDVtBolFzDuE3qwhHN6bL9H86emAUsk,732
17
- ocf_data_sampler/numpy_batch/sun_position.py,sha256=UW6-WtjrKdCkcguolHUDSLhYFfarknQzzjlCX8YdEOM,1700
18
- ocf_data_sampler/select/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
19
- ocf_data_sampler/select/dropout.py,sha256=3aDqlL3U9kzzIkIHV44h5_ZbfOUSg1iChHKingXk7-s,1064
20
- ocf_data_sampler/select/fill_time_periods.py,sha256=iTtMjIPFYG5xtUYYedAFBLjTWWUa7t7WQ0-yksWf0-E,440
21
- ocf_data_sampler/select/find_contiguous_time_periods.py,sha256=6ioB8LeFpFNBMgKDxrgG3zqzNjkBF_jlV9yye2ZYT2E,11925
22
- ocf_data_sampler/select/select_spatial_slice.py,sha256=7BSzOFPMSBWpBWXSajWTfI8luUVsSgh4zN-rkr-AuUs,11470
23
- ocf_data_sampler/select/select_time_slice.py,sha256=41cch1fQr59fZgv7UHsNGc3OvoynrixT3bmr3_1d7cU,6628
24
- ocf_data_sampler/torch_datasets/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
25
- ocf_data_sampler/torch_datasets/pvnet_uk_regional.py,sha256=W8AfmfkLywRjMJlPSJ6u3ZhB7ShwtiQuM4BZs5de_LA,18941
26
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- tests/conftest.py,sha256=OcArgF60paroZQqoP7xExRBF34nEyMuXd7dS7hD6p3w,5393
28
- ocf_data_sampler-0.0.18.dist-info/LICENSE,sha256=F-Q3UFCR-BECSocV55BFDpn4YKxve9PKrm-lTt6o_Tg,1073
29
- ocf_data_sampler-0.0.18.dist-info/METADATA,sha256=EJKObEAl-_R7a_1xgtXZQ-eXvg1Ljsgbl5QNG1mb1m4,801
30
- ocf_data_sampler-0.0.18.dist-info/WHEEL,sha256=5Mi1sN9lKoFv_gxcPtisEVrJZihrm_beibeg5R6xb4I,91
31
- ocf_data_sampler-0.0.18.dist-info/top_level.txt,sha256=KaQn5qzkJGJP6hKWqsVAc9t0cMLjVvSTk8-kTrW79SA,23
32
- ocf_data_sampler-0.0.18.dist-info/RECORD,,