use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class FlexReader method groupFiles.
private void groupFiles(String[] fileList, MetadataStore store) throws FormatException, IOException {
LOGGER.info("Grouping together files in the same dataset");
HashMap<String, ArrayList<String>> v = new HashMap<String, ArrayList<String>>();
Boolean firstCompressed = null;
int firstIFDCount = 0;
for (String file : fileList) {
LOGGER.warn("parsing {}", file);
RandomAccessInputStream s = new RandomAccessInputStream(file, 16);
TiffParser parser = new TiffParser(s);
IFD firstIFD = parser.getFirstIFD();
int ifdCount = parser.getIFDOffsets().length;
s.close();
boolean compressed = firstIFD.getCompression() != TiffCompression.UNCOMPRESSED;
if (firstCompressed == null) {
firstCompressed = compressed;
firstIFDCount = ifdCount;
}
if (compressed == firstCompressed && ifdCount == firstIFDCount) {
int[] well = getWell(file);
int field = getField(file);
if (well[0] > nRows)
nRows = well[0];
if (well[1] > nCols)
nCols = well[1];
if (fileList.length == 1) {
well[0] = 0;
well[1] = 0;
}
ArrayList<String> files = v.get(well[0] + "," + well[1]);
if (files == null) {
files = new ArrayList<String>();
}
files.add(file);
v.put(well[0] + "," + well[1], files);
} else {
v.clear();
ArrayList<String> files = new ArrayList<String>();
files.add(currentId);
v.put("0,0", files);
fileList = new String[] { currentId };
break;
}
}
nRows++;
nCols++;
if (fileList.length == 1) {
nRows = 1;
nCols = 1;
}
LOGGER.debug("Determined that there are {} rows and {} columns of wells.", nRows, nCols);
flexFiles = new ArrayList<FlexFile>();
wellCount = v.size();
wellNumber = new int[wellCount][2];
RandomAccessInputStream s = null;
boolean firstFile = true;
boolean compressed = false;
int nOffsets = 1;
int currentWell = 0;
for (int row = 0; row < nRows; row++) {
for (int col = 0; col < nCols; col++) {
ArrayList<String> files = v.get(row + "," + col);
if (files == null) {
continue;
}
nFiles = files.size();
String[] sortedFiles = files.toArray(new String[files.size()]);
Arrays.sort(sortedFiles);
files.clear();
for (String f : sortedFiles) {
files.add(f);
}
for (int field = 0; field < nFiles; field++) {
FlexFile file = new FlexFile();
file.row = row;
file.column = col;
file.field = field;
file.file = files.get(field);
if (file.file == null) {
continue;
}
wellNumber[currentWell][0] = row;
wellNumber[currentWell][1] = col;
s = new RandomAccessInputStream(getFileHandle(file.file));
TiffParser tp = new TiffParser(s);
if (compressed || firstFile) {
LOGGER.info("Parsing IFDs for well {}{}", (char) (row + 'A'), col + 1);
IFD firstIFD = tp.getFirstIFD();
compressed = firstIFD.getCompression() != TiffCompression.UNCOMPRESSED;
if (compressed || firstIFD.getStripOffsets()[0] == 16 || firstIFD.getStripOffsets().length == 1) {
tp.setDoCaching(false);
file.ifds = tp.getIFDs();
file.ifds.set(0, firstIFD);
if (firstIFD.getStripOffsets().length == 1) {
// used to ensure that image offsets are read, not calculated
compressed = true;
}
} else {
// if the pixel data is uncompressed and the IFD is stored
// before the image, we can assume that
// the pixel data for image #0 is located immediately before
// IFD #1; as a result, we only need to parse the first IFD
file.offsets = tp.getIFDOffsets();
nOffsets = file.offsets.length;
file.ifds = new IFDList();
file.ifds.add(firstIFD);
}
} else {
// retrieve the offsets to each IFD, instead of parsing
// all of the IFDs
LOGGER.info("Retrieving IFD offsets for well {}{}", (char) (row + 'A'), col + 1);
file.offsets = new long[nOffsets];
// Assume that all IFDs after the first are evenly spaced.
// TiffParser.getIFDOffsets() could be used instead, but is
// substantially slower.
file.offsets[0] = tp.getFirstOffset();
if (file.offsets.length > 1) {
s.seek(file.offsets[0]);
s.skipBytes(s.readShort() * TiffConstants.BYTES_PER_ENTRY);
file.offsets[1] = s.readInt();
int size = FormatTools.getPlaneSize(this) + 174;
for (int i = 2; i < file.offsets.length; i++) {
file.offsets[i] = file.offsets[i - 1] + size;
}
}
}
flexFiles.add(file);
// setting a negative field index indicates that the field count
// should be taken from the XML
parseFlexFile(currentWell, row, col, nFiles == 1 ? -1 : field, firstFile, store);
s.close();
if (firstFile)
firstFile = false;
}
currentWell++;
}
}
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class GelReader method initMetadata.
// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initMetadata() */
@Override
protected void initMetadata() throws FormatException, IOException {
ifds = tiffParser.getIFDs();
if (ifds.size() > 1) {
IFDList tmpIFDs = ifds;
ifds = new IFDList();
for (int i = 0; i < tmpIFDs.size() / 2; i++) {
IFD ifd = new IFD();
ifds.add(ifd);
ifd.putAll(tmpIFDs.get(i * 2 + 1));
ifd.putAll(tmpIFDs.get(i * 2));
tiffParser.fillInIFD(ifd);
}
}
IFD firstIFD = ifds.get(0);
tiffParser.fillInIFD(firstIFD);
super.initStandardMetadata();
fmt = firstIFD.getIFDLongValue(MD_FILETAG, LINEAR);
if (fmt == SQUARE_ROOT)
core.get(0).pixelType = FormatTools.FLOAT;
TiffRational scale = (TiffRational) firstIFD.getIFDValue(MD_SCALE_PIXEL);
if (scale == null)
scale = new TiffRational(1, 1);
core.get(0).imageCount = ifds.size();
core.get(0).sizeT = getImageCount();
// ignore MD_COLOR_TABLE
String info = firstIFD.getIFDStringValue(MD_SAMPLE_INFO);
String prepDate = firstIFD.getIFDStringValue(MD_PREP_DATE);
String prepTime = firstIFD.getIFDStringValue(MD_PREP_TIME);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
String units = firstIFD.getIFDStringValue(MD_FILE_UNITS);
String lab = firstIFD.getIFDStringValue(MD_LAB_NAME);
addGlobalMeta("Scale factor", scale);
addGlobalMeta("Lab name", lab);
addGlobalMeta("Sample info", info);
addGlobalMeta("Date prepared", prepDate);
addGlobalMeta("Time prepared", prepTime);
addGlobalMeta("File units", units);
addGlobalMeta("Data format", fmt == SQUARE_ROOT ? "square root" : "linear");
}
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
String parsedDate = DateTools.formatDate(prepDate, FORMATS);
String parsedTime = DateTools.formatDate(prepTime, FORMATS);
if (parsedDate != null) {
store.setImageAcquisitionDate(new Timestamp(parsedDate), 0);
} else if (parsedTime != null) {
store.setImageAcquisitionDate(new Timestamp(parsedTime), 0);
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
Double pixelSize = new Double(scale.doubleValue());
Length sizeX = FormatTools.getPhysicalSizeX(pixelSize);
Length sizeY = FormatTools.getPhysicalSizeY(pixelSize);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
}
}
use of loci.formats.tiff.IFDList in project bioformats by openmicroscopy.
the class ImarisTiffReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
// hack up the IFDs
//
// Imaris TIFFs store a thumbnail in the first IFD; each of the remaining
// IFDs defines a stack of tiled planes.
// MinimalTiffReader.initFile(String) removes thumbnail IFDs.
LOGGER.info("Verifying IFD sanity");
IFDList tmp = new IFDList();
for (IFD ifd : ifds) {
long[] byteCounts = ifd.getStripByteCounts();
long[] offsets = ifd.getStripOffsets();
for (int i = 0; i < byteCounts.length; i++) {
IFD t = new IFD(ifd);
t.putIFDValue(IFD.TILE_BYTE_COUNTS, byteCounts[i]);
t.putIFDValue(IFD.TILE_OFFSETS, offsets[i]);
tmp.add(t);
}
}
String comment = ifds.get(0).getComment();
LOGGER.info("Populating metadata");
CoreMetadata m = core.get(0);
m.sizeC = ifds.size();
m.sizeZ = tmp.size() / getSizeC();
m.sizeT = 1;
m.sizeX = (int) ifds.get(0).getImageWidth();
m.sizeY = (int) ifds.get(0).getImageLength();
ifds = tmp;
m.imageCount = getSizeC() * getSizeZ();
m.dimensionOrder = "XYZCT";
m.interleaved = false;
m.rgb = getImageCount() != getSizeZ() * getSizeC() * getSizeT();
m.pixelType = ifds.get(0).getPixelType();
LOGGER.info("Parsing comment");
// likely an INI-style comment, although we can't be sure
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
String description = null, creationDate = null;
final List<Double> emWave = new ArrayList<Double>();
final List<Double> exWave = new ArrayList<Double>();
final List<String> channelNames = new ArrayList<String>();
if (comment != null && comment.startsWith("[")) {
// parse key/value pairs
StringTokenizer st = new StringTokenizer(comment, "\n");
while (st.hasMoreTokens()) {
String line = st.nextToken();
int equals = line.indexOf('=');
if (equals < 0)
continue;
String key = line.substring(0, equals).trim();
String value = line.substring(equals + 1).trim();
addGlobalMeta(key, value);
if (key.equals("Description")) {
description = value;
} else if (key.equals("LSMEmissionWavelength") && !value.equals("0")) {
emWave.add(new Double(value));
} else if (key.equals("LSMExcitationWavelength") && !value.equals("0")) {
exWave.add(new Double(value));
} else if (key.equals("Name") && !currentId.endsWith(value)) {
channelNames.add(value);
} else if (key.equals("RecordingDate")) {
value = value.replaceAll(" ", "T");
creationDate = value.substring(0, value.indexOf('.'));
}
}
metadata.remove("Comment");
}
// populate Image data
store.setImageDescription(description, 0);
if (creationDate != null) {
store.setImageAcquisitionDate(new Timestamp(creationDate), 0);
}
// populate LogicalChannel data
for (int i = 0; i < emWave.size(); i++) {
Length emission = FormatTools.getEmissionWavelength(emWave.get(i));
Length excitation = FormatTools.getExcitationWavelength(exWave.get(i));
if (emission != null) {
store.setChannelEmissionWavelength(emission, 0, i);
}
if (excitation != null) {
store.setChannelExcitationWavelength(excitation, 0, i);
}
store.setChannelName(channelNames.get(i), 0, i);
}
}
}
Aggregations