Skip to content

Commit

Permalink
Merge branch 'master' of github.com:saalfeldlab/bigwarp
Browse files Browse the repository at this point in the history
  • Loading branch information
bogovicj committed Jul 12, 2024
2 parents e077ba9 + 3da8310 commit 4fe6a66
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 115 deletions.
5 changes: 3 additions & 2 deletions src/main/java/bdv/gui/sourceList/BigWarpSourceTableModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

Expand Down Expand Up @@ -45,8 +46,8 @@ public static enum SourceType { IMAGEPLUS, DATASET, URL };

private Component container;

public BigWarpSourceTableModel() {

public BigWarpSourceTableModel()
{
this(null);
}

Expand Down
137 changes: 125 additions & 12 deletions src/main/java/bdv/ij/ApplyBigwarpPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@
import net.imglib2.view.Views;

/**
*
* Apply a bigwarp transform to a 2d or 3d ImagePlus
*
*/
public class ApplyBigwarpPlugin implements PlugIn
{
Expand Down Expand Up @@ -825,18 +823,12 @@ public static <T> List<ImagePlus> apply(
final boolean wait,
final WriteDestinationOptions writeOpts) {

// int numChannels = bwData.movingSourceIndexList.size();
final int numChannels = bwData.numMovingSources();
// final List< SourceAndConverter< T >> sourcesxfm = BigWarp.wrapSourcesAsTransformed(
// bwData.sourceInfos,
// landmarks.getNumdims(),
// bwData );

final InvertibleRealTransform invXfm = new BigWarpTransform( landmarks, tranformTypeOption ).getTransformation();
for ( int i = 0; i < numChannels; i++ )
{
final SourceAndConverter< T > movingSource = bwData.getMovingSource( i );
// final int originalIdx = bwData.sources.indexOf(movingSource);
((WarpedSource<?>)(movingSource.getSpimSource())).updateTransform(invXfm);
((WarpedSource<?>)(movingSource.getSpimSource())).setIsTransformed(true);
}
Expand All @@ -858,12 +850,13 @@ public static <T> List<ImagePlus> apply(

if( writeOpts != null && writeOpts.n5Dataset != null && !writeOpts.n5Dataset.isEmpty())
{
final SourceAndConverter<T> src = bwData.getMovingSource(0);
final String unit = ApplyBigwarpPlugin.getUnit( bwData, resolutionOption );
runN5Export( bwData, bwData.sources, fieldOfViewOption,
runN5Export( bwData, src, fieldOfViewOption,
outputIntervalList.get( 0 ), interp,
offset, res, unit,
progressWriter, writeOpts,
Executors.newFixedThreadPool( nThreads ) );
Executors.newFixedThreadPool(nThreads));
return null;
}
else
Expand Down Expand Up @@ -959,6 +952,7 @@ private static double[] physicalOffsetFromPixelInterval(final RealInterval inter
return out;
}

@Deprecated
public static <S, T extends NativeType<T> & NumericType<T>> void runN5Export(
final BigWarpData<S> data,
final List< SourceAndConverter< S >> sources,
Expand All @@ -975,8 +969,12 @@ public static <S, T extends NativeType<T> & NumericType<T>> void runN5Export(
final int nd = BigWarp.detectNumDims( data.sources );
final double[] resolution = limit(nd,resolutionArg);

// final double[] offset = limit(nd,offsetArg);
final double[] offset = physicalOffsetFromPixelInterval(outputInterval, resolution);
final double[] offset = ApplyBigwarpPlugin.getPixelOffset( fieldOfViewOption, offsetArg, resolution,
outputInterval);

System.out.println("resolution: " + Arrays.toString(resolution));
System.out.println("offset : " + Arrays.toString(offset));
System.out.println("interval : " + Intervals.toString(outputInterval));

// setup n5 parameters
final String dataset = writeOpts.n5Dataset;
Expand Down Expand Up @@ -1074,6 +1072,121 @@ public static <S, T extends NativeType<T> & NumericType<T>> void runN5Export(
progressWriter.setProgress( 1.0 );
}

public static <S,T extends NativeType<T> & NumericType<T>> void runN5Export(
final BigWarpData<S> data,
final SourceAndConverter<S> sourceAndConverter,
final String fieldOfViewOption,
final Interval outputInterval,
final Interpolation interp,
final double[] offsetArg,
final double[] resolutionArg,
final String unit,
final ProgressWriter progressWriter,
final WriteDestinationOptions writeOpts,
final ExecutorService exec )
{

final int nd = BigWarp.detectNumDims( data.sources );
final double[] resolution = limit(nd,resolutionArg);

// pixel offset
final double[] offsetPixel = ApplyBigwarpPlugin.getPixelOffset( fieldOfViewOption, offsetArg, resolution,
outputInterval);

// setup n5 parameters
final String dataset = writeOpts.n5Dataset;
final int[] blockSize = writeOpts.blockSize;
final Compression compression = writeOpts.compression;
if( dataset == null || dataset.isEmpty() )
{
System.err.println("Problem with n5 dataset path: " + dataset);
return;
}
N5Writer n5;
try
{
n5 = new N5Factory().openWriter( writeOpts.pathOrN5Root );
}
catch ( final RuntimeException e1 )
{
System.err.println("Could not create n5 writer for: " + writeOpts.pathOrN5Root);
e1.printStackTrace();
return;
}

// build metadata
final OmeNgffMetadataParser parser = new OmeNgffMetadataParser();
final String[] axesLabels = nd == 2 ? new String[]{"x", "y"} : new String[]{"x", "y", "z"};
final Axis[] axes = new Axis[nd];
for (int i = 0; i < nd; i++)
axes[i] = new Axis(Axis.SPACE, axesLabels[i], unit);

// setup physical to pixel transform
final AffineTransform3D resolutionTransform = new AffineTransform3D();
resolutionTransform.set( resolution[ 0 ], 0, 0 );
resolutionTransform.set( resolution[ 1 ], 1, 1 );

if( resolution.length > 2 )
resolutionTransform.set( resolution[ 2 ], 2, 2 );

final double[] offsetPhysical = new double[resolution.length];
offsetPhysical[0] = resolution[0] * offsetPixel[0];
offsetPhysical[1] = resolution[1] * offsetPixel[1];

if( resolution.length > 2 )
offsetPhysical[2] = resolution[2] * offsetPixel[2];

final AffineTransform3D offsetTransform = new AffineTransform3D();
offsetTransform.set( offsetPhysical[ 0 ], 0, 3 );
offsetTransform.set( offsetPhysical[ 1 ], 1, 3 );

if( resolution.length > 2 )
offsetTransform.set( offsetPhysical[ 2 ], 2, 3 );

final AffineTransform3D pixelRenderToPhysical = new AffineTransform3D();
pixelRenderToPhysical.concatenate( resolutionTransform );
pixelRenderToPhysical.concatenate( offsetTransform );

// render and write
final String srcName = sourceAndConverter.getSpimSource().getName();
final BigWarpExporter<?> exporter = BigWarpExporter.getExporter( data,
sourceAndConverter, interp, progressWriter );
exporter.setRenderResolution( resolution );
exporter.setOffset( offsetPixel );
exporter.setInterval(Intervals.zeroMin(outputInterval));
exporter.setSingleChannelNoStack(true);
final RandomAccessibleInterval<T> imgExp = (RandomAccessibleInterval<T>)exporter.exportRai((Source<T>)sourceAndConverter.getSpimSource());
final IntervalView<T> img = Views.translateInverse( imgExp, Intervals.minAsLongArray( imgExp ));

RandomAccessibleInterval<T> imgToWrite;
if( nd == 2 )
imgToWrite = Views.hyperSlice( img, 2, 0 );
else
imgToWrite = img;

final String destDataset = dataset;

final OmeNgffMetadata metadata = OmeNgffMetadata.buildForWriting(nd, srcName, axes, new String[]{"s0"},
new double[][]{resolution}, new double[][]{offsetPhysical});

try
{
N5Utils.save( imgToWrite, n5, destDataset + "/s0", blockSize, compression, exec );
if( parser != null && metadata != null )
parser.writeMetadata( metadata, n5, destDataset );

n5.close();
}
catch ( final Exception e )
{
e.printStackTrace();
}


progressWriter.setProgress( 1.0 );
System.out.println("done");
}

@Override
public void run( final String arg )
{
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/bdv/ij/BigWarpToDeformationFieldPlugIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,10 @@ public static void writeTpsN5(

final String mvgSpaceName = data != null && data.numMovingSources() > 0 ? data.getMovingSource( 0 ).getSpimSource().getName() : "moving";
final String tgtSpaceName = data != null && data.numTargetSources() > 0 ? data.getTargetSource( 0 ).getSpimSource().getName() : "target";
final String input= mvgSpaceName;
final String output= tgtSpaceName;

// the TPS is an "inverse" transform from target space to moving space
final String input = tgtSpaceName;
final String output = mvgSpaceName;
final String name = input + " to " + output;

final String dataset = (n5Dataset == null) ? "" : n5Dataset;
Expand Down
20 changes: 15 additions & 5 deletions src/main/java/bigwarp/BigWarp.java
Original file line number Diff line number Diff line change
Expand Up @@ -1546,24 +1546,28 @@ public void exportAsImagePlus( boolean virtual, String path )
{
if( writeOpts.n5Dataset != null && !writeOpts.n5Dataset.isEmpty())
{
@SuppressWarnings("rawtypes")
final SourceAndConverter activeSource = getCurrentSourceInActiveViewer();

final String unit = ApplyBigwarpPlugin.getUnit( data, resolutionOption );
// export async
new Thread()
{
@SuppressWarnings("unchecked")
@Override
public void run()
{
progressWriter.setProgress( 0.01 );
ApplyBigwarpPlugin.runN5Export( data, data.sources, fieldOfViewOption,
outputIntervalList.get( 0 ), interp,
ApplyBigwarpPlugin.runN5Export( data, activeSource,
fieldOfViewOption,
outputIntervalList.get(0), interp,
offsetSpec, res, unit,
progressWriter, writeOpts,
Executors.newFixedThreadPool( nThreads ) );
Executors.newFixedThreadPool( nThreads ));

progressWriter.setProgress( 1.00 );
}
}.start();
}
}
else
{
// export
Expand All @@ -1575,6 +1579,12 @@ public void run()
}
}
}

private SourceAndConverter<?> getCurrentSourceInActiveViewer() {

BigWarpViewerFrame activeFrame = viewerFrameP.isActive() ? viewerFrameP : viewerFrameQ;
return activeFrame.getViewerPanel().state().getCurrentSource();
}

public void exportWarpField()
{
Expand Down
45 changes: 23 additions & 22 deletions src/main/java/bigwarp/BigWarpARGBExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,42 +92,43 @@ public boolean isRGB()
return true;
}

@SuppressWarnings("unchecked")
@Override
public RandomAccessibleInterval< ARGBType > exportRai()
{
final ArrayList< RandomAccessibleInterval< ARGBType > > raiList = new ArrayList< RandomAccessibleInterval< ARGBType > >();

buildTotalRenderTransform();
final AffineTransform3D srcXfm = new AffineTransform3D();


final int numChannels = bwData.numMovingSources();
final VoxelDimensions voxdim = new FinalVoxelDimensions( unit,
resolutionTransform.get( 0, 0 ),
resolutionTransform.get( 1, 1 ),
resolutionTransform.get( 2, 2 ));

for ( int i = 0; i < numChannels; i++ )
{
final Source<ARGBType> src = bwData.getMovingSource( i ).getSpimSource();
src.getSourceTransform(0, 0, srcXfm);
raiList.add( (RandomAccessibleInterval<ARGBType>)exportRai(src));
}
final RandomAccessibleInterval< ARGBType > raiStack = Views.stack( raiList );

// in pixel space
final RealRandomAccessible<ARGBType> raiRaw = ( RealRandomAccessible<ARGBType> ) src.getInterpolatedSource( 0, 0, interp );
return raiStack;
}

@Override
public RandomAccessibleInterval<?> exportRai(Source<?> src) {

buildTotalRenderTransform();
final AffineTransform3D srcXfm = new AffineTransform3D();
src.getSourceTransform(0, 0, srcXfm);

// the transform from world to new pixel coordinates
final AffineTransform3D pixelToPhysical = pixelRenderToPhysical.copy().inverse();
// but first need to transform from original pixel to world coordinates
pixelToPhysical.concatenate(srcXfm);
// in pixel space
final RealRandomAccessible<ARGBType> raiRaw = (RealRandomAccessible<ARGBType>)src.getInterpolatedSource(0, 0, interp);

// apply the transformations
final AffineRandomAccessible<ARGBType, AffineGet> rai = RealViews.affine(raiRaw, pixelToPhysical);
// the transform from world to new pixel coordinates
final AffineTransform3D pixelToPhysical = pixelRenderToPhysical.copy().inverse();
// but first need to transform from original pixel to world coordinates
pixelToPhysical.concatenate(srcXfm);

raiList.add( Views.interval( Views.raster( rai ), outputInterval ) );
}
final RandomAccessibleInterval< ARGBType > raiStack = Views.stack( raiList );
// apply the transformations
final AffineRandomAccessible<ARGBType, AffineGet> rai = RealViews.affine(raiRaw, pixelToPhysical);

return Views.interval(Views.raster(rai), outputInterval);

return raiStack;
}

@Override
Expand Down
Loading

0 comments on commit 4fe6a66

Please sign in to comment.