Changeset 7491


Ignore:
Timestamp:
01/10/11 10:15:17 (9 years ago)
Author:
melissa
Message:

Merged file grouping and channel name parsing fixes from trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/4.1/components/bio-formats/src/loci/formats/in/MetamorphReader.java

    r7287 r7491  
    2626import java.io.File; 
    2727import java.io.IOException; 
    28 import java.text.DecimalFormat; 
    2928import java.util.Arrays; 
    3029import java.util.Calendar; 
     
    3231import java.util.Vector; 
    3332 
     33import loci.common.DataTools; 
    3434import loci.common.DateTools; 
    3535import loci.common.Location; 
    3636import loci.common.RandomAccessInputStream; 
    37 import loci.common.XMLTools; 
     37import loci.common.xml.XMLTools; 
    3838import loci.formats.CoreMetadata; 
    3939import loci.formats.FormatException; 
     
    5353 * 
    5454 * <dl><dt><b>Source code:</b></dt> 
    55  * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/components/bio-formats/src/loci/formats/in/MetamorphReader.java">Trac</a>, 
    56  * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/components/bio-formats/src/loci/formats/in/MetamorphReader.java">SVN</a></dd></dl> 
     55 * <dd><a href="http://dev.loci.wisc.edu/trac/java/browser/trunk/components/bio-formats/src/loci/formats/in/MetamorphReader.java">Trac</a>, 
     56 * <a href="http://dev.loci.wisc.edu/svn/java/trunk/components/bio-formats/src/loci/formats/in/MetamorphReader.java">SVN</a></dd></dl> 
    5757 * 
    5858 * @author Eric Kjellman egkjellman at wisc.edu 
    59  * @author Melissa Linkert linkert at wisc.edu 
     59 * @author Melissa Linkert melissa at glencoesoftware.com 
    6060 * @author Curtis Rueden ctrueden at wisc.edu 
    6161 * @author Sebastien Huart Sebastien dot Huart at curie.fr 
     
    9999  private long[] internalStamps; 
    100100  private double[] zDistances, stageX, stageY; 
     101  private double zStart; 
     102  private Float sizeX = null, sizeY = null; 
     103  private double tempZ; 
     104  private boolean validZ; 
    101105 
    102106  private int mmPlanes; //number of metamorph planes 
    103107 
    104   private MetamorphReader stkReader; 
     108  private MetamorphReader[][] stkReaders; 
    105109 
    106110  /** List of STK files in the dataset. */ 
     
    151155    String[] files = l.getParentFile().list(); 
    152156 
    153     for (int i=0; i<files.length; i++) { 
    154       if (checkSuffix(files[i], ND_SUFFIX) && 
    155        id.startsWith(files[i].substring(0, files[i].lastIndexOf(".")))) 
     157    for (String file : files) { 
     158      if (checkSuffix(file, ND_SUFFIX) && 
     159       l.getName().startsWith(file.substring(0, file.lastIndexOf(".")))) 
    156160      { 
    157161        return FormatTools.MUST_GROUP; 
     
    170174    Vector<String> v = new Vector<String>(); 
    171175    if (ndFilename != null) v.add(ndFilename); 
    172     if (!noPixels) v.addAll(Arrays.asList(stks[getSeries()])); 
     176    if (!noPixels) { 
     177      for (String stk : stks[getSeries()]) { 
     178        if (stk != null && new Location(stk).exists()) { 
     179          v.add(stk); 
     180        } 
     181      } 
     182    } 
    173183    return v.toArray(new String[v.size()]); 
    174184  } 
     
    193203    // the original file is a .nd file, so we need to construct a new reader 
    194204    // for the constituent STK files 
    195     if (stkReader == null) { 
    196       stkReader = new MetamorphReader(); 
    197       stkReader.setCanLookForND(false); 
    198     } 
    199     stkReader.setId(file); 
     205    stkReaders[series][ndx].setId(file); 
    200206    int plane = stks[series].length == 1 ? no : coords[0]; 
    201     stkReader.openBytes(plane, buf, x, y, w, h); 
     207    stkReaders[series][ndx].openBytes(plane, buf, x, y, w, h); 
    202208    return buf; 
    203209  } 
     
    206212  public void close(boolean fileOnly) throws IOException { 
    207213    super.close(fileOnly); 
    208     if (stkReader != null) stkReader.close(fileOnly); 
     214    if (stkReaders != null) { 
     215      for (MetamorphReader[] s : stkReaders) { 
     216        if (s != null) { 
     217          for (MetamorphReader reader : s) { 
     218            if (reader != null) reader.close(fileOnly); 
     219          } 
     220        } 
     221      } 
     222    } 
    209223    if (!fileOnly) { 
    210       stkReader = null; 
    211224      imageName = imageCreationDate = null; 
    212225      emWavelength = null; 
     
    221234      internalStamps = null; 
    222235      zDistances = stageX = stageY = null; 
    223       canLookForND = true; 
    224236      firstSeriesChannels = null; 
     237      sizeX = sizeY = null; 
     238      tempZ = 0d; 
     239      validZ = false; 
     240      stkReaders = null; 
    225241    } 
    226242  } 
     
    237253        stkFile = stkFile.substring(stkFile.lastIndexOf(File.separator) + 1); 
    238254      } 
    239       String parentPath = id.substring(0, id.lastIndexOf(File.separator) + 1); 
    240       Location parent = new Location(parentPath).getAbsoluteFile(); 
     255      Location parent = new Location(id).getAbsoluteFile().getParentFile(); 
    241256      status("Looking for STK file in " + parent.getAbsolutePath()); 
    242       String[] dirList = parent.list(); 
    243       for (int i=0; i<dirList.length; i++) { 
    244         if (dirList[i].indexOf(stkFile) != -1 && 
    245           checkSuffix(dirList[i], STK_SUFFIX)) 
     257      String[] dirList = parent.list(true); 
     258      for (String f : dirList) { 
     259        int underscore = f.indexOf("_"); 
     260        if (underscore < 0) underscore = f.indexOf("."); 
     261        if (underscore < 0) underscore = f.length(); 
     262        String prefix = f.substring(0, underscore); 
     263 
     264        if ((f.equals(stkFile) || stkFile.startsWith(prefix)) && 
     265          checkSuffix(f, STK_SUFFIX)) 
    246266        { 
    247           stkFile = new Location( 
    248             parent.getAbsolutePath(), dirList[i]).getAbsolutePath(); 
     267          stkFile = new Location(parent.getAbsolutePath(), f).getAbsolutePath(); 
    249268          break; 
    250269        } 
     
    266285      // an STK file was passed to initFile 
    267286      // let's check the parent directory for an .nd file 
    268       Location parent = new Location(id).getAbsoluteFile().getParentFile(); 
    269       String[] list = parent.list(); 
    270       for (int i=0; i<list.length; i++) { 
    271         if (checkSuffix(list[i], ND_SUFFIX)) { 
    272           String prefix = list[i].substring(0, list[i].lastIndexOf(".")); 
    273           if (currentId.startsWith(prefix)) { 
    274             ndfile = new Location(parent, list[i]).getAbsoluteFile(); 
     287      Location stk = new Location(id).getAbsoluteFile(); 
     288      String stkName = stk.getName(); 
     289      String stkPrefix = stkName; 
     290      if (stkPrefix.indexOf("_") >= 0) { 
     291        stkPrefix = stkPrefix.substring(0, stkPrefix.indexOf("_") + 1); 
     292      } 
     293      Location parent = stk.getParentFile(); 
     294      String[] list = parent.list(true); 
     295      for (String f : list) { 
     296        if (checkSuffix(f, ND_SUFFIX)) { 
     297          String prefix = f.substring(0, f.lastIndexOf(".")); 
     298          if (stkName.startsWith(prefix) || prefix.equals(stkPrefix)) { 
     299            ndfile = new Location(parent, f).getAbsoluteFile(); 
    275300            break; 
    276301          } 
     
    285310    { 
    286311      // parse key/value pairs from .nd file 
    287  
    288       ndFilename = ndfile.getAbsolutePath(); 
    289  
    290       RandomAccessInputStream ndStream = 
    291         new RandomAccessInputStream(ndFilename); 
    292       String line = ndStream.readLine().trim(); 
    293312 
    294313      int zc = getSizeZ(), cc = getSizeC(), tc = getSizeT(); 
     
    300319      boolean useWaveNames = true; 
    301320 
    302       while (!line.equals("\"EndFile\"")) { 
     321      ndFilename = ndfile.getAbsolutePath(); 
     322      String[] lines = DataTools.readFile(ndFilename).split("\n"); 
     323 
     324      for (String line : lines) { 
    303325        int comma = line.indexOf(","); 
    304         if (comma <= 0) { 
    305           line = ndStream.readLine().trim(); 
    306           continue; 
    307         } 
     326        if (comma <= 0) continue; 
    308327        String key = line.substring(1, comma - 1).trim(); 
    309328        String value = line.substring(comma + 1).trim(); 
     
    317336        } 
    318337        else if (key.startsWith("WaveName")) { 
    319           waveNames.add(value); 
     338          waveNames.add(value.substring(1, value.length() - 1)); 
    320339        } 
    321340        else if (key.startsWith("Stage")) { 
     
    334353          useWaveNames = Boolean.parseBoolean(value); 
    335354        } 
    336  
    337         line = ndStream.readLine().trim(); 
    338355      } 
    339356 
     
    392409      prefix = prefix.substring(prefix.lastIndexOf(File.separator) + 1, 
    393410        prefix.lastIndexOf(".")); 
    394  
    395       for (int i=0; i<cc; i++) { 
    396         if (i < waveNames.size() && waveNames.get(i) != null) { 
    397           String name = waveNames.get(i); 
    398           waveNames.setElementAt(name.substring(1, name.length() - 1), i); 
    399         } 
    400       } 
    401411 
    402412      // build list of STK files 
     
    440450        for (int f=0; f<stks[s].length; f++) { 
    441451          Location l = new Location(ndfile.getParent(), stks[s][f]); 
    442           if (!l.exists()) { 
    443             // '%' can be converted to '-' 
    444             if (stks[s][f].indexOf("%") != -1) { 
    445               stks[s][f] = stks[s][f].replaceAll("%", "-"); 
    446               l = new Location(ndfile.getParent(), stks[s][f]); 
    447               if (!l.exists()) { 
    448                 // try replacing extension 
    449                 stks[s][f] = stks[s][f].substring(0, 
    450                   stks[s][f].lastIndexOf(".")) + ".TIF"; 
    451                 l = new Location(ndfile.getParent(), stks[s][f]); 
    452                 if (!l.exists()) { 
    453                   stks[s][f] = stks[s][f].substring(0, 
    454                     stks[s][f].lastIndexOf(".")) + ".tif"; 
    455                   l = new Location(ndfile.getParent(), stks[s][f]); 
    456                   if (!l.exists()) { 
    457                     stks[s][f] = null; 
    458                   } 
    459                 } 
    460               } 
    461             } 
    462  
    463             if (!l.exists()) { 
    464               // try replacing extension 
    465               stks[s][f] = stks[s][f].substring(0, 
    466                 stks[s][f].lastIndexOf(".")) + ".TIF"; 
    467               l = new Location(ndfile.getParent(), stks[s][f]); 
    468               if (!l.exists()) { 
    469                 stks[s][f] = stks[s][f].substring(0, 
    470                   stks[s][f].lastIndexOf(".")) + ".tif"; 
    471                 l = new Location(ndfile.getParent(), stks[s][f]); 
    472                 if (!l.exists()) { 
    473                   stks[s][f] = null; 
    474                 } 
    475               } 
    476             } 
    477           } 
    478           if (stks != null && l.exists()) stks[s][f] = l.getAbsolutePath(); 
    479           else if (stks == null) break; 
    480         } 
    481         if (stks == null) break; 
     452          stks[s][f] = getRealSTKFile(l); 
     453        } 
    482454      } 
    483455 
     
    541513    } 
    542514 
     515    if (stks == null) { 
     516      stkReaders = new MetamorphReader[1][1]; 
     517      stkReaders[0][0] = new MetamorphReader(); 
     518      stkReaders[0][0].setCanLookForND(false); 
     519    } 
     520    else { 
     521      stkReaders = new MetamorphReader[stks.length][]; 
     522      for (int i=0; i<stks.length; i++) { 
     523        stkReaders[i] = new MetamorphReader[stks[i].length]; 
     524        for (int j=0; j<stkReaders[i].length; j++) { 
     525          stkReaders[i][j] = new MetamorphReader(); 
     526          stkReaders[i][j].setCanLookForND(false); 
     527        } 
     528      } 
     529    } 
     530 
    543531    Vector<String> timestamps = null; 
    544532    MetamorphHandler handler = null; 
     
    557545      store.setImageInstrumentRef(instrumentID, i); 
    558546 
    559       String comment = null; 
    560  
    561       if (stks != null && stks[i][0] != null) { 
    562         RandomAccessInputStream stream = 
    563           new RandomAccessInputStream(stks[i][0]); 
    564         TiffParser tp = new TiffParser(stream); 
    565         IFD ifd = tp.getFirstIFD(); 
    566         stream.close(); 
    567         comment = ifd.getComment(); 
    568       } 
    569       else { 
    570         comment = ifds.get(0).getComment(); 
    571       } 
     547      String comment = getFirstComment(i); 
    572548      if (comment != null && comment.startsWith("<MetaData>")) { 
    573549        XMLTools.parseXML(comment, handler); 
     
    580556      else if (i > 0) MetadataTools.setDefaultCreationDate(store, id, i); 
    581557 
    582       String name = ""; 
    583       if (stageNames != null && stageNames.size() > 0) { 
    584         int stagePosition = i / (getSeriesCount() / stageNames.size()); 
    585         name += "Stage " + stageNames.get(stagePosition) + "; "; 
    586       } 
    587  
    588       if (firstSeriesChannels != null) { 
    589         for (int c=0; c<firstSeriesChannels.length; c++) { 
    590           if (firstSeriesChannels[c] == ((i % 2) == 0) && c < waveNames.size()) 
    591           { 
    592             name += waveNames.get(c) + "/"; 
    593           } 
    594         } 
    595         if (name.length() > 0) { 
    596           name = name.substring(0, name.length() - 1); 
    597         } 
    598       } 
    599  
    600       store.setImageName(name, i); 
     558      store.setImageName(makeImageName(i), i); 
     559 
    601560      store.setImageDescription("", i); 
    602561 
    603       store.setImagingEnvironmentTemperature( 
    604         new Float(handler.getTemperature()), i); 
    605       store.setDimensionsPhysicalSizeX( 
    606         new Float(handler.getPixelSizeX()), i, 0); 
    607       store.setDimensionsPhysicalSizeY( 
    608         new Float(handler.getPixelSizeY()), i, 0); 
     562      store.setImagingEnvironmentTemperature(handler.getTemperature(), i); 
     563 
     564      if (sizeX == null) sizeX = handler.getPixelSizeX(); 
     565      if (sizeY == null) sizeY = handler.getPixelSizeY(); 
     566 
     567      store.setDimensionsPhysicalSizeX(sizeX, i, 0); 
     568      store.setDimensionsPhysicalSizeY(sizeY, i, 0); 
    609569      if (zDistances != null) { 
    610570        stepSize = zDistances[0]; 
     
    631591          store.setLogicalChannelName(waveNames.get(waveIndex), i, c); 
    632592        } 
    633         store.setDetectorSettingsBinning(binning, i, c); 
    634         if (handler.getBinning() != null) { 
    635           store.setDetectorSettingsBinning(handler.getBinning(), i, c); 
     593        if (handler.getBinning() != null) binning = handler.getBinning(); 
     594        if (binning != null) { 
     595          store.setDetectorSettingsBinning(binning, i, c); 
    636596        } 
    637597        if (handler.getReadOutRate() != 0) { 
    638           store.setDetectorSettingsReadOutRate( 
    639             new Float(handler.getReadOutRate()), i, c); 
     598          store.setDetectorSettingsReadOutRate(handler.getReadOutRate(), i, c); 
    640599        } 
    641600        store.setDetectorSettingsDetector(detectorID, i, c); 
     
    644603          (int) wave[waveIndex] >= 1) 
    645604        { 
    646           store.setLightSourceSettingsWavelength( 
    647             new Integer((int) wave[waveIndex]), i, c); 
     605          store.setLightSourceSettingsWavelength((int) wave[waveIndex], i, c); 
    648606 
    649607          // link LightSource to Image 
     
    680638      int lastFile = -1; 
    681639      IFD lastIFD = null; 
     640      long[] lastOffsets = null; 
     641 
     642      double distance = zStart; 
    682643 
    683644      for (int p=0; p<getImageCount(); p++) { 
     
    685646        Float deltaT = new Float(0); 
    686647        Float exposureTime = new Float(0); 
    687  
    688         if (coords[2] > 0 && stks != null && lastFile >= 0 && 
    689           stks[i][lastFile] != null) 
    690         { 
    691           int fileIndex = getIndex(0, 0, coords[2]) / getSizeZ(); 
    692           if (fileIndex != lastFile) { 
    693             lastFile = fileIndex; 
    694             RandomAccessInputStream stream = 
    695               new RandomAccessInputStream(stks[i][lastFile]); 
     648        Float xmlZPosition = null; 
     649 
     650        int fileIndex = getIndex(0, 0, coords[2]) / getSizeZ(); 
     651        if (fileIndex >= 0) { 
     652          String file = stks == null ? currentId : stks[i][fileIndex]; 
     653          if (file != null) { 
     654            RandomAccessInputStream stream = new RandomAccessInputStream(file); 
    696655            TiffParser tp = new TiffParser(stream); 
    697             lastIFD = tp.getFirstIFD(); 
     656            tp.checkHeader(); 
     657            if (fileIndex != lastFile) { 
     658              lastFile = fileIndex; 
     659              lastOffsets = tp.getIFDOffsets(); 
     660            } 
     661 
     662            int index = p % lastOffsets.length; 
     663            lastIFD = tp.getIFD(index, lastOffsets[index]); 
    698664            stream.close(); 
     665            comment = lastIFD.getComment(); 
     666            if (comment != null) comment = comment.trim(); 
     667            handler = new MetamorphHandler(getSeriesMetadata()); 
     668            if (comment != null && comment.startsWith("<MetaData>")) { 
     669              XMLTools.parseXML(comment, handler); 
     670            } 
     671            timestamps = handler.getTimestamps(); 
     672            exposureTimes = handler.getExposures(); 
     673            Vector<Float> zPositions = handler.getZPositions(); 
     674            if (zPositions != null && zPositions.size() > 0) { 
     675              xmlZPosition = zPositions.get(0); 
     676            } 
    699677          } 
    700           comment = lastIFD.getComment(); 
    701           handler = new MetamorphHandler(getSeriesMetadata()); 
    702           if (comment != null && comment.startsWith("<MetaData>")) { 
    703             XMLTools.parseXML(comment, handler); 
    704           } 
    705           timestamps = handler.getTimestamps(); 
    706           exposureTimes = handler.getExposures(); 
    707678        } 
    708679 
     
    734705          store.setStagePositionPositionY(new Float(stageY[p]), i, 0, p); 
    735706        } 
     707        if (zDistances != null && p < zDistances.length) { 
     708          if (p > 0) { 
     709            if (zDistances[p] != 0d) distance += zDistances[p]; 
     710            else distance += zDistances[0]; 
     711          } 
     712          store.setStagePositionPositionZ(new Float(distance), i, 0, p); 
     713        } 
     714        else if (xmlZPosition != null) { 
     715          store.setStagePositionPositionZ(new Float(xmlZPosition), i, 0, p); 
     716        } 
    736717      } 
    737718    } 
     
    741722    store.setDetectorZoom(new Float(zoom), 0, 0); 
    742723    if (handler != null && handler.getZoom() != 0) { 
    743       store.setDetectorZoom(new Float(handler.getZoom()), 0, 0); 
     724      store.setDetectorZoom(handler.getZoom(), 0, 0); 
    744725    } 
    745726    store.setDetectorType("Unknown", 0, 0); 
     
    756737    int rgbChannels = getSizeC(); 
    757738 
     739    // Now that the base TIFF standard metadata has been parsed, we need to 
     740    // parse out the STK metadata from the UIC4TAG. 
     741 
     742    TiffIFDEntry uic1tagEntry = null; 
     743    TiffIFDEntry uic2tagEntry = null; 
     744    TiffIFDEntry uic4tagEntry = null; 
     745 
    758746    try { 
    759       // Now that the base TIFF standard metadata has been parsed, we need to 
    760       // parse out the STK metadata from the UIC4TAG. 
    761       TiffIFDEntry uic1tagEntry = tiffParser.getFirstIFDEntry(UIC1TAG); 
    762       TiffIFDEntry uic2tagEntry = tiffParser.getFirstIFDEntry(UIC2TAG); 
    763       TiffIFDEntry uic4tagEntry = tiffParser.getFirstIFDEntry(UIC4TAG); 
    764       mmPlanes = uic4tagEntry.getValueCount(); 
    765       parseUIC2Tags(uic2tagEntry.getValueOffset()); 
    766       parseUIC4Tags(uic4tagEntry.getValueOffset()); 
    767       parseUIC1Tags(uic1tagEntry.getValueOffset(), 
    768         uic1tagEntry.getValueCount()); 
     747      uic1tagEntry = tiffParser.getFirstIFDEntry(UIC1TAG); 
     748      uic2tagEntry = tiffParser.getFirstIFDEntry(UIC2TAG); 
     749      uic4tagEntry = tiffParser.getFirstIFDEntry(UIC4TAG); 
     750    } 
     751    catch (IllegalArgumentException exc) { 
     752      traceDebug(exc); 
     753    } 
     754 
     755    try { 
     756      if (uic4tagEntry != null) { 
     757        mmPlanes = uic4tagEntry.getValueCount(); 
     758      } 
     759      if (uic2tagEntry != null) { 
     760        parseUIC2Tags(uic2tagEntry.getValueOffset()); 
     761      } 
     762      if (uic4tagEntry != null) { 
     763        parseUIC4Tags(uic4tagEntry.getValueOffset()); 
     764      } 
     765      if (uic1tagEntry != null) { 
     766        parseUIC1Tags(uic1tagEntry.getValueOffset(), 
     767          uic1tagEntry.getValueCount()); 
     768      } 
    769769      in.seek(uic4tagEntry.getValueOffset()); 
    770770    } 
    771     catch (IllegalArgumentException exc) { traceDebug(exc); } // unknown tag 
    772     catch (NullPointerException exc) { traceDebug(exc); } 
    773     catch (IOException exc) { traceDebug(exc); } 
     771    catch (NullPointerException exc) { 
     772      traceDebug(exc); 
     773    } 
     774    catch (IOException exc) { 
     775      traceDebug(exc); 
     776    } 
    774777 
    775778    try { 
     
    778781      IFD firstIFD = ifds.get(0); 
    779782      long[] uic2 = firstIFD.getIFDLongArray(UIC2TAG, true); 
     783      if (uic2 == null) { 
     784        throw new FormatException("Invalid Metamorph file. Tag " + UIC2TAG + 
     785          " not found."); 
     786      } 
    780787      core[0].imageCount = uic2.length; 
    781788 
     
    835842        } 
    836843 
    837         temp.put(new Integer(IFD.STRIP_OFFSETS), newOffsets); 
     844        temp.putIFDValue(IFD.STRIP_OFFSETS, newOffsets); 
    838845 
    839846        long[] newByteCounts = new long[stripsPerImage]; 
     
    845852          Arrays.fill(newByteCounts, stripByteCounts[0]); 
    846853        } 
    847         temp.put(new Integer(IFD.STRIP_BYTE_COUNTS), newByteCounts); 
     854        temp.putIFDValue(IFD.STRIP_BYTE_COUNTS, newByteCounts); 
    848855 
    849856        tempIFDs.add(temp); 
     
    851858      ifds = tempIFDs; 
    852859    } 
    853     catch (IllegalArgumentException exc) { traceDebug(exc); } // unknown tag 
    854     catch (NullPointerException exc) { traceDebug(exc); } 
    855     catch (FormatException exc) { traceDebug(exc); } 
     860    catch (IllegalArgumentException exc) { 
     861      traceDebug(exc); 
     862    } 
     863    catch (NullPointerException exc) { 
     864      traceDebug(exc); 
     865    } 
     866    catch (FormatException exc) { 
     867      traceDebug(exc); 
     868    } 
    856869 
    857870    // parse (mangle) TIFF comment 
     
    896909          addSeriesMeta(key, value); 
    897910          if (key.equals("Exposure")) { 
     911            if (value.indexOf("=") != -1) { 
     912              value = value.substring(value.indexOf("=") + 1).trim(); 
     913            } 
    898914            if (value.indexOf(" ") != -1) { 
    899915              value = value.substring(0, value.indexOf(" ")); 
    900916            } 
    901             float exposure = Float.parseFloat(value); 
    902             exposureTime = new Float(exposure / 1000); 
     917            try { 
     918              float exposure = Float.parseFloat(value); 
     919              exposureTime = new Float(exposure / 1000); 
     920            } 
     921            catch (NumberFormatException e) { } 
    903922          } 
    904923        } 
     
    942961 
    943962  // -- Helper methods -- 
     963 
     964  /** 
     965   * Check that the given STK file exists.  If it does, then return the 
     966   * absolute path.  If it does not, then apply various formatting rules until 
     967   * an existing file is found. 
     968   * 
     969   * @return the absolute path of an STK file, or null if no STK file is found. 
     970   */ 
     971  private String getRealSTKFile(Location l) { 
     972    if (l.exists()) return l.getAbsolutePath(); 
     973    String name = l.getName(); 
     974    String parent = l.getParent(); 
     975 
     976    if (name.indexOf("_") > 0) { 
     977      String prefix = name.substring(0, name.indexOf("_")); 
     978      String suffix = name.substring(name.indexOf("_")); 
     979 
     980      String basePrefix = new Location(currentId).getName(); 
     981      int end = basePrefix.indexOf("_"); 
     982      if (end < 0) end = basePrefix.indexOf("."); 
     983      basePrefix = basePrefix.substring(0, end); 
     984 
     985      if (!basePrefix.equals(prefix)) { 
     986        name = basePrefix + suffix; 
     987        Location p = new Location(parent, name); 
     988        if (p.exists()) return p.getAbsolutePath(); 
     989      } 
     990    } 
     991 
     992    // '%' can be converted to '-' 
     993    if (name.indexOf("%") != -1) { 
     994      name = name.replaceAll("%", "-"); 
     995      l = new Location(parent, name); 
     996      if (!l.exists()) { 
     997        // try replacing extension 
     998        name = name.substring(0, name.lastIndexOf(".")) + ".TIF"; 
     999        l = new Location(parent, name); 
     1000        if (!l.exists()) { 
     1001          name = name.substring(0, name.lastIndexOf(".")) + ".tif"; 
     1002          l = new Location(parent, name); 
     1003          return l.exists() ? l.getAbsolutePath() : null; 
     1004        } 
     1005      } 
     1006    } 
     1007 
     1008    if (!l.exists()) { 
     1009      // try replacing extension 
     1010      name = name.substring(0, name.lastIndexOf(".")) + ".TIF"; 
     1011      l = new Location(parent, name); 
     1012      if (!l.exists()) { 
     1013        name = name.substring(0, name.lastIndexOf(".")) + ".tif"; 
     1014        l = new Location(parent, name); 
     1015        return l.exists() ? l.getAbsolutePath() : null; 
     1016      } 
     1017    } 
     1018    return l.getAbsolutePath(); 
     1019  } 
     1020 
     1021  /** 
     1022   * Returns the TIFF comment from the first IFD of the first STK file in the 
     1023   * given series. 
     1024   */ 
     1025  private String getFirstComment(int i) throws IOException { 
     1026    if (stks != null && stks[i][0] != null) { 
     1027      RandomAccessInputStream stream = new RandomAccessInputStream(stks[i][0]); 
     1028      TiffParser tp = new TiffParser(stream); 
     1029      String comment = tp.getComment(); 
     1030      stream.close(); 
     1031      return comment; 
     1032    } 
     1033    return ifds.get(0).getComment(); 
     1034  } 
     1035 
     1036  /** Create an appropriate name for the given series. */ 
     1037  private String makeImageName(int i) { 
     1038    String name = ""; 
     1039    if (stageNames != null && stageNames.size() > 0) { 
     1040      int stagePosition = i / (getSeriesCount() / stageNames.size()); 
     1041      name += "Stage " + stageNames.get(stagePosition) + "; "; 
     1042    } 
     1043 
     1044    if (firstSeriesChannels != null) { 
     1045      for (int c=0; c<firstSeriesChannels.length; c++) { 
     1046        if (firstSeriesChannels[c] == ((i % 2) == 0) && c < waveNames.size()) { 
     1047          name += waveNames.get(c) + "/"; 
     1048        } 
     1049      } 
     1050      if (name.length() > 0) { 
     1051        name = name.substring(0, name.length() - 1); 
     1052      } 
     1053    } 
     1054    return name; 
     1055  } 
    9441056 
    9451057  /** 
     
    10061118    in.seek(uic4offset); 
    10071119    if (in.getFilePointer() + 2 >= in.length()) return; 
     1120 
     1121    tempZ = 0d; 
     1122    validZ = false; 
     1123 
    10081124    short id = in.readShort(); 
    10091125    while (id != 0) { 
     
    10201136          break; 
    10211137        case 40: 
    1022           readRationals(new String[] {"absoluteZ"}); 
     1138          readRationals(new String[] {"UIC4 absoluteZ"}); 
    10231139          break; 
    10241140        case 41: 
    10251141          readAbsoluteZValid(); 
    10261142          break; 
     1143        case 46: 
     1144          in.skipBytes(mmPlanes * 8); // TODO 
     1145          break; 
     1146        default: 
     1147          in.skipBytes(4); 
    10271148      } 
    10281149      id = in.readShort(); 
    10291150    } 
    10301151    in.seek(saveLoc); 
     1152 
     1153    if (validZ) zStart = tempZ; 
    10311154  } 
    10321155 
     
    10411164      addSeriesMeta("stageX[" + pos + "]", stageX[i]); 
    10421165      addSeriesMeta("stageY[" + pos + "]", stageY[i]); 
     1166      addGlobalMeta("X position for position #" + (getSeries() + 1), stageX[i]); 
     1167      addGlobalMeta("Y position for position #" + (getSeries() + 1), stageY[i]); 
    10431168    } 
    10441169  } 
     
    10491174      pos = intFormatMax(i, mmPlanes); 
    10501175      for (int q=0; q<labels.length; q++) { 
    1051         addSeriesMeta(labels[q] + "[" + pos + "]", 
    1052           readRational(in).doubleValue()); 
     1176        double v = readRational(in).doubleValue(); 
     1177        if (labels[q].endsWith("absoluteZ") && i == 0) { 
     1178          tempZ = v; 
     1179        } 
     1180        addSeriesMeta(labels[q] + "[" + pos + "]", v); 
    10531181      } 
    10541182    } 
     
    10671195  void readAbsoluteZValid() throws IOException { 
    10681196    for (int i=0; i<mmPlanes; i++) { 
    1069       addSeriesMeta("absoluteZValid[" + intFormatMax(i, mmPlanes) + "]", 
    1070         in.readInt()); 
     1197      int valid = in.readInt(); 
     1198      addSeriesMeta("absoluteZValid[" + intFormatMax(i, mmPlanes) + "]", valid); 
     1199      if (i == 0) { 
     1200        validZ = valid == 1; 
     1201      } 
    10711202    } 
    10721203  } 
     
    10901221    String thedate, thetime; 
    10911222    long lastOffset; 
     1223 
     1224    tempZ = 0d; 
     1225    validZ = false; 
    10921226    for (int i=0; i<uic1count; i++) { 
    10931227      if (in.getFilePointer() >= in.length()) break; 
     
    11821316          value = binning; 
    11831317          break; 
     1318        case 40: 
     1319          if (valOrOffset != 0) { 
     1320            in.seek(valOrOffset); 
     1321            readRationals(new String[] {"UIC1 absoluteZ"}); 
     1322          } 
     1323          break; 
     1324        case 41: 
     1325          if (valOrOffset != 0) { 
     1326            in.seek(valOrOffset); 
     1327            readAbsoluteZValid(); 
     1328          } 
     1329          break; 
    11841330        case 49: 
    11851331          in.seek(valOrOffset); 
     
    11931339        zoom = Float.parseFloat(value.toString()); 
    11941340      } 
     1341      if ("XCalibration".equals(key) && value != null) { 
     1342        if (value instanceof TiffRational) { 
     1343          sizeX = (float) ((TiffRational) value).doubleValue(); 
     1344        } 
     1345        else sizeX = new Float(value.toString()); 
     1346      } 
     1347      if ("YCalibration".equals(key) && value != null) { 
     1348        if (value instanceof TiffRational) { 
     1349          sizeY = (float) ((TiffRational) value).doubleValue(); 
     1350        } 
     1351        else sizeY = new Float(value.toString()); 
     1352      } 
    11951353    } 
    11961354    in.seek(saveLoc); 
     1355 
     1356    if (validZ) zStart = tempZ; 
    11971357  } 
    11981358 
     
    12381398  /** Formats an integer value with leading 0s if needed. */ 
    12391399  public static String intFormat(int myint, int digits) { 
    1240     DecimalFormat df = new DecimalFormat(); 
    1241     df.setMaximumIntegerDigits(digits); 
    1242     df.setMinimumIntegerDigits(digits); 
    1243     return df.format(myint); 
     1400    return String.format("%0" + digits + "d", myint); 
    12441401  } 
    12451402 
     
    13151472  private String getKey(int id) { 
    13161473    switch (id) { 
     1474      case 0: return "AutoScale"; 
    13171475      case 1: return "MinScale"; 
    13181476      case 2: return "MaxScale"; 
     
    13361494      case 20: return "grayPointCount"; 
    13371495      case 21: return "grayX"; 
    1338       case 22: return "gray"; 
     1496      case 22: return "grayY"; 
    13391497      case 23: return "grayMin"; 
    13401498      case 24: return "grayMax"; 
     
    13421500      case 26: return "StandardLUT"; 
    13431501      case 27: return "Wavelength"; 
     1502      case 28: return "StagePosition"; 
     1503      case 29: return "CameraChipOffset"; 
    13441504      case 30: return "OverlayMask"; 
    13451505      case 31: return "OverlayCompress"; 
     
    13511511      case 38: return "AutoScaleLoInfo"; 
    13521512      case 39: return "AutoScaleHiInfo"; 
     1513      case 40: return "AbsoluteZ"; 
     1514      case 41: return "AbsoluteZValid"; 
    13531515      case 42: return "Gamma"; 
    13541516      case 43: return "GammaRed"; 
     
    13561518      case 45: return "GammaBlue"; 
    13571519      case 46: return "CameraBin"; 
     1520      case 47: return "NewLUT"; 
     1521      case 48: return "ImagePropertyEx"; 
     1522      case 49: return "PlaneProperty"; 
     1523      case 50: return "UserLutTable"; 
     1524      case 51: return "RedAutoScaleInfo"; 
     1525      case 52: return "RedAutoScaleLoInfo"; 
     1526      case 53: return "RedAutoScaleHiInfo"; 
     1527      case 54: return "RedMinScaleInfo"; 
     1528      case 55: return "RedMaxScaleInfo"; 
     1529      case 56: return "GreenAutoScaleInfo"; 
     1530      case 57: return "GreenAutoScaleLoInfo"; 
     1531      case 58: return "GreenAutoScaleHiInfo"; 
     1532      case 59: return "GreenMinScaleInfo"; 
     1533      case 60: return "GreenMaxScaleInfo"; 
     1534      case 61: return "BlueAutoScaleInfo"; 
     1535      case 62: return "BlueAutoScaleLoInfo"; 
     1536      case 63: return "BlueAutoScaleHiInfo"; 
     1537      case 64: return "BlueMinScaleInfo"; 
     1538      case 65: return "BlueMaxScaleInfo"; 
     1539      case 66: return "OverlayPlaneColor"; 
    13581540    } 
    13591541    return null; 
Note: See TracChangeset for help on using the changeset viewer.