From d0dec52020f7e6bb58d573624a682fb72b4fa6f2 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 2 Sep 2010 20:29:39 +0000 Subject: [PATCH] Better series handling when number of series is extremely large. --- .../src/loci/plugins/in/ImportProcess.java | 42 ++++++ .../src/loci/plugins/in/ImporterOptions.java | 27 ++-- .../src/loci/plugins/in/SeriesDialog.java | 130 ++++++++++-------- .../src/loci/plugins/in/importer-options.txt | 5 - 4 files changed, 123 insertions(+), 81 deletions(-) diff --git a/components/loci-plugins/src/loci/plugins/in/ImportProcess.java b/components/loci-plugins/src/loci/plugins/in/ImportProcess.java index 4a0f24d5208..8a74a6bcb5f 100644 --- a/components/loci-plugins/src/loci/plugins/in/ImportProcess.java +++ b/components/loci-plugins/src/loci/plugins/in/ImportProcess.java @@ -28,6 +28,7 @@ Data Browser and Stack Slicer. Copyright (C) 2005-@year@ Melissa Linkert, import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.StringTokenizer; import loci.common.Location; import loci.common.Region; @@ -181,6 +182,47 @@ public boolean isWindowless() { return baseReader != null && LociPrefs.isWindowless(baseReader); } + public void setSeriesList(String seriesList) { + final int seriesCount = getSeriesCount(); + options.clearSeries(); + + // remove illegal characters + seriesList = seriesList.replaceAll("[^\\d,\\-]", ""); + + // parse series list + StringTokenizer st = new StringTokenizer(seriesList, ","); + while (st.hasMoreTokens()) { + final String token = st.nextToken(); + int dash = token.indexOf("-"); + if (dash < 0) { + // single number + try { + final int s = Integer.parseInt(token) - 1; + options.setSeriesOn(s, true); + } + catch (NumberFormatException exc) { + // skip invalid series number + } + } + else { + // numerical range + final String firstString = token.substring(0, dash); + final String lastString = token.substring(dash + 1); + try { + final int first = Integer.parseInt(firstString) - 1; + final int last = Integer.parseInt(lastString) - 1; + for (int s = first; s <= last; s++) { + if (s >= seriesCount) break; // skip out of bounds series + options.setSeriesOn(s, true); + } + } + catch (NumberFormatException exc) { + // skip invalid numerical range + } + } + } + } + // -- ImportProcess methods - post-READER -- /** Valid only after {@link ImportStep#READER}. */ diff --git a/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java b/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java index 32f901e7790..ee43b9513a2 100644 --- a/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java +++ b/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java @@ -64,7 +64,6 @@ public class ImporterOptions extends OptionsList { public static final String KEY_OPEN_ALL_SERIES = "openAllSeries"; public static final String KEY_QUIET = "quiet"; //public static final String KEY_RECORD = "record"; - public static final String KEY_SERIES = "series"; public static final String KEY_SHOW_METADATA = "showMetadata"; public static final String KEY_SHOW_OME_XML = "showOMEXML"; public static final String KEY_SHOW_ROIS = "showROIs"; @@ -195,26 +194,26 @@ public void parseArg(String arg) { /** Handles obsolete macro keys, for backward compatibility. */ public void checkObsoleteOptions() { - String options = Macro.getOptions(); + final String macroOptions = Macro.getOptions(); // NB: It would be nice to remove the Standard ImageJ option someday; // when that happens, the following code provides support for old macros. // check obsolete view options - //String stackFormat = options == null ? - // null : Macro.getValue(options, "view", null); + //String stackFormat = macroOptions == null ? + // null : Macro.getValue(macroOptions, "view", null); //final String viewStandard = "Standard ImageJ"; //if (viewStandard.equals(stackFormat)) { // // Standard ImageJ -> Hyperstack - // options = options.replaceFirst( + // macroOptions = macroOptions.replaceFirst( // "\\[" + viewStandard + "\\]", VIEW_HYPERSTACK); - // Macro.setOptions(options); + // Macro.setOptions(macroOptions); // setStackFormat(VIEW_HYPERSTACK); //} // check obsolete color options - boolean mergeChannels = checkKey(options, "merge_channels"); - boolean rgbColorize = checkKey(options, "rgb_colorize"); - boolean customColorize = checkKey(options, "custom_colorize"); + final boolean mergeChannels = checkKey(macroOptions, "merge_channels"); + final boolean rgbColorize = checkKey(macroOptions, "rgb_colorize"); + final boolean customColorize = checkKey(macroOptions, "custom_colorize"); if (mergeChannels) setColorMode(COLOR_MODE_COMPOSITE); else if (rgbColorize) setColorMode(COLOR_MODE_COLORIZED); else if (customColorize) setColorMode(COLOR_MODE_CUSTOM); @@ -306,11 +305,6 @@ public boolean isColorModeCustom() { //public boolean isRecord() { return isSet(KEY_RECORD); } //public void setRecord(boolean b) { setValue(KEY_RECORD, b); } - // series - public String getSeriesInfo() { return getInfo(KEY_SERIES); } - public String getSeries() { return getValue(KEY_SERIES); } - public void setSeries(String s) { setValue(KEY_SERIES, s); } - // showMetadata public String getShowMetadataInfo() { return getInfo(KEY_SHOW_METADATA); } public boolean isShowMetadata() { return isSet(KEY_SHOW_METADATA); } @@ -404,6 +398,9 @@ public boolean isSeriesOn(int s) { public void setSeriesOn(int s, boolean value) { set(seriesOn, s, value, false); } + public void clearSeries() { + seriesOn.clear(); + } // swap options public String getInputOrder(int s) { return get(inputOrder, s, null); } @@ -485,7 +482,7 @@ private T get(List list, int index, T defaultValue) { } /** Tests whether the given boolean key is set in the specified options. */ - private boolean checkKey(String options, String key) { + protected boolean checkKey(String options, String key) { if (options == null) return false; // delete anything inside square brackets, for simplicity diff --git a/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java b/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java index c174dea63fe..cf9196068f7 100644 --- a/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java +++ b/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java @@ -29,6 +29,7 @@ Data Browser and Stack Slicer. Copyright (C) 2005-@year@ Melissa Linkert, import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; +import ij.Macro; import ij.gui.GenericDialog; import java.awt.Button; @@ -41,7 +42,6 @@ Data Browser and Stack Slicer. Copyright (C) 2005-@year@ Melissa Linkert, import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.StringTokenizer; import javax.swing.Box; import javax.swing.JPanel; @@ -62,6 +62,7 @@ public class SeriesDialog extends ImporterDialog implements ActionListener { public static final int MAX_COMPONENTS = 256; public static final int MAX_SERIES_THUMBS = 200; + public static final int MAX_SERIES_TOGGLES = MAX_SERIES_THUMBS; // -- Fields -- @@ -80,40 +81,12 @@ public SeriesDialog(ImportProcess process) { @Override protected boolean needPrompt() { - // CTR FIXME - eliminate weird handling of series string here - String seriesString = options.getSeries(); - if (process.isWindowless()) { - if (seriesString != null) { - if (seriesString.startsWith("[")) { - seriesString = seriesString.substring(1, seriesString.length() - 2); - } - - // default all series to false - final int seriesCount = process.getSeriesCount(); - for (int s=0; s 1 && + return !process.isWindowless() && process.getSeriesCount() > 1 && !options.openAllSeries() && !options.isViewNone(); } @Override protected GenericDialog constructDialog() { - // -- CTR FIXME - refactor series-related options into SeriesOptions class - // has a normalize(IFormatReader) method - // call both before and after the dialog here... - final int seriesCount = process.getSeriesCount(); // NB: Load thumbnails only when series count is modest. @@ -138,31 +111,44 @@ protected GenericDialog constructDialog() { GenericDialog gd = new GenericDialog("Bio-Formats Series Options"); - // NB: We need to add the checkboxes in groups, to prevent an - // exception from being thrown if there are more than 512 series. - // See also: - // https://skyking.microscopy.wisc.edu/trac/java/ticket/408 and - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5107980 - - final int nGroups = (seriesCount + MAX_COMPONENTS - 1) / MAX_COMPONENTS; - int nextSeries = 0; - for (int i=0; i