From 506f4213b7982f10e71e3ae2d104b2a00618898a Mon Sep 17 00:00:00 2001 From: David Gault Date: Mon, 18 Apr 2022 12:20:06 +0100 Subject: [PATCH 1/8] ZarrReader: Add support for OME-XML from bf2raw --- src/loci/formats/in/ZarrReader.java | 354 ++++++++++++++-------------- 1 file changed, 176 insertions(+), 178 deletions(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index 8bf69fb..ffd03d0 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -150,207 +150,126 @@ protected void initFile(String id) throws FormatException, IOException { initializeZarrService(zarrRootPath); - /* - * Open OME metadata file - * TODO: Old code to either be reworked with writer or removed entirely - */ - if (omeMetaFile.exists()) { - Document omeDocument = null; - try (RandomAccessInputStream measurement = - new RandomAccessInputStream(omeMetaFile.getAbsolutePath())) { - try { - omeDocument = XMLTools.parseDOM(measurement); - } - catch (ParserConfigurationException e) { - throw new IOException(e); - } - catch (SAXException e) { - throw new IOException(e); - } - } - omeDocument.getDocumentElement().normalize(); - - OMEXMLService service = null; - String xml = null; - try - { - xml = XMLTools.getXML( omeDocument ); - } - catch (TransformerException e2 ) - { - LOGGER.debug( "", e2 ); - } - OMEXMLMetadata omexmlMeta = null; - try - { - service = new ServiceFactory().getInstance( OMEXMLService.class ); - omexmlMeta = service.createOMEXMLMetadata( xml ); - } - catch (DependencyException | ServiceException | NullPointerException e1 ) - { - LOGGER.debug( "", e1 ); + if(omeMetaFile.exists()) { + parseOMEXML(omeMetaFile, store); + } + // Parse base level attributes + Map attr = zarrService.getGroupAttr(zarrRootPath); + int attrIndex = 0; + if (attr != null && !attr.isEmpty()) { + parseResolutionCount(zarrRootPath, ""); + parseOmeroMetadata(zarrRootPath, ""); + String jsonAttr; + try { + jsonAttr = ZarrUtils.toJson(attr, true); + store.setXMLAnnotationValue(jsonAttr, attrIndex); + String xml_id = MetadataTools.createLSID("AttributesAnnotation:", attrIndex); + store.setXMLAnnotationID(xml_id, attrIndex); + } catch (JZarrException e) { + LOGGER.warn("Failed to convert attributes to JSON"); + e.printStackTrace(); } + } - int numDatasets = omexmlMeta.getImageCount(); - - int oldSeries = getSeries(); - core.clear(); - for (int i=0; i attributes = zarrService.getGroupAttr(zarrRootPath+File.separator+key); + if (attributes != null && !attributes.isEmpty()) { + parseResolutionCount(zarrRootPath, key); + parseLabels(zarrRootPath, key); + parseImageLabels(zarrRootPath, key); + attrIndex++; + String jsonAttr; + try { + jsonAttr = ZarrUtils.toJson(attributes, true); + store.setXMLAnnotationValue(jsonAttr, attrIndex); + String xml_id = MetadataTools.createLSID("AttributesAnnotation:"+key, attrIndex); + store.setXMLAnnotationID(xml_id, attrIndex); + } catch (JZarrException e) { + LOGGER.warn("Failed to convert attributes to JSON"); + e.printStackTrace(); } } - setSeries(oldSeries); - MetadataConverter.convertMetadata( omexmlMeta, store ); } - else { - // Parse base level attributes - Map attr = zarrService.getGroupAttr(zarrRootPath); - int attrIndex = 0; - if (attr != null && !attr.isEmpty()) { - parseResolutionCount(zarrRootPath, ""); - parseOmeroMetadata(zarrRootPath, ""); + + // Parse array attributes + for (String key: zarrService.getArrayKeys(zarrRootPath)) { + Map attributes = zarrService.getArrayAttr(zarrRootPath+File.separator+key); + if (attributes != null && !attributes.isEmpty()) { + attrIndex++; String jsonAttr; try { - jsonAttr = ZarrUtils.toJson(attr, true); + jsonAttr = ZarrUtils.toJson(attributes, true); store.setXMLAnnotationValue(jsonAttr, attrIndex); - String xml_id = MetadataTools.createLSID("AttributesAnnotation:", attrIndex); + String xml_id = MetadataTools.createLSID("AttributesAnnotation:"+key, attrIndex); store.setXMLAnnotationID(xml_id, attrIndex); } catch (JZarrException e) { LOGGER.warn("Failed to convert attributes to JSON"); e.printStackTrace(); } } + } - // Parse group attributes - for (String key: zarrService.getGroupKeys(zarrRootPath)) { - Map attributes = zarrService.getGroupAttr(zarrRootPath+File.separator+key); - if (attributes != null && !attributes.isEmpty()) { - parseResolutionCount(zarrRootPath, key); - parseLabels(zarrRootPath, key); - parseImageLabels(zarrRootPath, key); - attrIndex++; - String jsonAttr; - try { - jsonAttr = ZarrUtils.toJson(attributes, true); - store.setXMLAnnotationValue(jsonAttr, attrIndex); - String xml_id = MetadataTools.createLSID("AttributesAnnotation:"+key, attrIndex); - store.setXMLAnnotationID(xml_id, attrIndex); - } catch (JZarrException e) { - LOGGER.warn("Failed to convert attributes to JSON"); - e.printStackTrace(); - } - } - } + arrayPaths = new ArrayList(); + arrayPaths.addAll(zarrService.getArrayKeys(zarrRootPath)); + orderArrayPaths(zarrRootPath); - // Parse array attributes - for (String key: zarrService.getArrayKeys(zarrRootPath)) { - Map attributes = zarrService.getArrayAttr(zarrRootPath+File.separator+key); - if (attributes != null && !attributes.isEmpty()) { - attrIndex++; - String jsonAttr; - try { - jsonAttr = ZarrUtils.toJson(attributes, true); - store.setXMLAnnotationValue(jsonAttr, attrIndex); - String xml_id = MetadataTools.createLSID("AttributesAnnotation:"+key, attrIndex); - store.setXMLAnnotationID(xml_id, attrIndex); - } catch (JZarrException e) { - LOGGER.warn("Failed to convert attributes to JSON"); - e.printStackTrace(); - } - } + core.clear(); + int resolutionTotal = 0; + for (int i=0; i(); - arrayPaths.addAll(zarrService.getArrayKeys(zarrRootPath)); - orderArrayPaths(zarrRootPath); - - core.clear(); - int resolutionTotal = 0; - for (int i=0; i pathDimensions = pathArrayDimensions.get(arrayPaths.get(i)); - if (!pathDimensions.isEmpty()) { - ms.sizeX = shape[pathDimensions.indexOf("x")]; - ms.sizeY = shape[pathDimensions.indexOf("y")]; - ms.sizeT = shape[pathDimensions.indexOf("t")]; - ms.sizeZ = shape[pathDimensions.indexOf("z")]; - ms.sizeC = shape[pathDimensions.indexOf("c")]; - String newDimOrder = ""; - for (int d = 1; d < pathDimensions.size() + 1; d++) { - newDimOrder += pathDimensions.get(pathDimensions.size() - d).toUpperCase(); - } - dimensionOrder = newDimOrder; - } - ms.dimensionOrder = dimensionOrder; - ms.imageCount = getSizeZ() * getSizeC() * getSizeT(); - ms.littleEndian = zarrService.isLittleEndian(); - ms.rgb = false; - ms.interleaved = false; - ms.resolutionCount = resolutionCount; + ms.sizeX = shape[4]; + ms.sizeY = shape[3]; + ms.sizeT = shape[0]; + ms.sizeZ = shape[2]; + ms.sizeC = shape[1]; + ArrayList pathDimensions = pathArrayDimensions.get(arrayPaths.get(i)); + if (!pathDimensions.isEmpty()) { + ms.sizeX = shape[pathDimensions.indexOf("x")]; + ms.sizeY = shape[pathDimensions.indexOf("y")]; + ms.sizeT = shape[pathDimensions.indexOf("t")]; + ms.sizeZ = shape[pathDimensions.indexOf("z")]; + ms.sizeC = shape[pathDimensions.indexOf("c")]; + String newDimOrder = ""; + for (int d = 1; d < pathDimensions.size() + 1; d++) { + newDimOrder += pathDimensions.get(pathDimensions.size() - d).toUpperCase(); + } + dimensionOrder = newDimOrder; } + ms.dimensionOrder = dimensionOrder; + ms.imageCount = getSizeZ() * getSizeC() * getSizeT(); + ms.littleEndian = zarrService.isLittleEndian(); + ms.rgb = false; + ms.interleaved = false; + ms.resolutionCount = resolutionCount; } MetadataTools.populatePixels( store, this, true ); for (int i = 0; i < getSeriesCount(); i++) { @@ -779,6 +698,85 @@ private Double getDouble(Map src, String key) { return val.doubleValue(); } + private void parseOMEXML(Location omeMetaFile, MetadataStore store) throws IOException, FormatException { + Document omeDocument = null; + try (RandomAccessInputStream measurement = + new RandomAccessInputStream(omeMetaFile.getAbsolutePath())) { + try { + omeDocument = XMLTools.parseDOM(measurement); + } + catch (ParserConfigurationException e) { + throw new IOException(e); + } + catch (SAXException e) { + throw new IOException(e); + } + } + omeDocument.getDocumentElement().normalize(); + + OMEXMLService service = null; + String xml = null; + try + { + xml = XMLTools.getXML( omeDocument ); + } + catch (TransformerException e2 ) + { + LOGGER.debug( "", e2 ); + } + OMEXMLMetadata omexmlMeta = null; + try + { + service = new ServiceFactory().getInstance( OMEXMLService.class ); + omexmlMeta = service.createOMEXMLMetadata( xml ); + } + catch (DependencyException | ServiceException | NullPointerException e1 ) + { + LOGGER.debug( "", e1 ); + } + + int numDatasets = omexmlMeta.getImageCount(); + + int oldSeries = getSeries(); + core.clear(); + for (int i=0; i Date: Thu, 28 Apr 2022 15:52:37 +0100 Subject: [PATCH 2/8] ZarrReader: Resolve conflicts for OMEXML parsing --- src/loci/formats/in/ZarrReader.java | 359 ++++++++++++++-------------- 1 file changed, 179 insertions(+), 180 deletions(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index b00d794..55d9cce 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -147,102 +147,61 @@ protected void initFile(String id) throws FormatException, IOException { String zarrPath = zarrFolder.getAbsolutePath(); String zarrRootPath = zarrPath.substring(0, zarrPath.indexOf(".zarr") + 5); String name = zarrRootPath.substring(zarrRootPath.lastIndexOf(File.separator)+1, zarrRootPath.length() - 5); - Location omeMetaFile = new Location( zarrRootPath, name+".ome.xml" ); + Location omeMetaFile = new Location( zarrRootPath + File.separator + "OME", "METADATA.ome.xml" ); initializeZarrService(zarrRootPath); - /* - * Open OME metadata file - * TODO: Old code to either be reworked with writer or removed entirely - */ - if (omeMetaFile.exists()) { - Document omeDocument = null; - try (RandomAccessInputStream measurement = - new RandomAccessInputStream(omeMetaFile.getAbsolutePath())) { - try { - omeDocument = XMLTools.parseDOM(measurement); - } - catch (ParserConfigurationException e) { - throw new IOException(e); - } - catch (SAXException e) { - throw new IOException(e); - } - } - omeDocument.getDocumentElement().normalize(); + if(omeMetaFile.exists()) { + parseOMEXML(omeMetaFile, store); + } - OMEXMLService service = null; - String xml = null; - try - { - xml = XMLTools.getXML( omeDocument ); - } - catch (TransformerException e2 ) - { - LOGGER.debug( "", e2 ); - } - OMEXMLMetadata omexmlMeta = null; - try - { - service = new ServiceFactory().getInstance( OMEXMLService.class ); - omexmlMeta = service.createOMEXMLMetadata( xml ); - } - catch (DependencyException | ServiceException | NullPointerException e1 ) - { - LOGGER.debug( "", e1 ); + // Parse base level attributes + Map attr = zarrService.getGroupAttr(zarrRootPath); + int attrIndex = 0; + if (attr != null && !attr.isEmpty()) { + parseResolutionCount(zarrRootPath, ""); + parseOmeroMetadata(zarrRootPath, ""); + String jsonAttr; + try { + jsonAttr = ZarrUtils.toJson(attr, true); + store.setXMLAnnotationValue(jsonAttr, attrIndex); + String xml_id = MetadataTools.createLSID("Annotation", attrIndex); + store.setXMLAnnotationID(xml_id, attrIndex); + } catch (JZarrException e) { + LOGGER.warn("Failed to convert attributes to JSON"); + e.printStackTrace(); } + } - int numDatasets = omexmlMeta.getImageCount(); - - int oldSeries = getSeries(); - core.clear(); - for (int i=0; i attributes = zarrService.getGroupAttr(zarrRootPath+File.separator+key); + if (attributes != null && !attributes.isEmpty()) { + parseResolutionCount(zarrRootPath, key); + parseLabels(zarrRootPath, key); + parseImageLabels(zarrRootPath, key); + attrIndex++; + String jsonAttr; + try { + jsonAttr = ZarrUtils.toJson(attributes, true); + store.setXMLAnnotationValue(jsonAttr, attrIndex); + String xml_id = MetadataTools.createLSID("Annotation", attrIndex); + store.setXMLAnnotationID(xml_id, attrIndex); + } catch (JZarrException e) { + LOGGER.warn("Failed to convert attributes to JSON"); + e.printStackTrace(); } } - setSeries(oldSeries); - MetadataConverter.convertMetadata( omexmlMeta, store ); } - else { - // Parse base level attributes - Map attr = zarrService.getGroupAttr(zarrRootPath); - int attrIndex = 0; - if (attr != null && !attr.isEmpty()) { - parseResolutionCount(zarrRootPath, ""); - parseOmeroMetadata(zarrRootPath, ""); + + // Parse array attributes + for (String key: zarrService.getArrayKeys(zarrRootPath)) { + Map attributes = zarrService.getArrayAttr(zarrRootPath+File.separator+key); + if (attributes != null && !attributes.isEmpty()) { + attrIndex++; String jsonAttr; try { - jsonAttr = ZarrUtils.toJson(attr, true); + jsonAttr = ZarrUtils.toJson(attributes, true); store.setXMLAnnotationValue(jsonAttr, attrIndex); String xml_id = MetadataTools.createLSID("Annotation", attrIndex); store.setXMLAnnotationID(xml_id, attrIndex); @@ -251,107 +210,68 @@ protected void initFile(String id) throws FormatException, IOException { e.printStackTrace(); } } + } - // Parse group attributes - for (String key: zarrService.getGroupKeys(zarrRootPath)) { - Map attributes = zarrService.getGroupAttr(zarrRootPath+File.separator+key); - if (attributes != null && !attributes.isEmpty()) { - parseResolutionCount(zarrRootPath, key); - parseLabels(zarrRootPath, key); - parseImageLabels(zarrRootPath, key); - attrIndex++; - String jsonAttr; - try { - jsonAttr = ZarrUtils.toJson(attributes, true); - store.setXMLAnnotationValue(jsonAttr, attrIndex); - String xml_id = MetadataTools.createLSID("Annotation", attrIndex); - store.setXMLAnnotationID(xml_id, attrIndex); - } catch (JZarrException e) { - LOGGER.warn("Failed to convert attributes to JSON"); - e.printStackTrace(); - } - } - } + arrayPaths = new ArrayList(); + arrayPaths.addAll(zarrService.getArrayKeys(zarrRootPath)); + orderArrayPaths(zarrRootPath); - // Parse array attributes - for (String key: zarrService.getArrayKeys(zarrRootPath)) { - Map attributes = zarrService.getArrayAttr(zarrRootPath+File.separator+key); - if (attributes != null && !attributes.isEmpty()) { - attrIndex++; - String jsonAttr; - try { - jsonAttr = ZarrUtils.toJson(attributes, true); - store.setXMLAnnotationValue(jsonAttr, attrIndex); - String xml_id = MetadataTools.createLSID("Annotation", attrIndex); - store.setXMLAnnotationID(xml_id, attrIndex); - } catch (JZarrException e) { - LOGGER.warn("Failed to convert attributes to JSON"); - e.printStackTrace(); - } - } + core.clear(); + int resolutionTotal = 0; + for (int i=0; i(); - arrayPaths.addAll(zarrService.getArrayKeys(zarrRootPath)); - orderArrayPaths(zarrRootPath); - - core.clear(); - int resolutionTotal = 0; - for (int i=0; i pathDimensions = pathArrayDimensions.get(arrayPaths.get(i)); - if (pathDimensions != null && !pathDimensions.isEmpty()) { - ms.sizeX = shape[pathDimensions.indexOf("x")]; - ms.sizeY = shape[pathDimensions.indexOf("y")]; - ms.sizeT = shape[pathDimensions.indexOf("t")]; - ms.sizeZ = shape[pathDimensions.indexOf("z")]; - ms.sizeC = shape[pathDimensions.indexOf("c")]; - String newDimOrder = ""; - for (int d = 1; d < pathDimensions.size() + 1; d++) { - newDimOrder += pathDimensions.get(pathDimensions.size() - d).toUpperCase(); - } - dimensionOrder = newDimOrder; - } - ms.dimensionOrder = dimensionOrder; - ms.imageCount = getSizeZ() * getSizeC() * getSizeT(); - ms.littleEndian = zarrService.isLittleEndian(); - ms.rgb = false; - ms.interleaved = false; - ms.resolutionCount = resolutionCount; + if (hasFlattenedResolutions()) { + setSeries(i); } + else { + setSeries(coreIndexToSeries(i)); + setResolution(resolutionIndex); + if (i == resolutionTotal + resolutionCount - 1) { + resolutionTotal += resolutionCount; + } + } + + ms.pixelType = zarrService.getPixelType(); + int[] shape = zarrService.getShape(); + if (shape.length < 5) { + shape = get5DShape(shape); + } + + ms.sizeX = shape[4]; + ms.sizeY = shape[3]; + ms.sizeT = shape[0]; + ms.sizeZ = shape[2]; + ms.sizeC = shape[1]; + ArrayList pathDimensions = pathArrayDimensions.get(arrayPaths.get(i)); + if (pathDimensions != null && !pathDimensions.isEmpty()) { + ms.sizeX = shape[pathDimensions.indexOf("x")]; + ms.sizeY = shape[pathDimensions.indexOf("y")]; + ms.sizeT = shape[pathDimensions.indexOf("t")]; + ms.sizeZ = shape[pathDimensions.indexOf("z")]; + ms.sizeC = shape[pathDimensions.indexOf("c")]; + String newDimOrder = ""; + for (int d = 1; d < pathDimensions.size() + 1; d++) { + newDimOrder += pathDimensions.get(pathDimensions.size() - d).toUpperCase(); + } + dimensionOrder = newDimOrder; + } + ms.dimensionOrder = dimensionOrder; + ms.imageCount = getSizeZ() * getSizeC() * getSizeT(); + ms.littleEndian = zarrService.isLittleEndian(); + ms.rgb = false; + ms.interleaved = false; + ms.resolutionCount = resolutionCount; } MetadataTools.populatePixels( store, this, true ); @@ -777,6 +697,85 @@ private void parseOmeroMetadata(String root, String key) throws IOException, For } } + private void parseOMEXML(Location omeMetaFile, MetadataStore store) throws IOException, FormatException { + Document omeDocument = null; + try (RandomAccessInputStream measurement = + new RandomAccessInputStream(omeMetaFile.getAbsolutePath())) { + try { + omeDocument = XMLTools.parseDOM(measurement); + } + catch (ParserConfigurationException e) { + throw new IOException(e); + } + catch (SAXException e) { + throw new IOException(e); + } + } + omeDocument.getDocumentElement().normalize(); + + OMEXMLService service = null; + String xml = null; + try + { + xml = XMLTools.getXML( omeDocument ); + } + catch (TransformerException e2 ) + { + LOGGER.debug( "", e2 ); + } + OMEXMLMetadata omexmlMeta = null; + try + { + service = new ServiceFactory().getInstance( OMEXMLService.class ); + omexmlMeta = service.createOMEXMLMetadata( xml ); + } + catch (DependencyException | ServiceException | NullPointerException e1 ) + { + LOGGER.debug( "", e1 ); + } + + int numDatasets = omexmlMeta.getImageCount(); + + int oldSeries = getSeries(); + core.clear(); + for (int i=0; i src, String key) { Number val = (Number) src.get(key); if (val == null) { From 3c268549dd83fe6455a8d23672f9bac47fc5c57b Mon Sep 17 00:00:00 2001 From: David Gault Date: Tue, 3 May 2022 12:18:54 +0100 Subject: [PATCH 3/8] ZarrReader: Fix for multi image multi res indexes --- src/loci/formats/in/ZarrReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index 6def7bd..ecf3d36 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -489,7 +489,7 @@ else if (multiscaleAxes.get(i) instanceof HashMap) { if (i == 0) { resCounts.put(key.isEmpty() ? scalePath : key + File.separator + scalePath, numRes); } - resIndexes.put(scalePath, i); + resIndexes.put(key.isEmpty() ? scalePath : key + File.separator + scalePath, i); ArrayList list = resSeries.get(resCounts.size() - 1); list.add(key.isEmpty() ? scalePath : key + File.separator + scalePath); resSeries.put(resCounts.size() - 1, list); From b904648001ee1c0acf336845f356e7c5000a2fb7 Mon Sep 17 00:00:00 2001 From: David Gault Date: Wed, 11 May 2022 14:41:59 +0100 Subject: [PATCH 4/8] ZarrReader: Populate original metadata --- src/loci/formats/in/ZarrReader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index ecf3d36..cb71e92 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -727,6 +728,8 @@ private void parseOMEXML(Location omeMetaFile, MetadataStore store) throws IOExc { service = new ServiceFactory().getInstance( OMEXMLService.class ); omexmlMeta = service.createOMEXMLMetadata( xml ); + Hashtable originalMetadata = service.getOriginalMetadata(omexmlMeta); + if (originalMetadata != null) metadata = originalMetadata; } catch (DependencyException | ServiceException | NullPointerException e1 ) { From caae5375b7e742f5715b178cbbd315d35b044a57 Mon Sep 17 00:00:00 2001 From: David Gault Date: Wed, 11 May 2022 16:33:02 +0100 Subject: [PATCH 5/8] ZarrReader: Support multiple variations of well row and col --- src/loci/formats/in/ZarrReader.java | 46 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index cb71e92..83c789e 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -68,6 +68,7 @@ import loci.formats.services.JZarrServiceImpl; import ome.xml.meta.MetadataConverter; import ome.xml.model.primitives.NonNegativeInteger; +import ome.xml.model.primitives.PositiveInteger; import loci.formats.services.OMEXMLService; import loci.formats.services.ZarrService; @@ -538,6 +539,7 @@ private void parsePlate(String root, String key, MetadataStore store) throws IOE acqIdsIndexMap.put(acqId, a); store.setPlateAcquisitionID( MetadataTools.createLSID("PlateAcquisition", 0, acqId), 0, a); + store.setPlateAcquisitionMaximumFieldCount(new PositiveInteger(maximumfieldcount), 0, a); } } for (int c = 0; c < columns.size(); c++) { @@ -551,27 +553,37 @@ private void parsePlate(String root, String key, MetadataStore store) throws IOE for (int w = 0; w < wells.size(); w++) { Map well = (Map) wells.get(w); String wellPath = (String) well.get("path"); - String wellCol = (String) well.get("column_index"); - String wellRow = (String) well.get("row_index"); String well_id = MetadataTools.createLSID("Well", wellCount); store.setWellID(well_id, 0, w); - String[] parts = wellPath.split("/"); - if (wellRow == null || wellRow.isEmpty()) { - wellRow = parts[parts.length - 2]; - } - if (wellCol == null || wellCol.isEmpty()) { - wellCol = parts[parts.length - 1]; + + // column_index & row_index stored as Integer in bioformats2raw 0.3 + Integer wellColIndex = (Integer) well.get("column_index"); + Integer wellRowIndex = (Integer) well.get("row_index"); + if (wellColIndex == null && wellRowIndex == null) { + // columnIndex & rowIndex stored as Integer in OME-NGFF v0.4 + wellColIndex = (Integer) well.get("columnIndex"); + wellRowIndex = (Integer) well.get("rowIndex"); } - int rowIndex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(wellRow.toUpperCase()); - if (rowIndex == -1) { - rowIndex = Integer.parseInt(wellRow); + if (wellColIndex != null && wellRowIndex != null) { + store.setWellRow(new NonNegativeInteger(wellRowIndex), 0, w); + store.setWellColumn(new NonNegativeInteger(wellColIndex), 0, w); } - int colIndex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(wellCol.toUpperCase()); - if (colIndex == -1) { - colIndex = Integer.parseInt(wellCol); + else { + // for OME-NGFF v0.2 parse row and column index from the path + String[] parts = wellPath.split("/"); + String wellRow = parts[parts.length - 2]; + String wellCol = parts[parts.length - 1]; + int rowIndex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(wellRow.toUpperCase()); + if (rowIndex == -1) { + rowIndex = Integer.parseInt(wellRow); + } + int colIndex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(wellCol.toUpperCase()); + if (colIndex == -1) { + colIndex = Integer.parseInt(wellCol); + } + store.setWellRow(new NonNegativeInteger(rowIndex), 0, w); + store.setWellColumn(new NonNegativeInteger(colIndex), 0, w); } - store.setWellRow(new NonNegativeInteger(rowIndex), 0, w); - store.setWellColumn(new NonNegativeInteger(colIndex), 0, w); store.setWellExternalIdentifier(wellPath, 0, w); parseWells(root, wellPath, store, 0, w, acqIdsIndexMap); wellCount++; @@ -605,7 +617,7 @@ private void parseWells(String root, String key, MetadataStore store, int plateI } String imageID = MetadataTools.createLSID("Image", coreIndexToSeries(arrayPaths.indexOf(imageRefPath))); store.setWellSampleImageRef(imageID, plateIndex, wellIndex, i); - if (acquisition != null) { + if (acquisition != null && acquisition >= 0) { store.setPlateAcquisitionWellSampleRef(site_id, plateIndex, (int) acquisition, i); } wellSamplesCount++; From 063d8fe21598bf55d5c24a2700cfd83c158af0d0 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 12 May 2022 10:32:40 +0100 Subject: [PATCH 6/8] Trust OME-XML plane data if present --- src/loci/formats/in/ZarrReader.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index 83c789e..5cefa2c 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -84,7 +84,7 @@ public class ZarrReader extends FormatReader { private int wellCount = 0; private int wellSamplesCount = 0; private HashMap> pathArrayDimensions = new HashMap>(); - + private boolean planesPrePopulated = false; private boolean hasSPW = false; public ZarrReader() { @@ -275,7 +275,9 @@ protected void initFile(String id) throws FormatException, IOException { ms.resolutionCount = resolutionCount; } - MetadataTools.populatePixels( store, this, true ); + if (!planesPrePopulated) { + MetadataTools.populatePixels( store, this, true ); + } for (int i = 0; i < getSeriesCount(); i++) { store.setImageName(arrayPaths.get(seriesToCoreIndex(i)), i); store.setImageID(MetadataTools.createLSID("Image", i), i); @@ -742,6 +744,7 @@ private void parseOMEXML(Location omeMetaFile, MetadataStore store) throws IOExc omexmlMeta = service.createOMEXMLMetadata( xml ); Hashtable originalMetadata = service.getOriginalMetadata(omexmlMeta); if (originalMetadata != null) metadata = originalMetadata; + planesPrePopulated = true; } catch (DependencyException | ServiceException | NullPointerException e1 ) { From 135e888e5aa63ec6b677de2c5deb3de8be78b3f6 Mon Sep 17 00:00:00 2001 From: David Gault Date: Thu, 12 May 2022 16:44:19 +0100 Subject: [PATCH 7/8] Remove previous PyramidResolution annotations --- src/loci/formats/in/ZarrReader.java | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index 5cefa2c..afd15f2 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -67,6 +67,10 @@ import loci.formats.ome.OMEXMLMetadata; import loci.formats.services.JZarrServiceImpl; import ome.xml.meta.MetadataConverter; +import ome.xml.meta.MetadataRoot; +import ome.xml.model.MapAnnotation; +import ome.xml.model.OME; +import ome.xml.model.StructuredAnnotations; import ome.xml.model.primitives.NonNegativeInteger; import ome.xml.model.primitives.PositiveInteger; import loci.formats.services.OMEXMLService; @@ -275,9 +279,7 @@ protected void initFile(String id) throws FormatException, IOException { ms.resolutionCount = resolutionCount; } - if (!planesPrePopulated) { - MetadataTools.populatePixels( store, this, true ); - } + MetadataTools.populatePixels( store, this, !planesPrePopulated ); for (int i = 0; i < getSeriesCount(); i++) { store.setImageName(arrayPaths.get(seriesToCoreIndex(i)), i); store.setImageID(MetadataTools.createLSID("Image", i), i); @@ -790,6 +792,27 @@ private void parseOMEXML(Location omeMetaFile, MetadataStore store) throws IOExc } } setSeries(oldSeries); + + // Remove old PyramidResolution annotations + OME root = (OME) omexmlMeta.getRoot(); + StructuredAnnotations annotations = root.getStructuredAnnotations(); + if (annotations != null) { + int numMapAnnotations = annotations.sizeOfMapAnnotationList(); + int index = 0; + for (int i = 0; i < numMapAnnotations; i++) { + MapAnnotation mapAnnotation = annotations.getMapAnnotation(index); + String namespace = mapAnnotation.getNamespace(); + if (namespace != null && namespace.toLowerCase().contains("pyramidresolution")) { + annotations.removeMapAnnotation(mapAnnotation); + } + else { + index++; + } + } + root.setStructuredAnnotations(annotations); + omexmlMeta.setRoot((MetadataRoot) root); + } + MetadataConverter.convertMetadata( omexmlMeta, store ); } From 83843bc9b03b058defe424612a9018a0f42188b6 Mon Sep 17 00:00:00 2001 From: David Gault Date: Sat, 14 May 2022 18:49:31 +0100 Subject: [PATCH 8/8] Add null check for maximumfieldcount --- src/loci/formats/in/ZarrReader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/loci/formats/in/ZarrReader.java b/src/loci/formats/in/ZarrReader.java index afd15f2..53cf4a3 100644 --- a/src/loci/formats/in/ZarrReader.java +++ b/src/loci/formats/in/ZarrReader.java @@ -543,7 +543,9 @@ private void parsePlate(String root, String key, MetadataStore store) throws IOE acqIdsIndexMap.put(acqId, a); store.setPlateAcquisitionID( MetadataTools.createLSID("PlateAcquisition", 0, acqId), 0, a); - store.setPlateAcquisitionMaximumFieldCount(new PositiveInteger(maximumfieldcount), 0, a); + if (maximumfieldcount != null) { + store.setPlateAcquisitionMaximumFieldCount(new PositiveInteger(maximumfieldcount), 0, a); + } } } for (int c = 0; c < columns.size(); c++) {