Skip to content

Commit

Permalink
Don't convert to UnisignedShortType when exporting to HDF5
Browse files Browse the repository at this point in the history
  • Loading branch information
tpietzsch committed Mar 4, 2024
1 parent bfe90a8 commit 1fb1aa5
Showing 1 changed file with 69 additions and 104 deletions.
173 changes: 69 additions & 104 deletions src/main/java/bdv/ij/ExportImagePlusPlugIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
import bdv.spimdata.SequenceDescriptionMinimal;
import bdv.spimdata.SpimDataMinimal;
import bdv.spimdata.XmlIoSpimDataMinimal;
import bdv.img.imagestack.ImageStackImageLoader;
import bdv.img.n5.N5ImageLoader;
import bdv.img.virtualstack.VirtualStackImageLoader;
import fiji.util.gui.GenericDialogPlus;
import ij.IJ;
import ij.ImageJ;
Expand All @@ -63,6 +66,7 @@
import ij.gui.DialogListener;
import ij.gui.GenericDialog;
import mpicbg.spim.data.generic.sequence.BasicViewSetup;
import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader;
import mpicbg.spim.data.registration.ViewRegistration;
import mpicbg.spim.data.registration.ViewRegistrations;
import mpicbg.spim.data.sequence.Channel;
Expand Down Expand Up @@ -139,19 +143,44 @@ public void run()
progressWriter.out().println( "starting export..." );

// create ImgLoader wrapping the image
final ImagePlusImgLoader< ? > imgLoader;
switch ( imp.getType() )
final TypedBasicImgLoader< ? > imgLoader;
final Runnable clearCache;
final boolean isVirtual = imp.getStack() != null && imp.getStack().isVirtual();
if ( isVirtual )
{
case ImagePlus.GRAY8:
imgLoader = ImagePlusImgLoader.createGray8( imp, params.minMaxOption, params.rangeMin, params.rangeMax );
break;
case ImagePlus.GRAY16:
imgLoader = ImagePlusImgLoader.createGray16( imp, params.minMaxOption, params.rangeMin, params.rangeMax );
break;
case ImagePlus.GRAY32:
default:
imgLoader = ImagePlusImgLoader.createGray32( imp, params.minMaxOption, params.rangeMin, params.rangeMax );
break;
final VirtualStackImageLoader< ?, ?, ? > il;
switch ( imp.getType() )
{
case ImagePlus.GRAY8:
il = VirtualStackImageLoader.createUnsignedByteInstance( imp );
break;
case ImagePlus.GRAY16:
il = VirtualStackImageLoader.createUnsignedShortInstance( imp );
break;
case ImagePlus.GRAY32:
default:
il = VirtualStackImageLoader.createFloatInstance( imp );
break;
}
imgLoader = il;
clearCache = il.getCacheControl()::clearCache;
}
else
{
switch ( imp.getType() )
{
case ImagePlus.GRAY8:
imgLoader = ImageStackImageLoader.createUnsignedByteInstance( imp );
break;
case ImagePlus.GRAY16:
imgLoader = ImageStackImageLoader.createUnsignedShortInstance( imp );
break;
case ImagePlus.GRAY32:
default:
imgLoader = ImageStackImageLoader.createFloatInstance( imp );
break;
}
clearCache = () -> {};
}

final int numTimepoints = imp.getNFrames();
Expand All @@ -174,8 +203,7 @@ public void run()
timepoints.add( new TimePoint( t ) );
final SequenceDescriptionMinimal seq = new SequenceDescriptionMinimal( new TimePoints( timepoints ), setups, imgLoader, null );

Map< Integer, ExportMipmapInfo > perSetupExportMipmapInfo;
perSetupExportMipmapInfo = new HashMap<>();
final Map< Integer, ExportMipmapInfo > perSetupExportMipmapInfo = new HashMap<>();
final ExportMipmapInfo mipmapInfo = params.setMipmapManual
? new ExportMipmapInfo( params.resolutions, params.subdivisions )
: autoMipmapSettings;
Expand All @@ -189,7 +217,6 @@ public void run()
// required for all original planes contributing to a "plane of
// blocks" at the current level. If this is more than 1/4 of
// available memory, use the loopback image.
final boolean isVirtual = imp.getStack().isVirtual();
final long planeSizeInBytes = imp.getWidth() * imp.getHeight() * imp.getBytesPerPixel();
final long ijMaxMemory = IJ.maxMemory();
final int numCellCreatorThreads = Math.max( 1, PluginHelper.numThreads() - 1 );
Expand Down Expand Up @@ -228,7 +255,7 @@ public void afterEachPlane( final boolean usedLoopBack )
final long actuallyFree = max - total + free;

if ( actuallyFree < max / 2 )
imgLoader.clearCache();
clearCache.run();
}
}

Expand Down Expand Up @@ -291,12 +318,6 @@ protected static class Parameters

final File hdf5File;

final MinMaxOption minMaxOption;

final double rangeMin;

final double rangeMax;

final boolean deflate;

final boolean split;
Expand All @@ -308,17 +329,14 @@ protected static class Parameters
public Parameters(
final boolean setMipmapManual, final int[][] resolutions, final int[][] subdivisions,
final File seqFile, final File hdf5File,
final MinMaxOption minMaxOption, final double rangeMin, final double rangeMax, final boolean deflate,
final boolean deflate,
final boolean split, final int timepointsPerPartition, final int setupsPerPartition )
{
this.setMipmapManual = setMipmapManual;
this.resolutions = resolutions;
this.subdivisions = subdivisions;
this.seqFile = seqFile;
this.hdf5File = hdf5File;
this.minMaxOption = minMaxOption;
this.rangeMin = rangeMin;
this.rangeMax = rangeMax;
this.deflate = deflate;
this.split = split;
this.timepointsPerPartition = timepointsPerPartition;
Expand All @@ -332,12 +350,6 @@ public Parameters(

static String lastChunkSizes = "{32,32,4}, {16,16,8}, {8,8,8}";

static int lastMinMaxChoice = 2;

static double lastMin = 0;

static double lastMax = 65535;

static boolean lastSplit = false;

static int lastTimepointsPerPartition = 0;
Expand All @@ -350,12 +362,6 @@ public Parameters(

protected Parameters getParameters( final double impMin, final double impMax, final ExportMipmapInfo autoMipmapSettings )
{
if ( lastMinMaxChoice == 0 ) // use ImageJs...
{
lastMin = impMin;
lastMax = impMax;
}

while ( true )
{
final GenericDialogPlus gd = new GenericDialogPlus( "Export for BigDataViewer" );
Expand All @@ -367,15 +373,6 @@ protected Parameters getParameters( final double impMin, final double impMax, fi
gd.addStringField( "Hdf5_chunk_sizes", lastChunkSizes, 25 );
final TextField tfChunkSizes = ( TextField ) gd.getStringFields().lastElement();

gd.addMessage( "" );
final String[] minMaxChoices = new String[] { "Use ImageJ's current min/max setting", "Compute min/max of the (hyper-)stack", "Use values specified below" };
gd.addChoice( "Value_range", minMaxChoices, minMaxChoices[ lastMinMaxChoice ] );
final Choice cMinMaxChoices = (Choice) gd.getChoices().lastElement();
gd.addNumericField( "Min", lastMin, 0 );
final TextField tfMin = (TextField) gd.getNumericFields().lastElement();
gd.addNumericField( "Max", lastMax, 0 );
final TextField tfMax = (TextField) gd.getNumericFields().lastElement();

gd.addMessage( "" );
gd.addCheckbox( "split_hdf5", lastSplit );
final Checkbox cSplit = ( Checkbox ) gd.getCheckboxes().lastElement();
Expand All @@ -390,59 +387,37 @@ protected Parameters getParameters( final double impMin, final double impMax, fi
gd.addMessage( "" );
PluginHelper.addSaveAsFileField( gd, "Export_path", lastExportPath, 25 );

// gd.addMessage( "" );
// gd.addMessage( "This Plugin is developed by Tobias Pietzsch ([email protected])\n" );
// Bead_Registration.addHyperLinkListener( ( MultiLineLabel ) gd.getMessage(), "mailto:[email protected]" );

final String autoSubsampling = ProposeMipmaps.getArrayString( autoMipmapSettings.getExportResolutions() );
final String autoChunkSizes = ProposeMipmaps.getArrayString( autoMipmapSettings.getSubdivisions() );
gd.addDialogListener( new DialogListener()
{
@Override
public boolean dialogItemChanged( final GenericDialog dialog, final AWTEvent e )
gd.addDialogListener( ( dialog, e ) -> {
gd.getNextBoolean();
gd.getNextString();
gd.getNextString();
gd.getNextBoolean();
gd.getNextNumber();
gd.getNextNumber();
gd.getNextBoolean();
gd.getNextString();
if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED && e.getSource() == cManualMipmap )
{
gd.getNextBoolean();
gd.getNextString();
gd.getNextString();
gd.getNextChoiceIndex();
gd.getNextNumber();
gd.getNextNumber();
gd.getNextBoolean();
gd.getNextNumber();
gd.getNextNumber();
gd.getNextBoolean();
gd.getNextString();
if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED && e.getSource() == cMinMaxChoices )
final boolean useManual = cManualMipmap.getState();
tfSubsampling.setEnabled( useManual );
tfChunkSizes.setEnabled( useManual );
if ( !useManual )
{
final boolean enable = cMinMaxChoices.getSelectedIndex() == 2;
tfMin.setEnabled( enable );
tfMax.setEnabled( enable );
tfSubsampling.setText( autoSubsampling );
tfChunkSizes.setText( autoChunkSizes );
}
else if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED && e.getSource() == cManualMipmap )
{
final boolean useManual = cManualMipmap.getState();
tfSubsampling.setEnabled( useManual );
tfChunkSizes.setEnabled( useManual );
if ( !useManual )
{
tfSubsampling.setText( autoSubsampling );
tfChunkSizes.setText( autoChunkSizes );
}
}
else if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED && e.getSource() == cSplit )
{
final boolean split = cSplit.getState();
tfSplitTimepoints.setEnabled( split );
tfSplitSetups.setEnabled( split );
}
return true;
}
else if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED && e.getSource() == cSplit )
{
final boolean split = cSplit.getState();
tfSplitTimepoints.setEnabled( split );
tfSplitSetups.setEnabled( split );
}
return true;
} );

final boolean enable = lastMinMaxChoice == 2;
tfMin.setEnabled( enable );
tfMax.setEnabled( enable );

tfSubsampling.setEnabled( lastSetMipmapManual );
tfChunkSizes.setEnabled( lastSetMipmapManual );
if ( !lastSetMipmapManual )
Expand All @@ -461,9 +436,6 @@ else if ( e instanceof ItemEvent && e.getID() == ItemEvent.ITEM_STATE_CHANGED &&
lastSetMipmapManual = gd.getNextBoolean();
lastSubsampling = gd.getNextString();
lastChunkSizes = gd.getNextString();
lastMinMaxChoice = gd.getNextChoiceIndex();
lastMin = gd.getNextNumber();
lastMax = gd.getNextNumber();
lastSplit = gd.getNextBoolean();
lastTimepointsPerPartition = ( int ) gd.getNextNumber();
lastSetupsPerPartition = ( int ) gd.getNextNumber();
Expand All @@ -489,14 +461,6 @@ else if ( resolutions.length != subdivisions.length )
continue;
}

final MinMaxOption minMaxOption;
if ( lastMinMaxChoice == 0 )
minMaxOption = MinMaxOption.TAKE_FROM_IMAGEPROCESSOR;
else if ( lastMinMaxChoice == 1 )
minMaxOption = MinMaxOption.COMPUTE;
else
minMaxOption = MinMaxOption.SET;

String seqFilename = lastExportPath;
if ( !seqFilename.endsWith( ".xml" ) )
seqFilename += ".xml";
Expand All @@ -510,6 +474,7 @@ else if ( lastMinMaxChoice == 1 )
final String hdf5Filename = seqFilename.substring( 0, seqFilename.length() - 4 ) + ".h5";
final File hdf5File = new File( hdf5Filename );

return new Parameters( lastSetMipmapManual, resolutions, subdivisions, seqFile, hdf5File, minMaxOption, lastMin, lastMax, lastDeflate, lastSplit, lastTimepointsPerPartition, lastSetupsPerPartition ); }
return new Parameters( lastSetMipmapManual, resolutions, subdivisions, seqFile, hdf5File, lastDeflate, lastSplit, lastTimepointsPerPartition, lastSetupsPerPartition );
}
}
}

0 comments on commit 1fb1aa5

Please sign in to comment.