Skip to content

Commit

Permalink
merge master -Dorg -Ssuccess-only: PR 4272 (FakeReader: add support f…
Browse files Browse the repository at this point in the history
…or populating channel wavelengths and instrument)
  • Loading branch information
snoopycrimecop committed Feb 9, 2025
2 parents 19ef383 + fdc6801 commit f839c7f
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 0 deletions.
73 changes: 73 additions & 0 deletions components/formats-bsd/src/loci/formats/in/FakeReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

package loci.formats.in;

import static ome.xml.model.Channel.getEmissionWavelengthUnitXsdDefault;
import static ome.xml.model.Channel.getExcitationWavelengthUnitXsdDefault;
import static ome.xml.model.Pixels.getPhysicalSizeXUnitXsdDefault;
import static ome.xml.model.Pixels.getPhysicalSizeYUnitXsdDefault;
import static ome.xml.model.Pixels.getPhysicalSizeZUnitXsdDefault;
Expand Down Expand Up @@ -150,6 +152,10 @@ public class FakeReader extends FormatReader {
/* physical sizes */
private Length physicalSizeX, physicalSizeY, physicalSizeZ;

/* channel wavelengths */
ArrayList<Length> excitationWavelengths = new ArrayList<Length>();
ArrayList<Length> emissionWavelengths = new ArrayList<Length>();

/* annotation counts per file */
private int annBool = 0;
private int annComment = 0;
Expand Down Expand Up @@ -509,6 +515,8 @@ public void close(boolean fileOnly) throws IOException {
plateCols = 0;
fields = 0;
plateAcqs = 0;
excitationWavelengths.clear();
emissionWavelengths.clear();
super.close(fileOnly);
}

Expand Down Expand Up @@ -607,6 +615,7 @@ protected void initFile(String id) throws FormatException, IOException {
boolean metadataComplete = true;
boolean thumbnail = false;
boolean withMicrobeam = false;
boolean withInstrument = false;

int seriesCount = 1;
int resolutionCount = 1;
Expand Down Expand Up @@ -716,6 +725,7 @@ else if (key.equals("pixelType")) {
else if (key.equals("fields")) fields = intValue;
else if (key.equals("plateAcqs")) plateAcqs = intValue;
else if (key.equals("withMicrobeam")) withMicrobeam = boolValue;
else if (key.equals("withInstrument")) withInstrument = boolValue;
else if (key.equals("annLong")) annLong = intValue;
else if (key.equals("annDouble")) annDouble = intValue;
else if (key.equals("annMap")) annMap = intValue;
Expand Down Expand Up @@ -755,6 +765,20 @@ else if (key.startsWith("color_")) {
color.add(null);
}
color.set(index, parseColor(value));
} else if (key.startsWith("emission_")) {
int index = Integer.parseInt(key.substring(key.indexOf('_') + 1));
while (index >= emissionWavelengths.size()) {
emissionWavelengths.add(null);
}
emissionWavelengths.set(index, parseWavelength(
value, getEmissionWavelengthUnitXsdDefault()));
} else if (key.startsWith("excitation_")) {
int index = Integer.parseInt(key.substring(key.indexOf('_') + 1));
while (index >= excitationWavelengths.size()) {
excitationWavelengths.add(null);
}
excitationWavelengths.set(index, parseWavelength(
value, getExcitationWavelengthUnitXsdDefault()));
} else if (key.equals("sleepOpenBytes")) {
sleepOpenBytes = intValue;
} else if (key.equals("sleepInitFile")) {
Expand Down Expand Up @@ -834,6 +858,8 @@ else if (dimOrder == null) {
populateSPW(store, screens, plates, plateRows, plateCols, fields, plateAcqs, withMicrobeam);
if (imageCount > 0) seriesCount = imageCount;
else hasSPW = false; // failed to generate SPW metadata
} else if (withInstrument) {
populateInstrument(store);
}

// populate core metadata
Expand Down Expand Up @@ -878,6 +904,7 @@ else if (dimOrder == null) {
MetadataTools.populatePixels(store, this, planeInfo);
fillExposureTime(store);
fillPhysicalSizes(store);
fillChannelWavelengths(store);
for (int currentImageIndex=0; currentImageIndex<seriesCount; currentImageIndex++) {
if (currentImageIndex < seriesTables.size()) {
parseSeriesTable(seriesTables.get(currentImageIndex), store, currentImageIndex);
Expand Down Expand Up @@ -960,6 +987,19 @@ private void fillExposureTime(MetadataStore store) {
setSeries(oldSeries);
}

private void fillChannelWavelengths(MetadataStore store) {
for (int s=0; s<getSeriesCount(); s++) {
for (int c=0; c<getEffectiveSizeC(); c++) {
if (c < emissionWavelengths.size() && emissionWavelengths.get(c) != null) {
store.setChannelEmissionWavelength(emissionWavelengths.get(c), s, c);
}
if (c < excitationWavelengths.size() && excitationWavelengths.get(c) != null) {
store.setChannelExcitationWavelength(excitationWavelengths.get(c), s, c);
}
}
}
}

private void fillAcquisitionDate(MetadataStore store, String date, int imageIndex) {
if (date == null) return;
if(DateTools.getTime(date, DateTools.FILENAME_FORMAT) != -1) {
Expand Down Expand Up @@ -1216,6 +1256,18 @@ private void parseSeriesTable(IniTable table, MetadataStore store, int newSeries
for (int c=0; c<getEffectiveSizeC(); c++) {
String channelName = table.get("ChannelName_" + c);
store.setChannelName(channelName, newSeries, c);
String emissionWavelength = table.get("ChannelEmissionWavelength_" + c);
if (emissionWavelength != null) {
store.setChannelEmissionWavelength(
parseWavelength(emissionWavelength, getEmissionWavelengthUnitXsdDefault()),
newSeries, c);
}
String excitationWavelength = table.get("ChannelExcitationWavelength_" + c);
if (excitationWavelength != null) {
store.setChannelExcitationWavelength(
parseWavelength(excitationWavelength, getExcitationWavelengthUnitXsdDefault()),
newSeries, c);
}
}

for (int i=0; i<getImageCount(); i++) {
Expand Down Expand Up @@ -1376,6 +1428,15 @@ private int populateSPW(MetadataStore store, int screens, int plates, int rows,
return ome.sizeOfImageList();
}

private void populateInstrument(MetadataStore store)
{
final XMLMockObjects xml = new XMLMockObjects();
OME ome = xml.getRoot();
ome.addInstrument(xml.createInstrument(true));
getOmeXmlMetadata().setRoot(new OMEXMLMetadataRoot(ome));
getOmeXmlService().convertMetadata(omeXmlMetadata, store);
}

/** Creates a mapping between indices and color values. */
private void createIndexMap(int num) {
int sizeC = core.get(0).sizeC;
Expand Down Expand Up @@ -1484,4 +1545,16 @@ private Length parsePhysicalSize(String s, String defaultUnit) {
return physicalSize;
}

private Length parseWavelength(String s, String defaultUnit) {
Length wavelength = FormatTools.parseLength(s, defaultUnit);
if (wavelength == null) {
throw new RuntimeException("Invalid wavelength: " + s);
}
if (!FormatTools.isPositiveValue(wavelength.value().doubleValue())) {
LOGGER.warn("Invalid wavelength value: {}", wavelength.value());
return null;
}
return wavelength;
}

}
102 changes: 102 additions & 0 deletions components/formats-bsd/test/loci/formats/utests/FakeReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -722,4 +722,106 @@ public void testInvalidDimensionOrder() throws Exception {
reader.setId("test&dimOrder=CXYZT.fake");
}

@Test
public void testExcitationWavelengths() throws Exception {
File fakeIni = mkIni("excitationWavelengths.fake.ini",
"sizeC=5",
"excitation_0 = 502nm",
"excitation_1 = 502.0nm",
"excitation_2 = 502",
"excitation_4 = 5020Å");
reader.setId(wd.resolve("excitationWavelengths.fake").toString());
assertEquals(reader.getSizeC(), 5);
m = service.asRetrieve(reader.getMetadataStore());
assertTrue(service.validateOMEXML(service.getOMEXML(m)));
assertEquals(m.getChannelExcitationWavelength(0, 0), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(0, 1), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(0, 2), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(0, 3), null);
assertEquals(m.getChannelExcitationWavelength(0, 4), new Length(5020.0, UNITS.ANGSTROM));
reader.close();
}

@Test
public void testEmissionWavelengths() throws Exception {
File fakeIni = mkIni("emissionWavelengths.fake.ini",
"sizeC=5",
"emission_0 = 502nm",
"emission_1 = 502.0nm",
"emission_2 = 502",
"emission_4 = 5020Å");
reader.setId(wd.resolve("emissionWavelengths.fake").toString());
assertEquals(reader.getSizeC(), 5);
m = service.asRetrieve(reader.getMetadataStore());
assertTrue(service.validateOMEXML(service.getOMEXML(m)));
assertEquals(m.getChannelEmissionWavelength(0, 0), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 1), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 2), new Length(502.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 3), null);
assertEquals(m.getChannelEmissionWavelength(0, 4), new Length(5020.0, UNITS.ANGSTROM));
reader.close();
}

@Test
public void testWavelengthSeries() throws Exception {
File fakeIni = mkIni("multiseries_wavelengths.fake.ini",
"series=2",
"sizeC=2",
"[series_0]",
"ChannelExcitationWavelength_0=340.0nm",
"ChannelEmissionWavelength_0=450.0nm",
"ChannelExcitationWavelength_1=470.0nm",
"ChannelEmissionWavelength_1=512.0nm",
"[series_1]",
"ChannelExcitationWavelength_0=350.0nm",
"ChannelEmissionWavelength_0=425.0nm",
"ChannelExcitationWavelength_1=500.0nm",
"ChannelEmissionWavelength_1=580.0nm");
reader.setId(fakeIni.getAbsolutePath());
m = service.asRetrieve(reader.getMetadataStore());
assertEquals(m.getChannelExcitationWavelength(0, 0), new Length(340.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 0), new Length(450.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(0, 1), new Length(470.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 1), new Length(512.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(1, 0), new Length(350.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(1, 0), new Length(425.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(1, 1), new Length(500.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(1, 1), new Length(580.0, UNITS.NANOMETER));
}

@Test
public void testWavelengthSeriesOverride() throws Exception {
File fakeIni = mkIni("multiseries_wavelengths.fake.ini",
"series=2",
"sizeC=2",
"excitation_0=340nm",
"emission_0=450nm",
"excitation_1=470nm",
"emission_1=512nm",
"[series_0]",
"[series_1]",
"ChannelExcitationWavelength_0=350.0nm",
"ChannelEmissionWavelength_0=425.0nm",
"ChannelExcitationWavelength_1=500.0nm",
"ChannelEmissionWavelength_1=580.0nm");
reader.setId(fakeIni.getAbsolutePath());
m = service.asRetrieve(reader.getMetadataStore());
assertEquals(m.getChannelExcitationWavelength(0, 0), new Length(340.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 0), new Length(450.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(0, 1), new Length(470.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(0, 1), new Length(512.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(1, 0), new Length(350.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(1, 0), new Length(425.0, UNITS.NANOMETER));
assertEquals(m.getChannelExcitationWavelength(1, 1), new Length(500.0, UNITS.NANOMETER));
assertEquals(m.getChannelEmissionWavelength(1, 1), new Length(580.0, UNITS.NANOMETER));
}

@Test
public void testInstrument() throws Exception {
reader.setId("test&withInstrument=true.fake");
m = service.asRetrieve(reader.getMetadataStore());
assertTrue(service.validateOMEXML(service.getOMEXML(m)));
assertEquals(m.getInstrumentCount(), 1);
reader.close();
}
}

0 comments on commit f839c7f

Please sign in to comment.