From b82443896d631797cce1cef8e3d69af33a93a381 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Wed, 6 Nov 2024 09:59:57 -0600 Subject: [PATCH 1/5] Leica TCS: make sure XML file is on used files list Fixes #4229. --- components/formats-gpl/src/loci/formats/in/TCSReader.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/TCSReader.java b/components/formats-gpl/src/loci/formats/in/TCSReader.java index e05296595f5..83a7c1b7586 100644 --- a/components/formats-gpl/src/loci/formats/in/TCSReader.java +++ b/components/formats-gpl/src/loci/formats/in/TCSReader.java @@ -247,6 +247,7 @@ protected void initFile(String id) throws FormatException, IOException { Arrays.sort(list); boolean isXML = checkSuffix(id, XML_SUFFIX); + if (isXML) xmlFile = l.getAbsolutePath(); if (list != null) { for (String file : list) { @@ -255,14 +256,17 @@ protected void initFile(String id) throws FormatException, IOException { break; } else if (checkSuffix(file, TiffReader.TIFF_SUFFIXES) && isXML) { + // this will result in a call to super.initFile(...), + // which calls close and resets xmlFile + // so xmlFile must be reset here before returning, + // otherwise the XML file will not appear on the used files list initFile(new Location(parent, file).getAbsolutePath()); + xmlFile = l.getAbsolutePath(); return; } } } - if (isXML) xmlFile = l.getAbsolutePath(); - super.initFile(id); MetadataStore store = makeFilterMetadata(); From 63bf9cab259d07a68dad3c6a5eb35f96be1b4365 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 11 Nov 2024 09:44:45 -0600 Subject: [PATCH 2/5] TCS: one more fix for keeping the XML file that is found --- .../src/loci/formats/in/TCSReader.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/TCSReader.java b/components/formats-gpl/src/loci/formats/in/TCSReader.java index 83a7c1b7586..8ab31f046c2 100644 --- a/components/formats-gpl/src/loci/formats/in/TCSReader.java +++ b/components/formats-gpl/src/loci/formats/in/TCSReader.java @@ -246,28 +246,29 @@ protected void initFile(String id) throws FormatException, IOException { String[] list = parent.list(); Arrays.sort(list); + String currentXMLFile = null; + boolean isXML = checkSuffix(id, XML_SUFFIX); - if (isXML) xmlFile = l.getAbsolutePath(); + if (isXML) currentXMLFile = l.getAbsolutePath(); if (list != null) { for (String file : list) { if (checkSuffix(file, XML_SUFFIX) && !isXML && isGroupFiles()) { - xmlFile = new Location(parent, file).getAbsolutePath(); + currentXMLFile = new Location(parent, file).getAbsolutePath(); break; } else if (checkSuffix(file, TiffReader.TIFF_SUFFIXES) && isXML) { - // this will result in a call to super.initFile(...), - // which calls close and resets xmlFile - // so xmlFile must be reset here before returning, - // otherwise the XML file will not appear on the used files list initFile(new Location(parent, file).getAbsolutePath()); - xmlFile = l.getAbsolutePath(); return; } } } + // super.initFile(...) calls close, which resets xmlFile + // so xmlFile must be set after super.initFile(...) returns, + // otherwise the XML file will not appear on the used files list super.initFile(id); + xmlFile = currentXMLFile; MetadataStore store = makeFilterMetadata(); From 5a00e833678cc0841495472f64f5e0d4cdd8317f Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Mon, 11 Nov 2024 09:45:35 -0600 Subject: [PATCH 3/5] Don't try to populate the PinholeSize if it wasn't parsed In particular, the pinhole size may be present in the XML, but just hasn't been parsed yet. --- .../src/loci/formats/in/LeicaHandler.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java index e5d4fdbbca0..9b9b17733da 100644 --- a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java +++ b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java @@ -202,8 +202,10 @@ public void endElement(String uri, String localName, String qName) { if (level != MetadataLevel.MINIMUM) { int nChannels = coreMeta.rgb ? 0 : numChannels; - for (int c=0; c Date: Mon, 11 Nov 2024 16:07:22 -0600 Subject: [PATCH 4/5] Don't set Plane metadata until we know the final plane counts --- .../src/loci/formats/in/LeicaHandler.java | 16 +++++++++++---- .../src/loci/formats/in/TCSReader.java | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java index 9b9b17733da..9dff7c51e5a 100644 --- a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java +++ b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java @@ -120,6 +120,9 @@ public class LeicaHandler extends BaseHandler { private MetadataLevel level; private int laserCount = 0; + private Map exposureTimes = new HashMap(); + private Map deltaT = new HashMap(); + // -- Constructor -- public LeicaHandler(MetadataStore store, MetadataLevel level) { @@ -144,6 +147,10 @@ public LeicaHandler(MetadataStore store, MetadataLevel level) { public Vector getLutNames() { return lutNames; } + public Map getExposureTimes() { return exposureTimes; } + + public Map getDeltaT() { return deltaT; } + // -- DefaultHandler API methods -- @Override @@ -549,7 +556,7 @@ else if (id.indexOf("WFC") == 1) { try { Double exposureTime = DataTools.parseDouble(value); if (exposureTime != null) { - store.setPlaneExposureTime(new Time(exposureTime, UNITS.SECOND), numDatasets, c); + exposureTimes.put(numDatasets + "-" + c, new Time(exposureTime, UNITS.SECOND)); } } catch (IndexOutOfBoundsException e) { } @@ -878,14 +885,14 @@ else if (qName.equals("TimeStamp") && numDatasets >= 0) { store.setImageAcquisitionDate(new Timestamp(date), numDatasets); } firstStamp = ms; - store.setPlaneDeltaT(new Time(0.0, UNITS.SECOND), numDatasets, count); + deltaT.put(numDatasets + "-" + count, new Time(0.0, UNITS.SECOND)); } else if (level != MetadataLevel.MINIMUM) { CoreMetadata coreMeta = core.get(numDatasets); int nImages = coreMeta.sizeZ * coreMeta.sizeT * coreMeta.sizeC; if (count < nImages) { ms -= firstStamp; - store.setPlaneDeltaT(new Time(ms / 1000.0, UNITS.SECOND), numDatasets, count); + deltaT.put(numDatasets + "-" + count, new Time(ms / 1000.0, UNITS.SECOND)); } } @@ -897,7 +904,8 @@ else if (qName.equals("RelTimeStamp") && level != MetadataLevel.MINIMUM) { if (count < nImages) { Double time = DataTools.parseDouble(attributes.getValue("Time")); if (time != null) { - store.setPlaneDeltaT(new Time(time, UNITS.SECOND), numDatasets, count++); + deltaT.put(numDatasets + "-" + count, new Time(time, UNITS.SECOND)); + count++; } } } diff --git a/components/formats-gpl/src/loci/formats/in/TCSReader.java b/components/formats-gpl/src/loci/formats/in/TCSReader.java index 8ab31f046c2..b2d9da0fb91 100644 --- a/components/formats-gpl/src/loci/formats/in/TCSReader.java +++ b/components/formats-gpl/src/loci/formats/in/TCSReader.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Map; import loci.common.DataTools; import loci.common.DateTools; @@ -49,6 +50,7 @@ import loci.formats.tiff.TiffParser; import ome.units.quantity.Length; +import ome.units.quantity.Time; /** * TCSReader is the file format reader for Leica TCS TIFF files and their @@ -465,6 +467,8 @@ else if (getSizeT() == 1) { else ms0.sizeZ *= ifds.size(); } + Map exposureTime = null; + Map deltaT = null; if (xmlFile != null) { // parse XML metadata @@ -474,6 +478,8 @@ else if (getSizeT() == 1) { LeicaHandler handler = new LeicaHandler(store, getMetadataOptions().getMetadataLevel()); XMLTools.parseXML(xml, handler); + exposureTime = handler.getExposureTimes(); + deltaT = handler.getDeltaT(); metadata = handler.getGlobalMetadata(); MetadataTools.merge(handler.getGlobalMetadata(), metadata, ""); @@ -509,6 +515,20 @@ else if (getSizeT() == 1) { if (sizeZ != null) { store.setPixelsPhysicalSizeZ(sizeZ, 0); } + + for (int s=0; s Date: Tue, 19 Nov 2024 14:49:28 -0600 Subject: [PATCH 5/5] Update LeicaHandler plane handling for backwards compatibility --- .../src/loci/formats/in/LeicaHandler.java | 41 +++++++++++++++++-- .../src/loci/formats/in/TCSReader.java | 2 +- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java index 9dff7c51e5a..35264b61a4d 100644 --- a/components/formats-gpl/src/loci/formats/in/LeicaHandler.java +++ b/components/formats-gpl/src/loci/formats/in/LeicaHandler.java @@ -120,6 +120,7 @@ public class LeicaHandler extends BaseHandler { private MetadataLevel level; private int laserCount = 0; + private boolean setPlaneMetadataInStore = true; private Map exposureTimes = new HashMap(); private Map deltaT = new HashMap(); @@ -139,6 +140,11 @@ public LeicaHandler(MetadataStore store, MetadataLevel level) { this.level = level; } + public LeicaHandler(MetadataStore store, MetadataLevel level, boolean planesInStore) { + this(store, level); + setPlaneMetadataInStore = planesInStore; + } + // -- LeicaHandler API methods -- public List getCoreMetadataList() { return core; } @@ -556,7 +562,13 @@ else if (id.indexOf("WFC") == 1) { try { Double exposureTime = DataTools.parseDouble(value); if (exposureTime != null) { - exposureTimes.put(numDatasets + "-" + c, new Time(exposureTime, UNITS.SECOND)); + Time expTime = new Time(exposureTime, UNITS.SECOND); + if (setPlaneMetadataInStore) { + store.setPlaneExposureTime(expTime, numDatasets, c); + } + else { + exposureTimes.put(numDatasets + "-" + c, expTime); + } } } catch (IndexOutOfBoundsException e) { } @@ -885,14 +897,28 @@ else if (qName.equals("TimeStamp") && numDatasets >= 0) { store.setImageAcquisitionDate(new Timestamp(date), numDatasets); } firstStamp = ms; - deltaT.put(numDatasets + "-" + count, new Time(0.0, UNITS.SECOND)); + + Time stamp = new Time(0.0, UNITS.SECOND); + if (setPlaneMetadataInStore) { + store.setPlaneDeltaT(stamp, numDatasets, count); + } + else { + deltaT.put(numDatasets + "-" + count, stamp); + } } else if (level != MetadataLevel.MINIMUM) { CoreMetadata coreMeta = core.get(numDatasets); int nImages = coreMeta.sizeZ * coreMeta.sizeT * coreMeta.sizeC; if (count < nImages) { ms -= firstStamp; - deltaT.put(numDatasets + "-" + count, new Time(ms / 1000.0, UNITS.SECOND)); + + Time stamp = new Time(ms / 1000.00, UNITS.SECOND); + if (setPlaneMetadataInStore) { + store.setPlaneDeltaT(stamp, numDatasets, count); + } + else { + deltaT.put(numDatasets + "-" + count, stamp); + } } } @@ -904,7 +930,14 @@ else if (qName.equals("RelTimeStamp") && level != MetadataLevel.MINIMUM) { if (count < nImages) { Double time = DataTools.parseDouble(attributes.getValue("Time")); if (time != null) { - deltaT.put(numDatasets + "-" + count, new Time(time, UNITS.SECOND)); + Time stamp = new Time(time, UNITS.SECOND); + if (setPlaneMetadataInStore) { + store.setPlaneDeltaT(stamp, numDatasets, count); + } + else { + deltaT.put(numDatasets + "-" + count, stamp); + } + count++; } } diff --git a/components/formats-gpl/src/loci/formats/in/TCSReader.java b/components/formats-gpl/src/loci/formats/in/TCSReader.java index b2d9da0fb91..9511c4552ba 100644 --- a/components/formats-gpl/src/loci/formats/in/TCSReader.java +++ b/components/formats-gpl/src/loci/formats/in/TCSReader.java @@ -476,7 +476,7 @@ else if (getSizeT() == 1) { xml = XMLTools.sanitizeXML(PREFIX + xml + SUFFIX); LeicaHandler handler = - new LeicaHandler(store, getMetadataOptions().getMetadataLevel()); + new LeicaHandler(store, getMetadataOptions().getMetadataLevel(), false); XMLTools.parseXML(xml, handler); exposureTime = handler.getExposureTimes(); deltaT = handler.getDeltaT();