Skip to content

Commit

Permalink
Revert "Coverage to 90% (#1198)"
Browse files Browse the repository at this point in the history
This reverts commit c71537a.
  • Loading branch information
rly committed Dec 20, 2024
1 parent 89f1f8b commit 5f708f2
Show file tree
Hide file tree
Showing 20 changed files with 1,073 additions and 63 deletions.
5 changes: 1 addition & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# HDMF Changelog

## HDMF 4.0.0 (Upcoming)

### Deprecations
- The following classes have been deprecated and removed: Array, AbstractSortedArray, SortedArray, LinSpace, Query, RegionSlicer, ListSlicer, H5RegionSlicer, DataRegion. The following methods have been deprecated and removed: fmt_docval_args, call_docval_func, get_container_cls, add_child, set_dataio (now refactored as set_data_io). We have also removed all early evelopment for region references. @mavaylon1 [#1998](https://github.com/hdmf-dev/hdmf/pull/1198)
## HDMF 3.14.6 (Upcoming)

### Enhancements
- Added support for expandable datasets of references for untyped and compound data types. @stephprince [#1188](https://github.com/hdmf-dev/hdmf/pull/1188)
Expand Down
Binary file removed SortedQueryTest.h5
Binary file not shown.
26 changes: 24 additions & 2 deletions src/hdmf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
from . import query
from .backends.hdf5.h5_utils import H5Dataset
from .container import Container, Data, HERDManager
from .backends.hdf5.h5_utils import H5Dataset, H5RegionSlicer
from .container import Container, Data, DataRegion, HERDManager
from .region import ListSlicer
from .utils import docval, getargs
from .term_set import TermSet, TermSetWrapper, TypeConfigurator


@docval(
{"name": "dataset", "type": None, "doc": "the HDF5 dataset to slice"},
{"name": "region", "type": None, "doc": "the region reference to use to slice"},
is_method=False,
)
def get_region_slicer(**kwargs):
import warnings # noqa: E402

warnings.warn(
"get_region_slicer is deprecated and will be removed in HDMF 3.0.",
DeprecationWarning,
)

dataset, region = getargs("dataset", "region", kwargs)
if isinstance(dataset, (list, tuple, Data)):
return ListSlicer(dataset, region)
elif isinstance(dataset, H5Dataset):
return H5RegionSlicer(dataset, region)
return None


try:
# see https://effigies.gitlab.io/posts/python-packaging-2023/
from ._version import __version__
Expand Down
197 changes: 197 additions & 0 deletions src/hdmf/array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
from abc import abstractmethod, ABCMeta

import numpy as np


class Array:

def __init__(self, data):
self.__data = data
if hasattr(data, 'dtype'):
self.dtype = data.dtype
else:
tmp = data
while isinstance(tmp, (list, tuple)):
tmp = tmp[0]
self.dtype = type(tmp)

@property
def data(self):
return self.__data

def __len__(self):
return len(self.__data)

def get_data(self):
return self.__data

def __getidx__(self, arg):
return self.__data[arg]

def __sliceiter(self, arg):
return (x for x in range(*arg.indices(len(self))))

def __getitem__(self, arg):
if isinstance(arg, list):
idx = list()
for i in arg:
if isinstance(i, slice):
idx.extend(x for x in self.__sliceiter(i))
else:
idx.append(i)
return np.fromiter((self.__getidx__(x) for x in idx), dtype=self.dtype)
elif isinstance(arg, slice):
return np.fromiter((self.__getidx__(x) for x in self.__sliceiter(arg)), dtype=self.dtype)
elif isinstance(arg, tuple):
return (self.__getidx__(arg[0]), self.__getidx__(arg[1]))
else:
return self.__getidx__(arg)


class AbstractSortedArray(Array, metaclass=ABCMeta):
'''
An abstract class for representing sorted array
'''

@abstractmethod
def find_point(self, val):
pass

def get_data(self):
return self

def __lower(self, other):
ins = self.find_point(other)
return ins

def __upper(self, other):
ins = self.__lower(other)
while self[ins] == other:
ins += 1
return ins

def __lt__(self, other):
ins = self.__lower(other)
return slice(0, ins)

def __le__(self, other):
ins = self.__upper(other)
return slice(0, ins)

def __gt__(self, other):
ins = self.__upper(other)
return slice(ins, len(self))

def __ge__(self, other):
ins = self.__lower(other)
return slice(ins, len(self))

@staticmethod
def __sort(a):
if isinstance(a, tuple):
return a[0]
else:
return a

def __eq__(self, other):
if isinstance(other, list):
ret = list()
for i in other:
eq = self == i
ret.append(eq)
ret = sorted(ret, key=self.__sort)
tmp = list()
for i in range(1, len(ret)):
a, b = ret[i - 1], ret[i]
if isinstance(a, tuple):
if isinstance(b, tuple):
if a[1] >= b[0]:
b[0] = a[0]
else:
tmp.append(slice(*a))
else:
if b > a[1]:
tmp.append(slice(*a))
elif b == a[1]:
a[1] == b + 1
else:
ret[i] = a
else:
if isinstance(b, tuple):
if a < b[0]:
tmp.append(a)
else:
if b - a == 1:
ret[i] = (a, b)
else:
tmp.append(a)
if isinstance(ret[-1], tuple):
tmp.append(slice(*ret[-1]))
else:
tmp.append(ret[-1])
ret = tmp
return ret
elif isinstance(other, tuple):
ge = self >= other[0]
ge = ge.start
lt = self < other[1]
lt = lt.stop
if ge == lt:
return ge
else:
return slice(ge, lt)
else:
lower = self.__lower(other)
upper = self.__upper(other)
d = upper - lower
if d == 1:
return lower
elif d == 0:
return None
else:
return slice(lower, upper)

def __ne__(self, other):
eq = self == other
if isinstance(eq, tuple):
return [slice(0, eq[0]), slice(eq[1], len(self))]
else:
return [slice(0, eq), slice(eq + 1, len(self))]


class SortedArray(AbstractSortedArray):
'''
A class for wrapping sorted arrays. This class overrides
<,>,<=,>=,==, and != to leverage the sorted content for
efficiency.
'''

def __init__(self, array):
super().__init__(array)

def find_point(self, val):
return np.searchsorted(self.data, val)


class LinSpace(SortedArray):

def __init__(self, start, stop, step):
self.start = start
self.stop = stop
self.step = step
self.dtype = float if any(isinstance(s, float) for s in (start, stop, step)) else int
self.__len = int((stop - start) / step)

def __len__(self):
return self.__len

def find_point(self, val):
nsteps = (val - self.start) / self.step
fl = int(nsteps)
if fl == nsteps:
return int(fl)
else:
return int(fl + 1)

def __getidx__(self, arg):
return self.start + self.step * arg
2 changes: 1 addition & 1 deletion src/hdmf/backends/hdf5/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from . import h5_utils, h5tools
from .h5_utils import H5DataIO
from .h5_utils import H5RegionSlicer, H5DataIO
from .h5tools import HDF5IO, H5SpecWriter, H5SpecReader
Loading

0 comments on commit 5f708f2

Please sign in to comment.