cellarr-array 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cellarr-array might be problematic. Click here for more details.

@@ -1,5 +1,11 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from contextlib import contextmanager
3
+
4
+ try:
5
+ from types import EllipsisType
6
+ except ImportError:
7
+ # TODO: This is required for Python <3.10. Remove once Python 3.9 reaches EOL in October 2025
8
+ EllipsisType = type(...)
3
9
  from typing import List, Literal, Optional, Tuple, Union
4
10
 
5
11
  import numpy as np
@@ -42,7 +48,8 @@ class CellArray(ABC):
42
48
  Defaults to None for automatic mode switching.
43
49
 
44
50
  config_or_context:
45
- Config or context object.
51
+ Optional config or context object.
52
+
46
53
  Defaults to None.
47
54
 
48
55
  validate:
@@ -53,14 +60,15 @@ class CellArray(ABC):
53
60
  self._mode = mode
54
61
 
55
62
  if config_or_context is None:
56
- config_or_context = tiledb.Config()
57
-
58
- if isinstance(config_or_context, tiledb.Config):
59
- ctx = tiledb.Ctx(config_or_context)
60
- elif isinstance(config_or_context, tiledb.Ctx):
61
- ctx = config_or_context
63
+ # config_or_context = tiledb.Config()
64
+ ctx = None
62
65
  else:
63
- raise TypeError("'config_or_context' must be either TileDB config or a context object.")
66
+ if isinstance(config_or_context, tiledb.Config):
67
+ ctx = tiledb.Ctx(config_or_context)
68
+ elif isinstance(config_or_context, tiledb.Ctx):
69
+ ctx = config_or_context
70
+ else:
71
+ raise TypeError("'config_or_context' must be either TileDB config or a context object.")
64
72
 
65
73
  self._ctx = ctx
66
74
  self._array = None
@@ -68,6 +76,7 @@ class CellArray(ABC):
68
76
  self._ndim = None
69
77
  self._dim_names = None
70
78
  self._attr_names = None
79
+ self._nonempty_domain = None
71
80
 
72
81
  if validate:
73
82
  self._validate(attr=attr)
@@ -157,7 +166,7 @@ class CellArray(ABC):
157
166
  finally:
158
167
  array.close()
159
168
 
160
- def __getitem__(self, key: Union[slice, Tuple[Union[slice, List[int]], ...]]):
169
+ def __getitem__(self, key: Union[slice, EllipsisType, Tuple[Union[slice, List[int]], ...], EllipsisType]):
161
170
  """Get item implementation that routes to either direct slicing or multi_index
162
171
  based on the type of indices provided.
163
172
 
@@ -174,16 +183,22 @@ class CellArray(ABC):
174
183
  # Normalize all indices
175
184
  normalized_key = tuple(SliceHelper.normalize_index(idx, self.shape[i]) for i, idx in enumerate(key))
176
185
 
186
+ num_ellipsis = sum(isinstance(i, EllipsisType) for i in normalized_key)
187
+ if num_ellipsis > 1:
188
+ raise IndexError(f"Found more than 1 Ellipsis (...) in key: {normalized_key}")
189
+
177
190
  # Check if we can use direct slicing
178
- use_direct = all(isinstance(idx, slice) for idx in normalized_key)
191
+ use_direct = all(isinstance(idx, (slice, EllipsisType)) for idx in normalized_key)
179
192
 
180
193
  if use_direct:
181
194
  return self._direct_slice(normalized_key)
182
195
  else:
196
+ if num_ellipsis > 0:
197
+ raise IndexError(f"tiledb does not support ellipsis in multi-index access: {normalized_key}")
183
198
  return self._multi_index(normalized_key)
184
199
 
185
200
  @abstractmethod
186
- def _direct_slice(self, key: Tuple[slice, ...]) -> np.ndarray:
201
+ def _direct_slice(self, key: Tuple[Union[slice, EllipsisType], ...]) -> np.ndarray:
187
202
  """Implementation for direct slicing."""
188
203
  pass
189
204
 
@@ -1,3 +1,8 @@
1
+ try:
2
+ from types import EllipsisType
3
+ except ImportError:
4
+ # TODO: This is required for Python <3.10. Remove once Python 3.9 reaches EOL in October 2025
5
+ EllipsisType = type(...)
1
6
  from typing import List, Tuple, Union
2
7
 
3
8
  import numpy as np
@@ -13,7 +18,7 @@ __license__ = "MIT"
13
18
  class DenseCellArray(CellArray):
14
19
  """Implementation for dense TileDB arrays."""
15
20
 
16
- def _direct_slice(self, key: Tuple[slice, ...]) -> np.ndarray:
21
+ def _direct_slice(self, key: Tuple[Union[slice, EllipsisType], ...]) -> np.ndarray:
17
22
  """Implementation for direct slicing of dense arrays.
18
23
 
19
24
  Args:
@@ -1,3 +1,8 @@
1
+ try:
2
+ from types import EllipsisType
3
+ except ImportError:
4
+ # TODO: This is required for Python <3.10. Remove once Python 3.9 reaches EOL in October 2025
5
+ EllipsisType = type(...)
1
6
  from typing import Dict, List, Optional, Tuple, Union
2
7
 
3
8
  import numpy as np
@@ -118,7 +123,7 @@ class SparseCellArray(CellArray):
118
123
 
119
124
  return sliced[key]
120
125
 
121
- def _direct_slice(self, key: Tuple[slice, ...]) -> Union[np.ndarray, sparse.coo_matrix]:
126
+ def _direct_slice(self, key: Tuple[Union[slice, EllipsisType], ...]) -> Union[np.ndarray, sparse.coo_matrix]:
122
127
  """Implementation for direct slicing of sparse arrays."""
123
128
  with self.open_array(mode="r") as array:
124
129
  result = array[key]
cellarr_array/__init__.py CHANGED
@@ -18,4 +18,4 @@ finally:
18
18
  from .config import CellArrConfig, ConsolidationConfig
19
19
  from .DenseCellArray import DenseCellArray
20
20
  from .SparseCellArray import SparseCellArray
21
- from .helpers import create_cellarray, SliceHelper
21
+ from .helpers import create_cellarray, SliceHelper
cellarr_array/helpers.py CHANGED
@@ -1,3 +1,8 @@
1
+ try:
2
+ from types import EllipsisType
3
+ except ImportError:
4
+ # TODO: This is required for Python <3.10. Remove once Python 3.9 reaches EOL in October 2025
5
+ EllipsisType = type(...)
1
6
  from typing import List, Optional, Tuple, Union
2
7
 
3
8
  import numpy as np
@@ -150,9 +155,12 @@ class SliceHelper:
150
155
  return None
151
156
 
152
157
  @staticmethod
153
- def normalize_index(idx: Union[int, slice, List[int]], dim_size: int) -> Union[slice, List[int]]:
158
+ def normalize_index(idx: Union[int, slice, List[int]], dim_size: int) -> Union[slice, List[int], EllipsisType]:
154
159
  """Normalize index to handle negative indices and ensure consistency."""
155
160
 
161
+ if isinstance(idx, EllipsisType):
162
+ return idx
163
+
156
164
  # Convert ranges to slices
157
165
  if isinstance(idx, range):
158
166
  idx = slice(idx.start, idx.stop, idx.step)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: cellarr-array
3
- Version: 0.0.1
3
+ Version: 0.0.3
4
4
  Summary: Base class for handling TileDB backed arrays.
5
5
  Home-page: https://github.com/cellarr/cellarr-array
6
6
  Author: Jayaram Kancherla
@@ -20,13 +20,14 @@ Provides-Extra: testing
20
20
  Requires-Dist: setuptools; extra == "testing"
21
21
  Requires-Dist: pytest; extra == "testing"
22
22
  Requires-Dist: pytest-cov; extra == "testing"
23
+ Dynamic: license-file
23
24
 
24
25
  [![PyPI-Server](https://img.shields.io/pypi/v/cellarr-array.svg)](https://pypi.org/project/cellarr-array/)
25
26
  ![Unit tests](https://github.com/cellarr/cellarr-array/actions/workflows/run-tests.yml/badge.svg)
26
27
 
27
28
  # cellarr-array
28
29
 
29
- This package provided high-level wrappers for TileDB arrays optimized for handling genomic data matrices.
30
+ This package provided high-level wrappers for TileDB arrays, for handling genomic data matrices.
30
31
 
31
32
  ## Install
32
33
 
@@ -116,24 +117,43 @@ subset = dense_array[100:200, genes]
116
117
  ### Working with Sparse Arrays
117
118
 
118
119
  ```python
119
- # Create a sparse array with COO output format
120
- coo_array = SparseCellArray(
120
+ from cellarr_array import SparseCellArray
121
+
122
+ # Create a sparse array with CSR output format
123
+ csr_array = SparseCellArray(
121
124
  uri="sparse_matrix.tdb",
122
- return_coo=True
125
+ return_sparse=True
123
126
  )
124
127
 
125
- # Get result as COO matrix
126
- result = coo_array[100:200, 500:1000]
128
+ # Get result as CSR matrix
129
+ result = csr_array[100:200, 500:1000]
127
130
 
128
131
  # Result is scipy.sparse.coo_matrix
129
- assert sparse.isspmatrix_coo(result)
132
+ assert sparse.isspmatrix_csr(result)
130
133
 
131
134
  # Perform sparse operations
132
135
  nnz = result.nnz
133
136
  density = result.nnz / (result.shape[0] * result.shape[1])
134
137
 
135
138
  # Convert to other sparse formats if needed
136
- result_csr = result.tocsr()
139
+ result_csc = result.tocsc()
140
+ ```
141
+
142
+ Likewise create a CSC output format
143
+
144
+ ```python
145
+ from scipy import sparse
146
+
147
+ # Create a sparse array with CSC output format
148
+ csc_array = SparseCellArray(
149
+ uri="sparse_matrix.tdb",
150
+ return_sparse=True,
151
+ sparse_coerce=sparse.csc_matrix
152
+ )
153
+
154
+ # Get result as CSR matrix
155
+ result = csc_array[100:200, 500:1000]
156
+ print(result)
137
157
  ```
138
158
 
139
159
  ### Array Maintenance
@@ -144,7 +164,7 @@ array.consolidate()
144
164
 
145
165
  # Custom consolidation
146
166
  config = ConsolidationConfig(
147
- steps=["fragment"],
167
+ steps=2,
148
168
  vacuum_after=True
149
169
  )
150
170
  array.consolidate(config)
@@ -0,0 +1,11 @@
1
+ cellarr_array/CellArray.py,sha256=vc_6oDLCpVgUaP8HsQz4vE0ZyJ1SPdX43s7VQyh7gF0,8204
2
+ cellarr_array/DenseCellArray.py,sha256=rlu2xq8SONwIswqe0TzRNCwM5f0HYgxr4QBtvbBe8ro,3953
3
+ cellarr_array/SparseCellArray.py,sha256=cOIbs_97j5u13FU7FfEfRNqAZi8rHUkypgLgRcubXrU,7304
4
+ cellarr_array/__init__.py,sha256=IUE9wMDISgRkWp-Fc0KJpDiezCJ61kzuTqS9HdK-JeE,779
5
+ cellarr_array/config.py,sha256=67zBxpYY9N_v6TMdyljUIZmckbwOBcuLC99aJooGmfA,2917
6
+ cellarr_array/helpers.py,sha256=ZqK_josEzKzTMP62P9pb4qBiOTisFofTCnu1LETYJT4,6449
7
+ cellarr_array-0.0.3.dist-info/licenses/LICENSE.txt,sha256=qI2hRZobcUlj8gqFqXwqt522HeYyWvHLF00zCSZofHA,1084
8
+ cellarr_array-0.0.3.dist-info/METADATA,sha256=1KgSZEEF2i9aCr4mkkyAmuPXht4y5ZG2-YdH4dBELpQ,4120
9
+ cellarr_array-0.0.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
10
+ cellarr_array-0.0.3.dist-info/top_level.txt,sha256=oErp0D8ABZV-QPtTiXT8_F2z36Ic7ykuDg_1Y84HLZM,14
11
+ cellarr_array-0.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- cellarr_array/CellArray.py,sha256=vOaq-0FbVKeuS31992oc_N5IOBXclcVkczPNIbua5Ws,7498
2
- cellarr_array/DenseCellArray.py,sha256=iPrjFtGolnHB0BTi4A8ncEpoFI9FWe6oZHhA1Men3Wo,3745
3
- cellarr_array/SparseCellArray.py,sha256=8bajVOvUMaQhWU-_pZY0Cg9sD6kWRAJCu2G45uY-W4Q,7096
4
- cellarr_array/__init__.py,sha256=8m0_shRPKNNaNab5tGBL2l0K5XgkKCFuLAh7QGogfYo,778
5
- cellarr_array/config.py,sha256=67zBxpYY9N_v6TMdyljUIZmckbwOBcuLC99aJooGmfA,2917
6
- cellarr_array/helpers.py,sha256=O0RgDLIdYbWc01yp2Cw0EmjJ3g_uzlz2JnYE8W7PZEE,6182
7
- cellarr_array-0.0.1.dist-info/LICENSE.txt,sha256=qI2hRZobcUlj8gqFqXwqt522HeYyWvHLF00zCSZofHA,1084
8
- cellarr_array-0.0.1.dist-info/METADATA,sha256=UaSorFB0-5KuhVrM8pvdGuN98WQ6iSLgUUH6MtpJwXM,3747
9
- cellarr_array-0.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
- cellarr_array-0.0.1.dist-info/top_level.txt,sha256=oErp0D8ABZV-QPtTiXT8_F2z36Ic7ykuDg_1Y84HLZM,14
11
- cellarr_array-0.0.1.dist-info/RECORD,,