// // MetamorphHandler.java // /* OME Bio-Formats package for reading and converting biological file formats. Copyright (C) 2005-@year@ UW-Madison LOCI and Glencoe Software, Inc. 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package loci.formats.in; import java.util.Hashtable; import java.util.Vector; import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; /** * MetamorphTiffReader is the file format reader for TIFF files produced by * Metamorph software version 7.5 and above. * * <dl><dt><b>Source code:</b></dt> * <dd><a href="http://trac.openmicroscopy.org.uk/ome/browser/bioformats.git/components/bio-formats/src/loci/formats/in/MetamorphHandler.java">Trac</a>, * <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/bio-formats/src/loci/formats/in/MetamorphHandler.java;hb=HEAD">Gitweb</a></dd></dl> * * @author Melissa Linkert melissa at glencoesoftware.com * @author Thomas Caswell tcaswell at uchicago.edu */ public class MetamorphHandler extends DefaultHandler { // -- Fields -- private Hashtable metadata; private Vector<String> timestamps; private String imageName; private String date; private Vector<Integer> wavelengths; private Vector<Double> zPositions; private double pixelSizeX, pixelSizeY; private double temperature; private String binning; private double readOutRate, zoom; private double positionX, positionY; private Vector<Double> exposures; private String channelName; private String stageLabel; // -- Constructor -- public MetamorphHandler() { this(null); } public MetamorphHandler(Hashtable metadata) { super(); this.metadata = metadata; timestamps = new Vector<String>(); wavelengths = new Vector<Integer>(); zPositions = new Vector<Double>(); exposures = new Vector<Double>(); } // -- MetamorphHandler API methods -- public String getChannelName() { return channelName; } public String getStageLabel() { return stageLabel; } public Vector<String> getTimestamps() { return timestamps; } public Vector<Integer> getWavelengths() { return wavelengths; } public Vector<Double> getZPositions() { return zPositions; } public String getDate() { return date; } public String getImageName() { return imageName; } public double getPixelSizeX() { return pixelSizeX; } public double getPixelSizeY() { return pixelSizeY; } public double getTemperature() { return temperature; } public String getBinning() { return binning; } public double getReadOutRate() { return readOutRate; } public double getZoom() { return zoom; } public double getStagePositionX() { return positionX; } public double getStagePositionY() { return positionY; } public Vector<Double> getExposures() { return exposures; } // -- DefaultHandler API methods -- public void startElement(String uri, String localName, String qName, Attributes attributes) { String id = attributes.getValue("id"); String value = attributes.getValue("value"); String delim = " "; if (id != null && value != null) { if (id.equals("Description")) { if (metadata != null) metadata.remove("Comment"); String k = null, v = null; if (value.indexOf(delim) != -1) { int currentIndex = -delim.length(); while (currentIndex != -1) { currentIndex += delim.length(); int nextIndex = value.indexOf(delim, currentIndex); String line = null; if (nextIndex == -1) { line = value.substring(currentIndex, value.length()); } else { line = value.substring(currentIndex, nextIndex); } currentIndex = nextIndex; int colon = line.indexOf(":"); if (colon != -1) { k = line.substring(0, colon).trim(); v = line.substring(colon + 1).trim(); if (metadata != null) metadata.put(k, v); checkKey(k, v); } } } else { int colon = value.indexOf(":"); while (colon != -1) { k = value.substring(0, colon); int space = value.lastIndexOf(" ", value.indexOf(":", colon + 1)); if (space == -1) space = value.length(); v = value.substring(colon + 1, space).trim(); if (metadata != null) metadata.put(k, v); value = value.substring(space).trim(); colon = value.indexOf(":"); checkKey(k, v); } } } else { if (metadata != null) metadata.put(id, value); checkKey(id, value); } } } // -- Helper methods -- /** Check if the value needs to be saved. */ private void checkKey(String key, String value) { if (key.equals("Temperature")) { temperature = Double.parseDouble(value); } else if (key.equals("spatial-calibration-x")) { pixelSizeX = Double.parseDouble(value); } else if (key.equals("spatial-calibration-y")) { pixelSizeY = Double.parseDouble(value); } else if (key.equals("z-position")) { zPositions.add(new Double(value)); } else if (key.equals("wavelength")) { wavelengths.add(new Integer(value)); } else if (key.equals("acquisition-time-local")) { date = value; timestamps.add(date); } else if (key.equals("image-name")) imageName = value; else if (key.equals("Binning")) { binning = value; } else if (key.equals("Readout Frequency")) { readOutRate = Double.parseDouble(value); } else if (key.equals("zoom-percent")) { zoom = Double.parseDouble(value); } else if (key.equals("stage-position-x")) { positionX = Double.parseDouble(value); if (metadata != null) { metadata.put("X position for position #1", positionX); } } else if (key.equals("stage-position-y")) { positionY = Double.parseDouble(value); if (metadata != null) { metadata.put("Y position for position #1", positionY); } } else if (key.equals("Speed")) { int space = value.indexOf(" "); if (space > 0) { value = value.substring(0, space); } try { readOutRate = Double.parseDouble(value.trim()); } catch (NumberFormatException e) { } } else if (key.equals("Exposure")) { if (value.indexOf(" ") != -1) { value = value.substring(0, value.indexOf(" ")); } // exposure times are stored in milliseconds, we want them in seconds try { exposures.add(new Double(Double.parseDouble(value) / 1000)); } catch (NumberFormatException e) { } } else if (key.equals("_IllumSetting_")) { channelName = value; } else if (key.equals("stage-label")) { stageLabel = value; } } }