Skip to content

Commit

Permalink
Merge branch 'master' of github.com:glencoesoftware/bioformats2raw in…
Browse files Browse the repository at this point in the history
…to well-indexing
  • Loading branch information
melissalinkert committed Mar 24, 2021
2 parents 89b07cc + 0b2ff91 commit 35813db
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 85 deletions.
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
mavenLocal()
jcenter()
maven {
url 'https://artifacts.glencoesoftware.com/artifactory/ome.releases'
}
maven {
url 'https://repo.glencoesoftware.com/repository/n5-zarr-snapshots/'
}
maven {
url 'https://repo.glencoesoftware.com/repository/jzarr-snapshots'
}
maven {
url 'https://maven.scijava.org/content/groups/public'
}
Expand All @@ -37,7 +41,7 @@ dependencies {
implementation 'ome:formats-gpl:6.5.1'
implementation 'info.picocli:picocli:4.2.0'
implementation 'com.univocity:univocity-parsers:2.8.4'
implementation 'com.bc.zarr:jzarr:0.3.2'
implementation 'com.bc.zarr:jzarr:0.3.3-gs-SNAPSHOT'

implementation 'org.openpnp:opencv:3.4.2-1'
implementation 'me.tongfei:progressbar:0.9.0'
Expand Down
77 changes: 51 additions & 26 deletions src/main/java/com/glencoesoftware/bioformats2raw/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,19 @@ public class Converter implements Callable<Void> {
PyramidTiffReader.class, MiraxReader.class
};

@Option(
names = "--nested", negatable=true,
description = "Whether to use '/' as the chunk path seprator " +
"(false by default)"
)
private volatile boolean nested = false;

@Option(
names = "--pyramid-name",
description = "Name of pyramid (default: ${DEFAULT-VALUE}) " +
"[Can break compatibility with raw2ometiff]"
)
private volatile String pyramidName = "data.zarr";
private volatile String pyramidName = null;

@Option(
names = "--scale-format-string",
Expand Down Expand Up @@ -305,6 +312,14 @@ public class Converter implements Callable<Void> {
)
private volatile boolean noHCS = false;

@Option(
names = "--no-root-group",
description = "Turn off creation of root group and corresponding " +
"metadata [Will break compatibility with raw2ometiff]"

)
private volatile boolean noRootGroup = false;

/** Scaling implementation that will be used during downsampling. */
private volatile IImageScaler scaler = new SimpleImageScaler();

Expand Down Expand Up @@ -511,7 +526,7 @@ public void convert()
String xml = getService().getOMEXML(meta);

// write the original OME-XML to a file
Path metadataPath = outputPath.resolve(pyramidName);
Path metadataPath = getRootPath();
if (!Files.exists(metadataPath)) {
Files.createDirectories(metadataPath);
}
Expand Down Expand Up @@ -580,6 +595,21 @@ public void write(int series)
saveResolutions(series);
}

/**
* Get the root path of the dataset, which will contain Zarr and OME-XML.
* By default, this is the specified output directory.
* If "--pyramid-name" was used, then this will be the pyramid name
* as a subdirectory of the output directory.
*
* @return directory into which Zarr and OME-XML data is written
*/
private Path getRootPath() {
if (pyramidName == null) {
return outputPath;
}
return outputPath.resolve(pyramidName);
}

/**
* Retrieves the scaled format string arguments, adding additional ones
* from a provided CSV file.
Expand Down Expand Up @@ -771,9 +801,7 @@ private byte[] getTileDownsampled(
final String pathName =
String.format(scaleFormatString,
getScaleFormatStringArgs(series, resolution - 1));
final ZarrGroup root = ZarrGroup.open(outputPath.resolve(pyramidName));
final ZarrArray zarr = root.openArray(pathName);

final ZarrArray zarr = ZarrArray.open(getRootPath().resolve(pathName));
int[] dimensions = zarr.getShape();
int[] blockSizes = zarr.getChunks();
int activeTileWidth = blockSizes[blockSizes.length - 1];
Expand Down Expand Up @@ -902,8 +930,7 @@ private void processTile(
String pathName =
String.format(scaleFormatString,
getScaleFormatStringArgs(series, resolution));
final ZarrGroup root = ZarrGroup.open(outputPath.resolve(pyramidName));
final ZarrArray zarr = root.openArray(pathName);
final ZarrArray zarr = ZarrArray.open(getRootPath().resolve(pathName));
IFormatReader reader = readers.take();
boolean littleEndian = reader.isLittleEndian();
int bpp = FormatTools.getBytesPerPixel(reader.getPixelType());
Expand Down Expand Up @@ -990,14 +1017,15 @@ public void saveResolutions(int series)
);

// fileset level metadata
final String pyramidPath = outputPath.resolve(pyramidName).toString();
final ZarrGroup root = ZarrGroup.create(pyramidPath);
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("bioformats2raw.layout", LAYOUT);
root.writeAttributes(attributes);
if (!noRootGroup) {
final ZarrGroup root = ZarrGroup.create(getRootPath());
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("bioformats2raw.layout", LAYOUT);
root.writeAttributes(attributes);
}

// series level metadata
setSeriesLevelMetadata(root, series, resolutions);
setSeriesLevelMetadata(series, resolutions);

for (int resCounter=0; resCounter<resolutions; resCounter++) {
final int resolution = resCounter;
Expand All @@ -1018,16 +1046,17 @@ public void saveResolutions(int series)
}

DataType dataType = getZarrType(pixelType);
String resolutionString = "/" + String.format(
String resolutionString = String.format(
scaleFormatString, getScaleFormatStringArgs(series, resolution));
ArrayParams arrayParams = new ArrayParams()
.shape(getDimensions(
workingReader, scaledWidth, scaledHeight))
.chunks(new int[] {1, 1, 1, activeTileHeight, activeTileWidth})
.dataType(dataType)
.nested(nested)
.compressor(CompressorFactory.create(
compressionType.toString(), compressionProperties));
root.createArray(resolutionString, arrayParams);
ZarrArray.create(getRootPath().resolve(resolutionString), arrayParams);

nTile = new AtomicInteger(0);
tileCount = (int) Math.ceil((double) scaledWidth / tileWidth)
Expand Down Expand Up @@ -1116,7 +1145,7 @@ private void saveHCSMetadata(IMetadata meta) throws IOException {
}

// assumes only one plate defined
Path rootPath = outputPath.resolve(pyramidName);
Path rootPath = getRootPath();
ZarrGroup root = ZarrGroup.open(rootPath);
int plate = 0;
Map<String, Object> plateMap = new HashMap<String, Object>();
Expand Down Expand Up @@ -1250,17 +1279,15 @@ private void saveHCSMetadata(IMetadata meta) throws IOException {
* to attach the multiscales metadata to the group containing
* the pyramids.
*
* @param root Root {@link ZarrGroup}.
* @param series Series which is currently being written.
* @param resolutions Total number of resolutions from which
* names will be generated.
* @throws IOException
*/
private void setSeriesLevelMetadata(
ZarrGroup root, int series, int resolutions)
throws IOException
private void setSeriesLevelMetadata(int series, int resolutions)
throws IOException
{
String resolutionString = "/" + String.format(
String resolutionString = String.format(
scaleFormatString, getScaleFormatStringArgs(series, 0));
String seriesString = resolutionString.substring(0,
resolutionString.lastIndexOf('/'));
Expand All @@ -1285,14 +1312,14 @@ private void setSeriesLevelMetadata(
multiscales.add(multiscale);
List<Map<String, String>> datasets = new ArrayList<Map<String, String>>();
for (int r = 0; r < resolutions; r++) {
resolutionString = "/" + String.format(
resolutionString = String.format(
scaleFormatString, getScaleFormatStringArgs(series, r));
String lastPath = resolutionString.substring(
resolutionString.lastIndexOf('/') + 1);
datasets.add(Collections.singletonMap("path", lastPath));
}
multiscale.put("datasets", datasets);
ZarrGroup subGroup = root.createSubGroup(seriesString);
ZarrGroup subGroup = ZarrGroup.create(getRootPath().resolve(seriesString));
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("multiscales", multiscales);
subGroup.writeAttributes(attributes);
Expand Down Expand Up @@ -1522,9 +1549,7 @@ public static DataType getZarrType(int type) {
}

private void checkOutputPaths() {
if ((!pyramidName.equals("data.zarr")) ||
!scaleFormatString.equals("%d/%d"))
{
if (pyramidName != null || !scaleFormatString.equals("%d/%d")) {
LOGGER.info("Output will be incompatible with raw2ometiff " +
"(pyramidName: {}, scaleFormatString: {})",
pyramidName, scaleFormatString);
Expand Down
Loading

0 comments on commit 35813db

Please sign in to comment.