Skip to content

Commit

Permalink
Merge pull request #70 from saalfeldlab/dev
Browse files Browse the repository at this point in the history
4.0.0 candidate
  • Loading branch information
bogovicj authored Jan 26, 2024
2 parents 86ac6eb + 850f390 commit 169d1bb
Show file tree
Hide file tree
Showing 21 changed files with 3,156 additions and 504 deletions.
177 changes: 177 additions & 0 deletions doc/ngffDeveloperExamples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# NGFF developer examples

Examples of reading and writing [ngff](https://github.com/ome/ngff) data using the N5 API.

## v0.4

The example below deal with [ngff version 0.4](https://ngff.openmicroscopy.org/0.4/)

### write: N5ScalePyramidExporter

```java
// parameters
final String n5Root = "/home/john/tmp/ngff-test.zarr";
final String metaType = N5Importer.MetadataOmeZarrKey;
final String downsamplingMethod = N5ScalePyramidExporter.DOWN_AVG;
final String dataset = "";
final String blockSizeArgument = "64";
final boolean multiscale = true;
final String compressionType = "gzip";
final long[] imageDimensions = new long[] { 64, 32, 16 };
final double[] imageResolutions = new double[] { 2.0, 3.0, 4.0 };

// make a sample image
ImagePlus imp = makeDemoImagePlus(imageDimensions, imageResolutions);

// export the image
final N5ScalePyramidExporter exp = new N5ScalePyramidExporter(
imp, n5Root, dataset, blockSizeArgument, multiscale, downsamplingMethod, metaType, compressionType );
exp.run();
```


<details>

<summary>where `makeDemoImagePlus`</summary>

```java
public static ImagePlus makeDemoImagePlus( long[] dimensions, double... resolution )
{
final IntImagePlus<IntType> img = ImagePlusImgs.ints(dimensions);
final PlanarCursor<IntType> c = img.cursor();
int i = 0;
while( c.hasNext() )
c.next().set(i++);

final ImagePlus imp = img.getImagePlus();
for( i = 0; i < resolution.length; i++ )
if( i == 0 )
imp.getCalibration().pixelWidth = resolution[i];
else if( i == 1 )
imp.getCalibration().pixelHeight = resolution[i];
else if( i == 2 )
imp.getCalibration().pixelDepth = resolution[i];

return imp;
}
```

</details>


### write: low-level, single-scale

```java
// parameters
final String n5Root = "/home/john/tmp/ngff-test.zarr";
final String baseDataset = "";
final long[] imageDimensions = new long[] { 64, 32, 16 };
final int[] blockSize = new int[] { 64, 32, 16 };

// make a demo array
final ArrayImg<IntType, IntArray> img = makeDemoImage( imageDimensions );

// make demo metadata
final OmeNgffMetadata meta = OmeNgffMetadata.buildForWriting( 3,
"name",
AxisUtils.defaultAxes("x", "y", "z"), // a helper method to create axes
new String[] {"s0"}, // location of the array in the hierarchy
new double[][]{{ 2.0, 3.0, 4.0 }}, // resolution
null); // translation / offset (if null, interpreted as zero)


// make the n5 writer
final N5Writer n5 = new N5Factory().openWriter(n5Root);

// write the array
N5Utils.save(img, n5, baseDataset + "/s0", blockSize, new GzipCompression());

// write the metadata
try {
new OmeNgffMetadataParser().writeMetadata(meta, n5, baseDataset);
} catch (Exception e) { }
```

<details>

<summary>where `makeDemoImage`</summary>

```java
public static ArrayImg<IntType, IntArray> makeDemoImage( long[] dimensions )
{
int N = 1;
for (int i = 0; i < dimensions.length; i++)
N *= dimensions[i];

return ArrayImgs.ints(
IntStream.range(0, N).toArray(),
dimensions);
}
```

</details>

### write: low-level, multi-scale

```java
// parameters
final String n5Root = "/home/john/tmp/ngff-test.zarr";
final String baseDataset = "";
final long[] imageDimensions = new long[] { 64, 32, 16 };
final int[] blockSize = new int[] { 64, 32, 16 };

// make a demo array and scale levels
List<RandomAccessibleInterval<IntType>> scaleLevels = makeDemoImageMultiscales( 3, imageDimensions, new long[]{2, 2, 2} );

// make demo metadata

// make the resolutions, 3 scale levels, base resolution[2,3,4], downsampled by [2,2,2]
final double[][] resolutions = MetadataUtils.scalesAndTranslations(new double[]{2.0, 3.0, 4.0}, new double[]{2.0, 2.0, 2.0}, 3);
// this will be:
/*
* [[2, 3, 4]
* [4, 6, 8]
* [8, 12, 16]]
*/
final OmeNgffMetadata meta = OmeNgffMetadata.buildForWriting( 3,
"name",
AxisUtils.defaultAxes("x", "y", "z"), // a helper method to create axes
new String[] {"s0", "s1", "s2"}, // location of the scale arrays in the hierarchy
resolutions, // resolutions
null); // translation / offset (if null, interpreted as zero)

// make the n5 writer
final N5Writer n5 = new N5Factory().openWriter(n5Root);

// write the array
int s = 0;
for( RandomAccessibleInterval<IntType> img : scaleLevels )
N5Utils.save(img, n5, String.format("%s/s%d", baseDataset, s++), blockSize, new GzipCompression());

// write the metadata
try {
new OmeNgffMetadataParser().writeMetadata(meta, n5, baseDataset);
} catch (Exception e) { }
```

<details>

<summary>where `makeDemoImageMultiscales`</summary>

```java
public static List<RandomAccessibleInterval<IntType>> makeDemoImageMultiscales( int numScales, long[] baseDimensions, long[] factors )
{
int N = 1;
for (int i = 0; i < baseDimensions.length; i++)
N *= baseDimensions[i];

ArrayList<RandomAccessibleInterval<IntType>> scaleList = new ArrayList<>();
scaleList.add( ArrayImgs.ints( IntStream.range(0, N).toArray(), baseDimensions));
for( int i = 1; i < numScales; i++ )
scaleList.add(Views.subsample( scaleList.get(0), factors ));

return scaleList;
}
```

</details>
24 changes: 14 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-ij</artifactId>
<version>3.2.7-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>

<name>N5 ImageJ Bindings</name>
<description>ImageJ convenience layer for N5</description>
Expand Down Expand Up @@ -85,9 +85,10 @@
<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>

<jackson-jq.version>1.0.0-preview.20191208</jackson-jq.version>

<n5-universe.version>1.2.0</n5-universe.version>
<n5.version>3.1.1</n5.version>
<n5-universe.version>1.3.0</n5-universe.version>
<n5-zarr.version>1.2.0</n5-zarr.version>
<n5-zstandard.version>1.0.2</n5-zstandard.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -128,6 +129,10 @@
<groupId>net.imagej</groupId>
<artifactId>ij</artifactId>
</dependency>
<dependency>
<groupId>net.imagej</groupId>
<artifactId>imagej</artifactId>
</dependency>

<!-- SciJava dependencies -->
<dependency>
Expand Down Expand Up @@ -160,11 +165,6 @@
<groupId>com.google.api</groupId>
<artifactId>gax</artifactId>
</dependency>
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq</artifactId>
<version>${jackson-jq.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
Expand All @@ -183,7 +183,11 @@
<dependency>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-universe</artifactId>
<version>${n5-universe.version}</version>
</dependency>
<dependency>
<groupId>org.janelia</groupId>
<artifactId>n5-zstandard</artifactId>
<version>${n5-zstandard.version}</version>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.janelia.saalfeldlab.n5.converters;

import net.imglib2.converter.Converter;
import net.imglib2.type.label.LabelMultisetType;
import net.imglib2.type.numeric.integer.UnsignedLongType;

public class LabelMultisetLongConverter implements Converter< LabelMultisetType, UnsignedLongType > {

@Override
public void convert( final LabelMultisetType input, final UnsignedLongType output ) {

output.set( input.argMax() );
}

}
Loading

0 comments on commit 169d1bb

Please sign in to comment.