/* * #%L * OME Bio-Formats manual and automated test suite. * %% * Copyright (C) 2006 - 2015 Open Microscopy Environment: * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * - University of Dundee * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package loci.tests.testng; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileReader; import java.io.InputStreamReader; import java.io.IOException; import loci.common.Constants; import loci.common.DataTools; import loci.common.IniList; import loci.common.IniParser; import loci.common.IniTable; import loci.common.IniWriter; import loci.common.Location; import loci.formats.FormatException; import loci.formats.FormatTools; import loci.formats.IFormatReader; import loci.formats.ImageReader; import loci.formats.ReaderWrapper; import loci.formats.meta.IMetadata; import ome.xml.model.primitives.PositiveInteger; import ome.xml.model.primitives.PositiveFloat; import ome.xml.model.primitives.Timestamp; import ome.units.quantity.Length; import ome.units.quantity.Time; import ome.units.UNITS; /** */ public class Configuration { // -- Constants -- public static final int TILE_SIZE = 512; private static final String ACCESS_TIME = "access_ms"; private static final String MEMORY = "mem_mb"; private static final String TEST = "test"; private static final String READER = "reader"; private static final String SERIES = " series_"; private static final String SIZE_X = "SizeX"; private static final String SIZE_Y = "SizeY"; private static final String SIZE_Z = "SizeZ"; private static final String SIZE_C = "SizeC"; private static final String SIZE_T = "SizeT"; private static final String DIMENSION_ORDER = "DimensionOrder"; private static final String IS_INDEXED = "Indexed"; private static final String IS_INTERLEAVED = "Interleaved"; private static final String IS_FALSE_COLOR = "FalseColor"; private static final String IS_RGB = "RGB"; private static final String THUMB_SIZE_X = "ThumbSizeX"; private static final String THUMB_SIZE_Y = "ThumbSizeY"; private static final String PIXEL_TYPE = "PixelType"; private static final String IS_LITTLE_ENDIAN = "LittleEndian"; private static final String MD5 = "MD5"; private static final String ALTERNATE_MD5 = "Alternate_MD5"; private static final String TILE_MD5 = "Tile_MD5"; private static final String TILE_ALTERNATE_MD5 = "Tile_Alternate_MD5"; private static final String PHYSICAL_SIZE_X = "PhysicalSizeX"; private static final String PHYSICAL_SIZE_Y = "PhysicalSizeY"; private static final String PHYSICAL_SIZE_Z = "PhysicalSizeZ"; private static final String TIME_INCREMENT = "TimeIncrement"; private static final String LIGHT_SOURCE = "LightSource_"; private static final String CHANNEL_NAME = "ChannelName_"; private static final String EXPOSURE_TIME = "ExposureTime_"; private static final String EMISSION_WAVELENGTH = "EmissionWavelength_"; private static final String EXCITATION_WAVELENGTH = "ExcitationWavelength_"; private static final String DETECTOR = "Detector_"; private static final String NAME = "Name"; private static final String DESCRIPTION = "Description"; private static final String SERIES_COUNT = "series_count"; private static final String CHANNEL_COUNT = "channel_count"; private static final String DATE = "Date"; private static final String DELTA_T = "DeltaT_"; private static final String X_POSITION = "PositionX_"; private static final String Y_POSITION = "PositionY_"; private static final String Z_POSITION = "PositionZ_"; // -- Fields -- private String dataFile; private String configFile; private IniList ini; private IniTable currentTable; private IniTable globalTable; // -- Constructors -- public Configuration(String dataFile, String configFile) throws IOException { this.dataFile = dataFile; this.configFile = configFile; BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(this.configFile), Constants.ENCODING)); IniParser parser = new IniParser(); parser.setCommentDelimiter(null); ini = parser.parseINI(reader); pruneINI(); } public Configuration(IFormatReader reader, String configFile) { this.dataFile = reader.getCurrentFile(); this.configFile = configFile; populateINI(reader); } // -- Configuration API methods -- // -- Global metadata -- public String getFile() { return dataFile; } public long getAccessTimeMillis() { String millis = globalTable.get(ACCESS_TIME); if (millis == null) return -1; return Long.parseLong(millis); } public int getMemory() { String memory = globalTable.get(MEMORY); if (memory == null) return -1; return Integer.parseInt(memory); } public boolean doTest() { return new Boolean(globalTable.get(TEST)).booleanValue(); } public String getReader() { return globalTable.get(READER); } public int getSeriesCount() { return Integer.parseInt(globalTable.get(SERIES_COUNT)); } // -- Per-series metadata -- public int getSizeX() { return Integer.parseInt(currentTable.get(SIZE_X)); } public int getSizeY() { return Integer.parseInt(currentTable.get(SIZE_Y)); } public int getSizeZ() { return Integer.parseInt(currentTable.get(SIZE_Z)); } public int getSizeC() { return Integer.parseInt(currentTable.get(SIZE_C)); } public int getSizeT() { return Integer.parseInt(currentTable.get(SIZE_T)); } public String getDimensionOrder() { return currentTable.get(DIMENSION_ORDER); } public boolean isInterleaved() { return new Boolean(currentTable.get(IS_INTERLEAVED)).booleanValue(); } public boolean isIndexed() { return new Boolean(currentTable.get(IS_INDEXED)).booleanValue(); } public boolean isFalseColor() { return new Boolean(currentTable.get(IS_FALSE_COLOR)).booleanValue(); } public boolean isRGB() { return new Boolean(currentTable.get(IS_RGB)).booleanValue(); } public int getThumbSizeX() { return Integer.parseInt(currentTable.get(THUMB_SIZE_X)); } public int getThumbSizeY() { return Integer.parseInt(currentTable.get(THUMB_SIZE_Y)); } public String getPixelType() { return currentTable.get(PIXEL_TYPE); } public boolean isLittleEndian() { return new Boolean(currentTable.get(IS_LITTLE_ENDIAN)).booleanValue(); } public String getMD5() { return currentTable.get(MD5); } public String getAlternateMD5() { return currentTable.get(ALTERNATE_MD5); } public String getTileMD5() { return currentTable.get(TILE_MD5); } public String getTileAlternateMD5() { return currentTable.get(TILE_ALTERNATE_MD5); } public Double getPhysicalSizeX() { String physicalSize = currentTable.get(PHYSICAL_SIZE_X); if (physicalSize == null) return null; try { return new Double(physicalSize); } catch (NumberFormatException e) { } return null; } public Double getPhysicalSizeY() { String physicalSize = currentTable.get(PHYSICAL_SIZE_Y); if (physicalSize == null) return null; try { return new Double(physicalSize); } catch (NumberFormatException e) { } return null; } public Double getPhysicalSizeZ() { String physicalSize = currentTable.get(PHYSICAL_SIZE_Z); if (physicalSize == null) return null; try { return new Double(physicalSize); } catch (NumberFormatException e) { } return null; } public Time getTimeIncrement() { String physicalSize = currentTable.get(TIME_INCREMENT); return physicalSize == null ? null : new Time(new Double(physicalSize), UNITS.S); } public int getChannelCount() { return Integer.parseInt(currentTable.get(CHANNEL_COUNT)); } public String getLightSource(int channel) { return currentTable.get(LIGHT_SOURCE + channel); } public String getChannelName(int channel) { return currentTable.get(CHANNEL_NAME + channel); } public boolean hasExposureTime(int channel) { return currentTable.containsKey(EXPOSURE_TIME + channel); } public Time getExposureTime(int channel) { String exposure = currentTable.get(EXPOSURE_TIME + channel); return exposure == null ? null : new Time(new Double(exposure), UNITS.S); } public Double getDeltaT(int plane) { String deltaT = currentTable.get(DELTA_T + plane); return deltaT == null ? null : new Double(deltaT); } public Double getPositionX(int plane) { String pos = currentTable.get(X_POSITION + plane); return pos == null ? null : new Double(pos); } public Double getPositionY(int plane) { String pos = currentTable.get(Y_POSITION + plane); return pos == null ? null : new Double(pos); } public Double getPositionZ(int plane) { String pos = currentTable.get(Z_POSITION + plane); return pos == null ? null : new Double(pos); } public Double getEmissionWavelength(int channel) { String wavelength = currentTable.get(EMISSION_WAVELENGTH + channel); return wavelength == null ? null : new Double(wavelength); } public Double getExcitationWavelength(int channel) { String wavelength = currentTable.get(EXCITATION_WAVELENGTH + channel); return wavelength == null ? null : new Double(wavelength); } public String getDetector(int channel) { return currentTable.get(DETECTOR + channel); } public String getImageName() { return currentTable.get(NAME); } public boolean hasImageDescription() { return currentTable.containsKey(DESCRIPTION); } public String getImageDescription() { return currentTable.get(DESCRIPTION); } public String getDate() { return currentTable.get(DATE); } public void setSeries(int series) { Location file = new Location(dataFile); currentTable = ini.getTable(file.getName() + SERIES + series); } public void saveToFile() throws IOException { IniWriter writer = new IniWriter(); writer.saveINI(ini, configFile, true, true); } public IniList getINI() { return ini; } // -- Object API methods -- @Override public boolean equals(Object o) { if (!(o instanceof Configuration)) return false; Configuration thatConfig = (Configuration) o; return this.getINI().equals(thatConfig.getINI()); } @Override public int hashCode() { return this.getINI().hashCode(); } // -- Helper methods -- private void populateINI(IFormatReader reader) { IMetadata retrieve = (IMetadata) reader.getMetadataStore(); ini = new IniList(); IniTable globalTable = new IniTable(); putTableName(globalTable, reader, " global"); int seriesCount = reader.getSeriesCount(); globalTable.put(SERIES_COUNT, String.valueOf(seriesCount)); IFormatReader r = reader; if (r instanceof ImageReader) { r = ((ImageReader) r).getReader(); } else if (r instanceof ReaderWrapper) { try { r = ((ReaderWrapper) r).unwrap(); } catch (FormatException e) { } catch (IOException e) { } } globalTable.put(READER, TestTools.shortClassName(r)); globalTable.put(TEST, "true"); globalTable.put(MEMORY, String.valueOf(TestTools.getUsedMemory())); long planeSize = (long) FormatTools.getPlaneSize(reader) * 3; boolean canOpenImages = planeSize > 0 && TestTools.canFitInMemory(planeSize); long t0 = System.currentTimeMillis(); if (canOpenImages) { try { reader.openBytes(0); } catch (FormatException e) { } catch (IOException e) { } } long t1 = System.currentTimeMillis(); globalTable.put(ACCESS_TIME, String.valueOf(t1 - t0)); ini.add(globalTable); for (int series=0; series<seriesCount; series++) { reader.setSeries(series); IniTable seriesTable = new IniTable(); putTableName(seriesTable, reader, SERIES + series); seriesTable.put(SIZE_X, String.valueOf(reader.getSizeX())); seriesTable.put(SIZE_Y, String.valueOf(reader.getSizeY())); seriesTable.put(SIZE_Z, String.valueOf(reader.getSizeZ())); seriesTable.put(SIZE_C, String.valueOf(reader.getSizeC())); seriesTable.put(SIZE_T, String.valueOf(reader.getSizeT())); seriesTable.put(DIMENSION_ORDER, reader.getDimensionOrder()); seriesTable.put(IS_INTERLEAVED, String.valueOf(reader.isInterleaved())); seriesTable.put(IS_INDEXED, String.valueOf(reader.isIndexed())); seriesTable.put(IS_FALSE_COLOR, String.valueOf(reader.isFalseColor())); seriesTable.put(IS_RGB, String.valueOf(reader.isRGB())); seriesTable.put(THUMB_SIZE_X, String.valueOf(reader.getThumbSizeX())); seriesTable.put(THUMB_SIZE_Y, String.valueOf(reader.getThumbSizeY())); seriesTable.put(PIXEL_TYPE, FormatTools.getPixelTypeString(reader.getPixelType())); seriesTable.put(IS_LITTLE_ENDIAN, String.valueOf(reader.isLittleEndian())); seriesTable.put(CHANNEL_COUNT, String.valueOf(retrieve.getChannelCount(series))); try { planeSize = DataTools.safeMultiply32(reader.getSizeX(), reader.getSizeY(), reader.getEffectiveSizeC(), FormatTools.getBytesPerPixel(reader.getPixelType())); canOpenImages = planeSize > 0 && TestTools.canFitInMemory(planeSize); } catch (IllegalArgumentException e) { canOpenImages = false; } if (canOpenImages) { try { byte[] plane = reader.openBytes(0); seriesTable.put(MD5, TestTools.md5(plane)); } catch (FormatException e) { // TODO } catch (IOException e) { // TODO } } try { int w = (int) Math.min(TILE_SIZE, reader.getSizeX()); int h = (int) Math.min(TILE_SIZE, reader.getSizeY()); byte[] tile = reader.openBytes(0, 0, 0, w, h); seriesTable.put(TILE_MD5, TestTools.md5(tile)); } catch (FormatException e) { // TODO } catch (IOException e) { // TODO } seriesTable.put(NAME, retrieve.getImageName(series)); seriesTable.put(DESCRIPTION, retrieve.getImageDescription(series)); Length physicalX = retrieve.getPixelsPhysicalSizeX(series); if (physicalX != null) { seriesTable.put(PHYSICAL_SIZE_X, physicalX.value(UNITS.MICROM).toString()); } Length physicalY = retrieve.getPixelsPhysicalSizeY(series); if (physicalY != null) { seriesTable.put(PHYSICAL_SIZE_Y, physicalY.value(UNITS.MICROM).toString()); } Length physicalZ = retrieve.getPixelsPhysicalSizeZ(series); if (physicalZ != null) { seriesTable.put(PHYSICAL_SIZE_Z, physicalZ.value(UNITS.MICROM).toString()); } Time timeIncrement = retrieve.getPixelsTimeIncrement(series); if (timeIncrement != null) { seriesTable.put(TIME_INCREMENT, timeIncrement.value().toString()); } Timestamp acquisition = retrieve.getImageAcquisitionDate(series); if (acquisition != null) { String date = acquisition.getValue(); if (date != null) { seriesTable.put(DATE, date); } } for (int c=0; c<retrieve.getChannelCount(series); c++) { seriesTable.put(CHANNEL_NAME + c, retrieve.getChannelName(series, c)); try { seriesTable.put(LIGHT_SOURCE + c, retrieve.getChannelLightSourceSettingsID(series, c)); } catch (NullPointerException e) { } try { int plane = reader.getIndex(0, c, 0); if (plane < retrieve.getPlaneCount(series)) { seriesTable.put(EXPOSURE_TIME + c, retrieve.getPlaneExposureTime(series, plane).value().toString()); } } catch (NullPointerException e) { } Length emWavelength = retrieve.getChannelEmissionWavelength(series, c); if (emWavelength != null) { seriesTable.put(EMISSION_WAVELENGTH + c, emWavelength.value(UNITS.NM).toString()); } Length exWavelength = retrieve.getChannelExcitationWavelength(series, c); if (exWavelength != null) { seriesTable.put(EXCITATION_WAVELENGTH + c, exWavelength.value(UNITS.NM).toString()); } try { seriesTable.put(DETECTOR + c, retrieve.getDetectorSettingsID(series, c)); } catch (NullPointerException e) { } } for (int p=0; p<reader.getImageCount(); p++) { try { Time deltaT = retrieve.getPlaneDeltaT(series, p); if (deltaT != null) { seriesTable.put(DELTA_T + p, deltaT.value(UNITS.S).toString()); } Length xPos = retrieve.getPlanePositionX(series, p); if (xPos != null) { seriesTable.put(X_POSITION + p, xPos.value(UNITS.REFERENCEFRAME).toString()); } Length yPos = retrieve.getPlanePositionY(series, p); if (yPos != null) { seriesTable.put(Y_POSITION + p, yPos.value(UNITS.REFERENCEFRAME).toString()); } Length zPos = retrieve.getPlanePositionZ(series, p); if (zPos != null) { seriesTable.put(Z_POSITION + p, zPos.value(UNITS.REFERENCEFRAME).toString()); } } catch (IndexOutOfBoundsException e) { // only happens if no Plane elements were populated } } ini.add(seriesTable); } } private void putTableName(IniTable table, IFormatReader reader, String suffix) { Location file = new Location(reader.getCurrentFile()); table.put(IniTable.HEADER_KEY, file.getName() + suffix); } private void pruneINI() { IniList newIni = new IniList(); for (IniTable table : ini) { String tableName = table.get(IniTable.HEADER_KEY); Location file = new Location(dataFile); if (tableName.startsWith(file.getName() + " ")) { newIni.add(table); if (tableName.endsWith("global")) { globalTable = table; } } } ini = newIni; } }