Skip to content

Commit 113841f

Browse files
authored
Merge pull request #238 from imagej/dim-order-kwargs-tests
Enable `dim_order` kwargs for direct image conversions
2 parents a5544fa + 799113d commit 113841f

7 files changed

+428
-251
lines changed

doc/06-Working-with-Images.ipynb

+154-98
Large diffs are not rendered by default.

src/imagej/__init__.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ def sync_image(self, imp: "jc.ImagePlus" = None):
419419
pixels = imp.getProcessor().getPixels()
420420
stack.setPixels(pixels, imp.getCurrentSlice())
421421

422-
def to_dataset(self, data):
422+
def to_dataset(self, data, dim_order=None):
423423
"""Convert the data into an ImageJ2 Dataset.
424424
425425
Converts a Python image (e.g. xarray or numpy array) or Java image (e.g.
@@ -428,7 +428,6 @@ def to_dataset(self, data):
428428
:param data: Image object to be converted to Dataset.
429429
:return: A net.imagej.Dataset.
430430
"""
431-
dim_order = None
432431
if sj.isjava(data):
433432
if dim_order:
434433
_logger.warning(
@@ -447,7 +446,7 @@ def to_dataset(self, data):
447446

448447
raise TypeError(f"Type not supported: {type(data)}")
449448

450-
def to_img(self, data):
449+
def to_img(self, data, dim_order=None):
451450
"""Convert the data into an ImgLib2 Img.
452451
453452
Converts a Python image (e.g. xarray or numpy array) or Java image (e.g.
@@ -456,7 +455,6 @@ def to_img(self, data):
456455
:param data: Image object to be converted to Img.
457456
:return: A net.imglib2.img.Img.
458457
"""
459-
dim_order = None
460458
if sj.isjava(data):
461459
if dim_order:
462460
_logger.warning(
@@ -500,7 +498,7 @@ def to_java(self, data, **hints):
500498

501499
return sj.to_java(data, **hints)
502500

503-
def to_xarray(self, data):
501+
def to_xarray(self, data, dim_order=None):
504502
"""Convert the data into an ImgLib2 Img.
505503
506504
Converts a Python image (e.g. xarray or numpy array) or Java image (e.g.
@@ -509,21 +507,24 @@ def to_xarray(self, data):
509507
:param data: Image object to be converted to xarray.DataArray.
510508
:return: An xarray.DataArray.
511509
"""
512-
dim_order = None
513510
if sj.isjava(data):
511+
if dim_order:
512+
_logger.warning(f"Conversion hints are not supported for {type(data)}.")
513+
if isinstance(data, jc.ImagePlus):
514+
data = convert.imageplus_to_imgplus(self._ij, data)
514515
if convert.supports_java_to_xarray(self._ij, data):
515-
if dim_order:
516-
_logger.warning(
517-
f"Conversion hints are not supported for {type(data)}."
518-
)
519516
return convert.java_to_xarray(self._ij, data)
517+
if convert.supports_java_to_ndarray(self._ij, data):
518+
return convert.ndarray_to_xarray(
519+
convert.java_to_ndarray(self._ij, data)
520+
)
520521

521522
if images.is_xarraylike(data):
522523
return convert._rename_xarray_dims(data, dim_order)
523524
if images.is_arraylike(data):
524525
return convert.ndarray_to_xarray(data, dim_order)
525526

526-
return TypeError(f"Type not supported: {type(data)}.")
527+
raise TypeError(f"Type not supported: {type(data)}.")
527528

528529
# -- Deprecated methods --
529530

src/imagej/convert.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,7 @@ def ndarray_to_xarray(narr: np.ndarray, dim_order=None) -> xr.DataArray:
143143
assert images.is_arraylike(narr)
144144
if dim_order:
145145
# check dim length
146-
if narr.ndim != len(dim_order):
147-
raise ValueError(
148-
f"Expected {narr.ndim} dimensions but got {len(dim_order)}."
149-
)
146+
dim_order = dims._validate_dim_order(dim_order, narr.shape)
150147
return xr.DataArray(narr, dims=dim_order)
151148
return xr.DataArray(narr)
152149

@@ -557,8 +554,7 @@ def _rename_xarray_dims(xarr, new_dims: Sequence[str]):
557554
if not new_dims:
558555
return xarr
559556
# check dim length
560-
if xarr.ndim != len(new_dims):
561-
raise ValueError(f"Expected {xarr.ndim} dimensions but got {len(new_dims)}.")
557+
new_dims = dims._validate_dim_order(new_dims, xarr.shape)
562558
dim_map = {}
563559
for i in range(xarr.ndim):
564560
dim_map[curr_dims[i]] = new_dims[i]

src/imagej/dims.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,13 @@ def _get_scale(axis):
284284
:return: The scale for this axis or None if it is a non-numeric scale.
285285
"""
286286
try:
287-
return axis.values[1] - axis.values[0]
287+
# HACK: This axis length check is a work around for singleton dimensions.
288+
# You can't calculate the slope of a singleton dimension.
289+
# This section will be removed when axis-scale-logic is merged.
290+
if len(axis) <= 1:
291+
return 1
292+
else:
293+
return axis.values[1] - axis.values[0]
288294
except TypeError:
289295
return None
290296

@@ -397,6 +403,27 @@ def _convert_dims(dimensions: List[str], direction: str) -> List[str]:
397403
return dimensions
398404

399405

406+
def _validate_dim_order(dim_order: List[str], shape: tuple) -> List[str]:
407+
"""
408+
Validate a List of dimensions. If the dimension list is smaller
409+
fill the rest of the list with "dim_n" (following xarrray convention).
410+
411+
:param dim_order: List of dimensions (e.g. X, Y, Channel, Z, Time)
412+
:param shape: Shape image for the dimension order.
413+
:return: List with "dim_n" dimensions added to match shape length.
414+
"""
415+
dim_len = len(dim_order)
416+
shape_len = len(shape)
417+
if dim_len < shape_len:
418+
d = shape_len - dim_len
419+
for i in range(d):
420+
dim_order.append(f"dim_{i}")
421+
return dim_order
422+
if dim_len > shape_len:
423+
raise ValueError(f"Expected {shape_len} dimensions but got {dim_len}.")
424+
return dim_order
425+
426+
400427
def _has_axis(rai: "jc.RandomAccessibleInterval"):
401428
"""Check if a RandomAccessibleInterval has axes."""
402429
if sj.isjava(rai):

src/imagej/stack.py

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ def rai_slice(rai, imin: Tuple, imax: Tuple, istep: Tuple):
2525
dim_itr = range(len(shape))
2626

2727
for py_dim, j_dim in zip(dim_itr, dim_itr):
28-
2928
# Set minimum
3029
if imin[py_dim] is None:
3130
index = 0

0 commit comments

Comments
 (0)