Skip to content

Commit 7ef2e15

Browse files
authored
Fix convert zarr (#1405)
* relax layer name constraints * revert attachment check * revert attachment eq * diag * better num_channel detection * fix convert-zarr * changelog * wkw -> wk
1 parent baaa337 commit 7ef2e15

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

webknossos/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ For upgrade instructions, please check the respective _Breaking Changes_ section
3333
- In the methods `Dataset.trigger_dataset_import`, `Dataset.trigger_reload_in_datastore` and `RemoteDataset.trigger_reload_in_datastore` the parameter `token` was deprecated (use an authenticated webknossos context instead). In `RemoteDataset.download_mesh` and `RemoteSegmentationLayer.download_mesh` the parameter `token` was renamed to `sharing_token` to clarify that it is meant for a dataset sharing token. Otherwise, use an authenticated webknossos context instead. [#1400](https://github.com/scalableminds/webknossos-libs/pull/1400)
3434

3535
### Fixed
36+
- Fixed bug in convert-zarr CLI command. [#1405](https://github.com/scalableminds/webknossos-libs/pull/1405)
3637
- Fixed a bug where user tokens would sometimes show up in the logging as a GET parameter. [#1400](https://github.com/scalableminds/webknossos-libs/pull/1400)
3738

3839

webknossos/tests/test_cli.py

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
from contextlib import contextmanager
99
from math import ceil
1010
from tempfile import TemporaryDirectory
11+
from typing import Literal
1112

1213
import numpy as np
1314
import pytest
15+
import tensorstore as ts
1416
from PIL import Image
1517
from typer.testing import CliRunner
1618
from upath import UPath
@@ -258,7 +260,7 @@ def test_convert() -> None:
258260

259261
with tmp_cwd():
260262
origin_path = TESTDATA_DIR / "tiff"
261-
wkw_path = UPath("wkw_from_tiff_simple")
263+
wkw_path = UPath("wk_from_tiff_simple")
262264

263265
result = runner.invoke(
264266
app,
@@ -281,7 +283,7 @@ def test_convert_single_file() -> None:
281283

282284
with tmp_cwd():
283285
origin_path = TESTDATA_DIR / "tiff" / "test.0000.tiff"
284-
wkw_path = UPath("wkw_from_tiff_single_file")
286+
wkw_path = UPath("wk_from_tiff_single_file")
285287

286288
result = runner.invoke(
287289
app,
@@ -303,7 +305,7 @@ def test_convert_with_all_params() -> None:
303305

304306
with tmp_cwd():
305307
origin_path = TESTDATA_DIR / "tiff_with_different_shapes"
306-
wkw_path = UPath(f"wkw_from_{origin_path.name}")
308+
wkw_path = UPath(f"wk_from_{origin_path.name}")
307309
with pytest.warns(UserWarning, match="Some images are larger than expected,"):
308310
result = runner.invoke(
309311
app,
@@ -314,7 +316,7 @@ def test_convert_with_all_params() -> None:
314316
"--data-format",
315317
"wkw",
316318
"--name",
317-
"wkw_from_tiff",
319+
"wk_from_tiff",
318320
"--compress",
319321
str(origin_path),
320322
str(wkw_path),
@@ -333,7 +335,7 @@ def test_convert_raw() -> None:
333335
origin_path.write_bytes(
334336
np.array([[0.2, 0.4], [0.6, 0.8]], dtype="float32").tobytes(order="F")
335337
)
336-
out_path = UPath(f"wkw_from_{origin_path.name}")
338+
out_path = UPath(f"wk_from_{origin_path.name}")
337339
result = runner.invoke(
338340
app,
339341
[
@@ -363,6 +365,62 @@ def test_convert_raw() -> None:
363365
)
364366

365367

368+
@pytest.mark.parametrize("zarr_format", ["zarr", "zarr3"])
369+
def test_convert_zarr(zarr_format: Literal["zarr", "zarr3"]) -> None:
370+
"""Tests the functionality of convert-zarr subcommand."""
371+
372+
with tmp_cwd():
373+
test_data = np.arange(32 * 32 * 32, dtype="uint16").reshape(32, 32, 32)
374+
375+
origin_path = UPath("test.zarr")
376+
metadata = (
377+
{
378+
"shape": [32, 32, 32],
379+
"chunk_grid": {
380+
"name": "regular",
381+
"configuration": {"chunk_shape": [32, 32, 32]},
382+
},
383+
"data_type": "uint16",
384+
}
385+
if zarr_format == "zarr3"
386+
else {
387+
"shape": [32, 32, 32],
388+
"chunks": [32, 32, 32],
389+
"dtype": "<u2",
390+
}
391+
)
392+
393+
ts.open(
394+
{
395+
"driver": zarr_format,
396+
"kvstore": {"driver": "file", "path": str(origin_path)},
397+
"metadata": metadata,
398+
"create": True,
399+
}
400+
).result().write(test_data).result()
401+
402+
out_path = UPath(f"wk_from_{origin_path.name}")
403+
result = runner.invoke(
404+
app,
405+
[
406+
"convert-zarr",
407+
"--voxel-size",
408+
"11.0,11.0,11.0",
409+
str(origin_path),
410+
str(out_path),
411+
],
412+
)
413+
414+
assert result.exit_code == 0, result.stdout
415+
assert (out_path / PROPERTIES_FILE_NAME).exists()
416+
417+
out_ds = Dataset.open(out_path)
418+
np.testing.assert_array_equal(
419+
out_ds.get_layer("color").get_finest_mag().read()[0],
420+
test_data,
421+
)
422+
423+
366424
@pytest.mark.use_proxay
367425
@pytest.mark.parametrize(
368426
"url",

webknossos/webknossos/cli/convert_zarr.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,12 @@
3737

3838

3939
def _try_open_zarr(path: UPath) -> tensorstore.TensorStore:
40-
try:
41-
return tensorstore.open(
42-
{"driver": "zarr3", "kvstore": {"driver": "file", "path": path}}
43-
).result()
44-
except tensorstore.TensorStoreError:
45-
return tensorstore.open(
46-
{"driver": "zarr", "kvstore": {"driver": "file", "path": path}}
47-
).result()
40+
return tensorstore.open(
41+
{
42+
"driver": "auto",
43+
"kvstore": {"driver": "file", "path": str(path)},
44+
}
45+
).result()
4846

4947

5048
def _zarr_chunk_converter(
@@ -86,7 +84,7 @@ def convert_zarr(
8684
ref_time = time.time()
8785

8886
file = _try_open_zarr(source_zarr_path)
89-
input_dtype: np.dtype = file.dtype
87+
input_dtype: np.dtype = file.dtype.numpy_dtype
9088
shape: tuple[int, ...] = file.domain.exclusive_max
9189

9290
wk_ds = Dataset(

0 commit comments

Comments
 (0)