Changeset 5119


Ignore:
Timestamp:
05/25/09 17:18:00 (11 years ago)
Author:
melissa
Message:
  • Fixed IPW dimension order.
  • Some cleanup in ICSReader - fixes a few NumberFormatExceptions.
Location:
trunk/components/bio-formats/src/loci/formats/in
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/in/ICSReader.java

    r5094 r5119  
    3030import java.util.zip.GZIPInputStream; 
    3131 
     32import loci.common.ByteArrayHandle; 
    3233import loci.common.DataTools; 
    3334import loci.common.Location; 
     
    5859  private static final String[] CATEGORIES = new String[] { 
    5960    "ics_version", "filename", "source", "layout", "representation", 
    60     "parameter", "sensor", "history", "document", "view", "end" 
    61   }; 
    62  
    63   /** Metadata field subcategories. */ 
    64   private static final String[] SUB_CATEGORIES = new String[] { 
    65     "file", "offset", "parameters", "order", "sizes", "coordinates", 
    66     "significant_bits", "format", "sign", "compression", "byte_order", 
    67     "origin", "scale", "units", "labels", "SCIL_TYPE", "type", "model", 
    68     "s_params", "laser", "gain*", "dwell", "shutter*", "pinhole", "laser*", 
    69     "version", "objective", "PassCount", "step*", "view", 
    70     "view*", "date", "GMTdate", "label", "software", "author", "length", 
    71     "Z (background)", "dimensions", "rep period", "image form", 
    72     "extents", "offsets", "region", "expon. order", "a*", "tau*", 
    73     "noiseval", "excitationfwhm", "created on", 
    74     "text", "other text", "mode", "CFD limit low", "CFD limit high", 
    75     "CFD zc level", "CFD holdoff", "SYNC zc level", "SYNC freq div", 
    76     "SYNC holdoff", "TAC range", "TAC gain", "TAC offset", "TAC limit low", 
    77     "ADC resolution", "Ext latch delay", "collection time", "repeat time", 
    78     "stop on time", "stop on O'flow", "dither range", "count increment", 
    79     "memory bank", "sync threshold", "dead time comp", "polarity", 
    80     "line compressio", "scan flyback", "scan borders", "pixel time", 
    81     "pixel clock", "trigger", "scan pixels x", "scan pixels y", 
    82     "routing chan x", "routing chan y", "detector type", "channel*", 
    83     "filter*", "wavelength*", "black level*", "gain*", "ht*", 
    84     "scan resolution", "scan speed", "scan zoom", "scan pattern", 
    85     "scan pos x", "scan pos y", "transmission", "x amplitude", "y amplitude", 
    86     "x offset", "y offset", "x delay", "y delay", "beam zoom", "mirror *", 
    87     "direct turret", "desc exc turret", "desc emm turret", "cube", 
    88     "stage_xyzum", "cube descriptio", "camera", "exposure", "bits/pixel", 
    89     "black level", "binning", "left", "top", "cols", "rows", "gain", 
    90     "significant_channels", "allowedlinemodes", "real_significant_bits", 
    91     "sample_width", "range", "ch", "lower_limit", "higher_limit", "passcount", 
    92     "detector", "dateGMT", "RefrInxMedium", "RefrInxLensMedium" 
    93   }; 
    94  
    95   /** Metadata field sub-subcategories. */ 
    96   private static final String[] SUB_SUB_CATEGORIES = new String[] { 
    97     "Channels", "PinholeRadius", "LambdaEx", "LambdaEm", "ExPhotonCnt", 
    98     "RefInxMedium", "NumAperture", "RefInxLensMedium", "PinholeSpacing", 
    99     "power", "wavelength", "name", "Type", "Magnification", "NA", 
    100     "WorkingDistance", "Immersion", "Pinhole", "Channel *", "Gain *", 
    101     "Shutter *", "Position", "Size", "Port", "Cursor", "Color", "BlackLevel", 
     61    "parameter", "sensor", "history", "document", "view.*", "end", "file", 
     62    "offset", "parameters", "order", "sizes", "coordinates", "significant_bits", 
     63    "format", "sign", "compression", "byte_order", "origin", "scale", "units", 
     64    "labels", "SCIL_TYPE", "type", "model", "s_params", "gain.*", "dwell", 
     65    "shutter.*", "pinhole", "laser.*", "version", "objective", "PassCount", 
     66    "step.*", "date", "GMTdate", "label", "software", "author", "length", 
     67    "Z (background)", "dimensions", "rep period", "image form", "extents", 
     68    "offsets", "region", "expon. order", "a.*", "tau.*", "noiseval", 
     69    "excitationfwhm", "created on", "text", "other text", "mode", 
     70    "CFD limit low", "CFD limit high", "CFD zc level", "CFD holdoff", 
     71    "SYNC zc level", "SYNC freq div", "SYNC holdoff", "TAC range", "TAC gain", 
     72    "TAC offset", "TAC limit low", "ADC resolution", "Ext latch delay", 
     73    "collection time", "repeat time", "stop on time", "stop on O'flow", 
     74    "dither range", "count increment", "memory bank", "sync threshold", 
     75    "dead time comp", "polarity", "line compressio", "scan flyback", 
     76    "scan borders", "pixel time", "pixel clock", "trigger", "scan pixels x", 
     77    "scan pixels y", "routing chan x", "routing chan y", "detector type", 
     78    "channel.*", "filter.*", "wavelength.*", "black level.*", "ht.*", 
     79    "scan resolution", "scan speed", "scan zoom", "scan pattern", "scan pos x", 
     80    "scan pos y", "transmission", "x amplitude", "y amplitude", "x offset", 
     81    "y offset", "x delay", "y delay", "beam zoom", "mirror .*", "direct turret", 
     82    "desc exc turret", "desc emm turret", "cube", "stage_xyzum", 
     83    "cube descriptio", "camera", "exposure", "bits/pixel", "binning", "left", 
     84    "top", "cols", "rows", "significant_channels", "allowedlinemodes", 
     85    "real_significant_bits", "sample_width", "range", "ch", "lower_limit", 
     86    "higher_limit", "passcount", "detector", "dateGMT", "RefrInxMedium", 
     87    "RefrInxLensMedium", "Channels", "PinholeRadius", "LambdaEx", "LambdaEm", 
     88    "ExPhotonCnt", "RefInxMedium", "NumAperture", "RefInxLensMedium", 
     89    "PinholeSpacing", "power", "name", "Type", "Magnification", "NA", 
     90    "WorkingDistance", "Immersion", "Pinhole", "Channel .*", "Gain .*", 
     91    "Shutter .*", "Position", "Size", "Port", "Cursor", "Color", "BlackLevel", 
    10292    "Saturation", "Gamma", "IntZoom", "Live", "Synchronize", "ShowIndex", 
    10393    "AutoResize", "UseUnits", "Zoom", "IgnoreAspect", "ShowCursor", "ShowAll", 
    104     "Axis", "Order", "Tile", "scale", "DimViewOption" 
     94    "Axis", "Order", "Tile", "DimViewOption", "channels", "pinholeradius", 
     95    "refrinxmedium", "numaperture", "refrinxlensmedium" 
    10596  }; 
    10697 
     
    111102  private String currentIdsId; 
    112103 
    113   /** Current ICS file. */ 
    114   private Location icsIn; 
    115  
    116   /** Number of bits per pixel. */ 
    117   private int bitsPerPixel; 
    118  
    119104  /** Flag indicating whether current file is v2.0. */ 
    120105  private boolean versionTwo; 
     
    123108  private byte[] data; 
    124109 
    125   /** Emission and excitation wavelength. */ 
    126   private String em, ex; 
    127  
     110  /** Offset to pixel data. */ 
    128111  private long offset; 
     112 
     113  /** Whether or not the pixels are GZIP-compressed. */ 
    129114  private boolean gzip; 
    130115 
     116  /** Whether or not the image is inverted along the Y axis. */ 
    131117  private boolean invertY; 
    132  
    133   private String imageName, date, magnification, lastName, description; 
    134   private String objectiveModel, immersion, lensNA, workingDistance; 
    135   private Hashtable gains, wavelengths, pinholes, channelNames; 
    136   private String[] stagePos; 
    137118 
    138119  // -- Constructor -- 
     
    165146    FormatTools.checkBufferSize(this, buf.length, w, h); 
    166147 
    167     int bpp = bitsPerPixel / 8; 
     148    int bpp = FormatTools.getBytesPerPixel(getPixelType()); 
    168149    int len = getSizeX() * getSizeY() * bpp * getRGBChannelCount(); 
    169150    int pixel = bpp * getRGBChannelCount(); 
     
    193174      else { 
    194175        for (int row=y; row<h + y; row++) { 
    195           System.arraycopy(data, len * no + row * getSizeX() * pixel + 
    196             x * pixel, buf, row * rowLen, rowLen); 
     176          System.arraycopy(data, len * no + pixel * (row * getSizeX() + x), 
     177            buf, row * rowLen, rowLen); 
    197178        } 
    198179      } 
     
    205186      byte[] row = new byte[rowLen]; 
    206187      for (int r=0; r<h/2; r++) { 
    207         System.arraycopy(buf, r*rowLen, row, 0, rowLen); 
    208         System.arraycopy(buf, (h - r - 1)*rowLen, buf, r*rowLen, rowLen); 
    209         System.arraycopy(row, 0, buf, (h - r - 1)*rowLen, rowLen); 
     188        int topOffset = r * rowLen; 
     189        int bottomOffset = (h - r - 1) * rowLen; 
     190        System.arraycopy(buf, topOffset, row, 0, rowLen); 
     191        System.arraycopy(buf, bottomOffset, buf, topOffset, rowLen); 
     192        System.arraycopy(row, 0, buf, bottomOffset, rowLen); 
    210193      } 
    211194    } 
     
    227210    FormatTools.assertId(currentId, true, 1); 
    228211    if (noPixels && !versionTwo) return new String[] {currentIcsId}; 
    229     return null; 
     212    else if (noPixels) return null; 
     213    return getUsedFiles(); 
    230214  } 
    231215 
     
    235219  public void close() throws IOException { 
    236220    super.close(); 
    237     icsIn = null; 
    238221    currentIcsId = null; 
    239222    currentIdsId = null; 
    240223    data = null; 
    241     bitsPerPixel = 0; 
    242224    versionTwo = false; 
    243225    gzip = false; 
    244226    invertY = false; 
    245     imageName = date = objectiveModel = immersion = lensNA = null; 
    246     workingDistance = magnification = lastName = description = null; 
    247     gains = wavelengths = pinholes = channelNames = null; 
    248     stagePos = null; 
    249227  } 
    250228 
     
    291269      if (!idsFile.exists()) throw new FormatException("IDS file not found."); 
    292270      currentIdsId = idsId; 
    293       in = new RandomAccessInputStream(idsId); 
     271      in = new RandomAccessInputStream(currentIdsId); 
    294272    } 
    295273    f.close(); 
     
    297275    currentIcsId = icsId; 
    298276 
    299     icsIn = icsFile; 
    300  
    301277    status("Reading metadata"); 
    302278 
    303     String layoutSizes = null, layoutOrder = null, byteOrder = null; 
    304     String rFormat = null, compression = null, scale = null; 
     279    Float[] pixelSizes = null; 
     280    String[] axes = null; 
     281    int[] axisLengths = null; 
     282    String byteOrder = null, rFormat = null, compression = null; 
    305283 
    306284    // parse key/value pairs from beginning of ICS file 
    307285 
    308     RandomAccessInputStream reader = 
    309       new RandomAccessInputStream(icsIn.getAbsolutePath()); 
     286    RandomAccessInputStream reader = new RandomAccessInputStream(icsId); 
    310287    reader.seek(0); 
    311     String token; 
     288    reader.readLine(); 
    312289    String line = reader.readLine(); 
    313     line = reader.readLine(); 
    314290    boolean signed = false; 
    315291 
    316292    StringBuffer textBlock = new StringBuffer(); 
    317     String[] sizes = null, labels = null, lengths= null; 
     293    float[] sizes = null; 
     294 
     295    Integer[] emWaves = null, exWaves = null; 
     296    Float[] stagePos = null; 
     297    String imageName = null, date = null, description = null; 
     298    Float magnification = null, lensNA = null, workingDistance = null; 
     299    String objectiveModel = null, immersion = null, lastName = null; 
     300    Hashtable<Integer, Float> gains = new Hashtable<Integer, Float>(); 
     301    Hashtable<Integer, Float> pinholes = new Hashtable<Integer, Float>(); 
     302    Hashtable<Integer, Integer> wavelengths = new Hashtable<Integer, Integer>(); 
     303    Hashtable<Integer, String> channelNames = new Hashtable<Integer, String>(); 
    318304 
    319305    while (line != null && !line.trim().equals("end")) { 
    320       String[] tokens = null; 
     306     String[] tokens = null; 
    321307      if (line.indexOf("\t") != -1) tokens = line.split("\t"); 
    322308      else tokens = line.split(" "); 
     
    328314        boolean foundValue = true; 
    329315        for (int i=0; i<CATEGORIES.length; i++) { 
    330           if (matches(CATEGORIES[i], tokens[q])) { 
     316          if (tokens[q].matches(CATEGORIES[i])) { 
    331317            foundValue = false; 
    332318            break; 
    333319          } 
    334320        } 
    335         if (foundValue) { 
    336           for (int i=0; i<SUB_CATEGORIES.length; i++) { 
    337             if (matches(SUB_CATEGORIES[i], tokens[q])) { 
    338               foundValue = false; 
    339               break; 
    340             } 
    341           } 
    342         } 
    343         if (foundValue) { 
    344           for (int i=0; i<SUB_SUB_CATEGORIES.length; i++) { 
    345             if (matches(SUB_SUB_CATEGORIES[i], tokens[q])) { 
    346               foundValue = false; 
    347               break; 
    348             } 
    349           } 
    350         } 
    351  
    352         if (foundValue) { 
    353           StringBuffer value = new StringBuffer(); 
    354           value.append(tokens[q++]); 
    355           for (; q<tokens.length; q++) { 
    356             value.append(" "); 
    357             value.append(tokens[q].trim()); 
    358           } 
    359           String k = key.toString().trim(); 
    360           String v = value.toString().trim(); 
    361           addMeta(k, v); 
    362  
    363           k = k.replaceAll("\t", " "); 
    364  
    365           if (k.equalsIgnoreCase("layout sizes")) layoutSizes = v; 
    366           else if (k.equalsIgnoreCase("layout order")) layoutOrder = v; 
    367           else if (k.equalsIgnoreCase("representation byte_order")) { 
    368             byteOrder = v; 
    369           } 
    370           else if (k.equalsIgnoreCase("representation format")) rFormat = v; 
    371           else if (k.equalsIgnoreCase("representation compression")) { 
    372             compression = v; 
    373           } 
    374           else if (k.equalsIgnoreCase("parameter scale")) scale = v; 
    375           else if (k.equalsIgnoreCase("representation sign")) { 
    376             signed = v.equals("signed"); 
    377           } 
    378           else if (k.equalsIgnoreCase("sensor s_params LambdaEm")) em = v; 
    379           else if (k.equalsIgnoreCase("sensor s_params LambdaEx")) ex = v; 
    380           else if (k.equalsIgnoreCase("history software") && 
    381             v.indexOf("SVI") != -1) 
    382           { 
    383             // ICS files written by SVI Huygens are inverted on the Y axis 
    384             invertY = true; 
    385           } 
    386           else if (k.equalsIgnoreCase("history") || 
    387             k.equalsIgnoreCase("history text")) 
    388           { 
    389             textBlock.append(v); 
    390             textBlock.append("\n"); 
    391             metadata.remove(k); 
    392           } 
    393           else if (k.equalsIgnoreCase("filename")) imageName = v; 
    394           else if (k.equalsIgnoreCase("history date") || 
    395             k.equalsIgnoreCase("history created on")) 
    396           { 
    397             if (v.indexOf(" ") == -1) continue; 
    398             date = v.substring(0, v.lastIndexOf(" ")); 
    399             String[] formats = new String[] {"EEEE, MMMM dd, yyyy HH:mm:ss", 
    400               "EEE dd MMMM yyyy HH:mm:ss", "EEE MMM dd HH:mm:ss yyyy", 
    401               "EE dd MMM yyyy HH:mm:ss z"}; 
    402  
    403             boolean success = false; 
    404  
    405             for (int n=0; n<formats.length; n++) { 
    406               try { 
    407                 date = DataTools.formatDate(date, formats[n]); 
    408                 success = true; 
    409               } 
    410               catch (NullPointerException e) { } 
    411             } 
    412  
    413             if (!success) date = null; 
    414           } 
    415           else if (k.startsWith("history gain")) { 
    416             int n = 0; 
    417             try { 
    418               n = Integer.parseInt(k.substring(12).trim()); 
    419             } 
    420             catch (NumberFormatException e) { } 
    421             if (gains == null) gains = new Hashtable(); 
    422             gains.put(new Integer(n), v); 
    423           } 
    424           else if (k.startsWith("history laser") && k.endsWith("wavelength")) { 
    425             int laser = Integer.parseInt(k.substring(13, k.indexOf(" ", 13))); 
    426             v = v.replaceAll("nm", "").trim(); 
    427             if (wavelengths == null) wavelengths = new Hashtable(); 
    428             wavelengths.put(new Integer(laser), v); 
    429           } 
    430           else if (k.equalsIgnoreCase("history objective type")) { 
    431             objectiveModel = v; 
    432           } 
    433           else if (k.equalsIgnoreCase("history objective immersion")) { 
    434             immersion = v; 
    435           } 
    436           else if (k.equalsIgnoreCase("history objective NA")) { 
    437             lensNA = v; 
    438           } 
    439           else if (k.equalsIgnoreCase("history objective WorkingDistance")) { 
    440             workingDistance = v; 
    441           } 
    442           else if (k.equalsIgnoreCase("history objective magnification")) { 
    443             magnification = v; 
    444           } 
    445           else if (k.equalsIgnoreCase("sensor s_params PinholeRadius")) { 
    446             String[] pins = v.split(" "); 
    447             int channel = 0; 
    448             if (pinholes == null) pinholes = new Hashtable(); 
    449             for (int n=0; n<pins.length; n++) { 
    450               if (pins[n].trim().equals("")) continue; 
    451               pinholes.put(new Integer(channel++), pins[n]); 
    452             } 
    453           } 
    454           else if (k.equalsIgnoreCase("history author")) lastName = v; 
    455           else if (k.equalsIgnoreCase("history extents")) { 
    456             sizes = v.split(" "); 
    457           } 
    458           else if (k.equalsIgnoreCase("history lengths")) { 
    459             lengths = v.split(" "); 
    460           } 
    461           else if (k.equalsIgnoreCase("history labels")) { 
    462             labels = v.split(" "); 
    463           } 
    464           else if (k.equalsIgnoreCase("history stage_xyzum")) { 
    465             stagePos = v.split(" "); 
    466           } 
    467           else if (k.equalsIgnoreCase("history other text")) { 
    468             description = v; 
    469           } 
    470           else if (k.startsWith("history step") && k.endsWith("name")) { 
    471             Integer n = new Integer(k.substring(12, k.indexOf(" ", 12))); 
    472             if (channelNames == null) channelNames = new Hashtable(); 
    473             channelNames.put(n, v); 
    474           } 
    475           else if (k.equalsIgnoreCase("parameter ch")) { 
    476             String[] names = v.split(" "); 
    477             if (channelNames == null) channelNames = new Hashtable(); 
    478             for (int n=0; n<names.length; n++) { 
    479               channelNames.put(new Integer(n), names[n].trim()); 
    480             } 
    481           } 
    482         } 
    483         else { 
     321        if (!foundValue) { 
    484322          key.append(tokens[q]); 
    485323          key.append(" "); 
     324          continue; 
     325        } 
     326 
     327        StringBuffer value = new StringBuffer(tokens[q++]); 
     328        for (; q<tokens.length; q++) { 
     329          value.append(" "); 
     330          value.append(tokens[q].trim()); 
     331        } 
     332        String k = key.toString().trim().replaceAll("\t", " "); 
     333        String v = value.toString().trim(); 
     334        addMeta(k, v); 
     335 
     336        Float floatValue = null; 
     337        try { 
     338          floatValue = new Float(v); 
     339        } 
     340        catch (NumberFormatException e) { 
     341          if (debug) trace(e); 
     342        } 
     343 
     344        if (k.equalsIgnoreCase("layout sizes")) { 
     345          StringTokenizer t = new StringTokenizer(v); 
     346          axisLengths = new int[t.countTokens()]; 
     347          for (int n=0; n<axisLengths.length; n++) { 
     348            try { 
     349              axisLengths[n] = Integer.parseInt(t.nextToken().trim()); 
     350            } 
     351            catch (NumberFormatException e) { 
     352              if (debug) trace(e); 
     353            } 
     354          } 
     355        } 
     356        else if (k.equalsIgnoreCase("layout order")) { 
     357          StringTokenizer t = new StringTokenizer(v); 
     358          axes = new String[t.countTokens()]; 
     359          for (int n=0; n<axes.length; n++) { 
     360            axes[n] = t.nextToken().trim(); 
     361          } 
     362        } 
     363        else if (k.equalsIgnoreCase("representation byte_order")) { 
     364          byteOrder = v; 
     365        } 
     366        else if (k.equalsIgnoreCase("representation format")) rFormat = v; 
     367        else if (k.equalsIgnoreCase("representation compression")) { 
     368          compression = v; 
     369        } 
     370        else if (k.equalsIgnoreCase("parameter scale")) { 
     371          StringTokenizer t = new StringTokenizer(v); 
     372          pixelSizes = new Float[t.countTokens()]; 
     373          for (int n=0; n<pixelSizes.length; n++) { 
     374            try { 
     375              pixelSizes[n] = new Float(t.nextToken().trim()); 
     376            } 
     377            catch (NumberFormatException e) { 
     378              if (debug) trace(e); 
     379            } 
     380          } 
     381        } 
     382        else if (k.equalsIgnoreCase("representation sign")) { 
     383          signed = v.equals("signed"); 
     384        } 
     385        else if (k.equalsIgnoreCase("sensor s_params LambdaEm")) { 
     386          String[] waves = v.split(" "); 
     387          emWaves = new Integer[waves.length]; 
     388          for (int n=0; n<emWaves.length; n++) { 
     389            try { 
     390              emWaves[n] = new Integer((int) Float.parseFloat(waves[n])); 
     391            } 
     392            catch (NumberFormatException e) { 
     393              if (debug) trace(e); 
     394            } 
     395          } 
     396        } 
     397        else if (k.equalsIgnoreCase("sensor s_params LambdaEx")) { 
     398          String[] waves = v.split(" "); 
     399          exWaves = new Integer[waves.length]; 
     400          for (int n=0; n<exWaves.length; n++) { 
     401            try { 
     402              exWaves[n] = new Integer((int) Float.parseFloat(waves[n])); 
     403            } 
     404            catch (NumberFormatException e) { 
     405              if (debug) trace(e); 
     406            } 
     407          } 
     408        } 
     409        else if (k.equalsIgnoreCase("history software") && 
     410          v.indexOf("SVI") != -1) 
     411        { 
     412          // ICS files written by SVI Huygens are inverted on the Y axis 
     413          invertY = true; 
     414        } 
     415        else if (k.equalsIgnoreCase("history") || 
     416          k.equalsIgnoreCase("history text")) 
     417        { 
     418          textBlock.append(v); 
     419          textBlock.append("\n"); 
     420          metadata.remove(k); 
     421        } 
     422        else if (k.equalsIgnoreCase("filename")) imageName = v; 
     423        else if (k.equalsIgnoreCase("history date") || 
     424          k.equalsIgnoreCase("history created on")) 
     425        { 
     426          if (v.indexOf(" ") == -1) continue; 
     427          date = v.substring(0, v.lastIndexOf(" ")); 
     428          String[] formats = new String[] {"EEEE, MMMM dd, yyyy HH:mm:ss", 
     429            "EEE dd MMMM yyyy HH:mm:ss", "EEE MMM dd HH:mm:ss yyyy", 
     430            "EE dd MMM yyyy HH:mm:ss z"}; 
     431 
     432          boolean success = false; 
     433 
     434          for (int n=0; n<formats.length; n++) { 
     435            try { 
     436              date = DataTools.formatDate(date, formats[n]); 
     437              success = true; 
     438            } 
     439            catch (NullPointerException e) { } 
     440          } 
     441 
     442          if (!success) date = null; 
     443        } 
     444        else if (k.startsWith("history gain")) { 
     445          Integer n = new Integer(0); 
     446          try { 
     447            n = new Integer(k.substring(12).trim()); 
     448            n = new Integer(n.intValue() - 1); 
     449          } 
     450          catch (NumberFormatException e) { } 
     451          if (floatValue != null) gains.put(n, floatValue); 
     452        } 
     453        else if (k.startsWith("history laser") && k.endsWith("wavelength")) { 
     454          int laser = Integer.parseInt(k.substring(13, k.indexOf(" ", 13))) - 1; 
     455          v = v.replaceAll("nm", "").trim(); 
     456          try { 
     457            wavelengths.put(new Integer(laser), new Integer(v)); 
     458          } 
     459          catch (NumberFormatException e) { 
     460            if (debug) trace(e); 
     461          } 
     462        } 
     463        else if (k.equalsIgnoreCase("history objective type")) { 
     464          objectiveModel = v; 
     465        } 
     466        else if (k.equalsIgnoreCase("history objective immersion")) { 
     467          immersion = v; 
     468        } 
     469        else if (k.equalsIgnoreCase("history objective NA")) { 
     470          lensNA = floatValue; 
     471        } 
     472        else if (k.equalsIgnoreCase("history objective WorkingDistance")) { 
     473          workingDistance = floatValue; 
     474        } 
     475        else if (k.equalsIgnoreCase("history objective magnification")) { 
     476          magnification = floatValue; 
     477        } 
     478        else if (k.equalsIgnoreCase("sensor s_params PinholeRadius")) { 
     479          String[] pins = v.split(" "); 
     480          int channel = 0; 
     481          for (int n=0; n<pins.length; n++) { 
     482            if (pins[n].trim().equals("")) continue; 
     483            try { 
     484              pinholes.put(new Integer(channel++), new Float(pins[n])); 
     485            } 
     486            catch (NumberFormatException e) { 
     487              if (debug) trace(e); 
     488            } 
     489          } 
     490        } 
     491        else if (k.equalsIgnoreCase("history author")) lastName = v; 
     492        else if (k.equalsIgnoreCase("history extents")) { 
     493          String[] lengths = v.split(" "); 
     494          sizes = new float[lengths.length]; 
     495          for (int n=0; n<sizes.length; n++) { 
     496            try { 
     497              sizes[n] = Float.parseFloat(lengths[n].trim()); 
     498            } 
     499            catch (NumberFormatException e) { 
     500              if (debug) trace(e); 
     501            } 
     502          } 
     503        } 
     504        else if (k.equalsIgnoreCase("history stage_xyzum")) { 
     505          String[] positions = v.split(" "); 
     506          stagePos = new Float[positions.length]; 
     507          for (int n=0; n<stagePos.length; n++) { 
     508            try { 
     509              stagePos[n] = new Float(positions[n]); 
     510            } 
     511            catch (NumberFormatException e) { 
     512              if (debug) trace(e); 
     513            } 
     514          } 
     515        } 
     516        else if (k.equalsIgnoreCase("history other text")) { 
     517          description = v; 
     518        } 
     519        else if (k.startsWith("history step") && k.endsWith("name")) { 
     520          Integer n = new Integer(k.substring(12, k.indexOf(" ", 12))); 
     521          channelNames.put(n, v); 
     522        } 
     523        else if (k.equalsIgnoreCase("parameter ch")) { 
     524          String[] names = v.split(" "); 
     525          for (int n=0; n<names.length; n++) { 
     526            channelNames.put(new Integer(n), names[n].trim()); 
     527          } 
    486528        } 
    487529      } 
     
    493535    addMeta("history text", textBlock.toString()); 
    494536 
    495     status("Populating metadata"); 
    496  
    497     layoutOrder = layoutOrder.trim(); 
    498     StringTokenizer t1 = new StringTokenizer(layoutSizes); 
    499     StringTokenizer t2 = new StringTokenizer(layoutOrder); 
    500  
    501     core[0].rgb = layoutOrder.indexOf("ch") >= 0 && 
    502       layoutOrder.indexOf("ch") < layoutOrder.indexOf("x"); 
     537    status("Populating core metadata"); 
     538 
     539    core[0].rgb = false; 
    503540    core[0].dimensionOrder = "XY"; 
    504541 
    505542    // find axis sizes 
    506543 
    507     String imageToken; 
    508     String orderToken; 
    509     while (t1.hasMoreTokens() && t2.hasMoreTokens()) { 
    510       imageToken = t1.nextToken().trim(); 
    511       orderToken = t2.nextToken().trim(); 
    512       if (orderToken.equals("bits")) { 
    513         bitsPerPixel = Integer.parseInt(imageToken); 
    514       } 
    515       else if (orderToken.equals("x")) { 
    516         core[0].sizeX = Integer.parseInt(imageToken); 
    517       } 
    518       else if (orderToken.equals("y")) { 
    519         core[0].sizeY = Integer.parseInt(imageToken); 
    520       } 
    521       else if (orderToken.equals("z")) { 
    522         core[0].sizeZ = Integer.parseInt(imageToken); 
     544    int bitsPerPixel = 0; 
     545    for (int i=0; i<axes.length; i++) { 
     546      if (i >= axisLengths.length) break; 
     547      if (axes[i].equals("bits")) { 
     548        bitsPerPixel = axisLengths[i]; 
     549        while (bitsPerPixel % 8 != 0) bitsPerPixel++; 
     550        if (bitsPerPixel == 24 || bitsPerPixel == 48) bitsPerPixel /= 3; 
     551      } 
     552      else if (axes[i].equals("x")) { 
     553        core[0].sizeX = axisLengths[i]; 
     554      } 
     555      else if (axes[i].equals("y")) { 
     556        core[0].sizeY = axisLengths[i]; 
     557      } 
     558      else if (axes[i].equals("z")) { 
     559        core[0].sizeZ = axisLengths[i]; 
    523560        core[0].dimensionOrder += "Z"; 
    524561      } 
    525       else if (orderToken.equals("ch")) { 
    526         core[0].sizeC = Integer.parseInt(imageToken); 
    527         if (getSizeC() > 4) core[0].rgb = false; 
     562      else if (axes[i].equals("ch")) { 
     563        core[0].sizeC = axisLengths[i]; 
     564        core[0].rgb = getSizeX() == 0 && getSizeC() <= 4 && getSizeC() > 1; 
    528565        core[0].dimensionOrder += "C"; 
    529566      } 
    530567      else { 
    531         core[0].sizeT = Integer.parseInt(imageToken); 
     568        core[0].sizeT = axisLengths[i]; 
    532569        core[0].dimensionOrder += "T"; 
    533570      } 
     
    548585    if (getSizeT() == 0) core[0].sizeT = 1; 
    549586 
    550     if (getImageCount() == 0) core[0].imageCount = 1; 
    551     core[0].rgb = isRGB() && getSizeC() > 1; 
    552587    core[0].interleaved = isRGB(); 
    553588    core[0].imageCount = getSizeZ() * getSizeT(); 
     
    556591    core[0].falseColor = false; 
    557592    core[0].metadataComplete = true; 
    558  
    559     String endian = byteOrder; 
    560593    core[0].littleEndian = true; 
    561594 
    562     if (endian != null) { 
    563       StringTokenizer endianness = new StringTokenizer(endian); 
    564       String firstByte = endianness.nextToken(); 
     595    if (byteOrder != null) { 
     596      String firstByte = byteOrder.split(" ")[0]; 
    565597      int first = Integer.parseInt(firstByte); 
    566598      core[0].littleEndian = rFormat.equals("real") ? first == 1 : first != 1; 
    567599    } 
    568600 
    569     String test = compression; 
    570     gzip = (test == null) ? false : test.equals("gzip"); 
     601    gzip = (compression == null) ? false : compression.equals("gzip"); 
    571602 
    572603    if (versionTwo) { 
    573604      String s = in.readLine(); 
    574       while(!s.trim().equals("end")) s = in.readLine(); 
     605      while (!s.trim().equals("end")) s = in.readLine(); 
    575606    } 
    576607 
     
    579610    // extra check is because some of our datasets are labeled as 'gzip', and 
    580611    // have a valid GZIP header, but are actually uncompressed 
    581     if (gzip && (((in.length() - in.getFilePointer()) / (getImageCount()) < 
    582       (getSizeX() * getSizeY() * bitsPerPixel / 8)))) 
    583     { 
     612    long pixelDataSize = getSizeX() * getSizeY() * (bitsPerPixel / 8) * 
     613      getImageCount() * getRGBChannelCount(); 
     614    if (gzip && ((in.length() - in.getFilePointer()) < pixelDataSize)) { 
    584615      data = new byte[(int) (in.length() - in.getFilePointer())]; 
    585616      status("Decompressing pixel data"); 
     
    588619      ByteVector v = new ByteVector(); 
    589620      try { 
    590         GZIPInputStream decompressor = 
    591           new GZIPInputStream(new ByteArrayInputStream(data)); 
    592         int r = decompressor.read(buf, 0, buf.length); 
    593         while (r > 0) { 
    594           v.add(buf, 0, r); 
    595           r = decompressor.read(buf, 0, buf.length); 
    596         } 
     621        GZIPInputStream r = new GZIPInputStream(new ByteArrayInputStream(data)); 
     622        int n = r.read(buf, 0, buf.length); 
     623        while (n > 0) { 
     624          v.add(buf, 0, n); 
     625          n = r.read(buf, 0, buf.length); 
     626        } 
     627        r.close(); 
    597628        data = v.toByteArray(); 
     629        Location.mapFile("data.gz", null); 
    598630      } 
    599631      catch (IOException dfe) { 
     
    603635    else gzip = false; 
    604636 
    605     status("Populating metadata"); 
    606  
    607     // populate Pixels element 
    608  
    609     String fmt = rFormat; 
    610  
    611637    if (bitsPerPixel < 32) core[0].littleEndian = !isLittleEndian(); 
    612638 
    613     if (fmt.equals("real") && bitsPerPixel == 32) { 
    614       core[0].pixelType = FormatTools.FLOAT; 
    615     } 
    616     else if (fmt.equals("real") && bitsPerPixel == 64) { 
    617       core[0].pixelType = FormatTools.DOUBLE; 
    618     } 
    619     else if (fmt.equals("integer")) { 
    620       while (bitsPerPixel % 8 != 0) bitsPerPixel++; 
    621       if (bitsPerPixel == 24 || bitsPerPixel == 48) bitsPerPixel /= 3; 
    622  
     639    if (rFormat.equals("real")) { 
     640      if (bitsPerPixel == 32) core[0].pixelType = FormatTools.FLOAT; 
     641      else if (bitsPerPixel == 64) core[0].pixelType = FormatTools.DOUBLE; 
     642    } 
     643    else if (rFormat.equals("integer")) { 
    623644      switch (bitsPerPixel) { 
    624645        case 8: 
     
    634655    } 
    635656    else { 
    636       throw new RuntimeException("Unknown pixel format: " + fmt); 
    637     } 
     657      throw new RuntimeException("Unknown pixel format: " + rFormat); 
     658    } 
     659 
     660    status("Populating OME metadata"); 
    638661 
    639662    MetadataStore store = 
     
    645668 
    646669    store.setImageName(imageName, 0); 
    647     if (date != null) { 
    648       store.setImageCreationDate(date, 0); 
    649     } 
     670 
     671    if (date != null) store.setImageCreationDate(date, 0); 
    650672    else MetadataTools.setDefaultCreationDate(store, id, 0); 
    651673 
     
    658680    // populate Dimensions data 
    659681 
    660     String pixelSizes = scale; 
    661     String o = layoutOrder; 
    662682    if (pixelSizes != null) { 
    663       StringTokenizer pixelSizeTokens = new StringTokenizer(pixelSizes); 
    664       StringTokenizer axisTokens = new StringTokenizer(o); 
    665  
    666       Float pixX = null, pixY = null, pixZ = null, pixT = null; 
    667       Integer pixC = null; 
    668  
    669       while (pixelSizeTokens.hasMoreTokens()) { 
    670         String axis = axisTokens.nextToken().trim().toLowerCase(); 
    671         String size = pixelSizeTokens.nextToken().trim(); 
    672         if (axis.equals("x")) pixX = new Float(size); 
    673         else if (axis.equals("y")) pixY = new Float(size); 
    674         else if (axis.equals("z")) pixZ = new Float(size); 
    675         else if (axis.equals("t")) pixT = new Float(size); 
    676         else if (axis.equals("ch")) { 
    677           pixC = new Integer(new Float(size).intValue()); 
    678         } 
    679       } 
    680       store.setDimensionsPhysicalSizeX(pixX, 0, 0); 
    681       store.setDimensionsPhysicalSizeY(pixY, 0, 0); 
    682       store.setDimensionsPhysicalSizeZ(pixZ, 0, 0); 
    683       store.setDimensionsTimeIncrement(pixT, 0, 0); 
    684       if (pixC != null && pixC.intValue() > 0) { 
    685         store.setDimensionsWaveIncrement(pixC, 0, 0); 
     683      for (int i=0; i<pixelSizes.length; i++) { 
     684        if (axes[i].equals("x")) { 
     685          store.setDimensionsPhysicalSizeX(pixelSizes[i], 0, 0); 
     686        } 
     687        else if (axes[i].equals("y")) { 
     688          store.setDimensionsPhysicalSizeY(pixelSizes[i], 0, 0); 
     689        } 
     690        else if (axes[i].equals("z")) { 
     691          store.setDimensionsPhysicalSizeZ(pixelSizes[i], 0, 0); 
     692        } 
     693        else if (axes[i].equals("t")) { 
     694          store.setDimensionsTimeIncrement(pixelSizes[i], 0, 0); 
     695        } 
     696        else if (axes[i].equals("ch")) { 
     697          int c = pixelSizes[i].intValue(); 
     698          if (c > 0) store.setDimensionsWaveIncrement(new Integer(c), 0, 0); 
     699        } 
    686700      } 
    687701    } 
    688702    else if (sizes != null) { 
    689       for (int i=0; i<sizes.length; i++) { 
    690         float size = Float.parseFloat(sizes[i].trim()); 
    691         if (i == 0) { 
    692           size /= getSizeX(); 
    693           store.setDimensionsPhysicalSizeX(new Float(size), 0, 0); 
    694         } 
    695         else if (i == 1) { 
    696           size /= getSizeY(); 
    697           store.setDimensionsPhysicalSizeY(new Float(size), 0, 0); 
    698         } 
     703      if (sizes.length > 0) { 
     704        store.setDimensionsPhysicalSizeX(new Float(sizes[0]), 0, 0); 
     705      } 
     706      if (sizes.length > 1) { 
     707        sizes[1] /= getSizeY(); 
     708        store.setDimensionsPhysicalSizeY(new Float(sizes[1]), 0, 0); 
    699709      } 
    700710    } 
     
    702712    // populate LogicalChannel data 
    703713 
    704     if (em != null) { 
    705       String[] emTokens = em.split(" "); 
    706       int channel = 0; 
    707       for (int i=0; i<emTokens.length; i++) { 
    708         if (emTokens[i].trim().equals("")) continue; 
    709         store.setLogicalChannelEmWave( 
    710           new Integer((int) Float.parseFloat(emTokens[i])), 0, channel++); 
    711       } 
    712     } 
    713     if (ex != null) { 
    714       String[] exTokens = ex.split(" "); 
    715       int channel = 0; 
    716       for (int i=0; i<exTokens.length; i++) { 
    717         if (exTokens[i].trim().equals("")) continue; 
    718         store.setLogicalChannelExWave( 
    719           new Integer((int) Float.parseFloat(exTokens[i])), 0, channel++); 
    720       } 
    721     } 
    722  
    723     for (int i=0; i<getSizeC(); i++) { 
     714    for (int i=0; i<getEffectiveSizeC(); i++) { 
    724715      Integer channel = new Integer(i); 
    725       if (channelNames != null) { 
    726         String name = (String) channelNames.get(channel); 
    727         store.setLogicalChannelName(name, 0, i); 
    728       } 
    729       if (pinholes != null) { 
    730         String pinhole = (String) pinholes.get(channel); 
    731         store.setLogicalChannelPinholeSize(new Float(pinhole), 0, i); 
     716      if (channelNames.containsKey(channel)) { 
     717        store.setLogicalChannelName(channelNames.get(channel), 0, i); 
     718      } 
     719      if (pinholes.containsKey(channel)) { 
     720        store.setLogicalChannelPinholeSize(pinholes.get(channel), 0, i); 
     721      } 
     722      if (emWaves != null && i < emWaves.length) { 
     723        store.setLogicalChannelEmWave(emWaves[i], 0, i); 
     724      } 
     725      if (exWaves != null && i < exWaves.length) { 
     726        store.setLogicalChannelExWave(exWaves[i], 0, i); 
    732727      } 
    733728    } 
     
    735730    // populate Laser data 
    736731 
    737     if (wavelengths != null) { 
    738       for (int i=1; i<=wavelengths.size(); i++) { 
    739         String wavelength = (String) wavelengths.get(new Integer(i)); 
    740         if (wavelength != null) { 
    741           store.setLaserWavelength(new Integer(wavelength), 0, i - 1); 
    742         } 
    743       } 
     732    Integer[] lasers = wavelengths.keySet().toArray(new Integer[0]); 
     733    for (int i=0; i<lasers.length; i++) { 
     734      store.setLaserWavelength(wavelengths.get(lasers[i]), 0, 
     735        lasers[i].intValue()); 
    744736    } 
    745737 
     
    749741    if (immersion != null) store.setObjectiveImmersion(immersion, 0, 0); 
    750742    else store.setObjectiveImmersion("Unknown", 0, 0); 
    751     if (lensNA != null) store.setObjectiveLensNA(new Float(lensNA), 0, 0); 
     743    if (lensNA != null) store.setObjectiveLensNA(lensNA, 0, 0); 
    752744    if (workingDistance != null) { 
    753       store.setObjectiveWorkingDistance(new Float(workingDistance), 0, 0); 
     745      store.setObjectiveWorkingDistance(workingDistance, 0, 0); 
    754746    } 
    755747    if (magnification != null) { 
    756       store.setObjectiveCalibratedMagnification(new Float(magnification), 0, 0); 
     748      store.setObjectiveCalibratedMagnification(magnification, 0, 0); 
    757749    } 
    758750    store.setObjectiveCorrection("Unknown", 0, 0); 
     
    762754    store.setObjectiveSettingsObjective("Objective:0", 0); 
    763755 
    764     if (gains != null) { 
    765       for (int i=0; i<gains.size(); i++) { 
    766         if (gains.containsKey(new Integer(i + 1))) { 
    767           store.setDetectorSettingsGain( 
    768             new Float((String) gains.get(new Integer(i + 1))), 0, i); 
    769           store.setDetectorType("Unknown", 0, i); 
    770           store.setDetectorID("Detector:" + i, 0, i); 
    771           store.setDetectorSettingsDetector("Detector:0", 0, i); 
    772         } 
    773       } 
     756    Integer[] gainKeys = gains.keySet().toArray(new Integer[0]); 
     757    for (int i=0; i<gainKeys.length; i++) { 
     758      int index = gainKeys[i].intValue(); 
     759      store.setDetectorSettingsGain(gains.get(gainKeys[i]), 0, index); 
     760      store.setDetectorType("Unknown", 0, index); 
     761      store.setDetectorID("Detector:" + index, 0, index); 
     762      store.setDetectorSettingsDetector("Detector:0", 0, index); 
    774763    } 
    775764 
    776765    // populate Experimenter data 
    777766 
    778     store.setExperimenterLastName(lastName, 0); 
     767    if (lastName != null) store.setExperimenterLastName(lastName, 0); 
    779768 
    780769    // populate StagePosition data 
     
    783772      for (int i=0; i<getImageCount(); i++) { 
    784773        if (stagePos.length > 0) { 
    785           store.setStagePositionPositionX(new Float(stagePos[0]), 0, 0, i); 
     774          store.setStagePositionPositionX(stagePos[0], 0, 0, i); 
    786775        } 
    787776        if (stagePos.length > 1) { 
    788           store.setStagePositionPositionY(new Float(stagePos[1]), 0, 0, i); 
     777          store.setStagePositionPositionY(stagePos[1], 0, 0, i); 
    789778        } 
    790779        if (stagePos.length > 2) { 
    791           store.setStagePositionPositionZ(new Float(stagePos[2]), 0, 0, i); 
     780          store.setStagePositionPositionZ(stagePos[2], 0, 0, i); 
    792781        } 
    793782      } 
     
    795784  } 
    796785 
    797   // -- Helper functions -- 
    798  
    799   private boolean matches(String pattern, String text) { 
    800     if (text == null || pattern == null) return false; 
    801     if (text.equalsIgnoreCase(pattern)) return true; 
    802     if (!pattern.endsWith("*")) return false; 
    803  
    804     return text.startsWith(pattern.substring(0, pattern.length() - 1)); 
    805   } 
    806  
    807786} 
  • trunk/components/bio-formats/src/loci/formats/in/IPWReader.java

    r5093 r5119  
    256256    core[0].sizeX = (int) TiffTools.getImageWidth(h); 
    257257    core[0].sizeY = (int) TiffTools.getImageLength(h); 
    258     core[0].dimensionOrder = isRGB() ? "XYCTZ" : "XYTCZ"; 
     258    core[0].dimensionOrder = isRGB() ? "XYCZT" : "XYZCT"; 
    259259 
    260260    if (getSizeZ() == 0) core[0].sizeZ = 1; 
Note: See TracChangeset for help on using the changeset viewer.