Skip to content

Commit 846c116

Browse files
committed
fix and test Lazy generator
* correctly accept target intervals with non zero min * test behavior for both zeroMin and non-zeroMin intervals * rename Lazy.process(...) to Lazy.generate(...)
1 parent 460e0c2 commit 846c116

File tree

4 files changed

+160
-61
lines changed

4 files changed

+160
-61
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>net.imglib2</groupId>
1313
<artifactId>imglib2-algorithm</artifactId>
14-
<version>0.11.3-SNAPSHOT</version>
14+
<version>0.12.0-SNAPSHOT</version>
1515

1616
<name>ImgLib2 Algorithms</name>
1717
<description>Useful image processing algorithms.</description>

src/main/java/net/imglib2/algorithm/bspline/BSplineLazyCoefficientsInterpolatorFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public < R > ImgFactory< R > imgFactory( R type ) throws IncompatibleTypeExcepti
285285
@Override
286286
public Img< S > create( long[] dim, S type )
287287
{
288-
return Lazy.process( interval, blockSize, type, AccessFlags.setOf( AccessFlags.VOLATILE ), decomposition );
288+
return Lazy.generate( interval, blockSize, type, AccessFlags.setOf( AccessFlags.VOLATILE ), decomposition );
289289
}
290290
}
291291

src/main/java/net/imglib2/algorithm/lazy/Lazy.java

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* #%L
33
* ImgLib2: a general-purpose, multidimensional image processing library.
44
* %%
5-
* Copyright (C) 2009 - 2018 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld,
5+
* Copyright (C) 2009 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld,
66
* John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke,
77
* Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner,
88
* Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert,
@@ -11,13 +11,13 @@
1111
* %%
1212
* Redistribution and use in source and binary forms, with or without
1313
* modification, are permitted provided that the following conditions are met:
14-
*
14+
*
1515
* 1. Redistributions of source code must retain the above copyright notice,
1616
* this list of conditions and the following disclaimer.
1717
* 2. Redistributions in binary form must reproduce the above copyright notice,
1818
* this list of conditions and the following disclaimer in the documentation
1919
* and/or other materials provided with the distribution.
20-
*
20+
*
2121
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2222
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2323
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -62,18 +62,21 @@
6262
import net.imglib2.type.numeric.real.DoubleType;
6363
import net.imglib2.type.numeric.real.FloatType;
6464
import net.imglib2.util.Intervals;
65+
import net.imglib2.view.Views;
6566

6667
/**
67-
* Convenience methods to create lazy evaluated cached cell images with ops or consumers.
68-
*
69-
* Warning: this class or its functionality could be moved elsewhere in the near future, likely
70-
* imglib2-cache or imgli2-core.
68+
* Convenience methods to create lazy evaluated cached cell images with
69+
* consumers.
7170
*
72-
* @author Stephan Saalfeld &lt;saalfelds@janelia.hhmi.org&gt;
71+
* Warning: this class or its functionality could be moved elsewhere in the near
72+
* future, likely imglib2-cache or imgli2-core.
73+
*
74+
* @author Stephan Saalfeld
7375
*/
74-
public class Lazy {
75-
76-
private Lazy() {}
76+
public class Lazy
77+
{
78+
private Lazy()
79+
{}
7780

7881
/**
7982
* Create a memory {@link CachedCellImg} with a cell {@link Cache}.
@@ -84,28 +87,37 @@ private Lazy() {}
8487
* @param accessFlags
8588
* @return
8689
*/
87-
@SuppressWarnings({"unchecked", "rawtypes"})
88-
public static <T extends NativeType<T>> CachedCellImg<T, ?> createImg(
89-
final CellGrid grid,
90-
final Cache<Long, Cell<?>> cache,
91-
final T type,
92-
final Set<AccessFlags> accessFlags) {
90+
@SuppressWarnings( { "unchecked", "rawtypes" } )
91+
private static < T extends NativeType< T > > CachedCellImg< T, ? > createImg( final CellGrid grid, final Cache< Long, Cell< ? > > cache, final T type, final Set< AccessFlags > accessFlags )
92+
{
93+
final CachedCellImg< T, ? > img;
9394

94-
final CachedCellImg<T, ?> img;
95-
96-
if (GenericByteType.class.isInstance(type)) {
97-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(BYTE, accessFlags));
98-
} else if (GenericShortType.class.isInstance(type)) {
99-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(SHORT, accessFlags));
100-
} else if (GenericIntType.class.isInstance(type)) {
101-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(INT, accessFlags));
102-
} else if (GenericLongType.class.isInstance(type)) {
103-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(LONG, accessFlags));
104-
} else if (FloatType.class.isInstance(type)) {
105-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(FLOAT, accessFlags));
106-
} else if (DoubleType.class.isInstance(type)) {
107-
img = new CachedCellImg(grid, type, cache, ArrayDataAccessFactory.get(DOUBLE, accessFlags));
108-
} else {
95+
if ( GenericByteType.class.isInstance( type ) )
96+
{
97+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( BYTE, accessFlags ) );
98+
}
99+
else if ( GenericShortType.class.isInstance( type ) )
100+
{
101+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( SHORT, accessFlags ) );
102+
}
103+
else if ( GenericIntType.class.isInstance( type ) )
104+
{
105+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( INT, accessFlags ) );
106+
}
107+
else if ( GenericLongType.class.isInstance( type ) )
108+
{
109+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( LONG, accessFlags ) );
110+
}
111+
else if ( FloatType.class.isInstance( type ) )
112+
{
113+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( FLOAT, accessFlags ) );
114+
}
115+
else if ( DoubleType.class.isInstance( type ) )
116+
{
117+
img = new CachedCellImg( grid, type, cache, ArrayDataAccessFactory.get( DOUBLE, accessFlags ) );
118+
}
119+
else
120+
{
109121
img = null;
110122
}
111123
return img;
@@ -121,25 +133,29 @@ private Lazy() {}
121133
* @param loader
122134
* @return
123135
*/
124-
public static <T extends NativeType<T>> CachedCellImg<T, ?> createImg(
125-
final Interval targetInterval,
126-
final int[] blockSize,
127-
final T type,
128-
final Set<AccessFlags> accessFlags,
129-
final CellLoader<T> loader) {
136+
private static < T extends NativeType< T > > CachedCellImg< T, ? > createImg( final Interval targetInterval, final int[] blockSize, final T type, final Set< AccessFlags > accessFlags, final Consumer< RandomAccessibleInterval< T > > loader )
137+
{
138+
final long[] dimensions = Intervals.dimensionsAsLongArray( targetInterval );
139+
final CellGrid grid = new CellGrid( dimensions, blockSize );
130140

131-
final long[] dimensions = Intervals.dimensionsAsLongArray(targetInterval);
132-
final CellGrid grid = new CellGrid(dimensions, blockSize);
141+
final CellLoader< T > offsetLoader;
142+
if ( Views.isZeroMin( targetInterval ) )
143+
offsetLoader = loader::accept;
144+
else
145+
{
146+
final long[] offset = targetInterval.minAsLongArray();
147+
offsetLoader = cell -> loader.accept( Views.translate( cell, offset ) );
148+
}
133149

134-
@SuppressWarnings({"unchecked", "rawtypes"})
135-
final Cache<Long, Cell<?>> cache =
136-
new SoftRefLoaderCache().withLoader(LoadedCellCacheLoader.get(grid, loader, type, accessFlags));
150+
@SuppressWarnings( { "unchecked", "rawtypes" } )
151+
final Cache< Long, Cell< ? > > cache = new SoftRefLoaderCache().withLoader( LoadedCellCacheLoader.get( grid, offsetLoader, type, accessFlags ) );
137152

138-
return createImg(grid, cache, type, accessFlags);
153+
return createImg( grid, cache, type, accessFlags );
139154
}
140155

141156
/**
142-
* Create a memory {@link CachedCellImg} with a cell generator {@link Consumer}.
157+
* Create a memory {@link CachedCellImg} with a cell generator
158+
* {@link Consumer}.
143159
*
144160
* @param targetInterval
145161
* @param blockSize
@@ -148,18 +164,8 @@ private Lazy() {}
148164
* @param op
149165
* @return
150166
*/
151-
public static <T extends NativeType<T>> CachedCellImg<T, ?> process(
152-
final Interval targetInterval,
153-
final int[] blockSize,
154-
final T type,
155-
final Set<AccessFlags> accessFlags,
156-
final Consumer<RandomAccessibleInterval<T>> op) {
157-
158-
return createImg(
159-
targetInterval,
160-
blockSize,
161-
type,
162-
accessFlags,
163-
op::accept);
167+
public static < T extends NativeType< T > > CachedCellImg< T, ? > generate( final Interval targetInterval, final int[] blockSize, final T type, final Set< AccessFlags > accessFlags, final Consumer< RandomAccessibleInterval< T > > op )
168+
{
169+
return createImg( targetInterval, blockSize, type, accessFlags, op );
164170
}
165-
}
171+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package net.imglib2.algorithm.lazy;
2+
3+
import java.util.Iterator;
4+
import java.util.function.Consumer;
5+
6+
import org.junit.Assert;
7+
import org.junit.Test;
8+
9+
import net.imglib2.Cursor;
10+
import net.imglib2.FinalInterval;
11+
import net.imglib2.RandomAccessibleInterval;
12+
import net.imglib2.cache.img.CachedCellImg;
13+
import net.imglib2.img.basictypeaccess.AccessFlags;
14+
import net.imglib2.position.FunctionRandomAccessible;
15+
import net.imglib2.type.Type;
16+
import net.imglib2.type.numeric.integer.LongType;
17+
import net.imglib2.util.Intervals;
18+
import net.imglib2.view.Views;
19+
20+
public class LazyTest
21+
{
22+
@Test
23+
public final void test()
24+
{
25+
final FunctionRandomAccessible< LongType > x = new FunctionRandomAccessible<>( 3, ( a, b ) -> b.set( a.getLongPosition( 0 ) ), LongType::new );
26+
final FunctionRandomAccessible< LongType > y = new FunctionRandomAccessible<>( 3, ( a, b ) -> b.set( a.getLongPosition( 1 ) ), LongType::new );
27+
final FunctionRandomAccessible< LongType > z = new FunctionRandomAccessible<>( 3, ( a, b ) -> b.set( a.getLongPosition( 2 ) ), LongType::new );
28+
29+
final Consumer< RandomAccessibleInterval< LongType > > xPositionLoader = cell -> {
30+
final Cursor< LongType > c = Views.iterable( cell ).cursor();
31+
while ( c.hasNext() )
32+
{
33+
c.fwd();
34+
c.get().set( c.getLongPosition( 0 ) );
35+
}
36+
};
37+
38+
final Consumer< RandomAccessibleInterval< LongType > > yPositionLoader = cell -> {
39+
final Cursor< LongType > c = Views.iterable( cell ).cursor();
40+
while ( c.hasNext() )
41+
{
42+
c.fwd();
43+
c.get().set( c.getLongPosition( 1 ) );
44+
}
45+
};
46+
47+
final Consumer< RandomAccessibleInterval< LongType > > zPositionLoader = cell -> {
48+
final Cursor< LongType > c = Views.iterable( cell ).cursor();
49+
while ( c.hasNext() )
50+
{
51+
c.fwd();
52+
c.get().set( c.getLongPosition( 2 ) );
53+
}
54+
};
55+
56+
final FinalInterval[] intervals =
57+
new FinalInterval[] {
58+
Intervals.createMinSize( 0, 0, 0, 11, 20, 33 ),
59+
Intervals.createMinSize( 22, 11, 3, 11, 20, 33 ) };
60+
61+
final int[] blockSize = { 3, 4, 5 };
62+
63+
for ( final FinalInterval interval : intervals)
64+
{
65+
66+
final CachedCellImg< LongType, ? > lazyX = Lazy.generate( interval, blockSize, new LongType(), AccessFlags.setOf(), xPositionLoader );
67+
68+
final CachedCellImg< LongType, ? > lazyY = Lazy.generate( interval, blockSize, new LongType(), AccessFlags.setOf(), yPositionLoader );
69+
70+
final CachedCellImg< LongType, ? > lazyZ = Lazy.generate( interval, blockSize, new LongType(), AccessFlags.setOf(), zPositionLoader );
71+
72+
Assert.assertTrue( equals( Views.flatIterable( lazyX ), Views.flatIterable( Views.interval( x, interval ) ) ) );
73+
74+
Assert.assertTrue( equals( Views.flatIterable( lazyY ), Views.flatIterable( Views.interval( y, interval ) ) ) );
75+
76+
Assert.assertTrue( equals( Views.flatIterable( lazyZ ), Views.flatIterable( Views.interval( z, interval ) ) ) );
77+
}
78+
}
79+
80+
private static < T extends Type< T > > boolean equals( final Iterable< ? extends T > a, final Iterable< ? extends T > b )
81+
{
82+
final Iterator< ? extends T > itA = a.iterator();
83+
final Iterator< ? extends T > itB = b.iterator();
84+
85+
while ( itA.hasNext() )
86+
{
87+
if ( !itA.next().valueEquals( itB.next() ) )
88+
return false;
89+
}
90+
return true;
91+
}
92+
93+
}

0 commit comments

Comments
 (0)