numpydantic/tests/fixtures/generation.py

107 lines
3.5 KiB
Python
Raw Normal View History

2024-09-03 23:54:31 +00:00
from datetime import datetime, timezone
2024-10-04 01:51:34 +00:00
from pathlib import Path
from typing import Callable, Tuple, Union
2024-10-04 01:51:34 +00:00
import cv2
import h5py
import numpy as np
import pytest
2024-04-30 02:49:38 +00:00
import zarr
from numpydantic.interface.hdf5 import H5ArrayPath
2024-04-30 02:49:38 +00:00
from numpydantic.interface.zarr import ZarrArrayPath
2024-05-15 03:18:04 +00:00
@pytest.fixture(scope="function")
def hdf5_array(
2024-09-27 02:58:27 +00:00
request, tmp_output_dir_func
) -> Callable[[Tuple[int, ...], Union[np.dtype, type]], H5ArrayPath]:
2024-09-27 02:58:27 +00:00
hdf5_file = tmp_output_dir_func / "h5f.h5"
def _hdf5_array(
shape: Tuple[int, ...] = (10, 10),
dtype: Union[np.dtype, type] = float,
compound: bool = False,
) -> H5ArrayPath:
array_path = "/" + "_".join([str(s) for s in shape]) + "__" + dtype.__name__
2024-10-04 02:57:54 +00:00
generator = np.random.default_rng()
2024-10-04 03:01:56 +00:00
if not compound:
2024-09-03 05:29:58 +00:00
if dtype is str:
2024-10-04 02:57:54 +00:00
data = generator.random(shape).astype(bytes)
2024-09-03 23:54:31 +00:00
elif dtype is datetime:
data = np.empty(shape, dtype="S32")
data.fill(datetime.now(timezone.utc).isoformat().encode("utf-8"))
2024-09-03 05:29:58 +00:00
else:
2024-10-04 02:57:54 +00:00
data = generator.random(shape).astype(dtype)
2024-09-27 02:58:27 +00:00
h5path = H5ArrayPath(hdf5_file, array_path)
else:
2024-09-03 05:14:47 +00:00
if dtype is str:
dt = np.dtype([("data", np.dtype("S10")), ("extra", "i8")])
data = np.array([("hey", 0)] * np.prod(shape), dtype=dt).reshape(shape)
2024-09-03 23:54:31 +00:00
elif dtype is datetime:
dt = np.dtype([("data", np.dtype("S32")), ("extra", "i8")])
data = np.array(
[(datetime.now(timezone.utc).isoformat().encode("utf-8"), 0)]
* np.prod(shape),
dtype=dt,
).reshape(shape)
2024-09-03 05:14:47 +00:00
else:
dt = np.dtype([("data", dtype), ("extra", "i8")])
data = np.zeros(shape, dtype=dt)
2024-09-27 02:58:27 +00:00
h5path = H5ArrayPath(hdf5_file, array_path, "data")
with h5py.File(hdf5_file, "w") as h5f:
_ = h5f.create_dataset(array_path, data=data)
return h5path
return _hdf5_array
2024-04-30 02:49:38 +00:00
@pytest.fixture(scope="function")
def zarr_nested_array(tmp_output_dir_func) -> ZarrArrayPath:
"""Zarr array within a nested array"""
file = tmp_output_dir_func / "nested.zarr"
path = "a/b/c"
root = zarr.open(str(file), mode="w")
2024-10-04 02:57:54 +00:00
_ = root.zeros(path, shape=(100, 100), chunks=(10, 10))
2024-04-30 02:49:38 +00:00
return ZarrArrayPath(file=file, path=path)
@pytest.fixture(scope="function")
def zarr_array(tmp_output_dir_func) -> Path:
file = tmp_output_dir_func / "array.zarr"
array = zarr.open(str(file), mode="w", shape=(100, 100), chunks=(10, 10))
array[:] = 0
return file
@pytest.fixture(scope="function")
2024-09-26 01:15:27 +00:00
def avi_video(tmp_output_dir_func) -> Callable[[Tuple[int, int], int, bool], Path]:
video_path = tmp_output_dir_func / "test.avi"
def _make_video(shape=(100, 50), frames=10, is_color=True) -> Path:
writer = cv2.VideoWriter(
str(video_path),
cv2.VideoWriter_fourcc(*"RGBA"), # raw video for testing purposes
30,
(shape[1], shape[0]),
is_color,
)
if is_color:
shape = (*shape, 3)
for i in range(frames):
# make fresh array every time bc opencv eats them
array = np.zeros(shape, dtype=np.uint8)
if not is_color:
array[i, i] = i
else:
array[i, i, :] = i
writer.write(array)
writer.release()
return video_path
return _make_video