/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ @Override public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser tp = new TiffParser(stream); IFD ifd = tp.getFirstIFD(); if (ifd == null) return false; return ifd.containsKey(SFEG_TAG) || ifd.containsKey(HELIOS_TAG) || ifd.containsKey(TITAN_TAG); }
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser parser = new TiffParser(stream); parser.setDoCaching(false); IFD ifd = parser.getFirstIFD(); if (ifd == null) return false; return ifd.containsKey(XML_TAG); }
private void parseFile(String tiff, MetamorphHandler handler) throws IOException { RandomAccessInputStream s = new RandomAccessInputStream(tiff); TiffParser parser = new TiffParser(s); IFD firstIFD = parser.getFirstIFD(); String xml = XMLTools.sanitizeXML(firstIFD.getComment()); XMLTools.parseXML(xml, handler); s.close(); }
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser parser = new TiffParser(stream); IFD ifd = parser.getFirstIFD(); if (ifd == null) return false; String copyright = ifd.getIFDTextValue(IFD.COPYRIGHT); if (copyright == null) return false; return copyright.indexOf("Trestle Corp.") >= 0; }
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser p = new TiffParser(stream); IFD ifd = p.getFirstIFD(); if (ifd == null) return false; String software = ifd.getIFDTextValue(IFD.SOFTWARE); if (software == null) return false; return software.trim().startsWith("MATROX Imaging Library"); }
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ @Override public boolean isThisType(RandomAccessInputStream stream) throws IOException { TiffParser parser = new TiffParser(stream); parser.setDoCaching(false); IFD ifd = parser.getFirstIFD(); if (ifd == null) return false; parser.fillInIFD(ifd); Object tag1 = ifd.get(IMAGE_PRO_TAG_1); Object tag3 = ifd.get(IMAGE_PRO_TAG_3); return (tag1 != null && (tag1 instanceof short[])) || (tag3 != null && (tag3 instanceof int[])); }
/* @see BaseTiffReader#initStandardMetadata() */ protected void initStandardMetadata() throws FormatException, IOException { super.initStandardMetadata(); ifds = tiffParser.getIFDs(); core.clear(); for (int i = 0; i < ifds.size(); i++) { CoreMetadata ms = new CoreMetadata(); core.add(ms); ms.imageCount = 1; IFD ifd = ifds.get(i); ifd.remove(PIXELS_TAG); tiffParser.fillInIFD(ifd); PhotoInterp photo = ifd.getPhotometricInterpretation(); int samples = ifd.getSamplesPerPixel(); ms.rgb = samples > 1 || photo == PhotoInterp.RGB || photo == PhotoInterp.CFA_ARRAY; if (photo == PhotoInterp.CFA_ARRAY) samples = 3; ms.sizeX = (int) ifd.getImageWidth(); ms.sizeY = (int) ifd.getImageLength(); ms.sizeZ = 1; ms.sizeC = isRGB() ? samples : 1; ms.sizeT = 1; ms.pixelType = ifd.getPixelType(); ms.indexed = photo == PhotoInterp.RGB_PALETTE; ms.dimensionOrder = "XYCZT"; ms.interleaved = false; } IFD firstIFD = ifds.get(0); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { String xml = firstIFD.getIFDTextValue(XML_TAG).trim(); xml = xml.substring(xml.indexOf("<")); XMLTools.parseXML(xml, new ImaconHandler()); } String[] creationInfo = firstIFD.getIFDTextValue(CREATOR_TAG).split("\n"); if (creationInfo.length > 4) { experimenterName = creationInfo[4].trim(); } if (creationInfo.length > 6) { imageName = creationInfo[6].trim(); } if (creationInfo.length > 8) { creationDate = creationInfo[8].trim(); } if (creationInfo.length > 10) { creationDate += " " + creationInfo[10].trim(); } }
private long getTimestamp(String file) throws FormatException, IOException { RandomAccessInputStream s = new RandomAccessInputStream(file); TiffParser parser = new TiffParser(s); parser.setDoCaching(false); IFD firstIFD = parser.getFirstIFD(); if (firstIFD != null) { TiffIFDEntry timestamp = (TiffIFDEntry) firstIFD.get(IFD.DATE_TIME); if (timestamp != null) { String stamp = parser.getIFDValue(timestamp).toString(); s.close(); stamp = DateTools.formatDate(stamp, BaseTiffReader.DATE_FORMATS); return DateTools.getTime(stamp, DateTools.ISO8601_FORMAT); } } s.close(); return new Location(file).lastModified(); }
public static String getExifTagName(int tag) { return IFD.getIFDTagName(tag); }
protected void putInt(String key, IFD ifd, int tag) { put(key, ifd.getIFDIntValue(tag)); }
/** * Populates the metadata store using the data parsed in {@link #initStandardMetadata()} along * with some further parsing done in the method itself. * * <p>All calls to the active <code>MetadataStore</code> should be made in this method and * <b>only</b> in this method. This is especially important for sub-classes that override the * getters for pixel set array size, etc. */ protected void initMetadataStore() throws FormatException { LOGGER.info("Populating OME metadata"); // the metadata store we're working with MetadataStore store = makeFilterMetadata(); IFD firstIFD = ifds.get(0); IFD exif = null; if (ifds.get(0).containsKey(IFD.EXIF)) { try { IFDList exifIFDs = tiffParser.getExifIFDs(); if (exifIFDs.size() > 0) { exif = exifIFDs.get(0); } tiffParser.fillInIFD(exif); } catch (IOException e) { LOGGER.debug("Could not read EXIF IFDs", e); } } MetadataTools.populatePixels(store, this, exif != null); // format the creation date to ISO 8601 String creationDate = getImageCreationDate(); String date = DateTools.formatDate(creationDate, DATE_FORMATS); if (creationDate != null && date == null) { LOGGER.warn("unknown creation date format: {}", creationDate); } creationDate = date; // populate Image if (creationDate != null) { store.setImageAcquisitionDate(new Timestamp(creationDate), 0); } if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { // populate Experimenter String artist = firstIFD.getIFDTextValue(IFD.ARTIST); if (artist != null) { String firstName = null, lastName = null; int ndx = artist.indexOf(" "); if (ndx < 0) lastName = artist; else { firstName = artist.substring(0, ndx); lastName = artist.substring(ndx + 1); } String email = firstIFD.getIFDStringValue(IFD.HOST_COMPUTER); store.setExperimenterFirstName(firstName, 0); store.setExperimenterLastName(lastName, 0); store.setExperimenterEmail(email, 0); store.setExperimenterID(MetadataTools.createLSID("Experimenter", 0), 0); } store.setImageDescription(firstIFD.getComment(), 0); // set the X and Y pixel dimensions double pixX = firstIFD.getXResolution(); double pixY = firstIFD.getYResolution(); PositiveFloat sizeX = FormatTools.getPhysicalSizeX(pixX); PositiveFloat sizeY = FormatTools.getPhysicalSizeY(pixY); if (sizeX != null) { store.setPixelsPhysicalSizeX(sizeX, 0); } if (sizeY != null) { store.setPixelsPhysicalSizeY(sizeY, 0); } store.setPixelsPhysicalSizeZ(null, 0); if (exif != null) { if (exif.containsKey(IFD.EXPOSURE_TIME)) { Object exp = exif.get(IFD.EXPOSURE_TIME); if (exp instanceof TiffRational) { Double exposure = ((TiffRational) exp).doubleValue(); for (int i = 0; i < getImageCount(); i++) { store.setPlaneExposureTime(exposure, 0, i); } } } } } }
/** * Parses standard metadata. * * <p>NOTE: Absolutely <b>no</b> calls to the metadata store should be made in this method or * methods that override this method. Data <b>will</b> be overwritten if you do so. */ protected void initStandardMetadata() throws FormatException, IOException { if (getMetadataOptions().getMetadataLevel() == MetadataLevel.MINIMUM) { return; } for (int i = 0; i < ifds.size(); i++) { put("PageName #" + i, ifds.get(i), IFD.PAGE_NAME); } IFD firstIFD = ifds.get(0); put("ImageWidth", firstIFD, IFD.IMAGE_WIDTH); put("ImageLength", firstIFD, IFD.IMAGE_LENGTH); put("BitsPerSample", firstIFD, IFD.BITS_PER_SAMPLE); // retrieve EXIF values, if available if (ifds.get(0).containsKey(IFD.EXIF)) { IFDList exifIFDs = tiffParser.getExifIFDs(); if (exifIFDs.size() > 0) { IFD exif = exifIFDs.get(0); tiffParser.fillInIFD(exif); for (Integer key : exif.keySet()) { int k = key.intValue(); addGlobalMeta(getExifTagName(k), exif.get(key)); } } } TiffCompression comp = firstIFD.getCompression(); put("Compression", comp.getCodecName()); PhotoInterp photo = firstIFD.getPhotometricInterpretation(); String photoInterp = photo.getName(); String metaDataPhotoInterp = photo.getMetadataType(); put("PhotometricInterpretation", photoInterp); put("MetaDataPhotometricInterpretation", metaDataPhotoInterp); putInt("CellWidth", firstIFD, IFD.CELL_WIDTH); putInt("CellLength", firstIFD, IFD.CELL_LENGTH); int or = firstIFD.getIFDIntValue(IFD.ORIENTATION); // adjust the width and height if necessary if (or == 8) { put("ImageWidth", firstIFD, IFD.IMAGE_LENGTH); put("ImageLength", firstIFD, IFD.IMAGE_WIDTH); } String orientation = null; // there is no case 0 switch (or) { case 1: orientation = "1st row -> top; 1st column -> left"; break; case 2: orientation = "1st row -> top; 1st column -> right"; break; case 3: orientation = "1st row -> bottom; 1st column -> right"; break; case 4: orientation = "1st row -> bottom; 1st column -> left"; break; case 5: orientation = "1st row -> left; 1st column -> top"; break; case 6: orientation = "1st row -> right; 1st column -> top"; break; case 7: orientation = "1st row -> right; 1st column -> bottom"; break; case 8: orientation = "1st row -> left; 1st column -> bottom"; break; } put("Orientation", orientation); putInt("SamplesPerPixel", firstIFD, IFD.SAMPLES_PER_PIXEL); put("Software", firstIFD, IFD.SOFTWARE); put("Instrument Make", firstIFD, IFD.MAKE); put("Instrument Model", firstIFD, IFD.MODEL); put("Document Name", firstIFD, IFD.DOCUMENT_NAME); put("DateTime", firstIFD, IFD.DATE_TIME); put("Artist", firstIFD, IFD.ARTIST); put("HostComputer", firstIFD, IFD.HOST_COMPUTER); put("Copyright", firstIFD, IFD.COPYRIGHT); put("NewSubfileType", firstIFD, IFD.NEW_SUBFILE_TYPE); int thresh = firstIFD.getIFDIntValue(IFD.THRESHHOLDING); String threshholding = null; switch (thresh) { case 1: threshholding = "No dithering or halftoning"; break; case 2: threshholding = "Ordered dithering or halftoning"; break; case 3: threshholding = "Randomized error diffusion"; break; } put("Threshholding", threshholding); int fill = firstIFD.getIFDIntValue(IFD.FILL_ORDER); String fillOrder = null; switch (fill) { case 1: fillOrder = "Pixels with lower column values are stored " + "in the higher order bits of a byte"; break; case 2: fillOrder = "Pixels with lower column values are stored " + "in the lower order bits of a byte"; break; } put("FillOrder", fillOrder); putInt("Make", firstIFD, IFD.MAKE); putInt("Model", firstIFD, IFD.MODEL); putInt("MinSampleValue", firstIFD, IFD.MIN_SAMPLE_VALUE); putInt("MaxSampleValue", firstIFD, IFD.MAX_SAMPLE_VALUE); putInt("XResolution", firstIFD, IFD.X_RESOLUTION); putInt("YResolution", firstIFD, IFD.Y_RESOLUTION); int planar = firstIFD.getIFDIntValue(IFD.PLANAR_CONFIGURATION); String planarConfig = null; switch (planar) { case 1: planarConfig = "Chunky"; break; case 2: planarConfig = "Planar"; break; } put("PlanarConfiguration", planarConfig); putInt("XPosition", firstIFD, IFD.X_POSITION); putInt("YPosition", firstIFD, IFD.Y_POSITION); putInt("FreeOffsets", firstIFD, IFD.FREE_OFFSETS); putInt("FreeByteCounts", firstIFD, IFD.FREE_BYTE_COUNTS); putInt("GrayResponseUnit", firstIFD, IFD.GRAY_RESPONSE_UNIT); putInt("GrayResponseCurve", firstIFD, IFD.GRAY_RESPONSE_CURVE); putInt("T4Options", firstIFD, IFD.T4_OPTIONS); putInt("T6Options", firstIFD, IFD.T6_OPTIONS); int res = firstIFD.getIFDIntValue(IFD.RESOLUTION_UNIT); String resUnit = null; switch (res) { case 1: resUnit = "None"; break; case 2: resUnit = "Inch"; break; case 3: resUnit = "Centimeter"; break; } put("ResolutionUnit", resUnit); putInt("PageNumber", firstIFD, IFD.PAGE_NUMBER); putInt("TransferFunction", firstIFD, IFD.TRANSFER_FUNCTION); int predict = firstIFD.getIFDIntValue(IFD.PREDICTOR); String predictor = null; switch (predict) { case 1: predictor = "No prediction scheme"; break; case 2: predictor = "Horizontal differencing"; break; } put("Predictor", predictor); putInt("WhitePoint", firstIFD, IFD.WHITE_POINT); putInt("PrimaryChromacities", firstIFD, IFD.PRIMARY_CHROMATICITIES); putInt("HalftoneHints", firstIFD, IFD.HALFTONE_HINTS); putInt("TileWidth", firstIFD, IFD.TILE_WIDTH); putInt("TileLength", firstIFD, IFD.TILE_LENGTH); putInt("TileOffsets", firstIFD, IFD.TILE_OFFSETS); putInt("TileByteCounts", firstIFD, IFD.TILE_BYTE_COUNTS); int ink = firstIFD.getIFDIntValue(IFD.INK_SET); String inkSet = null; switch (ink) { case 1: inkSet = "CMYK"; break; case 2: inkSet = "Other"; break; } put("InkSet", inkSet); putInt("InkNames", firstIFD, IFD.INK_NAMES); putInt("NumberOfInks", firstIFD, IFD.NUMBER_OF_INKS); putInt("DotRange", firstIFD, IFD.DOT_RANGE); put("TargetPrinter", firstIFD, IFD.TARGET_PRINTER); putInt("ExtraSamples", firstIFD, IFD.EXTRA_SAMPLES); int fmt = firstIFD.getIFDIntValue(IFD.SAMPLE_FORMAT); String sampleFormat = null; switch (fmt) { case 1: sampleFormat = "unsigned integer"; break; case 2: sampleFormat = "two's complement signed integer"; break; case 3: sampleFormat = "IEEE floating point"; break; case 4: sampleFormat = "undefined"; break; } put("SampleFormat", sampleFormat); putInt("SMinSampleValue", firstIFD, IFD.S_MIN_SAMPLE_VALUE); putInt("SMaxSampleValue", firstIFD, IFD.S_MAX_SAMPLE_VALUE); putInt("TransferRange", firstIFD, IFD.TRANSFER_RANGE); int jpeg = firstIFD.getIFDIntValue(IFD.JPEG_PROC); String jpegProc = null; switch (jpeg) { case 1: jpegProc = "baseline sequential process"; break; case 14: jpegProc = "lossless process with Huffman coding"; break; } put("JPEGProc", jpegProc); putInt("JPEGInterchangeFormat", firstIFD, IFD.JPEG_INTERCHANGE_FORMAT); putInt("JPEGRestartInterval", firstIFD, IFD.JPEG_RESTART_INTERVAL); putInt("JPEGLosslessPredictors", firstIFD, IFD.JPEG_LOSSLESS_PREDICTORS); putInt("JPEGPointTransforms", firstIFD, IFD.JPEG_POINT_TRANSFORMS); putInt("JPEGQTables", firstIFD, IFD.JPEG_Q_TABLES); putInt("JPEGDCTables", firstIFD, IFD.JPEG_DC_TABLES); putInt("JPEGACTables", firstIFD, IFD.JPEG_AC_TABLES); putInt("YCbCrCoefficients", firstIFD, IFD.Y_CB_CR_COEFFICIENTS); int ycbcr = firstIFD.getIFDIntValue(IFD.Y_CB_CR_SUB_SAMPLING); String subSampling = null; switch (ycbcr) { case 1: subSampling = "chroma image dimensions = luma image dimensions"; break; case 2: subSampling = "chroma image dimensions are " + "half the luma image dimensions"; break; case 4: subSampling = "chroma image dimensions are " + "1/4 the luma image dimensions"; break; } put("YCbCrSubSampling", subSampling); putInt("YCbCrPositioning", firstIFD, IFD.Y_CB_CR_POSITIONING); putInt("ReferenceBlackWhite", firstIFD, IFD.REFERENCE_BLACK_WHITE); // bits per sample and number of channels int[] q = firstIFD.getBitsPerSample(); int bps = q[0]; int numC = q.length; // numC isn't set properly if we have an indexed color image, so we need // to reset it here if (photo == PhotoInterp.RGB_PALETTE || photo == PhotoInterp.CFA_ARRAY) { numC = 3; } put("BitsPerSample", bps); put("NumberOfChannels", numC); }
/* @see loci.formats.FormatReader#initFile(String) */ protected void initFile(String id) throws FormatException, IOException { super.initFile(id); if (!checkSuffix(id, "vsi")) { Location current = new Location(id).getAbsoluteFile(); Location parent = current.getParentFile(); parent = parent.getParentFile(); Location grandparent = parent.getParentFile(); String vsi = parent.getName(); vsi = vsi.substring(1, vsi.length() - 1) + ".vsi"; Location vsiFile = new Location(grandparent, vsi); if (!vsiFile.exists()) { throw new FormatException("Could not find .vsi file."); } else { id = vsiFile.getAbsolutePath(); } } parser = new TiffParser(id); ifds = parser.getIFDs(); RandomAccessInputStream vsi = new RandomAccessInputStream(id); vsi.order(parser.getStream().isLittleEndian()); vsi.seek(8); readTags(vsi); vsi.seek(parser.getStream().getFilePointer()); vsi.skipBytes(273); ArrayList<String> files = new ArrayList<String>(); Location file = new Location(id).getAbsoluteFile(); Location dir = file.getParentFile(); String name = file.getName(); name = name.substring(0, name.lastIndexOf(".")); Location pixelsDir = new Location(dir, "_" + name + "_"); String[] stackDirs = pixelsDir.list(true); if (stackDirs != null) { for (String f : stackDirs) { Location stackDir = new Location(pixelsDir, f); String[] pixelsFiles = stackDir.list(true); if (pixelsFiles != null) { for (String pixelsFile : pixelsFiles) { if (checkSuffix(pixelsFile, "ets")) { files.add(new Location(stackDir, pixelsFile).getAbsolutePath()); } } } } } files.add(file.getAbsolutePath()); usedFiles = files.toArray(new String[files.size()]); core = new CoreMetadata[files.size() - 1 + ifds.size()]; tileOffsets = new Long[files.size() - 1][]; rows = new int[files.size() - 1]; cols = new int[files.size() - 1]; nDimensions = new int[core.length]; IFDList exifs = parser.getExifIFDs(); compressionType = new int[core.length]; tileX = new int[core.length]; tileY = new int[core.length]; tileMap = new HashMap[core.length]; for (int s = 0; s < core.length; s++) { core[s] = new CoreMetadata(); } for (int s = 0; s < core.length; s++) { tileMap[s] = new HashMap<TileCoordinate, Integer>(); if (s == 0 && !hasFlattenedResolutions()) { core[s].resolutionCount = ifds.size() + (files.size() == 1 ? 0 : 1); } if (s < files.size() - 1) { setSeries(s); parseETSFile(files.get(s), s); core[s].littleEndian = compressionType[s] == RAW; core[s].interleaved = core[s].rgb; if (s == 0 && exifs.size() > 0) { IFD exif = exifs.get(0); int newX = exif.getIFDIntValue(IFD.PIXEL_X_DIMENSION); int newY = exif.getIFDIntValue(IFD.PIXEL_Y_DIMENSION); if (getSizeX() > newX || getSizeY() > newY) { core[s].sizeX = newX; core[s].sizeY = newY; } } setSeries(0); } else { IFD ifd = ifds.get(s - files.size() + 1); PhotoInterp p = ifd.getPhotometricInterpretation(); int samples = ifd.getSamplesPerPixel(); core[s].rgb = samples > 1 || p == PhotoInterp.RGB; core[s].sizeX = (int) ifd.getImageWidth(); core[s].sizeY = (int) ifd.getImageLength(); core[s].sizeZ = 1; core[s].sizeT = 1; core[s].sizeC = core[s].rgb ? samples : 1; core[s].littleEndian = ifd.isLittleEndian(); core[s].indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null); core[s].imageCount = 1; core[s].pixelType = ifd.getPixelType(); core[s].interleaved = false; core[s].falseColor = false; core[s].thumbnail = s != 0; } core[s].metadataComplete = true; core[s].dimensionOrder = "XYCZT"; } vsi.close(); MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); }
/* @see loci.formats.FormatReader#initFile(String) */ protected void initFile(String id) throws FormatException, IOException { super.initFile(id); Vector<String> uniqueChannels = new Vector<String>(); Vector<Double> uniqueZs = new Vector<Double>(); Vector<Double> stageX = new Vector<Double>(); Vector<Double> stageY = new Vector<Double>(); String filename = id.substring(id.lastIndexOf(File.separator) + 1); filename = filename.substring(0, filename.indexOf(".")); boolean integerFilename = true; try { Integer.parseInt(filename); } catch (NumberFormatException e) { integerFilename = false; } if (integerFilename && ifds.size() == 1 && ifds.get(0).getIFDIntValue(IFD.NEW_SUBFILE_TYPE) == 2) { // look for other files in the dataset findTIFFs(); String stageLabel = null; for (String tiff : files) { MetamorphHandler handler = new MetamorphHandler(); parseFile(tiff, handler); String label = handler.getStageLabel(); if (stageLabel == null) { stageLabel = label; } else if (!label.equals(stageLabel)) { break; } if (!uniqueChannels.contains(handler.getChannelName())) { uniqueChannels.add(handler.getChannelName()); } Vector<Double> zPositions = handler.getZPositions(); Double pos = Math.rint(zPositions.get(0)); if (!uniqueZs.contains(pos)) { uniqueZs.add(pos); } } MetamorphHandler handler = new MetamorphHandler(); parseFile(files[files.length - 1], handler); String lastStageLabel = handler.getStageLabel(); int lastField = getField(lastStageLabel); int lastWellRow = getWellRow(lastStageLabel); int lastWellColumn = getWellColumn(lastStageLabel); int field = getField(stageLabel); int fieldRow = getWellRow(stageLabel); int fieldColumn = getWellColumn(stageLabel); wellCount = lastField - field + 1; fieldRowCount = lastWellRow - fieldRow + 1; fieldColumnCount = lastWellColumn - fieldColumn + 1; core[0].sizeC = uniqueChannels.size(); core[0].sizeZ = uniqueZs.size(); } else { files = new String[] {id}; wellCount = 1; fieldRowCount = 1; fieldColumnCount = 1; core[0].sizeC = 0; } // parse XML comment MetamorphHandler handler = new MetamorphHandler(getGlobalMetadata()); Vector<Double> xPositions = new Vector<Double>(); Vector<Double> yPositions = new Vector<Double>(); for (IFD ifd : ifds) { String xml = XMLTools.sanitizeXML(ifd.getComment()); XMLTools.parseXML(xml, handler); double x = handler.getStagePositionX(); double y = handler.getStagePositionY(); if (xPositions.size() == 0) { xPositions.add(x); yPositions.add(y); } else { double previousX = xPositions.get(xPositions.size() - 1); double previousY = yPositions.get(yPositions.size() - 1); if (Math.abs(previousX - x) > 0.21 || Math.abs(previousY - y) > 0.21) { xPositions.add(x); yPositions.add(y); } } } if (xPositions.size() > 1) { fieldRowCount = xPositions.size(); } Vector<Integer> wavelengths = handler.getWavelengths(); Vector<Double> zPositions = handler.getZPositions(); // calculate axis sizes Vector<Integer> uniqueC = new Vector<Integer>(); for (Integer c : wavelengths) { if (!uniqueC.contains(c)) { uniqueC.add(c); } } int effectiveC = uniqueC.size(); if (effectiveC == 0) effectiveC = 1; if (getSizeC() == 0) core[0].sizeC = 1; int samples = ifds.get(0).getSamplesPerPixel(); core[0].sizeC *= effectiveC * samples; Vector<Double> uniqueZ = new Vector<Double>(); for (Double z : zPositions) { if (!uniqueZ.contains(z)) uniqueZ.add(z); } if (getSizeZ() == 0) core[0].sizeZ = 1; core[0].sizeZ *= uniqueZ.size(); int totalPlanes = files.length * ifds.size(); effectiveC = getSizeC() / samples; core[0].sizeT = totalPlanes / (wellCount * fieldRowCount * fieldColumnCount * getSizeZ() * effectiveC); if (getSizeT() == 0) core[0].sizeT = 1; int seriesCount = wellCount * fieldRowCount * fieldColumnCount; if (seriesCount > 1 && getSizeZ() > totalPlanes / seriesCount) { core[0].sizeZ = 1; core[0].sizeT = totalPlanes / (seriesCount * getSizeT() * effectiveC); } core[0].imageCount = getSizeZ() * getSizeT() * effectiveC; if (seriesCount > 1) { CoreMetadata oldCore = core[0]; core = new CoreMetadata[seriesCount]; for (int i = 0; i < seriesCount; i++) { core[i] = oldCore; } } for (int s = 0; s < wellCount * fieldRowCount * fieldColumnCount; s++) { if (files.length > 1) { int[] lengths = new int[] { getSizeZ(), getEffectiveSizeC(), fieldColumnCount, fieldRowCount, wellCount, getSizeT() }; Well well = getWell(s); int[] position = new int[] {0, 0, well.fieldCol, well.fieldRow, well.well, 0}; int fileIndex = FormatTools.positionToRaster(lengths, position); parseFile(files[fileIndex], handler); stageX.add(handler.getStagePositionX()); stageY.add(handler.getStagePositionY()); } else { stageX.add(xPositions.get(s)); stageY.add(yPositions.get(s)); } } MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); store.setPlateID(MetadataTools.createLSID("Plate", 0), 0); store.setPlateRowNamingConvention(NamingConvention.LETTER, 0); store.setPlateColumnNamingConvention(NamingConvention.NUMBER, 0); for (int well = 0; well < wellCount; well++) { store.setWellID(MetadataTools.createLSID("Well", 0, well), 0, well); store.setWellRow(new NonNegativeInteger(0), 0, well); store.setWellColumn(new NonNegativeInteger(well), 0, well); for (int row = 0; row < fieldRowCount; row++) { for (int col = 0; col < fieldColumnCount; col++) { int field = row * fieldColumnCount + col; String wellSampleID = MetadataTools.createLSID("WellSample", 0, well, field); store.setWellSampleID(wellSampleID, 0, well, field); int seriesIndex = getSeriesIndex(row, col, well); String imageID = MetadataTools.createLSID("Image", seriesIndex); store.setImageID(imageID, seriesIndex); store.setWellSampleImageRef(imageID, 0, well, field); store.setWellSampleIndex(new NonNegativeInteger(seriesIndex), 0, well, field); } } } for (int s = 0; s < seriesCount; s++) { setSeries(s); Well well = getWell(s); String name = handler.getImageName(); if (seriesCount > 1) { name = "Field " + (char) (well.fieldRow + 'A') + (well.fieldCol + 1) + ", Well " + (well.well + 1) + ": " + name; } store.setImageName(name, s); String date = DateTools.formatDate(handler.getDate(), DateTools.ISO8601_FORMAT); store.setImageAcquiredDate(date, s); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { Vector<String> timestamps = handler.getTimestamps(); Vector<Double> exposures = handler.getExposures(); for (int i = 0; i < timestamps.size(); i++) { long timestamp = DateTools.getTime(timestamps.get(i), DATE_FORMAT); addSeriesMeta("timestamp " + i, timestamp); } for (int i = 0; i < exposures.size(); i++) { addSeriesMeta("exposure time " + i + " (ms)", exposures.get(i).floatValue() * 1000); } long startDate = 0; if (timestamps.size() > 0) { startDate = DateTools.getTime(timestamps.get(0), DATE_FORMAT); } store.setImageDescription("", s); int image = 0; for (int c = 0; c < getEffectiveSizeC(); c++) { for (int t = 0; t < getSizeT(); t++) { store.setPlaneTheZ(new NonNegativeInteger(0), s, image); store.setPlaneTheC(new NonNegativeInteger(c), s, image); store.setPlaneTheT(new NonNegativeInteger(t), s, image); if (t < timestamps.size()) { String stamp = timestamps.get(t); long ms = DateTools.getTime(stamp, DATE_FORMAT); store.setPlaneDeltaT((ms - startDate) / 1000.0, s, image); } if (image < exposures.size()) { store.setPlaneExposureTime(exposures.get(image), s, image); } if (s < stageX.size()) { store.setPlanePositionX(stageX.get(s), s, image); } if (s < stageY.size()) { store.setPlanePositionY(stageY.get(s), s, image); } image++; } } store.setImagingEnvironmentTemperature(handler.getTemperature(), s); store.setPixelsPhysicalSizeX(new PositiveFloat(handler.getPixelSizeX()), s); store.setPixelsPhysicalSizeY(new PositiveFloat(handler.getPixelSizeY()), s); for (int c = 0; c < getEffectiveSizeC(); c++) { if (uniqueChannels.size() > c) { store.setChannelName(uniqueChannels.get(c), s, c); } else store.setChannelName(handler.getChannelName(), s, c); } } } }
/* @see BaseTiffReader#initStandardMetadata() */ @Override protected void initStandardMetadata() throws FormatException, IOException { super.initStandardMetadata(); CoreMetadata m = core.get(0); m.sizeZ = 0; m.sizeT = 0; MetadataLevel level = getMetadataOptions().getMetadataLevel(); for (IFD ifd : ifds) { if (level != MetadataLevel.MINIMUM) { short[] tag1 = (short[]) ifd.getIFDValue(IMAGE_PRO_TAG_1); if (tag1 != null) { String seqId = ""; for (int i = 0; i < tag1.length; i++) seqId = seqId + tag1[i]; addGlobalMeta("Image-Pro SEQ ID", seqId); } } int tag2 = ifds.get(0).getIFDIntValue(IMAGE_PRO_TAG_2); if (tag2 != -1) { // should be one of these for every image plane m.sizeZ++; addGlobalMeta("Frame Rate", tag2); } addGlobalMeta("Number of images", getSizeZ()); } if (getSizeZ() == 0) m.sizeZ = 1; if (getSizeT() == 0) m.sizeT = 1; if (getSizeZ() == 1 && getSizeT() == 1) { m.sizeZ = ifds.size(); } // default values addGlobalMeta("frames", getSizeZ()); addGlobalMeta("channels", super.getSizeC()); addGlobalMeta("slices", getSizeT()); // parse the description to get channels, slices and times where applicable String descr = ifds.get(0).getComment(); metadata.remove("Comment"); if (descr != null) { String[] lines = descr.split("\n"); for (String token : lines) { token = token.trim(); int eq = token.indexOf("="); if (eq == -1) eq = token.indexOf(":"); if (eq != -1) { String label = token.substring(0, eq); String data = token.substring(eq + 1); addGlobalMeta(label, data); if (label.equals("channels")) m.sizeC = Integer.parseInt(data); else if (label.equals("frames")) { m.sizeT = Integer.parseInt(data); } else if (label.equals("slices")) { m.sizeZ = Integer.parseInt(data); } } } } if (isRGB() && getSizeC() != 3) m.sizeC *= 3; m.dimensionOrder = "XY"; int maxNdx = 0, max = 0; int[] dims = {getSizeZ(), getSizeC(), getSizeT()}; String[] axes = {"Z", "C", "T"}; for (int i = 0; i < dims.length; i++) { if (dims[i] > max) { max = dims[i]; maxNdx = i; } } m.dimensionOrder += axes[maxNdx]; if (maxNdx != 1) { if (getSizeC() > 1) { m.dimensionOrder += "C"; m.dimensionOrder += (maxNdx == 0 ? axes[2] : axes[0]); } else m.dimensionOrder += (maxNdx == 0 ? axes[2] : axes[0]) + "C"; } else { if (getSizeZ() > getSizeT()) m.dimensionOrder += "ZT"; else m.dimensionOrder += "TZ"; } }
/* @see loci.formats.in.BaseTiffReader#initStandardMetadata() */ protected void initStandardMetadata() throws FormatException, IOException { super.initStandardMetadata(); ifds = tiffParser.getIFDs(); for (IFD ifd : ifds) { tiffParser.fillInIFD(ifd); } String comment = ifds.get(0).getComment(); String[] values = comment.split(";"); for (String v : values) { int eq = v.indexOf("="); if (eq < 0) continue; String key = v.substring(0, eq).trim(); String value = v.substring(eq + 1).trim(); addGlobalMeta(key, value); if (key.equals("OverlapsXY")) { String[] overlapValues = value.split(" "); overlaps = new int[ifds.size() * 2]; for (int i = 0; i < overlapValues.length; i++) { overlaps[i] = Integer.parseInt(overlapValues[i]); } } } core = new CoreMetadata[ifds.size()]; for (int i = 0; i < core.length; i++) { setSeries(i); core[i] = new CoreMetadata(); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {} } setSeries(0); // repopulate core metadata for (int s = 0; s < core.length; s++) { IFD ifd = ifds.get(s); PhotoInterp p = ifd.getPhotometricInterpretation(); int samples = ifd.getSamplesPerPixel(); core[s].rgb = samples > 1 || p == PhotoInterp.RGB; long numTileRows = ifd.getTilesPerColumn() - 1; long numTileCols = ifd.getTilesPerRow() - 1; int overlapX = overlaps[s * 2]; int overlapY = overlaps[s * 2 + 1]; core[s].sizeX = (int) (ifd.getImageWidth() - (numTileCols * overlapX)); core[s].sizeY = (int) (ifd.getImageLength() - (numTileRows * overlapY)); core[s].sizeZ = 1; core[s].sizeT = 1; core[s].sizeC = core[s].rgb ? samples : 1; core[s].littleEndian = ifd.isLittleEndian(); core[s].indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null); core[s].imageCount = 1; core[s].pixelType = ifd.getPixelType(); core[s].metadataComplete = true; core[s].interleaved = false; core[s].falseColor = false; core[s].dimensionOrder = "XYCZT"; core[s].thumbnail = s > 0; } // look for all of the other associated metadata files files = new ArrayList<String>(); Location baseFile = new Location(currentId).getAbsoluteFile(); Location parent = baseFile.getParentFile(); String name = baseFile.getName(); if (name.indexOf(".") >= 0) { name = name.substring(0, name.indexOf(".") + 1); } roiFile = new Location(parent, name + "ROI").getAbsolutePath(); roiDrawFile = new Location(parent, name + "ROI-draw").getAbsolutePath(); String[] list = parent.list(true); for (String f : list) { if (!f.equals(baseFile.getName())) { files.add(new Location(parent, f).getAbsolutePath()); } } }