Skip to content

Commit bb1cc3b

Browse files
committed
add an exploratory notebook for testing and showing the Array class
1 parent 9077fe8 commit bb1cc3b

File tree

2 files changed

+212
-6
lines changed

2 files changed

+212
-6
lines changed

explore.ipynb

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"from funlib.persistence import Array\n",
10+
"\n",
11+
"import numpy as np\n",
12+
"\n",
13+
"import zarr"
14+
]
15+
},
16+
{
17+
"cell_type": "code",
18+
"execution_count": 2,
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"container = zarr.open(\"example.zarr\")\n",
23+
"shape = (2, 3, 3)\n",
24+
"\n",
25+
"ds = container.create_dataset(\n",
26+
" \"raw\",\n",
27+
" chunks=(1, 3, 3),\n",
28+
" dtype=\"f4\",\n",
29+
" data=np.random.randn(*shape),\n",
30+
" overwrite=True,\n",
31+
")"
32+
]
33+
},
34+
{
35+
"cell_type": "code",
36+
"execution_count": 3,
37+
"metadata": {},
38+
"outputs": [
39+
{
40+
"name": "stdout",
41+
"output_type": "stream",
42+
"text": [
43+
"[[[ 0.44273075 -0.17070776 -0.7056614 ]\n",
44+
" [ 0.99363405 -0.7815089 1.3557754 ]\n",
45+
" [ 0.5848475 0.59523624 -1.4611949 ]]\n",
46+
"\n",
47+
" [[ 0.09116387 -1.4376557 0.5421799 ]\n",
48+
" [ 1.1627685 1.9053004 1.2552763 ]\n",
49+
" [ 0.2825793 -0.8584084 -1.4131508 ]]]\n"
50+
]
51+
}
52+
],
53+
"source": [
54+
"array = Array(ds, (0, 0), (1, 1))\n",
55+
"print(array[array.roi])"
56+
]
57+
},
58+
{
59+
"cell_type": "code",
60+
"execution_count": 4,
61+
"metadata": {},
62+
"outputs": [
63+
{
64+
"name": "stdout",
65+
"output_type": "stream",
66+
"text": [
67+
"[[[ 0.09116387 -1.4376557 0.5421799 ]\n",
68+
" [ 1.1627685 1.9053004 1.2552763 ]\n",
69+
" [ 0.2825793 -0.8584084 -1.4131508 ]]]\n"
70+
]
71+
}
72+
],
73+
"source": [
74+
"array_sliced = Array(ds, (0, 0), (1, 1), adapter=slice(1,2))\n",
75+
"print(array_sliced[array_sliced.roi])"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": 5,
81+
"metadata": {},
82+
"outputs": [
83+
{
84+
"name": "stdout",
85+
"output_type": "stream",
86+
"text": [
87+
"[[[10.091164 8.562345 10.54218 ]\n",
88+
" [11.162768 11.9053 11.255277]\n",
89+
" [10.282579 9.141592 8.586849]]]\n"
90+
]
91+
}
92+
],
93+
"source": [
94+
"array_sliced[array_sliced.roi] = array_sliced[array_sliced.roi] + 10\n",
95+
"print(array_sliced[array_sliced.roi])"
96+
]
97+
},
98+
{
99+
"cell_type": "code",
100+
"execution_count": 6,
101+
"metadata": {},
102+
"outputs": [
103+
{
104+
"name": "stdout",
105+
"output_type": "stream",
106+
"text": [
107+
"[[[ 0.44273075 -0.17070776 -0.7056614 ]\n",
108+
" [ 0.99363405 -0.7815089 1.3557754 ]\n",
109+
" [ 0.5848475 0.59523624 -1.4611949 ]]\n",
110+
"\n",
111+
" [[10.091164 8.562345 10.54218 ]\n",
112+
" [11.162768 11.9053 11.255277 ]\n",
113+
" [10.282579 9.141592 8.586849 ]]]\n"
114+
]
115+
}
116+
],
117+
"source": [
118+
"print(ds[:])"
119+
]
120+
},
121+
{
122+
"cell_type": "code",
123+
"execution_count": 7,
124+
"metadata": {},
125+
"outputs": [
126+
{
127+
"name": "stdout",
128+
"output_type": "stream",
129+
"text": [
130+
"bool\n",
131+
"[[[False False False]\n",
132+
" [False False False]\n",
133+
" [False False False]]\n",
134+
"\n",
135+
" [[ True True True]\n",
136+
" [ True True True]\n",
137+
" [ True True True]]]\n"
138+
]
139+
}
140+
],
141+
"source": [
142+
"thresholded = Array(ds, (0, 0), (1, 1), adapter=lambda x: x > 5)\n",
143+
"print(thresholded.dtype)\n",
144+
"print(thresholded[thresholded.roi])"
145+
]
146+
},
147+
{
148+
"cell_type": "code",
149+
"execution_count": 8,
150+
"metadata": {},
151+
"outputs": [
152+
{
153+
"ename": "RuntimeError",
154+
"evalue": "This array is not writeable since you have applied a custom callable adapter that may or may not be invertable.",
155+
"output_type": "error",
156+
"traceback": [
157+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
158+
"\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
159+
"Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mthresholded\u001b[49m\u001b[43m[\u001b[49m\u001b[43mthresholded\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mroi\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m thresholded[thresholded\u001b[38;5;241m.\u001b[39mroi] \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m10\u001b[39m\n",
160+
"File \u001b[0;32m~/Work/Packages/funlib.persistence/funlib/persistence/arrays/array.py:211\u001b[0m, in \u001b[0;36mArray.__setitem__\u001b[0;34m(self, key, value)\u001b[0m\n\u001b[1;32m 209\u001b[0m da\u001b[38;5;241m.\u001b[39mstore(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata[roi_slices], \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_source_data, regions\u001b[38;5;241m=\u001b[39mroi_slices)\n\u001b[1;32m 210\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 211\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\n\u001b[1;32m 212\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis array is not writeable since you have applied a custom callable \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 213\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124madapter that may or may not be invertable.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 214\u001b[0m )\n",
161+
"\u001b[0;31mRuntimeError\u001b[0m: This array is not writeable since you have applied a custom callable adapter that may or may not be invertable."
162+
]
163+
}
164+
],
165+
"source": [
166+
"\n",
167+
"thresholded[thresholded.roi] = thresholded[thresholded.roi] + 10"
168+
]
169+
},
170+
{
171+
"cell_type": "code",
172+
"execution_count": null,
173+
"metadata": {},
174+
"outputs": [],
175+
"source": []
176+
}
177+
],
178+
"metadata": {
179+
"kernelspec": {
180+
"display_name": "funlib.persistence",
181+
"language": "python",
182+
"name": "python3"
183+
},
184+
"language_info": {
185+
"codemirror_mode": {
186+
"name": "ipython",
187+
"version": 3
188+
},
189+
"file_extension": ".py",
190+
"mimetype": "text/x-python",
191+
"name": "python",
192+
"nbconvert_exporter": "python",
193+
"pygments_lexer": "ipython3",
194+
"version": "3.11.8"
195+
}
196+
},
197+
"nbformat": 4,
198+
"nbformat_minor": 2
199+
}

funlib/persistence/arrays/array.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ def dtype(self):
128128
def is_writeable(self):
129129
return len(self.adapter) == 0 or all(
130130
[
131-
isinstance(adapter, slice) or isinstance(adapter, list[slice])
131+
isinstance(adapter, slice)
132+
or (
133+
isinstance(adapter, Iterable)
134+
and all([isinstance(a, slice) for a in adapter])
135+
)
132136
for adapter in self.adapter
133137
]
134138
)
@@ -161,7 +165,7 @@ def __getitem__(self, key) -> np.ndarray:
161165
% (roi, self.roi)
162166
)
163167

164-
return self.data[self.__slices(roi)]
168+
return self.data[self.__slices(roi)].compute()
165169

166170
elif isinstance(key, Coordinate):
167171
coordinate = key
@@ -173,7 +177,7 @@ def __getitem__(self, key) -> np.ndarray:
173177
return self.data[index].compute()
174178

175179
else:
176-
return self.data[key]
180+
return self.data[key].compute()
177181

178182
def __setitem__(self, key, value: np.ndarray):
179183
"""Set the data of this array within the given ROI.
@@ -203,6 +207,11 @@ def __setitem__(self, key, value: np.ndarray):
203207
self.data[roi_slices] = value
204208

205209
da.store(self.data[roi_slices], self._source_data, regions=roi_slices)
210+
else:
211+
raise RuntimeError(
212+
"This array is not writeable since you have applied a custom callable "
213+
"adapter that may or may not be invertable."
214+
)
206215

207216
def to_ndarray(self, roi, fill_value=0):
208217
"""An alternative implementation of `__getitem__` that supports
@@ -268,8 +277,6 @@ def _combine_slices(
268277
slice(slice_range.start, slice_range.stop, slice_range.step)
269278
)
270279

271-
print(roi_slices, combined_slices)
272-
273280
return tuple(combined_slices)
274281

275282
def __slices(self, roi, check_chunk_align=False):
@@ -299,7 +306,7 @@ def __slices(self, roi, check_chunk_align=False):
299306
]
300307

301308
combined_slice = self._combine_slices(roi_slices, *adapter_slices)
302-
309+
303310
return combined_slice
304311

305312
def __index(self, coordinate):

0 commit comments

Comments
 (0)