use of loci.common.RandomAccessInputStream in project bioformats by openmicroscopy.
the class OxfordInstrumentsReader 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);
CoreMetadata m = core.get(0);
m.littleEndian = true;
in.order(isLittleEndian());
in.seek(48);
String comment = in.readString(32);
String dateTime = readDate();
in.skipBytes(8);
double xSize = -in.readFloat() + in.readFloat();
in.skipBytes(20);
double ySize = -in.readFloat() + in.readFloat();
in.skipBytes(24);
double zMin = in.readFloat();
double zMax = in.readFloat();
in.skipBytes(864);
m.sizeX = in.readInt();
m.sizeY = in.readInt();
in.skipBytes(28);
if (getSizeX() == 0 && getSizeY() == 0) {
m.sizeX = in.readInt();
m.sizeY = in.readInt();
in.skipBytes(196);
} else
in.skipBytes(204);
m.pixelType = FormatTools.UINT16;
m.sizeZ = 1;
m.sizeC = 1;
m.sizeT = 1;
m.imageCount = 1;
m.rgb = false;
m.indexed = false;
m.dimensionOrder = "XYZCT";
m.interleaved = false;
if (FormatTools.getPlaneSize(this) + in.getFilePointer() > in.length()) {
m.sizeY = 1;
}
int lutSize = in.readInt();
in.skipBytes(lutSize);
headerSize = in.getFilePointer();
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
in.skipBytes(FormatTools.getPlaneSize(this));
int nMetadataStrings = in.readInt();
for (int i = 0; i < nMetadataStrings; i++) {
int length = in.readInt();
String s = in.readString(length);
if (s.indexOf(':') != -1) {
String key = s.substring(0, s.indexOf(':')).trim();
String value = s.substring(s.indexOf(':') + 1).trim();
if (!value.equals("-")) {
addGlobalMeta(key, value);
}
}
}
addGlobalMeta("Description", comment);
addGlobalMeta("Acquisition date", dateTime);
addGlobalMeta("X size (um)", xSize);
addGlobalMeta("Y size (um)", ySize);
addGlobalMeta("Z minimum (um)", zMin);
addGlobalMeta("Z maximum (um)", zMax);
}
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
store.setImageDescription(comment, 0);
if (dateTime != null) {
store.setImageAcquisitionDate(new Timestamp(dateTime), 0);
}
double physicalSizeX = xSize / getSizeX();
double physicalSizeY = ySize / getSizeY();
Length sizeX = FormatTools.getPhysicalSizeX(physicalSizeX);
Length sizeY = FormatTools.getPhysicalSizeY(physicalSizeY);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
}
use of loci.common.RandomAccessInputStream in project bioformats by openmicroscopy.
the class PCIReader method getOptimalTileHeight.
/* @see loci.formats.IFormatReader#getOptimalTileHeight() */
@Override
public int getOptimalTileHeight() {
FormatTools.assertId(currentId, true, 1);
String file = imageFiles.get(0);
try {
if (poi == null) {
initPOIService();
}
RandomAccessInputStream s = poi.getDocumentStream(file);
TiffParser tp = new TiffParser(s);
if (tp.isValidHeader()) {
IFD ifd = tp.getFirstIFD();
s.close();
return (int) ifd.getTileLength();
}
s.close();
} catch (FormatException e) {
LOGGER.debug("Could not retrieve tile height", e);
} catch (IOException e) {
LOGGER.debug("Could not retrieve tile height", e);
}
return super.getOptimalTileHeight();
}
use of loci.common.RandomAccessInputStream in project bioformats by openmicroscopy.
the class MRCReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
public void initFile(String id) throws FormatException, IOException {
super.initFile(id);
in = new RandomAccessInputStream(id);
MetadataLevel level = getMetadataOptions().getMetadataLevel();
CoreMetadata m = core.get(0);
LOGGER.info("Reading header");
// check endianness
in.seek(ENDIANNESS_OFFSET);
m.littleEndian = in.read() == 68;
// read dimension information from 1024 byte header
in.seek(0);
in.order(isLittleEndian());
m.sizeX = in.readInt();
m.sizeY = in.readInt();
m.sizeZ = in.readInt();
// We are using BigInteger here because of the very real possiblity
// of not just an int overflow but also a long overflow when multiplying
// sizeX * sizeY * sizeZ.
BigInteger v = BigInteger.valueOf(getSizeX());
v = v.multiply(BigInteger.valueOf(getSizeY()));
v = v.multiply(BigInteger.valueOf(getSizeZ()));
if (getSizeX() < 0 || getSizeY() < 0 || getSizeZ() < 0 || (v.compareTo(BigInteger.valueOf(in.length())) > 0)) {
LOGGER.debug("Detected endianness is wrong, swapping");
m.littleEndian = !isLittleEndian();
in.seek(0);
in.order(isLittleEndian());
m.sizeX = in.readInt();
m.sizeY = in.readInt();
m.sizeZ = in.readInt();
}
m.sizeC = 1;
m.rgb = false;
int mode = in.readInt();
switch(mode) {
case 0:
in.seek(IMODSTAMP_OFFSET);
if (in.readInt() == 1146047817) {
m.pixelType = FormatTools.INT8;
} else {
m.pixelType = FormatTools.UINT8;
}
break;
case 1:
m.pixelType = FormatTools.INT16;
break;
case 6:
m.pixelType = FormatTools.UINT16;
break;
case 2:
m.pixelType = FormatTools.FLOAT;
break;
case 3:
m.pixelType = FormatTools.UINT32;
break;
case 4:
m.pixelType = FormatTools.DOUBLE;
break;
case 16:
m.sizeC = 3;
m.pixelType = FormatTools.UINT8;
m.rgb = true;
break;
}
in.seek(GRIDSIZE_OFFSET);
// pixel size = xlen / mx
double xSize = 0d, ySize = 0d, zSize = 0d;
if (level != MetadataLevel.MINIMUM) {
int mx = in.readInt();
int my = in.readInt();
int mz = in.readInt();
float xlen = in.readFloat();
float ylen = in.readFloat();
float zlen = in.readFloat();
// physical sizes are stored in ångströms
xSize = (xlen / mx);
ySize = (ylen / my);
zSize = (zlen / mz);
addGlobalMeta("Grid size (X)", mx);
addGlobalMeta("Grid size (Y)", my);
addGlobalMeta("Grid size (Z)", mz);
addGlobalMeta("Cell size (X)", xlen);
addGlobalMeta("Cell size (Y)", ylen);
addGlobalMeta("Cell size (Z)", zlen);
addGlobalMeta("Alpha angle", in.readFloat());
addGlobalMeta("Beta angle", in.readFloat());
addGlobalMeta("Gamma angle", in.readFloat());
in.skipBytes(12);
// min, max and mean pixel values
} else
in.skipBytes(48);
double minValue = in.readFloat();
double maxValue = in.readFloat();
addGlobalMeta("Minimum pixel value", minValue);
addGlobalMeta("Maximum pixel value", maxValue);
addGlobalMeta("Mean pixel value", in.readFloat());
int bytes = FormatTools.getBytesPerPixel(getPixelType());
double range = Math.pow(2, bytes * 8) - 1;
double pixelTypeMin = 0;
boolean signed = FormatTools.isSigned(getPixelType());
if (signed) {
pixelTypeMin -= (range / 2);
}
double pixelTypeMax = pixelTypeMin + range;
// See https://trac.openmicroscopy.org/ome/ticket/4619
if (pixelTypeMax < maxValue || pixelTypeMin > minValue && signed) {
switch(getPixelType()) {
case FormatTools.INT16:
m.pixelType = FormatTools.UINT16;
break;
case FormatTools.INT32:
m.pixelType = FormatTools.UINT32;
break;
}
}
int ispg = in.readInt();
addGlobalMeta("ISPG", ispg);
addGlobalMeta("Is data cube", ispg == 1);
extHeaderSize = in.readInt();
if (level != MetadataLevel.MINIMUM) {
in.skipBytes(64);
int idtype = in.readShort();
String type = "unknown";
if (idtype >= 0 && idtype < TYPES.length)
type = TYPES[idtype];
addGlobalMeta("Series type", type);
addGlobalMeta("Lens", in.readShort());
addGlobalMeta("ND1", in.readShort());
addGlobalMeta("ND2", in.readShort());
addGlobalMeta("VD1", in.readShort());
addGlobalMeta("VD2", in.readShort());
for (int i = 0; i < 6; i++) {
addGlobalMetaList("Angle", in.readFloat());
}
in.skipBytes(24);
addGlobalMeta("Number of useful labels", in.readInt());
for (int i = 0; i < 10; i++) {
addGlobalMetaList("Label", in.readString(80));
}
}
LOGGER.info("Populating metadata");
m.sizeT = 1;
m.dimensionOrder = isRGB() ? "XYCZT" : "XYZTC";
m.imageCount = getSizeZ() * (isRGB() ? 1 : getSizeC());
m.interleaved = true;
m.indexed = false;
m.falseColor = false;
m.metadataComplete = true;
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
if (level != MetadataLevel.MINIMUM) {
Length sizeX = FormatTools.getPhysicalSizeX(xSize, UNITS.ANGSTROM);
Length sizeY = FormatTools.getPhysicalSizeY(ySize, UNITS.ANGSTROM);
Length sizeZ = FormatTools.getPhysicalSizeZ(zSize, UNITS.ANGSTROM);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
if (sizeZ != null) {
store.setPixelsPhysicalSizeZ(sizeZ, 0);
}
}
}
use of loci.common.RandomAccessInputStream in project bioformats by openmicroscopy.
the class FlexReader method parseFlexFile.
/**
* Parses XML metadata from the Flex file corresponding to the given well.
* If the 'firstFile' flag is set, then the core metadata is also
* populated.
*/
private void parseFlexFile(int currentWell, int wellRow, int wellCol, int field, boolean firstFile, MetadataStore store) throws FormatException, IOException {
LOGGER.info("Parsing .flex file (well {}{}, field {})", (char) (wellRow + 'A'), wellCol + 1, field);
FlexFile file = lookupFile(wellRow, wellCol, field < 0 ? 0 : field);
if (file == null)
return;
int originalFieldCount = fieldCount;
if (xPositions == null)
xPositions = new ArrayList<Double>();
if (yPositions == null)
yPositions = new ArrayList<Double>();
if (xSizes == null)
xSizes = new ArrayList<Double>();
if (ySizes == null)
ySizes = new ArrayList<Double>();
if (cameraIDs == null)
cameraIDs = new ArrayList<String>();
if (lightSourceIDs == null)
lightSourceIDs = new ArrayList<String>();
if (objectiveIDs == null)
objectiveIDs = new ArrayList<String>();
if (lightSourceCombinationIDs == null) {
lightSourceCombinationIDs = new HashMap<String, List<String>>();
}
if (lightSourceCombinationRefs == null) {
lightSourceCombinationRefs = new ArrayList<String>();
}
if (cameraRefs == null)
cameraRefs = new ArrayList<String>();
if (objectiveRefs == null)
objectiveRefs = new ArrayList<String>();
if (binnings == null)
binnings = new ArrayList<String>();
if (filterSets == null)
filterSets = new ArrayList<String>();
if (filterSetMap == null)
filterSetMap = new HashMap<String, FilterGroup>();
// parse factors from XML
LOGGER.debug("Parsing XML from {}", file.file);
int nOffsets = file.offsets != null ? file.offsets.length : 0;
IFD ifd = null;
if (nOffsets == 0) {
ifd = file.ifds.get(0);
} else {
RandomAccessInputStream ras = new RandomAccessInputStream(file.file);
try {
TiffParser parser = new TiffParser(ras);
ifd = parser.getFirstIFD();
} finally {
ras.close();
}
}
String xml = XMLTools.sanitizeXML(ifd.getIFDStringValue(FLEX));
final List<String> n = new ArrayList<String>();
final List<String> f = new ArrayList<String>();
DefaultHandler handler = new FlexHandler(n, f, store, firstFile, currentWell, field);
LOGGER.info("Parsing XML in .flex file");
xml = xml.trim();
// some files have a trailing ">" or "%", which needs to be removed
if (xml.endsWith(">>") || xml.endsWith("%")) {
xml = xml.substring(0, xml.length() - 1);
}
XMLTools.parseXML(xml.getBytes(Constants.ENCODING), handler);
channelNames = n.toArray(new String[n.size()]);
if (firstFile) {
populateCoreMetadata(wellRow, wellCol, field < 0 ? 0 : field, n);
}
int totalPlanes = getSeriesCount() * getImageCount();
LOGGER.info("Populating pixel scaling factors");
// verify factor count
int nsize = n.size();
int fsize = f.size();
if (nsize != fsize || nsize != totalPlanes) {
LOGGER.warn("mismatch between image count, names and factors " + "(count={}, names={}, factors={})", new Object[] { totalPlanes, nsize, fsize });
}
if (firstFile) {
for (String ns : n) {
addGlobalMetaList("Name", ns);
}
for (String fs : f) {
addGlobalMetaList("Factor", fs);
}
}
// parse factor values
file.factors = new double[totalPlanes];
int max = 0;
boolean oneFactors = true;
for (int i = 0; i < fsize; i++) {
String factor = f.get(i);
double q = 1;
try {
q = Double.parseDouble(factor);
} catch (NumberFormatException exc) {
LOGGER.warn("invalid factor #{}: {}", i, factor);
}
if (i < file.factors.length) {
file.factors[i] = q;
if (q > file.factors[max])
max = i;
if (oneFactors && q != 1d) {
oneFactors = false;
}
}
}
if (fsize < file.factors.length) {
Arrays.fill(file.factors, fsize, file.factors.length, 1);
}
// determine pixel type
if (file.factors[max] > 256) {
core.get(0).pixelType = FormatTools.UINT32;
} else if (file.factors[max] > 1) {
core.get(0).pixelType = FormatTools.UINT16;
}
for (int i = 1; i < core.size(); i++) {
core.get(i).pixelType = getPixelType();
}
if (!firstFile) {
fieldCount = originalFieldCount;
}
if (oneFactors) {
file.factors = null;
}
}
use of loci.common.RandomAccessInputStream in project bioformats by openmicroscopy.
the class FluoviewReader method initStandardMetadata.
// -- Internal BaseTiffReader API methods --
/* @see loci.formats.BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
super.initStandardMetadata();
// First, we want to determine whether this file is a Fluoview TIFF.
// Originally, Andor TIFF had its own reader; however, the two formats are
// very similar, so it made more sense to merge the two formats into one
// reader.
short[] s = ifds.get(0).getIFDShortArray(MMHEADER);
if (s == null) {
initAlternateMetadata();
return;
}
byte[] mmheader = shortArrayToBytes(s);
RandomAccessInputStream ras = new RandomAccessInputStream(mmheader);
ras.order(isLittleEndian());
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
put("Header Flag", ras.readShort());
put("Image Type", ras.read());
String name = ras.readString(257);
name = name.substring(0, name.indexOf("\0"));
put("Image name", name);
// skip pointer to data field
ras.skipBytes(4);
put("Number of colors", ras.readInt());
// skip pointer to palette field
ras.skipBytes(4);
// skip pointer to other palette field
ras.skipBytes(4);
put("Comment size", ras.readInt());
// skip pointer to comment field
ras.skipBytes(4);
} else
ras.skipBytes(284);
// read dimension information
String[] names = new String[10];
int[] sizes = new int[10];
double[] resolutions = new double[10];
for (int i = 0; i < 10; i++) {
names[i] = ras.readString(16);
sizes[i] = ras.readInt();
double origin = ras.readDouble();
resolutions[i] = ras.readDouble();
put("Dimension " + (i + 1) + " Name", names[i]);
put("Dimension " + (i + 1) + " Size", sizes[i]);
put("Dimension " + (i + 1) + " Origin", origin);
put("Dimension " + (i + 1) + " Resolution", resolutions[i]);
put("Dimension " + (i + 1) + " Units", ras.readString(64));
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
// skip pointer to spatial position data
ras.skipBytes(4);
put("Map type", ras.readShort());
put("Map min", ras.readDouble());
put("Map max", ras.readDouble());
put("Min value", ras.readDouble());
put("Max value", ras.readDouble());
// skip pointer to map data
ras.skipBytes(4);
put("Gamma", ras.readDouble());
put("Offset", ras.readDouble());
// read gray channel data
put("Gray Channel Name", ras.readString(16));
put("Gray Channel Size", ras.readInt());
put("Gray Channel Origin", ras.readDouble());
put("Gray Channel Resolution", ras.readDouble());
put("Gray Channel Units", ras.readString(64));
// skip pointer to thumbnail data
ras.skipBytes(4);
put("Voice field", ras.readInt());
// skip pointer to voice field
ras.skipBytes(4);
// now we need to read the MMSTAMP data to determine dimension order
readStamps();
}
ras.close();
// calculate the dimension order and axis sizes
CoreMetadata m = core.get(0);
dimensionOrder = "XY";
int seriesCount = 1;
m.sizeZ = m.sizeC = m.sizeT = 1;
for (int i = 0; i < 10; i++) {
String name = names[i];
int size = sizes[i];
double voxel = resolutions[i];
if (name == null || size == 0)
continue;
name = name.toLowerCase().trim();
if (name.length() == 0)
continue;
if (name.equals("x")) {
voxelX = voxel;
} else if (name.equals("y")) {
voxelY = voxel;
} else if (name.equals("event")) {
m.sizeZ *= size;
if (dimensionOrder.indexOf('Z') == -1) {
dimensionOrder += 'Z';
}
if (Double.compare(voxelZ, 1) == 0) {
voxelZ = voxel;
}
} else if (name.equals("z")) {
m.sizeZ *= size;
if (dimensionOrder.indexOf('Z') == -1) {
dimensionOrder += 'Z';
}
ArrayList<Double> uniqueZ = new ArrayList<Double>();
if (i > 1 && stamps != null) {
zPositions = stamps[i - 2];
if (zPositions != null) {
for (Double z : zPositions) {
BigDecimal bd = new BigDecimal(z);
bd = bd.setScale(10, RoundingMode.HALF_UP);
if (!uniqueZ.contains(bd.doubleValue()))
uniqueZ.add(bd.doubleValue());
}
}
}
if (uniqueZ.size() > 1 && uniqueZ.size() == size) {
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);
voxelZ = zRange.divide(zSize, mc).doubleValue();
// Need to convert from millimetre to micrometre
voxelZ *= Math.pow(10, 3);
} else {
voxelZ = voxel;
}
} else if (name.equals("ch") || name.equals("wavelength")) {
m.sizeC *= size;
if (dimensionOrder.indexOf('C') == -1) {
dimensionOrder += 'C';
}
voxelC = voxel;
} else if (name.equals("time") || name.equals("t") || name.equals("animation")) {
m.sizeT *= size;
if (dimensionOrder.indexOf('T') == -1) {
dimensionOrder += 'T';
}
voxelT = voxel;
timeIndex = i - 2;
} else {
if (dimensionOrder.indexOf('S') == -1)
dimensionOrder += 'S';
seriesCount *= size;
if (name.equals("montage"))
montageIndex = i - 2;
else if (name.equals("xy"))
fieldIndex = i - 2;
}
}
if (dimensionOrder.indexOf('Z') == -1)
dimensionOrder += 'Z';
if (dimensionOrder.indexOf('T') == -1)
dimensionOrder += 'T';
if (dimensionOrder.indexOf('C') == -1)
dimensionOrder += 'C';
if (dimensionOrder.indexOf('S') == -1)
dimensionOrder += 'S';
m.imageCount = ifds.size() / seriesCount;
if (getSizeZ() > getImageCount())
m.sizeZ = getImageCount();
if (getSizeT() > getImageCount())
m.sizeT = getImageCount();
if (getSizeZ() * getSizeC() * getSizeT() > getImageCount()) {
int diff = getSizeZ() * getSizeC() * getSizeT() - getImageCount();
if (diff == getSizeC()) {
if (getSizeZ() > 1)
m.sizeZ--;
else if (getSizeT() > 1)
m.sizeT--;
else
m.sizeC /= getSizeC();
}
}
if (getImageCount() == 1 && (getSizeT() == getSizeY() || getSizeZ() == getSizeY()) && (getSizeT() > getImageCount() || getSizeZ() > getImageCount())) {
m.sizeY = 1;
m.imageCount = getSizeZ() * getSizeC() * getSizeT();
}
m.dimensionOrder = dimensionOrder.replaceAll("S", "");
if (getPixelType() == FormatTools.UINT32) {
m.pixelType = FormatTools.FLOAT;
}
if (seriesCount > 1) {
core.clear();
for (int i = 0; i < seriesCount; i++) {
core.add(m);
}
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
// cut up the comment, if necessary
comment = ifds.get(0).getComment();
gains = new String[getSizeC()];
offsets = new String[getSizeC()];
voltages = new String[getSizeC()];
channelNames = new String[getSizeC()];
lensNA = new String[getSizeC()];
parsePageName();
parseComment();
addGlobalMeta("Comment", comment);
}
}
Aggregations