11package net .imglib2 .algorithm .math ;
22
3+ import java .util .HashMap ;
34import java .util .Map ;
45
56import net .imglib2 .Localizable ;
67import net .imglib2 .algorithm .math .abstractions .ATrinaryFunction ;
78import net .imglib2 .algorithm .math .abstractions .Compare ;
89import net .imglib2 .algorithm .math .abstractions .IFunction ;
10+ import net .imglib2 .algorithm .math .abstractions .IVar ;
911import net .imglib2 .algorithm .math .optimizations .IfBoolean ;
1012import net .imglib2 .converter .Converter ;
1113import net .imglib2 .type .numeric .RealType ;
@@ -23,7 +25,7 @@ protected If( final RealType< ? > scrap, final IFunction f1, final IFunction f2,
2325 }
2426
2527 @ Override
26- public RealType < ? > eval ()
28+ public final RealType < ? > eval ()
2729 {
2830 return 0 != this .a .eval ().getRealFloat () ?
2931 // Then
@@ -33,7 +35,7 @@ protected If( final RealType< ? > scrap, final IFunction f1, final IFunction f2,
3335 }
3436
3537 @ Override
36- public RealType < ? > eval ( final Localizable loc )
38+ public final RealType < ? > eval ( final Localizable loc )
3739 {
3840 return 0 != this .a .eval ().getRealFloat () ?
3941 // Then
@@ -43,14 +45,42 @@ protected If( final RealType< ? > scrap, final IFunction f1, final IFunction f2,
4345 }
4446
4547 @ Override
46- public If reInit ( final RealType < ? > tmp , final Map < String , RealType < ? > > bindings , final Converter <RealType <?>, RealType <?>> converter )
48+ public IFunction reInit (
49+ final RealType < ? > tmp ,
50+ final Map < String , RealType < ? > > bindings ,
51+ final Converter <RealType <?>, RealType <?>> converter ,
52+ final Map < IVar , IFunction > imgSources )
4753 {
54+ // Fix: if there is an ImgSource among the children of then (this.b) or else (this.c),
55+ // replace them with a Var, reading from a Let inserted as a parent of this If,
56+ // in order to guarantee that their iterators are advanced.
57+ final Map < IVar , IFunction > imgS ;
58+ if ( null == imgSources )
59+ imgS = new HashMap <>();
60+ else
61+ imgS = imgSources ; // There is an upstream If
62+
4863 // Optimization: reInit as IfBoolean if the first argument is a Compare.
4964 // Avoids having to set the output to 1 (true) or 0 (false),
5065 // and then having to read it out and compare it to zero to make a boolean,
5166 // instead returning a boolean directly.
67+ final IFunction instance ;
5268 if ( this .a instanceof Compare )
53- return new IfBoolean ( tmp .copy (), ( Compare ) this .a .reInit ( tmp , bindings , converter ), this .b .reInit ( tmp , bindings , converter ), this .c .reInit ( tmp , bindings , converter ) );
54- return new If ( tmp .copy (), this .a .reInit ( tmp , bindings , converter ), this .b .reInit ( tmp , bindings , converter ), this .c .reInit ( tmp , bindings , converter ) );
69+ instance = new IfBoolean ( tmp .copy (), ( Compare ) this .a .reInit ( tmp , bindings , converter , imgS ),
70+ this .b .reInit ( tmp , bindings , converter , imgS ), this .c .reInit ( tmp , bindings , converter , imgS ) );
71+ else
72+ instance = new If ( tmp .copy (), this .a .reInit ( tmp , bindings , converter , imgSources ),
73+ this .b .reInit ( tmp , bindings , converter , imgS ), this .c .reInit ( tmp , bindings , converter , imgS ) );
74+
75+ // Check if there was an upstream If, which has preference, or there aren't any imgSource downstream
76+ if ( null != imgSources || imgS .isEmpty () )
77+ return instance ;
78+
79+ // Return a Let that declares all Vars in imgS, recursively, and places this If as the innermost body
80+ Let let = null ;
81+ for ( final Map .Entry < IVar , IFunction > e : imgS .entrySet () )
82+ let = new Let ( e .getKey ().getScrap (), e .getKey ().getName (), e .getValue (), null == let ? instance : let );
83+
84+ return let ;
5585 }
56- }
86+ };
0 commit comments