Skip to content

Commit

Permalink
fix: writing transform metadata
Browse files Browse the repository at this point in the history
* add transform write/parse tests
  • Loading branch information
bogovicj committed Sep 29, 2021
1 parent 1dd6cc2 commit a99d50a
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.janelia.saalfeldlab.n5.metadata.transforms;

import java.io.IOException;
import java.util.Arrays;

import org.janelia.saalfeldlab.n5.N5Reader;
import org.janelia.saalfeldlab.n5.imglib2.N5Utils;
Expand Down Expand Up @@ -55,11 +54,8 @@ protected static <T extends RealType<T> & NativeType<T>> double[] getDoubleArray
while (c.hasNext())
params[i++] = c.next().getRealDouble();

System.out.println("got params: " + Arrays.toString(params));
return params;

} catch (IOException e) {
}
} catch (IOException e) { }
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public class AffineSpatialTransform extends AbstractLinearSpatialTransform {

public final double[] affine;
public double[] affine;

public transient AffineGet transform;

Expand All @@ -25,8 +25,14 @@ public AffineSpatialTransform( final N5Reader n5, final String path ) {
buildTransform( affine );
}

public AffineSpatialTransform( final String path ) {
super("affine", path );
this.affine = null;
}

@Override
public AffineGet buildTransform( double[] parameters ) {
this.affine = parameters;
if( parameters.length == 6 ) {
AffineTransform2D tmp = new AffineTransform2D();
tmp.set( parameters );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public class ScaleSpatialTransform extends AbstractLinearSpatialTransform {

public final double[] scale;
public double[] scale;

public transient AffineGet transform;

Expand All @@ -20,14 +20,20 @@ public ScaleSpatialTransform( final double[] scale ) {
}

public ScaleSpatialTransform( final N5Reader n5, final String path ) {
super("scale");
super("scale", path );
this.scale = getParameters(n5);
buildTransform( scale );
}

public ScaleSpatialTransform( final String path ) {
super("scale", path );
this.scale = null;
}

@Override
public AffineGet buildTransform( double[] parameters )
{
this.scale = parameters;
if( parameters.length == 2 )
transform = new Scale2D(parameters);
else if( parameters.length == 3 )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public SpatialTransform deserialize(JsonElement json, Type typeOfT, JsonDeserial
private final SpatialTransform readTransformParameters( final SpatialTransform transform ) {

if( transform instanceof ParametrizedTransform ) {
System.out.println( "reading transform params" );
ParametrizedTransform pt = (ParametrizedTransform)transform;
if( pt.getParameterPath() != null ) {
pt.buildTransform( pt.getParameters(n5));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public class TranslationSpatialTransform extends AbstractLinearSpatialTransform {

public final double[] translation;
public double[] translation;

public transient AffineGet transform;

Expand All @@ -25,9 +25,15 @@ public TranslationSpatialTransform( final N5Reader n5, final String path ) {
buildTransform( translation );
}

public TranslationSpatialTransform( final String path ) {
super("translation", path );
this.translation = null;
}

@Override
public AffineGet buildTransform( double[] parameters )
{
this.translation = parameters;
if( parameters.length == 2 )
transform = new Translation2D(parameters);
else if( parameters.length == 3 )
Expand Down
155 changes: 155 additions & 0 deletions src/test/java/org/janelia/saalfeldlab/n5/metadata/TransformTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package org.janelia.saalfeldlab.n5.metadata;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;

import org.janelia.saalfeldlab.n5.GzipCompression;
import org.janelia.saalfeldlab.n5.N5FSWriter;
import org.janelia.saalfeldlab.n5.N5Writer;
import org.janelia.saalfeldlab.n5.RunImportExportTest;
import org.janelia.saalfeldlab.n5.imglib2.N5Utils;
import org.janelia.saalfeldlab.n5.metadata.canonical.CanonicalMetadata;
import org.janelia.saalfeldlab.n5.metadata.canonical.SpatialMetadataCanonical;
import org.janelia.saalfeldlab.n5.metadata.canonical.TranslatedTreeMetadataParser;
import org.janelia.saalfeldlab.n5.metadata.transforms.AffineSpatialTransform;
import org.janelia.saalfeldlab.n5.metadata.transforms.ScaleSpatialTransform;
import org.janelia.saalfeldlab.n5.metadata.transforms.SequenceSpatialTransform;
import org.janelia.saalfeldlab.n5.metadata.transforms.SpatialTransform;
import org.janelia.saalfeldlab.n5.metadata.transforms.TranslationSpatialTransform;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import net.imglib2.img.array.ArrayCursor;
import net.imglib2.img.array.ArrayImg;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.basictypeaccess.array.ByteArray;
import net.imglib2.img.basictypeaccess.array.DoubleArray;
import net.imglib2.type.numeric.integer.UnsignedByteType;
import net.imglib2.type.numeric.real.DoubleType;


public class TransformTests {

private File containerDir;

private N5Writer n5;

private ArrayImg<UnsignedByteType, ByteArray> img;

private double[] translation = new double[] { 100, 200, 300 };

private double[] scale = new double[] { 1.1, 2.2, 3.3 };

private double[] affine = new double[] {
1.1, 0.1, 0.2, -10,
0.3, 2.2, 0.4, -20,
0.5, 0.6, 3.3, -30 };

@Before
public void before()
{
URL configUrl = RunImportExportTest.class.getResource( "/plugins.config" );
File baseDir = new File( configUrl.getFile() ).getParentFile();
containerDir = new File( baseDir, "transforms.n5" );

try {
n5 = new N5FSWriter( containerDir.getCanonicalPath() );

int v = 0;
img = ArrayImgs.unsignedBytes( 3, 4, 5);
ArrayCursor<UnsignedByteType> c = img.cursor();
while( c.hasNext())
c.next().set( v++ );

} catch (IOException e) {
e.printStackTrace();
}
}

@After
public void after()
{
try {
n5.remove();
} catch (IOException e) { }
}

@Test
public void testParametrizedTransforms() throws IOException {

// translation
ArrayImg<DoubleType, DoubleArray> translationParams = ArrayImgs.doubles( translation, 3 );
N5Utils.save( translationParams, n5, "translation", new int[]{3}, new GzipCompression());

// scale
ArrayImg<DoubleType, DoubleArray> scaleParams = ArrayImgs.doubles( scale, 3 );
N5Utils.save( scaleParams, n5, "scale", new int[]{3}, new GzipCompression());

// affine
ArrayImg<DoubleType, DoubleArray> affineParams = ArrayImgs.doubles( affine, 12 );
N5Utils.save( affineParams, n5, "affine", new int[]{12}, new GzipCompression());

final ScaleSpatialTransform scaleTransform = new ScaleSpatialTransform( "scale" );
final TranslationSpatialTransform translationTransform = new TranslationSpatialTransform( "translation" );
final AffineSpatialTransform affineTransform = new AffineSpatialTransform( "affine" );
final SequenceSpatialTransform seq = new SequenceSpatialTransform(
new SpatialTransform[]{ affineTransform, scaleTransform, translationTransform });

// make an image
N5Utils.save( img, n5, "imgParam", new int[] {5, 5, 5}, new GzipCompression());

// set the transform metadata
SpatialMetadataCanonical transform = new SpatialMetadataCanonical(null, seq, "pixel", null);
n5.setAttribute("imgParam", "spatialTransform", transform);

testParsedTransformSeq("/imgParam");
}

@Test
public void testTransforms() throws IOException {

final ScaleSpatialTransform scaleTransform = new ScaleSpatialTransform( scale );
final TranslationSpatialTransform translationTransform = new TranslationSpatialTransform( translation );
final AffineSpatialTransform affineTransform = new AffineSpatialTransform( affine );
final SequenceSpatialTransform seq = new SequenceSpatialTransform(
new SpatialTransform[]{ affineTransform, scaleTransform, translationTransform });

// make an image
N5Utils.save( img, n5, "img", new int[] {5, 5, 5}, new GzipCompression());

// set the transform metadata
SpatialMetadataCanonical transform = new SpatialMetadataCanonical(null, seq, "pixel", null);
n5.setAttribute("img", "spatialTransform", transform);

testParsedTransformSeq("img");
}

private void testParsedTransformSeq( String dataset )
{
// canonical parser
final TranslatedTreeMetadataParser parser = new TranslatedTreeMetadataParser( n5, "." );
Optional<CanonicalMetadata> metaOpt = parser.parseMetadata(n5, dataset);
CanonicalMetadata meta = metaOpt.get();
SpatialMetadataCanonical parsedXfm = meta.getSpatialTransform();

Assert.assertTrue("parsed as sequence", parsedXfm.transform() instanceof SequenceSpatialTransform);
SequenceSpatialTransform parsedSeq = (SequenceSpatialTransform)parsedXfm.transform();
SpatialTransform transform0 = parsedSeq.getTransformations()[0];
SpatialTransform transform1 = parsedSeq.getTransformations()[1];
SpatialTransform transform2 = parsedSeq.getTransformations()[2];

Assert.assertTrue("transform0 is affine", transform0 instanceof AffineSpatialTransform);
Assert.assertArrayEquals( "parsed affine parameters", affine, ((AffineSpatialTransform)transform0).affine, 1e-9 );

Assert.assertTrue("transform1 is scale", transform1 instanceof ScaleSpatialTransform);
Assert.assertArrayEquals( "parsed scale parameters", scale, ((ScaleSpatialTransform)transform1).scale, 1e-9 );

Assert.assertTrue("transform2 is translation", transform2 instanceof TranslationSpatialTransform);
Assert.assertArrayEquals( "parsed translation parameters", translation, ((TranslationSpatialTransform)transform2).translation, 1e-9 );
}

}

0 comments on commit a99d50a

Please sign in to comment.