Skip to content

Commit

Permalink
significantly improve splitting code, taking into account valid split…
Browse files Browse the repository at this point in the history
…sizes due to downsampling pyramids
  • Loading branch information
StephanPreibisch committed May 8, 2024
1 parent e150fcc commit ae3c98f
Show file tree
Hide file tree
Showing 3 changed files with 301 additions and 72 deletions.
173 changes: 142 additions & 31 deletions src/main/java/net/preibisch/mvrecon/fiji/plugin/Split_Views.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
package net.preibisch.mvrecon.fiji.plugin;

import java.awt.Color;
import java.util.Arrays;
import java.util.HashMap;

import fiji.util.gui.GenericDialogPlus;
import ij.ImageJ;
import ij.plugin.PlugIn;
import mpicbg.spim.data.SpimDataException;
import mpicbg.spim.data.generic.AbstractSpimData;
import mpicbg.spim.data.generic.sequence.BasicImgLoader;
import mpicbg.spim.data.generic.sequence.BasicViewSetup;
import mpicbg.spim.data.sequence.MultiResolutionImgLoader;
import net.imglib2.Dimensions;
import net.imglib2.util.Pair;
import net.imglib2.util.Util;
Expand All @@ -45,13 +49,15 @@

public class Split_Views implements PlugIn
{
public static int defaultImgX = 600;
public static int defaultImgY = 600;
public static int defaultImgZ = 200;
public static long defaultImgX = 500;
public static long defaultImgY = 500;
public static long defaultImgZ = 200;

public static int defaultOverlapX = 60;
public static int defaultOverlapY = 60;
public static int defaultOverlapZ = 20;
public static long defaultOverlapX = 60;
public static long defaultOverlapY = 60;
public static long defaultOverlapZ = 20;

public static boolean defaultOptimize = true;

public static String defaultPath = null;

Expand All @@ -74,15 +80,13 @@ public void run(String arg)
public static boolean split(
final SpimData2 data,
final String saveAs,
final int sx,
final int sy,
final int sz,
final int ox,
final int oy,
final int oz,
final long[] targetSize,
final long[] overlap,
final long[] minStepSize,
final boolean optimize,
final boolean display )
{
final SpimData2 newSD = SplittingTools.splitImages( data, new long[] { ox, oy, oz }, new long[] { sx, sy, sz } );
final SpimData2 newSD = SplittingTools.splitImages( data, overlap, targetSize, minStepSize, optimize );

if ( display )
{
Expand All @@ -99,6 +103,8 @@ public static boolean split(

public static boolean split( final SpimData2 data, final String fileName )
{
final long[] minStepSize = findMinStepSize( data );

final Pair< HashMap< String, Integer >, long[] > imgSizes = collectImageSizes( data );

IOFunctions.println( "Current image sizes of dataset :");
Expand All @@ -108,16 +114,28 @@ public static boolean split( final SpimData2 data, final String fileName )

final GenericDialogPlus gd = new GenericDialogPlus( "Dataset splitting/subdividing" );

gd.addSlider( "New_Image_Size_X", 100, 2000, defaultImgX );
gd.addSlider( "New_Image_Size_Y", 100, 2000, defaultImgY );
gd.addSlider( "New_Image_Size_Z", 100, 2000, defaultImgZ );
defaultImgX = closestLargerLongDivisableBy( defaultImgX, minStepSize[ 0 ] );
defaultImgY = closestLargerLongDivisableBy( defaultImgY, minStepSize[ 1 ] );
defaultImgZ = closestLargerLongDivisableBy( defaultImgZ, minStepSize[ 2 ] );

defaultOverlapX = closestLargerLongDivisableBy( defaultOverlapX, minStepSize[ 0 ] );
defaultOverlapY = closestLargerLongDivisableBy( defaultOverlapY, minStepSize[ 1 ] );
defaultOverlapZ = closestLargerLongDivisableBy( defaultOverlapZ, minStepSize[ 2 ] );

gd.addSlider( "Target_Image_Size_X", 100, 2000, defaultImgX, minStepSize[ 0 ] );
gd.addSlider( "Target_Image_Size_Y", 100, 2000, defaultImgY, minStepSize[ 1 ] );
gd.addSlider( "Target_Image_Size_Z", 100, 2000, defaultImgZ, minStepSize[ 2 ] );

gd.addCheckbox( "Optimize_image_sizes per view", defaultOptimize );

gd.addMessage( "Note: new sizes will be adjusted to be divisible by " + Arrays.toString( minStepSize ), GUIHelper.mediumstatusfont, Color.RED );
gd.addMessage( "" );

gd.addSlider( "Overlap_X", 10, 200, defaultOverlapX );
gd.addSlider( "Overlap_Y", 10, 200, defaultOverlapY );
gd.addSlider( "Overlap_Z", 10, 200, defaultOverlapZ );
gd.addSlider( "Overlap_X", 10, 200, defaultOverlapX, minStepSize[ 0 ] );
gd.addSlider( "Overlap_Y", 10, 200, defaultOverlapY, minStepSize[ 1 ] );
gd.addSlider( "Overlap_Z", 10, 200, defaultOverlapZ, minStepSize[ 2 ] );

gd.addMessage( "Note: overlap will be adjusted to be divisible by " + Arrays.toString( minStepSize ), GUIHelper.mediumstatusfont, Color.RED );
gd.addMessage( "Minimal image sizes per dimension: " + Util.printCoordinates( imgSizes.getB() ), GUIHelper.mediumstatusfont, Color.DARK_GRAY );

gd.addMessage( "" );
Expand All @@ -140,18 +158,29 @@ public static boolean split( final SpimData2 data, final String fileName )
if ( gd.wasCanceled() )
return false;

final int sx = defaultImgX = (int)Math.round( gd.getNextNumber() );
final int sy = defaultImgY = (int)Math.round( gd.getNextNumber() );
final int sz = defaultImgZ = (int)Math.round( gd.getNextNumber() );
final long sx = defaultImgX = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 0 ] );
final long sy = defaultImgY = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 1 ] );
final long sz = defaultImgZ = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 2 ] );

final boolean optimize = defaultOptimize = gd.getNextBoolean();

final int ox = defaultOverlapX = (int)Math.round( gd.getNextNumber() );
final int oy = defaultOverlapY = (int)Math.round( gd.getNextNumber() );
final int oz = defaultOverlapZ = (int)Math.round( gd.getNextNumber() );
final long ox = defaultOverlapX = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 0 ] );
final long oy = defaultOverlapY = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 1 ] );
final long oz = defaultOverlapZ = closestLargerLongDivisableBy( Math.round( gd.getNextNumber() ), minStepSize[ 2 ] );

final String saveAs = defaultPath = gd.getNextString();
final int choice = defaultChoice = gd.getNextChoiceIndex();

return split( data, saveAs, sx, sy, sz, ox, oy, oz, choice == 0 );
System.out.println( sx + ", " + sy + ", " + sz + ", " + ox + ", " + oy + ", " + oz );

if ( ox > sx || oy > sy || oz > sz )
{
IOFunctions.println( "overlap cannot be bigger than size" );

return false;
}

return split( data, saveAs, new long[]{ sx, sy, sz }, new long[]{ ox, oy, oz }, minStepSize, optimize, choice == 0 );
}

public static Pair< HashMap< String, Integer >, long[] > collectImageSizes( final AbstractSpimData< ? > data )
Expand Down Expand Up @@ -188,15 +217,97 @@ public static Pair< HashMap< String, Integer >, long[] > collectImageSizes( fina
return new ValuePair<HashMap<String,Integer>, long[]>( sizes, minSize );
}

public static void main( String[] args )
public static long greatestCommonDivisor( long a, long b )
{
new ImageJ();
while (b > 0)
{
long temp = b;
b = a % b;
a = temp;
}
return a;
}

if ( !System.getProperty("os.name").toLowerCase().contains( "mac" ) )
GenericLoadParseQueryXML.defaultXMLfilename = "/home/steffi/Desktop/HisYFP-SPIM/dataset.xml";
public static long lowestCommonMultiplier( long a, long b )
{
return a * (b / greatestCommonDivisor(a, b));
}

public static long closestSmallerLongDivisableBy( final long a, final long b )
{
if ( a == b || a == 0 || a % b == 0 )
return a;
else
GenericLoadParseQueryXML.defaultXMLfilename = "/Users/spreibi/Documents/Microscopy/SPIM/HisYFP-SPIM/dataset.xml";//"/Users/spreibi/Documents/Microscopy/SPIM/HisYFP-SPIM//dataset.xml";
return a - (a % b);
}

public static long closestLargerLongDivisableBy( final long a, final long b )
{
if ( a == b || a == 0 || a % b == 0 )
return a;
else
return (a + b) - (a % b);
}

public static long closestLongDivisableBy( final long a, final long b)
{
final long c1 = closestSmallerLongDivisableBy( a, b );//a - (a % b);
final long c2 = closestLargerLongDivisableBy( a, b ); //(a + b) - (a % b);

if (a - c1 > c2 - a)
return c2;
else
return c1;
}

public static long[] findMinStepSize( final AbstractSpimData< ? > data )
{
final BasicImgLoader imgLoader = data.getSequenceDescription().getImgLoader();

final long[] minStepSize = new long[] { 1, 1, 1 };

if ( MultiResolutionImgLoader.class.isInstance( imgLoader ) )
{
IOFunctions.println( "We have a multi-resolution image loader: " + imgLoader.getClass().getName() + ", finding resolution steps");

final MultiResolutionImgLoader mrImgLoader = ( MultiResolutionImgLoader ) imgLoader;

for ( final BasicViewSetup vs : data.getSequenceDescription().getViewSetupsOrdered() )
{
final double[][] mipmapResolutions = mrImgLoader.getSetupImgLoader( vs.getId() ).getMipmapResolutions();

IOFunctions.println( "ViewSetup: " + vs.getName() + " (id=" + vs.getId() + "): " + Arrays.deepToString( mipmapResolutions ) );

// lowest resolution defines the minimal steps size
final double[] lowestResolution = mipmapResolutions[ mipmapResolutions.length - 1 ];

for ( int d = 0; d < minStepSize.length; ++d )
{
if ( lowestResolution[ d ] % 1 != 0.0 )
throw new RuntimeException( "Downsampling has a fraction, cannot split dataset" );

minStepSize[ d ] = lowestCommonMultiplier( minStepSize[ d ], Math.round( lowestResolution[ d ] ) );
}
}
}
else
{
IOFunctions.println( "Not a multi-resolution image loader, all data splits are possible." );
}

IOFunctions.println( "Final minimal step size: " + Arrays.toString( minStepSize ) );

return minStepSize;
}

public static void main( String[] args ) throws SpimDataException
{
new ImageJ();

GenericLoadParseQueryXML.defaultXMLfilename = "/Users/preibischs/SparkTest/IP/dataset.xml";

new Split_Views().run( null );
//SpimData2 data = new XmlIoSpimData2("").load( GenericLoadParseQueryXML.defaultXMLfilename );
//findMinStepSize(data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import ij.ImageJ;
import mpicbg.spim.data.SpimDataException;
import net.preibisch.mvrecon.fiji.plugin.Split_Views;
import net.preibisch.mvrecon.fiji.spimdata.SpimData2;
import net.preibisch.mvrecon.fiji.spimdata.XmlIoSpimData2;
import net.preibisch.mvrecon.fiji.spimdata.explorer.ViewSetupExplorer;
Expand Down Expand Up @@ -56,8 +57,19 @@ public static void main( String[] args ) throws SpimDataException
// load drosophila
spimData = new XmlIoSpimData2( "" ).load( file );

final long[] minStepSize = Split_Views.findMinStepSize( spimData );

//SpimData2 newSD = SplittingTools.splitImages( spimData, new long[] { 30, 30, 15 }, new long[] { 600, 600, 300 } );
SpimData2 newSD = SplittingTools.splitImages( spimData, new long[] { 30, 30, 10 }, new long[] { 200, 200, 40 } );
SpimData2 newSD =
SplittingTools.splitImages(
spimData,
new long[] { 30, 30, 10 },
new long[] {
Split_Views.closestLongDivisableBy( 200, minStepSize[ 0 ] ),
Split_Views.closestLongDivisableBy( 200, minStepSize[ 1 ] ),
Split_Views.closestLongDivisableBy( 40, minStepSize[ 2 ] ) },
minStepSize,
true );
// drosophila with 1000 views

final ViewSetupExplorer< SpimData2 > explorer = new ViewSetupExplorer<>( newSD, fileOut, new XmlIoSpimData2( "" ) );
Expand Down
Loading

0 comments on commit ae3c98f

Please sign in to comment.