use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class CellSensReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
if (!checkSuffix(id, "vsi")) {
Location current = new Location(id).getAbsoluteFile();
Location parent = current.getParentFile();
parent = parent.getParentFile();
Location grandparent = parent.getParentFile();
String vsi = parent.getName();
vsi = vsi.substring(1, vsi.length() - 1) + ".vsi";
Location vsiFile = new Location(grandparent, vsi);
if (!vsiFile.exists()) {
throw new FormatException("Could not find .vsi file.");
} else {
id = vsiFile.getAbsolutePath();
}
}
parser = new TiffParser(id);
ifds = parser.getIFDs();
RandomAccessInputStream vsi = new RandomAccessInputStream(id);
vsi.order(parser.getStream().isLittleEndian());
vsi.seek(8);
readTags(vsi, false, "");
vsi.close();
ArrayList<String> files = new ArrayList<String>();
Location file = new Location(id).getAbsoluteFile();
Location dir = file.getParentFile();
String name = file.getName();
name = name.substring(0, name.lastIndexOf("."));
Location pixelsDir = new Location(dir, "_" + name + "_");
String[] stackDirs = pixelsDir.list(true);
if (stackDirs != null) {
Arrays.sort(stackDirs);
for (String f : stackDirs) {
Location stackDir = new Location(pixelsDir, f);
String[] pixelsFiles = stackDir.list(true);
if (pixelsFiles != null) {
Arrays.sort(pixelsFiles);
for (String pixelsFile : pixelsFiles) {
if (checkSuffix(pixelsFile, "ets")) {
files.add(new Location(stackDir, pixelsFile).getAbsolutePath());
}
}
}
}
}
files.add(file.getAbsolutePath());
usedFiles = files.toArray(new String[files.size()]);
if (expectETS && files.size() == 1) {
String message = "Missing expected .ets files in " + pixelsDir.getAbsolutePath();
if (failOnMissingETS()) {
throw new FormatException(message);
} else {
LOGGER.warn(message);
}
} else if (!expectETS && files.size() > 1) {
LOGGER.warn(".ets files present but not expected");
}
int seriesCount = files.size();
core.clear();
IFDList exifs = parser.getExifIFDs();
int index = 0;
for (int s = 0; s < seriesCount; s++) {
CoreMetadata ms = new CoreMetadata();
core.add(ms);
if (s < files.size() - 1) {
setCoreIndex(index);
parseETSFile(files.get(s), s);
ms.littleEndian = compressionType.get(index) == RAW;
ms.interleaved = ms.rgb;
for (int q = 1; q < ms.resolutionCount; q++) {
int res = core.size() - ms.resolutionCount + q;
core.get(res).littleEndian = ms.littleEndian;
core.get(res).interleaved = ms.interleaved;
}
if (s == 0 && exifs.size() > 0) {
IFD exif = exifs.get(0);
int newX = exif.getIFDIntValue(IFD.PIXEL_X_DIMENSION);
int newY = exif.getIFDIntValue(IFD.PIXEL_Y_DIMENSION);
if (getSizeX() > newX || getSizeY() > newY) {
ms.sizeX = newX;
ms.sizeY = newY;
}
}
index += ms.resolutionCount;
if (s < pyramids.size()) {
ms.seriesMetadata = pyramids.get(s).originalMetadata;
}
setCoreIndex(0);
} else {
IFD ifd = ifds.get(s - files.size() + 1);
PhotoInterp p = ifd.getPhotometricInterpretation();
int samples = ifd.getSamplesPerPixel();
ms.rgb = samples > 1 || p == PhotoInterp.RGB;
ms.sizeX = (int) ifd.getImageWidth();
ms.sizeY = (int) ifd.getImageLength();
ms.sizeZ = 1;
ms.sizeT = 1;
ms.sizeC = ms.rgb ? samples : 1;
ms.littleEndian = ifd.isLittleEndian();
ms.indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null);
ms.imageCount = 1;
ms.pixelType = ifd.getPixelType();
ms.interleaved = false;
ms.falseColor = false;
ms.thumbnail = s != 0;
index++;
}
ms.metadataComplete = true;
ms.dimensionOrder = "XYCZT";
}
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this, true);
String instrument = MetadataTools.createLSID("Instrument", 0);
store.setInstrumentID(instrument, 0);
for (int i = 0; i < pyramids.size(); i++) {
Pyramid pyramid = pyramids.get(i);
store.setObjectiveID(MetadataTools.createLSID("Objective", 0, i), 0, i);
store.setObjectiveNominalMagnification(pyramid.magnification, 0, i);
store.setObjectiveWorkingDistance(FormatTools.createLength(pyramid.workingDistance, UNITS.MICROMETER), 0, i);
for (int q = 0; q < pyramid.objectiveTypes.size(); q++) {
if (pyramid.objectiveTypes.get(q) == 1) {
store.setObjectiveModel(pyramid.objectiveNames.get(q), 0, i);
break;
}
}
store.setObjectiveLensNA(pyramid.numericalAperture, 0, i);
store.setDetectorID(MetadataTools.createLSID("Detector", 0, i), 0, i);
store.setDetectorOffset(pyramid.offset, 0, i);
store.setDetectorGain(pyramid.gain, 0, i);
for (int q = 0; q < pyramid.deviceTypes.size(); q++) {
if (pyramid.deviceTypes.get(q).equals("Camera")) {
if (q < pyramid.deviceNames.size()) {
store.setDetectorModel(pyramid.deviceNames.get(q), 0, i);
}
if (q < pyramid.deviceIDs.size()) {
store.setDetectorSerialNumber(pyramid.deviceIDs.get(q), 0, i);
}
if (q < pyramid.deviceManufacturers.size()) {
store.setDetectorManufacturer(pyramid.deviceManufacturers.get(q), 0, i);
}
store.setDetectorType(getDetectorType("CCD"), 0, i);
break;
}
}
}
int nextPyramid = 0;
for (int i = 0; i < core.size(); ) {
setCoreIndex(i);
Pyramid pyramid = null;
if (nextPyramid < pyramids.size()) {
pyramid = pyramids.get(nextPyramid++);
}
int ii = coreIndexToSeries(i);
if (pyramid != null) {
int nextPlane = 0;
int effectiveSizeC = core.get(i).rgb ? 1 : core.get(i).sizeC;
for (int c = 0; c < effectiveSizeC; c++) {
store.setDetectorSettingsID(MetadataTools.createLSID("Detector", 0, nextPyramid - 1), ii, c);
store.setDetectorSettingsBinning(getBinning(pyramid.binningX + "x" + pyramid.binningY), ii, c);
if (c == 0) {
store.setDetectorSettingsGain(pyramid.redGain, ii, c);
store.setDetectorSettingsOffset(pyramid.redOffset, ii, c);
} else if (c == 1) {
store.setDetectorSettingsGain(pyramid.greenGain, ii, c);
store.setDetectorSettingsOffset(pyramid.greenOffset, ii, c);
} else if (c == 2) {
store.setDetectorSettingsGain(pyramid.blueGain, ii, c);
store.setDetectorSettingsOffset(pyramid.blueOffset, ii, c);
}
if (c < pyramid.channelNames.size()) {
store.setChannelName(pyramid.channelNames.get(c), ii, c);
}
if (c < pyramid.channelWavelengths.size()) {
int wave = pyramid.channelWavelengths.get(c).intValue();
if (wave > 0) {
store.setChannelEmissionWavelength(FormatTools.getEmissionWavelength((double) wave), ii, c);
}
}
for (int z = 0; z < core.get(i).sizeZ; z++) {
for (int t = 0; t < core.get(i).sizeT; t++) {
nextPlane = getIndex(z, c, t);
Long exp = pyramid.defaultExposureTime;
if (c < pyramid.exposureTimes.size()) {
exp = pyramid.exposureTimes.get(c);
}
if (exp != null) {
store.setPlaneExposureTime(FormatTools.createTime(exp / 1000000.0, UNITS.SECOND), ii, nextPlane);
}
store.setPlanePositionX(FormatTools.createLength(pyramid.originX, UNITS.MICROMETER), ii, nextPlane);
store.setPlanePositionY(FormatTools.createLength(pyramid.originY, UNITS.MICROMETER), ii, nextPlane);
}
}
}
}
store.setImageInstrumentRef(instrument, ii);
if (pyramid != null) {
String imageName = pyramid.name;
boolean duplicate = false;
for (int q = 0; q < pyramids.size(); q++) {
if (q != (nextPyramid - 1) && imageName.equals(pyramids.get(q).name)) {
duplicate = true;
break;
}
}
if (!imageName.equals("Overview") && !imageName.equals("Label") && duplicate) {
imageName += " #" + ii;
}
if (imageName.equals("Overview") || imageName.equals("Label")) {
imageName = imageName.toLowerCase();
}
store.setImageName(imageName, ii);
store.setObjectiveSettingsID(MetadataTools.createLSID("Objective", 0, nextPyramid - 1), ii);
store.setObjectiveSettingsRefractiveIndex(pyramid.refractiveIndex, ii);
if (pyramid.physicalSizeX > 0) {
store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(pyramid.physicalSizeX), ii);
}
if (pyramid.physicalSizeY > 0) {
store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(pyramid.physicalSizeY), ii);
}
if (pyramid.acquisitionTime != null) {
// acquisition time is stored in seconds
store.setImageAcquisitionDate(new Timestamp(DateTools.convertDate(pyramid.acquisitionTime * 1000, DateTools.UNIX)), ii);
}
} else {
store.setImageName("macro image", ii);
}
i += core.get(i).resolutionCount;
}
setCoreIndex(0);
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class ZeissLSMReader method initMetadata.
protected void initMetadata(int series) throws FormatException, IOException {
setSeries(series);
IFDList ifds = ifdsList.get(series);
IFD ifd = ifds.get(0);
in.close();
in = new RandomAccessInputStream(getLSMFileFromSeries(series), 16);
in.order(isLittleEndian());
tiffParser = new TiffParser(in);
PhotoInterp photo = ifd.getPhotometricInterpretation();
int samples = ifd.getSamplesPerPixel();
CoreMetadata ms = core.get(series);
ms.sizeX = (int) ifd.getImageWidth();
ms.sizeY = (int) ifd.getImageLength();
ms.rgb = samples > 1 || photo == PhotoInterp.RGB;
ms.interleaved = false;
ms.sizeC = isRGB() ? samples : 1;
ms.pixelType = ifd.getPixelType();
ms.imageCount = ifds.size();
ms.sizeZ = getImageCount();
ms.sizeT = 1;
LOGGER.info("Reading LSM metadata for series #{}", series);
MetadataStore store = makeFilterMetadata();
int instrument = getEffectiveSeries(series);
String imageName = getLSMFileFromSeries(series);
if (imageName.indexOf('.') != -1) {
imageName = imageName.substring(0, imageName.lastIndexOf("."));
}
if (imageName.indexOf(File.separator) != -1) {
imageName = imageName.substring(imageName.lastIndexOf(File.separator) + 1);
}
if (lsmFilenames.length != getSeriesCount()) {
imageName += " #" + (getPosition(series) + 1);
}
// link Instrument and Image
store.setImageID(MetadataTools.createLSID("Image", series), series);
String instrumentID = MetadataTools.createLSID("Instrument", instrument);
store.setInstrumentID(instrumentID, instrument);
store.setImageInstrumentRef(instrumentID, series);
RandomAccessInputStream ras = getCZTag(ifd);
if (ras == null) {
imageNames.add(imageName);
return;
}
ras.seek(16);
ms.sizeZ = ras.readInt();
ras.skipBytes(4);
ms.sizeT = ras.readInt();
int dataType = ras.readInt();
switch(dataType) {
case 2:
addSeriesMeta("DataType", "12 bit unsigned integer");
break;
case 5:
addSeriesMeta("DataType", "32 bit float");
break;
case 0:
addSeriesMeta("DataType", "varying data types");
break;
default:
addSeriesMeta("DataType", "8 bit unsigned integer");
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
ras.seek(0);
addSeriesMeta("MagicNumber ", ras.readInt());
addSeriesMeta("StructureSize", ras.readInt());
addSeriesMeta("DimensionX", ras.readInt());
addSeriesMeta("DimensionY", ras.readInt());
ras.seek(32);
addSeriesMeta("ThumbnailX", ras.readInt());
addSeriesMeta("ThumbnailY", ras.readInt());
// pixel sizes are stored in meters, we need them in microns
pixelSizeX = ras.readDouble() * 1000000;
pixelSizeY = ras.readDouble() * 1000000;
pixelSizeZ = ras.readDouble() * 1000000;
addSeriesMeta("VoxelSizeX", pixelSizeX);
addSeriesMeta("VoxelSizeY", pixelSizeY);
addSeriesMeta("VoxelSizeZ", pixelSizeZ);
originX = ras.readDouble() * 1000000;
originY = ras.readDouble() * 1000000;
originZ = ras.readDouble() * 1000000;
addSeriesMeta("OriginX", originX);
addSeriesMeta("OriginY", originY);
addSeriesMeta("OriginZ", originZ);
} else
ras.seek(88);
int scanType = ras.readShort();
switch(scanType) {
case 0:
addSeriesMeta("ScanType", "x-y-z scan");
ms.dimensionOrder = "XYZCT";
break;
case 1:
addSeriesMeta("ScanType", "z scan (x-z plane)");
ms.dimensionOrder = "XYZCT";
break;
case 2:
addSeriesMeta("ScanType", "line scan");
ms.dimensionOrder = "XYZCT";
break;
case 3:
addSeriesMeta("ScanType", "time series x-y");
ms.dimensionOrder = "XYTCZ";
break;
case 4:
addSeriesMeta("ScanType", "time series x-z");
ms.dimensionOrder = "XYZTC";
break;
case 5:
addSeriesMeta("ScanType", "time series 'Mean of ROIs'");
ms.dimensionOrder = "XYTCZ";
break;
case 6:
addSeriesMeta("ScanType", "time series x-y-z");
ms.dimensionOrder = "XYZTC";
break;
case 7:
addSeriesMeta("ScanType", "spline scan");
ms.dimensionOrder = "XYCTZ";
break;
case 8:
addSeriesMeta("ScanType", "spline scan x-z");
ms.dimensionOrder = "XYCZT";
break;
case 9:
addSeriesMeta("ScanType", "time series spline plane x-z");
ms.dimensionOrder = "XYTCZ";
break;
case 10:
addSeriesMeta("ScanType", "point mode");
ms.dimensionOrder = "XYZCT";
break;
default:
addSeriesMeta("ScanType", "x-y-z scan");
ms.dimensionOrder = "XYZCT";
}
ms.indexed = lut != null && lut[series] != null;
if (isIndexed()) {
ms.rgb = false;
}
if (getSizeC() == 0)
ms.sizeC = 1;
if (isRGB()) {
// shuffle C to front of order string
ms.dimensionOrder = getDimensionOrder().replaceAll("C", "");
ms.dimensionOrder = getDimensionOrder().replaceAll("XY", "XYC");
}
if (getEffectiveSizeC() == 0) {
ms.imageCount = getSizeZ() * getSizeT();
} else {
ms.imageCount = getSizeZ() * getSizeT() * getEffectiveSizeC();
}
if (getImageCount() != ifds.size()) {
int diff = getImageCount() - ifds.size();
ms.imageCount = ifds.size();
if (diff % getSizeZ() == 0) {
ms.sizeT -= (diff / getSizeZ());
} else if (diff % getSizeT() == 0) {
ms.sizeZ -= (diff / getSizeT());
} else if (getSizeZ() > 1) {
ms.sizeZ = ifds.size();
ms.sizeT = 1;
} else if (getSizeT() > 1) {
ms.sizeT = ifds.size();
ms.sizeZ = 1;
}
}
if (getSizeZ() == 0)
ms.sizeZ = getImageCount();
if (getSizeT() == 0)
ms.sizeT = getImageCount() / getSizeZ();
long channelColorsOffset = 0;
long timeStampOffset = 0;
long eventListOffset = 0;
long scanInformationOffset = 0;
long channelWavelengthOffset = 0;
long applicationTagOffset = 0;
channelColor = new Color[getSizeC()];
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
int spectralScan = ras.readShort();
if (spectralScan != 1) {
addSeriesMeta("SpectralScan", "no spectral scan");
} else
addSeriesMeta("SpectralScan", "acquired with spectral scan");
int type = ras.readInt();
switch(type) {
case 1:
addSeriesMeta("DataType2", "calculated data");
break;
case 2:
addSeriesMeta("DataType2", "animation");
break;
default:
addSeriesMeta("DataType2", "original scan data");
}
long[] overlayOffsets = new long[9];
String[] overlayKeys = new String[] { "VectorOverlay", "InputLut", "OutputLut", "ROI", "BleachROI", "MeanOfRoisOverlay", "TopoIsolineOverlay", "TopoProfileOverlay", "LinescanOverlay" };
overlayOffsets[0] = ras.readInt();
overlayOffsets[1] = ras.readInt();
overlayOffsets[2] = ras.readInt();
channelColorsOffset = ras.readInt();
addSeriesMeta("TimeInterval", ras.readDouble());
ras.skipBytes(4);
scanInformationOffset = ras.readInt();
applicationTagOffset = ras.readInt();
timeStampOffset = ras.readInt();
eventListOffset = ras.readInt();
overlayOffsets[3] = ras.readInt();
overlayOffsets[4] = ras.readInt();
ras.skipBytes(4);
addSeriesMeta("DisplayAspectX", ras.readDouble());
addSeriesMeta("DisplayAspectY", ras.readDouble());
addSeriesMeta("DisplayAspectZ", ras.readDouble());
addSeriesMeta("DisplayAspectTime", ras.readDouble());
overlayOffsets[5] = ras.readInt();
overlayOffsets[6] = ras.readInt();
overlayOffsets[7] = ras.readInt();
overlayOffsets[8] = ras.readInt();
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.NO_OVERLAYS) {
for (int i = 0; i < overlayOffsets.length; i++) {
parseOverlays(series, overlayOffsets[i], overlayKeys[i], store);
}
}
addSeriesMeta("ToolbarFlags", ras.readInt());
channelWavelengthOffset = ras.readInt();
ras.skipBytes(64);
} else
ras.skipBytes(182);
if (getSizeC() > 1) {
if (!splitPlanes)
splitPlanes = isRGB();
ms.rgb = false;
if (splitPlanes)
ms.imageCount *= getSizeC();
}
// NB: the Zeiss LSM 5.5 specification indicates that there should be
// 15 32-bit integers here; however, there are actually 16 32-bit
// integers before the tile position offset.
// We have confirmed with Zeiss that this is correct, and the 6.0
// specification was updated to contain the correct information.
// rotations and phases may be reversed
// we only have examples where both values are equal
rotations = ras.readInt();
phases = ras.readInt();
illuminations = ras.readInt();
if (rotations > 1) {
ms.moduloZ.step = ms.sizeZ;
ms.moduloZ.end = ms.sizeZ * (rotations - 1);
ms.moduloZ.type = FormatTools.ROTATION;
ms.sizeZ *= rotations;
}
if (illuminations > 1) {
ms.moduloC.step = ms.sizeC;
ms.moduloC.end = ms.sizeC * (illuminations - 1);
ms.moduloC.type = FormatTools.ILLUMINATION;
ms.moduloC.parentType = FormatTools.CHANNEL;
ms.sizeC *= illuminations;
}
if (phases > 1) {
ms.moduloT.step = ms.sizeT;
ms.moduloT.end = ms.sizeT * (phases - 1);
ms.moduloT.type = FormatTools.PHASE;
ms.sizeT *= phases;
}
for (int c = 0; c < getEffectiveSizeC(); c++) {
String lsid = MetadataTools.createLSID("Channel", series, c);
store.setChannelID(lsid, series, c);
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
ras.skipBytes(52);
int tilePositionOffset = ras.readInt();
ras.skipBytes(36);
int positionOffset = ras.readInt();
// read referenced structures
addSeriesMeta("DimensionZ", getSizeZ());
addSeriesMeta("DimensionChannels", getSizeC());
addSeriesMeta("DimensionM", dimensionM);
addSeriesMeta("DimensionP", dimensionP);
if (lsmFilenames.length == 1) {
xCoordinates.clear();
yCoordinates.clear();
zCoordinates.clear();
}
if (positionOffset != 0) {
in.seek(positionOffset);
int nPositions = in.readInt();
for (int i = 0; i < nPositions; i++) {
double xPos = originX + in.readDouble() * 1000000;
double yPos = originY + in.readDouble() * 1000000;
double zPos = originZ + in.readDouble() * 1000000;
xCoordinates.add(xPos);
yCoordinates.add(yPos);
zCoordinates.add(zPos);
addGlobalMetaList("X position for position", xPos);
addGlobalMetaList("Y position for position", yPos);
addGlobalMetaList("Z position for position", zPos);
}
}
if (tilePositionOffset != 0) {
in.seek(tilePositionOffset);
int nTiles = in.readInt();
for (int i = 0; i < nTiles; i++) {
double xPos = originX + in.readDouble() * 1000000;
double yPos = originY + in.readDouble() * 1000000;
double zPos = originZ + in.readDouble() * 1000000;
if (xCoordinates.size() > i) {
xPos += xCoordinates.get(i);
xCoordinates.set(i, xPos);
} else if (xCoordinates.size() == i) {
xCoordinates.add(xPos);
}
if (yCoordinates.size() > i) {
yPos += yCoordinates.get(i);
yCoordinates.set(i, yPos);
} else if (yCoordinates.size() == i) {
yCoordinates.add(yPos);
}
if (zCoordinates.size() > i) {
zPos += zCoordinates.get(i);
zCoordinates.set(i, zPos);
} else if (zCoordinates.size() == i) {
zCoordinates.add(zPos);
}
addGlobalMetaList("X position for position", xPos);
addGlobalMetaList("Y position for position", yPos);
addGlobalMetaList("Z position for position", zPos);
}
}
if (channelColorsOffset != 0) {
in.seek(channelColorsOffset + 12);
int colorsOffset = in.readInt();
int namesOffset = in.readInt();
if (colorsOffset > 0) {
in.seek(channelColorsOffset + colorsOffset);
lut[getSeries()] = new byte[getSizeC() * 3][256];
core.get(getSeries()).indexed = true;
for (int i = 0; i < getSizeC(); i++) {
if (i >= channelColor.length) {
continue;
}
int color = in.readInt();
int red = color & 0xff;
int green = (color & 0xff00) >> 8;
int blue = (color & 0xff0000) >> 16;
// otherwise set the color to white, as this will display better
if (red == 0 && green == 0 & blue == 0) {
if (i > 0) {
red = channelColor[i - 1].getRed();
green = channelColor[i - 1].getGreen();
blue = channelColor[i - 1].getBlue();
} else {
red = 255;
green = 255;
blue = 255;
}
}
channelColor[i] = new Color(red, green, blue, 255);
for (int j = 0; j < 256; j++) {
lut[getSeries()][i * 3][j] = (byte) ((red / 255.0) * j);
lut[getSeries()][i * 3 + 1][j] = (byte) ((green / 255.0) * j);
lut[getSeries()][i * 3 + 2][j] = (byte) ((blue / 255.0) * j);
}
}
}
if (namesOffset > 0) {
in.seek(channelColorsOffset + namesOffset);
channelNames[series] = new String[getSizeC()];
for (int i = 0; i < getSizeC(); i++) {
if (in.getFilePointer() >= in.length() - 1)
break;
// we want to read until we find a null char
int length = in.readInt();
String name = in.readString(length);
while ((name.length() > 0) && (name.codePointAt(name.length() - 1) == 0)) {
name = name.substring(0, name.length() - 1);
}
if (name.length() <= 128) {
addSeriesMetaList("ChannelName", name);
}
channelNames[series][i] = name;
}
}
}
if (timeStampOffset != 0) {
in.seek(timeStampOffset + 4);
int nStamps = in.readInt();
for (int i = 0; i < nStamps; i++) {
double stamp = in.readDouble();
addSeriesMetaList("TimeStamp", stamp);
timestamps.add(stamp);
}
}
if (eventListOffset != 0) {
in.seek(eventListOffset + 4);
int numEvents = in.readInt();
in.seek(in.getFilePointer() - 4);
in.order(!in.isLittleEndian());
int tmpEvents = in.readInt();
if (numEvents < 0)
numEvents = tmpEvents;
else
numEvents = (int) Math.min(numEvents, tmpEvents);
in.order(!in.isLittleEndian());
if (numEvents > 65535)
numEvents = 0;
for (int i = 0; i < numEvents; i++) {
if (in.getFilePointer() + 16 <= in.length()) {
int size = in.readInt();
double eventTime = in.readDouble();
int eventType = in.readInt();
addSeriesMetaList("Event Time", eventTime);
addSeriesMetaList("Event Type", eventType);
long fp = in.getFilePointer();
int len = size - 16;
if (len > 65536)
len = 65536;
if (len < 0)
len = 0;
addSeriesMetaList("Event Description", in.readString(len));
in.seek(fp + size - 16);
if (in.getFilePointer() < 0)
break;
}
}
}
if (scanInformationOffset != 0) {
in.seek(scanInformationOffset);
nextLaser = nextDetector = 0;
nextFilter = nextDichroicChannel = nextDichroic = 0;
nextDetectChannel = nextIllumChannel = 0;
final List<SubBlock> blocks = new ArrayList<SubBlock>();
while (in.getFilePointer() < in.length() - 12) {
if (in.getFilePointer() < 0)
break;
int entry = in.readInt();
int blockType = in.readInt();
int dataSize = in.readInt();
if (blockType == TYPE_SUBBLOCK) {
SubBlock block = null;
switch(entry) {
case SUBBLOCK_RECORDING:
block = new Recording();
break;
case SUBBLOCK_LASER:
block = new Laser();
break;
case SUBBLOCK_TRACK:
block = new Track();
break;
case SUBBLOCK_DETECTION_CHANNEL:
block = new DetectionChannel();
break;
case SUBBLOCK_ILLUMINATION_CHANNEL:
block = new IlluminationChannel();
break;
case SUBBLOCK_BEAM_SPLITTER:
block = new BeamSplitter();
break;
case SUBBLOCK_DATA_CHANNEL:
block = new DataChannel();
break;
case SUBBLOCK_TIMER:
block = new Timer();
break;
case SUBBLOCK_MARKER:
block = new Marker();
break;
}
if (block != null) {
blocks.add(block);
}
} else if (dataSize + in.getFilePointer() <= in.length() && dataSize > 0) {
in.skipBytes(dataSize);
} else
break;
}
final List<SubBlock> nonAcquiredBlocks = new ArrayList<SubBlock>();
SubBlock[] metadataBlocks = blocks.toArray(new SubBlock[0]);
for (SubBlock block : metadataBlocks) {
block.addToHashtable();
if (!block.acquire) {
nonAcquiredBlocks.add(block);
blocks.remove(block);
}
}
for (int i = 0; i < blocks.size(); i++) {
SubBlock block = blocks.get(i);
// a valid DataChannel or IlluminationChannel
if ((block instanceof IlluminationChannel) && i < blocks.size() - 1) {
SubBlock nextBlock = blocks.get(i + 1);
if (!(nextBlock instanceof DataChannel) && !(nextBlock instanceof IlluminationChannel)) {
((IlluminationChannel) block).wavelength = null;
}
} else // a valid Track or DetectionChannel
if ((block instanceof DetectionChannel) && i > 0) {
SubBlock prevBlock = blocks.get(i - 1);
if (!(prevBlock instanceof Track) && !(prevBlock instanceof DetectionChannel)) {
block.acquire = false;
nonAcquiredBlocks.add(block);
}
}
if (block.acquire)
populateMetadataStore(block, store, series);
}
for (SubBlock block : nonAcquiredBlocks) {
populateMetadataStore(block, store, series);
}
}
if (applicationTagOffset != 0) {
in.seek(applicationTagOffset);
parseApplicationTags();
}
}
imageNames.add(imageName);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (userName != null) {
String experimenterID = MetadataTools.createLSID("Experimenter", 0);
store.setExperimenterID(experimenterID, 0);
store.setExperimenterUserName(userName, 0);
}
Length pixX = FormatTools.getPhysicalSizeX(pixelSizeX);
Length pixY = FormatTools.getPhysicalSizeY(pixelSizeY);
Length pixZ = FormatTools.getPhysicalSizeZ(pixelSizeZ);
if (pixX != null) {
store.setPixelsPhysicalSizeX(pixX, series);
}
if (pixY != null) {
store.setPixelsPhysicalSizeY(pixY, series);
}
if (pixZ != null) {
store.setPixelsPhysicalSizeZ(pixZ, series);
}
for (int i = 0; i < getSizeC(); i++) {
store.setChannelColor(channelColor[i], series, i);
if (channelNames[series] != null) {
store.setChannelName(channelNames[series][i], series, i);
}
}
int stampIndex = 0;
for (int i = 0; i < series; i++) {
stampIndex += core.get(i).sizeT;
}
double firstStamp = 0;
if (timestamps.size() > 0 && stampIndex < timestamps.size()) {
firstStamp = timestamps.get(stampIndex).doubleValue();
}
for (int i = 0; i < getImageCount(); i++) {
int[] zct = FormatTools.getZCTCoords(this, i);
if (getSizeT() > 1 && zct[2] < timestamps.size() - stampIndex) {
double thisStamp = timestamps.get(stampIndex + zct[2]).doubleValue();
store.setPlaneDeltaT(new Time(thisStamp - firstStamp, UNITS.SECOND), series, i);
}
if (xCoordinates.size() > series) {
final Double xCoord = xCoordinates.get(series);
final Double yCoord = yCoordinates.get(series);
final Double zCoord = zCoordinates.get(series);
if (xCoord == null) {
store.setPlanePositionX(null, series, i);
} else {
final Length x = new Length(xCoord, UNITS.REFERENCEFRAME);
store.setPlanePositionX(x, series, i);
}
if (yCoord == null) {
store.setPlanePositionY(null, series, i);
} else {
final Length y = new Length(yCoord, UNITS.REFERENCEFRAME);
store.setPlanePositionY(y, series, i);
}
if (zCoord == null) {
store.setPlanePositionZ(null, series, i);
} else {
final Length z = new Length(zCoord, UNITS.REFERENCEFRAME);
store.setPlanePositionZ(z, series, i);
}
}
}
}
ras.close();
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class ZeissLSMReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
if (checkSuffix(id, MDB_SUFFIX)) {
lsmFilenames = parseMDB(id);
} else
lsmFilenames = new String[] { id };
if (lsmFilenames == null || lsmFilenames.length == 0) {
throw new FormatException("LSM files were not found.");
}
totalROIs = 0;
timestamps = new ArrayList<Double>();
imageNames = new ArrayList<String>();
xCoordinates = new ArrayList<Double>();
yCoordinates = new ArrayList<Double>();
zCoordinates = new ArrayList<Double>();
seriesCounts = new HashMap<String, Integer>();
int seriesCount = 0;
final List<String> validFiles = new ArrayList<String>();
for (String filename : lsmFilenames) {
try {
int extraSeries = getExtraSeries(filename);
seriesCounts.put(filename, extraSeries);
seriesCount += extraSeries;
validFiles.add(filename);
} catch (IOException e) {
LOGGER.debug("Failed to parse " + filename, e);
}
}
lsmFilenames = validFiles.toArray(new String[validFiles.size()]);
core.clear();
for (int c = 0; c < seriesCount; c++) {
CoreMetadata ms = new CoreMetadata();
core.add(ms);
}
channelNames = new String[seriesCount][];
ifdsList = new ArrayList<IFDList>();
for (int series = 0; series < seriesCount; series++) {
ifdsList.add(null);
}
int realSeries = 0;
for (int i = 0; i < lsmFilenames.length; i++) {
RandomAccessInputStream stream = null;
try {
stream = new RandomAccessInputStream(lsmFilenames[i], 16);
int count = seriesCounts.get(lsmFilenames[i]);
TiffParser tp = new TiffParser(stream);
Boolean littleEndian = tp.checkHeader();
long[] ifdOffsets = tp.getIFDOffsets();
int ifdsPerSeries = (ifdOffsets.length / 2) / count;
int offset = 0;
Object zeissTag = null;
for (int s = 0; s < count; s++, realSeries++) {
CoreMetadata ms = core.get(realSeries);
ms.littleEndian = littleEndian;
IFDList ifds = new IFDList();
while (ifds.size() < ifdsPerSeries) {
tp.setDoCaching(offset == 0);
IFD ifd = tp.getIFD(ifdOffsets[offset]);
if (offset == 0)
zeissTag = ifd.get(ZEISS_ID);
if (offset > 0 && ifds.isEmpty()) {
ifd.putIFDValue(ZEISS_ID, zeissTag);
}
ifds.add(ifd);
if (zeissTag != null)
offset += 2;
else
offset++;
}
for (IFD ifd : ifds) {
tp.fillInIFD(ifd);
}
ifdsList.set(realSeries, ifds);
}
} catch (IOException e) {
throw e;
} finally {
if (stream != null)
stream.close();
}
}
MetadataStore store = makeFilterMetadata();
lut = new byte[ifdsList.size()][][];
long[] previousStripOffsets = null;
for (int series = 0; series < ifdsList.size(); series++) {
// the previous series
if (series > 0 && getSizeT() > 1) {
previousStripOffsets = null;
}
IFDList ifds = ifdsList.get(series);
for (IFD ifd : ifds) {
// than LZW compression is used
if (ifd.getCompression() != TiffCompression.LZW) {
ifd.putIFDValue(IFD.PREDICTOR, 1);
}
}
// fix the offsets for > 4 GB files
RandomAccessInputStream s = null;
try {
s = new RandomAccessInputStream(getLSMFileFromSeries(series));
for (int i = 0; i < ifds.size(); i++) {
long[] stripOffsets = ifds.get(i).getStripOffsets();
if (stripOffsets == null || (i != 0 && previousStripOffsets == null)) {
throw new FormatException("Strip offsets are missing; this is an invalid file.");
} else if (i == 0 && previousStripOffsets == null) {
previousStripOffsets = stripOffsets;
continue;
}
boolean neededAdjustment = false;
for (int j = 0; j < stripOffsets.length; j++) {
if (j >= previousStripOffsets.length)
break;
if (stripOffsets[j] < previousStripOffsets[j]) {
stripOffsets[j] = (previousStripOffsets[j] & ~0xffffffffL) | (stripOffsets[j] & 0xffffffffL);
if (stripOffsets[j] < previousStripOffsets[j]) {
long newOffset = stripOffsets[j] + 0x100000000L;
if (newOffset < s.length()) {
stripOffsets[j] = newOffset;
}
}
neededAdjustment = true;
}
if (neededAdjustment) {
ifds.get(i).putIFDValue(IFD.STRIP_OFFSETS, stripOffsets);
}
}
previousStripOffsets = stripOffsets;
}
initMetadata(series);
} catch (IOException e) {
throw e;
} finally {
if (s != null)
s.close();
}
}
for (int i = 0; i < getSeriesCount(); i++) {
CoreMetadata ms = core.get(i);
ms.imageCount = ms.sizeZ * ms.sizeC * ms.sizeT;
}
MetadataTools.populatePixels(store, this, true);
for (int series = 0; series < ifdsList.size(); series++) {
setSeries(series);
if (series < imageNames.size()) {
store.setImageName(imageNames.get(series), series);
}
if (acquiredDate.containsKey(series)) {
store.setImageAcquisitionDate(new Timestamp(acquiredDate.get(series)), series);
}
}
setSeries(0);
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class TCSReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
Location l = new Location(id).getAbsoluteFile();
Location parent = l.getParentFile();
String[] list = parent.list();
Arrays.sort(list);
boolean isXML = checkSuffix(id, XML_SUFFIX);
if (list != null) {
for (String file : list) {
if (checkSuffix(file, XML_SUFFIX) && !isXML && isGroupFiles()) {
xmlFile = new Location(parent, file).getAbsolutePath();
break;
} else if (checkSuffix(file, TiffReader.TIFF_SUFFIXES) && isXML) {
initFile(new Location(parent, file).getAbsolutePath());
return;
}
}
}
if (isXML)
xmlFile = l.getAbsolutePath();
super.initFile(id);
MetadataStore store = makeFilterMetadata();
in = new RandomAccessInputStream(id, 16);
tiffParser = new TiffParser(in);
tiffs = new ArrayList<String>();
IFDList ifds = tiffParser.getIFDs();
String date = ifds.get(0).getIFDStringValue(IFD.DATE_TIME);
if (date != null) {
datestamp = DateTools.getTime(date, "yyyy:MM:dd HH:mm:ss");
}
groupFiles();
addGlobalMeta("Number of image files", tiffs.size());
tiffReaders = new TiffReader[tiffs.size()];
for (int i = 0; i < tiffReaders.length; i++) {
tiffReaders[i] = new TiffReader();
}
tiffReaders[0].setId(tiffs.get(0));
int[] ch = new int[ifds.size()];
int[] idx = new int[ifds.size()];
long[] stamp = new long[ifds.size()];
int channelCount = 0;
CoreMetadata ms0 = core.get(0);
ms0.sizeZ = 1;
ms0.sizeC = tiffReaders[0].getSizeC();
ms0.dimensionOrder = isRGB() ? "XYC" : "XY";
if (isGroupFiles()) {
try {
FilePattern fp = new FilePattern(new Location(currentId).getAbsoluteFile());
AxisGuesser guesser = new AxisGuesser(fp, "XYTZC", 1, ifds.size(), 1, true);
int[] axisTypes = guesser.getAxisTypes();
int[] count = fp.getCount();
for (int i = axisTypes.length - 1; i >= 0; i--) {
if (axisTypes[i] == AxisGuesser.Z_AXIS) {
if (getDimensionOrder().indexOf('Z') == -1) {
ms0.dimensionOrder += 'Z';
}
ms0.sizeZ *= count[i];
} else if (axisTypes[i] == AxisGuesser.C_AXIS) {
if (getDimensionOrder().indexOf('C') == -1) {
ms0.dimensionOrder += 'C';
}
ms0.sizeC *= count[i];
}
}
} catch (NullPointerException e) {
}
}
for (int i = 0; i < ifds.size(); i++) {
String document = ifds.get(i).getIFDStringValue(IFD.DOCUMENT_NAME);
if (document == null)
continue;
int index = document.indexOf("INDEX");
String s = document.substring(8, index).trim();
ch[i] = Integer.parseInt(s);
if (ch[i] > channelCount)
channelCount = ch[i];
int space = document.indexOf(" ", index + 6);
if (space < 0)
continue;
String n = document.substring(index + 6, space).trim();
idx[i] = Integer.parseInt(n);
date = document.substring(space, document.indexOf("FORMAT")).trim();
stamp[i] = DateTools.getTime(date, DATE_FORMAT, ".");
addGlobalMetaList("Timestamp for plane", stamp[i]);
}
ms0.sizeT = 0;
// determine the axis sizes and ordering
boolean unique = true;
for (int i = 0; i < stamp.length; i++) {
for (int j = i + 1; j < stamp.length; j++) {
if (stamp[j] == stamp[i]) {
unique = false;
break;
}
}
if (unique) {
ms0.sizeT++;
if (getDimensionOrder().indexOf('T') < 0) {
ms0.dimensionOrder += 'T';
}
} else if (i > 0) {
if ((ch[i] != ch[i - 1]) && getDimensionOrder().indexOf('C') < 0) {
ms0.dimensionOrder += 'C';
} else if (getDimensionOrder().indexOf('Z') < 0) {
ms0.dimensionOrder += 'Z';
}
}
unique = true;
}
if (getDimensionOrder().indexOf('Z') < 0)
ms0.dimensionOrder += 'Z';
if (getDimensionOrder().indexOf('C') < 0)
ms0.dimensionOrder += 'C';
if (getDimensionOrder().indexOf('T') < 0)
ms0.dimensionOrder += 'T';
if (getSizeC() == 0)
ms0.sizeC = 1;
if (getSizeT() == 0)
ms0.sizeT = 1;
if (channelCount == 0)
channelCount = 1;
if (getSizeZ() <= 1) {
ms0.sizeZ = ifds.size() / (getSizeT() * channelCount);
}
ms0.sizeC *= channelCount;
ms0.imageCount = getSizeZ() * getSizeT() * getSizeC();
// cut up comment
String comment = ifds.get(0).getComment();
if (comment != null && comment.startsWith("[") && getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
String[] lines = comment.split("\n");
for (String line : lines) {
if (!line.startsWith("[")) {
int eq = line.indexOf('=');
if (eq < 0)
continue;
String key = line.substring(0, eq).trim();
String value = line.substring(eq + 1).trim();
if (key.equals("VoxelSizeX")) {
try {
voxelX = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
} else if (key.equals("VoxelSizeY")) {
try {
voxelY = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
} else if (key.equals("VoxelSizeZ")) {
try {
voxelZ = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
}
addGlobalMeta(key, value);
}
}
metadata.remove("Comment");
}
ms0.sizeX = tiffReaders[0].getSizeX();
ms0.sizeY = tiffReaders[0].getSizeY();
ms0.rgb = tiffReaders[0].isRGB();
ms0.pixelType = tiffReaders[0].getPixelType();
ms0.littleEndian = tiffReaders[0].isLittleEndian();
ms0.interleaved = tiffReaders[0].isInterleaved();
ms0.falseColor = true;
ms0.indexed = tiffReaders[0].isIndexed();
if (isRGB())
ms0.imageCount /= (getSizeC() / channelCount);
if (getSizeZ() * getSizeT() * getEffectiveSizeC() != (ifds.size() * tiffReaders.length)) {
int c = getEffectiveSizeC();
if (c == 0)
c = 1;
ms0.sizeT = (ifds.size() * tiffReaders.length) / (c * getSizeZ());
ms0.imageCount = getSizeT() * c * getSizeZ();
if (getSizeT() == 0) {
ms0.sizeT = 1;
ms0.imageCount = ifds.size() * tiffReaders.length;
}
}
if (getImageCount() == ifds.size() * getSizeZ() * getSizeT() && ifds.size() > 1) {
if (getSizeZ() == 1) {
ms0.sizeZ = ifds.size();
} else if (getSizeT() == 1) {
ms0.sizeT = ifds.size();
} else
ms0.sizeZ *= ifds.size();
}
if (xmlFile != null) {
// parse XML metadata
String xml = DataTools.readFile(xmlFile);
xml = XMLTools.sanitizeXML(PREFIX + xml + SUFFIX);
LeicaHandler handler = new LeicaHandler(store, getMetadataOptions().getMetadataLevel());
XMLTools.parseXML(xml, handler);
metadata = handler.getGlobalMetadata();
MetadataTools.merge(handler.getGlobalMetadata(), metadata, "");
core = handler.getCoreMetadataList();
for (int i = 0; i < getSeriesCount(); i++) {
CoreMetadata ms = core.get(i);
if (tiffs.size() < ms.imageCount) {
int div = ms.imageCount / ms.sizeC;
ms.imageCount = tiffs.size();
if (div >= ms.sizeZ)
ms.sizeZ /= div;
else if (div >= ms.sizeT)
ms.sizeT /= div;
}
ms.dimensionOrder = getSizeZ() > getSizeT() ? "XYCZT" : "XYCTZ";
ms.rgb = false;
ms.interleaved = false;
ms.indexed = tiffReaders[0].isIndexed();
}
}
MetadataTools.populatePixels(store, this, true);
Length sizeX = FormatTools.getPhysicalSizeX(voxelX);
Length sizeY = FormatTools.getPhysicalSizeY(voxelY);
Length sizeZ = FormatTools.getPhysicalSizeZ(voxelZ);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
if (sizeZ != null) {
store.setPixelsPhysicalSizeZ(sizeZ, 0);
}
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class ZeissTIFFReader method fillMetadataPass1.
@Override
protected void fillMetadataPass1(MetadataStore store) throws FormatException, IOException {
super.fillMetadataPass1(store);
int nplanes = tiffInfo.handler.planes.size();
if (rawCount == 0)
rawCount = nplanes;
else if (rawCount != nplanes)
LOGGER.warn("Problem determining correct number of image planes. Document reported {}, while {} were found", rawCount, nplanes);
if (rawCount == 0)
LOGGER.warn("No image planes found");
// Determine number of separate timepoints, channels, and z slices.
for (ZeissTIFFHandler.Plane p : tiffInfo.handler.planes) {
Plane np = new Plane();
boolean tag_1047_present = false;
for (Tag t : p.tagset.tags) {
if (t.getKeyID() == 1047)
tag_1047_present = true;
}
for (Tag t : p.tagset.tags) {
// better to use the latter.
if (t.getKeyID() != 1025 || tag_1047_present == false)
np.tags.put(t.getKey(), t.getValue());
}
np.taglist = p.tagset.tags;
// Other planes: _files/_meta
if (nplanes == 1 && tiffInfo.multifile == false)
np.filename = tiffInfo.origname;
else
np.filename = new CaseInsensitiveLocation(tiffInfo.basedir + "/" + tiffInfo.prefix + "_" + p.basename + ".tif").getAbsolutePath();
int tileid = parseInt(np.tags.get("ImageTile Index"));
int channelid = parseInt(np.tags.get("Image Channel Index"));
int sliceid = parseInt(np.tags.get("Image Index Z"));
int timepointid = parseInt(np.tags.get("Image Index T"));
int xsize = parseInt(np.tags.get("Camera Frame Width"));
int ysize = parseInt(np.tags.get("Camera Frame Height"));
np.site = tileid;
tileIndices.add(tileid);
channelIndices.add(channelid);
zIndices.add(sliceid);
timepointIndices.add(timepointid);
if (getSizeX() == 0) {
core.get(0).sizeX = xsize;
core.get(0).sizeY = ysize;
}
planes.add(np);
if (bpp == 0) {
tiffReader.setId(np.filename);
IFDList ifds = tiffReader.getIFDs();
tiffReader.close();
IFD firstIFD = ifds.get(0);
int bits = firstIFD.getBitsPerSample()[0];
int samples = firstIFD.getSamplesPerPixel();
bpp = (bits / 8) * samples;
}
}
// Filter out images with an incomplete number of z slices.
// This is to work around a probable bug in AxioVision.
int full = Collections.max(tileIndices);
int[] indexCount = new int[full + 1];
int max = 0;
for (Plane plane : planes) {
indexCount[plane.site]++;
if (indexCount[plane.site] > max)
max = indexCount[plane.site];
}
for (int i = 0; i < full + 1; i++) {
if (indexCount[i] != max)
tileIndices.remove(i);
}
for (Iterator<Plane> i = planes.iterator(); i.hasNext(); ) {
Plane plane = i.next();
if (!tileIndices.contains(plane.site)) {
i.remove();
}
}
// Allocates memory for arrays below
countImages();
for (int i = 0; i < planes.size(); i++) {
Plane plane = planes.get(i);
int channelid = parseInt(plane.tags.get("Image Channel Index"));
int sliceid = parseInt(plane.tags.get("Image Index Z"));
int timepointid = parseInt(plane.tags.get("Image Index T"));
coordinates[i][0] = sliceid;
coordinates[i][1] = channelid;
coordinates[i][2] = timepointid;
imageFiles[i] = plane.filename;
}
int total = tileIndices.size() * channelIndices.size() * zIndices.size() * timepointIndices.size();
if (total != planes.size())
LOGGER.warn("Number of image planes not detected correctly: total={} planes.size={}", total, planes.size());
}
Aggregations