Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import net.imglib2.loops.LoopBuilder;
import net.imglib2.util.Intervals;

import net.imglib2.view.Views;
import org.scijava.function.Computers;

/**
Expand All @@ -44,7 +45,7 @@
* @implNote op name='transform.project', priority='99.'
*/
public class DefaultProjectParallel<T, V> implements
Computers.Arity3<RandomAccessibleInterval<T>, Computers.Arity1<Iterable<T>, V>, Integer, RandomAccessibleInterval<V>>
Computers.Arity3<RandomAccessibleInterval<T>, Computers.Arity1<? super RandomAccessibleInterval<T>, V>, Integer, RandomAccessibleInterval<V>>
{

/**
Expand All @@ -57,9 +58,8 @@ public class DefaultProjectParallel<T, V> implements
*/
@Override
public void compute(final RandomAccessibleInterval<T> input,
Computers.Arity1<Iterable<T>, V> op, Integer dim,
final RandomAccessibleInterval<V> output)
{
Computers.Arity1<? super RandomAccessibleInterval<T>, V> op, Integer dim,
final RandomAccessibleInterval<V> output) {
// TODO this first check is too simple, but for now ok
if (input.numDimensions() != output.numDimensions() + 1) //
throw new IllegalArgumentException(
Expand All @@ -69,22 +69,12 @@ public void compute(final RandomAccessibleInterval<T> input,
"ERROR: input image must contain dimension " + dim);

LoopBuilder.setImages(output, Intervals.positions(output)).multiThreaded()
.forEachChunk(chunk -> {
var chunkRA = input.randomAccess();
chunk.forEachPixel((pixel, position) -> {
for (var d = 0; d < input.numDimensions(); d++) {
if (d != dim) {
chunkRA.setPosition(position.getIntPosition(d - (d > dim ? 1
: 0)), d);
}
}

op.compute(new DimensionIterable(input.dimension(dim), dim, chunkRA),
pixel);

});

return null;
.forEachPixel((pixel, position) -> {
var ra = input;
for (var d = 0; d < position.numDimensions(); d++) {
ra = Views.hyperSlice(ra, d < dim ? 0 : 1, position.getIntPosition(d));
}
op.compute(ra, pixel);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@
* #L%
*/

package org.scijava.ops.image.transform.project.project;
package org.scijava.ops.image.transform.project;

import static org.junit.jupiter.api.Assertions.assertEquals;

import net.imglib2.FinalInterval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.view.Views;
import org.scijava.ops.image.AbstractOpTest;
import org.scijava.ops.image.util.TestImgGeneration;
import net.imglib2.RandomAccess;
Expand All @@ -50,7 +54,6 @@ public class ProjectTest extends AbstractOpTest {
private Img<UnsignedByteType> in;
private Img<UnsignedByteType> out1;
private Img<UnsignedByteType> out2;
private Computers.Arity1<Iterable<UnsignedByteType>, UnsignedByteType> op;

@BeforeEach
public void initImg() {
Expand All @@ -70,18 +73,11 @@ public void initImg() {

out1 = TestImgGeneration.unsignedByteArray(false, 10, 10);
out2 = TestImgGeneration.unsignedByteArray(false, 10, 10);

op = OpBuilder.matchComputer(ops, "stats.sum",
new Nil<Iterable<UnsignedByteType>>()
{}, new Nil<UnsignedByteType>() {});
}

@Test
public void testProjector() {
// TODO: uncomment when this Op is ported (assuming it will be?)
// ops.run(DefaultProjectParallel.class, out1, in, op, PROJECTION_DIM);
// ops.run(DefaultProjectParallel.class, out2, in, op, PROJECTION_DIM);
// testEquality(out1, out2);
var op = ops.op("stats.sum").input(in).outType(UnsignedByteType.class).computer();

ops.op("transform.project").input(in, op, PROJECTION_DIM).output(out1)
.compute();
Expand All @@ -90,6 +86,37 @@ public void testProjector() {
testEquality(out1, out2);
}

/**
* Ensures {@code "transform.project"} runs only within the passed interval.
*/
@Test
public void testInterval() {
// Set up img[x, y, z] = z
var input = ArrayImgs.unsignedBytes(10, 10, 10);
for(int x = 0; x < 10; x++) {
for(int y = 0; y < 10; y++) {
for(int z = 0; z < 10; z++) {
input.getAt(x, y, z).set(z);
}
}
}
// Create an interval containing 2<=z<=4
var intervaled = Views.interval(input, new FinalInterval(new long[] {0, 0, 2}, new long[] {10, 10, 4}));

// Project on the interval
var out = ArrayImgs.unsignedBytes(10, 10);
var op = ops.op("stats.sum").input(intervaled).outType(UnsignedByteType.class).computer();
ops.op("transform.project").input(intervaled, op, PROJECTION_DIM).output(out).compute();

// Assert that the projection (summation) only covered z=2, z=3, z=4
var outCursor = out.cursor();
while (outCursor.hasNext()) {
// 2 + 3 + 4 = 9
assertEquals(9, outCursor.next().get());
}

}

private void testEquality(final Img<UnsignedByteType> img1,
final Img<UnsignedByteType> img2)
{
Expand Down
Loading