Skip to content

Commit 79c670d

Browse files
ctruedenclaude
andcommitted
Add unit tests for the ImgLib2 <-> NDArray converters
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7e0f1f9 commit 79c670d

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* #%L
3+
* Python scripting language plugin to be used via scyjava.
4+
* %%
5+
* Copyright (C) 2021 - 2025 SciJava developers.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
30+
31+
package org.scijava.plugins.scripting.appose.python;
32+
33+
import static org.junit.Assert.assertArrayEquals;
34+
import static org.junit.Assert.assertEquals;
35+
import static org.junit.Assert.assertFalse;
36+
import static org.junit.Assert.assertNotNull;
37+
import static org.junit.Assert.assertSame;
38+
import static org.junit.Assert.assertTrue;
39+
40+
import java.io.File;
41+
42+
import net.imglib2.appose.ShmImg;
43+
import net.imglib2.img.Img;
44+
import net.imglib2.img.array.ArrayImgs;
45+
import net.imglib2.img.planar.PlanarImg;
46+
import net.imglib2.type.numeric.integer.UnsignedByteType;
47+
import net.imglib2.type.numeric.real.FloatType;
48+
import net.imglib2.util.Intervals;
49+
import net.imglib2.view.Views;
50+
51+
import org.apposed.appose.NDArray;
52+
import org.junit.After;
53+
import org.junit.Before;
54+
import org.junit.Test;
55+
import org.scijava.Context;
56+
import org.scijava.convert.ConvertService;
57+
58+
/**
59+
* Tests {@link RAIToNDArrayConverter} and {@link NDArrayToImgConverter}.
60+
*
61+
* @author Curtis Rueden
62+
*/
63+
public class ConvertersTest {
64+
65+
private Context context;
66+
private ConvertService convertService;
67+
68+
@Before
69+
public void setUp() {
70+
context = new Context();
71+
convertService = context.service(ConvertService.class);
72+
}
73+
74+
@After
75+
public void tearDown() {
76+
context.dispose();
77+
}
78+
79+
@Test
80+
public void testRoundTrip() {
81+
final byte[] data = { 1, 2, 3, 4, 5, 6 };
82+
final Img<UnsignedByteType> img = ArrayImgs.unsignedBytes(data, 3, 2);
83+
assertTrue(convertService.supports(img, NDArray.class));
84+
85+
try (final NDArray nd = convertService.convert(img, NDArray.class)) {
86+
assertNotNull(nd);
87+
assertEquals(NDArray.DType.UINT8, nd.dType());
88+
assertArrayEquals(new int[] { 3, 2 },
89+
nd.shape().toIntArray(NDArray.Shape.Order.F_ORDER));
90+
91+
assertTrue(convertService.supports(nd, Img.class));
92+
final Img<?> result = convertService.convert(nd, Img.class);
93+
assertTrue(result instanceof PlanarImg);
94+
assertTrue(result.firstElement() instanceof UnsignedByteType);
95+
assertArrayEquals(new long[] { 3, 2 }, Intervals.dimensionsAsLongArray(result));
96+
@SuppressWarnings("unchecked")
97+
final Img<UnsignedByteType> typed = (Img<UnsignedByteType>) result;
98+
int i = 0;
99+
for (final UnsignedByteType t : Views.flatIterable(typed)) {
100+
assertEquals(data[i++], t.get());
101+
}
102+
}
103+
}
104+
105+
@Test
106+
public void testConvertedImgOutlivesNDArray() {
107+
final NDArray nd = convertService.convert(ArrayImgs.floats(
108+
new float[] { 1.5f, -2 }, 2), NDArray.class);
109+
@SuppressWarnings("unchecked")
110+
final Img<FloatType> result = convertService.convert(nd, Img.class);
111+
nd.close();
112+
// The result is a copy, so it must remain usable after closing.
113+
assertEquals(1.5f, result.firstElement().get(), 0);
114+
}
115+
116+
@Test
117+
public void testShmImgIsNotCopied() {
118+
final ShmImg<UnsignedByteType> img =
119+
ShmImg.copyOf(ArrayImgs.unsignedBytes(4, 4));
120+
try (final NDArray nd = img.ndArray()) {
121+
assertSame(nd, convertService.convert(img, NDArray.class));
122+
}
123+
}
124+
125+
@Test
126+
public void testNonImagesAreNotConverted() {
127+
for (final Object o : new Object[] { "text", 5, 2.5, true,
128+
new File("x.tif"), new int[] { 1, 2, 3 } })
129+
{
130+
assertFalse(o.getClass().getName(),
131+
convertService.supports(o, NDArray.class));
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)