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

@@ -90,11 +90,10 @@ class DropoutMixin(Base):
90
90
  "negative or zero.",
91
91
  )
92
92
 
93
- dropout_fraction: float = Field(
93
+ dropout_fraction: float|list[float] = Field(
94
94
  default=0,
95
- description="Chance of dropout being applied to each sample",
96
- ge=0,
97
- le=1,
95
+ description="Either a float(Chance of dropout being applied to each sample) or a list of "
96
+ "floats (probability that dropout of the corresponding timedelta is applied)",
98
97
  )
99
98
 
100
99
  @field_validator("dropout_timedeltas_minutes")
@@ -105,6 +104,36 @@ class DropoutMixin(Base):
105
104
  raise ValueError("Dropout timedeltas must be negative")
106
105
  return v
107
106
 
107
+
108
+ @field_validator("dropout_fraction")
109
+ def dropout_fractions(cls, dropout_frac: float|list[float]) -> float|list[float]:
110
+ """Validate 'dropout_frac'."""
111
+ from math import isclose
112
+ if isinstance(dropout_frac, float):
113
+ if not (dropout_frac <= 1):
114
+ raise ValueError("Input should be less than or equal to 1")
115
+ elif not (dropout_frac >= 0):
116
+ raise ValueError("Input should be greater than or equal to 0")
117
+
118
+ elif isinstance(dropout_frac, list):
119
+ if not dropout_frac:
120
+ raise ValueError("List cannot be empty")
121
+
122
+ if not all(isinstance(i, float) for i in dropout_frac):
123
+ raise ValueError("All elements in the list must be floats")
124
+
125
+ if not all(0 <= i <= 1 for i in dropout_frac):
126
+ raise ValueError("Each float in the list must be between 0 and 1")
127
+
128
+ if not isclose(sum(dropout_frac), 1.0, rel_tol=1e-9):
129
+ raise ValueError("Sum of all floats in the list must be 1.0")
130
+
131
+
132
+ else:
133
+ raise TypeError("Must be either a float or a list of floats")
134
+ return dropout_frac
135
+
136
+
108
137
  @model_validator(mode="after")
109
138
  def dropout_instructions_consistent(self) -> "DropoutMixin":
110
139
  """Validator for dropout instructions."""
@@ -1,6 +1,6 @@
1
1
  """Conversion from Xarray to NumpySample"""
2
2
 
3
- from .datetime_features import make_datetime_numpy_dict
3
+ from .datetime_features import encode_datetimes
4
4
  from .gsp import convert_gsp_to_numpy_sample, GSPSampleKey
5
5
  from .nwp import convert_nwp_to_numpy_sample, NWPSampleKey
6
6
  from .satellite import convert_satellite_to_numpy_sample, SatelliteSampleKey
@@ -6,33 +6,24 @@ import pandas as pd
6
6
  from ocf_data_sampler.numpy_sample.common_types import NumpySample
7
7
 
8
8
 
9
- def _get_date_time_in_pi(dt: pd.DatetimeIndex) -> tuple[np.ndarray, np.ndarray]:
10
- """Create positional embeddings for the datetimes in radians.
9
+ def encode_datetimes(datetimes: pd.DatetimeIndex) -> NumpySample:
10
+ """Creates dictionary of sin and cos datetime embeddings.
11
11
 
12
12
  Args:
13
- dt: DatetimeIndex to create radian embeddings for
13
+ datetimes: DatetimeIndex to create radian embeddings for
14
14
 
15
15
  Returns:
16
- Tuple of numpy arrays containing radian coordinates for date and time
16
+ Dictionary of datetime encodings
17
17
  """
18
- day_of_year = dt.dayofyear
19
- minute_of_day = dt.minute + dt.hour * 60
20
-
21
- time_in_pi = (2 * np.pi) * (minute_of_day / (24 * 60))
22
- date_in_pi = (2 * np.pi) * (day_of_year / 365)
23
-
24
- return date_in_pi, time_in_pi
25
-
26
-
27
- def make_datetime_numpy_dict(datetimes: pd.DatetimeIndex, key_prefix: str = "wind") -> NumpySample:
28
- """Creates dictionary of cyclical datetime features - encoded."""
29
- date_in_pi, time_in_pi = _get_date_time_in_pi(datetimes)
30
-
31
- time_numpy_sample = {}
32
-
33
- time_numpy_sample[key_prefix + "_date_sin"] = np.sin(date_in_pi)
34
- time_numpy_sample[key_prefix + "_date_cos"] = np.cos(date_in_pi)
35
- time_numpy_sample[key_prefix + "_time_sin"] = np.sin(time_in_pi)
36
- time_numpy_sample[key_prefix + "_time_cos"] = np.cos(time_in_pi)
37
-
38
- return time_numpy_sample
18
+ day_of_year = datetimes.dayofyear
19
+ minute_of_day = datetimes.minute + datetimes.hour * 60
20
+
21
+ time_in_radians = (2 * np.pi) * (minute_of_day / (24 * 60))
22
+ date_in_radians = (2 * np.pi) * (day_of_year / 365)
23
+
24
+ return {
25
+ "date_sin": np.sin(date_in_radians),
26
+ "date_cos": np.cos(date_in_radians),
27
+ "time_sin": np.sin(time_in_radians),
28
+ "time_cos": np.cos(time_in_radians),
29
+ }
@@ -13,10 +13,7 @@ class SiteSampleKey:
13
13
  time_utc = "site_time_utc"
14
14
  t0_idx = "site_t0_idx"
15
15
  id = "site_id"
16
- date_sin = "site_date_sin"
17
- date_cos = "site_date_cos"
18
- time_sin = "site_time_sin"
19
- time_cos = "site_time_cos"
16
+
20
17
 
21
18
 
22
19
  def convert_site_to_numpy_sample(da: xr.DataArray, t0_idx: int | None = None) -> NumpySample:
@@ -31,10 +28,6 @@ def convert_site_to_numpy_sample(da: xr.DataArray, t0_idx: int | None = None) ->
31
28
  SiteSampleKey.capacity_kwp: da.isel(time_utc=0)["capacity_kwp"].values,
32
29
  SiteSampleKey.time_utc: da["time_utc"].values.astype(float),
33
30
  SiteSampleKey.id: da["site_id"].values,
34
- SiteSampleKey.date_sin: da["date_sin"].values,
35
- SiteSampleKey.date_cos: da["date_cos"].values,
36
- SiteSampleKey.time_sin: da["time_sin"].values,
37
- SiteSampleKey.time_cos: da["time_cos"].values,
38
31
  }
39
32
 
40
33
  if t0_idx is not None:
@@ -12,7 +12,7 @@ import xarray as xr
12
12
  def apply_sampled_dropout_time(
13
13
  t0: pd.Timestamp,
14
14
  dropout_timedeltas: list[pd.Timedelta],
15
- dropout_frac: float,
15
+ dropout_frac: float|list[float],
16
16
  da: xr.DataArray,
17
17
  ) -> xr.DataArray:
18
18
  """Randomly pick a dropout time from a list of timedeltas and apply dropout time to the data.
@@ -20,28 +20,42 @@ def apply_sampled_dropout_time(
20
20
  Args:
21
21
  t0: The forecast init-time
22
22
  dropout_timedeltas: List of timedeltas relative to t0 to pick from
23
- dropout_frac: Probability that dropout will be applied.
24
- This should be between 0 and 1 inclusive
23
+ dropout_frac: Either a probability that dropout will be applied.
24
+ This should be between 0 and 1 inclusive.
25
+ Or a list of probabilities for each of the corresponding timedeltas
25
26
  da: Xarray DataArray with 'time_utc' coordinate
26
27
  """
27
- # sample dropout time
28
- if dropout_frac > 0 and len(dropout_timedeltas) == 0:
29
- raise ValueError("To apply dropout, dropout_timedeltas must be provided")
28
+ if isinstance(dropout_frac, list):
29
+ # checking if len match
30
+ if len(dropout_frac) != len(dropout_timedeltas):
31
+ raise ValueError("Lengths of dropout_frac and dropout_timedeltas should match")
30
32
 
31
- for t in dropout_timedeltas:
32
- if t > pd.Timedelta("0min"):
33
- raise ValueError("Dropout timedeltas must be negative")
34
33
 
35
- if not (0 <= dropout_frac <= 1):
36
- raise ValueError("dropout_frac must be between 0 and 1 inclusive")
37
34
 
38
- if (len(dropout_timedeltas) == 0) or (np.random.uniform() >= dropout_frac):
39
- dropout_time = None
35
+
36
+ dropout_time = t0 + np.random.choice(dropout_timedeltas,p=dropout_frac)
37
+
38
+ return da.where(da.time_utc <= dropout_time)
39
+
40
+
41
+
42
+ # old logic
40
43
  else:
41
- dropout_time = t0 + np.random.choice(dropout_timedeltas)
44
+ # sample dropout time
45
+ if dropout_frac > 0 and len(dropout_timedeltas) == 0:
46
+ raise ValueError("To apply dropout, dropout_timedeltas must be provided")
47
+
48
+
49
+ if not (0 <= dropout_frac <= 1):
50
+ raise ValueError("dropout_frac must be between 0 and 1 inclusive")
51
+
52
+ if (len(dropout_timedeltas) == 0) or (np.random.uniform() >= dropout_frac):
53
+ dropout_time = None
54
+ else:
55
+ dropout_time = t0 + np.random.choice(dropout_timedeltas)
42
56
 
43
- # apply dropout time
44
- if dropout_time is None:
45
- return da
46
- # This replaces the times after the dropout with NaNs
47
- return da.where(da.time_utc <= dropout_time)
57
+ # apply dropout time
58
+ if dropout_time is None:
59
+ return da
60
+ # This replaces the times after the dropout with NaNs
61
+ return da.where(da.time_utc <= dropout_time)
@@ -13,7 +13,7 @@ from ocf_data_sampler.numpy_sample import (
13
13
  convert_nwp_to_numpy_sample,
14
14
  convert_satellite_to_numpy_sample,
15
15
  convert_site_to_numpy_sample,
16
- make_datetime_numpy_dict,
16
+ encode_datetimes,
17
17
  make_sun_position_numpy_sample,
18
18
  )
19
19
  from ocf_data_sampler.numpy_sample.collate import stack_np_samples_into_batch
@@ -249,7 +249,7 @@ class SitesDataset(Dataset):
249
249
 
250
250
  # add datetime features
251
251
  datetimes = pd.DatetimeIndex(combined_sample_dataset.site__time_utc.values)
252
- datetime_features = make_datetime_numpy_dict(datetimes=datetimes, key_prefix="site_")
252
+ datetime_features = encode_datetimes(datetimes=datetimes)
253
253
  combined_sample_dataset = combined_sample_dataset.assign_coords(
254
254
  {k: ("site__time_utc", v) for k, v in datetime_features.items()},
255
255
  )
@@ -445,11 +445,7 @@ class SitesDatasetConcurrent(Dataset):
445
445
  da_sites = da_sites / da_sites.capacity_kwp
446
446
 
447
447
  # Convert to NumpyBatch
448
- numpy_modalities.append(
449
- convert_site_to_numpy_sample(
450
- da_sites,
451
- ),
452
- )
448
+ numpy_modalities.append(convert_site_to_numpy_sample(da_sites))
453
449
 
454
450
  # Only add solar position if explicitly configured
455
451
  has_solar_config = (
@@ -578,13 +574,11 @@ def convert_netcdf_to_numpy_sample(ds: xr.Dataset) -> dict:
578
574
  sample_dict["sat"] = sample_dict.pop("satellite")
579
575
 
580
576
  # process and combine the datasets
581
- sample = convert_to_numpy_and_combine(
582
- dataset_dict=sample_dict,
583
- )
577
+ sample = convert_to_numpy_and_combine(dataset_dict=sample_dict)
584
578
 
585
- # Extraction of solar position coords
586
- solar_keys = ["solar_azimuth", "solar_elevation"]
587
- for key in solar_keys:
579
+ # Add solar coord and datetime features
580
+ keys = ["solar_azimuth", "solar_elevation", "date_sin", "date_cos", "time_sin", "time_cos"]
581
+ for key in keys:
588
582
  if key in ds.coords:
589
583
  sample[key] = ds.coords[key].values
590
584
 
@@ -672,11 +666,7 @@ def convert_to_numpy_and_combine(dataset_dict: dict[xr.Dataset]) -> NumpySample:
672
666
  if "site" in dataset_dict:
673
667
  da_sites = dataset_dict["site"]
674
668
 
675
- numpy_modalities.append(
676
- convert_site_to_numpy_sample(
677
- da_sites,
678
- ),
679
- )
669
+ numpy_modalities.append(convert_site_to_numpy_sample(da_sites))
680
670
 
681
671
  # Combine all the modalities and fill NaNs
682
672
  combined_sample = merge_dicts(numpy_modalities)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ocf-data-sampler
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Author: James Fulton, Peter Dudfield
5
5
  Author-email: Open Climate Fix team <info@openclimatefix.org>
6
6
  License: MIT License
@@ -49,7 +49,7 @@ Requires-Dist: xarray-tensorstore==0.1.5
49
49
  # ocf-data-sampler
50
50
 
51
51
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
52
- [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-)
52
+ [![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-)
53
53
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
54
54
 
55
55
  [![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)
@@ -128,6 +128,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
128
128
  <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>
129
129
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Sachin-G13"><img src="https://avatars.githubusercontent.com/u/190184500?v=4?s=100" width="100px;" alt="Sachin-G13"/><br /><sub><b>Sachin-G13</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=Sachin-G13" title="Code">💻</a></td>
130
130
  <td align="center" valign="top" width="14.28%"><a href="https://drona-gyawali.github.io/"><img src="https://avatars.githubusercontent.com/u/170401554?v=4?s=100" width="100px;" alt="Dorna Raj Gyawali"/><br /><sub><b>Dorna Raj Gyawali</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=drona-gyawali" title="Code">💻</a></td>
131
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/adnanhashmi25"><img src="https://avatars.githubusercontent.com/u/55550094?v=4?s=100" width="100px;" alt="Adnan Hashmi"/><br /><sub><b>Adnan Hashmi</b></sub></a><br /><a href="https://github.com/openclimatefix/ocf-data-sampler/commits?author=adnanhashmi25" title="Code">💻</a></td>
131
132
  </tr>
132
133
  </tbody>
133
134
  </table>
@@ -2,7 +2,7 @@ ocf_data_sampler/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,
2
2
  ocf_data_sampler/utils.py,sha256=2NEl70ySdTpr0pbLRk4LGklvXe1Nv1hun9XKcDw7-44,610
3
3
  ocf_data_sampler/config/__init__.py,sha256=O29mbH0XG2gIY1g3BaveGCnpBO2SFqdu-qzJ7a6evl0,223
4
4
  ocf_data_sampler/config/load.py,sha256=LL-7wemI8o4KPkx35j-wQ3HjsMvDgqXr7G46IcASfnU,632
5
- ocf_data_sampler/config/model.py,sha256=xX2PPywEFGYDsx_j9DX1GlwMRq3ovJR-mhmysMt_mO0,11116
5
+ ocf_data_sampler/config/model.py,sha256=Jss8UDJAaQIBDr9megX2pERoT0ocFmwLNFC8pCWN6VA,12386
6
6
  ocf_data_sampler/config/save.py,sha256=m8SPw5rXjkMm1rByjh3pK5StdBi4e8ysnn3jQopdRaI,1064
7
7
  ocf_data_sampler/data/uk_gsp_locations_20220314.csv,sha256=RSh7DRh55E3n8lVAaWXGTaXXHevZZtI58td4d4DhGos,10415772
8
8
  ocf_data_sampler/data/uk_gsp_locations_20250109.csv,sha256=XZISFatnbpO9j8LwaxNKFzQSjs6hcHFsV8a9uDDpy2E,9055334
@@ -22,17 +22,17 @@ ocf_data_sampler/load/nwp/providers/gfs.py,sha256=h6vm-Rfz1JGOE4P_fP1_XQJ3bugNbe
22
22
  ocf_data_sampler/load/nwp/providers/icon.py,sha256=iVZwLKRr_D74_kAu5MHir6pRKEfbTmIxFRZAxzmiYdI,1257
23
23
  ocf_data_sampler/load/nwp/providers/ukv.py,sha256=2i32VM9gnmWUpbL0qBSp_AKzuyKucXZPS8yklbcGlbc,1039
24
24
  ocf_data_sampler/load/nwp/providers/utils.py,sha256=cVwCiC8FqNpkZFSUGv1CRqIQlKdjx1sIsb2SIUlvWV8,2333
25
- ocf_data_sampler/numpy_sample/__init__.py,sha256=nY5C6CcuxiWZ_jrXRzWtN7WyKXhJImSiVTIG6Rz4B_4,401
25
+ ocf_data_sampler/numpy_sample/__init__.py,sha256=eeIVC3NcLl6vVN2rgI-oY-LxwMAZYDLMUU9kzrVy1Io,393
26
26
  ocf_data_sampler/numpy_sample/collate.py,sha256=hoxIc5SoHoIs3Nx37aRZzWChpswjy9lHUgaKgHIoo80,2039
27
27
  ocf_data_sampler/numpy_sample/common_types.py,sha256=9CjYHkUTx0ObduWh43fhsybZCTXvexql7qC2ptMDoek,377
28
- ocf_data_sampler/numpy_sample/datetime_features.py,sha256=qoUOQzHZebnc5JiXCwm258kPLwNRNJgE5JcVHKI9b70,1278
28
+ ocf_data_sampler/numpy_sample/datetime_features.py,sha256=ObHM42VnZB7_daQ5a42GeftoDWYtVMT-wDP8kRtY_84,857
29
29
  ocf_data_sampler/numpy_sample/gsp.py,sha256=aUHDIUSu2LMsVmR7TsTriZxVfv495QNL-scaxyJFHgQ,1149
30
30
  ocf_data_sampler/numpy_sample/nwp.py,sha256=lXqE2Il0xX5hzz76HHkiYmfDsXWWhmaA_6bSnmwbAXU,1078
31
31
  ocf_data_sampler/numpy_sample/satellite.py,sha256=RaYzYIcB1AmDrKeiqSpn4QVfBH-QMe26F1P5t1az2Jg,1111
32
- ocf_data_sampler/numpy_sample/site.py,sha256=zfYBjK3CJrIaKH1QdKXU7gwOxTqONt527y3nJ9TRnwc,1325
32
+ ocf_data_sampler/numpy_sample/site.py,sha256=4S19bzCN5lswVUrmWRfwpVsBPUE7bi0OIdxsD9wgvhU,982
33
33
  ocf_data_sampler/numpy_sample/sun_position.py,sha256=5tt-zNm6aRuZMsxZPaAxyg7HeikswfZCeHWXTHuO2K0,1555
34
34
  ocf_data_sampler/select/__init__.py,sha256=mK7Wu_-j9IXGTYrOuDf5yDDuU5a306b0iGKTAooNg_s,210
35
- ocf_data_sampler/select/dropout.py,sha256=9gPyDF7bGmvSoMjMPu1j0gTZFHNFqsT3ToIo9mFNA00,1565
35
+ ocf_data_sampler/select/dropout.py,sha256=BYpv8L771faPOyN7SdIJ5cwkpDve-ohClj95jjsHmjg,1973
36
36
  ocf_data_sampler/select/fill_time_periods.py,sha256=TlGxp1xiAqnhdWfLy0pv3FuZc00dtimjWdLzr4JoTGA,865
37
37
  ocf_data_sampler/select/find_contiguous_time_periods.py,sha256=etkr6LuB7zxkfzWJ6SgHiULdRuFzFlq5bOUNd257Qx4,11545
38
38
  ocf_data_sampler/select/geospatial.py,sha256=CDExkl36eZOKmdJPzUr_K0Wn3axHqv5nYo-EkSiINcc,5032
@@ -41,7 +41,7 @@ ocf_data_sampler/select/select_spatial_slice.py,sha256=Hd4jGRUfIZRoWCirOQZeoLpaU
41
41
  ocf_data_sampler/select/select_time_slice.py,sha256=HeHbwZ0CP03x0-LaJtpbSdtpLufwVTR73p6wH6O_PS8,5513
42
42
  ocf_data_sampler/torch_datasets/datasets/__init__.py,sha256=jfJSFcR0eO1AqeH7S3KnGjsBqVZT5w3oyi784PUR6Q0,146
43
43
  ocf_data_sampler/torch_datasets/datasets/pvnet_uk.py,sha256=v63goKEMI6UgBPnQCnIbxhFFdwuP_sxgcPYY6iNfGkc,12257
44
- ocf_data_sampler/torch_datasets/datasets/site.py,sha256=R9sYZz3e1zr8NAtlYQp8_DgI3wIfC7Zvaeo_73TyiA8,24936
44
+ ocf_data_sampler/torch_datasets/datasets/site.py,sha256=RGk1tNXxC4RXHVQtChlgtOSfi4DXOVeSyGSX3wiAjiM,24799
45
45
  ocf_data_sampler/torch_datasets/sample/__init__.py,sha256=GL84vdZl_SjHDGVyh9Uekx2XhPYuZ0dnO3l6f6KXnHI,100
46
46
  ocf_data_sampler/torch_datasets/sample/base.py,sha256=cQ1oIyhdmlotejZK8B3Cw6MNvpdnBPD8G_o2h7Ye4Vc,2206
47
47
  ocf_data_sampler/torch_datasets/sample/site.py,sha256=Pq-QjAg88kWXzFR4ci5ATaTWA864eifU7wrJSpmqK4s,1292
@@ -56,7 +56,7 @@ ocf_data_sampler/torch_datasets/utils/validation_utils.py,sha256=YqmT-lExWlI8_ul
56
56
  scripts/download_gsp_location_data.py,sha256=rRDXMoqX-RYY4jPdxhdlxJGhWdl6r245F5UARgKV6P4,3121
57
57
  scripts/refactor_site.py,sha256=skzvsPP0Cn9yTKndzkilyNcGz4DZ88ctvCJ0XrBdc2A,3135
58
58
  utils/compute_icon_mean_stddev.py,sha256=a1oWMRMnny39rV-dvu8rcx85sb4bXzPFrR1gkUr4Jpg,2296
59
- ocf_data_sampler-0.3.0.dist-info/METADATA,sha256=Kq7LhwcpxOpfu4S4NOq-JHFJYI7eeeuxPleNPx6UMLE,12224
60
- ocf_data_sampler-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
61
- ocf_data_sampler-0.3.0.dist-info/top_level.txt,sha256=LEFU4Uk-PEo72QGLAfnVZIUEm37Q8mKuMeg_Xk-p33g,31
62
- ocf_data_sampler-0.3.0.dist-info/RECORD,,
59
+ ocf_data_sampler-0.4.0.dist-info/METADATA,sha256=QbbQ2msPobYgD4v0ghC-xkU3NRGtzi8fhn8A7Gb9TAk,12588
60
+ ocf_data_sampler-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
61
+ ocf_data_sampler-0.4.0.dist-info/top_level.txt,sha256=LEFU4Uk-PEo72QGLAfnVZIUEm37Q8mKuMeg_Xk-p33g,31
62
+ ocf_data_sampler-0.4.0.dist-info/RECORD,,