Changeset 6992


Ignore:
Timestamp:
09/28/10 10:33:43 (9 years ago)
Author:
melissa
Message:

Merged recent Zeiss LSM changes to 4.2: r6697, r6713, and r6842.

Location:
branches/4.2/components/bio-formats
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/4.2/components/bio-formats/src/loci/formats/in

  • branches/4.2/components/bio-formats/src/loci/formats/in/ZeissLSMReader.java

    r6910 r6992  
    166166  private Vector<String> imageNames; 
    167167  private String binning; 
     168  private Vector<Double> xCoordinates, yCoordinates; 
     169  private int dimensionM, dimensionP; 
     170  private Hashtable<String, Integer> seriesCounts; 
    168171 
    169172  private int totalROIs = 0; 
     
    210213      prevPlane = -1; 
    211214      prevBuf = null; 
     215      xCoordinates = null; 
     216      yCoordinates = null; 
     217      dimensionM = 0; 
     218      dimensionP = 0; 
     219      seriesCounts = null; 
    212220    } 
    213221  } 
     
    237245      return lsmFilenames; 
    238246    } 
    239     return new String[] {currentId, lsmFilenames[getSeries()]}; 
     247    return new String[] {currentId, getLSMFileFromSeries(getSeries())}; 
    240248  } 
    241249 
     
    290298    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); 
    291299 
    292     in = new RandomAccessInputStream(lsmFilenames[getSeries()]); 
     300    in = new RandomAccessInputStream(getLSMFileFromSeries(getSeries())); 
    293301    in.order(!isLittleEndian()); 
    294302 
     
    312320      ImageTools.splitChannels(prevBuf, buf, c, getSizeC(), bpp, false, false); 
    313321    } 
    314     else tiffParser.getSamples(ifds.get(no), buf, x, y, w, h); 
     322    else { 
     323      tiffParser.getSamples(ifds.get(no), buf, x, y, w, h); 
     324    } 
    315325    in.close(); 
    316326    return buf; 
     
    342352    timestamps = new Vector<Double>(); 
    343353    imageNames = new Vector<String>(); 
    344  
    345     core = new CoreMetadata[lsmFilenames.length]; 
     354    xCoordinates = new Vector<Double>(); 
     355    yCoordinates = new Vector<Double>(); 
     356    seriesCounts = new Hashtable<String, Integer>(); 
     357 
     358    int seriesCount = 0; 
     359 
     360    for (String filename : lsmFilenames) { 
     361      int extraSeries = getExtraSeries(filename); 
     362      seriesCounts.put(filename, extraSeries); 
     363      seriesCount += extraSeries; 
     364    } 
     365 
     366    core = new CoreMetadata[seriesCount]; 
    346367    ifdsList = new Vector<IFDList>(); 
    347368    ifdsList.setSize(core.length); 
    348     for (int i=0; i<core.length; i++) { 
    349       core[i] = new CoreMetadata(); 
    350       RandomAccessInputStream s = new RandomAccessInputStream(lsmFilenames[i]); 
    351       core[i].littleEndian = s.read() == TiffConstants.LITTLE; 
    352       s.order(isLittleEndian()); 
    353       s.seek(0); 
    354       // calling tp.getNonThumbnailIFDs() would give us the same IFDList, but 
    355       // assuming that every other IFD is a thumbnail reduces the parsing time 
    356       TiffParser tp = new TiffParser(s); 
     369 
     370    int realSeries = 0; 
     371    for (int i=0; i<lsmFilenames.length; i++) { 
     372      RandomAccessInputStream stream = 
     373        new RandomAccessInputStream(lsmFilenames[i]); 
     374      int count = seriesCounts.get(lsmFilenames[i]); 
     375      boolean littleEndian = stream.read() == TiffConstants.LITTLE; 
     376      stream.order(littleEndian); 
     377 
     378      TiffParser tp = new TiffParser(stream); 
    357379      long[] ifdOffsets = tp.getIFDOffsets(); 
    358       IFDList ifds = new IFDList(); 
    359       for (int offset=0; offset<ifdOffsets.length;) { 
    360         ifds.add(tp.getIFD(ifdOffsets[offset])); 
    361         if (ifds.get(0).containsKey(ZEISS_ID)) offset += 2; 
    362         else offset++; 
    363       } 
    364       ifdsList.set(i, ifds); 
    365       s.close(); 
     380      int ifdsPerSeries = (ifdOffsets.length / 2) / count; 
     381 
     382      int offset = 0; 
     383      Object zeissTag = null; 
     384      for (int s=0; s<count; s++, realSeries++) { 
     385        core[realSeries] = new CoreMetadata(); 
     386        core[realSeries].littleEndian = littleEndian; 
     387 
     388        IFDList ifds = new IFDList(); 
     389        while (ifds.size() < ifdsPerSeries) { 
     390          IFD ifd = tp.getIFD(ifdOffsets[offset]); 
     391          if (offset == 0) zeissTag = ifd.get(ZEISS_ID); 
     392          if (offset > 0 && ifds.size() == 0) { 
     393            ifd.putIFDValue(ZEISS_ID, zeissTag); 
     394          } 
     395          ifds.add(ifd); 
     396          if (zeissTag != null) offset += 2; 
     397          else offset++; 
     398        } 
     399        ifdsList.set(realSeries, ifds); 
     400      } 
     401      stream.close(); 
    366402    } 
    367403 
     
    379415 
    380416      // fix the offsets for > 4 GB files 
     417      RandomAccessInputStream s = 
     418        new RandomAccessInputStream(getLSMFileFromSeries(series)); 
    381419      for (int i=1; i<ifds.size(); i++) { 
    382420        long[] stripOffsets = ifds.get(i).getStripOffsets(); 
     
    404442        } 
    405443      } 
     444      s.close(); 
    406445 
    407446      initMetadata(series); 
    408447    } 
     448 
     449    for (int i=0; i<getSeriesCount(); i++) { 
     450      core[i].imageCount = core[i].sizeZ * core[i].sizeC * core[i].sizeT; 
     451    } 
     452 
    409453    MetadataTools.populatePixels(store, this, true); 
    410454    for (int series=0; series<ifdsList.size(); series++) { 
    411455      setSeries(series); 
    412       store.setImageName(imageNames.get(series), series); 
     456      if (series < imageNames.size()) { 
     457        store.setImageName(imageNames.get(series), series); 
     458      } 
    413459      store.setPixelsBinDataBigEndian(!isLittleEndian(), series, 0); 
    414460    } 
     
    439485  } 
    440486 
     487  private int getEffectiveSeries(int currentSeries) { 
     488    int seriesCount = 0; 
     489    for (int i=0; i<lsmFilenames.length; i++) { 
     490      Integer count = seriesCounts.get(lsmFilenames[i]); 
     491      if (count == null) count = 1; 
     492      seriesCount += count; 
     493      if (seriesCount > currentSeries) return i; 
     494    } 
     495    return -1; 
     496  } 
     497 
     498  private String getLSMFileFromSeries(int currentSeries) { 
     499    int effectiveSeries = getEffectiveSeries(currentSeries); 
     500    return effectiveSeries < 0 ? null : lsmFilenames[effectiveSeries]; 
     501  } 
     502 
     503  private int getExtraSeries(String file) throws FormatException, IOException { 
     504    in = new RandomAccessInputStream(file); 
     505    boolean littleEndian = in.read() == TiffConstants.LITTLE; 
     506    in.order(littleEndian); 
     507 
     508    tiffParser = new TiffParser(in); 
     509    IFD ifd = tiffParser.getFirstIFD(); 
     510    RandomAccessInputStream ras = getCZTag(ifd); 
     511    if (ras == null) return 1; 
     512    ras.order(littleEndian); 
     513 
     514    ras.seek(264); 
     515    dimensionP = ras.readInt(); 
     516    dimensionM = ras.readInt(); 
     517    ras.close(); 
     518 
     519    int nSeries = dimensionM * dimensionP; 
     520    return nSeries <= 0 ? 1 : nSeries; 
     521  } 
     522 
     523  private int getPosition(int currentSeries) { 
     524    int effectiveSeries = getEffectiveSeries(currentSeries); 
     525    int firstPosition = 0; 
     526    for (int i=0; i<effectiveSeries; i++) { 
     527      firstPosition += seriesCounts.get(lsmFilenames[i]); 
     528    } 
     529    return currentSeries - firstPosition; 
     530  } 
     531 
     532  private RandomAccessInputStream getCZTag(IFD ifd) 
     533    throws FormatException, IOException 
     534  { 
     535    // get TIF_CZ_LSMINFO structure 
     536    short[] s = ifd.getIFDShortArray(ZEISS_ID); 
     537    if (s == null) { 
     538      LOGGER.warn("Invalid Zeiss LSM file. Tag {} not found.", ZEISS_ID); 
     539      TiffReader reader = new TiffReader(); 
     540      reader.setId(getLSMFileFromSeries(series)); 
     541      core[getSeries()] = reader.getCoreMetadata()[0]; 
     542      reader.close(); 
     543      return null; 
     544    } 
     545    byte[] cz = new byte[s.length]; 
     546    for (int i=0; i<s.length; i++) { 
     547      cz[i] = (byte) s[i]; 
     548    } 
     549 
     550    RandomAccessInputStream ras = new RandomAccessInputStream(cz); 
     551    ras.order(isLittleEndian()); 
     552    return ras; 
     553  } 
     554 
    441555  protected void initMetadata(int series) throws FormatException, IOException { 
    442556    setSeries(series); 
     
    444558    IFD ifd = ifds.get(0); 
    445559 
    446     in = new RandomAccessInputStream(lsmFilenames[series]); 
     560    in = new RandomAccessInputStream(getLSMFileFromSeries(series)); 
    447561    in.order(isLittleEndian()); 
    448562 
     
    466580    MetadataStore store = makeFilterMetadata(); 
    467581 
    468     String imageName = lsmFilenames[series]; 
     582    int instrument = getEffectiveSeries(series); 
     583 
     584    String imageName = getLSMFileFromSeries(series); 
    469585    if (imageName.indexOf(".") != -1) { 
    470586      imageName = imageName.substring(0, imageName.lastIndexOf(".")); 
     
    474590        imageName.substring(imageName.lastIndexOf(File.separator) + 1); 
    475591    } 
     592    if (lsmFilenames.length != getSeriesCount()) { 
     593      imageName += " #" + (getPosition(series) + 1); 
     594    } 
    476595 
    477596    // link Instrument and Image 
    478597    store.setImageID(MetadataTools.createLSID("Image", series), series); 
    479     String instrumentID = MetadataTools.createLSID("Instrument", series); 
    480     store.setInstrumentID(instrumentID, series); 
     598    String instrumentID = MetadataTools.createLSID("Instrument", instrument); 
     599    store.setInstrumentID(instrumentID, instrument); 
    481600    store.setImageInstrumentRef(instrumentID, series); 
    482601 
    483     // get TIF_CZ_LSMINFO structure 
    484     short[] s = ifd.getIFDShortArray(ZEISS_ID); 
    485     if (s == null) { 
    486       LOGGER.warn("Invalid Zeiss LSM file. Tag {} not found.", ZEISS_ID); 
    487       TiffReader reader = new TiffReader(); 
    488       reader.setId(lsmFilenames[series]); 
    489       core[series] = reader.getCoreMetadata()[0]; 
    490       reader.close(); 
     602    RandomAccessInputStream ras = getCZTag(ifd); 
     603    if (ras == null) { 
    491604      imageNames.add(imageName); 
    492605      return; 
    493606    } 
    494     byte[] cz = new byte[s.length]; 
    495     for (int i=0; i<s.length; i++) { 
    496       cz[i] = (byte) s[i]; 
    497     } 
    498  
    499     RandomAccessInputStream ras = new RandomAccessInputStream(cz); 
    500     ras.order(isLittleEndian()); 
    501607 
    502608    ras.seek(16); 
     
    545651      addSeriesMeta("OriginZ", ras.readDouble()); 
    546652    } 
    547     else ras.seek(56); 
     653    else ras.seek(88); 
    548654 
    549655    int scanType = ras.readShort(); 
     
    641747    if (getSizeT() == 0) core[series].sizeT = getImageCount() / getSizeZ(); 
    642748 
    643     MetadataTools.setDefaultCreationDate(store, getCurrentFile(), series); 
    644     if (getSizeC() > 1) { 
    645       if (!splitPlanes) splitPlanes = isRGB(); 
    646       core[series].rgb = false; 
    647       if (splitPlanes) core[series].imageCount *= getSizeC(); 
    648     } 
    649  
    650     for (int c=0; c<getEffectiveSizeC(); c++) { 
    651       String lsid = MetadataTools.createLSID("Channel", series, c); 
    652       store.setChannelID(lsid, series, c); 
    653     } 
     749    long channelColorsOffset = 0; 
     750    long timeStampOffset = 0; 
     751    long eventListOffset = 0; 
     752    long scanInformationOffset = 0; 
    654753 
    655754    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { 
     
    681780      overlayOffsets[2] = ras.readInt(); 
    682781 
    683       long channelColorsOffset = ras.readInt(); 
     782      channelColorsOffset = ras.readInt(); 
    684783 
    685784      addSeriesMeta("TimeInterval", ras.readDouble()); 
    686785      ras.skipBytes(4); 
    687       long scanInformationOffset = ras.readInt(); 
     786      scanInformationOffset = ras.readInt(); 
    688787      ras.skipBytes(4); 
    689       long timeStampOffset = ras.readInt(); 
    690       long eventListOffset = ras.readInt(); 
     788      timeStampOffset = ras.readInt(); 
     789      eventListOffset = ras.readInt(); 
    691790      overlayOffsets[3] = ras.readInt(); 
    692791      overlayOffsets[4] = ras.readInt(); 
     
    715814 
    716815      int wavelengthOffset = ras.readInt(); 
     816      ras.skipBytes(64); 
     817    } 
     818    else ras.skipBytes(182); 
     819 
     820    MetadataTools.setDefaultCreationDate(store, getCurrentFile(), series); 
     821    if (getSizeC() > 1) { 
     822      if (!splitPlanes) splitPlanes = isRGB(); 
     823      core[series].rgb = false; 
     824      if (splitPlanes) core[series].imageCount *= getSizeC(); 
     825    } 
     826 
     827    for (int c=0; c<getEffectiveSizeC(); c++) { 
     828      String lsid = MetadataTools.createLSID("Channel", series, c); 
     829      store.setChannelID(lsid, series, c); 
     830    } 
     831 
     832    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { 
     833      // NB: the Zeiss LSM 5.5 specification indicates that there should be 
     834      //     15 32-bit integers here; however, there are actually 16 32-bit 
     835      //     integers before the tile position offset. 
     836      //     We have confirmed with Zeiss that this is correct. 
     837      ras.skipBytes(64); 
     838 
     839      int tilePositionOffset = ras.readInt(); 
    717840 
    718841      // read referenced structures 
     
    720843      addSeriesMeta("DimensionZ", getSizeZ()); 
    721844      addSeriesMeta("DimensionChannels", getSizeC()); 
     845      addSeriesMeta("DimensionM", dimensionM); 
     846      addSeriesMeta("DimensionP", dimensionP); 
     847 
     848      if (tilePositionOffset != 0) { 
     849        in.seek(tilePositionOffset); 
     850        int nTiles = in.readInt(); 
     851        for (int i=0; i<nTiles; i++) { 
     852          xCoordinates.add(in.readDouble()); 
     853          yCoordinates.add(in.readDouble()); 
     854        } 
     855      } 
    722856 
    723857      if (channelColorsOffset != 0) { 
     
    9091043          store.setPlaneExposureTime(nextStamp - thisStamp, series, i); 
    9101044        } 
     1045        if (xCoordinates.size() > 0) { 
     1046          double planesPerStage = 
     1047            (double) getImageCount() / xCoordinates.size(); 
     1048          int stage = (int) (i / planesPerStage); 
     1049          store.setPlanePositionX(xCoordinates.get(stage), series, i); 
     1050          store.setPlanePositionY(yCoordinates.get(stage), series, i); 
     1051        } 
    9111052      } 
    9121053    } 
     
    9231064    } 
    9241065 
     1066    int instrument = getEffectiveSeries(series); 
     1067 
    9251068    // NB: block.acquire can be false.  If that is the case, Instrument data 
    9261069    // is the only thing that should be populated. 
    9271070    if (block instanceof Recording) { 
    9281071      Recording recording = (Recording) block; 
    929       String objectiveID = MetadataTools.createLSID("Objective", series, 0); 
     1072      String objectiveID = MetadataTools.createLSID("Objective", instrument, 0); 
    9301073      if (recording.acquire) { 
    9311074        store.setImageDescription(recording.description, series); 
     
    9351078      } 
    9361079      store.setObjectiveCorrection( 
    937         getCorrection(recording.correction), series, 0); 
    938       store.setObjectiveImmersion(getImmersion(recording.immersion), series, 0); 
     1080        getCorrection(recording.correction), instrument, 0); 
     1081      store.setObjectiveImmersion( 
     1082        getImmersion(recording.immersion), instrument, 0); 
    9391083      if (recording.magnification != null && recording.magnification > 0) { 
    9401084        store.setObjectiveNominalMagnification( 
    941           new PositiveInteger(recording.magnification), series, 0); 
    942       } 
    943       store.setObjectiveLensNA(recording.lensNA, series, 0); 
    944       store.setObjectiveIris(recording.iris, series, 0); 
    945       store.setObjectiveID(objectiveID, series, 0); 
     1085          new PositiveInteger(recording.magnification), instrument, 0); 
     1086      } 
     1087      store.setObjectiveLensNA(recording.lensNA, instrument, 0); 
     1088      store.setObjectiveIris(recording.iris, instrument, 0); 
     1089      store.setObjectiveID(objectiveID, instrument, 0); 
    9461090    } 
    9471091    else if (block instanceof Laser) { 
     
    9491093      if (laser.medium != null) { 
    9501094        store.setLaserLaserMedium(getLaserMedium(laser.medium), 
    951           series, nextLaser); 
     1095          instrument, nextLaser); 
    9521096      } 
    9531097      if (laser.type != null) { 
    954         store.setLaserType(getLaserType(laser.type), series, nextLaser); 
     1098        store.setLaserType(getLaserType(laser.type), instrument, nextLaser); 
    9551099      } 
    9561100      if (laser.model != null) { 
    957         store.setLaserModel(laser.model, series, nextLaser); 
     1101        store.setLaserModel(laser.model, instrument, nextLaser); 
    9581102      } 
    9591103      String lightSourceID = 
    960         MetadataTools.createLSID("LightSource", series, nextLaser); 
    961       store.setLaserID(lightSourceID, series, nextLaser); 
     1104        MetadataTools.createLSID("LightSource", instrument, nextLaser); 
     1105      store.setLaserID(lightSourceID, instrument, nextLaser); 
    9621106      nextLaser++; 
    9631107    } 
     
    9841128      } 
    9851129      if (channel.filter != null) { 
    986         String id = MetadataTools.createLSID("Filter", series, nextFilter); 
     1130        String id = MetadataTools.createLSID("Filter", instrument, nextFilter); 
    9871131        if (channel.acquire && nextDetectChannel < getSizeC()) { 
    988           store.setLightPathEmissionFilterRef(id, series, nextDetectChannel, 0); 
    989         } 
    990         store.setFilterID(id, series, nextFilter); 
    991         store.setFilterModel(channel.filter, series, nextFilter); 
     1132          store.setLightPathEmissionFilterRef( 
     1133            id, instrument, nextDetectChannel, 0); 
     1134        } 
     1135        store.setFilterID(id, instrument, nextFilter); 
     1136        store.setFilterModel(channel.filter, instrument, nextFilter); 
    9921137 
    9931138        int space = channel.filter.indexOf(" "); 
     
    9971142          else if (type.equals("LP")) type = "LongPass"; 
    9981143 
    999           store.setFilterType(getFilterType(type), series, nextFilter); 
     1144          store.setFilterType(getFilterType(type), instrument, nextFilter); 
    10001145 
    10011146          String transmittance = channel.filter.substring(space + 1).trim(); 
     
    10031148          try { 
    10041149            store.setTransmittanceRangeCutIn( 
    1005                 PositiveInteger.valueOf(v[0].trim()), series, nextFilter); 
     1150              PositiveInteger.valueOf(v[0].trim()), instrument, nextFilter); 
    10061151          } 
    10071152          catch (NumberFormatException e) { } 
     
    10091154            try { 
    10101155              store.setTransmittanceRangeCutOut( 
    1011                   PositiveInteger.valueOf(v[1].trim()), series, nextFilter); 
     1156                PositiveInteger.valueOf(v[1].trim()), instrument, nextFilter); 
    10121157            } 
    10131158            catch (NumberFormatException e) { } 
     
    10191164      if (channel.channelName != null) { 
    10201165        String detectorID = 
    1021           MetadataTools.createLSID("Detector", series, nextDetector); 
    1022         store.setDetectorID(detectorID, series, nextDetector); 
     1166          MetadataTools.createLSID("Detector", instrument, nextDetector); 
     1167        store.setDetectorID(detectorID, instrument, nextDetector); 
    10231168        if (channel.acquire && nextDetector < getSizeC()) { 
    10241169          store.setDetectorSettingsID(detectorID, series, nextDetector); 
     
    10281173      } 
    10291174      if (channel.amplificationGain != null) { 
    1030         store.setDetectorAmplificationGain(channel.amplificationGain, series, 
    1031           nextDetector); 
     1175        store.setDetectorAmplificationGain( 
     1176          channel.amplificationGain, instrument, nextDetector); 
    10321177      } 
    10331178      if (channel.gain != null) { 
    1034         store.setDetectorGain(channel.gain, series, nextDetector); 
    1035       } 
    1036       store.setDetectorType(getDetectorType("PMT"), series, nextDetector); 
    1037       store.setDetectorZoom(zoom, series, nextDetector); 
     1179        store.setDetectorGain(channel.gain, instrument, nextDetector); 
     1180      } 
     1181      store.setDetectorType(getDetectorType("PMT"), instrument, nextDetector); 
     1182      store.setDetectorZoom(zoom, instrument, nextDetector); 
    10381183      nextDetectChannel++; 
    10391184      nextDetector++; 
     
    10431188      if (beamSplitter.filterSet != null) { 
    10441189        if (beamSplitter.filter != null) { 
    1045           String id = 
    1046             MetadataTools.createLSID("Dichroic", series, nextDichroic); 
    1047           store.setDichroicID(id, series, nextDichroic); 
    1048           store.setDichroicModel(beamSplitter.filter, series, nextDichroic); 
     1190          String id = MetadataTools.createLSID( 
     1191            "Dichroic", instrument, nextDichroic); 
     1192          store.setDichroicID(id, instrument, nextDichroic); 
     1193          store.setDichroicModel(beamSplitter.filter, instrument, nextDichroic); 
    10491194          if (nextDichroicChannel < getEffectiveSizeC()) { 
    10501195            store.setLightPathDichroicRef(id, series, nextDichroicChannel); 
  • branches/4.2/components/bio-formats/src/loci/formats/meta

  • branches/4.2/components/bio-formats/src/loci/formats/ome

  • branches/4.2/components/bio-formats/src/loci/formats/tiff

  • branches/4.2/components/bio-formats/test/loci/formats/utests

Note: See TracChangeset for help on using the changeset viewer.