Skip to content

Commit

Permalink
Merge branch 'dev' into rly-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
mavaylon1 authored Jan 22, 2025
2 parents 8f452ba + 775fa3b commit b4f33ef
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: Install package with optional dependencies
if: ${{ matrix.opt_req }}
run: |
python -m pip install ".[test,tqdm,zarr,termset]"
python -m pip install ".[test,tqdm,sparse,zarr,termset]"
- name: Run tests and generate coverage report
run: |
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ formats: all
# Optionally set the version of Python and requirements required to build your docs
python:
install:
- path: .[docs,tqdm,zarr,termset] # path to the package relative to the root
- path: .[docs,tqdm,sparse,zarr,termset] # path to the package relative to the root

# Optionally include all submodules
submodules:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Importing from `hdmf.build.map` is no longer supported. Import from `hdmf.build` instead. @rly [#1221](https://github.com/hdmf-dev/hdmf/pull/1221)
- Python 3.8 has reached end of life. Dropped support for Python 3.8 and add support for Python 3.13. @mavaylon1 [#1209](https://github.com/hdmf-dev/hdmf/pull/1209)
- Support for Zarr is limited to versions < 3. @rly [#1229](https://github.com/hdmf-dev/hdmf/pull/1229)
- Scipy is no longer a required dependency. Users using the `CSRMatrix` data type should install `scipy` separately or with `pip install "hdmf[sparse]"`. @rly [#1140](https://github.com/hdmf-dev/hdmf/pull/1140)

### Changed
- Added checks to ensure that group and dataset spec names and default names do not contain slashes. @bendichter [#1219](https://github.com/hdmf-dev/hdmf/pull/1219)
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ dependencies = [
'numpy>=1.19.3',
"pandas>=1.2.0",
"ruamel.yaml>=0.16",
"scipy>=1.7",
]
dynamic = ["version"]

[project.optional-dependencies]
tqdm = ["tqdm>=4.41.0"]
zarr = ["zarr>=2.12.0,<3"]
sparse = ["scipy>=1.7"]
termset = [
"linkml-runtime>=1.5.5",
"schemasheets>=0.1.23",
Expand Down Expand Up @@ -70,7 +70,7 @@ docs = [
]

# all possible dependencies
all = ["hdmf[tqdm,zarr,termset,test,docs]"]
all = ["hdmf[tqdm,zarr,sparse,termset,test,docs]"]

[project.urls]
"Homepage" = "https://github.com/hdmf-dev/hdmf"
Expand Down
22 changes: 17 additions & 5 deletions src/hdmf/common/sparse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import scipy.sparse as sps
try:
from scipy.sparse import csr_matrix
SCIPY_INSTALLED = True
except ImportError:
SCIPY_INSTALLED = False
class csr_matrix: # dummy class to prevent import errors
pass

from . import register_class
from ..container import Container
from ..utils import docval, popargs, to_uint_array, get_data_shape, AllowPositional
Expand All @@ -7,7 +14,7 @@
@register_class('CSRMatrix')
class CSRMatrix(Container):

@docval({'name': 'data', 'type': (sps.csr_matrix, 'array_data'),
@docval({'name': 'data', 'type': (csr_matrix, 'array_data'),
'doc': 'the data to use for this CSRMatrix or CSR data array.'
'If passing CSR data array, *indices*, *indptr*, and *shape* must also be provided'},
{'name': 'indices', 'type': 'array_data', 'doc': 'CSR index array', 'default': None},
Expand All @@ -16,13 +23,17 @@ class CSRMatrix(Container):
{'name': 'name', 'type': str, 'doc': 'the name to use for this when storing', 'default': 'csr_matrix'},
allow_positional=AllowPositional.WARNING)
def __init__(self, **kwargs):
if not SCIPY_INSTALLED:
raise ImportError(
"scipy must be installed to use CSRMatrix. Please install scipy using `pip install scipy`."
)
data, indices, indptr, shape = popargs('data', 'indices', 'indptr', 'shape', kwargs)
super().__init__(**kwargs)
if not isinstance(data, sps.csr_matrix):
if not isinstance(data, csr_matrix):
temp_shape = get_data_shape(data)
temp_ndim = len(temp_shape)
if temp_ndim == 2:
data = sps.csr_matrix(data)
data = csr_matrix(data)
elif temp_ndim == 1:
if any(_ is None for _ in (indptr, indices, shape)):
raise ValueError("Must specify 'indptr', 'indices', and 'shape' arguments when passing data array.")
Expand All @@ -31,9 +42,10 @@ def __init__(self, **kwargs):
shape = self.__check_arr(shape, 'shape')
if len(shape) != 2:
raise ValueError("'shape' argument must specify two and only two dimensions.")
data = sps.csr_matrix((data, indices, indptr), shape=shape)
data = csr_matrix((data, indices, indptr), shape=shape)
else:
raise ValueError("'data' argument cannot be ndarray of dimensionality > 2.")
# self.__data is a scipy.sparse.csr_matrix
self.__data = data

@staticmethod
Expand Down
22 changes: 19 additions & 3 deletions tests/unit/common/test_sparse.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
from hdmf.common import CSRMatrix
from hdmf.testing import TestCase, H5RoundTripMixin

import scipy.sparse as sps
import numpy as np
import unittest

try:
import scipy.sparse as sps
SCIPY_INSTALLED = True
except ImportError:
SCIPY_INSTALLED = False


@unittest.skipIf(SCIPY_INSTALLED, "scipy is installed")
class TestCSRMatrixNoScipy(TestCase):

def test_import_error(self):
data = np.array([[1, 0, 2], [0, 0, 3], [4, 5, 6]])
with self.assertRaises(ImportError):
CSRMatrix(data=data)


@unittest.skipIf(not SCIPY_INSTALLED, "scipy is not installed")
class TestCSRMatrix(TestCase):

def test_from_sparse_matrix(self):
Expand Down Expand Up @@ -153,7 +168,7 @@ def test_array_bad_dim(self):
with self.assertRaisesWith(ValueError, msg):
CSRMatrix(data=data, indices=indices, indptr=indptr, shape=shape)


@unittest.skipIf(not SCIPY_INSTALLED, "scipy is not installed")
class TestCSRMatrixRoundTrip(H5RoundTripMixin, TestCase):

def setUpContainer(self):
Expand All @@ -164,6 +179,7 @@ def setUpContainer(self):
return CSRMatrix(data=data, indices=indices, indptr=indptr, shape=shape)


@unittest.skipIf(not SCIPY_INSTALLED, "scipy is not installed")
class TestCSRMatrixRoundTripFromLists(H5RoundTripMixin, TestCase):
"""Test that CSRMatrix works with lists as well"""

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extras =
# which optional dependency set(s) to use (default: none)
pytest: test
gallery: doc
optional: tqdm,zarr,termset
optional: tqdm,sparse,zarr,termset
commands =
# commands to run for every environment
python --version # print python version for debugging
Expand Down

0 comments on commit b4f33ef

Please sign in to comment.