Skip to content

Commit f68ff7a

Browse files
committed
ImgMath: refactored formula constructor into class Compute,
invoked from ImgMath.compute static methods.
1 parent f5633d5 commit f68ff7a

File tree

3 files changed

+195
-218
lines changed

3 files changed

+195
-218
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package net.imglib2.algorithm.math;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.LinkedList;
6+
7+
import net.imglib2.Cursor;
8+
import net.imglib2.RandomAccessibleInterval;
9+
import net.imglib2.algorithm.math.abstractions.IBinaryFunction;
10+
import net.imglib2.algorithm.math.abstractions.IFunction;
11+
import net.imglib2.algorithm.math.abstractions.ITrinaryFunction;
12+
import net.imglib2.algorithm.math.abstractions.IUnaryFunction;
13+
import net.imglib2.algorithm.math.abstractions.Util;
14+
import net.imglib2.converter.Converter;
15+
import net.imglib2.type.numeric.RealType;
16+
import net.imglib2.view.Views;
17+
18+
public class Compute
19+
{
20+
private final IFunction operation;
21+
private final Converter< RealType< ? >, RealType< ? > > converter;
22+
23+
public Compute( final IFunction operation )
24+
{
25+
this( operation,
26+
new Converter< RealType< ? >, RealType< ? > >()
27+
{
28+
@Override
29+
public final void convert( final RealType< ? > input, final RealType< ? > output) {
30+
output.setReal( input.getRealDouble() );
31+
}
32+
});
33+
}
34+
35+
public Compute(
36+
final IFunction operation,
37+
final Converter< RealType< ? >, RealType< ? > > converter
38+
)
39+
{
40+
this.operation = operation;
41+
this.converter = converter;
42+
}
43+
44+
public < O extends RealType< O > > RandomAccessibleInterval< O > into( final RandomAccessibleInterval< O > target )
45+
{
46+
// Recursive copy: initializes interval iterators
47+
final IFunction f = this.operation.copy();
48+
// Set temporary computation holders
49+
final O scrap = target.randomAccess().get().createVariable();
50+
f.setScrap( scrap );
51+
52+
final boolean compatible_iteration_order = this.setup( f, converter );
53+
54+
// Check compatible iteration order and dimensions
55+
if ( compatible_iteration_order )
56+
{
57+
// Evaluate function for every pixel
58+
for ( final O output : Views.iterable( target ) )
59+
f.eval( output );
60+
}
61+
else
62+
{
63+
// Incompatible iteration order
64+
final Cursor< O > cursor = Views.iterable( target ).cursor();
65+
66+
while ( cursor.hasNext() )
67+
{
68+
cursor.fwd();
69+
f.eval( cursor.get(), cursor );
70+
}
71+
}
72+
73+
return target;
74+
}
75+
76+
@SuppressWarnings({ "rawtypes", "unchecked" })
77+
private boolean setup( final IFunction f, final Converter< ?, ? > converter )
78+
{
79+
final LinkedList< IFunction > ops = new LinkedList<>();
80+
ops.add( f );
81+
82+
// child-parent map
83+
final HashMap< IFunction, IFunction > cp = new HashMap<>();
84+
85+
// Collect images to later check their iteration order
86+
final LinkedList< RandomAccessibleInterval< ? > > images = new LinkedList<>();
87+
88+
// Collect Var instances to check that each corresponds to an upstream Let
89+
final ArrayList< Var > vars = new ArrayList<>();
90+
91+
IFunction parent = null;
92+
93+
// Iterate into the nested operations
94+
while ( ! ops.isEmpty() )
95+
{
96+
final IFunction op = ops.removeFirst();
97+
cp.put( op, parent );
98+
parent = op;
99+
100+
if ( op instanceof IterableImgSource )
101+
{
102+
final IterableImgSource iis = ( IterableImgSource )op;
103+
// Side effect: set the converter from input to output types
104+
iis.setConverter( converter );
105+
images.addLast( iis.rai );
106+
}
107+
else if ( op instanceof IUnaryFunction )
108+
{
109+
ops.addLast( ( ( IUnaryFunction )op ).getFirst() );
110+
111+
if ( op instanceof IBinaryFunction )
112+
{
113+
ops.addLast( ( ( IBinaryFunction )op ).getSecond() );
114+
115+
if ( op instanceof ITrinaryFunction )
116+
{
117+
ops.addLast( ( ( ITrinaryFunction )op ).getThird() );
118+
}
119+
}
120+
}
121+
else if ( op instanceof Var )
122+
{
123+
final Var var = ( Var )op;
124+
vars.add( var );
125+
}
126+
}
127+
128+
// Check Vars: are they all using names declared in upstream Lets
129+
all: for ( final Var var : vars )
130+
{
131+
parent = var;
132+
while ( null != ( parent = cp.get( parent ) ) )
133+
{
134+
if ( parent instanceof Let )
135+
{
136+
Let let = ( Let )parent;
137+
if ( let.varName != var.name )
138+
continue;
139+
// Else, found: Var is in use
140+
continue all;
141+
}
142+
}
143+
// No upstream Let found
144+
throw new RuntimeException( "The Var(\"" + var.name + "\") does not read from any upstream Let. " );
145+
}
146+
147+
return Util.compatibleIterationOrder( images );
148+
}
149+
}

src/main/java/net/imglib2/algorithm/math/ImgMath.java

Lines changed: 5 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
*
3131
* RandomAccessibleInterval<O> result = ...
3232
*
33-
* new ImgMath<A, O>( Div<O>( Max<O>( img1, img2, img3 ), 3.0 ) ).into( result );
33+
* compute( div( max( img1, img2, img3 ), 3.0 ) ).into( result );
3434
* }
3535
* </pre>
3636
*
@@ -43,144 +43,14 @@
4343
*/
4444
public class ImgMath
4545
{
46-
private final IFunction operation;
47-
private final Converter< RealType< ? >, RealType< ? > > converter;
48-
49-
public ImgMath( final IFunction operation )
50-
{
51-
this( operation,
52-
new Converter< RealType< ? >, RealType< ? > >()
53-
{
54-
@Override
55-
public final void convert( final RealType< ? > input, final RealType< ? > output) {
56-
output.setReal( input.getRealDouble() );
57-
}
58-
});
59-
}
60-
61-
public ImgMath(
62-
final IFunction operation,
63-
final Converter< RealType< ? >, RealType< ? > > converter
64-
)
65-
{
66-
this.operation = operation;
67-
this.converter = converter;
68-
}
69-
70-
public < O extends RealType< O > > RandomAccessibleInterval< O > into( final RandomAccessibleInterval< O > target )
71-
{
72-
// Recursive copy: initializes interval iterators
73-
final IFunction f = this.operation.copy();
74-
// Set temporary computation holders
75-
final O scrap = target.randomAccess().get().createVariable();
76-
f.setScrap( scrap );
77-
78-
final boolean compatible_iteration_order = this.setup( f, converter );
79-
80-
// Check compatible iteration order and dimensions
81-
if ( compatible_iteration_order )
82-
{
83-
// Evaluate function for every pixel
84-
for ( final O output : Views.iterable( target ) )
85-
f.eval( output );
86-
}
87-
else
88-
{
89-
// Incompatible iteration order
90-
final Cursor< O > cursor = Views.iterable( target ).cursor();
91-
92-
while ( cursor.hasNext() )
93-
{
94-
cursor.fwd();
95-
f.eval( cursor.get(), cursor );
96-
}
97-
}
98-
99-
return target;
100-
}
101-
102-
@SuppressWarnings({ "rawtypes", "unchecked" })
103-
private boolean setup( final IFunction f, final Converter< ?, ? > converter )
104-
{
105-
final LinkedList< IFunction > ops = new LinkedList<>();
106-
ops.add( f );
107-
108-
// child-parent map
109-
final HashMap< IFunction, IFunction > cp = new HashMap<>();
110-
111-
// Collect images to later check their iteration order
112-
final LinkedList< RandomAccessibleInterval< ? > > images = new LinkedList<>();
113-
114-
// Collect Var instances to check that each corresponds to an upstream Let
115-
final ArrayList< Var > vars = new ArrayList<>();
116-
117-
IFunction parent = null;
118-
119-
// Iterate into the nested operations
120-
while ( ! ops.isEmpty() )
121-
{
122-
final IFunction op = ops.removeFirst();
123-
cp.put( op, parent );
124-
parent = op;
125-
126-
if ( op instanceof IterableImgSource )
127-
{
128-
final IterableImgSource iis = ( IterableImgSource )op;
129-
// Side effect: set the converter from input to output types
130-
iis.setConverter( converter );
131-
images.addLast( iis.rai );
132-
}
133-
else if ( op instanceof IUnaryFunction )
134-
{
135-
ops.addLast( ( ( IUnaryFunction )op ).getFirst() );
136-
137-
if ( op instanceof IBinaryFunction )
138-
{
139-
ops.addLast( ( ( IBinaryFunction )op ).getSecond() );
140-
141-
if ( op instanceof ITrinaryFunction )
142-
{
143-
ops.addLast( ( ( ITrinaryFunction )op ).getThird() );
144-
}
145-
}
146-
}
147-
else if ( op instanceof Var )
148-
{
149-
final Var var = ( Var )op;
150-
vars.add( var );
151-
}
152-
}
153-
154-
// Check Vars: are they all using names declared in upstream Lets
155-
all: for ( final Var var : vars )
156-
{
157-
parent = var;
158-
while ( null != ( parent = cp.get( parent ) ) )
159-
{
160-
if ( parent instanceof Let )
161-
{
162-
Let let = ( Let )parent;
163-
if ( let.varName != var.name )
164-
continue;
165-
// Else, found: Var is in use
166-
continue all;
167-
}
168-
}
169-
// No upstream Let found
170-
throw new RuntimeException( "The Var(\"" + var.name + "\") does not read from any upstream Let. " );
171-
}
172-
173-
return Util.compatibleIterationOrder( images );
174-
}
175-
176-
static public final ImgMath compute( final IFunction operation )
46+
static public final Compute compute( final IFunction operation )
17747
{
178-
return new ImgMath( operation );
48+
return new Compute( operation );
17949
}
18050

181-
static public final ImgMath compute( final IFunction operation, final Converter< RealType< ? >, RealType< ? > > converter )
51+
static public final Compute compute( final IFunction operation, final Converter< RealType< ? >, RealType< ? > > converter )
18252
{
183-
return new ImgMath( operation, converter );
53+
return new Compute( operation, converter );
18454
}
18555

18656
static public final Add add( final Object o1, final Object o2 )

0 commit comments

Comments
 (0)