Changeset 6874


Ignore:
Timestamp:
09/02/10 15:29:39 (9 years ago)
Author:
curtis
Message:

Better series handling when number of series is extremely large.

Location:
trunk/components/loci-plugins/src/loci/plugins/in
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/loci-plugins/src/loci/plugins/in/ImportProcess.java

    r6716 r6874  
    2929import java.util.ArrayList; 
    3030import java.util.List; 
     31import java.util.StringTokenizer; 
    3132 
    3233import loci.common.Location; 
     
    180181    if (options.isWindowless()) return true; // globally windowless 
    181182    return baseReader != null && LociPrefs.isWindowless(baseReader); 
     183  } 
     184 
     185  public void setSeriesList(String seriesList) { 
     186    final int seriesCount = getSeriesCount(); 
     187    options.clearSeries(); 
     188 
     189    // remove illegal characters 
     190    seriesList = seriesList.replaceAll("[^\\d,\\-]", ""); 
     191 
     192    // parse series list 
     193    StringTokenizer st = new StringTokenizer(seriesList, ","); 
     194    while (st.hasMoreTokens()) { 
     195      final String token = st.nextToken(); 
     196      int dash = token.indexOf("-"); 
     197      if (dash < 0) { 
     198        // single number 
     199        try { 
     200          final int s = Integer.parseInt(token) - 1; 
     201          options.setSeriesOn(s, true); 
     202        } 
     203        catch (NumberFormatException exc) { 
     204          // skip invalid series number 
     205        } 
     206      } 
     207      else { 
     208        // numerical range 
     209        final String firstString = token.substring(0, dash); 
     210        final String lastString = token.substring(dash + 1); 
     211        try { 
     212          final int first = Integer.parseInt(firstString) - 1; 
     213          final int last = Integer.parseInt(lastString) - 1; 
     214          for (int s = first; s <= last; s++) { 
     215            if (s >= seriesCount) break; // skip out of bounds series 
     216            options.setSeriesOn(s, true); 
     217          } 
     218        } 
     219        catch (NumberFormatException exc) { 
     220          // skip invalid numerical range 
     221        } 
     222      } 
     223    } 
    182224  } 
    183225 
  • trunk/components/loci-plugins/src/loci/plugins/in/ImporterOptions.java

    r6659 r6874  
    6565  public static final String KEY_QUIET           = "quiet"; 
    6666  //public static final String KEY_RECORD          = "record"; 
    67   public static final String KEY_SERIES          = "series"; 
    6867  public static final String KEY_SHOW_METADATA   = "showMetadata"; 
    6968  public static final String KEY_SHOW_OME_XML    = "showOMEXML"; 
     
    196195  /** Handles obsolete macro keys, for backward compatibility. */ 
    197196  public void checkObsoleteOptions() { 
    198     String options = Macro.getOptions(); 
     197    final String macroOptions = Macro.getOptions(); 
    199198 
    200199    // NB: It would be nice to remove the Standard ImageJ option someday; 
    201200    // when that happens, the following code provides support for old macros. 
    202201    // check obsolete view options 
    203     //String stackFormat = options == null ? 
    204     //  null : Macro.getValue(options, "view", null); 
     202    //String stackFormat = macroOptions == null ? 
     203    //  null : Macro.getValue(macroOptions, "view", null); 
    205204    //final String viewStandard = "Standard ImageJ"; 
    206205    //if (viewStandard.equals(stackFormat)) { 
    207206    //  // Standard ImageJ -> Hyperstack 
    208     //  options = options.replaceFirst( 
     207    //  macroOptions = macroOptions.replaceFirst( 
    209208    //    "\\[" + viewStandard + "\\]", VIEW_HYPERSTACK); 
    210     //  Macro.setOptions(options); 
     209    //  Macro.setOptions(macroOptions); 
    211210    //  setStackFormat(VIEW_HYPERSTACK); 
    212211    //} 
    213212 
    214213    // check obsolete color options 
    215     boolean mergeChannels = checkKey(options, "merge_channels"); 
    216     boolean rgbColorize = checkKey(options, "rgb_colorize"); 
    217     boolean customColorize = checkKey(options, "custom_colorize"); 
     214    final boolean mergeChannels = checkKey(macroOptions, "merge_channels"); 
     215    final boolean rgbColorize = checkKey(macroOptions, "rgb_colorize"); 
     216    final boolean customColorize = checkKey(macroOptions, "custom_colorize"); 
    218217    if (mergeChannels) setColorMode(COLOR_MODE_COMPOSITE); 
    219218    else if (rgbColorize) setColorMode(COLOR_MODE_COLORIZED); 
     
    307306  //public void setRecord(boolean b) { setValue(KEY_RECORD, b); } 
    308307 
    309   // series 
    310   public String getSeriesInfo() { return getInfo(KEY_SERIES); } 
    311   public String getSeries() { return getValue(KEY_SERIES); } 
    312   public void setSeries(String s) { setValue(KEY_SERIES, s); } 
    313  
    314308  // showMetadata 
    315309  public String getShowMetadataInfo() { return getInfo(KEY_SHOW_METADATA); } 
     
    404398  public void setSeriesOn(int s, boolean value) { 
    405399    set(seriesOn, s, value, false); 
     400  } 
     401  public void clearSeries() { 
     402    seriesOn.clear(); 
    406403  } 
    407404 
     
    486483 
    487484  /** Tests whether the given boolean key is set in the specified options. */ 
    488   private boolean checkKey(String options, String key) { 
     485  protected boolean checkKey(String options, String key) { 
    489486    if (options == null) return false; 
    490487 
  • trunk/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java

    r6660 r6874  
    3030import com.jgoodies.forms.layout.FormLayout; 
    3131 
     32import ij.Macro; 
    3233import ij.gui.GenericDialog; 
    3334 
     
    4243import java.awt.event.ActionEvent; 
    4344import java.awt.event.ActionListener; 
    44 import java.util.StringTokenizer; 
    4545 
    4646import javax.swing.Box; 
     
    6363  public static final int MAX_COMPONENTS = 256; 
    6464  public static final int MAX_SERIES_THUMBS = 200; 
     65  public static final int MAX_SERIES_TOGGLES = MAX_SERIES_THUMBS; 
    6566 
    6667  // -- Fields -- 
     
    8182  @Override 
    8283  protected boolean needPrompt() { 
    83     // CTR FIXME - eliminate weird handling of series string here 
    84     String seriesString = options.getSeries(); 
    85     if (process.isWindowless()) { 
    86       if (seriesString != null) { 
    87         if (seriesString.startsWith("[")) { 
    88           seriesString = seriesString.substring(1, seriesString.length() - 2); 
    89         } 
    90  
    91         // default all series to false 
    92         final int seriesCount = process.getSeriesCount(); 
    93         for (int s=0; s<seriesCount; s++) options.setSeriesOn(s, false); 
    94  
    95         // extract enabled series values from series string 
    96         StringTokenizer tokens = new StringTokenizer(seriesString, " "); 
    97         while (tokens.hasMoreTokens()) { 
    98           String token = tokens.nextToken().trim(); 
    99           int n = Integer.parseInt(token); 
    100           if (n < seriesCount) options.setSeriesOn(n, true); 
    101         } 
    102       } 
    103       options.setSeries(seriesString); 
    104       return false; 
    105     } 
    106  
    107     return process.getSeriesCount() > 1 && 
     84    return !process.isWindowless() && process.getSeriesCount() > 1 && 
    10885      !options.openAllSeries() && !options.isViewNone(); 
    10986  } 
     
    11188  @Override 
    11289  protected GenericDialog constructDialog() { 
    113     // -- CTR FIXME - refactor series-related options into SeriesOptions class 
    114     // has a normalize(IFormatReader) method 
    115     // call both before and after the dialog here... 
    116  
    11790    final int seriesCount = process.getSeriesCount(); 
    11891 
     
    139112    GenericDialog gd = new GenericDialog("Bio-Formats Series Options"); 
    140113 
    141     // NB: We need to add the checkboxes in groups, to prevent an 
    142     // exception from being thrown if there are more than 512 series. 
    143     // See also: 
    144     //   https://skyking.microscopy.wisc.edu/trac/java/ticket/408 and 
    145     //   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5107980 
    146  
    147     final int nGroups = (seriesCount + MAX_COMPONENTS - 1) / MAX_COMPONENTS; 
    148     int nextSeries = 0; 
    149     for (int i=0; i<nGroups; i++) { 
    150       final int nRows = Math.min(MAX_COMPONENTS, seriesCount - nextSeries); 
    151       final String[] labels = new String[nRows]; 
    152       final boolean[] defaultValues = new boolean[nRows]; 
    153       for (int row=0; row<nRows; row++) { 
    154         labels[row] = process.getSeriesLabel(nextSeries); 
    155         defaultValues[row] = options.isSeriesOn(nextSeries); 
    156         nextSeries++; 
    157       } 
    158       gd.addCheckboxGroup(nRows, 1, labels, defaultValues); 
    159     } 
    160  
    161     // extract checkboxes, for "Select All" and "Deselect All" functions 
    162     boxes = WindowTools.getCheckboxes(gd).toArray(new Checkbox[0]); 
    163  
    164     // rebuild dialog so that the thumbnails and checkboxes line up correctly 
    165     rebuildDialog(gd, nGroups); 
     114    // NB: Provide individual checkboxes only when series count is manageable. 
     115    if (seriesCount < MAX_SERIES_TOGGLES) { 
     116      // NB: We need to add the checkboxes in groups, to prevent an 
     117      // exception from being thrown if there are more than 512 series. 
     118      // See also: 
     119      //   https://skyking.microscopy.wisc.edu/trac/java/ticket/408 and 
     120      //   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5107980 
     121 
     122      final int nGroups = (seriesCount + MAX_COMPONENTS - 1) / MAX_COMPONENTS; 
     123      int nextSeries = 0; 
     124      for (int i=0; i<nGroups; i++) { 
     125        final int nRows = Math.min(MAX_COMPONENTS, seriesCount - nextSeries); 
     126        final String[] labels = new String[nRows]; 
     127        final boolean[] defaultValues = new boolean[nRows]; 
     128        for (int row=0; row<nRows; row++) { 
     129          labels[row] = process.getSeriesLabel(nextSeries); 
     130          defaultValues[row] = options.isSeriesOn(nextSeries); 
     131          nextSeries++; 
     132        } 
     133        gd.addCheckboxGroup(nRows, 1, labels, defaultValues); 
     134      } 
     135 
     136      // extract checkboxes, for "Select All" and "Deselect All" functions 
     137      boxes = WindowTools.getCheckboxes(gd).toArray(new Checkbox[0]); 
     138 
     139      // rebuild dialog so that the thumbnails and checkboxes line up correctly 
     140      rebuildDialog(gd, nGroups); 
     141    } 
     142    else { 
     143      // too many series; display a simple text field for specifying series 
     144      gd.addMessage( 
     145        "Please specify the image series you wish to import.\n" + 
     146        "Use commas to list multiple series. You can also use\n" + 
     147        "a dash to represent a range of series. For example,\n" + 
     148        "to import series 1, 3, 4, 5, 7, 8, 9, 12, 15 & 16,\n" + 
     149        "you could write: 1, 3-5, 7-9, 12, 15-16"); 
     150      gd.addStringField("Series_list: ", "1"); 
     151    } 
    166152 
    167153    return gd; 
     
    183169  protected boolean harvestResults(GenericDialog gd) { 
    184170    final int seriesCount = process.getSeriesCount(); 
    185     String seriesString = "["; 
    186     for (int i=0; i<seriesCount; i++) { 
    187       boolean on = gd.getNextBoolean(); 
    188       options.setSeriesOn(i, on); 
    189       if (on) seriesString += i + " "; 
    190     } 
    191     seriesString += "]"; 
    192     options.setSeries(seriesString); 
     171    options.clearSeries(); 
     172 
     173    // examine series key regardless of number of series 
     174    final String macroOptions = Macro.getOptions(); 
     175    final String macroSeriesList = macroOptions == null ? null : 
     176      Macro.getValue(macroOptions, "series_list", null); 
     177    if (macroSeriesList != null) process.setSeriesList(macroSeriesList); 
     178 
     179    if (seriesCount < MAX_SERIES_TOGGLES) { 
     180      // harvest individual checkbox values 
     181      for (int i=0; i<seriesCount; i++) { 
     182        final boolean on = gd.getNextBoolean(); 
     183        if (on) options.setSeriesOn(i, on); 
     184      } 
     185    } 
     186    else { 
     187      // harvest series string 
     188      final String seriesList = gd.getNextString(); 
     189      process.setSeriesList(seriesList); 
     190    } 
     191 
     192    // examine series_XX keys regardless of number of series 
     193    if (macroOptions != null) { 
     194      for (int i=0; i<seriesCount; i++) { 
     195        final String seriesKey = "series_" + (i + 1); 
     196        final boolean on = options.checkKey(macroOptions, seriesKey); 
     197        if (on) options.setSeriesOn(i, on); 
     198      } 
     199    } 
     200 
    193201    return true; 
    194202  } 
     
    197205 
    198206  public void actionPerformed(ActionEvent e) { 
    199     String cmd = e.getActionCommand(); 
     207    final String cmd = e.getActionCommand(); 
    200208    if ("select".equals(cmd)) { 
    201209      for (int i=0; i<boxes.length; i++) boxes[i].setState(true); 
     
    219227 
    220228  private void rebuildDialog(GenericDialog gd, int buttonRow) { 
    221     // rebuild dialog using FormLayout to organize things more nicely 
     229    // rebuild dialog to organize things more nicely 
    222230 
    223231    final String cols = p == null ? "pref" : "pref, 3dlu, pref"; 
  • trunk/components/loci-plugins/src/loci/plugins/in/importer-options.txt

    r6869 r6874  
    173173#  more like a normal, fully memory-resident image stack. 
    174174#default = false 
    175  
    176 [series] 
    177 type = string 
    178 label = series 
    179 default = 0 
    180175 
    181176[showMetadata] 
Note: See TracChangeset for help on using the changeset viewer.