-
Notifications
You must be signed in to change notification settings - Fork 19
Description
I encountered ArrayIndexOufOfBoundsException in calls to PartialDerivative.gradientCentralDifference. I was able to make minimum working example that reproduced that behavior:
import net.imglib2.algorithm.gradient.PartialDerivative;
import net.imglib2.cache.img.CellLoader;
import net.imglib2.cache.img.DiskCachedCellImg;
import net.imglib2.cache.img.DiskCachedCellImgFactory;
import net.imglib2.cache.img.DiskCachedCellImgOptions;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
public class PartialDerivativeBug
{
public static void main( final String[] args )
{
final long[] dim = new long[] { 200, 300, 400 };
final DiskCachedCellImgOptions opts = DiskCachedCellImgOptions.options().cellDimensions( 64, 64, 64 ).dirtyAccesses( false ).maxCacheSize( 100 );
final DiskCachedCellImgFactory< FloatType > factory = new DiskCachedCellImgFactory<>( opts );
final CellLoader< FloatType > loader1 = img -> {
};
final DiskCachedCellImg< FloatType, ? > img1 = factory.create( dim, new FloatType(), loader1 );
final CellLoader< FloatType > loader2 = img -> {
PartialDerivative.gradientCentralDifference( Views.extendBorder( img1 ), img, 2 );
};
final DiskCachedCellImg< FloatType, ? > gradient = factory.create( dim, new FloatType(), loader2 );
for ( final FloatType g : gradient )
g.get();
}
}This code throws the following Exception:
Exception in thread "main" java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: -4096
at net.imglib2.cache.util.CacheAsUncheckedCacheAdapter.get(CacheAsUncheckedCacheAdapter.java:32)
at net.imglib2.img.cell.LazyCellImg$LazyCells.get(LazyCellImg.java:78)
at net.imglib2.img.list.AbstractLongListImg$LongListCursor.get(AbstractLongListImg.java:98)
at net.imglib2.img.cell.CellCursor.getCell(CellCursor.java:94)
at net.imglib2.img.cell.CellCursor.moveToNextCell(CellCursor.java:182)
at net.imglib2.img.cell.CellCursor.reset(CellCursor.java:152)
at net.imglib2.img.cell.CellCursor.<init>(CellCursor.java:88)
at net.imglib2.img.cell.AbstractCellImg.cursor(AbstractCellImg.java:92)
at net.imglib2.img.cell.AbstractCellImg.cursor(AbstractCellImg.java:51)
at net.imglib2.img.AbstractImg.iterator(AbstractImg.java:75)
at de.hanslovsky.zspacing.spark.experiments.visualization.PartialDerivativeBug.main(PartialDerivativeBug.java:35)
Caused by: java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: -4096
at net.imglib2.cache.ref.SoftRefLoaderRemoverCache.get(SoftRefLoaderRemoverCache.java:168)
at net.imglib2.cache.util.LoaderRemoverCacheAsLoaderCacheAdapter.get(LoaderRemoverCacheAsLoaderCacheAdapter.java:37)
at net.imglib2.cache.util.LoaderCacheAsCacheAdapter.get(LoaderCacheAsCacheAdapter.java:30)
at net.imglib2.cache.util.CacheAsUncheckedCacheAdapter.get(CacheAsUncheckedCacheAdapter.java:28)
... 10 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: -4096
at net.imglib2.img.basictypeaccess.array.AbstractFloatArray.getValue(AbstractFloatArray.java:61)
at net.imglib2.type.numeric.real.FloatType.get(FloatType.java:115)
at net.imglib2.type.numeric.real.FloatType.sub(FloatType.java:198)
at net.imglib2.type.numeric.real.FloatType.sub(FloatType.java:50)
at net.imglib2.algorithm.gradient.PartialDerivative.gradientCentralDifference(PartialDerivative.java:198)
at de.hanslovsky.zspacing.spark.experiments.visualization.PartialDerivativeBug.lambda$1(PartialDerivativeBug.java:30)
at net.imglib2.cache.img.LoadedCellCacheLoader.get(LoadedCellCacheLoader.java:82)
at net.imglib2.cache.img.LoadedCellCacheLoader.get(LoadedCellCacheLoader.java:44)
at net.imglib2.cache.img.DiskCellCache.get(DiskCellCache.java:104)
at net.imglib2.cache.img.DiskCellCache.get(DiskCellCache.java:43)
at net.imglib2.cache.IoSync.get(IoSync.java:174)
at net.imglib2.cache.ref.SoftRefLoaderRemoverCache.get(SoftRefLoaderRemoverCache.java:158)
... 13 more
gradientCentralDifference tries to get the most efficient RandomAccesses by specifying the required intervals for the forward and backward terms of the finite difference sum:
https://github.com/imglib/imglib2-algorithm/blob/master/src/main/java/net/imglib2/algorithm/gradient/PartialDerivative.java#L183-L184
As far as I can tell, the specifications for the required intervals are wrong, though: back and front should be translated by -1 and 1, respectively. Currently, it is the other way round. As some implementations of RandomAccessible delegate randomAccess( Interval ) to randomAccess(), this issue does not happen a lot, in practice.
I will make a fix for this.