diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml deleted file mode 100644 index 5f44587..0000000 --- a/.github/workflows/pythonapp.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Python application - -on: [push] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: Set up Python 3.7 - uses: actions/setup-python@v1 - with: - python-version: 3.7 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install . - - name: Test with pytest - run: | - pip install pytest - pytest diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..d2d076e --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,38 @@ +name: Python application + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-dev.txt + - name: Install lazy_ops + run: | + pip install -e . + - name: Generate coverage report + run: | + pip install pytest + pip install pytest-cov + pytest --cov=./ --cov-report=xml + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml + flags: unittests + name: codecov-umbrella + yml: ./codecov.yml diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..1a96c14 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include requirements.txt requirements-dev.txt diff --git a/README.md b/README.md index 46a9493..fef71d0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # lazy_ops -Lazy transposing and slicing of h5py Datasets +Lazy transposing and slicing of h5py Datasets and zarr arrays ## Installation diff --git a/lazy_ops/__init__.py b/lazy_ops/__init__.py index 439b24b..b7a3813 100644 --- a/lazy_ops/__init__.py +++ b/lazy_ops/__init__.py @@ -1,2 +1,4 @@ from lazy_ops.lazy_loading import DatasetView from lazy_ops.lazy_loading import lazy_transpose + +from .version import version as __version__ diff --git a/lazy_ops/lazy_loading.py b/lazy_ops/lazy_loading.py index bf7d2d0..cb3b313 100644 --- a/lazy_ops/lazy_loading.py +++ b/lazy_ops/lazy_loading.py @@ -28,11 +28,11 @@ from abc import ABCMeta, abstractmethod from typing import Union import h5py -import zarr +installed_dataset_types = h5py.Dataset class DatasetView(metaclass=ABCMeta): - def __new__(cls, dataset: Union[h5py.Dataset,zarr.core.Array] = None, slice_index=(np.index_exp[:],()), axis_order=None): + def __new__(cls, dataset: installed_dataset_types = None, slice_index=(np.index_exp[:],()), axis_order=None): """ Args: dataset: the underlying dataset @@ -43,16 +43,17 @@ def __new__(cls, dataset: Union[h5py.Dataset,zarr.core.Array] = None, slice_inde """ if cls == DatasetView: if isinstance(dataset,h5py.Dataset): - dsetview = DatasetViewh5py(dataset=dataset) - elif isinstance(dataset,zarr.core.Array): - dsetview = DatasetViewzarr(dataset=dataset) - else: - raise TypeError("DatasetView requires either an h5py dataset or a zarr array as first argument") - return dsetview + return DatasetViewh5py(dataset=dataset) + elif HAVE_ZARR: + if isinstance(dataset,zarr.core.Array): + return DatasetViewzarr(dataset=dataset) + elif str(z1).find("zarr") != -1: + raise TypeError("To use DatasetView with a zarr array install zarr: \n pip install zarr\n") + raise TypeError("DatasetView requires either an h5py dataset or a zarr array as first argument") else: return super().__new__(cls) - def __init__(self, dataset: Union[h5py.Dataset,zarr.core.Array] = None, slice_index=(np.index_exp[:],()), axis_order=None): + def __init__(self, dataset: installed_dataset_types = None, slice_index=(np.index_exp[:],()), axis_order=None): """ Args: dataset: the underlying dataset @@ -364,7 +365,7 @@ def read_direct(self, dest, source_sel=None, dest_sel=None): self.dataset.read_direct(reversed_dest, source_sel=reversed_slice_key, dest_sel=reversed_dest_sel) np.copyto(dest, reversed_dest.transpose(axis_order_read)) -def lazy_transpose(dset: Union[h5py.Dataset,zarr.core.Array], axes=None): +def lazy_transpose(dset: installed_dataset_types, axes=None): """ Array lazy transposition, not passing axis argument reverses the order of dimensions Args: dset: h5py dataset @@ -385,11 +386,11 @@ def __new__(cls,dataset): h5py.Dataset.__init__(_self, dataset.id) return _self -class DatasetViewzarr(DatasetView, zarr.core.Array): - - def __new__(cls,dataset): - - _self = super().__new__(cls) - zarr.core.Array.__init__(_self, dataset.store, path=dataset.path) - return _self - +try: + import zarr + from .lazy_loading_zarr import DatasetViewzarr + installed_dataset_types = Union[installed_dataset_types,zarr.core.Array] + HAVE_ZARR = True +except ImportError: + HAVE_ZARR = False + DatasetViewzarr = None \ No newline at end of file diff --git a/lazy_ops/lazy_loading_zarr.py b/lazy_ops/lazy_loading_zarr.py new file mode 100644 index 0000000..88e73cb --- /dev/null +++ b/lazy_ops/lazy_loading_zarr.py @@ -0,0 +1,11 @@ +import zarr +from .lazy_loading import DatasetView + +class DatasetViewzarr(DatasetView, zarr.core.Array): + + def __new__(cls,dataset): + + _self = super().__new__(cls) + zarr.core.Array.__init__(_self, dataset.store, path=dataset.path) + return _self + diff --git a/lazy_ops/version.py b/lazy_ops/version.py new file mode 100644 index 0000000..01673f6 --- /dev/null +++ b/lazy_ops/version.py @@ -0,0 +1 @@ +version = '0.2.1' diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..a6486bb --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +h5py +zarr diff --git a/setup.py b/setup.py index 4028899..65db5dc 100644 --- a/setup.py +++ b/setup.py @@ -1,17 +1,29 @@ from setuptools import setup, find_packages +with open('requirements.txt', "r") as f: + install_requires = f.read().split() + +with open("lazy_ops/version.py", "r") as fv: + exec(fv.read()) + with open("README.md", "r") as fh: long_description = fh.read() setup( name="lazy_ops", - version="0.1.2", + version=version, url="https://github.com/ben-dichter-consulting/lazy_ops", - description="Lazy slicing and transpose operations for h5py", + description="Lazy slicing and transpose operations for h5py and zarr", long_description=long_description, long_description_content_type="text/markdown", author="Daniel Sotoude, Ben Dichter", author_email="dsot@protonmail.com, ben.dichter@gmail.com", packages=find_packages(), - install_requires=['numpy', 'h5py'], + install_requires=install_requires, + classifiers=['Operating System :: OS Independent', + 'Development Status :: 3 - Alpha', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + ], ) diff --git a/tox.ini b/tox.ini index 560630e..678c3c6 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist = py35, py36, py37, py38 [testenv] # install testing framework deps = - -rrequirements.txt + -rrequirements-dev.txt pytest # run the tests commands = pytest