2929
3030package org .scijava .ops .image .transform .project .project ;
3131
32- import java .util .Iterator ;
3332
34- import net .imglib2 .RandomAccess ;
33+ import net .imglib2 .FinalInterval ;
3534import net .imglib2 .RandomAccessibleInterval ;
3635import net .imglib2 .loops .LoopBuilder ;
3736import net .imglib2 .util .Intervals ;
3837
38+ import net .imglib2 .view .Views ;
3939import org .scijava .function .Computers ;
4040
4141/**
42- * @param <T>
43- * @param <V>
44- * @implNote op name='transform.project', priority='99.'
42+ * <b>Projection</b> is the act of creating 1-dimensional slices of an n-dimensional image,
43+ * reducing that slice down to a single value, and combining those images back into a (n-1)-dimensional array
44+ * <p>
45+ * Note that this Op cannot be adapted because the output is necessarily of different dimensionality than the input.
46+ * </p>
47+ *
48+ * @param <T> the type of input image elements
49+ * @param <V> the type of output image elements
50+ * @implNote op name='transform.project', priority='99.', hints="adaptation.FORBIDDEN"
51+ * @see ProjectParallelFunction for an Op that creates its own output
4552 */
46- public class DefaultProjectParallel <T , V > implements
47- Computers .Arity3 <RandomAccessibleInterval <T >, Computers .Arity1 <Iterable <T >, V >, Integer , RandomAccessibleInterval <V >>
53+ public class ProjectParallelComputer <T , V > implements
54+ Computers .Arity3 <
55+ RandomAccessibleInterval <T >,
56+ Computers .Arity1 <? super RandomAccessibleInterval <T >, V >,
57+ Integer ,
58+ RandomAccessibleInterval <V >
59+ >
4860{
49-
5061 /**
51- * TODO
62+ * Projects {@code op} along 1-dimensional slices (along dimension {@code dim}) of {@code input}
5263 *
53- * @param input
54- * @param op
55- * @param dim
56- * @param output
64+ * @param input the input {@code n}-dimensional dataset
65+ * @param op the Op to project over {@code dim}
66+ * @param dim the dimension along {@code input} to project
67+ * @param output the output {@code n-1}-dimensional dataset
5768 */
5869 @ Override
5970 public void compute (final RandomAccessibleInterval <T > input ,
60- Computers .Arity1 <Iterable <T >, V > op , Integer dim ,
61- final RandomAccessibleInterval <V > output )
62- {
71+ Computers .Arity1 <? super RandomAccessibleInterval <T >, V > op , Integer dim ,
72+ final RandomAccessibleInterval <V > output ) {
6373 // TODO this first check is too simple, but for now ok
6474 if (input .numDimensions () != output .numDimensions () + 1 ) //
6575 throw new IllegalArgumentException (
@@ -70,61 +80,18 @@ public void compute(final RandomAccessibleInterval<T> input,
7080
7181 LoopBuilder .setImages (output , Intervals .positions (output )).multiThreaded ()
7282 .forEachChunk (chunk -> {
73- var chunkRA = input .randomAccess ();
83+ var min = new long [input .numDimensions ()];
84+ var max = new long [input .numDimensions ()];
85+ min [dim ] = input .min (dim );
86+ max [dim ] = input .max (dim );
7487 chunk .forEachPixel ((pixel , position ) -> {
75- for (var d = 0 ; d < input .numDimensions (); d ++) {
76- if (d != dim ) {
77- chunkRA .setPosition (position .getIntPosition (d - (d > dim ? 1
78- : 0 )), d );
79- }
88+ for (var d = 0 ; d < position .numDimensions (); d ++) {
89+ min [d >= dim ? d +1 : d ] = position .getLongPosition (d );
90+ max [d >= dim ? d +1 : d ] = position .getLongPosition (d );
8091 }
81-
82- op .compute (new DimensionIterable (input .dimension (dim ), dim , chunkRA ),
83- pixel );
84-
92+ op .compute (Views .interval (input , new FinalInterval (min , max )), pixel );
8593 });
86-
87- return null ;
94+ return chunk ;
8895 });
8996 }
90-
91- final class DimensionIterable implements Iterable <T > {
92-
93- private final long size ;
94- private final int dim ;
95- private final RandomAccess <T > access ;
96-
97- public DimensionIterable (final long size , final int dim ,
98- final RandomAccess <T > access )
99- {
100- this .size = size ;
101- this .dim = dim ;
102- this .access = access ;
103- }
104-
105- @ Override
106- public Iterator <T > iterator () {
107- return new Iterator <T >() {
108-
109- int k = -1 ;
110-
111- @ Override
112- public boolean hasNext () {
113- return k < size - 1 ;
114- }
115-
116- @ Override
117- public T next () {
118- k ++;
119- access .setPosition (k , dim );
120- return access .get ();
121- }
122-
123- @ Override
124- public void remove () {
125- throw new UnsupportedOperationException ("Not supported" );
126- }
127- };
128- }
129- }
13097}
0 commit comments