<commit_before>//
// 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@ <NAME>,
<NAME> and <NAME>.

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;

/**
 * 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 <NAME> <EMAIL> at <EMAIL>
 */
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 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 getPixelsPhysicalSizeX(Double[] sizeX) {
    int imageIndex = r.getSeries();
    MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore();
    sizeX[0] = retrieve.getPixelsPhysicalSizeX(imageIndex).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();
    sizeY[0] = retrieve.getPixelsPhysicalSizeY(imageIndex).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();
    sizeZ[0] = retrieve.getPixelsPhysicalSizeZ(imageIndex).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\");");<commit_msg>Prevent ugly error messages if PhysicalSize* is not populated.<commit_after>//
// 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@ <NAME>,
<NAME> and <NAME>.

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 <NAME> <EMAIL> at <EMAIL>
 */
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 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 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\");");
{'fraction_non_alphanumeric': 0.129847419852563, 'fraction_numerical': 0.006583233327618721, 'mean_word_length': 4.057395526270158, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '828526', 'n_tokens_mistral': 9472, 'n_tokens_neox': 9137, 'n_words': 2163}