66import java .util .LinkedList ;
77
88import net .imglib2 .Cursor ;
9+ import net .imglib2 .RandomAccess ;
910import net .imglib2 .RandomAccessibleInterval ;
1011import net .imglib2 .algorithm .math .abstractions .IBinaryFunction ;
1112import net .imglib2 .algorithm .math .abstractions .IFunction ;
1213import net .imglib2 .algorithm .math .abstractions .ITrinaryFunction ;
1314import net .imglib2 .algorithm .math .abstractions .IUnaryFunction ;
1415import net .imglib2 .algorithm .math .abstractions .OFunction ;
1516import net .imglib2 .algorithm .math .abstractions .Util ;
17+ import net .imglib2 .algorithm .math .execution .FunctionCursor ;
18+ import net .imglib2 .algorithm .math .execution .FunctionCursorIncompatibleOrder ;
19+ import net .imglib2 .algorithm .math .execution .FunctionRandomAccess ;
1620import net .imglib2 .converter .Converter ;
1721import net .imglib2 .type .numeric .RealType ;
1822import net .imglib2 .view .Views ;
@@ -21,7 +25,7 @@ public class Compute
2125{
2226 private final IFunction operation ;
2327 private final boolean compatible_iteration_order ;
24-
28+
2529 /**
2630 * Validate the {code operation}.
2731 *
@@ -71,14 +75,7 @@ public < O extends RealType< O > > RandomAccessibleInterval< O > into(
7175 )
7276 {
7377 if ( null == converter )
74- converter = new Converter < RealType < ? >, O >()
75- {
76- @ Override
77- public final void convert ( final RealType < ? > input , final O output )
78- {
79- output .setReal ( input .getRealDouble () );
80- }
81- };
78+ converter = Util .genericRealTypeConverter ();
8279
8380 // Recursive copy: initializes interval iterators and sets temporary computation holder
8481 final OFunction < O > f = this .operation .reInit (
@@ -115,6 +112,7 @@ private boolean validate( final IFunction f )
115112
116113 // child-parent map
117114 final HashMap < IFunction , IFunction > cp = new HashMap <>();
115+ cp .put ( f , null );
118116
119117 // Collect images to later check their iteration order
120118 final LinkedList < RandomAccessibleInterval < ? > > images = new LinkedList <>();
@@ -125,26 +123,26 @@ private boolean validate( final IFunction f )
125123 // Collect Let instances to check that their declared variables are used
126124 final HashSet < Let > lets = new HashSet <>();
127125
128- IFunction parent = null ;
129-
130- // Iterate into the nested operations
126+ // Iterate into the nested operations, depth-first
131127 while ( ! ops .isEmpty () )
132128 {
133129 final IFunction op = ops .removeFirst ();
134- cp .put ( op , parent );
135- parent = op ;
136130
137131 if ( op instanceof ImgSource )
138132 {
139- images .addLast ( ( ( ImgSource < ? > )op ).getRandomAccessibleInterval () );
133+ images .addFirst ( ( ( ImgSource < ? > )op ).getRandomAccessibleInterval () );
140134 }
141135 else if ( op instanceof IUnaryFunction )
142136 {
143- ops .addLast ( ( ( IUnaryFunction )op ).getFirst () );
137+ final IFunction first = ( ( IUnaryFunction )op ).getFirst ();
138+ ops .addFirst ( first );
139+ cp .put ( first , op );
144140
145141 if ( op instanceof IBinaryFunction )
146142 {
147- ops .addLast ( ( ( IBinaryFunction )op ).getSecond () );
143+ final IFunction second = ( ( IBinaryFunction )op ).getSecond ();
144+ ops .add ( 1 , second );
145+ cp .put ( second , op );
148146
149147 if ( op instanceof Let )
150148 {
@@ -153,7 +151,9 @@ else if ( op instanceof IUnaryFunction )
153151
154152 if ( op instanceof ITrinaryFunction )
155153 {
156- ops .addLast ( ( ( ITrinaryFunction )op ).getThird () );
154+ final IFunction third = ( ( ITrinaryFunction )op ).getThird ();
155+ ops .add ( 2 , third );
156+ cp .put ( third , op );
157157 }
158158 }
159159 }
@@ -168,16 +168,16 @@ else if ( op instanceof Var )
168168 final HashSet < Let > used = new HashSet <>();
169169 all : for ( final Var var : vars )
170170 {
171- parent = var ;
171+ IFunction parent = var ;
172172 while ( null != ( parent = cp .get ( parent ) ) )
173173 {
174174 if ( parent instanceof Let )
175175 {
176- Let let = ( Let )parent ;
176+ final Let let = ( Let )parent ;
177177 if ( let .getVarName () != var .getName () )
178178 continue ;
179179 // Else, found: Var is in use
180- used .add ( let );
180+ used .add ( let ); // might already be in used
181181 continue all ;
182182 }
183183 }
@@ -200,4 +200,43 @@ else if ( op instanceof Var )
200200
201201 return Util .compatibleIterationOrder ( images );
202202 }
203+
204+ public < O extends RealType < O > > RandomAccess < O > randomAccess ( final O outputType , final Converter < RealType < ? >, O > converter )
205+ {
206+ return new FunctionRandomAccess < O >( this .operation , outputType , converter );
207+ }
208+
209+ public < O extends RealType < O > > RandomAccess < O > randomAccess ( final O outputType )
210+ {
211+ return new FunctionRandomAccess < O >( this .operation , outputType , Util .genericRealTypeConverter () );
212+ }
213+
214+ /** Returns a {@link RandomAccess} with the same type as the first input image found. */
215+ public < O extends RealType < O > > RandomAccess < O > randomAccess ()
216+ {
217+ @ SuppressWarnings ("unchecked" )
218+ final RandomAccessibleInterval < O > img = ( RandomAccessibleInterval < O > )Util .findFirstImg ( operation );
219+ final O outputType = img .randomAccess ().get ().createVariable ();
220+ return new FunctionRandomAccess < O >( this .operation , outputType , Util .genericRealTypeConverter () );
221+ }
222+
223+ public < O extends RealType < O > > Cursor < O > cursor ( final O outputType , final Converter < RealType < ? >, O > converter )
224+ {
225+ if ( this .compatible_iteration_order )
226+ return new FunctionCursor < O >( this .operation , outputType , converter );
227+ return new FunctionCursorIncompatibleOrder < O >( this .operation , outputType , converter );
228+ }
229+
230+ public < O extends RealType < O > > Cursor < O > cursor ( final O outputType )
231+ {
232+ return this .cursor ( outputType , Util .genericRealTypeConverter () );
233+ }
234+
235+ /** Returns a {@link Cursor} with the same type as the first input image found. */
236+ public < O extends RealType < O > > Cursor < O > cursor ()
237+ {
238+ @ SuppressWarnings ("unchecked" )
239+ final RandomAccessibleInterval < O > img = ( RandomAccessibleInterval < O > )Util .findFirstImg ( operation );
240+ return this .cursor ( img .randomAccess ().get ().createVariable () );
241+ }
203242}
0 commit comments