//
// LociFunctions.java
//
/*
LOCI Plugins for ImageJ: a collection of ImageJ plugins including the
Bio-Formats Importer, Bio-Formats Exporter, Bio-Formats Macro Extensions,
Data Browser and Stack Slicer. Copyright (C) 2005-@year@ Melissa Linkert,
Curtis Rueden and Christopher Peterson.
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.plugins.macro;
import ij.IJ;
import ij.ImagePlus;
import ij.process.ImageProcessor;
import java.io.IOException;
import java.util.Arrays;
import loci.common.Region;
import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.common.services.ServiceFactory;
import loci.formats.ChannelSeparator;
import loci.formats.FileStitcher;
import loci.formats.FormatException;
import loci.formats.FormatTools;
import loci.formats.IFormatReader;
import loci.formats.ImageReader;
import loci.formats.meta.MetadataRetrieve;
import loci.formats.services.OMEXMLService;
import loci.plugins.BF;
import loci.plugins.in.Calibrator;
import loci.plugins.in.ImagePlusReader;
import loci.plugins.in.ImportProcess;
import loci.plugins.in.ImporterOptions;
import loci.plugins.util.ImageProcessorReader;
import loci.plugins.util.LociPrefs;
import ome.xml.model.primitives.PositiveFloat;
/**
* This class provides macro extensions for ImageJ for Bio-Formats and other
* LOCI tools. Currently, it is a fairly tight mirror to the
* {@link loci.formats.IFormatReader} interface, with some additional
* functions to control the type of format reader used.
*
* <dl><dt><b>Source code:</b></dt>
* <dd><a href="http://trac.openmicroscopy.org.uk/ome/browser/bioformats.git/components/loci-plugins/src/loci/plugins/macro/LociFunctions.java">Trac</a>,
* <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/loci-plugins/src/loci/plugins/macro/LociFunctions.java;hb=HEAD">Gitweb</a></dd></dl>
*
* @author Curtis Rueden ctrueden at wisc.edu
*/
public class LociFunctions extends MacroFunctions {
// -- Constants --
/** URL for LOCI Software Javadocs. */
public static final String URL_LOCI_SOFTWARE_JAVADOCS =
"http://hudson.openmicroscopy.org.uk/job/LOCI/javadoc/";
// -- Fields --
private ImageProcessorReader r;
// -- Constructor --
public LociFunctions() {
r = new ImageProcessorReader(new ChannelSeparator(
new FileStitcher(LociPrefs.makeImageReader(), true)));
try {
ServiceFactory factory = new ServiceFactory();
OMEXMLService service = factory.getInstance(OMEXMLService.class);
r.setMetadataStore(service.createOMEXMLMetadata());
}
catch (DependencyException de) { }
catch (ServiceException se) { }
}
// -- LociFunctions API methods - version numbers --
public void getRevision(String[] revision) {
revision[0] = FormatTools.VCS_REVISION;
}
public void getBuildDate(String[] date) {
date[0] = FormatTools.DATE;
}
public void getVersionNumber(String[] version) {
version[0] = FormatTools.VERSION;
}
// -- LociFunctions API methods - loci.formats.IFormatReader --
public void getImageCount(Double[] imageCount) {
imageCount[0] = new Double(r.getImageCount());
}
public void getSizeX(Double[] sizeX) { sizeX[0] = new Double(r.getSizeX()); }
public void getSizeY(Double[] sizeY) { sizeY[0] = new Double(r.getSizeY()); }
public void getSizeZ(Double[] sizeZ) { sizeZ[0] = new Double(r.getSizeZ()); }
public void getSizeC(Double[] sizeC) { sizeC[0] = new Double(r.getSizeC()); }
public void getSizeT(Double[] sizeT) { sizeT[0] = new Double(r.getSizeT()); }
public void getPixelType(String[] pixelType) {
pixelType[0] = FormatTools.getPixelTypeString(r.getPixelType());
}
public void getEffectiveSizeC(Double[] effectiveSizeC) {
effectiveSizeC[0] = new Double(r.getEffectiveSizeC());
}
public void getRGBChannelCount(Double[] rgbChannelCount) {
rgbChannelCount[0] = new Double(r.getRGBChannelCount());
}
public void isIndexed(String[] indexed) {
indexed[0] = r.isIndexed() ? "true" : "false";
}
public void getChannelDimCount(Double[] channelDimCount) {
channelDimCount[0] = new Double(r.getChannelDimLengths().length);
}
public void getChannelDimLength(Double i, Double[] channelDimLength) {
channelDimLength[0] = new Double(r.getChannelDimLengths()[i.intValue()]);
}
public void getChannelDimType(Double i, Double[] channelDimType) {
channelDimType[0] = new Double(r.getChannelDimTypes()[i.intValue()]);
}
// public void getThumbSizeX(Double[] thumbSizeX) {
// thumbSizeX[0] = new Double(r.getThumbSizeX());
// }
// public void getThumbSizeY(Double[] thumbSizeY) {
// thumbSizeY[0] = new Double(r.getThumbSizeY());
// }
public void isLittleEndian(String[] littleEndian) {
littleEndian[0] = r.isLittleEndian() ? "true" : "false";
}
public void getDimensionOrder(String[] dimOrder) {
dimOrder[0] = r.getDimensionOrder();
}
public void isOrderCertain(String[] orderCertain) {
orderCertain[0] = r.isOrderCertain() ? "true" : "false";
}
public void isInterleaved(String[] interleaved) {
interleaved[0] = r.isInterleaved() ? "true" : "false";
}
public void isInterleavedSubC(Double subC, String[] interleaved) {
interleaved[0] = r.isInterleaved(subC.intValue()) ? "true" : "false";
}
public void openImagePlus(String path) {
ImagePlus[] imps = null;
try {
imps = BF.openImagePlus(path);
for (ImagePlus imp : imps) imp.show();
}
catch (IOException exc) {
IJ.handleException(exc);
}
catch (FormatException exc) {
IJ.handleException(exc);
}
}
public void openThumbImagePlus(String path) {
ImagePlus[] imps = null;
try {
imps = BF.openThumbImagePlus(path);
for (ImagePlus imp : imps) imp.show();
}
catch (IOException exc) {
IJ.handleException(exc);
}
catch (FormatException exc) {
IJ.handleException(exc);
}
}
public void openThumbImage(String title, Double no)
throws FormatException, IOException
{
ImporterOptions options = new ImporterOptions();
options.setWindowless(true);
options.setId(r.getCurrentFile());
options.setCrop(true);
options.setSpecifyRanges(true);
options.setSeriesOn(r.getSeries(), true);
int[] zct = r.getZCTCoords(no.intValue());
options.setCBegin(r.getSeries(), zct[1]);
options.setZBegin(r.getSeries(), zct[0]);
options.setTBegin(r.getSeries(), zct[2]);
options.setCEnd(r.getSeries(), zct[1]);
options.setZEnd(r.getSeries(), zct[0]);
options.setTEnd(r.getSeries(), zct[2]);
ImportProcess process = new ImportProcess(options);
process.execute();
ImagePlusReader reader = new ImagePlusReader(process);
final ImagePlus imp = reader.openThumbImagePlus()[0];
Calibrator calibrator = new Calibrator(process);
calibrator.applyCalibration(imp);
process.getReader().close();
imp.show();
}
public void openImage(String title, Double no)
throws FormatException, IOException
{
openSubImage(title, no, 0d, 0d,
new Double(r.getSizeX()), new Double(r.getSizeY()));
}
public void openSubImage(String title, Double no, Double x, Double y,
Double w, Double h) throws FormatException, IOException
{
ImporterOptions options = new ImporterOptions();
options.setWindowless(true);
options.setId(r.getCurrentFile());
options.setCrop(true);
options.setSpecifyRanges(true);
options.setSeriesOn(r.getSeries(), true);
int[] zct = r.getZCTCoords(no.intValue());
options.setCBegin(r.getSeries(), zct[1]);
options.setZBegin(r.getSeries(), zct[0]);
options.setTBegin(r.getSeries(), zct[2]);
options.setCEnd(r.getSeries(), zct[1]);
options.setZEnd(r.getSeries(), zct[0]);
options.setTEnd(r.getSeries(), zct[2]);
Region region =
new Region(x.intValue(), y.intValue(), w.intValue(), h.intValue());
options.setCropRegion(r.getSeries(), region);
ImportProcess process = new ImportProcess(options);
process.execute();
ImagePlusReader reader = new ImagePlusReader(process);
final ImagePlus imp = reader.openImagePlus()[0];
Calibrator calibrator = new Calibrator(process);
calibrator.applyCalibration(imp);
process.getReader().close();
imp.show();
}
public void close() throws IOException { r.close(); }
public void closeFileOnly() throws IOException { r.close(true); }
public void getSeriesCount(Double[] seriesCount) {
seriesCount[0] = new Double(r.getSeriesCount());
}
public void setSeries(Double seriesNum) {
r.setSeries(seriesNum.intValue());
}
public void getSeries(Double[] seriesNum) {
seriesNum[0] = new Double(r.getSeries());
}
public void setNormalized(Boolean normalize) {
r.setNormalized(normalize.booleanValue());
}
public void isNormalized(Boolean[] normalize) {
normalize[0] = new Boolean(r.isNormalized());
}
@SuppressWarnings("deprecation")
public void setMetadataCollected(Boolean collect) {
r.setMetadataCollected(collect.booleanValue());
}
@SuppressWarnings("deprecation")
public void isMetadataCollected(Boolean[] collect) {
collect[0] = new Boolean(r.isMetadataCollected());
}
public void setOriginalMetadataPopulated(Boolean populate) {
r.setOriginalMetadataPopulated(populate.booleanValue());
}
public void isOriginalMetadataPopulated(Boolean[] populate) {
populate[0] = new Boolean(r.isOriginalMetadataPopulated());
}
public void setGroupFiles(String groupFiles) {
r.setGroupFiles("true".equalsIgnoreCase(groupFiles));
}
public void isGroupFiles(String[] groupFiles) {
groupFiles[0] = r.isGroupFiles() ? "true" : "false";
}
public void isMetadataComplete(String[] complete) {
complete[0] = r.isMetadataComplete() ? "true" : "false";
}
public void fileGroupOption(String id, String[] fileGroupOption)
throws FormatException, IOException
{
switch (r.fileGroupOption(id)) {
case IFormatReader.MUST_GROUP:
fileGroupOption[0] = "must";
break;
case IFormatReader.CAN_GROUP:
fileGroupOption[0] = "can";
break;
case IFormatReader.CANNOT_GROUP:
fileGroupOption[0] = "cannot";
break;
default:
fileGroupOption[0] = "unknown";
}
}
public void getUsedFileCount(Double[] count) {
count[0] = new Double(r.getUsedFiles().length);
}
public void getUsedFile(Double i, String[] used) {
used[0] = r.getUsedFiles()[i.intValue()];
}
public void getCurrentFile(String[] file) {
file[0] = r.getCurrentFile();
}
public void getIndex(Double z, Double c, Double t, Double[] index) {
index[0] = new Double(r.getIndex(z.intValue(), c.intValue(), t.intValue()));
}
public void getZCTCoords(Double index, Double[] z, Double[] c, Double[] t) {
int[] zct = r.getZCTCoords(index.intValue());
z[0] = new Double(zct[0]);
c[0] = new Double(zct[1]);
t[0] = new Double(zct[2]);
}
public void getMetadataValue(String field, String[] value) {
Object o = r.getMetadataValue(field);
value[0] = o == null ? null : o.toString();
}
public void getSeriesMetadataValue(String field, String[] value) {
Object o = r.getSeriesMetadataValue(field);
value[0] = o == null ? null : o.toString();
}
public void setMetadataFiltered(String metadataFiltered) {
r.setMetadataFiltered("true".equalsIgnoreCase(metadataFiltered));
}
public void isMetadataFiltered(String[] metadataFiltered) {
metadataFiltered[0] = r.isMetadataFiltered() ? "true" : "false";
}
// -- LociFunctions API methods - additional methods --
public void getFormat(String id, String[] format)
throws FormatException, IOException
{
ImageReader reader = new ImageReader();
format[0] = reader.getFormat(id);
}
public void setId(String id) throws FormatException, IOException {
r.setId(id);
}
public void isThisType(String name, String[] thisType) {
thisType[0] = r.isThisType(name) ? "true" : "false";
}
public void isThisTypeFast(String name, String[] thisType) {
thisType[0] = r.isThisType(name, false) ? "true" : "false";
}
public void getSeriesName(String[] seriesName) {
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
seriesName[0] = retrieve.getImageName(r.getSeries());
}
public void getImageCreationDate(String[] creationDate) {
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
creationDate[0] = retrieve.getImageAcquiredDate(r.getSeries());
}
public void getPlaneTimingDeltaT(Double[] deltaT, Double no) {
int imageIndex = r.getSeries();
int planeIndex = getPlaneIndex(r, no.intValue());
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
Double val = null;
if (planeIndex >= 0) {
val = retrieve.getPlaneDeltaT(imageIndex, planeIndex);
}
deltaT[0] = val == null ? new Double(Double.NaN) : val;
}
public void getPlaneTimingExposureTime(Double[] exposureTime, Double no) {
int imageIndex = r.getSeries();
int planeIndex = getPlaneIndex(r, no.intValue());
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
Double val = null;
if (planeIndex >= 0) {
val = retrieve.getPlaneExposureTime(imageIndex, planeIndex);
}
exposureTime[0] = val == null ? new Double(Double.NaN) : val;
}
public void getPlanePositionX(Double[] positionX, Double no) {
int imageIndex = r.getSeries();
int planeIndex = getPlaneIndex(r, no.intValue());
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
Double val = null;
if (planeIndex >= 0) {
val = retrieve.getPlanePositionX(imageIndex, planeIndex);
}
positionX[0] = val == null ? new Double(Double.NaN) : val;
}
public void getPlanePositionY(Double[] positionY, Double no) {
int imageIndex = r.getSeries();
int planeIndex = getPlaneIndex(r, no.intValue());
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
Double val = null;
if (planeIndex >= 0) {
val = retrieve.getPlanePositionY(imageIndex, planeIndex);
}
positionY[0] = val == null ? new Double(Double.NaN) : val;
}
public void getPlanePositionZ(Double[] positionZ, Double no) {
int imageIndex = r.getSeries();
int planeIndex = getPlaneIndex(r, no.intValue());
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
Double val = null;
if (planeIndex >= 0) {
val = retrieve.getPlanePositionZ(imageIndex, planeIndex);
}
positionZ[0] = val == null ? new Double(Double.NaN) : val;
}
public void getPixelsPhysicalSizeX(Double[] sizeX) {
int imageIndex = r.getSeries();
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
PositiveFloat x = retrieve.getPixelsPhysicalSizeX(imageIndex);
if (x != null) {
sizeX[0] = x.getValue();
}
if (sizeX[0] == null) sizeX[0] = new Double(Double.NaN);
}
public void getPixelsPhysicalSizeY(Double[] sizeY) {
int imageIndex = r.getSeries();
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
PositiveFloat y = retrieve.getPixelsPhysicalSizeY(imageIndex);
if (y != null) {
sizeY[0] = y.getValue();
}
if (sizeY[0] == null) sizeY[0] = new Double(Double.NaN);
}
public void getPixelsPhysicalSizeZ(Double[] sizeZ) {
int imageIndex = r.getSeries();
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
PositiveFloat z = retrieve.getPixelsPhysicalSizeZ(imageIndex);
if (z != null) {
sizeZ[0] = z.getValue();
}
if (sizeZ[0] == null) sizeZ[0] = new Double(Double.NaN);
}
public void getPixelsTimeIncrement(Double[] sizeT) {
int imageIndex = r.getSeries();
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
sizeT[0] = retrieve.getPixelsTimeIncrement(imageIndex);
if (sizeT[0] == null) sizeT[0] = new Double(Double.NaN);
}
// -- PlugIn API methods --
public void run(String arg) {
if (IJ.macroRunning()) super.run(arg);
else {
IJ.showMessage("LOCI Plugins for ImageJ",
"The macro extensions are designed to be used within a macro.\n" +
"Instructions on doing so will be printed to the Results window.");
IJ.log("To gain access to more advanced features of Bio-Formats");
IJ.log("from within a macro, put the following line at the");
IJ.log("beginning of your macro:");
IJ.log("");
IJ.log("run(\"Bio-Formats Macro Extensions\");");
IJ.log("");
IJ.log("This will enable the following macro functions:");
IJ.log("");
IJ.log("-= Usable any time =-");
IJ.log("");
IJ.log("Ext.openImagePlus(path)");
IJ.log("-- Opens the image at the given path with the default options.");
IJ.log("Ext.openThumbImagePlus(path)");
IJ.log("-- Opens the thumbnail image at the given path");
IJ.log("-- with the default options.");
IJ.log("Ext.getFormat(id, format)");
IJ.log("-- Retrieves the file format of the given id (filename).");
IJ.log("Ext.setId(id)");
IJ.log("-- Initializes the given id (filename).");
IJ.log("Ext.isThisType(name, thisType)");
IJ.log("-- True if Bio-Formats recognizes the given file as a");
IJ.log("-- supported image file format; if necessary, will ");
IJ.log("-- examine the file contents to decide for sure.");
IJ.log("Ext.isThisTypeFast(name, thisType)");
IJ.log("-- True if Bio-Formats recognizes the given filename as a");
IJ.log("-- supported image file format; will decide based on file");
IJ.log("-- extension only, without examining file contents.");
IJ.log("Ext.isMetadataComplete(complete)");
IJ.log("-- True if Bio-Formats completely parses the current");
IJ.log("-- dataset's file format. If this function returns false,");
IJ.log("-- there are known limitations or missing features in how");
IJ.log("-- Bio-Formats handles this file format.");
IJ.log("Ext.fileGroupOption(id, fileGroupOption)");
IJ.log("-- Returns a code indicating the file grouping policy for");
IJ.log("-- for the current dataset. Possible values are:");
IJ.log("-- must, can, cannot, unknown");
IJ.log("Ext.getVersionNumber(version)");
IJ.log("-- Returns the version number of the currently installed");
IJ.log("-- version of Bio-Formats.");
IJ.log("Ext.getRevision(revision)");
IJ.log("-- Returns the revision number of the currently");
IJ.log("-- installed version of Bio-Formats.");
IJ.log("Ext.getBuildDate(date)");
IJ.log("-- Returns the build date of the currently installed");
IJ.log("-- version of Bio-Formats.");
IJ.log("");
IJ.log("-= Usable before initializing a file =-");
IJ.log("");
IJ.log("Ext.setNormalized(normalize)");
IJ.log("-- Sets whether to normalize floating point data to [0-1].");
IJ.log("Ext.isNormalized(normalize)");
IJ.log("-- Gets whether float data is being normalized to [0-1].");
IJ.log("Ext.setMetadataCollected(collect)");
IJ.log("-- Sets whether Bio-Formats should extract metadata at all.");
IJ.log("Ext.isMetadataCollected(collect)");
IJ.log("-- Gets whether Bio-Formats is supposed to extract metadata.");
IJ.log("Ext.setOriginalMetadataPopulated(populate)");
IJ.log("-- Sets whether Bio-Formats should save proprietary metadata");
IJ.log("-- to the OME metadata store as custom attributes.");
IJ.log("Ext.isOriginalMetadataPopulated(populate)");
IJ.log("-- Sets whether Bio-Formats is saving proprietary metadata");
IJ.log("-- to the OME metadata store as custom attributes.");
IJ.log("Ext.setGroupFiles(group)");
IJ.log("-- For multi-file formats, sets whether to force grouping.");
IJ.log("Ext.isGroupFiles(group)");
IJ.log("-- Gets whether grouping is forced for multi-file formats..");
IJ.log("Ext.setMetadataFiltered(filter)");
IJ.log("-- Sets whether to filter out ugly metadata from the table");
IJ.log("-- (i.e., entries with unprintable characters, and extremely");
IJ.log("-- long values).");
IJ.log("Ext.isMetadataFiltered(filter)");
IJ.log("-- Gets whether ugly metadata is being filtered out.");
IJ.log("");
IJ.log("-== Usable after initializing a file ==-");
IJ.log("");
IJ.log("Ext.getSeriesCount(seriesCount)");
IJ.log("-- Gets the number of image series in the active dataset.");
IJ.log("Ext.setSeries(seriesNum)");
IJ.log("-- Sets the current series within the active dataset.");
IJ.log("Ext.getSeries(seriesNum)");
IJ.log("-- Gets the current series within the active dataset.");
IJ.log("Ext.getUsedFileCount(count)");
IJ.log("-- Gets the number of files that are part of this dataset.");
IJ.log("Ext.getUsedFile(i, used)");
IJ.log("-- Gets the i'th filename part of this dataset.");
IJ.log("Ext.getCurrentFile(file)");
IJ.log("-- Gets the base filename used to initialize this dataset.");
IJ.log("Ext.openImage(title, no)");
IJ.log("-- Opens the no'th plane in a new window named 'title'.");
IJ.log("Ext.openSubImage(title, no, x, y, width, height)");
IJ.log("-- Opens a subset of the no'th plane in a new window");
IJ.log("-- named 'title'.");
IJ.log("Ext.openThumbImage(title, no)");
IJ.log("-- Opens the no'th thumbnail in a new window named 'title'.");
IJ.log("Ext.close()");
IJ.log("-- Closes the active dataset.");
IJ.log("Ext.closeFileOnly()");
IJ.log("-- Closes open files, leaving the current dataset active.");
IJ.log("");
IJ.log("-== Applying to the current series ==-");
IJ.log("");
IJ.log("Ext.getImageCount(imageCount)");
IJ.log("-- Gets the total number of planes in the current dataset.");
IJ.log("Ext.getSizeX(sizeX)");
IJ.log("-- Gets the width of each image plane in pixels.");
IJ.log("Ext.getSizeY(sizeY)");
IJ.log("-- Gets the height of each image plane in pixels.");
IJ.log("Ext.getSizeZ(sizeZ)");
IJ.log("-- Gets the number of focal planes in the dataset.");
IJ.log("Ext.getSizeC(sizeC)");
IJ.log("-- Gets the number of channels in the dataset.");
IJ.log("Ext.getSizeT(sizeT)");
IJ.log("-- Gets the number of time points in the dataset.");
IJ.log("Ext.getPixelType(pixelType)");
IJ.log("-- Gets a code representing the pixel type of the image.");
IJ.log("-- Possible values include:");
IJ.log("-- int8, uint8, int16, uint16, int32, uint32, float, double");
IJ.log("Ext.getEffectiveSizeC(effectiveSizeC)");
IJ.log("-- Gets the 'effective' number of channels, such that:");
IJ.log("-- effectiveSizeC * sizeZ * sizeT == imageCount");
IJ.log("Ext.getRGBChannelCount(rgbChannelCount)");
IJ.log("-- Gets the number of channels per composite image plane:");
IJ.log("-- sizeC / rgbChannelCount == effectiveSizeC");
IJ.log("Ext.isIndexed(indexed)");
IJ.log("-- Gets whether the image planes are stored as indexed color");
IJ.log("-- (i.e., whether they have embedded LUTs).");
IJ.log("Ext.getChannelDimCount(channelDimCount)");
IJ.log("-- For highly multidimensional image data, the C dimension");
IJ.log("-- may consist of multiple embedded 'sub' dimensions.");
IJ.log("-- This function returns the number of such dimensions.");
IJ.log("Ext.getChannelDimLength(i, channelDimLength)");
IJ.log("-- Gets the length of the i'th embedded 'sub' dimension.");
IJ.log("Ext.getChannelDimType(i, channelDimType)");
IJ.log("-- Gets a string label for the i'th embedded 'sub' channel.");
IJ.log("Ext.isLittleEndian(littleEndian)");
IJ.log("-- For multi-byte pixel types, get the data's endianness.");
IJ.log("Ext.getDimensionOrder(dimOrder)");
IJ.log("-- Gets a five-character string representing the dimensional");
IJ.log("-- rasterization order within the dataset. Valid orders are:");
IJ.log("-- XYCTZ, XYCZT, XYTCZ, XYTZC, XYZCT, XYZTC");
IJ.log("-- In cases where the channels are interleaved (e.g., CXYTZ),");
IJ.log("-- C will be the first dimension after X and Y (e.g., XYCTZ)");
IJ.log("-- and the isInterleaved function will return true.");
IJ.log("Ext.isOrderCertain(orderCertain)");
IJ.log("-- Gets whether the dimension order and sizes are known,");
IJ.log("-- or merely guesses.");
IJ.log("Ext.isInterleaved(interleaved)");
IJ.log("-- Gets whether or not the channels are interleaved.");
IJ.log("-- This function exists because X and Y must appear first");
IJ.log("-- in the dimension order. For interleaved data, XYCTZ or");
IJ.log("-- XYCZT is used, and this method returns true.");
IJ.log("Ext.isInterleavedSubC(subC, interleaved)");
IJ.log("-- Gets whether the given 'sub' channel is interleaved.");
IJ.log("-- This method exists because some data with multiple");
IJ.log("-- rasterized sub-dimensions within C have one sub-dimension");
IJ.log("-- interleaved, and the other not -- e.g., the SDT reader");
IJ.log("-- handles spectral-lifetime data with interleaved lifetime");
IJ.log("-- bins and non-interleaved spectral channels.");
IJ.log("Ext.getIndex(z, c, t, index)");
IJ.log("-- Gets the rasterized index corresponding to the given");
IJ.log("-- Z, C and T coordinates, according to the dataset's");
IJ.log("-- dimension order.");
IJ.log("Ext.getZCTCoords(index, z, c, t)");
IJ.log("-- Gets the Z, C and T coordinates corresponding to the given");
IJ.log("-- rasterized index value, according to the dataset's");
IJ.log("-- dimension order.");
IJ.log("Ext.getMetadataValue(field, value)");
IJ.log("-- Obtains the specified metadata field's value.");
IJ.log("Ext.getSeriesName(seriesName)");
IJ.log("-- Obtains the name of the current series.");
IJ.log("Ext.getImageCreationDate(creationDate)");
IJ.log("-- Obtains the creation date of the dataset");
IJ.log("-- in ISO 8601 format.");
IJ.log("Ext.getPlaneTimingDeltaT(deltaT, no)");
IJ.log("-- Obtains the time offset (seconds since the beginning ");
IJ.log("-- of the experiment) for the no'th plane, or NaN if none.");
IJ.log("Ext.getPlaneTimingExposureTime(exposureTime, no)");
IJ.log("-- Obtains the exposure time (in seconds) for the no'th");
IJ.log("-- plane, or NaN if none.");
IJ.log("Ext.getPlanePositionX(positionX, no)");
IJ.log("-- Obtains the X coordinate of the stage for the no'th plane");
IJ.log("-- or NaN if none.");
IJ.log("Ext.getPlanePositionY(positionY, no)");
IJ.log("-- Obtains the Y coordinate of the stage for the no'th plane");
IJ.log("-- or NaN if none.");
IJ.log("Ext.getPlanePositionZ(positionZ, no)");
IJ.log("-- Obtains the Z coordinate of the stage for the no'th plane");
IJ.log("-- or NaN if none.");
IJ.log("Ext.getPixelsPhysicalSizeX(sizeX)");
IJ.log("-- Obtains the width of a pixel in microns, or NaN if the");
IJ.log("-- the width is not stored in the original file.");
IJ.log("Ext.getPixelsPhysicalSizeY(sizeY)");
IJ.log("-- Obtains the height of a pixel in microns, or NaN if the");
IJ.log("-- the height is not stored in the original file.");
IJ.log("Ext.getPixelsPhysicalSizeZ(sizeZ)");
IJ.log("-- Obtains the spacing between Z sections in microns, or NaN");
IJ.log("-- if the spacing is not stored in the original file.");
IJ.log("Ext.getPixelsTimeIncrement(sizeT)");
IJ.log("-- Obtains the spacing between time points in seconds, or");
IJ.log("-- NaN if the spacing is not stored in the original file.");
IJ.log("");
IJ.log("For more information, see the online Javadocs");
IJ.log("for the loci.formats.IFormatReader and ");
IJ.log("loci.formats.meta.MetadataRetrieve interfaces:");
IJ.log(URL_LOCI_SOFTWARE_JAVADOCS);
}
}
// -- Utility methods --
/** Finds the Plane index corresponding to the given image plane number. */
private static int getPlaneIndex(IFormatReader r, int no) {
MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
int imageIndex = r.getSeries();
int planeCount = retrieve.getPlaneCount(imageIndex);
int[] zct = r.getZCTCoords(no);
for (int i=0; i<planeCount; i++) {
Integer theC = retrieve.getPlaneTheC(imageIndex, i).getValue();
Integer theT = retrieve.getPlaneTheT(imageIndex, i).getValue();
Integer theZ = retrieve.getPlaneTheZ(imageIndex, i).getValue();
if (zct[0] == theZ.intValue() && zct[1] == theC.intValue() &&
zct[2] == theT.intValue())
{
return i;
}
}
return -1;
}
}