diff --git a/CHANGELOG.md b/CHANGELOG.md index b893092..1dd49bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Changelog -## Version 0.3.0 - 0.3.1 +## Version 0.3.0 - 0.3.2 - Support for string dimensions when creating cellarr arrays. - Support query conditions for slice operations. - Added unique dim values. Only supported for sparse arrays. - Fix a minor bug causing memory leaks on large sparse arrays. +- Fix an issue when domain is max dimension. - EOL for Python 3.9 ## Version 0.2.0 diff --git a/src/cellarr_array/core/base.py b/src/cellarr_array/core/base.py index 76abbbd..24dcd29 100644 --- a/src/cellarr_array/core/base.py +++ b/src/cellarr_array/core/base.py @@ -172,6 +172,7 @@ def dim_names(self) -> List[str]: if self._dim_names is None: with self.open_array(mode="r") as A: self._dim_names = [dim.name for dim in A.schema.domain] + return self._dim_names @property @@ -180,6 +181,7 @@ def attr_names(self) -> List[str]: if self._attr_names is None: with self.open_array(mode="r") as A: self._attr_names = [A.schema.attr(i).name for i in range(A.schema.nattr)] + return self._attr_names @property @@ -196,6 +198,7 @@ def shape(self) -> Tuple[int, ...]: # We use a large number as a placeholder for slicing purposes. shape_list.append(2**63 - 1) self._shape = tuple(shape_list) + return self._shape @property @@ -208,6 +211,7 @@ def nonempty_domain(self) -> Optional[Tuple[Any, ...]]: self._nonempty_domain = None else: self._nonempty_domain = tuple(ned) if isinstance(ned[0], tuple) else (ned,) + return self._nonempty_domain @property @@ -217,6 +221,7 @@ def ndim(self) -> int: with self.open_array(mode="r") as A: self._ndim = A.schema.ndim # self._ndim = len(self.shape) + return self._ndim @property @@ -225,6 +230,7 @@ def dim_dtypes(self) -> List[np.dtype]: if self._dim_dtypes is None: with self.open_array(mode="r") as A: self._dim_dtypes = [dim.dtype for dim in A.schema.domain] + return self._dim_dtypes @contextmanager diff --git a/src/cellarr_array/core/helpers.py b/src/cellarr_array/core/helpers.py index df2236c..a378af4 100644 --- a/src/cellarr_array/core/helpers.py +++ b/src/cellarr_array/core/helpers.py @@ -71,6 +71,7 @@ def create_cellarray( if attr_dtype is None: attr_dtype = np.float32 + if isinstance(attr_dtype, str): attr_dtype = np.dtype(attr_dtype) @@ -91,6 +92,7 @@ def create_cellarray( if shape is None: shape = tuple(np.iinfo(dt).max if np.issubdtype(dt, np.integer) else None for dt in dim_dtypes) + if None in shape: shape = tuple( np.iinfo(dt).max if s is None and np.issubdtype(dt, np.integer) else s for s, dt in zip(shape, dim_dtypes) @@ -99,7 +101,6 @@ def create_cellarray( if dim_names is None: dim_names = [f"dim_{i}" for i in range(len(shape))] - # Validate all input lengths if not (len(shape) == len(dim_dtypes) == len(dim_names)): raise ValueError("Lengths of 'shape', 'dim_dtypes', and 'dim_names' must match.") @@ -107,7 +108,15 @@ def create_cellarray( for name, s, dt in zip(dim_names, shape, dim_dtypes): if np.issubdtype(dt, np.integer): domain = (0, 0 if s == 0 else s - 1) - tile = min(1 if s == 0 else s // 2, config.tile_capacity // 2) + + is_max_domain = s == np.iinfo(dt).max + if is_max_domain: + # If domain is maxed out, we cannot set a tile extent + # or TileDB will fail on domain expansion. + tile = None + else: + tile = min(1 if s == 0 else s // 2, config.tile_capacity // 2) + dim_dtype = dt else: # Assumes string or object dtype domain = (None, None) diff --git a/src/cellarr_array/core/sparse.py b/src/cellarr_array/core/sparse.py index 9007772..d23e69b 100644 --- a/src/cellarr_array/core/sparse.py +++ b/src/cellarr_array/core/sparse.py @@ -178,7 +178,6 @@ def _to_sparse_format( raise RuntimeError("Internal error: Coordinate remap dictionary not found.") new_coords.append(np.array([remap_dict[val] for val in global_coords])) - elif origins_or_maps[i] is not None: new_coords.append(global_coords - origins_or_maps[i]) else: