Search in sources :

Example 21 with IFDList

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

the class FlexReader method groupFiles.

private void groupFiles(String[] fileList, MetadataStore store) throws FormatException, IOException {
    LOGGER.info("Grouping together files in the same dataset");
    HashMap<String, ArrayList<String>> v = new HashMap<String, ArrayList<String>>();
    Boolean firstCompressed = null;
    int firstIFDCount = 0;
    for (String file : fileList) {
        LOGGER.warn("parsing {}", file);
        RandomAccessInputStream s = new RandomAccessInputStream(file, 16);
        TiffParser parser = new TiffParser(s);
        IFD firstIFD = parser.getFirstIFD();
        int ifdCount = parser.getIFDOffsets().length;
        s.close();
        boolean compressed = firstIFD.getCompression() != TiffCompression.UNCOMPRESSED;
        if (firstCompressed == null) {
            firstCompressed = compressed;
            firstIFDCount = ifdCount;
        }
        if (compressed == firstCompressed && ifdCount == firstIFDCount) {
            int[] well = getWell(file);
            int field = getField(file);
            if (well[0] > nRows)
                nRows = well[0];
            if (well[1] > nCols)
                nCols = well[1];
            if (fileList.length == 1) {
                well[0] = 0;
                well[1] = 0;
            }
            ArrayList<String> files = v.get(well[0] + "," + well[1]);
            if (files == null) {
                files = new ArrayList<String>();
            }
            files.add(file);
            v.put(well[0] + "," + well[1], files);
        } else {
            v.clear();
            ArrayList<String> files = new ArrayList<String>();
            files.add(currentId);
            v.put("0,0", files);
            fileList = new String[] { currentId };
            break;
        }
    }
    nRows++;
    nCols++;
    if (fileList.length == 1) {
        nRows = 1;
        nCols = 1;
    }
    LOGGER.debug("Determined that there are {} rows and {} columns of wells.", nRows, nCols);
    flexFiles = new ArrayList<FlexFile>();
    wellCount = v.size();
    wellNumber = new int[wellCount][2];
    RandomAccessInputStream s = null;
    boolean firstFile = true;
    boolean compressed = false;
    int nOffsets = 1;
    int currentWell = 0;
    for (int row = 0; row < nRows; row++) {
        for (int col = 0; col < nCols; col++) {
            ArrayList<String> files = v.get(row + "," + col);
            if (files == null) {
                continue;
            }
            nFiles = files.size();
            String[] sortedFiles = files.toArray(new String[files.size()]);
            Arrays.sort(sortedFiles);
            files.clear();
            for (String f : sortedFiles) {
                files.add(f);
            }
            for (int field = 0; field < nFiles; field++) {
                FlexFile file = new FlexFile();
                file.row = row;
                file.column = col;
                file.field = field;
                file.file = files.get(field);
                if (file.file == null) {
                    continue;
                }
                wellNumber[currentWell][0] = row;
                wellNumber[currentWell][1] = col;
                s = new RandomAccessInputStream(getFileHandle(file.file));
                TiffParser tp = new TiffParser(s);
                if (compressed || firstFile) {
                    LOGGER.info("Parsing IFDs for well {}{}", (char) (row + 'A'), col + 1);
                    IFD firstIFD = tp.getFirstIFD();
                    compressed = firstIFD.getCompression() != TiffCompression.UNCOMPRESSED;
                    if (compressed || firstIFD.getStripOffsets()[0] == 16 || firstIFD.getStripOffsets().length == 1) {
                        tp.setDoCaching(false);
                        file.ifds = tp.getIFDs();
                        file.ifds.set(0, firstIFD);
                        if (firstIFD.getStripOffsets().length == 1) {
                            // used to ensure that image offsets are read, not calculated
                            compressed = true;
                        }
                    } else {
                        // if the pixel data is uncompressed and the IFD is stored
                        // before the image, we can assume that
                        // the pixel data for image #0 is located immediately before
                        // IFD #1; as a result, we only need to parse the first IFD
                        file.offsets = tp.getIFDOffsets();
                        nOffsets = file.offsets.length;
                        file.ifds = new IFDList();
                        file.ifds.add(firstIFD);
                    }
                } else {
                    // retrieve the offsets to each IFD, instead of parsing
                    // all of the IFDs
                    LOGGER.info("Retrieving IFD offsets for well {}{}", (char) (row + 'A'), col + 1);
                    file.offsets = new long[nOffsets];
                    // Assume that all IFDs after the first are evenly spaced.
                    // TiffParser.getIFDOffsets() could be used instead, but is
                    // substantially slower.
                    file.offsets[0] = tp.getFirstOffset();
                    if (file.offsets.length > 1) {
                        s.seek(file.offsets[0]);
                        s.skipBytes(s.readShort() * TiffConstants.BYTES_PER_ENTRY);
                        file.offsets[1] = s.readInt();
                        int size = FormatTools.getPlaneSize(this) + 174;
                        for (int i = 2; i < file.offsets.length; i++) {
                            file.offsets[i] = file.offsets[i - 1] + size;
                        }
                    }
                }
                flexFiles.add(file);
                // setting a negative field index indicates that the field count
                // should be taken from the XML
                parseFlexFile(currentWell, row, col, nFiles == 1 ? -1 : field, firstFile, store);
                s.close();
                if (firstFile)
                    firstFile = false;
            }
            currentWell++;
        }
    }
}
Also used : HashMap(java.util.HashMap) IFD(loci.formats.tiff.IFD) ArrayList(java.util.ArrayList) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 22 with IFDList

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

the class GelReader method initMetadata.

// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initMetadata() */
@Override
protected void initMetadata() throws FormatException, IOException {
    ifds = tiffParser.getIFDs();
    if (ifds.size() > 1) {
        IFDList tmpIFDs = ifds;
        ifds = new IFDList();
        for (int i = 0; i < tmpIFDs.size() / 2; i++) {
            IFD ifd = new IFD();
            ifds.add(ifd);
            ifd.putAll(tmpIFDs.get(i * 2 + 1));
            ifd.putAll(tmpIFDs.get(i * 2));
            tiffParser.fillInIFD(ifd);
        }
    }
    IFD firstIFD = ifds.get(0);
    tiffParser.fillInIFD(firstIFD);
    super.initStandardMetadata();
    fmt = firstIFD.getIFDLongValue(MD_FILETAG, LINEAR);
    if (fmt == SQUARE_ROOT)
        core.get(0).pixelType = FormatTools.FLOAT;
    TiffRational scale = (TiffRational) firstIFD.getIFDValue(MD_SCALE_PIXEL);
    if (scale == null)
        scale = new TiffRational(1, 1);
    core.get(0).imageCount = ifds.size();
    core.get(0).sizeT = getImageCount();
    // ignore MD_COLOR_TABLE
    String info = firstIFD.getIFDStringValue(MD_SAMPLE_INFO);
    String prepDate = firstIFD.getIFDStringValue(MD_PREP_DATE);
    String prepTime = firstIFD.getIFDStringValue(MD_PREP_TIME);
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        String units = firstIFD.getIFDStringValue(MD_FILE_UNITS);
        String lab = firstIFD.getIFDStringValue(MD_LAB_NAME);
        addGlobalMeta("Scale factor", scale);
        addGlobalMeta("Lab name", lab);
        addGlobalMeta("Sample info", info);
        addGlobalMeta("Date prepared", prepDate);
        addGlobalMeta("Time prepared", prepTime);
        addGlobalMeta("File units", units);
        addGlobalMeta("Data format", fmt == SQUARE_ROOT ? "square root" : "linear");
    }
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
    String parsedDate = DateTools.formatDate(prepDate, FORMATS);
    String parsedTime = DateTools.formatDate(prepTime, FORMATS);
    if (parsedDate != null) {
        store.setImageAcquisitionDate(new Timestamp(parsedDate), 0);
    } else if (parsedTime != null) {
        store.setImageAcquisitionDate(new Timestamp(parsedTime), 0);
    }
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        Double pixelSize = new Double(scale.doubleValue());
        Length sizeX = FormatTools.getPhysicalSizeX(pixelSize);
        Length sizeY = FormatTools.getPhysicalSizeY(pixelSize);
        if (sizeX != null) {
            store.setPixelsPhysicalSizeX(sizeX, 0);
        }
        if (sizeY != null) {
            store.setPixelsPhysicalSizeY(sizeY, 0);
        }
    }
}
Also used : MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) IFD(loci.formats.tiff.IFD) IFDList(loci.formats.tiff.IFDList) TiffRational(loci.formats.tiff.TiffRational) Timestamp(ome.xml.model.primitives.Timestamp)

Example 23 with IFDList

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

the class ImarisTiffReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    // hack up the IFDs
    // 
    // Imaris TIFFs store a thumbnail in the first IFD; each of the remaining
    // IFDs defines a stack of tiled planes.
    // MinimalTiffReader.initFile(String) removes thumbnail IFDs.
    LOGGER.info("Verifying IFD sanity");
    IFDList tmp = new IFDList();
    for (IFD ifd : ifds) {
        long[] byteCounts = ifd.getStripByteCounts();
        long[] offsets = ifd.getStripOffsets();
        for (int i = 0; i < byteCounts.length; i++) {
            IFD t = new IFD(ifd);
            t.putIFDValue(IFD.TILE_BYTE_COUNTS, byteCounts[i]);
            t.putIFDValue(IFD.TILE_OFFSETS, offsets[i]);
            tmp.add(t);
        }
    }
    String comment = ifds.get(0).getComment();
    LOGGER.info("Populating metadata");
    CoreMetadata m = core.get(0);
    m.sizeC = ifds.size();
    m.sizeZ = tmp.size() / getSizeC();
    m.sizeT = 1;
    m.sizeX = (int) ifds.get(0).getImageWidth();
    m.sizeY = (int) ifds.get(0).getImageLength();
    ifds = tmp;
    m.imageCount = getSizeC() * getSizeZ();
    m.dimensionOrder = "XYZCT";
    m.interleaved = false;
    m.rgb = getImageCount() != getSizeZ() * getSizeC() * getSizeT();
    m.pixelType = ifds.get(0).getPixelType();
    LOGGER.info("Parsing comment");
    // likely an INI-style comment, although we can't be sure
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        String description = null, creationDate = null;
        final List<Double> emWave = new ArrayList<Double>();
        final List<Double> exWave = new ArrayList<Double>();
        final List<String> channelNames = new ArrayList<String>();
        if (comment != null && comment.startsWith("[")) {
            // parse key/value pairs
            StringTokenizer st = new StringTokenizer(comment, "\n");
            while (st.hasMoreTokens()) {
                String line = st.nextToken();
                int equals = line.indexOf('=');
                if (equals < 0)
                    continue;
                String key = line.substring(0, equals).trim();
                String value = line.substring(equals + 1).trim();
                addGlobalMeta(key, value);
                if (key.equals("Description")) {
                    description = value;
                } else if (key.equals("LSMEmissionWavelength") && !value.equals("0")) {
                    emWave.add(new Double(value));
                } else if (key.equals("LSMExcitationWavelength") && !value.equals("0")) {
                    exWave.add(new Double(value));
                } else if (key.equals("Name") && !currentId.endsWith(value)) {
                    channelNames.add(value);
                } else if (key.equals("RecordingDate")) {
                    value = value.replaceAll(" ", "T");
                    creationDate = value.substring(0, value.indexOf('.'));
                }
            }
            metadata.remove("Comment");
        }
        // populate Image data
        store.setImageDescription(description, 0);
        if (creationDate != null) {
            store.setImageAcquisitionDate(new Timestamp(creationDate), 0);
        }
        // populate LogicalChannel data
        for (int i = 0; i < emWave.size(); i++) {
            Length emission = FormatTools.getEmissionWavelength(emWave.get(i));
            Length excitation = FormatTools.getExcitationWavelength(exWave.get(i));
            if (emission != null) {
                store.setChannelEmissionWavelength(emission, 0, i);
            }
            if (excitation != null) {
                store.setChannelExcitationWavelength(excitation, 0, i);
            }
            store.setChannelName(channelNames.get(i), 0, i);
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) ArrayList(java.util.ArrayList) CoreMetadata(loci.formats.CoreMetadata) Timestamp(ome.xml.model.primitives.Timestamp) MetadataStore(loci.formats.meta.MetadataStore) StringTokenizer(java.util.StringTokenizer) Length(ome.units.quantity.Length) IFDList(loci.formats.tiff.IFDList)

Aggregations

IFDList (loci.formats.tiff.IFDList)23 IFD (loci.formats.tiff.IFD)20 RandomAccessInputStream (loci.common.RandomAccessInputStream)15 CoreMetadata (loci.formats.CoreMetadata)15 TiffParser (loci.formats.tiff.TiffParser)15 MetadataStore (loci.formats.meta.MetadataStore)12 ArrayList (java.util.ArrayList)9 FormatException (loci.formats.FormatException)9 IOException (java.io.IOException)8 Length (ome.units.quantity.Length)8 Timestamp (ome.xml.model.primitives.Timestamp)8 PhotoInterp (loci.formats.tiff.PhotoInterp)7 Location (loci.common.Location)6 TiffRational (loci.formats.tiff.TiffRational)5 Time (ome.units.quantity.Time)5 HashMap (java.util.HashMap)3 File (java.io.File)2 List (java.util.List)2 Map (java.util.Map)2 StringTokenizer (java.util.StringTokenizer)2