Search in sources :

Example 51 with TiffParser

use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.

the class FlowSightReader method initFile.

/* (non-Javadoc)
   * @see loci.formats.FormatReader#initFile(java.lang.String)
   */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    in = new RandomAccessInputStream(id);
    tiffParser = new TiffParser(in);
    tiffParser.setDoCaching(false);
    tiffParser.setUse64BitOffsets(false);
    final Boolean littleEndian = tiffParser.checkHeader();
    if (littleEndian == null) {
        throw new FormatException("Invalid FlowSight file");
    }
    final boolean little = littleEndian.booleanValue();
    in.order(little);
    LOGGER.info("Reading IFDs");
    ifdOffsets = tiffParser.getIFDOffsets();
    if (ifdOffsets.length < 2) {
        throw new FormatException("No IFDs found");
    }
    LOGGER.info("Populating metadata");
    /*
     * The first IFD contains file-scope metadata
     */
    final IFD ifd0 = tiffParser.getFirstIFD();
    tiffParser.fillInIFD(ifd0);
    int channelCount = ifd0.getIFDIntValue(CHANNEL_COUNT_TAG, 1);
    final String channelNamesString = ifd0.getIFDStringValue(CHANNEL_NAMES_TAG);
    if (channelNamesString != null) {
        channelNames = channelNamesString.split("\\|");
        if (channelNames.length != channelCount) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Channel count (%d) does not match number of " + "channel names (%d) in string \"%s\"", channelCount, channelNames.length, channelNamesString);
            }
            channelCount = channelNames.length;
        }
        LOGGER.debug("Found {} channels: {}", channelCount, channelNamesString.replace('|', ','));
    }
    final String channelDescsString = ifd0.getIFDStringValue(CHANNEL_DESCS_TAG);
    if (channelDescsString != null) {
        channelDescs = channelDescsString.split("\\|");
        if (channelDescs.length != channelCount) {
            throw new FormatException(String.format("Channel count (%d) does not match number of channel descriptions (%d) in string \"%s\"", channelCount, channelDescs.length, channelDescsString));
        }
    }
    String xml = ifd0.getIFDTextValue(METADATA_XML_TAG);
    xml = XMLTools.sanitizeXML(xml);
    try {
        Element xmlRoot = XMLTools.parseDOM(xml).getDocumentElement();
        NodeList imagingNodes = xmlRoot.getElementsByTagName("Imaging");
        if (imagingNodes.getLength() > 0) {
            Element imagingNode = (Element) imagingNodes.item(0);
            NodeList children = imagingNode.getChildNodes();
            for (int child = 0; child < children.getLength(); child++) {
                Node childNode = children.item(child);
                String name = childNode.getNodeName();
                if (name.startsWith("ChannelInUseIndicators")) {
                    channelCount = 0;
                    String text = childNode.getTextContent();
                    String[] tokens = text.split(" ");
                    for (String token : tokens) {
                        if (token.equals("1")) {
                            channelCount++;
                        }
                    }
                }
            }
        }
    } catch (ParserConfigurationException e) {
        LOGGER.debug("Could not parse XML", e);
    } catch (SAXException e) {
        LOGGER.debug("Could not parse XML", e);
    }
    /*
     * Scan the remaining IFDs
     * 
     * Unfortunately, each image can have a different width and height
     * and the images and masks have a different bit depth, so in the
     * OME scheme of things, we get one series per plane.
     */
    for (int idxOff = 1; idxOff < ifdOffsets.length; idxOff++) {
        // TODO: Record the channel names
        final long offset = ifdOffsets[idxOff];
        final boolean first = (idxOff == 1);
        final IFD ifd = tiffParser.getIFD(offset);
        tiffParser.fillInIFD(ifd);
        CoreMetadata ms = first ? core.get(0) : new CoreMetadata();
        ms.rgb = false;
        ms.interleaved = false;
        ms.littleEndian = ifd0.isLittleEndian();
        ms.sizeX = (int) ifd.getImageWidth() / channelCount;
        ms.sizeY = (int) ifd.getImageLength();
        ms.sizeZ = 1;
        ms.sizeC = channelCount;
        ms.sizeT = 1;
        ms.indexed = false;
        ms.dimensionOrder = "XYCZT";
        ms.bitsPerPixel = ifd.getIFDIntValue(IFD.BITS_PER_SAMPLE);
        ms.pixelType = (ms.bitsPerPixel == 8) ? FormatTools.UINT8 : FormatTools.UINT16;
        ms.imageCount = channelCount;
        ms.resolutionCount = 1;
        ms.thumbnail = false;
        ms.metadataComplete = true;
        if (!first) {
            core.add(ms);
        }
    }
    /*
     * Run through the metadata store, setting the channel names
     * for all the series.
     */
    final MetadataStore store = getMetadataStore();
    MetadataTools.populatePixels(store, this);
    if (channelNames != null && channelDescs != null) {
        String[] maskDescs = new String[channelCount];
        for (int i = 0; i < channelCount; i++) {
            maskDescs[i] = channelDescs[i] + " Mask";
        }
        for (int series = 0; series < ifdOffsets.length - 1; series++) {
            final boolean isMask = core.get(series).pixelType == FormatTools.UINT8;
            String[] descs = isMask ? maskDescs : channelDescs;
            for (int channel = 0; channel < channelCount; channel++) {
                store.setChannelName(descs[channel], series, channel);
                String cid = MetadataTools.createLSID("Channel", series, channel) + ":";
                store.setChannelID(cid + channelNames[channel], series, channel);
            }
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) SAXException(org.xml.sax.SAXException) MetadataStore(loci.formats.meta.MetadataStore) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Example 52 with TiffParser

use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.

the class FlowSightReader method reopenFile.

@Override
public void reopenFile() throws IOException {
    super.reopenFile();
    tiffParser = new TiffParser(in);
    tiffParser.setDoCaching(false);
    tiffParser.setUse64BitOffsets(false);
}
Also used : TiffParser(loci.formats.tiff.TiffParser)

Example 53 with TiffParser

use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.

the class MicromanagerReader method parsePosition.

// -- Helper methods --
private void parsePosition(int posIndex) throws IOException, FormatException {
    Position p = positions.get(posIndex);
    String s = DataTools.readFile(p.metadataFile);
    parsePosition(s, posIndex);
    buildTIFFList(posIndex);
    // parse original metadata from each TIFF's JSON
    p.positions = new Double[p.tiffs.size()][3];
    int digits = String.valueOf(p.tiffs.size() - 1).length();
    boolean parseMMJSONTag = true;
    for (int plane = 0; plane < p.tiffs.size(); ) {
        String path = p.tiffs.get(plane);
        // file ordering is correct
        if (p.tiffs.size() == p.fileNameMap.size() && plane < getImageCount()) {
            path = p.getFile(plane);
        }
        if (path == null || !new Location(path).exists()) {
            plane++;
            continue;
        }
        try {
            TiffParser parser = new TiffParser(path);
            int nIFDs = parser.getIFDs().size();
            IFD firstIFD = parser.getFirstIFD();
            parser.fillInIFD(firstIFD);
            // ensure that the plane dimensions and pixel type are correct
            CoreMetadata ms = core.get(posIndex);
            ms.sizeX = (int) firstIFD.getImageWidth();
            ms.sizeY = (int) firstIFD.getImageLength();
            ms.pixelType = firstIFD.getPixelType();
            ms.littleEndian = firstIFD.isLittleEndian();
            String json = firstIFD.getIFDTextValue(JSON_TAG);
            if (json != null) {
                String[] lines = json.split("\n");
                for (String line : lines) {
                    String toSplit = line.trim();
                    if (toSplit.length() == 0) {
                        continue;
                    }
                    toSplit = toSplit.substring(0, toSplit.length() - 1);
                    String[] values = toSplit.split("\": ");
                    if (values.length < 2) {
                        continue;
                    }
                    String key = values[0].replaceAll("\"", "");
                    String value = values[1].replaceAll("\"", "");
                    if (key.length() > 0 && value.length() > 0) {
                        parseKeyAndValue(key, value, digits, plane * nIFDs, nIFDs);
                    }
                }
            }
            IFDList ifds = parser.getIFDs();
            for (int i = 0; i < ifds.size(); i++) {
                if (!parseMMJSONTag) {
                    break;
                }
                IFD ifd = ifds.get(i);
                parser.fillInIFD(ifd);
                json = ifd.getIFDTextValue(MM_JSON_TAG);
                LOGGER.trace("JSON for IFD #{} = {}", i, json);
                if (json == null) {
                    // if one of the files is missing the per-plane JSON tag,
                    // assume all files are missing it (for performance)
                    parseMMJSONTag = false;
                    break;
                }
                String[] tokens = json.split("[\\{\\}:,\"]");
                String key = null, value = null, propType = null;
                int nEmptyTokens = 0;
                for (int q = 0; q < tokens.length; q++) {
                    String token = tokens[q];
                    if (token.length() == 0) {
                        nEmptyTokens++;
                        continue;
                    }
                    if (nEmptyTokens == 5 && value == null) {
                        key = null;
                    }
                    if (key == null && value == null && propType == null) {
                        // don't use completeCoords as a key, defer to child attributes
                        if (!token.equals("completeCoords")) {
                            key = token;
                        }
                        nEmptyTokens = 0;
                    } else if (token.equals("PropVal") || token.equals("[")) {
                        value = token;
                    } else if (token.equals("PropType")) {
                        propType = token;
                    } else if (value != null && value.equals("PropVal") && propType == null) {
                        value = token;
                    } else if (value != null && propType == null && value.startsWith("[") && !token.startsWith("]")) {
                        value += token;
                        value += ", ";
                    } else if (((propType != null && propType.equals("PropType")) || token.equals("]")) || (key != null && value == null)) {
                        if (value == null && (propType == null || !propType.equals("PropType"))) {
                            StringBuilder sb = new StringBuilder(token);
                            while (q + 1 < tokens.length && tokens[q + 1].trim().length() > 0) {
                                sb.append(':');
                                sb.append(tokens[q + 1]);
                                q++;
                            }
                            value = sb.toString();
                        }
                        if (!value.equals("PropVal")) {
                            parseKeyAndValue(key, value, digits, plane + i, 1);
                        }
                        propType = null;
                        key = null;
                        value = null;
                        nEmptyTokens = 0;
                    }
                }
            }
            plane += ifds.size();
            parser.getStream().close();
        } catch (IOException e) {
            LOGGER.debug("Failed to read metadata from " + path, e);
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) IOException(java.io.IOException) CoreMetadata(loci.formats.CoreMetadata) Location(loci.common.Location)

Example 54 with TiffParser

use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.

the class FV1000Reader method getOptimalTileWidth.

// -- IFormatReader API methods --
/* @see loci.formats.IFormatReader#getOptimalTileWidth() */
@Override
public int getOptimalTileWidth() {
    FormatTools.assertId(currentId, true, 1);
    RandomAccessInputStream plane = getPlane(getSeries(), 0);
    if (plane == null)
        return super.getOptimalTileWidth();
    try {
        TiffParser tp = new TiffParser(plane);
        IFD ifd = tp.getFirstIFD();
        plane.close();
        return (int) ifd.getTileWidth();
    } catch (FormatException e) {
        LOGGER.debug("Could not retrieve tile width", e);
    } catch (IOException e) {
        LOGGER.debug("Could not retrieve tile width", e);
    }
    return super.getOptimalTileWidth();
}
Also used : IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) IOException(java.io.IOException) FormatException(loci.formats.FormatException)

Example 55 with TiffParser

use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.

the class FV1000Reader method getOptimalTileHeight.

/* @see loci.formats.IFormatReader#getOptimalTileHeight() */
@Override
public int getOptimalTileHeight() {
    FormatTools.assertId(currentId, true, 1);
    RandomAccessInputStream plane = getPlane(getSeries(), 0);
    if (plane == null)
        return super.getOptimalTileHeight();
    try {
        TiffParser tp = new TiffParser(plane);
        IFD ifd = tp.getFirstIFD();
        plane.close();
        return (int) ifd.getTileLength();
    } catch (FormatException e) {
        LOGGER.debug("Could not retrieve tile height", e);
    } catch (IOException e) {
        LOGGER.debug("Could not retrieve tile height", e);
    }
    return super.getOptimalTileHeight();
}
Also used : IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) IOException(java.io.IOException) FormatException(loci.formats.FormatException)

Aggregations

TiffParser (loci.formats.tiff.TiffParser)96 IFD (loci.formats.tiff.IFD)74 RandomAccessInputStream (loci.common.RandomAccessInputStream)56 FormatException (loci.formats.FormatException)26 CoreMetadata (loci.formats.CoreMetadata)19 IOException (java.io.IOException)18 IFDList (loci.formats.tiff.IFDList)16 Location (loci.common.Location)15 MetadataStore (loci.formats.meta.MetadataStore)15 ArrayList (java.util.ArrayList)12 Timestamp (ome.xml.model.primitives.Timestamp)9 Length (ome.units.quantity.Length)8 PhotoInterp (loci.formats.tiff.PhotoInterp)6 File (java.io.File)5 HashMap (java.util.HashMap)5 ServiceException (loci.common.services.ServiceException)4 Time (ome.units.quantity.Time)4 NonNegativeInteger (ome.xml.model.primitives.NonNegativeInteger)4 List (java.util.List)3 ByteArrayHandle (loci.common.ByteArrayHandle)3