Search in sources :

Example 11 with CoreMetadata

use of loci.formats.CoreMetadata in project bioformats by openmicroscopy.

the class MetamorphReader method initStandardMetadata.

// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
    super.initStandardMetadata();
    CoreMetadata ms0 = core.get(0);
    ms0.sizeZ = 1;
    ms0.sizeT = 0;
    int rgbChannels = getSizeC();
    // Now that the base TIFF standard metadata has been parsed, we need to
    // parse out the STK metadata from the UIC4TAG.
    TiffIFDEntry uic1tagEntry = null;
    TiffIFDEntry uic2tagEntry = null;
    TiffIFDEntry uic4tagEntry = null;
    try {
        uic1tagEntry = tiffParser.getFirstIFDEntry(UIC1TAG);
        uic2tagEntry = tiffParser.getFirstIFDEntry(UIC2TAG);
        uic4tagEntry = tiffParser.getFirstIFDEntry(UIC4TAG);
    } catch (IllegalArgumentException exc) {
        LOGGER.debug("Unknown tag", exc);
    }
    try {
        if (uic4tagEntry != null) {
            mmPlanes = uic4tagEntry.getValueCount();
        }
        if (mmPlanes == 0) {
            mmPlanes = ifds.size();
        }
        if (uic2tagEntry != null) {
            parseUIC2Tags(uic2tagEntry.getValueOffset());
        }
        if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
            if (uic4tagEntry != null) {
                parseUIC4Tags(uic4tagEntry.getValueOffset());
            }
            if (uic1tagEntry != null) {
                parseUIC1Tags(uic1tagEntry.getValueOffset(), uic1tagEntry.getValueCount());
            }
        }
        in.seek(uic4tagEntry.getValueOffset());
    } catch (NullPointerException exc) {
        LOGGER.debug("", exc);
    } catch (IOException exc) {
        LOGGER.debug("Failed to parse proprietary tags", exc);
    }
    try {
        // copy ifds into a new array of Hashtables that will accommodate the
        // additional image planes
        IFD firstIFD = ifds.get(0);
        long[] uic2 = firstIFD.getIFDLongArray(UIC2TAG);
        if (uic2 == null) {
            throw new FormatException("Invalid Metamorph file. Tag " + UIC2TAG + " not found.");
        }
        ms0.imageCount = uic2.length;
        Object entry = firstIFD.getIFDValue(UIC3TAG);
        TiffRational[] uic3 = entry instanceof TiffRational[] ? (TiffRational[]) entry : new TiffRational[] { (TiffRational) entry };
        wave = new double[uic3.length];
        final List<Double> uniqueWavelengths = new ArrayList<Double>();
        for (int i = 0; i < uic3.length; i++) {
            wave[i] = uic3[i].doubleValue();
            addSeriesMeta("Wavelength [" + intFormatMax(i, mmPlanes) + "]", wave[i]);
            final Double v = wave[i];
            if (!uniqueWavelengths.contains(v))
                uniqueWavelengths.add(v);
        }
        if (getSizeC() == 1) {
            ms0.sizeC = uniqueWavelengths.size();
            if (getSizeC() < getImageCount() && getSizeC() > (getImageCount() - getSizeC()) && (getImageCount() % getSizeC()) != 0) {
                ms0.sizeC = getImageCount();
            }
        }
        IFDList tempIFDs = new IFDList();
        long[] oldOffsets = firstIFD.getStripOffsets();
        long[] stripByteCounts = firstIFD.getStripByteCounts();
        int rowsPerStrip = (int) firstIFD.getRowsPerStrip()[0];
        int stripsPerImage = getSizeY() / rowsPerStrip;
        if (stripsPerImage * rowsPerStrip != getSizeY())
            stripsPerImage++;
        PhotoInterp check = firstIFD.getPhotometricInterpretation();
        if (check == PhotoInterp.RGB_PALETTE) {
            firstIFD.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION, PhotoInterp.BLACK_IS_ZERO);
        }
        emWavelength = firstIFD.getIFDLongArray(UIC3TAG);
        // for each image plane, construct an IFD hashtable
        IFD temp;
        for (int i = 0; i < getImageCount(); i++) {
            // copy data from the first IFD
            temp = new IFD(firstIFD);
            // now we need a StripOffsets entry - the original IFD doesn't have this
            long[] newOffsets = new long[stripsPerImage];
            if (stripsPerImage * (i + 1) <= oldOffsets.length) {
                System.arraycopy(oldOffsets, stripsPerImage * i, newOffsets, 0, stripsPerImage);
            } else {
                System.arraycopy(oldOffsets, 0, newOffsets, 0, stripsPerImage);
                long image = (stripByteCounts[0] / rowsPerStrip) * getSizeY();
                for (int q = 0; q < stripsPerImage; q++) {
                    newOffsets[q] += i * image;
                }
            }
            temp.putIFDValue(IFD.STRIP_OFFSETS, newOffsets);
            long[] newByteCounts = new long[stripsPerImage];
            if (stripsPerImage * i < stripByteCounts.length) {
                System.arraycopy(stripByteCounts, stripsPerImage * i, newByteCounts, 0, stripsPerImage);
            } else {
                Arrays.fill(newByteCounts, stripByteCounts[0]);
            }
            temp.putIFDValue(IFD.STRIP_BYTE_COUNTS, newByteCounts);
            tempIFDs.add(temp);
        }
        ifds = tempIFDs;
    } catch (IllegalArgumentException exc) {
        LOGGER.debug("Unknown tag", exc);
    } catch (NullPointerException exc) {
        LOGGER.debug("", exc);
    } catch (FormatException exc) {
        LOGGER.debug("Failed to build list of IFDs", exc);
    }
    // parse (mangle) TIFF comment
    String descr = ifds.get(0).getComment();
    if (descr != null) {
        String[] lines = descr.split("\n");
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.startsWith("<") && line.endsWith(">")) {
                // XML comment; this will have already been parsed so can be ignored
                break;
            }
            int colon = line.indexOf(':');
            if (colon < 0) {
                // normal line (not a key/value pair)
                if (line.length() > 0) {
                    // not a blank line
                    sb.append(line);
                    sb.append("  ");
                }
            } else {
                String descrValue = null;
                if (i == 0) {
                    // first line could be mangled; make a reasonable guess
                    int dot = line.lastIndexOf(".", colon);
                    if (dot >= 0) {
                        descrValue = line.substring(0, dot + 1);
                    }
                    line = line.substring(dot + 1);
                    colon -= dot + 1;
                }
                // append value to description
                if (descrValue != null) {
                    sb.append(descrValue);
                    if (!descrValue.endsWith("."))
                        sb.append(".");
                    sb.append("  ");
                }
                // add key/value pair embedded in comment as separate metadata
                String key = line.substring(0, colon);
                String value = line.substring(colon + 1).trim();
                addSeriesMeta(key, value);
                if (key.equals("Exposure")) {
                    if (value.indexOf('=') != -1) {
                        value = value.substring(value.indexOf('=') + 1).trim();
                    }
                    if (value.indexOf(' ') != -1) {
                        value = value.substring(0, value.indexOf(' '));
                    }
                    try {
                        value = value.replace(',', '.');
                        double exposure = Double.parseDouble(value);
                        exposureTime = exposure / 1000;
                    } catch (NumberFormatException e) {
                    }
                } else if (key.equals("Bit Depth")) {
                    if (value.indexOf('-') != -1) {
                        value = value.substring(0, value.indexOf('-'));
                    }
                    try {
                        ms0.bitsPerPixel = Integer.parseInt(value);
                    } catch (NumberFormatException e) {
                    }
                } else if (key.equals("Gain")) {
                    int space = value.indexOf(' ');
                    if (space != -1) {
                        int nextSpace = value.indexOf(" ", space + 1);
                        if (nextSpace < 0) {
                            nextSpace = value.length();
                        }
                        try {
                            gain = new Double(value.substring(space, nextSpace));
                        } catch (NumberFormatException e) {
                        }
                    }
                }
            }
        }
        // replace comment with trimmed version
        descr = sb.toString().trim();
        if (descr.equals(""))
            metadata.remove("Comment");
        else
            addSeriesMeta("Comment", descr);
    }
    ms0.sizeT = getImageCount() / (getSizeZ() * (getSizeC() / rgbChannels));
    if (getSizeT() * getSizeZ() * (getSizeC() / rgbChannels) != getImageCount()) {
        ms0.sizeT = 1;
        ms0.sizeZ = getImageCount() / (getSizeC() / rgbChannels);
    }
    // if '_t' is present in the file name, swap Z and T sizes
    // this file was probably part of a larger dataset, but the .nd file is
    // missing
    String filename = currentId.substring(currentId.lastIndexOf(File.separator) + 1);
    if (filename.contains("_t") && getSizeT() > 1) {
        int z = getSizeZ();
        ms0.sizeZ = getSizeT();
        ms0.sizeT = z;
    }
    if (getSizeZ() == 0)
        ms0.sizeZ = 1;
    if (getSizeT() == 0)
        ms0.sizeT = 1;
    if (getSizeZ() * getSizeT() * (isRGB() ? 1 : getSizeC()) != getImageCount()) {
        ms0.sizeZ = getImageCount();
        ms0.sizeT = 1;
        if (!isRGB())
            ms0.sizeC = 1;
    }
}
Also used : IFD(loci.formats.tiff.IFD) ArrayList(java.util.ArrayList) TiffRational(loci.formats.tiff.TiffRational) PhotoInterp(loci.formats.tiff.PhotoInterp) IOException(java.io.IOException) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) TiffIFDEntry(loci.formats.tiff.TiffIFDEntry) IFDList(loci.formats.tiff.IFDList)

Example 12 with CoreMetadata

use of loci.formats.CoreMetadata in project bioformats by openmicroscopy.

the class MetamorphReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    if (checkSuffix(id, ND_SUFFIX)) {
        LOGGER.info("Initializing " + id);
        // find an associated STK file
        String stkFile = id.substring(0, id.lastIndexOf("."));
        if (stkFile.indexOf(File.separatorChar) != -1) {
            stkFile = stkFile.substring(stkFile.lastIndexOf(File.separator) + 1);
        }
        Location parent = new Location(id).getAbsoluteFile().getParentFile();
        LOGGER.info("Looking for STK file in {}", parent.getAbsolutePath());
        String[] dirList = parent.list(true);
        Arrays.sort(dirList);
        for (String f : dirList) {
            int underscore = f.indexOf('_');
            if (underscore < 0)
                underscore = f.indexOf('.');
            if (underscore < 0)
                underscore = f.length();
            String prefix = f.substring(0, underscore);
            if ((f.equals(stkFile) || stkFile.startsWith(prefix)) && checkSuffix(f, STK_SUFFIX)) {
                stkFile = new Location(parent.getAbsolutePath(), f).getAbsolutePath();
                break;
            }
        }
        if (!checkSuffix(stkFile, STK_SUFFIX)) {
            throw new FormatException("STK file not found in " + parent.getAbsolutePath() + ".");
        }
        super.initFile(stkFile);
    } else
        super.initFile(id);
    Location ndfile = null;
    if (checkSuffix(id, ND_SUFFIX))
        ndfile = new Location(id);
    else if (canLookForND && isGroupFiles()) {
        // an STK file was passed to initFile
        // let's check the parent directory for an .nd file
        Location stk = new Location(id).getAbsoluteFile();
        String stkName = stk.getName();
        String stkPrefix = stkName;
        if (stkPrefix.indexOf('_') >= 0) {
            stkPrefix = stkPrefix.substring(0, stkPrefix.indexOf('_') + 1);
        }
        Location parent = stk.getParentFile();
        String[] list = parent.list(true);
        int matchingChars = 0;
        for (String f : list) {
            if (checkSuffix(f, ND_SUFFIX)) {
                String prefix = f.substring(0, f.lastIndexOf("."));
                if (prefix.indexOf('_') >= 0) {
                    prefix = prefix.substring(0, prefix.indexOf('_') + 1);
                }
                if (stkName.startsWith(prefix) || prefix.equals(stkPrefix)) {
                    int charCount = 0;
                    for (int i = 0; i < f.length(); i++) {
                        if (i >= stkName.length()) {
                            break;
                        }
                        if (f.charAt(i) == stkName.charAt(i)) {
                            charCount++;
                        } else {
                            break;
                        }
                    }
                    if (charCount > matchingChars || (charCount == matchingChars && f.charAt(charCount) == '.')) {
                        ndfile = new Location(parent, f).getAbsoluteFile();
                        matchingChars = charCount;
                    }
                }
            }
        }
    }
    String creationTime = null;
    if (ndfile != null && ndfile.exists() && (fileGroupOption(id) == FormatTools.MUST_GROUP || isGroupFiles())) {
        // parse key/value pairs from .nd file
        int zc = getSizeZ(), cc = getSizeC(), tc = getSizeT();
        int nstages = 0;
        String z = null, c = null, t = null;
        final List<Boolean> hasZ = new ArrayList<Boolean>();
        waveNames = new ArrayList<String>();
        stageNames = new ArrayList<String>();
        boolean useWaveNames = true;
        ndFilename = ndfile.getAbsolutePath();
        String[] lines = DataTools.readFile(ndFilename).split("\n");
        boolean globalDoZ = true;
        boolean doTimelapse = false;
        StringBuilder currentValue = new StringBuilder();
        String key = "";
        for (String line : lines) {
            int comma = line.indexOf(',');
            if (comma <= 0) {
                currentValue.append("\n");
                currentValue.append(line);
                continue;
            }
            String value = currentValue.toString();
            addGlobalMeta(key, value);
            if (key.equals("NZSteps"))
                z = value;
            else if (key.equals("DoTimelapse")) {
                doTimelapse = Boolean.parseBoolean(value);
            } else if (key.equals("NWavelengths"))
                c = value;
            else if (key.equals("NTimePoints"))
                t = value;
            else if (key.startsWith("WaveDoZ")) {
                hasZ.add(Boolean.parseBoolean(value));
            } else if (key.startsWith("WaveName")) {
                String waveName = value.substring(1, value.length() - 1);
                if (waveName.equals("Both lasers") || waveName.startsWith("DUAL")) {
                    bizarreMultichannelAcquisition = true;
                }
                waveNames.add(waveName);
            } else if (key.startsWith("Stage")) {
                stageNames.add(value);
            } else if (key.startsWith("StartTime")) {
                creationTime = value;
            } else if (key.equals("ZStepSize")) {
                value = value.replace(',', '.');
                stepSize = Double.parseDouble(value);
            } else if (key.equals("NStagePositions")) {
                nstages = Integer.parseInt(value);
            } else if (key.equals("WaveInFileName")) {
                useWaveNames = Boolean.parseBoolean(value);
            } else if (key.equals("DoZSeries")) {
                globalDoZ = Boolean.parseBoolean(value);
            }
            key = line.substring(1, comma - 1).trim();
            currentValue.delete(0, currentValue.length());
            currentValue.append(line.substring(comma + 1).trim());
        }
        if (!globalDoZ) {
            for (int i = 0; i < hasZ.size(); i++) {
                hasZ.set(i, false);
            }
        }
        if (z != null)
            zc = Integer.parseInt(z);
        if (c != null)
            cc = Integer.parseInt(c);
        if (t != null)
            tc = Integer.parseInt(t);
        else if (!doTimelapse) {
            tc = 1;
        }
        if (cc == 0)
            cc = 1;
        if (cc == 1 && bizarreMultichannelAcquisition) {
            cc = 2;
        }
        if (tc == 0) {
            tc = 1;
        }
        int numFiles = cc * tc;
        if (nstages > 0)
            numFiles *= nstages;
        // determine series count
        int stagesCount = nstages == 0 ? 1 : nstages;
        int seriesCount = stagesCount;
        firstSeriesChannels = new boolean[cc];
        Arrays.fill(firstSeriesChannels, true);
        boolean differentZs = false;
        for (int i = 0; i < cc; i++) {
            boolean hasZ1 = i < hasZ.size() && hasZ.get(i);
            boolean hasZ2 = i != 0 && (i - 1 < hasZ.size()) && hasZ.get(i - 1);
            if (i > 0 && hasZ1 != hasZ2 && globalDoZ) {
                if (!differentZs)
                    seriesCount *= 2;
                differentZs = true;
            }
        }
        int channelsInFirstSeries = cc;
        if (differentZs) {
            channelsInFirstSeries = 0;
            for (int i = 0; i < cc; i++) {
                if ((!hasZ.get(0) && i == 0) || (hasZ.get(0) && hasZ.get(i))) {
                    channelsInFirstSeries++;
                } else
                    firstSeriesChannels[i] = false;
            }
        }
        stks = new String[seriesCount][];
        if (seriesCount == 1)
            stks[0] = new String[numFiles];
        else if (differentZs) {
            for (int i = 0; i < stagesCount; i++) {
                stks[i * 2] = new String[channelsInFirstSeries * tc];
                stks[i * 2 + 1] = new String[(cc - channelsInFirstSeries) * tc];
            }
        } else {
            for (int i = 0; i < stks.length; i++) {
                stks[i] = new String[numFiles / stks.length];
            }
        }
        String prefix = ndfile.getPath();
        prefix = prefix.substring(prefix.lastIndexOf(File.separator) + 1, prefix.lastIndexOf("."));
        // build list of STK files
        boolean anyZ = hasZ.contains(Boolean.TRUE);
        int[] pt = new int[seriesCount];
        for (int i = 0; i < tc; i++) {
            for (int s = 0; s < stagesCount; s++) {
                for (int j = 0; j < cc; j++) {
                    boolean validZ = j >= hasZ.size() || hasZ.get(j);
                    int seriesNdx = s * (seriesCount / stagesCount);
                    if ((seriesCount != 1 && (!validZ || (hasZ.size() > 0 && !hasZ.get(0)))) || (nstages == 0 && ((!validZ && cc > 1) || seriesCount > 1))) {
                        if (anyZ && j > 0 && seriesNdx < seriesCount - 1 && (!validZ || !hasZ.get(0))) {
                            seriesNdx++;
                        }
                    }
                    if (seriesNdx >= stks.length || seriesNdx >= pt.length || pt[seriesNdx] >= stks[seriesNdx].length) {
                        continue;
                    }
                    stks[seriesNdx][pt[seriesNdx]] = prefix;
                    if (j < waveNames.size() && waveNames.get(j) != null) {
                        stks[seriesNdx][pt[seriesNdx]] += "_w" + (j + 1);
                        if (useWaveNames) {
                            String waveName = waveNames.get(j);
                            // If there are underscores in the wavelength name, translate
                            // them to hyphens. (See #558)
                            waveName = waveName.replace('_', '-');
                            // If there are slashes (forward or backward) in the wavelength
                            // name, translate them to hyphens. (See #5922)
                            waveName = waveName.replace('/', '-');
                            waveName = waveName.replace('\\', '-');
                            waveName = waveName.replace('(', '-');
                            waveName = waveName.replace(')', '-');
                            stks[seriesNdx][pt[seriesNdx]] += waveName;
                        }
                    }
                    if (nstages > 0) {
                        stks[seriesNdx][pt[seriesNdx]] += "_s" + (s + 1);
                    }
                    if (tc > 1 || doTimelapse) {
                        stks[seriesNdx][pt[seriesNdx]] += "_t" + (i + 1) + ".STK";
                    } else
                        stks[seriesNdx][pt[seriesNdx]] += ".STK";
                    pt[seriesNdx]++;
                }
            }
        }
        ndfile = ndfile.getAbsoluteFile();
        for (int s = 0; s < stks.length; s++) {
            for (int f = 0; f < stks[s].length; f++) {
                Location l = new Location(ndfile.getParent(), stks[s][f]);
                stks[s][f] = getRealSTKFile(l);
            }
        }
        String file = locateFirstValidFile();
        if (file == null) {
            throw new FormatException("Unable to locate at least one valid STK file!");
        }
        RandomAccessInputStream s = new RandomAccessInputStream(file, 16);
        TiffParser tp = new TiffParser(s);
        IFD ifd = tp.getFirstIFD();
        CoreMetadata ms0 = core.get(0);
        s.close();
        ms0.sizeX = (int) ifd.getImageWidth();
        ms0.sizeY = (int) ifd.getImageLength();
        if (bizarreMultichannelAcquisition) {
            ms0.sizeX /= 2;
        }
        ms0.sizeZ = hasZ.size() > 0 && !hasZ.get(0) ? 1 : zc;
        ms0.sizeC = cc;
        ms0.sizeT = tc;
        ms0.imageCount = getSizeZ() * getSizeC() * getSizeT();
        ms0.dimensionOrder = "XYZCT";
        if (stks != null && stks.length > 1) {
            // Note that core can't be replaced with newCore until the end of this block.
            ArrayList<CoreMetadata> newCore = new ArrayList<CoreMetadata>();
            for (int i = 0; i < stks.length; i++) {
                CoreMetadata ms = new CoreMetadata();
                newCore.add(ms);
                ms.sizeX = getSizeX();
                ms.sizeY = getSizeY();
                ms.sizeZ = getSizeZ();
                ms.sizeC = getSizeC();
                ms.sizeT = getSizeT();
                ms.pixelType = getPixelType();
                ms.imageCount = getImageCount();
                ms.dimensionOrder = getDimensionOrder();
                ms.rgb = isRGB();
                ms.littleEndian = isLittleEndian();
                ms.interleaved = isInterleaved();
                ms.orderCertain = true;
            }
            if (stks.length > nstages) {
                for (int j = 0; j < stagesCount; j++) {
                    int idx = j * 2 + 1;
                    CoreMetadata midx = newCore.get(idx);
                    CoreMetadata pmidx = newCore.get(j * 2);
                    pmidx.sizeC = stks[j * 2].length / getSizeT();
                    midx.sizeC = stks[idx].length / midx.sizeT;
                    midx.sizeZ = hasZ.size() > 1 && hasZ.get(1) && core.get(0).sizeZ == 1 ? zc : 1;
                    pmidx.imageCount = pmidx.sizeC * pmidx.sizeT * pmidx.sizeZ;
                    midx.imageCount = midx.sizeC * midx.sizeT * midx.sizeZ;
                }
            }
            core = newCore;
        }
    }
    if (stks == null) {
        stkReaders = new MetamorphReader[1][1];
        stkReaders[0][0] = new MetamorphReader();
        stkReaders[0][0].setCanLookForND(false);
    } else {
        stkReaders = new MetamorphReader[stks.length][];
        for (int i = 0; i < stks.length; i++) {
            stkReaders[i] = new MetamorphReader[stks[i].length];
            for (int j = 0; j < stkReaders[i].length; j++) {
                stkReaders[i][j] = new MetamorphReader();
                stkReaders[i][j].setCanLookForND(false);
                if (j > 0) {
                    stkReaders[i][j].setMetadataOptions(new DefaultMetadataOptions(MetadataLevel.MINIMUM));
                }
            }
        }
    }
    // check stage labels for plate data
    int rows = 0;
    int cols = 0;
    Map<String, Integer> rowMap = null;
    Map<String, Integer> colMap = null;
    isHCS = true;
    if (null == stageLabels) {
        isHCS = false;
    } else {
        Set<Map.Entry<Integer, Integer>> uniqueWells = new HashSet<Map.Entry<Integer, Integer>>();
        rowMap = new HashMap<String, Integer>();
        colMap = new HashMap<String, Integer>();
        for (String label : stageLabels) {
            if (null == label) {
                isHCS = false;
                break;
            }
            Map.Entry<Integer, Integer> wellCoords = getWellCoords(label);
            if (null == wellCoords) {
                isHCS = false;
                break;
            }
            uniqueWells.add(wellCoords);
            rowMap.put(label, wellCoords.getKey());
            colMap.put(label, wellCoords.getValue());
        }
        if (uniqueWells.size() != stageLabels.length) {
            isHCS = false;
        } else {
            rows = Collections.max(rowMap.values());
            cols = Collections.max(colMap.values());
            CoreMetadata c = core.get(0);
            core.clear();
            c.sizeZ = 1;
            c.sizeT = 1;
            c.imageCount = 1;
            for (int s = 0; s < uniqueWells.size(); s++) {
                CoreMetadata toAdd = new CoreMetadata(c);
                if (s > 0) {
                    toAdd.seriesMetadata.clear();
                }
                core.add(toAdd);
            }
            seriesToIFD = true;
        }
    }
    List<String> timestamps = null;
    MetamorphHandler handler = null;
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this, true);
    if (isHCS) {
        store.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
        store.setPlateRows(new PositiveInteger(rows), 0);
        store.setPlateColumns(new PositiveInteger(cols), 0);
        store.setPlateRowNamingConvention(NamingConvention.LETTER, 0);
        store.setPlateColumnNamingConvention(NamingConvention.NUMBER, 0);
    }
    int nextObjective = 0;
    String instrumentID = MetadataTools.createLSID("Instrument", 0);
    String detectorID = MetadataTools.createLSID("Detector", 0, 0);
    store.setInstrumentID(instrumentID, 0);
    store.setDetectorID(detectorID, 0, 0);
    store.setDetectorType(getDetectorType("Other"), 0, 0);
    for (int i = 0; i < getSeriesCount(); i++) {
        setSeries(i);
        // do not reparse the same XML for every well
        if (i == 0 || !isHCS) {
            handler = new MetamorphHandler(getSeriesMetadata());
        }
        if (isHCS) {
            String label = stageLabels[i];
            String wellID = MetadataTools.createLSID("Well", 0, i);
            store.setWellID(wellID, 0, i);
            store.setWellColumn(new NonNegativeInteger(colMap.get(label)), 0, i);
            store.setWellRow(new NonNegativeInteger(rowMap.get(label)), 0, i);
            store.setWellSampleID(MetadataTools.createLSID("WellSample", 0, i, 0), 0, i, 0);
            store.setWellSampleImageRef(MetadataTools.createLSID("Image", i), 0, i, 0);
            store.setWellSampleIndex(new NonNegativeInteger(i), 0, i, 0);
        }
        store.setImageInstrumentRef(instrumentID, i);
        String comment = getFirstComment(i);
        if (i == 0 || !isHCS) {
            if (comment != null && comment.startsWith("<MetaData>")) {
                try {
                    XMLTools.parseXML(XMLTools.sanitizeXML(comment), handler);
                } catch (IOException e) {
                }
            }
        }
        if (creationTime != null) {
            String date = DateTools.formatDate(creationTime, SHORT_DATE_FORMAT, ".");
            if (date != null) {
                store.setImageAcquisitionDate(new Timestamp(date), 0);
            }
        }
        store.setImageName(makeImageName(i).trim(), i);
        if (getMetadataOptions().getMetadataLevel() == MetadataLevel.MINIMUM) {
            continue;
        }
        store.setImageDescription("", i);
        store.setImagingEnvironmentTemperature(new Temperature(handler.getTemperature(), UNITS.CELSIUS), i);
        if (sizeX == null)
            sizeX = handler.getPixelSizeX();
        if (sizeY == null)
            sizeY = handler.getPixelSizeY();
        Length physicalSizeX = FormatTools.getPhysicalSizeX(sizeX);
        Length physicalSizeY = FormatTools.getPhysicalSizeY(sizeY);
        if (physicalSizeX != null) {
            store.setPixelsPhysicalSizeX(physicalSizeX, i);
        }
        if (physicalSizeY != null) {
            store.setPixelsPhysicalSizeY(physicalSizeY, i);
        }
        if (zDistances != null) {
            stepSize = zDistances[0];
        } else {
            List<Double> zPositions = new ArrayList<Double>();
            final List<Double> uniqueZ = new ArrayList<Double>();
            for (IFD ifd : ifds) {
                MetamorphHandler zPlaneHandler = new MetamorphHandler();
                String zComment = ifd.getComment();
                if (zComment != null && zComment.startsWith("<MetaData>")) {
                    try {
                        XMLTools.parseXML(XMLTools.sanitizeXML(zComment), zPlaneHandler);
                    } catch (IOException e) {
                    }
                }
                zPositions = zPlaneHandler.getZPositions();
                for (Double z : zPositions) {
                    if (!uniqueZ.contains(z))
                        uniqueZ.add(z);
                }
            }
            if (uniqueZ.size() > 1 && uniqueZ.size() == getSizeZ()) {
                BigDecimal lastZ = BigDecimal.valueOf(uniqueZ.get(uniqueZ.size() - 1));
                BigDecimal firstZ = BigDecimal.valueOf(uniqueZ.get(0));
                BigDecimal zRange = (lastZ.subtract(firstZ)).abs();
                BigDecimal zSize = BigDecimal.valueOf((double) (getSizeZ() - 1));
                MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
                stepSize = zRange.divide(zSize, mc).doubleValue();
            }
        }
        Length physicalSizeZ = FormatTools.getPhysicalSizeZ(stepSize);
        if (physicalSizeZ != null) {
            store.setPixelsPhysicalSizeZ(physicalSizeZ, i);
        }
        if (handler.getLensNA() != 0 || handler.getLensRI() != 0) {
            String objectiveID = MetadataTools.createLSID("Objective", 0, nextObjective);
            store.setObjectiveID(objectiveID, 0, nextObjective);
            if (handler.getLensNA() != 0) {
                store.setObjectiveLensNA(handler.getLensNA(), 0, nextObjective);
            }
            store.setObjectiveSettingsID(objectiveID, i);
            if (handler.getLensRI() != 0) {
                store.setObjectiveSettingsRefractiveIndex(handler.getLensRI(), i);
            }
            nextObjective++;
        }
        int waveIndex = 0;
        for (int c = 0; c < getEffectiveSizeC(); c++) {
            if (firstSeriesChannels == null || (stageNames != null && stageNames.size() == getSeriesCount())) {
                waveIndex = c;
            } else if (firstSeriesChannels != null) {
                int s = i % 2;
                while (firstSeriesChannels[waveIndex] == (s == 1) && waveIndex < firstSeriesChannels.length) {
                    waveIndex++;
                }
            }
            if (waveNames != null && waveIndex < waveNames.size()) {
                store.setChannelName(waveNames.get(waveIndex).trim(), i, c);
            }
            if (handler.getBinning() != null)
                binning = handler.getBinning();
            if (binning != null) {
                store.setDetectorSettingsBinning(getBinning(binning), i, c);
            }
            if (handler.getReadOutRate() != 0) {
                store.setDetectorSettingsReadOutRate(new Frequency(handler.getReadOutRate(), UNITS.HERTZ), i, c);
            }
            if (gain == null) {
                gain = handler.getGain();
            }
            if (gain != null) {
                store.setDetectorSettingsGain(gain, i, c);
            }
            store.setDetectorSettingsID(detectorID, i, c);
            if (wave != null && waveIndex < wave.length) {
                Length wavelength = FormatTools.getWavelength(wave[waveIndex]);
                if ((int) wave[waveIndex] >= 1) {
                    // link LightSource to Image
                    int laserIndex = i * getEffectiveSizeC() + c;
                    String lightSourceID = MetadataTools.createLSID("LightSource", 0, laserIndex);
                    store.setLaserID(lightSourceID, 0, laserIndex);
                    store.setChannelLightSourceSettingsID(lightSourceID, i, c);
                    store.setLaserType(getLaserType("Other"), 0, laserIndex);
                    store.setLaserLaserMedium(getLaserMedium("Other"), 0, laserIndex);
                    if (wavelength != null) {
                        store.setChannelLightSourceSettingsWavelength(wavelength, i, c);
                    }
                }
            }
            waveIndex++;
        }
        timestamps = handler.getTimestamps();
        for (int t = 0; t < timestamps.size(); t++) {
            String date = DateTools.convertDate(DateTools.getTime(timestamps.get(t), SHORT_DATE_FORMAT, "."), DateTools.UNIX, SHORT_DATE_FORMAT + ".SSS");
            addSeriesMetaList("timestamp", date);
        }
        long startDate = 0;
        if (timestamps.size() > 0) {
            startDate = DateTools.getTime(timestamps.get(0), SHORT_DATE_FORMAT, ".");
        }
        final Length positionX = handler.getStagePositionX();
        final Length positionY = handler.getStagePositionY();
        final List<Double> exposureTimes = handler.getExposures();
        if (exposureTimes.size() == 0) {
            for (int p = 0; p < getImageCount(); p++) {
                exposureTimes.add(exposureTime);
            }
        } else if (exposureTimes.size() == 1 && exposureTimes.size() < getSizeC()) {
            for (int c = 1; c < getSizeC(); c++) {
                MetamorphHandler channelHandler = new MetamorphHandler();
                String channelComment = getComment(i, c);
                if (channelComment != null && channelComment.startsWith("<MetaData>")) {
                    try {
                        XMLTools.parseXML(XMLTools.sanitizeXML(channelComment), channelHandler);
                    } catch (IOException e) {
                    }
                }
                final List<Double> channelExpTime = channelHandler.getExposures();
                exposureTimes.add(channelExpTime.get(0));
            }
        }
        int lastFile = -1;
        IFDList lastIFDs = null;
        IFD lastIFD = null;
        double distance = zStart;
        TiffParser tp = null;
        RandomAccessInputStream stream = null;
        for (int p = 0; p < getImageCount(); p++) {
            int[] coords = getZCTCoords(p);
            Double deltaT = 0d;
            Double expTime = exposureTime;
            Double xmlZPosition = null;
            int fileIndex = getIndex(0, coords[1], coords[2]) / getSizeZ();
            if (fileIndex >= 0) {
                String file = stks == null ? currentId : stks[i][fileIndex];
                if (file != null) {
                    if (fileIndex != lastFile) {
                        if (stream != null) {
                            stream.close();
                        }
                        stream = new RandomAccessInputStream(file, 16);
                        tp = new TiffParser(stream);
                        tp.checkHeader();
                        IFDList f = tp.getIFDs();
                        if (f.size() > 0) {
                            lastFile = fileIndex;
                            lastIFDs = f;
                        } else {
                            file = null;
                            stks[i][fileIndex] = null;
                        }
                    }
                }
                if (file != null) {
                    lastIFD = lastIFDs.get(p % lastIFDs.size());
                    Object commentEntry = lastIFD.get(IFD.IMAGE_DESCRIPTION);
                    if (commentEntry != null) {
                        if (commentEntry instanceof String) {
                            comment = (String) commentEntry;
                        } else if (commentEntry instanceof TiffIFDEntry) {
                            comment = tp.getIFDValue((TiffIFDEntry) commentEntry).toString();
                        }
                    }
                    if (comment != null)
                        comment = comment.trim();
                    if (comment != null && comment.startsWith("<MetaData>")) {
                        String[] lines = comment.split("\n");
                        timestamps = new ArrayList<String>();
                        for (String line : lines) {
                            line = line.trim();
                            if (line.startsWith("<prop")) {
                                int firstQuote = line.indexOf("\"") + 1;
                                int lastQuote = line.lastIndexOf("\"");
                                String key = line.substring(firstQuote, line.indexOf("\"", firstQuote));
                                String value = line.substring(line.lastIndexOf("\"", lastQuote - 1) + 1, lastQuote);
                                if (key.equals("z-position")) {
                                    xmlZPosition = new Double(value);
                                } else if (key.equals("acquisition-time-local")) {
                                    timestamps.add(value);
                                }
                            }
                        }
                    }
                }
            }
            int index = 0;
            if (timestamps.size() > 0) {
                if (coords[2] < timestamps.size())
                    index = coords[2];
                String stamp = timestamps.get(index);
                long ms = DateTools.getTime(stamp, SHORT_DATE_FORMAT, ".");
                deltaT = (ms - startDate) / 1000.0;
            } else if (internalStamps != null && p < internalStamps.length) {
                long delta = internalStamps[p] - internalStamps[0];
                deltaT = delta / 1000.0;
                if (coords[2] < exposureTimes.size())
                    index = coords[2];
            }
            if (index == 0 && p > 0 && exposureTimes.size() > 0) {
                index = coords[1] % exposureTimes.size();
            }
            if (index < exposureTimes.size()) {
                expTime = exposureTimes.get(index);
            }
            if (deltaT != null) {
                store.setPlaneDeltaT(new Time(deltaT, UNITS.SECOND), i, p);
            }
            if (expTime != null) {
                store.setPlaneExposureTime(new Time(expTime, UNITS.SECOND), i, p);
            }
            if (stageX != null && p < stageX.length) {
                store.setPlanePositionX(stageX[p], i, p);
            } else if (positionX != null) {
                store.setPlanePositionX(positionX, i, p);
            }
            if (stageY != null && p < stageY.length) {
                store.setPlanePositionY(stageY[p], i, p);
            } else if (positionY != null) {
                store.setPlanePositionY(positionY, i, p);
            }
            if (zDistances != null && p < zDistances.length) {
                if (p > 0) {
                    if (zDistances[p] != 0d)
                        distance += zDistances[p];
                    else
                        distance += zDistances[0];
                }
                final Length zPos = new Length(distance, UNITS.REFERENCEFRAME);
                store.setPlanePositionZ(zPos, i, p);
            } else if (xmlZPosition != null) {
                final Length zPos = new Length(xmlZPosition, UNITS.REFERENCEFRAME);
                store.setPlanePositionZ(zPos, i, p);
            }
        }
        if (stream != null) {
            stream.close();
        }
    }
    setSeries(0);
}
Also used : Temperature(ome.units.quantity.Temperature) IFD(loci.formats.tiff.IFD) ArrayList(java.util.ArrayList) DateTime(org.joda.time.DateTime) Time(ome.units.quantity.Time) Timestamp(ome.xml.model.primitives.Timestamp) TiffIFDEntry(loci.formats.tiff.TiffIFDEntry) TiffIFDEntry(loci.formats.tiff.TiffIFDEntry) ArrayList(java.util.ArrayList) IFDList(loci.formats.tiff.IFDList) List(java.util.List) HashSet(java.util.HashSet) PositiveInteger(ome.xml.model.primitives.PositiveInteger) NonNegativeInteger(ome.xml.model.primitives.NonNegativeInteger) IOException(java.io.IOException) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) BigDecimal(java.math.BigDecimal) MathContext(java.math.MathContext) PositiveInteger(ome.xml.model.primitives.PositiveInteger) NonNegativeInteger(ome.xml.model.primitives.NonNegativeInteger) MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) Frequency(ome.units.quantity.Frequency) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) HashMap(java.util.HashMap) Map(java.util.Map) AbstractMap(java.util.AbstractMap) Location(loci.common.Location)

Example 13 with CoreMetadata

use of loci.formats.CoreMetadata in project bioformats by openmicroscopy.

the class NAFReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    in = new RandomAccessInputStream(id);
    String endian = in.readString(2);
    boolean little = endian.equals("II");
    in.order(little);
    in.seek(98);
    int seriesCount = in.readInt();
    in.seek(192);
    while (in.read() == 0) ;
    String description = in.readCString();
    addGlobalMeta("Description", description);
    while (in.readInt() == 0) ;
    long fp = in.getFilePointer();
    if ((fp % 2) == 0)
        fp -= 4;
    else
        fp--;
    offsets = new long[seriesCount];
    core.clear();
    for (int i = 0; i < seriesCount; i++) {
        in.seek(fp + i * 256);
        CoreMetadata ms = new CoreMetadata();
        core.add(ms);
        ms.littleEndian = little;
        ms.sizeX = in.readInt();
        ms.sizeY = in.readInt();
        int numBits = in.readInt();
        ms.sizeC = in.readInt();
        ms.sizeZ = in.readInt();
        ms.sizeT = in.readInt();
        ms.imageCount = ms.sizeZ * ms.sizeC * ms.sizeT;
        int nBytes = numBits / 8;
        ms.pixelType = FormatTools.pixelTypeFromBytes(nBytes, false, nBytes == 8);
        ms.dimensionOrder = "XYCZT";
        ms.rgb = false;
        in.skipBytes(4);
        long pointer = in.getFilePointer();
        String name = in.readCString();
        if (i == 0) {
            in.skipBytes((int) (92 - in.getFilePointer() + pointer));
            while (true) {
                int check = in.readInt();
                if (check > in.getFilePointer()) {
                    offsets[i] = (long) check + LUT_SIZE;
                    break;
                }
                in.skipBytes(92);
            }
        } else {
            CoreMetadata mp = core.get(i - 1);
            offsets[i] = offsets[i - 1] + mp.sizeX * mp.sizeY * mp.imageCount * FormatTools.getBytesPerPixel(mp.pixelType);
        }
        offsets[i] += 352;
        in.seek(offsets[i]);
        while (in.getFilePointer() + 116 < in.length() && in.read() == 3 && in.read() == 37) {
            in.skipBytes(114);
            offsets[i] = in.getFilePointer();
        }
        in.seek(in.getFilePointer() - 1);
        byte[] buf = new byte[3 * 1024 * 1024];
        int n = in.read(buf, 0, 1);
        boolean found = false;
        while (!found && in.getFilePointer() < in.length()) {
            n += in.read(buf, 1, buf.length - 1);
            for (int q = 0; q < buf.length - 1; q++) {
                if ((buf[q] & 0xff) == 192 && (buf[q + 1] & 0xff) == 46) {
                    offsets[i] = in.getFilePointer() - n + q;
                    found = true;
                    break;
                }
            }
            buf[0] = buf[buf.length - 1];
            n = 1;
        }
        if (found)
            offsets[i] += 16063;
        if (i == offsets.length - 1 && !compressed && i > 0) {
            offsets[i] = (int) (in.length() - (ms.sizeX * ms.sizeY * ms.imageCount * (numBits / 8)));
        }
    }
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
}
Also used : MetadataStore(loci.formats.meta.MetadataStore) RandomAccessInputStream(loci.common.RandomAccessInputStream) CoreMetadata(loci.formats.CoreMetadata)

Example 14 with CoreMetadata

use of loci.formats.CoreMetadata in project bioformats by openmicroscopy.

the class ND2Handler method startElement.

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
    String runtype = attributes.getValue("runtype");
    if ("CLxListVariant".equals(runtype) || "RLxIRect".equals(runtype)) {
        prevElement = qName;
    }
    String value = attributes.getValue("value");
    CoreMetadata ms0 = core.get(0);
    try {
        if (qName.equals("uiWidth")) {
            int x = Integer.parseInt(value);
            if (x != 0 && populateXY) {
                ms0.sizeX = x;
            }
        } else if (qName.equals("uiCamPxlCountX")) {
            if (ms0.sizeX == 0 && populateXY) {
                ms0.sizeX = Integer.parseInt(value);
            }
        } else if (qName.equals("uiCamPxlCountY")) {
            if (ms0.sizeY == 0 && populateXY) {
                ms0.sizeY = Integer.parseInt(value);
            }
        } else if (qName.equals("iXFields")) {
            int fields = Integer.parseInt(value);
            nXFields += fields;
        } else if (qName.equals("iYFields")) {
            int fields = Integer.parseInt(value);
            nYFields += fields;
        } else if ("rectSensorUser".equals(prevElement) && populateXY) {
            if (qName.equals("left") && ms0.sizeX == 0) {
                ms0.sizeX = -1 * Integer.parseInt(value);
            } else if (qName.equals("top") && ms0.sizeY == 0) {
                ms0.sizeY = -1 * Integer.parseInt(value);
            } else if (qName.equals("right") && ms0.sizeX <= 0) {
                ms0.sizeX += Integer.parseInt(value);
            } else if (qName.equals("bottom") && ms0.sizeY <= 0) {
                ms0.sizeY += Integer.parseInt(value);
            }
        } else if ("LoopState".equals(prevElement) && value != null) {
            long v = Long.parseLong(value);
            validLoopState.add(v != 529 && v < 0xfffff);
        } else if ("LoopSize".equals(prevElement) && value != null) {
            int v = Integer.parseInt(value);
            int loopIndex = 0;
            while (validLoopState.get(loopIndex) == null) {
                loopIndex++;
            }
            boolean loop = validLoopState.get(loopIndex);
            if (!loop && validLoopState.contains(true)) {
                v = 1;
            }
            if (ms0.sizeT == 0 || (ms0.sizeT * ms0.sizeZ > nImages && v < ms0.sizeT)) {
                ms0.sizeT = v;
            } else if (qName.equals("no_name") && v > 1 && core.size() == 1) {
                core = new ArrayList<CoreMetadata>();
                for (int q = 0; q < v; q++) {
                    core.add(ms0);
                }
            } else if (ms0.sizeZ == 0) {
                ms0.sizeZ = v;
            } else {
                canAdjustDimensions = false;
            }
            ms0.dimensionOrder = "CZT";
        } else if ("pPosName".equals(prevElement) && value != null) {
            posNames.add(value);
        } else if (qName.equals("FramesBefore")) {
            if (ms0.sizeZ == 0) {
                ms0.sizeZ = 1;
            }
            // only adjust if we haven't parsed all of the dimensions already
            if (canAdjustDimensions && core.size() == 1 && (ms0.sizeT <= 1 || ms0.sizeT * ms0.sizeZ != nImages)) {
                ms0.sizeZ *= Integer.parseInt(value);
            }
        } else if (qName.equals("FramesAfter")) {
            int loopIndex = 0;
            while (validLoopState.get(loopIndex) == null) {
                loopIndex++;
            }
            boolean loop = validLoopState.get(loopIndex);
            validLoopState.set(loopIndex, null);
            if (canAdjustDimensions && core.size() == 1) {
                ms0.sizeZ *= Integer.parseInt(value);
                if (ms0.sizeT * ms0.sizeZ > nImages && ms0.sizeT <= nImages && ms0.sizeT != ms0.sizeZ) {
                    ms0.sizeZ = ms0.sizeT;
                    ms0.sizeT = 1;
                }
            }
        } else if (qName.equals("TimeBefore") && canAdjustDimensions) {
            if (ms0.sizeT == 0) {
                ms0.sizeT = 1;
            }
            ms0.sizeT *= Integer.parseInt(value);
        } else if (qName.equals("TimeAfter") && canAdjustDimensions) {
            ms0.sizeT *= Integer.parseInt(value);
        } else if (qName.equals("uiMaxDst")) {
            int maxPixelValue = Integer.parseInt(value) + 1;
            int bits = 0;
            while (maxPixelValue > 0) {
                maxPixelValue /= 2;
                bits++;
            }
            try {
                if (ms0.pixelType == 0) {
                    ms0.pixelType = FormatTools.pixelTypeFromBytes(bits / 8, false, false);
                }
            } catch (FormatException e) {
                LOGGER.warn("Could not set the pixel type", e);
            }
        } else if (qName.equals("uiWidthBytes") || qName.startsWith("uiBpcInMemory") || qName.startsWith("uiBpcSignificant")) {
            int div = qName.equals("uiWidthBytes") ? ms0.sizeX : 8;
            if (div > 0) {
                int bits = Integer.parseInt(value);
                int bytes = bits / div;
                if (bytes * div == bits) {
                    try {
                        ms0.pixelType = FormatTools.pixelTypeFromBytes(bytes, false, false);
                    } catch (FormatException e) {
                    }
                }
                parseKeyAndValue(qName, value, prevRuntype);
            }
        } else if ("dPosX".equals(prevElement) && qName.startsWith("item_")) {
            final Double number = DataTools.parseDouble(value);
            posX.add(new Length(number, UNITS.REFERENCEFRAME));
            metadata.put("X position for position #" + posX.size(), value);
        } else if ("dPosY".equals(prevElement) && qName.startsWith("item_")) {
            final Double number = DataTools.parseDouble(value);
            posY.add(new Length(number, UNITS.REFERENCEFRAME));
            metadata.put("Y position for position #" + posY.size(), value);
        } else if ("dPosZ".equals(prevElement) && qName.startsWith("item_")) {
            final Double number = DataTools.parseDouble(value);
            posZ.add(new Length(number, UNITS.REFERENCEFRAME));
            metadata.put("Z position for position #" + posZ.size(), value);
        } else if (qName.startsWith("item_")) {
            int v = Integer.parseInt(qName.substring(qName.indexOf('_') + 1));
            if (v == numSeries) {
                numSeries++;
            }
        } else if (qName.equals("uiCompCount")) {
            int v = Integer.parseInt(value);
            ms0.sizeC = (int) Math.max(ms0.sizeC, v);
        } else if (qName.equals("uiHeight") && populateXY) {
            int y = Integer.parseInt(value);
            if (y != 0) {
                ms0.sizeY = y;
            }
        } else if (qName.startsWith("TextInfo")) {
            parseKeyAndValue(qName, attributes.getValue("Text"), prevRuntype);
            parseKeyAndValue(qName, value, prevRuntype);
        } else if (qName.equals("dCompressionParam")) {
            isLossless = Double.parseDouble(value) > 0;
            parseKeyAndValue(qName, value, prevRuntype);
        } else if (qName.equals("CalibrationSeq") || qName.equals("MetadataSeq")) {
            prefix = qName + " " + attributes.getValue("_SEQUENCE_INDEX");
        } else if (qName.equals("HorizontalLine") || qName.equals("VerticalLine") || qName.equals("Text")) {
            Hashtable<String, String> roi = new Hashtable<String, String>();
            roi.put("ROIType", qName);
            for (int q = 0; q < attributes.getLength(); q++) {
                roi.put(attributes.getQName(q), attributes.getValue(q));
            }
            rois.add(roi);
        } else if (qName.equals("dPinholeRadius")) {
            pinholeSize = DataTools.parseDouble(value);
            metadata.put("Pinhole size", value);
        } else if (qName.endsWith("ChannelColor")) {
            String name = qName.substring(0, qName.indexOf("Channel"));
            colors.put(name, new Integer(value));
        } else if (qName.endsWith("DyeName")) {
            int channelIndex = qName.indexOf("Channel");
            if (channelIndex < 0)
                channelIndex = 0;
            dyes.put(qName.substring(0, channelIndex), value);
        } else if (qName.equals("uiSequenceCount")) {
            int imageCount = Integer.parseInt(value);
            if (core.size() > 0) {
                int newCount = imageCount / core.size();
                if (newCount * core.size() == imageCount) {
                    imageCount = newCount;
                }
            }
            if (ms0.sizeZ * ms0.sizeT != imageCount && ms0.sizeZ * ms0.sizeC * ms0.sizeT != imageCount) {
                if (ms0.sizeZ > 1 && ms0.sizeT <= 1) {
                    ms0.sizeZ = imageCount;
                    ms0.sizeT = 1;
                    ms0.imageCount = imageCount;
                } else if (ms0.sizeT > 1 && ms0.sizeZ <= 1) {
                    ms0.sizeT = imageCount;
                    ms0.sizeZ = 1;
                    ms0.imageCount = imageCount;
                } else if (imageCount == 0) {
                    ms0.sizeT = 0;
                    ms0.sizeZ = 0;
                    ms0.imageCount = 0;
                }
            }
            metadata.put(qName, value);
        } else {
            final StringBuilder sb = new StringBuilder();
            if (prefix != null) {
                sb.append(prefix);
                sb.append(" ");
            }
            sb.append(qName);
            parseKeyAndValue(sb.toString(), value, prevRuntype);
        }
    } catch (NumberFormatException exc) {
        LOGGER.warn("Could not parse {} value: {}", qName, value);
    }
    prevRuntype = attributes.getValue("runtype");
}
Also used : Hashtable(java.util.Hashtable) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) Length(ome.units.quantity.Length)

Example 15 with CoreMetadata

use of loci.formats.CoreMetadata in project bioformats by openmicroscopy.

the class ND2Handler method parseKeyAndValue.

// -- Helper methods --
public void parseKeyAndValue(String key, String value, String runtype) {
    if (key == null || value == null)
        return;
    CoreMetadata ms0 = core.get(0);
    metadata.put(key, value);
    try {
        if (key.endsWith("dCalibration")) {
            pixelSizeX = DataTools.parseDouble(value);
            pixelSizeY = pixelSizeX;
        } else if (key.endsWith("dZStep")) {
            pixelSizeZ = DataTools.parseDouble(value);
        } else if (key.endsWith("Gain")) {
            Double gainValue = DataTools.parseDouble(value);
            if (gainValue != null)
                gain.add(gainValue);
        } else if (key.endsWith("dLampVoltage")) {
            voltage = DataTools.parseDouble(value);
        } else if (key.endsWith("dObjectiveMag") && mag == null) {
            mag = DataTools.parseDouble(value);
        } else if (key.endsWith("dObjectiveNA")) {
            na = DataTools.parseDouble(value);
        } else if (key.endsWith("dRefractIndex1")) {
            refractiveIndex = DataTools.parseDouble(value);
        } else if (key.equals("sObjective") || key.equals("wsObjectiveName") || key.equals("sOptics")) {
            String[] tokens = value.split(" ");
            int magIndex = -1;
            for (int i = 0; i < tokens.length; i++) {
                if (tokens[i].indexOf('x') != -1) {
                    magIndex = i;
                    break;
                }
            }
            final StringBuilder s = new StringBuilder();
            for (int i = 0; i < magIndex; i++) {
                s.append(tokens[i]);
            }
            correction = s.toString();
            if (magIndex >= 0) {
                String m = tokens[magIndex].substring(0, tokens[magIndex].indexOf('x'));
                mag = DataTools.parseDouble(m);
            }
            if (magIndex + 1 < tokens.length)
                immersion = tokens[magIndex + 1];
        } else if (key.endsWith("dTimeMSec")) {
            Long v = DataTools.parseLong(value);
            if (!ts.contains(v)) {
                ts.add(v);
                metadata.put("number of timepoints", ts.size());
            }
        } else if (key.endsWith("dZPos")) {
            Long v = DataTools.parseLong(value);
            if (!zs.contains(v))
                zs.add(v);
        } else if (key.endsWith("uiCount")) {
            if (runtype != null) {
                if (runtype.endsWith("ZStackLoop")) {
                    if (ms0.sizeZ == 0) {
                        ms0.sizeZ = Integer.parseInt(value);
                        if (ms0.dimensionOrder.indexOf('Z') == -1) {
                            ms0.dimensionOrder = "Z" + ms0.dimensionOrder;
                        }
                    }
                } else if (runtype.endsWith("TimeLoop")) {
                    if (ms0.sizeT == 0) {
                        ms0.sizeT = Integer.parseInt(value);
                        if (ms0.dimensionOrder.indexOf('T') == -1) {
                            ms0.dimensionOrder = "T" + ms0.dimensionOrder;
                        }
                    }
                } else if (runtype.endsWith("XYPosLoop") && core.size() == 1) {
                    int len = Integer.parseInt(value);
                    core = new ArrayList<CoreMetadata>();
                    for (int i = 0; i < len; i++) {
                        core.add(ms0);
                    }
                }
            }
        } else if (key.endsWith("uiBpcSignificant")) {
            ms0.bitsPerPixel = Integer.parseInt(value);
        } else if (key.equals("VirtualComponents")) {
            if (ms0.sizeC == 0) {
                ms0.sizeC = Integer.parseInt(value);
                if (ms0.dimensionOrder.indexOf('C') == -1) {
                    ms0.dimensionOrder += "C" + ms0.dimensionOrder;
                }
            }
        } else if (key.startsWith("TextInfoItem") || key.endsWith("TextInfoItem")) {
            metadata.remove(key);
            value = value.replaceAll("&#x000d;", "");
            value = value.replaceAll("#x000d;", "");
            value = value.replaceAll("&#x000a;", "\n");
            value = value.replaceAll("#x000a;", "\n");
            String[] tokens = value.split("\n");
            for (String t : tokens) {
                t = t.trim();
                String[] v = t.split(":");
                if (v.length == 0) {
                    continue;
                } else if (v.length == 2) {
                    parseKeyAndValue(v[0].trim(), v[1].trim(), runtype);
                } else if (v[0].equals("Line")) {
                    parseKeyAndValue(v[0], t.substring(t.indexOf(':') + 1).trim(), runtype);
                } else if (v.length > 1) {
                    v[0] = v[0].replace('{', ' ');
                    v[0] = v[0].replace('}', ' ');
                    metadata.put(v[0].trim(), v[1]);
                } else if (v.length == 1) {
                    metadata.put(key, v[0]);
                }
            }
        } else if (isDimensions(key)) {
            String[] dims = value.split(" x ");
            if (ms0.sizeZ == 0)
                ms0.sizeZ = 1;
            if (ms0.sizeT == 0)
                ms0.sizeT = 1;
            if (ms0.sizeC == 0)
                ms0.sizeC = 1;
            for (String dim : dims) {
                dim = dim.trim();
                int v = Integer.parseInt(dim.replaceAll("\\D", ""));
                v = (int) Math.max(v, 1);
                if (dim.startsWith("XY")) {
                    numSeries = v;
                    if (numSeries > 1) {
                        int x = ms0.sizeX;
                        int y = ms0.sizeY;
                        int z = ms0.sizeZ;
                        int tSize = ms0.sizeT;
                        int c = ms0.sizeC;
                        String order = ms0.dimensionOrder;
                        core = new ArrayList<CoreMetadata>();
                        for (int i = 0; i < numSeries; i++) {
                            CoreMetadata ms = new CoreMetadata();
                            core.add(ms);
                            ms.sizeX = x;
                            ms.sizeY = y;
                            ms.sizeZ = z == 0 ? 1 : z;
                            ms.sizeC = c == 0 ? 1 : c;
                            ms.sizeT = tSize == 0 ? 1 : tSize;
                            ms.dimensionOrder = order;
                        }
                        ms0 = core.get(0);
                    }
                } else if (dim.startsWith("T")) {
                    if (ms0.sizeT <= 1 || v < ms0.sizeT) {
                        ms0.sizeT = v;
                    }
                } else if (dim.startsWith("Z")) {
                    if (ms0.sizeZ <= 1) {
                        ms0.sizeZ = v;
                    }
                } else if (ms0.sizeC <= 1) {
                    ms0.sizeC = v;
                }
            }
            ms0.imageCount = ms0.sizeZ * ms0.sizeC * ms0.sizeT;
        } else if (key.startsWith("Number of Picture Planes")) {
            ms0.sizeC = Integer.parseInt(value.replaceAll("\\D", ""));
        } else if (key.equals("Name")) {
            channelNames.add(value);
        } else if (key.equals("Modality")) {
            modality.add(value);
        } else if (key.equals("Camera Type")) {
            cameraModel = value;
        } else if (key.equals("Binning")) {
            binning.add(value);
        } else if (key.equals("Readout Speed")) {
            int last = value.lastIndexOf(" ");
            if (last != -1)
                value = value.substring(0, last);
            speed.add(DataTools.parseDouble(value));
        } else if (key.equals("Temperature")) {
            String temp = value.replaceAll("[\\D&&[^-.]]", "");
            temperature.add(DataTools.parseDouble(temp));
        } else if (key.equals("Exposure")) {
            String[] s = value.trim().split(" ");
            Double time = DataTools.parseDouble(s[0]);
            if (time != null) {
                // TODO: check for other units
                if (s.length > 1) {
                    if (s[1].equals("ms"))
                        time /= 1000;
                } else {
                    // assume time is in milliseconds
                    time /= 1000;
                }
                exposureTime.add(time);
            }
        } else if (key.equals("{Pinhole Size}")) {
            pinholeSize = DataTools.parseDouble(value);
            metadata.put("Pinhole size", value);
        } else if (key.startsWith("- Step")) {
            Double step = parsePixelsSizeZFromKey(key);
            if (step != null)
                pixelSizeZ = step;
        } else if (key.equals("Line")) {
            String[] values = value.split(";");
            for (int q = 0; q < values.length; q++) {
                int colon = values[q].indexOf(':');
                if (colon < 0)
                    continue;
                String nextKey = values[q].substring(0, colon).trim();
                String nextValue = values[q].substring(colon + 1).trim();
                parseKeyAndValue(nextKey, nextValue, runtype);
            }
        } else if (key.equalsIgnoreCase("Emission wavelength")) {
            String[] v = value.split(" ");
            emWave.add(new Double(v[0]));
        } else if (key.equalsIgnoreCase("Excitation wavelength")) {
            String[] v = value.split(" ");
            exWave.add(new Double(v[0]));
        } else if (key.equals("Power")) {
            power.add(DataTools.parseInteger(value));
        } else if (key.equals("CameraUniqueName")) {
            cameraModel = value;
        } else if (key.equals("ExposureTime")) {
            exposureTime.add(new Double(value) / 1000d);
        } else if (key.equals("sDate")) {
            date = DateTools.formatDate(value, DATE_FORMAT);
        } else if (key.equals("Name") && channelNames.size() < ms0.sizeC) {
            channelNames.add(value);
        } else if (key.equals("Z Stack Loop")) {
            int v = Integer.parseInt(value);
            if (v <= nImages || nImages <= 0) {
                core.get(0).sizeZ = v;
            }
        } else if (key.equals("Time Loop")) {
            int v = Integer.parseInt(value);
            if (v <= nImages && firstTimeLoop) {
                core.get(0).sizeT = v;
                firstTimeLoop = false;
            }
        }
    } catch (NumberFormatException exc) {
        LOGGER.warn("Could not parse {} value: {}", key, value);
    }
}
Also used : CoreMetadata(loci.formats.CoreMetadata)

Aggregations

CoreMetadata (loci.formats.CoreMetadata)211 MetadataStore (loci.formats.meta.MetadataStore)130 RandomAccessInputStream (loci.common.RandomAccessInputStream)108 FormatException (loci.formats.FormatException)87 Length (ome.units.quantity.Length)74 Location (loci.common.Location)55 ArrayList (java.util.ArrayList)50 Timestamp (ome.xml.model.primitives.Timestamp)44 IFD (loci.formats.tiff.IFD)33 Time (ome.units.quantity.Time)30 IOException (java.io.IOException)21 TiffParser (loci.formats.tiff.TiffParser)19 PhotoInterp (loci.formats.tiff.PhotoInterp)17 NonNegativeInteger (ome.xml.model.primitives.NonNegativeInteger)16 IFDList (loci.formats.tiff.IFDList)15 DependencyException (loci.common.services.DependencyException)14 ServiceFactory (loci.common.services.ServiceFactory)13 PositiveInteger (ome.xml.model.primitives.PositiveInteger)13 IniList (loci.common.IniList)9 HashMap (java.util.HashMap)8