Skip to content
Snippets Groups Projects
Commit c1a4ffc2 authored by Stephan Saalfeld's avatar Stephan Saalfeld
Browse files

Merge branch 'janelia2' of github.com:tpietzsch/spimviewer into janelia2

Conflicts:
	pom.xml
	src/main/java/bdv/BigDataViewer.java
parents 5a78bfb5 aefc5bc6
No related branches found
No related tags found
No related merge requests found
Showing
with 671 additions and 110 deletions
...@@ -79,11 +79,15 @@ ...@@ -79,11 +79,15 @@
<artifactId>vecmath</artifactId> <artifactId>vecmath</artifactId>
<version>1.3.1</version> <version>1.3.1</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.1.3.v20140225</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.2.4</version> <version>2.2.4</version>
<scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>
......
package bdv;
import java.io.File;
import mpicbg.spim.data.View;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.Volatile;
import net.imglib2.type.numeric.real.FloatType;
import org.jdom2.Element;
public abstract class AbstractViewerImgLoader< T, V extends Volatile< T > > implements ViewerImgLoader< T, V >
{
protected final T type;
protected final V volatileType;
public AbstractViewerImgLoader( final T type, final V volatileType )
{
this.type = type;
this.volatileType = volatileType;
}
@Override
public T getImageType()
{
return type;
}
@Override
public V getVolatileImageType()
{
return volatileType;
}
@Override
public Element toXml( final File basePath )
{
throw new UnsupportedOperationException( "not implemented" );
}
@Override
public RandomAccessibleInterval< FloatType > getFloatImage( final View view )
{
throw new UnsupportedOperationException( "not implemented" );
}
@Override
public RandomAccessibleInterval< T > getImage( final View view )
{
return getImage( view, 0 );
}
}
...@@ -29,15 +29,9 @@ public class SpimSource< T extends NumericType< T > > extends AbstractSpimSource ...@@ -29,15 +29,9 @@ public class SpimSource< T extends NumericType< T > > extends AbstractSpimSource
zero.setZero(); zero.setZero();
final View view = sequenceViews.getView( timepoint, setup ); final View view = sequenceViews.getView( timepoint, setup );
final AffineTransform3D reg = view.getModel(); final AffineTransform3D reg = view.getModel();
final AffineTransform3D mipmapTransform = new AffineTransform3D();
for ( int level = 0; level < currentSources.length; level++ ) for ( int level = 0; level < currentSources.length; level++ )
{ {
final double[] resolution = imgLoader.getMipmapResolutions( setup )[ level ]; final AffineTransform3D mipmapTransform = imgLoader.getMipmapTransforms( setup )[ level ];
for ( int d = 0; d < 3; ++d )
{
mipmapTransform.set( resolution[ d ], d, d );
mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
}
currentSourceTransforms[ level ].set( reg ); currentSourceTransforms[ level ].set( reg );
currentSourceTransforms[ level ].concatenate( mipmapTransform ); currentSourceTransforms[ level ].concatenate( mipmapTransform );
currentSources[ level ] = imgLoader.getImage( view, level ); currentSources[ level ] = imgLoader.getImage( view, level );
......
...@@ -4,6 +4,8 @@ import mpicbg.spim.data.ImgLoader; ...@@ -4,6 +4,8 @@ import mpicbg.spim.data.ImgLoader;
import mpicbg.spim.data.View; import mpicbg.spim.data.View;
import net.imglib2.RandomAccessibleInterval; import net.imglib2.RandomAccessibleInterval;
import net.imglib2.Volatile; import net.imglib2.Volatile;
import net.imglib2.realtransform.AffineTransform3D;
import bdv.img.cache.Cache;
public interface ViewerImgLoader< T, V extends Volatile< T > > extends ImgLoader< T > public interface ViewerImgLoader< T, V extends Volatile< T > > extends ImgLoader< T >
{ {
...@@ -17,5 +19,9 @@ public interface ViewerImgLoader< T, V extends Volatile< T > > extends ImgLoader ...@@ -17,5 +19,9 @@ public interface ViewerImgLoader< T, V extends Volatile< T > > extends ImgLoader
public double[][] getMipmapResolutions( final int setup ); public double[][] getMipmapResolutions( final int setup );
public AffineTransform3D[] getMipmapTransforms( final int setup );
public int numMipmapLevels( final int setup ); public int numMipmapLevels( final int setup );
public Cache getCache();
} }
...@@ -34,15 +34,9 @@ public class VolatileSpimSource< T extends NumericType< T >, V extends Volatile< ...@@ -34,15 +34,9 @@ public class VolatileSpimSource< T extends NumericType< T >, V extends Volatile<
zero.setZero(); zero.setZero();
final View view = sequenceViews.getView( timepoint, setup ); final View view = sequenceViews.getView( timepoint, setup );
final AffineTransform3D reg = view.getModel(); final AffineTransform3D reg = view.getModel();
final AffineTransform3D mipmapTransform = new AffineTransform3D();
for ( int level = 0; level < currentSources.length; level++ ) for ( int level = 0; level < currentSources.length; level++ )
{ {
final double[] resolution = imgLoader.getMipmapResolutions( setup )[ level ]; final AffineTransform3D mipmapTransform = imgLoader.getMipmapTransforms( setup )[ level ];
for ( int d = 0; d < 3; ++d )
{
mipmapTransform.set( resolution[ d ], d, d );
mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
}
currentSourceTransforms[ level ].set( reg ); currentSourceTransforms[ level ].set( reg );
currentSourceTransforms[ level ].concatenate( mipmapTransform ); currentSourceTransforms[ level ].concatenate( mipmapTransform );
currentSources[ level ] = imgLoader.getVolatileImage( view, level ); currentSources[ level ] = imgLoader.getVolatileImage( view, level );
......
...@@ -217,6 +217,7 @@ public class VolatileGlobalCellCache< A extends VolatileAccess > implements Cach ...@@ -217,6 +217,7 @@ public class VolatileGlobalCellCache< A extends VolatileAccess > implements Cach
{ {
final Fetcher f = new Fetcher(); final Fetcher f = new Fetcher();
f.setDaemon( true ); f.setDaemon( true );
f.setName( "Fetcher-" + i );
fetchers.add( f ); fetchers.add( f );
f.start(); f.start();
} }
......
...@@ -9,20 +9,18 @@ import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray; ...@@ -9,20 +9,18 @@ import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray;
import net.imglib2.img.cell.CellImg; import net.imglib2.img.cell.CellImg;
import net.imglib2.type.NativeType; import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.ARGBType; import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.type.volatiles.VolatileARGBType; import net.imglib2.type.volatiles.VolatileARGBType;
import org.jdom2.Element; import org.jdom2.Element;
import bdv.ViewerImgLoader; import bdv.AbstractViewerImgLoader;
import bdv.img.cache.Cache;
import bdv.img.cache.VolatileCell; import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache; import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy; import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
import bdv.img.cache.VolatileImgCells; import bdv.img.cache.VolatileImgCells;
import bdv.img.cache.VolatileImgCells.CellCache; import bdv.img.cache.VolatileImgCells.CellCache;
public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileARGBType > public class CatmaidImageLoader extends AbstractViewerImgLoader< ARGBType, VolatileARGBType >
{ {
private long width; private long width;
...@@ -50,6 +48,11 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR ...@@ -50,6 +48,11 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR
protected VolatileGlobalCellCache< VolatileIntArray > cache; protected VolatileGlobalCellCache< VolatileIntArray > cache;
public CatmaidImageLoader()
{
super( new ARGBType(), new VolatileARGBType() );
}
@Override @Override
public void init( final Element elem, final File basePath ) public void init( final Element elem, final File basePath )
{ {
...@@ -61,7 +64,7 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR ...@@ -61,7 +64,7 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR
resZ = Double.parseDouble( elem.getChildText( "resZ" ) ); resZ = Double.parseDouble( elem.getChildText( "resZ" ) );
urlFormat = elem.getChildText( "urlFormat" ); urlFormat = elem.getChildText( "urlFormat" );
tileWidth = Integer.parseInt( elem.getChildText( "tileWidth" ) ); tileWidth = Integer.parseInt( elem.getChildText( "tileWidth" ) );
tileHeight = Integer.parseInt( elem.getChildText( "tileHeight" ) ); tileHeight = Integer.parseInt( elem.getChildText( "tileHeight" ) );
...@@ -76,7 +79,6 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR ...@@ -76,7 +79,6 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR
blockDimensions = new int[ numScales ][]; blockDimensions = new int[ numScales ][];
for ( int l = 0; l < numScales; ++l ) for ( int l = 0; l < numScales; ++l )
{ {
mipmapResolutions[ l ] = new double[] { 1 << l, 1 << l, 1 }; mipmapResolutions[ l ] = new double[] { 1 << l, 1 << l, 1 };
imageDimensions[ l ] = new long[] { width >> l, height >> l, depth }; imageDimensions[ l ] = new long[] { width >> l, height >> l, depth };
blockDimensions[ l ] = new int[] { tileWidth, tileHeight, 1 }; blockDimensions[ l ] = new int[] { tileWidth, tileHeight, 1 };
...@@ -97,24 +99,6 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR ...@@ -97,24 +99,6 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR
return i; return i;
} }
@Override
public Element toXml( final File basePath )
{
throw new UnsupportedOperationException( "not implemented" );
}
@Override
public RandomAccessibleInterval< FloatType > getFloatImage( final View view )
{
throw new UnsupportedOperationException( "not implemented" );
}
@Override
public RandomAccessibleInterval< ARGBType > getImage( final View view )
{
return getImage( view, 0 );
}
@Override @Override
public RandomAccessibleInterval< ARGBType > getImage( final View view, final int level ) public RandomAccessibleInterval< ARGBType > getImage( final View view, final int level )
{ {
...@@ -161,25 +145,9 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR ...@@ -161,25 +145,9 @@ public class CatmaidImageLoader implements ViewerImgLoader< ARGBType, VolatileAR
return img; return img;
} }
public Cache getCache()
{
return cache;
}
private final ARGBType type = new ARGBType();
private final VolatileARGBType volatileType = new VolatileARGBType();
@Override
public ARGBType getImageType()
{
return type;
}
@Override @Override
public VolatileARGBType getVolatileImageType() public VolatileGlobalCellCache< VolatileIntArray > getCache()
{ {
return volatileType; return cache;
} }
} }
...@@ -61,7 +61,7 @@ public class CatmaidVolatileIntArrayLoader implements CacheArrayLoader< Volatile ...@@ -61,7 +61,7 @@ public class CatmaidVolatileIntArrayLoader implements CacheArrayLoader< Volatile
@Override @Override
public int getBytesPerElement() public int getBytesPerElement()
{ {
return 1; return 4;
} }
@Override @Override
......
...@@ -31,7 +31,7 @@ public class CatmaidVolatileShortArrayLoader implements CacheArrayLoader< Volati ...@@ -31,7 +31,7 @@ public class CatmaidVolatileShortArrayLoader implements CacheArrayLoader< Volati
@Override @Override
public int getBytesPerElement() public int getBytesPerElement()
{ {
return 1; return 2;
} }
@Override @Override
......
...@@ -15,16 +15,16 @@ import net.imglib2.RandomAccessibleInterval; ...@@ -15,16 +15,16 @@ import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.NativeImg; import net.imglib2.img.NativeImg;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray; import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import net.imglib2.img.cell.CellImg; import net.imglib2.img.cell.CellImg;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.sampler.special.ConstantRandomAccessible; import net.imglib2.sampler.special.ConstantRandomAccessible;
import net.imglib2.type.NativeType; import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.integer.UnsignedShortType; import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.type.volatiles.VolatileUnsignedShortType; import net.imglib2.type.volatiles.VolatileUnsignedShortType;
import net.imglib2.view.Views; import net.imglib2.view.Views;
import org.jdom2.Element; import org.jdom2.Element;
import bdv.ViewerImgLoader; import bdv.AbstractViewerImgLoader;
import bdv.img.cache.VolatileCell; import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache; import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy; import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
...@@ -34,7 +34,7 @@ import ch.systemsx.cisd.hdf5.HDF5DataSetInformation; ...@@ -34,7 +34,7 @@ import ch.systemsx.cisd.hdf5.HDF5DataSetInformation;
import ch.systemsx.cisd.hdf5.HDF5Factory; import ch.systemsx.cisd.hdf5.HDF5Factory;
import ch.systemsx.cisd.hdf5.IHDF5Reader; import ch.systemsx.cisd.hdf5.IHDF5Reader;
public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, VolatileUnsignedShortType > public class Hdf5ImageLoader extends AbstractViewerImgLoader< UnsignedShortType, VolatileUnsignedShortType >
{ {
protected File hdf5File; protected File hdf5File;
...@@ -44,6 +44,8 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -44,6 +44,8 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
protected final ArrayList< double[][] > perSetupMipmapResolutions; protected final ArrayList< double[][] > perSetupMipmapResolutions;
protected final ArrayList< AffineTransform3D[] > perSetupMipmapTransforms;
protected final ArrayList< int[][] > perSetupSubdivisions; protected final ArrayList< int[][] > perSetupSubdivisions;
/** /**
...@@ -77,8 +79,6 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -77,8 +79,6 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
*/ */
protected Boolean[] cachedExistence; protected Boolean[] cachedExistence;
protected final boolean isCoarsestLevelBlocking = true;
public Hdf5ImageLoader() public Hdf5ImageLoader()
{ {
this( null ); this( null );
...@@ -86,10 +86,12 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -86,10 +86,12 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
public Hdf5ImageLoader( final ArrayList< Partition > hdf5Partitions ) public Hdf5ImageLoader( final ArrayList< Partition > hdf5Partitions )
{ {
super( new UnsignedShortType(), new VolatileUnsignedShortType() );
hdf5File = null; hdf5File = null;
hdf5Reader = null; hdf5Reader = null;
cache = null; cache = null;
perSetupMipmapResolutions = new ArrayList< double[][] >(); perSetupMipmapResolutions = new ArrayList< double[][] >();
perSetupMipmapTransforms = new ArrayList< AffineTransform3D[] >();
perSetupSubdivisions = new ArrayList< int[][] >(); perSetupSubdivisions = new ArrayList< int[][] >();
partitions = new ArrayList< Partition >(); partitions = new ArrayList< Partition >();
if ( hdf5Partitions != null ) if ( hdf5Partitions != null )
...@@ -106,7 +108,9 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -106,7 +108,9 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
public Hdf5ImageLoader( final File hdf5File, final ArrayList< Partition > hdf5Partitions, final boolean doOpen ) public Hdf5ImageLoader( final File hdf5File, final ArrayList< Partition > hdf5Partitions, final boolean doOpen )
{ {
super( new UnsignedShortType(), new VolatileUnsignedShortType() );
this.hdf5File = hdf5File; this.hdf5File = hdf5File;
perSetupMipmapTransforms = new ArrayList< AffineTransform3D[] >();
perSetupMipmapResolutions = new ArrayList< double[][] >(); perSetupMipmapResolutions = new ArrayList< double[][] >();
perSetupSubdivisions = new ArrayList< int[][] >(); perSetupSubdivisions = new ArrayList< int[][] >();
partitions = new ArrayList< Partition >(); partitions = new ArrayList< Partition >();
...@@ -128,13 +132,27 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -128,13 +132,27 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
perSetupSubdivisions.clear(); perSetupSubdivisions.clear();
for ( int setup = 0; setup < numSetups; ++setup ) for ( int setup = 0; setup < numSetups; ++setup )
{ {
final double [][] mipmapResolutions = hdf5Reader.readDoubleMatrix( getResolutionsPath( setup ) ); final double[][] mipmapResolutions = hdf5Reader.readDoubleMatrix( getResolutionsPath( setup ) );
perSetupMipmapResolutions.add( mipmapResolutions ); perSetupMipmapResolutions.add( mipmapResolutions );
if ( mipmapResolutions.length > maxNumLevels ) if ( mipmapResolutions.length > maxNumLevels )
maxNumLevels = mipmapResolutions.length; maxNumLevels = mipmapResolutions.length;
maxLevels[ setup ] = mipmapResolutions.length - 1; maxLevels[ setup ] = mipmapResolutions.length - 1;
final int [][] subdivisions = hdf5Reader.readIntMatrix( getSubdivisionsPath( setup ) ); final AffineTransform3D[] mipmapTransforms = new AffineTransform3D[ mipmapResolutions.length ];
for ( int level = 0; level < mipmapResolutions.length; level++ )
{
final AffineTransform3D mipmapTransform = new AffineTransform3D();
final double[] resolution = mipmapResolutions[ level ];
for ( int d = 0; d < 3; ++d )
{
mipmapTransform.set( resolution[ d ], d, d );
mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
}
mipmapTransforms[ level ] = mipmapTransform;
}
perSetupMipmapTransforms.add( mipmapTransforms );
final int[][] subdivisions = hdf5Reader.readIntMatrix( getSubdivisionsPath( setup ) );
perSetupSubdivisions.add( subdivisions ); perSetupSubdivisions.add( subdivisions );
} }
...@@ -221,18 +239,6 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -221,18 +239,6 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
return partitions; return partitions;
} }
@Override
public RandomAccessibleInterval< FloatType > getFloatImage( final View view )
{
throw new UnsupportedOperationException( "currently not used" );
}
@Override
public RandomAccessibleInterval< UnsignedShortType > getImage( final View view )
{
return getImage( view, 0 );
}
@Override @Override
public RandomAccessibleInterval< UnsignedShortType > getImage( final View view, final int level ) public RandomAccessibleInterval< UnsignedShortType > getImage( final View view, final int level )
{ {
...@@ -261,6 +267,7 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -261,6 +267,7 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
return img; return img;
} }
@Override
public VolatileGlobalCellCache< VolatileShortArray > getCache() public VolatileGlobalCellCache< VolatileShortArray > getCache()
{ {
return cache; return cache;
...@@ -272,6 +279,12 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -272,6 +279,12 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
return perSetupMipmapResolutions.get( setup ); return perSetupMipmapResolutions.get( setup );
} }
@Override
public AffineTransform3D[] getMipmapTransforms( final int setup )
{
return perSetupMipmapTransforms.get( setup );
}
public int[][] getSubdivisions( final int setup ) public int[][] getSubdivisions( final int setup )
{ {
return perSetupSubdivisions.get( setup ); return perSetupSubdivisions.get( setup );
...@@ -289,10 +302,21 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -289,10 +302,21 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
* *
* @return true, if the given image data is present. * @return true, if the given image data is present.
*/ */
protected boolean existsImageData( final View view, final int level ) public boolean existsImageData( final View view, final int level )
{ {
final int timepoint = view.getTimepointIndex(); final int timepoint = view.getTimepointIndex();
final int setup = view.getSetupIndex(); final int setup = view.getSetupIndex();
return existsImageData( timepoint, setup, level );
}
/**
* Checks whether the given image data is present in the hdf5. Missing data
* may be caused by missing partition files
*
* @return true, if the given image data is present.
*/
public boolean existsImageData( final int timepoint, final int setup, final int level )
{
final int index = getViewInfoCacheIndex( timepoint, setup, level ); final int index = getViewInfoCacheIndex( timepoint, setup, level );
if ( cachedExistence[ index ] == null ) if ( cachedExistence[ index ] == null )
// will set cachedExistence[ index ] as a side effect // will set cachedExistence[ index ] as a side effect
...@@ -316,7 +340,7 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -316,7 +340,7 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
return Views.interval( new ConstantRandomAccessible< T >( constant, 3 ), new FinalInterval( d ) ); return Views.interval( new ConstantRandomAccessible< T >( constant, 3 ), new FinalInterval( d ) );
} }
protected long[] getImageDimension( final int timepoint, final int setup, final int level ) public long[] getImageDimension( final int timepoint, final int setup, final int level )
{ {
final int index = getViewInfoCacheIndex( timepoint, setup, level ); final int index = getViewInfoCacheIndex( timepoint, setup, level );
if ( cachedDimensions[ index ] == null ) if ( cachedDimensions[ index ] == null )
...@@ -392,20 +416,4 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola ...@@ -392,20 +416,4 @@ public class Hdf5ImageLoader implements ViewerImgLoader< UnsignedShortType, Vola
} }
} }
} }
private final UnsignedShortType type = new UnsignedShortType();
private final VolatileUnsignedShortType volatileType = new VolatileUnsignedShortType();
@Override
public UnsignedShortType getImageType()
{
return type;
}
@Override
public VolatileUnsignedShortType getVolatileImageType()
{
return volatileType;
}
} }
package bdv.img.remote;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import mpicbg.spim.data.View;
import net.imglib2.FinalInterval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.NativeImg;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import net.imglib2.img.cell.CellImg;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.sampler.special.ConstantRandomAccessible;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.volatiles.VolatileUnsignedShortType;
import net.imglib2.util.IntervalIndexer;
import net.imglib2.view.Views;
import org.jdom2.Element;
import bdv.AbstractViewerImgLoader;
import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
import bdv.img.cache.VolatileImgCells;
import bdv.img.cache.VolatileImgCells.CellCache;
import com.google.gson.Gson;
public class RemoteImageLoader extends AbstractViewerImgLoader< UnsignedShortType, VolatileUnsignedShortType >
{
protected String baseUrl;
protected RemoteImageLoaderMetaData metadata;
protected final ArrayList< AffineTransform3D[] > perSetupMipmapTransforms;
protected int[][] cellsDimensions;
protected VolatileGlobalCellCache< VolatileShortArray > cache;
public RemoteImageLoader()
{
super( new UnsignedShortType(), new VolatileUnsignedShortType() );
perSetupMipmapTransforms = new ArrayList< AffineTransform3D[] >();
}
private void open() throws IOException
{
final URL url = new URL( baseUrl + "?p=init" );
metadata = new Gson().fromJson(
new InputStreamReader( url.openStream() ),
RemoteImageLoaderMetaData.class );
cache = new VolatileGlobalCellCache< VolatileShortArray >(
new RemoteVolatileShortArrayLoader( this ),
metadata.numTimepoints,
metadata.numSetups,
metadata.maxNumLevels,
metadata.maxLevels,
10 );
for ( int setup = 0; setup < metadata.numSetups; ++setup )
{
final double[][] mipmapResolutions = metadata.perSetupMipmapResolutions.get( setup );
final AffineTransform3D[] mipmapTransforms = new AffineTransform3D[ mipmapResolutions.length ];
for ( int level = 0; level < mipmapResolutions.length; level++ )
{
final AffineTransform3D mipmapTransform = new AffineTransform3D();
final double[] resolution = mipmapResolutions[ level ];
for ( int d = 0; d < 3; ++d )
{
mipmapTransform.set( resolution[ d ], d, d );
mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
}
mipmapTransforms[ level ] = mipmapTransform;
}
perSetupMipmapTransforms.add( mipmapTransforms );
}
cellsDimensions = metadata.createCellsDimensions();
}
@Override
public void init( final Element elem, final File basePath )
{
try
{
baseUrl = elem.getChildText( "baseUrl" );
open();
}
catch ( final Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public RandomAccessibleInterval< UnsignedShortType > getImage( final View view, final int level )
{
if ( ! existsImageData( view, level ) )
{
System.err.println( "image data for " + view.getBasename() + " level " + level + " could not be found. Partition file missing?" );
return getMissingDataImage( view, level, new UnsignedShortType() );
}
final CellImg< UnsignedShortType, VolatileShortArray, VolatileCell< VolatileShortArray > > img = prepareCachedImage( view, level, LoadingStrategy.BLOCKING );
final UnsignedShortType linkedType = new UnsignedShortType( img );
img.setLinkedType( linkedType );
return img;
}
@Override
public RandomAccessibleInterval< VolatileUnsignedShortType > getVolatileImage( final View view, final int level )
{
if ( ! existsImageData( view, level ) )
{
System.err.println( "image data for " + view.getBasename() + " level " + level + " could not be found." );
return getMissingDataImage( view, level, new VolatileUnsignedShortType() );
}
final CellImg< VolatileUnsignedShortType, VolatileShortArray, VolatileCell< VolatileShortArray > > img = prepareCachedImage( view, level, LoadingStrategy.BUDGETED );
final VolatileUnsignedShortType linkedType = new VolatileUnsignedShortType( img );
img.setLinkedType( linkedType );
return img;
}
@Override
public VolatileGlobalCellCache< VolatileShortArray > getCache()
{
return cache;
}
@Override
public double[][] getMipmapResolutions( final int setup )
{
return metadata.perSetupMipmapResolutions.get( setup );
}
@Override
public AffineTransform3D[] getMipmapTransforms( final int setup )
{
return perSetupMipmapTransforms.get( setup );
}
public int[][] getSubdivisions( final int setup )
{
return metadata.perSetupSubdivisions.get( setup );
}
@Override
public int numMipmapLevels( final int setup )
{
return getMipmapResolutions( setup ).length;
}
/**
* Checks whether the given image data is present on the server.
*
* @return true, if the given image data is present.
*/
public boolean existsImageData( final View view, final int level )
{
final int timepoint = view.getTimepointIndex();
final int setup = view.getSetupIndex();
return existsImageData( timepoint, setup, level );
}
/**
* Checks whether the given image data is present on the server.
*
* @return true, if the given image data is present.
*/
public boolean existsImageData( final int timepoint, final int setup, final int level )
{
final int index = getViewInfoCacheIndex( timepoint, setup, level );
return metadata.existence[ index ];
}
/**
* For images that are missing on the server, a constant image is created.
* If the dimension of the missing image is present in
* {@link RemoteImageLoaderMetaData#dimensions} then use that. Otherwise
* create a 1x1x1 image.
*/
protected < T > RandomAccessibleInterval< T > getMissingDataImage( final View view, final int level, final T constant )
{
final int t = view.getTimepointIndex();
final int s = view.getSetupIndex();
final int index = getViewInfoCacheIndex( t, s, level );
long[] d = metadata.dimensions[ index ];
if ( d == null )
d = new long[] { 1, 1, 1 };
return Views.interval( new ConstantRandomAccessible< T >( constant, 3 ), new FinalInterval( d ) );
}
public long[] getImageDimension( final int timepoint, final int setup, final int level )
{
final int index = getViewInfoCacheIndex( timepoint, setup, level );
return metadata.dimensions[ index ];
}
private int getViewInfoCacheIndex( final int timepoint, final int setup, final int level )
{
return level + metadata.maxNumLevels * ( setup + metadata.numSetups * timepoint );
}
int getCellIndex( final int timepoint, final int setup, final int level, final long[] globalPosition )
{
final int index = getViewInfoCacheIndex( timepoint, setup, level );
final int[] cellSize = getSubdivisions( setup )[ level ];
final int[] cellPos = new int[] {
( int ) globalPosition[ 0 ] / cellSize[ 0 ],
( int ) globalPosition[ 1 ] / cellSize[ 1 ],
( int ) globalPosition[ 2 ] / cellSize[ 2 ] };
return IntervalIndexer.positionToIndex( cellPos, cellsDimensions[ index ] );
}
/**
* (Almost) create a {@link CellImg} backed by the cache.
* The created image needs a {@link NativeImg#setLinkedType(net.imglib2.type.Type) linked type} before it can be used.
* The type should be either {@link UnsignedShortType} and {@link VolatileUnsignedShortType}.
*/
protected < T extends NativeType< T > > CellImg< T, VolatileShortArray, VolatileCell< VolatileShortArray > > prepareCachedImage( final View view, final int level, final LoadingStrategy loadingStrategy )
{
if ( cache == null )
throw new RuntimeException( "no connection open" );
final int timepoint = view.getTimepointIndex();
final int setup = view.getSetupIndex();
final long[] dimensions = getImageDimension( timepoint, setup, level );
final int[] cellDimensions = metadata.perSetupSubdivisions.get( setup )[ level ];
final CellCache< VolatileShortArray > c = cache.new VolatileCellCache( timepoint, setup, level, loadingStrategy );
final VolatileImgCells< VolatileShortArray > cells = new VolatileImgCells< VolatileShortArray >( c, 1, dimensions, cellDimensions );
final CellImg< T, VolatileShortArray, VolatileCell< VolatileShortArray > > img = new CellImg< T, VolatileShortArray, VolatileCell< VolatileShortArray > >( null, cells );
return img;
}
}
package bdv.img.remote;
import java.util.ArrayList;
import bdv.img.hdf5.Hdf5ImageLoader;
public class RemoteImageLoaderMetaData
{
protected final ArrayList< double[][] > perSetupMipmapResolutions;
protected final ArrayList< int[][] > perSetupSubdivisions;
protected int numTimepoints;
protected int numSetups;
protected int[] maxLevels;
protected int maxNumLevels;
/**
* An array of long[] arrays with {@link #numTimepoints} *
* {@link #numSetups} * {@link #maxNumLevels} entries. Every entry is the
* dimensions of one image (identified by flattened index of level, setup,
* and timepoint).
*/
protected long[][] dimensions;
/**
* An array of Booleans with {@link #numTimepoints} * {@link #numSetups} *
* {@link #maxNumLevels} entries. Every entry is the existence of one image
* (identified by flattened index of level, setup, and timepoint).
*/
protected boolean[] existence;
public RemoteImageLoaderMetaData()
{
perSetupMipmapResolutions = new ArrayList< double[][] >();
perSetupSubdivisions = new ArrayList< int[][] >();
}
public RemoteImageLoaderMetaData( final Hdf5ImageLoader imgLoader, final int numTimepoints, final int numSetups )
{
perSetupMipmapResolutions = new ArrayList< double[][] >();
perSetupSubdivisions = new ArrayList< int[][] >();
this.numTimepoints = numTimepoints;
this.numSetups = numSetups;
maxLevels = new int[ numSetups ];
maxNumLevels = 0;
for ( int setup = 0; setup < numSetups; ++setup )
{
perSetupMipmapResolutions.add( imgLoader.getMipmapResolutions( setup ) );
perSetupSubdivisions.add( imgLoader.getSubdivisions( setup ) );
final int numLevels = imgLoader.numMipmapLevels( setup );
maxLevels[ setup ] = numLevels - 1;
if ( numLevels > maxNumLevels )
maxNumLevels = numLevels;
}
final int numImages = numTimepoints * numSetups * maxNumLevels;
dimensions = new long[ numImages ][];
existence = new boolean[ numImages ];
for ( int t = 0; t < numTimepoints; ++t )
for ( int s = 0; s < numSetups; ++s )
for ( int l = 0; l <= maxLevels[ s ]; ++l )
{
final int i = l + maxNumLevels * ( s + numSetups * t );
existence[ i ] = imgLoader.existsImageData( t, s, l );
dimensions[ i ] = imgLoader.getImageDimension( t, s, l );
}
}
/**
* Create an array of int[] with {@link #numTimepoints} * {@link #numSetups}
* * {@link #maxNumLevels} entries. Every entry is the dimensions in cells
* (instead of pixels) of one image (identified by flattened index of level,
* setup, and timepoint).
*/
protected int[][] createCellsDimensions()
{
final int numImages = numTimepoints * numSetups * maxNumLevels;
final int[][] cellsDimensions = new int[ numImages ][];
for ( int t = 0; t < numTimepoints; ++t )
for ( int s = 0; s < numSetups; ++s )
for ( int l = 0; l <= maxLevels[ s ]; ++l )
{
final int i = l + maxNumLevels * ( s + numSetups * t );
final long[] imageDimensions = dimensions[ i ];
final int[] cellSize = perSetupSubdivisions.get( s )[ l ];
cellsDimensions[ i ] = new int[] {
( int ) imageDimensions[ 0 ] / cellSize[ 0 ],
( int ) imageDimensions[ 1 ] / cellSize[ 1 ],
( int ) imageDimensions[ 2 ] / cellSize[ 2 ] };
}
return cellsDimensions;
}
}
package bdv.img.remote;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import bdv.img.cache.CacheArrayLoader;
public class RemoteVolatileShortArrayLoader implements CacheArrayLoader< VolatileShortArray >
{
private VolatileShortArray theEmptyArray;
private final RemoteImageLoader imgLoader;
public RemoteVolatileShortArrayLoader( final RemoteImageLoader imgLoader )
{
theEmptyArray = new VolatileShortArray( 32 * 32 * 32, false );
this.imgLoader = imgLoader;
}
@Override
public VolatileShortArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int index = imgLoader.getCellIndex( timepoint, setup, level, min );
final short[] data = new short[ dimensions[ 0 ] * dimensions[ 1 ] * dimensions[ 2 ] ];
try
{
final URL url = new URL( String.format( "%s?p=cell/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d",
imgLoader.baseUrl,
index,
timepoint,
setup,
level,
dimensions[ 0 ],
dimensions[ 1 ],
dimensions[ 2 ],
min[ 0 ],
min[ 1 ],
min[ 2 ] ) );
final InputStream s = url.openStream();
final byte[] buf = new byte[ data.length * 2 ];
for ( int i = 0, l = s.read( buf, 0, buf.length ); l != -1; i += l, l = s.read( buf, i, buf.length - i ) );
for ( int i = 0, j = 0; i < data.length; ++i, j += 2 )
data[ i ] = ( short ) ( ( ( buf[ j ] & 0xff ) << 8 ) | ( buf[ j + 1 ] & 0xff ) );
s.close();
}
catch ( final MalformedURLException e )
{
e.printStackTrace();
}
catch ( final IOException e )
{
e.printStackTrace();
}
return new VolatileShortArray( data, true );
}
@Override
public VolatileShortArray emptyArray( final int[] dimensions )
{
int numEntities = 1;
for ( int i = 0; i < dimensions.length; ++i )
numEntities *= dimensions[ i ];
if ( theEmptyArray.getCurrentStorageArray().length < numEntities )
theEmptyArray = new VolatileShortArray( numEntities, false );
return theEmptyArray;
}
@Override
public int getBytesPerElement() {
return 2;
}
}
package bdv.server;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import mpicbg.spim.data.SequenceDescription;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.jdom2.JDOMException;
import bdv.SequenceViewsLoader;
import bdv.img.cache.VolatileCell;
import bdv.img.cache.VolatileGlobalCellCache;
import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
import bdv.img.hdf5.Hdf5ImageLoader;
import bdv.img.remote.RemoteImageLoaderMetaData;
import com.google.gson.Gson;
public class BigDataServer
{
public static void main( final String[] args ) throws Exception
{
final String fn = args.length > 0 ? args[ 0 ] : "/Users/pietzsch/Desktop/data/fibsem.xml";
final Server server = new Server( 8080 );
server.setHandler( new CellHandler( fn ) );
server.start();
server.join();
}
static class CellHandler extends AbstractHandler
{
private final VolatileGlobalCellCache< VolatileShortArray > cache;
private final String metadataJson;
private final RemoteImageLoaderMetaData metadata;
public CellHandler( final String xmlFilename ) throws JDOMException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
final SequenceViewsLoader loader = new SequenceViewsLoader( xmlFilename );
final SequenceDescription seq = loader.getSequenceDescription();
final Hdf5ImageLoader imgLoader = ( Hdf5ImageLoader ) seq.imgLoader;
cache = imgLoader.getCache();
metadata = new RemoteImageLoaderMetaData( imgLoader, seq.numTimepoints(), seq.numViewSetups() );
metadataJson = new Gson().toJson( metadata );
}
@Override
public void handle( final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response ) throws IOException, ServletException
{
final String cellString = request.getParameter( "p" );
if ( cellString == null )
return;
final String[] parts = cellString.split( "/" );
if ( parts[ 0 ].equals( "cell" ) )
{
final int index = Integer.parseInt( parts[ 1 ] );
final int timepoint = Integer.parseInt( parts[ 2 ] );
final int setup = Integer.parseInt( parts[ 3 ] );
final int level = Integer.parseInt( parts[ 4 ] );
VolatileCell< VolatileShortArray > cell = cache.getGlobalIfCached( timepoint, setup, level, index, LoadingStrategy.BLOCKING );
if ( cell == null )
{
final int[] cellDims = new int[] {
Integer.parseInt( parts[ 5 ] ),
Integer.parseInt( parts[ 6 ] ),
Integer.parseInt( parts[ 7 ] ) };
final long[] cellMin = new long[] {
Long.parseLong( parts[ 8 ] ),
Long.parseLong( parts[ 9 ] ),
Long.parseLong( parts[ 10 ] ) };
cell = cache.createGlobal( cellDims, cellMin, timepoint, setup, level, index, LoadingStrategy.BLOCKING );
}
final short[] data = cell.getData().getCurrentStorageArray();
final byte[] buf = new byte[ 2 * data.length ];
for ( int i = 0, j = 0; i < data.length; i++ )
{
final short s = data[ i ];
buf[ j++ ] = ( byte ) ( ( s >> 8 ) & 0xff );
buf[ j++ ] = ( byte ) ( s & 0xff );
}
response.setContentType( "application/octet-stream" );
response.setContentLength( buf.length );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final OutputStream os = response.getOutputStream();
os.write( buf );
os.close();
}
else if ( parts[ 0 ].equals( "init" ) )
{
response.setContentType( "application/octet-stream" );
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
final PrintWriter ow = response.getWriter();
ow.write( metadataJson );
ow.close();
}
}
}
}
package bdv.viewer.render; package bdv.viewer.render;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import net.imglib2.Cursor; import net.imglib2.Cursor;
...@@ -43,6 +43,8 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector ...@@ -43,6 +43,8 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector
*/ */
protected final int numThreads; protected final int numThreads;
protected final ExecutorService executorService;
/** /**
* Time needed for rendering the last frame, in nano-seconds. * Time needed for rendering the last frame, in nano-seconds.
*/ */
...@@ -57,7 +59,8 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector ...@@ -57,7 +59,8 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector
final ArrayList< ? extends RandomAccessible< A > > sources, final ArrayList< ? extends RandomAccessible< A > > sources,
final Converter< ? super A, B > converter, final Converter< ? super A, B > converter,
final RandomAccessibleInterval< B > target, final RandomAccessibleInterval< B > target,
final int numThreads ) final int numThreads,
final ExecutorService executorService )
{ {
this.sourceProjectors = sourceProjectors; this.sourceProjectors = sourceProjectors;
this.sources = new ArrayList< IterableInterval< A > >(); this.sources = new ArrayList< IterableInterval< A > >();
...@@ -67,6 +70,7 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector ...@@ -67,6 +70,7 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector
this.target = target; this.target = target;
this.iterableTarget = Views.flatIterable( target ); this.iterableTarget = Views.flatIterable( target );
this.numThreads = numThreads; this.numThreads = numThreads;
this.executorService = executorService;
lastFrameRenderNanoTime = -1; lastFrameRenderNanoTime = -1;
} }
...@@ -96,23 +100,25 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector ...@@ -96,23 +100,25 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector
final int height = ( int ) target.dimension( 1 ); final int height = ( int ) target.dimension( 1 );
final int length = width * height; final int length = width * height;
final ExecutorService ex = Executors.newFixedThreadPool( numThreads ); final boolean createExecutor = ( executorService == null );
final int numTasks = Math.max( numThreads * 10, height ); final ExecutorService ex = createExecutor ? Executors.newFixedThreadPool( numThreads ) : executorService;
final int numTasks = Math.min( numThreads * 10, height );
final double taskLength = ( double ) length / numTasks; final double taskLength = ( double ) length / numTasks;
final int numSources = sources.size(); final int numSources = sources.size();
final ArrayList< Callable< Void > > tasks = new ArrayList< Callable< Void > >( numTasks );
for ( int taskNum = 0; taskNum < numTasks; ++taskNum ) for ( int taskNum = 0; taskNum < numTasks; ++taskNum )
{ {
final int myOffset = ( int ) ( taskNum * taskLength ); final int myOffset = ( int ) ( taskNum * taskLength );
final int myLength = ( (taskNum == numTasks - 1 ) ? length : ( int ) ( ( taskNum + 1 ) * taskLength ) ) - myOffset; final int myLength = ( (taskNum == numTasks - 1 ) ? length : ( int ) ( ( taskNum + 1 ) * taskLength ) ) - myOffset;
final Runnable r = new Runnable() final Callable< Void > r = new Callable< Void >()
{ {
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
@Override @Override
public void run() public Void call()
{ {
if ( interrupted.get() ) if ( interrupted.get() )
return; return null;
final Cursor< A >[] sourceCursors = new Cursor[ numSources ]; final Cursor< A >[] sourceCursors = new Cursor[ numSources ];
for ( int s = 0; s < numSources; ++s ) for ( int s = 0; s < numSources; ++s )
...@@ -130,19 +136,21 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector ...@@ -130,19 +136,21 @@ public abstract class AccumulateProjector< A, B > implements VolatileProjector
sourceCursors[ s ].fwd(); sourceCursors[ s ].fwd();
accumulate( sourceCursors, targetCursor.next() ); accumulate( sourceCursors, targetCursor.next() );
} }
return null;
} }
}; };
ex.execute( r ); tasks.add( r );
} }
ex.shutdown();
try try
{ {
ex.awaitTermination( 1, TimeUnit.HOURS ); ex.invokeAll( tasks );
} }
catch ( final InterruptedException e ) catch ( final InterruptedException e )
{ {
e.printStackTrace(); e.printStackTrace();
} }
if ( createExecutor )
ex.shutdown();
lastFrameRenderNanoTime = stopWatch.nanoTime(); lastFrameRenderNanoTime = stopWatch.nanoTime();
......
package bdv.viewer.render; package bdv.viewer.render;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import net.imglib2.Cursor; import net.imglib2.Cursor;
import net.imglib2.RandomAccessible; import net.imglib2.RandomAccessible;
...@@ -14,9 +15,10 @@ public class AccumulateProjectorARGB extends AccumulateProjector< ARGBType, ARGB ...@@ -14,9 +15,10 @@ public class AccumulateProjectorARGB extends AccumulateProjector< ARGBType, ARGB
final ArrayList< VolatileProjector > sourceProjectors, final ArrayList< VolatileProjector > sourceProjectors,
final ArrayList< ? extends RandomAccessible< ARGBType > > sources, final ArrayList< ? extends RandomAccessible< ARGBType > > sources,
final RandomAccessibleInterval< ARGBType > target, final RandomAccessibleInterval< ARGBType > target,
final int numThreads ) final int numThreads,
final ExecutorService executorService )
{ {
super( sourceProjectors, sources, null, target, numThreads ); super( sourceProjectors, sources, null, target, numThreads, executorService );
} }
@Override @Override
......
...@@ -571,7 +571,7 @@ public class MultiResolutionRenderer ...@@ -571,7 +571,7 @@ public class MultiResolutionRenderer
sourceProjectors.add( p ); sourceProjectors.add( p );
sourceImages.add( renderImage ); sourceImages.add( renderImage );
} }
projector = new AccumulateProjectorARGB( sourceProjectors, sourceImages, screenImage, numRenderingThreads ); projector = new AccumulateProjectorARGB( sourceProjectors, sourceImages, screenImage, numRenderingThreads, renderingExecutorService );
} }
previousTimepoint = viewerState.getCurrentTimepoint(); previousTimepoint = viewerState.getCurrentTimepoint();
cache.initIoTimeBudget( iobudget ); cache.initIoTimeBudget( iobudget );
...@@ -680,7 +680,7 @@ public class MultiResolutionRenderer ...@@ -680,7 +680,7 @@ public class MultiResolutionRenderer
} }
// for ( int i = bestLevel - 1; i >= 0; --i ) // for ( int i = bestLevel - 1; i >= 0; --i )
// levels.add( getTransformedSource( viewerState, spimSource, screenScaleTransform, i ) ); // levels.add( getTransformedSource( viewerState, spimSource, screenScaleTransform, i ) );
return new VolatileHierarchyProjector< T, ARGBType >( levels, source.getConverter(), screenImage, numRenderingThreads, renderingExecutorService ); return new VolatileHierarchyProjector< T, ARGBType >( levels, source.getConverter(), screenImage, maskArray, numRenderingThreads, renderingExecutorService );
} }
private static < T > RandomAccessible< T > getTransformedSource( final ViewerState viewerState, final Source< T > source, final AffineTransform3D screenScaleTransform, final int mipmapIndex ) private static < T > RandomAccessible< T > getTransformedSource( final ViewerState viewerState, final Source< T > source, final AffineTransform3D screenScaleTransform, final int mipmapIndex )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment