use of loci.formats.meta.MetadataStore in project bioformats by openmicroscopy.
the class CellVoyagerReader method readInfo.
private void readInfo(final Document msDocument, final Document omeDocument) throws FormatException {
/*
* Magnification.
*
* We need it early, because the file format reports only un-magnified
* sizes. So if we are to put proper metadata, we need to make the
* conversion to size measured at the sample level ourselves. I feel
* like this is fragile and most likely to change in a future version of
* the file format.
*/
final Element msRoot = msDocument.getDocumentElement();
final double objectiveMagnification = Double.parseDouble(getChildText(msRoot, new String[] { "ObjectiveLens", "Magnification" }));
// final double zoomLensMagnification = Double.parseDouble(
// getChildText( msRoot, new String[] { "ZoomLens", "Magnification",
// "Value" } ) );
// *
final double magnification = objectiveMagnification;
// zoomLensMagnification;
/*
* Read the ome.xml file. Since it is malformed, we need to parse all
* nodes, and add an "ID" attribute to those who do not have it.
*/
final NodeList nodeList = omeDocument.getElementsByTagName("*");
for (int i = 0; i < nodeList.getLength(); i++) {
final Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
final NamedNodeMap atts = node.getAttributes();
final Node namedItem = atts.getNamedItem("ID");
if (namedItem == null) {
final String name = node.getNodeName();
final String id = name + ":" + i;
if (!node.getParentNode().getNodeName().equals("LightSource")) {
((Element) node).setAttribute("ID", id);
}
}
}
}
/*
* For single-slice image, the PhysicalSizeZ can be 0, which will make
* the metadata read fail. Correct that.
*/
final Element pszEl = getChild(omeDocument.getDocumentElement(), new String[] { "Image", "Pixels" });
final double physicalSizeZ = Double.parseDouble(pszEl.getAttribute("PhysicalSizeZ"));
if (physicalSizeZ <= 0) {
// default to 1 whatever
pszEl.setAttribute("PhysicalSizeZ", "" + 1);
}
/*
* Now that the XML document is properly formed, we can build a metadata
* object from it.
*/
OMEXMLService service = null;
String xml = null;
try {
xml = XMLTools.getXML(omeDocument);
} catch (final TransformerConfigurationException e2) {
LOGGER.debug("", e2);
} catch (final TransformerException e2) {
LOGGER.debug("", e2);
}
try {
service = new ServiceFactory().getInstance(OMEXMLService.class);
} catch (final DependencyException e1) {
LOGGER.debug("", e1);
}
OMEXMLMetadata omeMD = null;
try {
omeMD = service.createOMEXMLMetadata(xml);
} catch (final ServiceException e) {
LOGGER.debug("", e);
} catch (final NullPointerException npe) {
LOGGER.debug("", npe);
throw npe;
}
// Correct pixel size for magnification
omeMD.setPixelsPhysicalSizeX(FormatTools.createLength(omeMD.getPixelsPhysicalSizeX(0).value().doubleValue() / magnification, omeMD.getPixelsPhysicalSizeX(0).unit()), 0);
omeMD.setPixelsPhysicalSizeY(FormatTools.createLength(omeMD.getPixelsPhysicalSizeY(0).value().doubleValue() / magnification, omeMD.getPixelsPhysicalSizeY(0).unit()), 0);
// Time interval
if (Double.valueOf(readFrameInterval(msDocument)) != null) {
omeMD.setPixelsTimeIncrement(new Time(Double.valueOf(readFrameInterval(msDocument)), UNITS.SECOND), 0);
}
/*
* Channels
*/
final Element channelsEl = getChild(msRoot, "Channels");
final List<Element> channelEls = getChildren(channelsEl, "Channel");
channelInfos = new ArrayList<ChannelInfo>();
for (final Element channelEl : channelEls) {
final boolean isEnabled = Boolean.parseBoolean(getChildText(channelEl, "IsEnabled"));
if (!isEnabled) {
continue;
}
final ChannelInfo ci = readChannel(channelEl);
channelInfos.add(ci);
}
/*
* Fix missing IDs.
*
* Some IDs are missing in the malformed OME.XML file. We must put them
* back manually. Some are fixed here
*/
omeMD.setProjectID(MetadataTools.createLSID("Project", 0), 0);
omeMD.setScreenID(MetadataTools.createLSID("Screen", 0), 0);
omeMD.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
omeMD.setInstrumentID(MetadataTools.createLSID("Instrument", 0), 0);
// Read pixel sizes from OME metadata.
final double pixelWidth = omeMD.getPixelsPhysicalSizeX(0).value().doubleValue();
final double pixelHeight = omeMD.getPixelsPhysicalSizeY(0).value().doubleValue();
/*
* Read tile size from channel info. This is weird, but it's like that.
* Since we build a multi-C image, we have to assume that all channels
* have the same dimension, even if the file format allows for changing
* the size, binning, etc. from channel to channel. Failure to load
* datasets that have this exoticity is to be sought here.
*/
final int tileWidth = channelInfos.get(0).tileWidth;
final int tileHeight = channelInfos.get(0).tileHeight;
/*
* Handle multiple wells.
*
* The same kind of remark apply: We assume that a channel setting can
* be applied to ALL wells. So this file reader will fail for dataset
* that have one well that has a different dimension that of others.
*/
/*
* First remark: there can be two modes to store Areas in the xml file:
* Either we define different areas for each well, and in that case, the
* areas are found as a child element of the well element. Either the
* definition of areas is common to all wells, and in that case they
* area defined in a separate element.
*/
final boolean sameAreaPerWell = Boolean.parseBoolean(getChildText(msRoot, "UsesSameAreaParWell"));
List<AreaInfo> areas = null;
if (sameAreaPerWell) {
final Element areasEl = getChild(msRoot, new String[] { "SameAreaUsingWell", "Areas" });
final List<Element> areaEls = getChildren(areasEl, "Area");
int areaIndex = 0;
areas = new ArrayList<AreaInfo>(areaEls.size());
int fieldIndex = 1;
for (final Element areaEl : areaEls) {
final AreaInfo area = readArea(areaEl, fieldIndex, pixelWidth, pixelHeight, tileWidth, tileHeight);
area.index = areaIndex++;
areas.add(area);
// Continue incrementing field index across areas.
fieldIndex = area.fields.get(area.fields.size() - 1).index + 1;
}
}
final Element wellsEl = getChild(msRoot, "Wells");
final List<Element> wellEls = getChildren(wellsEl, "Well");
wells = new ArrayList<WellInfo>();
for (final Element wellEl : wellEls) {
final boolean isWellEnabled = Boolean.parseBoolean(getChild(wellEl, "IsEnabled").getTextContent());
if (isWellEnabled) {
final WellInfo wi = readWellInfo(wellEl, pixelWidth, pixelHeight, tileWidth, tileHeight);
if (sameAreaPerWell) {
wi.areas = areas;
}
wells.add(wi);
}
}
/*
* Z range.
*
* In this file format, the Z range appears to be general: it applies to
* all fields of all wells.
*/
final int nZSlices = Integer.parseInt(getChildText(msRoot, new String[] { "ZStackConditions", "NumberOfSlices" }));
/*
* Time points. They are general as well. Which just makes sense.
*/
timePoints = readTimePoints(msDocument);
/*
* Populate CORE metadata for each area.
*
* This reader takes to convention that state that 1 area = 1 series. So
* if you have 10 wells with 2 areas in each well, and each area is made
* of 20 fields, you will get 20 series, and each series will be
* stitched from 20 fields.
*/
OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) omeMD.getRoot();
Image firstImage = root.getImage(0);
core.clear();
for (final WellInfo well : wells) {
for (final AreaInfo area : well.areas) {
final CoreMetadata ms = new CoreMetadata();
core.add(ms);
if (core.size() > 1) {
root.addImage(firstImage);
}
ms.sizeX = area.width;
ms.sizeY = area.height;
ms.sizeZ = nZSlices;
ms.sizeC = channelInfos.size();
ms.sizeT = timePoints.size();
ms.dimensionOrder = "XYCZT";
ms.rgb = false;
ms.imageCount = nZSlices * channelInfos.size() * timePoints.size();
// Bit depth.
switch(omeMD.getPixelsType(0)) {
case UINT8:
ms.pixelType = FormatTools.UINT8;
ms.bitsPerPixel = 8;
break;
case UINT16:
ms.pixelType = FormatTools.UINT16;
ms.bitsPerPixel = 16;
break;
case UINT32:
ms.pixelType = FormatTools.UINT32;
ms.bitsPerPixel = 32;
break;
default:
throw new FormatException("Cannot read image with pixel type = " + omeMD.getPixelsType(0));
}
// Determined manually on sample data. Check here is the image
// you get is weird.
ms.littleEndian = true;
}
}
omeMD.setRoot(root);
/*
* Populate the MetadataStore.
*/
final MetadataStore store = makeFilterMetadata();
MetadataConverter.convertMetadata(omeMD, store);
MetadataTools.populatePixels(store, this, true);
/*
* Pinhole disk
*/
final double pinholeSize = Double.parseDouble(getChildText(msRoot, new String[] { "PinholeDisk", "PinholeSize_um" }));
/*
* MicroPlate specific stuff
*/
final Element containerEl = getChild(msRoot, new String[] { "Attachment", "HolderInfoList", "HolderInfo", "MountedSampleContainer" });
final String type = containerEl.getAttribute("xsi:type");
boolean plateMetadata = false;
if (type.equals("WellPlate")) {
plateMetadata = true;
final int nrows = Integer.parseInt(getChildText(containerEl, "RowCount"));
final int ncols = Integer.parseInt(getChildText(containerEl, "ColumnCount"));
store.setPlateRows(new PositiveInteger(nrows), 0);
store.setPlateColumns(new PositiveInteger(ncols), 0);
final String plateAcqID = MetadataTools.createLSID("PlateAcquisition", 0, 0);
store.setPlateAcquisitionID(plateAcqID, 0, 0);
final Element dimInfoEl = getChild(msRoot, "DimensionsInfo");
final int maxNFields = Integer.parseInt(getChild(dimInfoEl, "F").getAttribute("Max"));
final PositiveInteger fieldCount = FormatTools.getMaxFieldCount(maxNFields);
if (fieldCount != null) {
store.setPlateAcquisitionMaximumFieldCount(fieldCount, 0, 0);
}
// Plate acquisition time
final String beginTime = getChildText(msRoot, "BeginTime");
final String endTime = getChildText(msRoot, "EndTime");
store.setPlateAcquisitionStartTime(new Timestamp(beginTime), 0, 0);
store.setPlateAcquisitionEndTime(new Timestamp(endTime), 0, 0);
store.setPlateName(beginTime, 0);
} else if (!type.equals("PreparedSlide")) {
LOGGER.warn("Unexpected acquisition type: {}", type);
}
// Wells position on the plate
int seriesIndex = -1;
int wellIndex = -1;
for (final WellInfo well : wells) {
wellIndex++;
final int wellNumber = well.number;
if (plateMetadata) {
store.setWellID(MetadataTools.createLSID("Well", 0, wellIndex), 0, wellIndex);
store.setWellRow(new NonNegativeInteger(well.row), 0, wellIndex);
store.setWellColumn(new NonNegativeInteger(well.col), 0, wellIndex);
}
int areaIndex = -1;
for (final AreaInfo area : well.areas) {
seriesIndex++;
areaIndex++;
String imageID = MetadataTools.createLSID("Image", seriesIndex);
store.setImageID(imageID, seriesIndex);
final String imageName = "Well " + wellNumber + " (UID=" + well.UID + ", r=" + well.row + ", c=" + well.col + ") - Area " + areaIndex;
store.setImageName(imageName, seriesIndex);
if (plateMetadata) {
Length posX = new Length(Double.valueOf(well.centerX), UNITS.REFERENCEFRAME);
Length posY = new Length(Double.valueOf(well.centerY), UNITS.REFERENCEFRAME);
String wellSample = MetadataTools.createLSID("WellSample", 0, wellIndex, areaIndex);
store.setWellSampleID(wellSample, 0, wellIndex, areaIndex);
store.setWellSampleImageRef(imageID, 0, wellIndex, areaIndex);
store.setWellSampleIndex(new NonNegativeInteger(area.index), 0, wellIndex, areaIndex);
store.setWellSamplePositionX(posX, 0, wellIndex, areaIndex);
store.setWellSamplePositionY(posY, 0, wellIndex, areaIndex);
store.setPlateAcquisitionWellSampleRef(wellSample, 0, 0, seriesIndex);
}
store.setImageInstrumentRef(MetadataTools.createLSID("Instrument", 0), seriesIndex);
for (int i = 0; i < channelInfos.size(); i++) {
store.setChannelPinholeSize(new Length(pinholeSize, UNITS.MICROMETER), seriesIndex, i);
store.setChannelName(channelInfos.get(i).name, seriesIndex, i);
store.setChannelColor(channelInfos.get(i).color, seriesIndex, i);
}
}
}
}
use of loci.formats.meta.MetadataStore in project bioformats by openmicroscopy.
the class CellWorxReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
if (!checkSuffix(id, "htd")) {
LOGGER.info("Searching for .htd file");
String base = new Location(id).getAbsolutePath();
base = base.substring(0, base.lastIndexOf("_"));
id = base + ".HTD";
if (!new Location(id).exists()) {
Location parent = new Location(id).getAbsoluteFile().getParentFile();
directoryList = parent.list(true);
for (String f : directoryList) {
if (checkSuffix(f, "htd")) {
id = new Location(parent, f).getAbsolutePath();
LOGGER.info("Found .htd file {}", f);
break;
}
}
}
}
super.initFile(id);
try {
ServiceFactory factory = new ServiceFactory();
service = factory.getInstance(OMEXMLService.class);
} catch (DependencyException exc) {
throw new FormatException("Could not create OME-XML store.", exc);
}
String plateData = DataTools.readFile(id);
String[] lines = plateData.split("\n");
int xWells = 0, yWells = 0;
int xFields = 0, yFields = 0;
String[] wavelengths = null;
int nTimepoints = 1;
// determine dataset dimensions
for (String line : lines) {
int split = line.indexOf("\",");
if (split < 1)
continue;
String key = line.substring(1, split).trim();
String value = line.substring(split + 2).trim();
if (key.equals("XWells")) {
xWells = Integer.parseInt(value);
} else if (key.equals("YWells")) {
yWells = Integer.parseInt(value);
wellFiles = new String[yWells][xWells][];
logFiles = new String[yWells][xWells];
} else if (key.startsWith("WellsSelection")) {
int row = Integer.parseInt(key.substring(14)) - 1;
String[] mapping = value.split(",");
for (int col = 0; col < xWells; col++) {
if (new Boolean(mapping[col].trim()).booleanValue()) {
wellFiles[row][col] = new String[1];
}
}
} else if (key.equals("XSites")) {
xFields = Integer.parseInt(value);
} else if (key.equals("YSites")) {
yFields = Integer.parseInt(value);
fieldMap = new boolean[yFields][xFields];
} else if (key.equals("TimePoints")) {
nTimepoints = Integer.parseInt(value);
} else if (key.startsWith("SiteSelection")) {
int row = Integer.parseInt(key.substring(13)) - 1;
String[] mapping = value.split(",");
for (int col = 0; col < xFields; col++) {
fieldMap[row][col] = new Boolean(mapping[col].trim()).booleanValue();
}
} else if (key.equals("Waves")) {
doChannels = new Boolean(value.toLowerCase());
} else if (key.equals("NWavelengths")) {
wavelengths = new String[Integer.parseInt(value)];
} else if (key.startsWith("WaveName")) {
int index = Integer.parseInt(key.substring(8)) - 1;
wavelengths[index] = value.replaceAll("\"", "");
}
}
for (int row = 0; row < fieldMap.length; row++) {
for (int col = 0; col < fieldMap[row].length; col++) {
if (fieldMap[row][col])
fieldCount++;
}
}
// find pixels files
String plateName = new Location(id).getAbsolutePath();
plateName = plateName.substring(0, plateName.lastIndexOf(".")) + "_";
int wellCount = 0;
for (int row = 0; row < wellFiles.length; row++) {
for (int col = 0; col < wellFiles[row].length; col++) {
if (wellFiles[row][col] != null) {
wellCount++;
char rowLetter = (char) (row + 'A');
String base = plateName + rowLetter + String.format("%02d", col + 1);
wellFiles[row][col][0] = base + ".pnl";
logFiles[row][col] = base + "_scan.log";
if (!new Location(wellFiles[row][col][0]).exists()) {
// using TIFF files instead
wellFiles[row][col] = getTiffFiles(plateName, rowLetter, col, wavelengths.length, nTimepoints);
}
}
}
}
plateLogFile = plateName + "scan.log";
String serialNumber = null;
if (new Location(plateLogFile).exists()) {
String[] f = DataTools.readFile(plateLogFile).split("\n");
for (String line : f) {
if (line.trim().startsWith("Z Map File")) {
String file = line.substring(line.indexOf(':') + 1);
file = file.substring(file.lastIndexOf("/") + 1).trim();
String parent = new Location(id).getAbsoluteFile().getParent();
zMapFile = new Location(parent, file).getAbsolutePath();
} else if (line.trim().startsWith("Scanner SN")) {
serialNumber = line.substring(line.indexOf(':') + 1).trim();
}
}
}
int seriesCount = fieldCount * wellCount;
int planeIndex = 0;
int seriesIndex = 0;
String file = getFile(seriesIndex, planeIndex);
while (!new Location(file).exists()) {
if (planeIndex < nTimepoints * wavelengths.length) {
planeIndex++;
} else if (seriesIndex < seriesCount - 1) {
planeIndex = 0;
seriesIndex++;
} else {
break;
}
file = getFile(seriesIndex, planeIndex);
}
IFormatReader pnl = getReader(file, true);
core.clear();
for (int i = 0; i < seriesCount; i++) {
CoreMetadata ms = new CoreMetadata();
core.add(ms);
setSeries(i);
ms.littleEndian = pnl.isLittleEndian();
ms.sizeX = pnl.getSizeX();
ms.sizeY = pnl.getSizeY();
ms.pixelType = pnl.getPixelType();
ms.sizeZ = 1;
ms.sizeT = nTimepoints;
ms.sizeC = wavelengths.length;
ms.imageCount = getSizeZ() * getSizeC() * getSizeT();
ms.dimensionOrder = "XYCZT";
ms.rgb = false;
ms.interleaved = pnl.isInterleaved();
}
OMEXMLMetadata readerMetadata = (OMEXMLMetadata) pnl.getMetadataStore();
OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) readerMetadata.getRoot();
Instrument instrument = root.getInstrument(0);
List<Image> images = root.copyImageList();
OMEXMLMetadataRoot convertRoot = new OMEXMLMetadataRoot();
convertRoot.addInstrument(instrument);
for (int i = 0; i < core.size() / images.size(); i++) {
for (Image img : images) {
convertRoot.addImage(img);
}
}
OMEXMLMetadata convertMetadata;
try {
convertMetadata = service.createOMEXMLMetadata();
} catch (ServiceException exc) {
throw new FormatException("Could not create OME-XML store.", exc);
}
convertMetadata.setRoot(convertRoot);
pnl.close();
MetadataStore store = makeFilterMetadata();
MetadataConverter.convertMetadata(convertMetadata, store);
MetadataTools.populatePixels(store, this);
String plateID = MetadataTools.createLSID("Plate", 0);
Location plate = new Location(id).getAbsoluteFile();
store.setPlateID(plateID, 0);
plateName = plate.getName();
if (plateName.indexOf('.') > 0) {
plateName = plateName.substring(0, plateName.lastIndexOf('.'));
}
store.setPlateName(plateName, 0);
store.setPlateRows(new PositiveInteger(wellFiles.length), 0);
store.setPlateColumns(new PositiveInteger(wellFiles[0].length), 0);
for (int i = 0; i < core.size(); i++) {
store.setImageID(MetadataTools.createLSID("Image", i), i);
}
String plateAcqID = MetadataTools.createLSID("PlateAcquisition", 0, 0);
store.setPlateAcquisitionID(plateAcqID, 0, 0);
PositiveInteger fieldCount = FormatTools.getMaxFieldCount(fieldMap.length * fieldMap[0].length);
if (fieldCount != null) {
store.setPlateAcquisitionMaximumFieldCount(fieldCount, 0, 0);
}
int nextImage = 0;
for (int row = 0; row < wellFiles.length; row++) {
for (int col = 0; col < wellFiles[row].length; col++) {
int wellIndex = row * wellFiles[row].length + col;
String wellID = MetadataTools.createLSID("Well", 0, wellIndex);
store.setWellID(wellID, 0, wellIndex);
store.setWellColumn(new NonNegativeInteger(col), 0, wellIndex);
store.setWellRow(new NonNegativeInteger(row), 0, wellIndex);
int fieldIndex = 0;
for (int fieldRow = 0; fieldRow < fieldMap.length; fieldRow++) {
for (int fieldCol = 0; fieldCol < fieldMap[fieldRow].length; fieldCol++) {
if (fieldMap[fieldRow][fieldCol] && wellFiles[row][col] != null) {
String wellSampleID = MetadataTools.createLSID("WellSample", 0, wellIndex, fieldIndex);
store.setWellSampleID(wellSampleID, 0, wellIndex, fieldIndex);
String imageID = MetadataTools.createLSID("Image", nextImage);
store.setWellSampleImageRef(imageID, 0, wellIndex, fieldIndex);
store.setWellSampleIndex(new NonNegativeInteger(nextImage), 0, wellIndex, fieldIndex);
store.setPlateAcquisitionWellSampleRef(wellSampleID, 0, 0, nextImage);
String well = (char) (row + 'A') + String.format("%02d", col + 1);
store.setImageName("Well " + well + " Field #" + (fieldIndex + 1), nextImage);
nextImage++;
fieldIndex++;
}
}
}
}
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (serialNumber != null) {
store.setMicroscopeSerialNumber(serialNumber, 0);
}
for (int well = 0; well < wellCount; well++) {
parseWellLogFile(well, store);
}
if (timestamps.size() > 0) {
store.setPlateAcquisitionStartTime(timestamps.get(0), 0, 0);
store.setPlateAcquisitionEndTime(timestamps.get(timestamps.size() - 1), 0, 0);
}
for (int i = 0; i < core.size(); i++) {
for (int c = 0; c < getSizeC(); c++) {
if (c < wavelengths.length && wavelengths[c] != null) {
store.setChannelName(wavelengths[c], i, c);
}
}
}
}
}
use of loci.formats.meta.MetadataStore in project bioformats by openmicroscopy.
the class CellomicsReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
// look for files with similar names
Location baseFile = new Location(id).getAbsoluteFile();
Location parent = baseFile.getParentFile();
ArrayList<String> pixelFiles = new ArrayList<String>();
String plateName = getPlateName(baseFile.getName());
if (plateName != null && isGroupFiles()) {
String[] list = parent.list();
for (String f : list) {
if (plateName.equals(getPlateName(f)) && (checkSuffix(f, "c01") || checkSuffix(f, "dib"))) {
Location loc = new Location(parent, f);
if ((!f.startsWith(".") || !loc.isHidden()) && getChannel(f) >= 0) {
pixelFiles.add(loc.getAbsolutePath());
}
}
}
} else
pixelFiles.add(id);
files = pixelFiles.toArray(new String[pixelFiles.size()]);
int wellRows = 0;
int wellColumns = 0;
int fields = 0;
ArrayList<Integer> uniqueRows = new ArrayList<Integer>();
ArrayList<Integer> uniqueCols = new ArrayList<Integer>();
ArrayList<Integer> uniqueFields = new ArrayList<Integer>();
ArrayList<Integer> uniqueChannels = new ArrayList<Integer>();
for (String f : files) {
int wellRow = getWellRow(f);
int wellCol = getWellColumn(f);
int field = getField(f);
int channel = getChannel(f);
if (!uniqueRows.contains(wellRow))
uniqueRows.add(wellRow);
if (!uniqueCols.contains(wellCol))
uniqueCols.add(wellCol);
if (!uniqueFields.contains(field))
uniqueFields.add(field);
if (!uniqueChannels.contains(channel))
uniqueChannels.add(channel);
}
fields = uniqueFields.size();
wellRows = uniqueRows.size();
wellColumns = uniqueCols.size();
if (fields * wellRows * wellColumns > files.length) {
files = new String[] { id };
}
Arrays.sort(files, new Comparator<String>() {
@Override
public int compare(String f1, String f2) {
int wellRow1 = getWellRow(f1);
int wellCol1 = getWellColumn(f1);
int field1 = getField(f1);
int channel1 = getChannel(f1);
int wellRow2 = getWellRow(f2);
int wellCol2 = getWellColumn(f2);
int field2 = getField(f2);
int channel2 = getChannel(f2);
if (wellRow1 < wellRow2) {
return -1;
} else if (wellRow1 > wellRow2) {
return 1;
}
if (wellCol1 < wellCol2) {
return -1;
} else if (wellCol1 > wellCol2) {
return 1;
}
if (field1 < field2) {
return -1;
} else if (field1 > field2) {
return 1;
}
return channel1 - channel2;
}
});
core.clear();
int seriesCount = files.length;
if (uniqueChannels.size() > 0) {
seriesCount /= uniqueChannels.size();
}
for (int i = 0; i < seriesCount; i++) {
core.add(new CoreMetadata());
}
in = getDecompressedStream(id);
LOGGER.info("Reading header data");
in.order(true);
in.skipBytes(4);
int x = in.readInt();
int y = in.readInt();
int nPlanes = in.readShort();
int nBits = in.readShort();
int compression = in.readInt();
if (x * y * nPlanes * (nBits / 8) + 52 > in.length()) {
throw new UnsupportedCompressionException("Compressed pixel data is not yet supported.");
}
in.skipBytes(4);
int pixelWidth = 0, pixelHeight = 0;
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
pixelWidth = in.readInt();
pixelHeight = in.readInt();
int colorUsed = in.readInt();
int colorImportant = in.readInt();
LOGGER.info("Populating metadata hashtable");
addGlobalMeta("Image width", x);
addGlobalMeta("Image height", y);
addGlobalMeta("Number of planes", nPlanes);
addGlobalMeta("Bits per pixel", nBits);
addGlobalMeta("Compression", compression);
addGlobalMeta("Pixels per meter (X)", pixelWidth);
addGlobalMeta("Pixels per meter (Y)", pixelHeight);
addGlobalMeta("Color used", colorUsed);
addGlobalMeta("Color important", colorImportant);
}
LOGGER.info("Populating core metadata");
for (int i = 0; i < getSeriesCount(); i++) {
CoreMetadata ms = core.get(i);
ms.sizeX = x;
ms.sizeY = y;
ms.sizeZ = nPlanes;
ms.sizeT = 1;
ms.sizeC = uniqueChannels.size();
ms.imageCount = getSizeZ() * getSizeT() * getSizeC();
ms.littleEndian = true;
ms.dimensionOrder = "XYCZT";
ms.pixelType = FormatTools.pixelTypeFromBytes(nBits / 8, false, false);
}
LOGGER.info("Populating metadata store");
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this);
store.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
store.setPlateName(plateName, 0);
store.setPlateRowNamingConvention(NamingConvention.LETTER, 0);
store.setPlateColumnNamingConvention(NamingConvention.NUMBER, 0);
int realRows = wellRows;
int realCols = wellColumns;
if (files.length == 1) {
realRows = 1;
realCols = 1;
} else if (realRows <= 8 && realCols <= 12) {
realRows = 8;
realCols = 12;
} else {
realRows = 16;
realCols = 24;
}
int fieldCntr = 0;
int wellCntr = 0;
int wellIndexPrev = 0;
int wellIndex = 0;
for (int i = 0; i < getSeriesCount(); i++) {
String file = files[i * getSizeC()];
int fieldIndex = getField(file);
int row = getWellRow(file);
int col = getWellColumn(file);
store.setImageName(String.format("Well %s%02d, Field #%02d", new String(Character.toChars(row + 'A')), col, fieldIndex), i);
if (files.length == 1) {
row = 0;
col = 0;
}
if (i > 0 && files.length != 1) {
String prevFile = files[(i - 1) * getSizeC()];
int prevRow = getWellRow(prevFile);
int prevCol = getWellColumn(prevFile);
if (prevRow < realRows && prevCol < realCols) {
wellIndexPrev = prevRow * realCols + prevCol;
}
}
String imageID = MetadataTools.createLSID("Image", i);
store.setImageID(imageID, i);
if (row < realRows && col < realCols) {
wellIndex = row * realCols + col;
if ((wellIndexPrev != wellIndex) || i == 0) {
if (i > 0) {
wellCntr++;
fieldCntr = 0;
} else {
wellIndexPrev = wellIndex;
}
store.setWellID(MetadataTools.createLSID("Well", 0, wellIndex), 0, wellCntr);
store.setWellRow(new NonNegativeInteger(row), 0, wellCntr);
store.setWellColumn(new NonNegativeInteger(col), 0, wellCntr);
}
if (files.length == 1) {
fieldIndex = 0;
}
if (fieldIndex == 0) {
fieldCntr = 0;
}
String wellSampleID = MetadataTools.createLSID("WellSample", 0, wellIndex, fieldIndex);
store.setWellSampleID(wellSampleID, 0, wellCntr, fieldCntr);
store.setWellSampleIndex(new NonNegativeInteger(i), 0, wellCntr, fieldCntr);
store.setWellSampleImageRef(imageID, 0, wellCntr, fieldCntr);
fieldCntr++;
}
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
// physical dimensions are stored as pixels per meter - we want them
// in microns per pixel
double width = pixelWidth == 0 ? 0.0 : 1000000.0 / pixelWidth;
double height = pixelHeight == 0 ? 0.0 : 1000000.0 / pixelHeight;
Length sizeX = FormatTools.getPhysicalSizeX(width);
Length sizeY = FormatTools.getPhysicalSizeY(height);
for (int i = 0; i < getSeriesCount(); i++) {
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
}
}
}
use of loci.formats.meta.MetadataStore in project bioformats by openmicroscopy.
the class DeltavisionReader method initPixels.
protected void initPixels() throws FormatException, IOException {
LOGGER.info("Reading header");
MetadataStore store = makeFilterMetadata();
in.seek(96);
in.order(true);
boolean little = in.readShort() == LITTLE_ENDIAN;
in.order(little);
in.seek(0);
int sizeX = in.readInt();
int sizeY = in.readInt();
int imageCount = in.readInt();
int filePixelType = in.readInt();
in.seek(180);
int rawSizeT = in.readUnsignedShort();
int sizeT = rawSizeT == 0 ? 1 : rawSizeT;
int sequence = in.readShort();
in.seek(92);
extSize = in.readInt();
in.seek(196);
int rawSizeC = in.readShort();
int sizeC = rawSizeC == 0 ? 1 : rawSizeC;
// --- compute some secondary values ---
String imageSequence = getImageSequence(sequence);
int sizeZ = imageCount / (sizeC * sizeT);
// --- populate core metadata ---
LOGGER.info("Populating core metadata");
CoreMetadata m = core.get(0);
m.littleEndian = little;
m.sizeX = sizeX;
m.sizeY = sizeY;
m.imageCount = imageCount;
String pixel = getPixelString(filePixelType);
m.pixelType = getPixelType(filePixelType);
m.dimensionOrder = "XY" + imageSequence.replaceAll("W", "C");
int planeSize = getSizeX() * getSizeY() * FormatTools.getBytesPerPixel(getPixelType());
int realPlaneCount = (int) ((in.length() - HEADER_LENGTH - extSize) / planeSize);
if (realPlaneCount < getImageCount() && !truncatedFileFlag) {
LOGGER.debug("Truncated file");
m.imageCount = realPlaneCount;
if (sizeZ == 1) {
sizeT = realPlaneCount / sizeC;
} else if (sizeT == 1) {
sizeZ = realPlaneCount / sizeC;
if ((realPlaneCount % sizeC) != 0) {
sizeZ++;
m.imageCount = sizeZ * sizeC;
}
} else if (getDimensionOrder().indexOf('Z') < getDimensionOrder().indexOf('T')) {
sizeZ = realPlaneCount / (sizeC * sizeT);
if (sizeZ == 0) {
sizeT = 1;
sizeZ = realPlaneCount / sizeC;
if ((realPlaneCount % sizeC) != 0) {
sizeZ++;
m.imageCount = sizeZ * sizeC;
}
}
if (getImageCount() > (sizeZ * sizeC * sizeT)) {
m.imageCount = imageCount;
sizeC = rawSizeC == 0 ? 1 : rawSizeC;
sizeT = rawSizeT == 0 ? 1 : rawSizeT;
sizeZ = getImageCount() / (sizeC * sizeT);
}
} else {
sizeT = realPlaneCount / (sizeC * sizeZ);
}
}
m.sizeT = sizeT;
m.sizeC = sizeC;
m.sizeZ = sizeZ;
m.rgb = false;
m.interleaved = false;
m.metadataComplete = true;
m.indexed = false;
m.falseColor = false;
// --- parse extended header ---
in.seek(128);
numIntsPerSection = in.readShort();
numFloatsPerSection = in.readShort();
LOGGER.info("Reading extended header");
setOffsetInfo(sequence, getSizeZ(), getSizeC(), getSizeT());
extHdrFields = new DVExtHdrFields[getSizeZ()][getSizeC()][getSizeT()];
ndFilters = new Double[getSizeC()];
final List<Length> uniqueTileX = new ArrayList<Length>();
final List<Length> uniqueTileY = new ArrayList<Length>();
// Run through every image and fill in the
// Extended Header information array for that image
int offset = HEADER_LENGTH + numIntsPerSection * 4;
boolean hasZeroX = false;
boolean hasZeroY = false;
for (int i = 0; i < getImageCount(); i++) {
int[] coords = getZCTCoords(i);
int z = coords[0];
int w = coords[1];
int t = coords[2];
// -- read in the extended header data --
in.seek(offset + getTotalOffset(z, w, t));
DVExtHdrFields hdr = new DVExtHdrFields(in);
extHdrFields[z][w][t] = hdr;
if (!uniqueTileX.contains(hdr.stageXCoord) && hdr.stageXCoord.value().floatValue() != 0) {
uniqueTileX.add(hdr.stageXCoord);
} else if (hdr.stageXCoord.value().floatValue() == 0) {
hasZeroX = true;
}
if (!uniqueTileY.contains(hdr.stageYCoord) && hdr.stageYCoord.value().floatValue() != 0) {
uniqueTileY.add(hdr.stageYCoord);
} else if (hdr.stageYCoord.value().floatValue() == 0) {
hasZeroY = true;
}
}
xTiles = uniqueTileX.size();
yTiles = uniqueTileY.size();
if (xTiles > 1 || yTiles > 1) {
if (hasZeroX) {
xTiles++;
}
if (hasZeroY) {
yTiles++;
}
}
if (yTiles > 1) {
// TODO: use compareTo once Length implements Comparable
final Number y0 = uniqueTileY.get(0).value(UNITS.REFERENCEFRAME);
final Number y1 = uniqueTileY.get(1).value(UNITS.REFERENCEFRAME);
if (y1.floatValue() < y0.floatValue()) {
backwardsStage = true;
}
}
int nStagePositions = xTiles * yTiles;
if (nStagePositions > 0 && nStagePositions <= getSizeT()) {
int t = getSizeT();
m.sizeT /= nStagePositions;
if (getSizeT() * nStagePositions != t) {
m.sizeT = t;
nStagePositions = 1;
} else {
m.imageCount /= nStagePositions;
}
if (nStagePositions > 1) {
CoreMetadata originalCore = core.get(0);
core.clear();
for (int i = 0; i < nStagePositions; i++) {
core.add(originalCore);
}
}
}
lengths = new int[4];
int lengthIndex = 0;
int dimIndex = 0;
while (lengthIndex < lengths.length) {
char dim = imageSequence.charAt(dimIndex++);
switch(dim) {
case 'Z':
lengths[lengthIndex++] = getSizeZ();
break;
case 'W':
lengths[lengthIndex++] = getSizeC();
break;
case 'T':
lengths[lengthIndex++] = getSeriesCount();
lengths[lengthIndex++] = getSizeT();
break;
}
}
// --- populate original metadata ---
LOGGER.info("Populating original metadata");
addGlobalMeta("ImageWidth", sizeX);
addGlobalMeta("ImageHeight", sizeY);
addGlobalMeta("NumberOfImages", imageCount);
addGlobalMeta("PixelType", pixel);
addGlobalMeta("Number of timepoints", rawSizeT);
addGlobalMeta("Image sequence", imageSequence);
addGlobalMeta("Number of wavelengths", rawSizeC);
addGlobalMeta("Number of focal planes", sizeZ);
for (int series = 0; series < getSeriesCount(); series++) {
setSeries(series);
for (int plane = 0; plane < getImageCount(); plane++) {
int[] coords = getZCTCoords(plane);
int tIndex = getSeriesCount() * coords[2] + series;
DVExtHdrFields hdr = extHdrFields[coords[0]][coords[1]][tIndex];
// -- record original metadata --
String prefix = "Extended header Z" + coords[0] + " W" + coords[1] + " T" + coords[2];
for (Map.Entry<String, Object> entry : hdr.asMap().entrySet()) {
addSeriesMeta(prefix + ":" + entry.getKey(), entry.getValue());
}
addGlobalMetaList("X position for position", hdr.stageXCoord);
addGlobalMetaList("Y position for position", hdr.stageYCoord);
addGlobalMetaList("Z position for position", hdr.stageZCoord);
}
}
setSeries(0);
// --- populate OME metadata ---
LOGGER.info("Populating OME metadata");
MetadataTools.populatePixels(store, this, true);
// link Instrument and Image
String instrumentID = MetadataTools.createLSID("Instrument", 0);
store.setInstrumentID(instrumentID, 0);
for (int i = 0; i < getSeriesCount(); i++) {
store.setImageInstrumentRef(instrumentID, i);
}
}
use of loci.formats.meta.MetadataStore in project bioformats by openmicroscopy.
the class DeltavisionReader method initExtraMetadata.
protected void initExtraMetadata() throws FormatException, IOException {
MetadataStore store = makeFilterMetadata();
// --- read in the image header data ---
LOGGER.info("Reading header");
in.seek(16);
int subImageStartX = in.readInt();
int subImageStartY = in.readInt();
int subImageStartZ = in.readInt();
int pixelSamplingX = in.readInt();
int pixelSamplingY = in.readInt();
int pixelSamplingZ = in.readInt();
float pixX = in.readFloat();
float pixY = in.readFloat();
float pixZ = in.readFloat();
float xAxisAngle = in.readFloat();
float yAxisAngle = in.readFloat();
float zAxisAngle = in.readFloat();
int xAxisSeq = in.readInt();
int yAxisSeq = in.readInt();
int zAxisSeq = in.readInt();
float[] minWave = new float[5];
float[] maxWave = new float[5];
minWave[0] = in.readFloat();
maxWave[0] = in.readFloat();
float meanIntensity = in.readFloat();
int spaceGroupNumber = in.readInt();
in.seek(132);
short numSubResSets = in.readShort();
short zAxisReductionQuotient = in.readShort();
for (int i = 1; i <= 3; i++) {
minWave[i] = in.readFloat();
maxWave[i] = in.readFloat();
}
int type = in.readShort();
int lensID = in.readShort();
in.seek(172);
minWave[4] = in.readFloat();
maxWave[4] = in.readFloat();
in.seek(184);
float xTiltAngle = in.readFloat();
float yTiltAngle = in.readFloat();
float zTiltAngle = in.readFloat();
in.skipBytes(2);
short[] waves = new short[5];
for (int i = 0; i < waves.length; i++) {
waves[i] = in.readShort();
}
float xOrigin = in.readFloat();
float yOrigin = in.readFloat();
float zOrigin = in.readFloat();
in.skipBytes(4);
String[] title = new String[10];
for (int i = 0; i < title.length; i++) {
// Make sure that "null" characters are stripped out
title[i] = in.readByteToString(80).replaceAll("\0", "");
}
// --- compute some secondary values ---
String imageType = type < IMAGE_TYPES.length ? IMAGE_TYPES[type] : "unknown";
String imageDesc = title[0];
if (imageDesc != null && imageDesc.length() == 0)
imageDesc = null;
// --- populate original metadata ---
LOGGER.info("Populating original metadata");
addGlobalMeta("Sub-image starting point (X)", subImageStartX);
addGlobalMeta("Sub-image starting point (Y)", subImageStartY);
addGlobalMeta("Sub-image starting point (Z)", subImageStartZ);
addGlobalMeta("Pixel sampling size (X)", pixelSamplingX);
addGlobalMeta("Pixel sampling size (Y)", pixelSamplingY);
addGlobalMeta("Pixel sampling size (Z)", pixelSamplingZ);
addGlobalMeta("X element length (in um)", pixX);
addGlobalMeta("Y element length (in um)", pixY);
addGlobalMeta("Z element length (in um)", pixZ);
addGlobalMeta("X axis angle", xAxisAngle);
addGlobalMeta("Y axis angle", yAxisAngle);
addGlobalMeta("Z axis angle", zAxisAngle);
addGlobalMeta("Column axis sequence", xAxisSeq);
addGlobalMeta("Row axis sequence", yAxisSeq);
addGlobalMeta("Section axis sequence", zAxisSeq);
addGlobalMeta("Image Type", imageType);
addGlobalMeta("Lens ID Number", lensID);
addGlobalMeta("X axis tilt angle", xTiltAngle);
addGlobalMeta("Y axis tilt angle", yTiltAngle);
addGlobalMeta("Z axis tilt angle", zTiltAngle);
for (int i = 0; i < waves.length; i++) {
addGlobalMeta("Wavelength " + (i + 1) + " (in nm)", waves[i]);
}
addGlobalMeta("X origin (in um)", xOrigin);
addGlobalMeta("Y origin (in um)", yOrigin);
addGlobalMeta("Z origin (in um)", zOrigin);
for (String t : title) {
addGlobalMetaList("Title", t);
}
for (int i = 0; i < minWave.length; i++) {
addGlobalMeta("Wavelength " + (i + 1) + " min. intensity", minWave[i]);
addGlobalMeta("Wavelength " + (i + 1) + " max. intensity", maxWave[i]);
}
addGlobalMeta("Wavelength 1 mean intensity", meanIntensity);
addGlobalMeta("Space group number", spaceGroupNumber);
addGlobalMeta("Number of Sub-resolution sets", numSubResSets);
addGlobalMeta("Z axis reduction quotient", zAxisReductionQuotient);
// --- populate OME metadata ---
LOGGER.info("Populating OME metadata");
for (int series = 0; series < getSeriesCount(); series++) {
if (store instanceof IMinMaxStore) {
IMinMaxStore minMaxStore = (IMinMaxStore) store;
for (int i = 0; i < minWave.length; i++) {
if (i < getEffectiveSizeC()) {
minMaxStore.setChannelGlobalMinMax(i, minWave[i], maxWave[i], series);
}
}
}
Double x = new Double(pixX);
Length sizeX = FormatTools.getPhysicalSizeX(x);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, series);
}
Double y = new Double(pixY);
Length sizeY = FormatTools.getPhysicalSizeY(y);
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, series);
}
Double z = new Double(pixZ);
Length sizeZ = FormatTools.getPhysicalSizeZ(z);
if (sizeZ != null) {
store.setPixelsPhysicalSizeZ(sizeZ, series);
}
store.setImageDescription(imageDesc, series);
}
populateObjective(store, lensID);
// if matching log file exists, extract key/value pairs from it
boolean logFound = isGroupFiles() ? parseLogFile(store) : false;
if (isGroupFiles())
parseDeconvolutionLog(store);
if (getSeriesCount() == 1) {
xTiles = 1;
yTiles = 1;
backwardsStage = false;
}
for (int series = 0; series < getSeriesCount(); series++) {
int seriesIndex = series;
if (backwardsStage) {
int x = series % xTiles;
int y = series / xTiles;
seriesIndex = (yTiles - y - 1) * xTiles + (xTiles - x - 1);
}
for (int i = 0; i < getImageCount(); i++) {
int[] coords = getZCTCoords(i);
int tIndex = getSeriesCount() * coords[2] + seriesIndex;
DVExtHdrFields hdr = extHdrFields[coords[0]][coords[1]][tIndex];
// plane timing
store.setPlaneDeltaT(new Time(new Double(hdr.timeStampSeconds), UNITS.SECOND), series, i);
store.setPlaneExposureTime(new Time(new Double(extHdrFields[0][coords[1]][0].expTime), UNITS.SECOND), series, i);
// stage position
if (!logFound || getSeriesCount() > 1) {
store.setPlanePositionX(hdr.stageXCoord, series, i);
store.setPlanePositionY(hdr.stageYCoord, series, i);
store.setPlanePositionZ(hdr.stageZCoord, series, i);
}
}
for (int w = 0; w < getSizeC(); w++) {
DVExtHdrFields hdrC = extHdrFields[0][w][series];
Length emission = FormatTools.getEmissionWavelength(new Double(waves[w]));
Length excitation = FormatTools.getExcitationWavelength(new Double(hdrC.exWavelen));
if (emission != null) {
store.setChannelEmissionWavelength(emission, series, w);
}
if (excitation != null) {
store.setChannelExcitationWavelength(excitation, series, w);
}
if (ndFilters[w] == null)
ndFilters[w] = new Double(hdrC.ndFilter);
store.setChannelNDFilter(ndFilters[w], series, w);
}
}
}
Aggregations