use of ome.units.quantity.Time in project bioformats by openmicroscopy.
the class Exporter method run.
// -- Exporter API methods --
/**
* Executes the plugin.
*/
public void run() {
String outfile = null;
Boolean splitZ = null;
Boolean splitC = null;
Boolean splitT = null;
Boolean padded = null;
Boolean saveRoi = null;
String compression = null;
Boolean windowless = Boolean.FALSE;
if (plugin.arg != null) {
outfile = Macro.getValue(plugin.arg, "outfile", null);
String z = Macro.getValue(plugin.arg, "splitZ", null);
String c = Macro.getValue(plugin.arg, "splitC", null);
String t = Macro.getValue(plugin.arg, "splitT", null);
String zeroPad = Macro.getValue(plugin.arg, "padded", null);
String sr = Macro.getValue(plugin.arg, "saveRoi", null);
compression = Macro.getValue(plugin.arg, "compression", null);
String id = Macro.getValue(plugin.arg, "imageid", null);
splitZ = z == null ? null : Boolean.valueOf(z);
splitC = c == null ? null : Boolean.valueOf(c);
splitT = t == null ? null : Boolean.valueOf(t);
padded = zeroPad == null ? null : Boolean.valueOf(zeroPad);
saveRoi = sr == null ? null : Boolean.valueOf(sr);
if (id != null) {
try {
int imageID = Integer.parseInt(id);
ImagePlus plus = WindowManager.getImage(imageID);
if (plus != null)
imp = plus;
} catch (Exception e) {
// nothing to do, we use the current imagePlus
}
}
String w = Macro.getValue(plugin.arg, "windowless", null);
if (w != null) {
windowless = Boolean.valueOf(w);
}
plugin.arg = null;
}
if (outfile == null) {
String options = Macro.getOptions();
if (options != null) {
String save = Macro.getValue(options, "save", null);
if (save != null)
outfile = save;
}
}
// create a temporary file if window less
if (windowless && (outfile == null || outfile.length() == 0)) {
File tmp = null;
try {
String name = removeExtension(imp.getTitle());
String n = name + ".ome.tif";
tmp = File.createTempFile(name, ".ome.tif");
File p = tmp.getParentFile();
File[] list = p.listFiles();
// make sure we delete a previous tmp file with same name if any
if (list != null) {
File toDelete = null;
for (int i = 0; i < list.length; i++) {
if (list[i].getName().equals(n)) {
toDelete = list[i];
break;
}
}
if (toDelete != null) {
toDelete.delete();
}
}
outfile = new File(p, n).getAbsolutePath();
if (Recorder.record)
Recorder.recordPath("outputfile", outfile);
IJ.log("exporter outputfile " + outfile);
} catch (Exception e) {
// fall back to window mode.
} finally {
if (tmp != null)
tmp.delete();
}
}
File f = null;
if (outfile == null || outfile.length() == 0) {
// open a dialog prompting for the filename to save
// NB: Copied and adapted from ij.io.SaveDIalog.jSaveDispatchThread,
// so that the save dialog has a file filter for choosing output format.
String dir = null, name = null;
JFileChooser fc = GUITools.buildFileChooser(new ImageWriter(), false);
fc.setDialogTitle("Bio-Formats Exporter");
String defaultDir = OpenDialog.getDefaultDirectory();
if (defaultDir != null)
fc.setCurrentDirectory(new File(defaultDir));
// set OME-TIFF as the default output format
FileFilter[] ff = fc.getChoosableFileFilters();
FileFilter defaultFilter = null;
for (int i = 0; i < ff.length; i++) {
if (ff[i] instanceof ExtensionFileFilter) {
ExtensionFileFilter eff = (ExtensionFileFilter) ff[i];
if (i == 0 || eff.getExtension().equals("ome.tif")) {
defaultFilter = eff;
break;
}
}
}
if (defaultFilter != null)
fc.setFileFilter(defaultFilter);
int returnVal = fc.showSaveDialog(IJ.getInstance());
if (returnVal != JFileChooser.APPROVE_OPTION) {
Macro.abort();
return;
}
f = fc.getSelectedFile();
dir = fc.getCurrentDirectory().getPath() + File.separator;
name = fc.getName(f);
if (f.exists()) {
int ret = JOptionPane.showConfirmDialog(fc, "The file " + f.getName() + " already exists. \n" + "Would you like to replace it?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (ret != JOptionPane.OK_OPTION)
f = null;
} else {
// ensure filename matches selected filter
FileFilter filter = fc.getFileFilter();
if (filter instanceof ExtensionFileFilter) {
ExtensionFileFilter eff = (ExtensionFileFilter) filter;
String[] ext = eff.getExtensions();
String lName = name.toLowerCase();
boolean hasExtension = false;
for (int i = 0; i < ext.length; i++) {
if (lName.endsWith("." + ext[i])) {
hasExtension = true;
break;
}
}
if (!hasExtension && ext.length > 0) {
// append chosen extension
name = name + "." + ext[0];
}
f = fc.getSelectedFile();
String filePath = f.getAbsolutePath();
if (!filePath.endsWith("." + ext[0])) {
f = new File(filePath + '.' + ext[0]);
}
if (f.exists()) {
int ret1 = JOptionPane.showConfirmDialog(fc, "The file " + f.getName() + " already exists. \n" + "Would you like to replace it?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (ret1 != JOptionPane.OK_OPTION)
f = null;
}
}
}
if (f == null)
Macro.abort();
else {
// do some ImageJ bookkeeping
OpenDialog.setDefaultDirectory(dir);
if (Recorder.record)
Recorder.recordPath("save", dir + name);
}
if (dir == null || name == null)
return;
outfile = new File(dir, name).getAbsolutePath();
if (outfile == null)
return;
}
if (windowless) {
if (splitZ == null)
splitZ = Boolean.FALSE;
if (splitC == null)
splitC = Boolean.FALSE;
if (splitT == null)
splitT = Boolean.FALSE;
if (padded == null)
padded = Boolean.FALSE;
}
if (splitZ == null || splitC == null || splitT == null) {
// ask if we want to export multiple files
GenericDialog multiFile = new GenericDialog("Bio-Formats Exporter - Multiple Files");
multiFile.addCheckbox("Write_each_Z_section to a separate file", false);
multiFile.addCheckbox("Write_each_timepoint to a separate file", false);
multiFile.addCheckbox("Write_each_channel to a separate file", false);
multiFile.addCheckbox("Use zero padding for filename indexes", false);
multiFile.showDialog();
splitZ = multiFile.getNextBoolean();
splitT = multiFile.getNextBoolean();
splitC = multiFile.getNextBoolean();
padded = multiFile.getNextBoolean();
if (multiFile.wasCanceled())
return;
}
try (IFormatWriter w = new ImageWriter().getWriter(outfile)) {
int ptype = 0;
int channels = 1;
switch(imp.getType()) {
case ImagePlus.GRAY8:
case ImagePlus.COLOR_256:
ptype = FormatTools.UINT8;
break;
case ImagePlus.COLOR_RGB:
channels = 3;
ptype = FormatTools.UINT8;
break;
case ImagePlus.GRAY16:
ptype = FormatTools.UINT16;
break;
case ImagePlus.GRAY32:
ptype = FormatTools.FLOAT;
break;
}
String title = imp.getTitle();
w.setWriteSequentially(true);
FileInfo fi = imp.getOriginalFileInfo();
String xml = fi == null ? null : fi.description == null ? null : fi.description.indexOf("xml") == -1 ? null : fi.description;
OMEXMLService service = null;
IMetadata store = null;
try {
ServiceFactory factory = new ServiceFactory();
service = factory.getInstance(OMEXMLService.class);
store = service.createOMEXMLMetadata(xml);
} catch (DependencyException de) {
} catch (ServiceException se) {
}
if (store == null)
IJ.error("OME-XML Java library not found.");
OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) store.getRoot();
if (root.sizeOfROIList() > 0) {
while (root.sizeOfROIList() > 0) {
ROI roi = root.getROI(0);
root.removeROI(roi);
}
store.setRoot(root);
}
if (xml == null) {
store.createRoot();
} else if (store.getImageCount() > 1) {
// the original dataset had multiple series
// we need to modify the IMetadata to represent the correct series
ArrayList<Integer> matchingSeries = new ArrayList<Integer>();
for (int series = 0; series < store.getImageCount(); series++) {
String type = store.getPixelsType(series).toString();
int pixelType = FormatTools.pixelTypeFromString(type);
if (pixelType == ptype) {
String imageName = store.getImageName(series);
if (title.indexOf(imageName) >= 0) {
matchingSeries.add(series);
}
}
}
int series = 0;
if (matchingSeries.size() > 1) {
for (int i = 0; i < matchingSeries.size(); i++) {
int index = matchingSeries.get(i);
String name = store.getImageName(index);
boolean valid = true;
for (int j = 0; j < matchingSeries.size(); j++) {
if (i != j) {
String compName = store.getImageName(matchingSeries.get(j));
if (compName.indexOf(name) >= 0) {
valid = false;
break;
}
}
}
if (valid) {
series = index;
break;
}
}
} else if (matchingSeries.size() == 1)
series = matchingSeries.get(0);
ome.xml.model.Image exportImage = root.getImage(series);
List<ome.xml.model.Image> allImages = root.copyImageList();
for (ome.xml.model.Image img : allImages) {
if (!img.equals(exportImage)) {
root.removeImage(img);
}
}
store.setRoot(root);
}
store.setPixelsSizeX(new PositiveInteger(imp.getWidth()), 0);
store.setPixelsSizeY(new PositiveInteger(imp.getHeight()), 0);
store.setPixelsSizeZ(new PositiveInteger(imp.getNSlices()), 0);
store.setPixelsSizeC(new PositiveInteger(channels * imp.getNChannels()), 0);
store.setPixelsSizeT(new PositiveInteger(imp.getNFrames()), 0);
if (store.getImageID(0) == null) {
store.setImageID(MetadataTools.createLSID("Image", 0), 0);
}
if (store.getPixelsID(0) == null) {
store.setPixelsID(MetadataTools.createLSID("Pixels", 0), 0);
}
// reset the pixel type, unless the only change is signedness
// this prevents problems if the user changed the bit depth of the image
boolean applyCalibrationFunction = false;
try {
int originalType = -1;
if (store.getPixelsType(0) != null) {
originalType = FormatTools.pixelTypeFromString(store.getPixelsType(0).toString());
}
if (ptype != originalType && (store.getPixelsType(0) == null || !FormatTools.isSigned(originalType) || FormatTools.getBytesPerPixel(originalType) != FormatTools.getBytesPerPixel(ptype))) {
store.setPixelsType(PixelType.fromString(FormatTools.getPixelTypeString(ptype)), 0);
} else if (FormatTools.isSigned(originalType)) {
applyCalibrationFunction = true;
}
} catch (EnumerationException e) {
}
if (store.getPixelsBinDataCount(0) == 0 || store.getPixelsBinDataBigEndian(0, 0) == null) {
store.setPixelsBinDataBigEndian(Boolean.FALSE, 0, 0);
}
if (store.getPixelsDimensionOrder(0) == null) {
try {
store.setPixelsDimensionOrder(DimensionOrder.fromString(ORDER), 0);
} catch (EnumerationException e) {
}
}
LUT[] luts = new LUT[imp.getNChannels()];
for (int c = 0; c < imp.getNChannels(); c++) {
if (c >= store.getChannelCount(0) || store.getChannelID(0, c) == null) {
String lsid = MetadataTools.createLSID("Channel", 0, c);
store.setChannelID(lsid, 0, c);
}
store.setChannelSamplesPerPixel(new PositiveInteger(channels), 0, 0);
if (imp instanceof CompositeImage) {
luts[c] = ((CompositeImage) imp).getChannelLut(c + 1);
}
}
Calibration cal = imp.getCalibration();
store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(cal.pixelWidth), 0);
store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(cal.pixelHeight), 0);
store.setPixelsPhysicalSizeZ(FormatTools.getPhysicalSizeZ(cal.pixelDepth), 0);
store.setPixelsTimeIncrement(new Time(new Double(cal.frameInterval), UNITS.SECOND), 0);
if (imp.getImageStackSize() != imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) {
if (!windowless) {
IJ.showMessageWithCancel("Bio-Formats Exporter Warning", "The number of planes in the stack (" + imp.getImageStackSize() + ") does not match the number of expected planes (" + (imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) + ")." + "\nIf you select 'OK', only " + imp.getImageStackSize() + " planes will be exported. If you wish to export all of the " + "planes,\nselect 'Cancel' and convert the Image5D window " + "to a stack.");
}
store.setPixelsSizeZ(new PositiveInteger(imp.getImageStackSize()), 0);
store.setPixelsSizeC(new PositiveInteger(1), 0);
store.setPixelsSizeT(new PositiveInteger(1), 0);
}
Object info = imp.getProperty("Info");
if (info != null) {
String imageInfo = info.toString();
if (imageInfo != null) {
String[] lines = imageInfo.split("\n");
for (String line : lines) {
int eq = line.lastIndexOf("=");
if (eq > 0) {
String key = line.substring(0, eq).trim();
String value = line.substring(eq + 1).trim();
if (key.endsWith("BitsPerPixel")) {
w.setValidBitsPerPixel(Integer.parseInt(value));
break;
}
}
}
}
}
// NB: Animation rate code copied from ij.plugin.Animator#doOptions().
final int rate;
if (cal.fps != 0.0) {
rate = (int) cal.fps;
} else if (cal.frameInterval != 0.0 && cal.getTimeUnit().equals("sec")) {
rate = (int) (1.0 / cal.frameInterval);
} else {
// NB: Code from ij.plugin.Animator#animationRate initializer.
// The value is 7 by default in ImageJ, so must be 7 here as well.
rate = (int) Prefs.getDouble(Prefs.FPS, 7.0);
}
if (rate > 0)
w.setFramesPerSecond(rate);
String[] outputFiles = new String[] { outfile };
int sizeZ = store.getPixelsSizeZ(0).getValue();
int sizeC = store.getPixelsSizeC(0).getValue();
int sizeT = store.getPixelsSizeT(0).getValue();
if (splitZ || splitC || splitT) {
int nFiles = 1;
if (splitZ) {
nFiles *= sizeZ;
}
if (splitC) {
nFiles *= sizeC;
}
if (splitT) {
nFiles *= sizeT;
}
outputFiles = new String[nFiles];
int dot = outfile.indexOf(".", outfile.lastIndexOf(File.separator));
String base = outfile.substring(0, dot);
String ext = outfile.substring(dot);
int nextFile = 0;
for (int z = 0; z < (splitZ ? sizeZ : 1); z++) {
for (int c = 0; c < (splitC ? sizeC : 1); c++) {
for (int t = 0; t < (splitT ? sizeT : 1); t++) {
int index = FormatTools.getIndex(ORDER, sizeZ, sizeC, sizeT, sizeZ * sizeC * sizeT, z, c, t);
String pattern = base + (splitZ ? "_Z%z" : "") + (splitC ? "_C%c" : "") + (splitT ? "_T%t" : "") + ext;
outputFiles[nextFile++] = FormatTools.getFilename(0, index, store, pattern, padded);
}
}
}
}
if (!w.getFormat().startsWith("OME")) {
if (splitZ) {
store.setPixelsSizeZ(new PositiveInteger(1), 0);
}
if (splitC) {
store.setPixelsSizeC(new PositiveInteger(1), 0);
}
if (splitT) {
store.setPixelsSizeT(new PositiveInteger(1), 0);
}
}
// prompt for options
String[] codecs = w.getCompressionTypes();
ImageProcessor proc = imp.getImageStack().getProcessor(1);
Image firstImage = proc.createImage();
firstImage = AWTImageTools.makeBuffered(firstImage, proc.getColorModel());
int thisType = AWTImageTools.getPixelType((BufferedImage) firstImage);
if (proc instanceof ColorProcessor) {
thisType = FormatTools.UINT8;
} else if (proc instanceof ShortProcessor) {
thisType = FormatTools.UINT16;
}
boolean notSupportedType = !w.isSupportedType(thisType);
if (notSupportedType) {
IJ.error("Pixel type (" + FormatTools.getPixelTypeString(thisType) + ") not supported by this format.");
return;
}
if (codecs != null && codecs.length > 1) {
boolean selected = false;
if (compression != null) {
for (int i = 0; i < codecs.length; i++) {
if (codecs[i].equals(compression)) {
selected = true;
break;
}
}
}
if (!selected && !windowless) {
GenericDialog gd = new GenericDialog("Bio-Formats Exporter Options");
gd.addChoice("Compression type: ", codecs, codecs[0]);
if (saveRoi != null) {
gd.addCheckbox("Export ROIs", saveRoi.booleanValue());
} else {
gd.addCheckbox("Export ROIs", true);
}
gd.showDialog();
saveRoi = gd.getNextBoolean();
if (gd.wasCanceled())
return;
compression = gd.getNextChoice();
}
}
boolean in = false;
if (outputFiles.length > 1) {
for (int i = 0; i < outputFiles.length; i++) {
if (new File(outputFiles[i]).exists()) {
in = true;
break;
}
}
}
if (in && !windowless) {
int ret1 = JOptionPane.showConfirmDialog(null, "Some files already exist. \n" + "Would you like to replace them?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (ret1 != JOptionPane.OK_OPTION) {
return;
}
// Delete the files overwrite does not correctly work
for (int i = 0; i < outputFiles.length; i++) {
new File(outputFiles[i]).delete();
}
}
// delete the file.
if (f != null)
f.delete();
if (compression != null) {
w.setCompression(compression);
}
// Save ROI's
if (saveRoi != null && saveRoi.booleanValue()) {
ROIHandler.saveROIs(store);
}
w.setMetadataRetrieve(store);
// convert and save slices
int size = imp.getImageStackSize();
ImageStack is = imp.getImageStack();
boolean doStack = w.canDoStacks() && size > 1;
int start = doStack ? 0 : imp.getCurrentSlice() - 1;
int end = doStack ? size : start + 1;
boolean littleEndian = false;
if (w.getMetadataRetrieve().getPixelsBigEndian(0) != null) {
littleEndian = !w.getMetadataRetrieve().getPixelsBigEndian(0).booleanValue();
} else if (w.getMetadataRetrieve().getPixelsBinDataCount(0) == 0) {
littleEndian = !w.getMetadataRetrieve().getPixelsBinDataBigEndian(0, 0).booleanValue();
}
byte[] plane = null;
w.setInterleaved(false);
int[] no = new int[outputFiles.length];
for (int i = start; i < end; i++) {
if (doStack) {
BF.status(false, "Saving plane " + (i + 1) + "/" + size);
BF.progress(false, i, size);
} else
BF.status(false, "Saving image");
proc = is.getProcessor(i + 1);
if (proc instanceof RecordedImageProcessor) {
proc = ((RecordedImageProcessor) proc).getChild();
}
int x = proc.getWidth();
int y = proc.getHeight();
if (proc instanceof ByteProcessor) {
if (applyCalibrationFunction) {
// don't alter 'pixels' directly as that will
// affect the open ImagePlus
byte[] pixels = (byte[]) proc.getPixels();
plane = new byte[pixels.length];
float[] calibration = proc.getCalibrationTable();
for (int pixel = 0; pixel < pixels.length; pixel++) {
plane[pixel] = (byte) calibration[pixels[pixel] & 0xff];
}
} else {
plane = (byte[]) proc.getPixels();
}
} else if (proc instanceof ShortProcessor) {
short[] pixels = (short[]) proc.getPixels();
if (applyCalibrationFunction) {
// don't alter 'pixels' directly as that will
// affect the open ImagePlus
plane = new byte[pixels.length * 2];
float[] calibration = proc.getCalibrationTable();
for (int pixel = 0; pixel < pixels.length; pixel++) {
short v = (short) calibration[pixels[pixel] & 0xffff];
DataTools.unpackBytes(v, plane, pixel * 2, 2, littleEndian);
}
} else {
plane = DataTools.shortsToBytes(pixels, littleEndian);
}
} else if (proc instanceof FloatProcessor) {
plane = DataTools.floatsToBytes((float[]) proc.getPixels(), littleEndian);
} else if (proc instanceof ColorProcessor) {
byte[][] pix = new byte[3][x * y];
((ColorProcessor) proc).getRGB(pix[0], pix[1], pix[2]);
plane = new byte[3 * x * y];
System.arraycopy(pix[0], 0, plane, 0, x * y);
System.arraycopy(pix[1], 0, plane, x * y, x * y);
System.arraycopy(pix[2], 0, plane, 2 * x * y, x * y);
if (i == start) {
sizeC /= 3;
}
}
int fileIndex = 0;
if (doStack) {
int[] coords = FormatTools.getZCTCoords(ORDER, sizeZ, sizeC, sizeT, size, i);
int realZ = sizeZ;
int realC = sizeC;
int realT = sizeT;
if (!splitZ) {
coords[0] = 0;
realZ = 1;
}
if (!splitC) {
coords[1] = 0;
realC = 1;
}
if (!splitT) {
coords[2] = 0;
realT = 1;
}
fileIndex = FormatTools.getIndex(ORDER, realZ, realC, realT, realZ * realC * realT, coords[0], coords[1], coords[2]);
}
if (notSupportedType) {
IJ.error("Pixel type not supported by this format.");
} else {
w.changeOutputFile(outputFiles[fileIndex]);
int currentChannel = FormatTools.getZCTCoords(ORDER, sizeZ, sizeC, sizeT, imp.getStackSize(), i)[1];
if (luts[currentChannel] != null) {
// expand to 16-bit LUT if necessary
int bpp = FormatTools.getBytesPerPixel(thisType);
if (bpp == 1) {
w.setColorModel(luts[currentChannel]);
} else if (bpp == 2) {
int lutSize = luts[currentChannel].getMapSize();
byte[][] lut = new byte[3][lutSize];
luts[currentChannel].getReds(lut[0]);
luts[currentChannel].getGreens(lut[1]);
luts[currentChannel].getBlues(lut[2]);
short[][] newLut = new short[3][65536];
int bins = newLut[0].length / lut[0].length;
for (int c = 0; c < newLut.length; c++) {
for (int q = 0; q < newLut[c].length; q++) {
int index = q / bins;
newLut[c][q] = (short) ((lut[c][index] * lut[0].length) + (q % bins));
}
}
w.setColorModel(new Index16ColorModel(16, newLut[0].length, newLut, littleEndian));
}
} else if (!proc.isDefaultLut()) {
w.setColorModel(proc.getColorModel());
}
w.saveBytes(no[fileIndex]++, plane);
}
}
w.close();
} catch (FormatException e) {
WindowTools.reportException(e);
} catch (IOException e) {
WindowTools.reportException(e);
}
}
use of ome.units.quantity.Time in project bioformats by openmicroscopy.
the class ICSReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
LOGGER.info("Finding companion file");
String icsId = id, idsId = id;
int dot = id.lastIndexOf(".");
String ext = dot < 0 ? "" : id.substring(dot + 1).toLowerCase();
if (ext.equals("ics")) {
// convert C to D regardless of case
char[] c = idsId.toCharArray();
c[c.length - 2]++;
idsId = new String(c);
} else if (ext.equals("ids")) {
// convert D to C regardless of case
char[] c = icsId.toCharArray();
c[c.length - 2]--;
icsId = new String(c);
}
if (icsId == null)
throw new FormatException("No ICS file found.");
Location icsFile = new Location(icsId);
if (!icsFile.exists())
throw new FormatException("ICS file not found.");
LOGGER.info("Checking file version");
// check if we have a v2 ICS file - means there is no companion IDS file
RandomAccessInputStream f = new RandomAccessInputStream(icsId);
if (f.readString(17).trim().equals("ics_version\t2.0")) {
in = new RandomAccessInputStream(icsId);
versionTwo = true;
} else {
if (idsId == null) {
f.close();
throw new FormatException("No IDS file found.");
}
Location idsFile = new Location(idsId);
if (!idsFile.exists()) {
f.close();
throw new FormatException("IDS file not found.");
}
currentIdsId = idsId;
in = new RandomAccessInputStream(currentIdsId);
}
f.close();
currentIcsId = icsId;
LOGGER.info("Reading metadata");
CoreMetadata m = core.get(0);
Double[] scales = null;
Double[] timestamps = null;
String[] units = null;
String[] axes = null;
int[] axisLengths = null;
String byteOrder = null, rFormat = null, compression = null;
// parse key/value pairs from beginning of ICS file
RandomAccessInputStream reader = new RandomAccessInputStream(icsId);
reader.seek(0);
reader.readString(NL);
String line = reader.readString(NL);
boolean signed = false;
final StringBuilder textBlock = new StringBuilder();
double[] sizes = null;
Double[] emWaves = null, exWaves = null;
Length[] stagePos = null;
String imageName = null, date = null, description = null;
Double magnification = null, lensNA = null, workingDistance = null;
String objectiveModel = null, immersion = null, lastName = null;
Hashtable<Integer, Double> gains = new Hashtable<Integer, Double>();
Hashtable<Integer, Double> pinholes = new Hashtable<Integer, Double>();
Hashtable<Integer, Double> wavelengths = new Hashtable<Integer, Double>();
Hashtable<Integer, String> channelNames = new Hashtable<Integer, String>();
String laserModel = null;
String laserManufacturer = null;
Double laserPower = null;
Double laserRepetitionRate = null;
String detectorManufacturer = null;
String detectorModel = null;
String microscopeModel = null;
String microscopeManufacturer = null;
String experimentType = null;
Time exposureTime = null;
String filterSetModel = null;
String dichroicModel = null;
String excitationModel = null;
String emissionModel = null;
while (line != null && !line.trim().equals("end") && reader.getFilePointer() < reader.length() - 1) {
line = line.trim();
if (line.length() > 0) {
// split the line into tokens
String[] tokens = tokenize(line);
String token0 = tokens[0].toLowerCase();
String[] keyValue = null;
// version category
if (token0.equals("ics_version")) {
String value = concatenateTokens(tokens, 1, tokens.length);
addGlobalMeta(token0, value);
} else // filename category
if (token0.equals("filename")) {
imageName = concatenateTokens(tokens, 1, tokens.length);
addGlobalMeta(token0, imageName);
} else // layout category
if (token0.equals("layout")) {
keyValue = findKeyValue(tokens, LAYOUT_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
if (key.equalsIgnoreCase("layout sizes")) {
StringTokenizer t = new StringTokenizer(value);
axisLengths = new int[t.countTokens()];
for (int n = 0; n < axisLengths.length; n++) {
try {
axisLengths[n] = Integer.parseInt(t.nextToken().trim());
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse axis length", e);
}
}
} else if (key.equalsIgnoreCase("layout order")) {
StringTokenizer t = new StringTokenizer(value);
axes = new String[t.countTokens()];
for (int n = 0; n < axes.length; n++) {
axes[n] = t.nextToken().trim();
}
} else if (key.equalsIgnoreCase("layout significant_bits")) {
m.bitsPerPixel = Integer.parseInt(value);
}
} else // representation category
if (token0.equals("representation")) {
keyValue = findKeyValue(tokens, REPRESENTATION_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
if (key.equalsIgnoreCase("representation byte_order")) {
byteOrder = value;
} else if (key.equalsIgnoreCase("representation format")) {
rFormat = value;
} else if (key.equalsIgnoreCase("representation compression")) {
compression = value;
} else if (key.equalsIgnoreCase("representation sign")) {
signed = value.equals("signed");
}
} else // parameter category
if (token0.equals("parameter")) {
keyValue = findKeyValue(tokens, PARAMETER_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
if (key.equalsIgnoreCase("parameter scale")) {
// parse physical pixel sizes and time increment
scales = splitDoubles(value);
} else if (key.equalsIgnoreCase("parameter t")) {
// parse explicit timestamps
timestamps = splitDoubles(value);
} else if (key.equalsIgnoreCase("parameter units")) {
// parse units for scale
units = value.split("\\s+");
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (key.equalsIgnoreCase("parameter ch")) {
String[] names = value.split(" ");
for (int n = 0; n < names.length; n++) {
channelNames.put(new Integer(n), names[n].trim());
}
}
}
} else // history category
if (token0.equals("history")) {
keyValue = findKeyValue(tokens, HISTORY_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
Double doubleValue = null;
try {
doubleValue = new Double(value);
} catch (NumberFormatException e) {
// ARG this happens a lot; spurious error in most cases
LOGGER.debug("Could not parse double value '{}'", value, e);
}
if (key.equalsIgnoreCase("history software") && value.indexOf("SVI") != -1) {
// ICS files written by SVI Huygens are inverted on the Y axis
invertY = true;
} else if (key.equalsIgnoreCase("history date") || key.equalsIgnoreCase("history created on")) {
if (value.indexOf(' ') > 0) {
date = value.substring(0, value.lastIndexOf(" "));
date = DateTools.formatDate(date, DATE_FORMATS);
}
} else if (key.equalsIgnoreCase("history creation date")) {
date = DateTools.formatDate(value, DATE_FORMATS);
} else if (key.equalsIgnoreCase("history type")) {
// HACK - support for Gray Institute at Oxford's ICS lifetime data
if (value.equalsIgnoreCase("time resolved") || value.equalsIgnoreCase("FluorescenceLifetime")) {
lifetime = true;
}
experimentType = value;
} else if (key.equalsIgnoreCase("history labels")) {
// HACK - support for Gray Institute at Oxford's ICS lifetime data
labels = value;
} else if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (key.equalsIgnoreCase("history") || key.equalsIgnoreCase("history text")) {
textBlock.append(value);
textBlock.append("\n");
metadata.remove(key);
} else if (key.startsWith("history gain")) {
Integer n = 0;
try {
n = new Integer(key.substring(12).trim());
n = new Integer(n.intValue() - 1);
} catch (NumberFormatException e) {
}
if (doubleValue != null) {
gains.put(n, doubleValue);
}
} else if (key.startsWith("history laser") && key.endsWith("wavelength")) {
int laser = Integer.parseInt(key.substring(13, key.indexOf(" ", 13))) - 1;
value = value.replaceAll("nm", "").trim();
try {
wavelengths.put(new Integer(laser), new Double(value));
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse wavelength", e);
}
} else if (key.equalsIgnoreCase("history Wavelength*")) {
String[] waves = value.split(" ");
for (int i = 0; i < waves.length; i++) {
wavelengths.put(new Integer(i), new Double(waves[i]));
}
} else if (key.equalsIgnoreCase("history laser manufacturer")) {
laserManufacturer = value;
} else if (key.equalsIgnoreCase("history laser model")) {
laserModel = value;
} else if (key.equalsIgnoreCase("history laser power")) {
try {
// TODO ARG i.e. doubleValue
laserPower = new Double(value);
} catch (NumberFormatException e) {
}
} else if (key.equalsIgnoreCase("history laser rep rate")) {
String repRate = value;
if (repRate.indexOf(' ') != -1) {
repRate = repRate.substring(0, repRate.lastIndexOf(" "));
}
laserRepetitionRate = new Double(repRate);
} else if (key.equalsIgnoreCase("history objective type") || key.equalsIgnoreCase("history objective")) {
objectiveModel = value;
} else if (key.equalsIgnoreCase("history objective immersion")) {
immersion = value;
} else if (key.equalsIgnoreCase("history objective NA")) {
lensNA = doubleValue;
} else if (key.equalsIgnoreCase("history objective WorkingDistance")) {
workingDistance = doubleValue;
} else if (key.equalsIgnoreCase("history objective magnification") || key.equalsIgnoreCase("history objective mag")) {
magnification = doubleValue;
} else if (key.equalsIgnoreCase("history camera manufacturer")) {
detectorManufacturer = value;
} else if (key.equalsIgnoreCase("history camera model")) {
detectorModel = value;
} else if (key.equalsIgnoreCase("history author") || key.equalsIgnoreCase("history experimenter")) {
lastName = value;
} else if (key.equalsIgnoreCase("history extents")) {
String[] lengths = value.split(" ");
sizes = new double[lengths.length];
for (int n = 0; n < sizes.length; n++) {
try {
sizes[n] = Double.parseDouble(lengths[n].trim());
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse axis length", e);
}
}
} else if (key.equalsIgnoreCase("history stage_xyzum")) {
String[] positions = value.split(" ");
stagePos = new Length[positions.length];
for (int n = 0; n < stagePos.length; n++) {
try {
final Double number = Double.valueOf(positions[n]);
stagePos[n] = new Length(number, UNITS.REFERENCEFRAME);
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse stage position", e);
}
}
} else if (key.equalsIgnoreCase("history stage positionx")) {
if (stagePos == null) {
stagePos = new Length[3];
}
final Double number = Double.valueOf(value);
stagePos[0] = new Length(number, UNITS.REFERENCEFRAME);
} else if (key.equalsIgnoreCase("history stage positiony")) {
if (stagePos == null) {
stagePos = new Length[3];
}
final Double number = Double.valueOf(value);
stagePos[1] = new Length(number, UNITS.REFERENCEFRAME);
} else if (key.equalsIgnoreCase("history stage positionz")) {
if (stagePos == null) {
stagePos = new Length[3];
}
final Double number = Double.valueOf(value);
stagePos[2] = new Length(number, UNITS.REFERENCEFRAME);
} else if (key.equalsIgnoreCase("history other text")) {
description = value;
} else if (key.startsWith("history step") && key.endsWith("name")) {
Integer n = new Integer(key.substring(12, key.indexOf(" ", 12)));
channelNames.put(n, value);
} else if (key.equalsIgnoreCase("history cube")) {
channelNames.put(new Integer(channelNames.size()), value);
} else if (key.equalsIgnoreCase("history cube emm nm")) {
if (emWaves == null) {
emWaves = new Double[1];
}
emWaves[0] = new Double(value.split(" ")[1].trim());
} else if (key.equalsIgnoreCase("history cube exc nm")) {
if (exWaves == null) {
exWaves = new Double[1];
}
exWaves[0] = new Double(value.split(" ")[1].trim());
} else if (key.equalsIgnoreCase("history microscope")) {
microscopeModel = value;
} else if (key.equalsIgnoreCase("history manufacturer")) {
microscopeManufacturer = value;
} else if (key.equalsIgnoreCase("history Exposure")) {
String expTime = value;
if (expTime.indexOf(' ') != -1) {
expTime = expTime.substring(0, expTime.indexOf(' '));
}
Double expDouble = new Double(expTime);
if (expDouble != null) {
exposureTime = new Time(expDouble, UNITS.SECOND);
}
} else if (key.equalsIgnoreCase("history filterset")) {
filterSetModel = value;
} else if (key.equalsIgnoreCase("history filterset dichroic name")) {
dichroicModel = value;
} else if (key.equalsIgnoreCase("history filterset exc name")) {
excitationModel = value;
} else if (key.equalsIgnoreCase("history filterset emm name")) {
emissionModel = value;
}
}
} else // document category
if (token0.equals("document")) {
keyValue = findKeyValue(tokens, DOCUMENT_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
} else // sensor category
if (token0.equals("sensor")) {
keyValue = findKeyValue(tokens, SENSOR_KEYS);
String key = keyValue[0];
String value = keyValue[1];
addGlobalMeta(key, value);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
if (key.equalsIgnoreCase("sensor s_params LambdaEm")) {
String[] waves = value.split(" ");
emWaves = new Double[waves.length];
for (int n = 0; n < emWaves.length; n++) {
try {
emWaves[n] = new Double(Double.parseDouble(waves[n]));
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse emission wavelength", e);
}
}
} else if (key.equalsIgnoreCase("sensor s_params LambdaEx")) {
String[] waves = value.split(" ");
exWaves = new Double[waves.length];
for (int n = 0; n < exWaves.length; n++) {
try {
exWaves[n] = new Double(Double.parseDouble(waves[n]));
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse excitation wavelength", e);
}
}
} else if (key.equalsIgnoreCase("sensor s_params PinholeRadius")) {
String[] pins = value.split(" ");
int channel = 0;
for (int n = 0; n < pins.length; n++) {
if (pins[n].trim().equals(""))
continue;
try {
pinholes.put(new Integer(channel++), new Double(pins[n]));
} catch (NumberFormatException e) {
LOGGER.debug("Could not parse pinhole", e);
}
}
}
}
} else // view category
if (token0.equals("view")) {
keyValue = findKeyValue(tokens, VIEW_KEYS);
String key = keyValue[0];
String value = keyValue[1];
// handle "view view color lib lut Green Fire green", etc.
if (key.equalsIgnoreCase("view view color lib lut")) {
int index;
int redIndex = value.toLowerCase().lastIndexOf("red");
int greenIndex = value.toLowerCase().lastIndexOf("green");
int blueIndex = value.toLowerCase().lastIndexOf("blue");
if (redIndex > 0 && redIndex > greenIndex && redIndex > blueIndex) {
index = redIndex + "red".length();
} else if (greenIndex > 0 && greenIndex > redIndex && greenIndex > blueIndex) {
index = greenIndex + "green".length();
} else if (blueIndex > 0 && blueIndex > redIndex && blueIndex > greenIndex) {
index = blueIndex + "blue".length();
} else {
index = value.indexOf(' ');
}
if (index > 0) {
key = key + ' ' + value.substring(0, index);
value = value.substring(index + 1);
}
} else // "view view color mode rgb set blue-green-red", etc.
if (key.equalsIgnoreCase("view view color mode rgb set")) {
int index = value.toLowerCase().lastIndexOf("colors");
if (index > 0) {
index += "colors".length();
} else {
index = value.indexOf(' ');
}
if (index > 0) {
key = key + ' ' + value.substring(0, index);
value = value.substring(index + 1);
}
}
addGlobalMeta(key, value);
} else {
LOGGER.debug("Unknown category " + token0);
}
}
line = reader.readString(NL);
}
reader.close();
hasInstrumentData = emWaves != null || exWaves != null || lensNA != null || stagePos != null || magnification != null || workingDistance != null || objectiveModel != null || immersion != null;
addGlobalMeta("history text", textBlock.toString());
LOGGER.info("Populating core metadata");
m.rgb = false;
m.dimensionOrder = "XY";
// find axis sizes
channelLengths = new Vector<Integer>();
channelTypes = new Vector<String>();
int bitsPerPixel = 0;
for (int i = 0; i < axes.length; i++) {
if (i >= axisLengths.length)
break;
if (axes[i].equals("bits")) {
bitsPerPixel = axisLengths[i];
while (bitsPerPixel % 8 != 0) bitsPerPixel++;
if (bitsPerPixel == 24 || bitsPerPixel == 48)
bitsPerPixel /= 3;
} else if (axes[i].equals("x")) {
m.sizeX = axisLengths[i];
} else if (axes[i].equals("y")) {
m.sizeY = axisLengths[i];
} else if (axes[i].equals("z")) {
m.sizeZ = axisLengths[i];
if (getDimensionOrder().indexOf('Z') == -1) {
m.dimensionOrder += 'Z';
}
} else if (axes[i].equals("t")) {
if (getSizeT() == 0)
m.sizeT = axisLengths[i];
else
m.sizeT *= axisLengths[i];
if (getDimensionOrder().indexOf('T') == -1) {
m.dimensionOrder += 'T';
}
} else {
if (m.sizeC == 0)
m.sizeC = axisLengths[i];
else
m.sizeC *= axisLengths[i];
channelLengths.add(new Integer(axisLengths[i]));
storedRGB = getSizeX() == 0;
m.rgb = getSizeX() == 0 && getSizeC() <= 4 && getSizeC() > 1;
if (getDimensionOrder().indexOf('C') == -1) {
m.dimensionOrder += 'C';
}
if (axes[i].startsWith("c")) {
channelTypes.add(FormatTools.CHANNEL);
} else if (axes[i].equals("p")) {
channelTypes.add(FormatTools.PHASE);
} else if (axes[i].equals("f")) {
channelTypes.add(FormatTools.FREQUENCY);
} else
channelTypes.add("");
}
}
if (channelLengths.isEmpty()) {
channelLengths.add(1);
channelTypes.add(FormatTools.CHANNEL);
}
if (isRGB() && emWaves != null && emWaves.length == getSizeC()) {
m.rgb = false;
storedRGB = true;
}
m.dimensionOrder = MetadataTools.makeSaneDimensionOrder(getDimensionOrder());
if (getSizeZ() == 0)
m.sizeZ = 1;
if (getSizeC() == 0)
m.sizeC = 1;
if (getSizeT() == 0)
m.sizeT = 1;
// length and type.
if (channelLengths.size() > 0) {
int clen0 = channelLengths.get(0);
String ctype0 = channelTypes.get(0);
boolean same = true;
for (Integer len : channelLengths) {
if (clen0 != len)
same = false;
}
for (String type : channelTypes) {
if (!ctype0.equals(type))
same = false;
}
if (same) {
m.moduloC.type = ctype0;
if (FormatTools.LIFETIME.equals(ctype0)) {
m.moduloC.parentType = FormatTools.SPECTRA;
}
m.moduloC.typeDescription = "TCSPC";
m.moduloC.start = 0;
m.moduloC.step = 1;
m.moduloC.end = clen0 - 1;
}
}
m.interleaved = isRGB();
m.indexed = false;
m.falseColor = false;
m.metadataComplete = true;
m.littleEndian = true;
// HACK - support for Gray Institute at Oxford's ICS lifetime data
if (lifetime && labels != null) {
int binCount = 0;
String newOrder = null;
if (labels.equalsIgnoreCase("t x y")) {
// nominal X Y Z is actually C X Y (which is X Y C interleaved)
newOrder = "XYCZT";
m.interleaved = true;
binCount = m.sizeX;
m.sizeX = m.sizeY;
m.sizeY = m.sizeZ;
m.sizeZ = 1;
} else if (labels.equalsIgnoreCase("x y t")) {
// nominal X Y Z is actually X Y C
newOrder = "XYCZT";
binCount = m.sizeZ;
m.sizeZ = 1;
} else {
LOGGER.debug("Lifetime data, unexpected 'history labels' " + labels);
}
if (newOrder != null) {
m.dimensionOrder = newOrder;
m.sizeC = binCount;
m.moduloC.parentType = FormatTools.LIFETIME;
}
}
// do not modify the Z, T, or channel counts after this point
m.imageCount = getSizeZ() * getSizeT();
if (!isRGB())
m.imageCount *= getSizeC();
if (byteOrder != null) {
String firstByte = byteOrder.split(" ")[0];
int first = Integer.parseInt(firstByte);
m.littleEndian = rFormat.equals("real") ? first == 1 : first != 1;
}
gzip = (compression == null) ? false : compression.equals("gzip");
if (versionTwo) {
String s = in.readString(NL);
while (!s.trim().equals("end")) s = in.readString(NL);
}
offset = in.getFilePointer();
int bytes = bitsPerPixel / 8;
if (bitsPerPixel < 32)
m.littleEndian = !isLittleEndian();
boolean fp = rFormat.equals("real");
m.pixelType = FormatTools.pixelTypeFromBytes(bytes, signed, fp);
LOGGER.info("Populating OME metadata");
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this, true);
// populate Image data
store.setImageName(imageName, 0);
if (date != null)
store.setImageAcquisitionDate(new Timestamp(date), 0);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
store.setImageDescription(description, 0);
// link Instrument and Image
String instrumentID = MetadataTools.createLSID("Instrument", 0);
store.setInstrumentID(instrumentID, 0);
store.setMicroscopeModel(microscopeModel, 0);
store.setMicroscopeManufacturer(microscopeManufacturer, 0);
store.setImageInstrumentRef(instrumentID, 0);
store.setExperimentID(MetadataTools.createLSID("Experiment", 0), 0);
store.setExperimentType(getExperimentType(experimentType), 0);
if (scales != null) {
if (units != null && units.length == scales.length - 1) {
// correct for missing units
// sometimes, the units for the C axis are missing entirely
ArrayList<String> realUnits = new ArrayList<String>();
int unitIndex = 0;
for (int i = 0; i < axes.length; i++) {
if (axes[i].toLowerCase().equals("ch")) {
realUnits.add("nm");
} else {
realUnits.add(units[unitIndex++]);
}
}
units = realUnits.toArray(new String[realUnits.size()]);
}
for (int i = 0; i < scales.length; i++) {
Double scale = scales[i];
if (scale == null) {
continue;
}
String axis = axes != null && axes.length > i ? axes[i] : "";
String unit = units != null && units.length > i ? units[i] : "";
if (axis.equals("x")) {
if (checkUnit(unit, "um", "microns", "micrometers")) {
Length x = FormatTools.getPhysicalSizeX(scale);
if (x != null) {
store.setPixelsPhysicalSizeX(x, 0);
}
}
} else if (axis.equals("y")) {
if (checkUnit(unit, "um", "microns", "micrometers")) {
Length y = FormatTools.getPhysicalSizeY(scale);
if (y != null) {
store.setPixelsPhysicalSizeY(y, 0);
}
}
} else if (axis.equals("z")) {
if (checkUnit(unit, "um", "microns", "micrometers")) {
Length z = FormatTools.getPhysicalSizeZ(scale);
if (z != null) {
store.setPixelsPhysicalSizeZ(z, 0);
}
}
} else if (axis.equals("t") && scale != null) {
if (checkUnit(unit, "ms")) {
store.setPixelsTimeIncrement(new Time(scale, UNITS.MILLISECOND), 0);
} else if (checkUnit(unit, "seconds") || checkUnit(unit, "s")) {
store.setPixelsTimeIncrement(new Time(scale, UNITS.SECOND), 0);
}
}
}
} else if (sizes != null) {
if (sizes.length > 0) {
Length x = FormatTools.getPhysicalSizeX(sizes[0]);
if (x != null) {
store.setPixelsPhysicalSizeX(x, 0);
}
}
if (sizes.length > 1) {
sizes[1] /= getSizeY();
Length y = FormatTools.getPhysicalSizeY(sizes[1]);
if (y != null) {
store.setPixelsPhysicalSizeY(y, 0);
}
}
}
if (timestamps != null) {
for (int t = 0; t < timestamps.length; t++) {
// ignore superfluous timestamps
if (t >= getSizeT())
break;
// ignore missing timestamp
if (timestamps[t] == null)
continue;
Time deltaT = new Time(timestamps[t], UNITS.SECOND);
// ignore invalid timestamp
if (Double.isNaN(deltaT.value().doubleValue()))
continue;
// assign timestamp to all relevant planes
for (int z = 0; z < getSizeZ(); z++) {
for (int c = 0; c < getEffectiveSizeC(); c++) {
int index = getIndex(z, c, t);
store.setPlaneDeltaT(deltaT, 0, index);
}
}
}
}
for (int i = 0; i < getEffectiveSizeC(); i++) {
if (channelNames.containsKey(i)) {
store.setChannelName(channelNames.get(i), 0, i);
}
if (pinholes.containsKey(i)) {
store.setChannelPinholeSize(new Length(pinholes.get(i), UNITS.MICROMETER), 0, i);
}
if (emWaves != null && i < emWaves.length) {
Length em = FormatTools.getEmissionWavelength(emWaves[i]);
if (em != null) {
store.setChannelEmissionWavelength(em, 0, i);
}
}
if (exWaves != null && i < exWaves.length) {
Length ex = FormatTools.getExcitationWavelength(exWaves[i]);
if (ex != null) {
store.setChannelExcitationWavelength(ex, 0, i);
}
}
}
// populate Laser data
Integer[] lasers = wavelengths.keySet().toArray(new Integer[0]);
Arrays.sort(lasers);
for (int i = 0; i < lasers.length; i++) {
store.setLaserID(MetadataTools.createLSID("LightSource", 0, i), 0, i);
Length wave = FormatTools.getWavelength(wavelengths.get(lasers[i]));
if (wave != null) {
store.setLaserWavelength(wave, 0, i);
}
store.setLaserType(getLaserType("Other"), 0, i);
store.setLaserLaserMedium(getLaserMedium("Other"), 0, i);
store.setLaserManufacturer(laserManufacturer, 0, i);
store.setLaserModel(laserModel, 0, i);
Power theLaserPower = FormatTools.createPower(laserPower, UNITS.MILLIWATT);
if (theLaserPower != null) {
store.setLaserPower(theLaserPower, 0, i);
}
Frequency theLaserRepetitionRate = FormatTools.createFrequency(laserRepetitionRate, UNITS.HERTZ);
if (theLaserRepetitionRate != null) {
store.setLaserRepetitionRate(theLaserRepetitionRate, 0, i);
}
}
if (lasers.length == 0 && laserManufacturer != null) {
store.setLaserID(MetadataTools.createLSID("LightSource", 0, 0), 0, 0);
store.setLaserType(getLaserType("Other"), 0, 0);
store.setLaserLaserMedium(getLaserMedium("Other"), 0, 0);
store.setLaserManufacturer(laserManufacturer, 0, 0);
store.setLaserModel(laserModel, 0, 0);
Power theLaserPower = FormatTools.createPower(laserPower, UNITS.MILLIWATT);
if (theLaserPower != null) {
store.setLaserPower(theLaserPower, 0, 0);
}
Frequency theLaserRepetitionRate = FormatTools.createFrequency(laserRepetitionRate, UNITS.HERTZ);
if (theLaserRepetitionRate != null) {
store.setLaserRepetitionRate(theLaserRepetitionRate, 0, 0);
}
}
if (filterSetModel != null) {
store.setFilterSetID(MetadataTools.createLSID("FilterSet", 0, 0), 0, 0);
store.setFilterSetModel(filterSetModel, 0, 0);
String dichroicID = MetadataTools.createLSID("Dichroic", 0, 0);
String emFilterID = MetadataTools.createLSID("Filter", 0, 0);
String exFilterID = MetadataTools.createLSID("Filter", 0, 1);
store.setDichroicID(dichroicID, 0, 0);
store.setDichroicModel(dichroicModel, 0, 0);
store.setFilterSetDichroicRef(dichroicID, 0, 0);
store.setFilterID(emFilterID, 0, 0);
store.setFilterModel(emissionModel, 0, 0);
store.setFilterSetEmissionFilterRef(emFilterID, 0, 0, 0);
store.setFilterID(exFilterID, 0, 1);
store.setFilterModel(excitationModel, 0, 1);
store.setFilterSetExcitationFilterRef(exFilterID, 0, 0, 0);
}
if (objectiveModel != null)
store.setObjectiveModel(objectiveModel, 0, 0);
if (immersion == null)
immersion = "Other";
store.setObjectiveImmersion(getImmersion(immersion), 0, 0);
if (lensNA != null)
store.setObjectiveLensNA(lensNA, 0, 0);
if (workingDistance != null) {
store.setObjectiveWorkingDistance(new Length(workingDistance, UNITS.MICROMETER), 0, 0);
}
if (magnification != null) {
store.setObjectiveCalibratedMagnification(magnification, 0, 0);
}
store.setObjectiveCorrection(getCorrection("Other"), 0, 0);
// link Objective to Image
String objectiveID = MetadataTools.createLSID("Objective", 0, 0);
store.setObjectiveID(objectiveID, 0, 0);
store.setObjectiveSettingsID(objectiveID, 0);
// populate Detector data
String detectorID = MetadataTools.createLSID("Detector", 0, 0);
store.setDetectorID(detectorID, 0, 0);
store.setDetectorManufacturer(detectorManufacturer, 0, 0);
store.setDetectorModel(detectorModel, 0, 0);
store.setDetectorType(getDetectorType("Other"), 0, 0);
for (Integer key : gains.keySet()) {
int index = key.intValue();
if (index < getEffectiveSizeC()) {
store.setDetectorSettingsGain(gains.get(key), 0, index);
store.setDetectorSettingsID(detectorID, 0, index);
}
}
if (lastName != null) {
String experimenterID = MetadataTools.createLSID("Experimenter", 0);
store.setExperimenterID(experimenterID, 0);
store.setExperimenterLastName(lastName, 0);
}
if (stagePos != null) {
for (int i = 0; i < getImageCount(); i++) {
if (stagePos.length > 0) {
store.setPlanePositionX(stagePos[0], 0, i);
addGlobalMeta("X position for position #1", stagePos[0]);
}
if (stagePos.length > 1) {
store.setPlanePositionY(stagePos[1], 0, i);
addGlobalMeta("Y position for position #1", stagePos[1]);
}
if (stagePos.length > 2) {
store.setPlanePositionZ(stagePos[2], 0, i);
addGlobalMeta("Z position for position #1", stagePos[2]);
}
}
}
if (exposureTime != null) {
for (int i = 0; i < getImageCount(); i++) {
store.setPlaneExposureTime(exposureTime, 0, i);
}
}
}
}
use of ome.units.quantity.Time in project bioformats by openmicroscopy.
the class MicromanagerReader method parsePosition.
private void parsePosition(String jsonData, int posIndex) throws IOException, FormatException {
Position p = positions.get(posIndex);
CoreMetadata ms = core.get(posIndex);
String parent = new Location(p.metadataFile).getParent();
// now parse the rest of the metadata
// metadata.txt looks something like this:
//
// {
// "Section Name": {
// "Key": "Value",
// "Array key": [
// first array value, second array value
// ]
// }
//
// }
LOGGER.info("Populating metadata");
Vector<Double> stamps = new Vector<Double>();
p.voltage = new Vector<Double>();
StringTokenizer st = new StringTokenizer(jsonData, "\n");
int[] slice = new int[3];
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
boolean open = token.indexOf('[') != -1;
boolean closed = token.indexOf(']') != -1;
if (open || (!open && !closed && !token.equals("{") && !token.startsWith("}"))) {
int quote = token.indexOf("\"") + 1;
String key = token.substring(quote, token.indexOf("\"", quote));
String value = null;
if (open == closed) {
value = token.substring(token.indexOf(':') + 1);
} else if (!closed) {
final StringBuilder valueBuffer = new StringBuilder();
while (!closed) {
token = st.nextToken();
closed = token.indexOf(']') != -1;
valueBuffer.append(token);
}
value = valueBuffer.toString();
value = value.replaceAll("\n", "");
}
if (value == null)
continue;
int startIndex = value.indexOf('[');
int endIndex = value.indexOf(']');
if (endIndex == -1)
endIndex = value.length();
value = value.substring(startIndex + 1, endIndex).trim();
if (value.length() == 0) {
continue;
}
value = value.substring(0, value.length() - 1);
value = value.replaceAll("\"", "");
if (value.endsWith(","))
value = value.substring(0, value.length() - 1);
addSeriesMeta(key, value);
if (key.equals("Channels")) {
ms.sizeC = Integer.parseInt(value);
} else if (key.equals("ChNames")) {
p.channels = value.split(",");
for (int q = 0; q < p.channels.length; q++) {
p.channels[q] = p.channels[q].replaceAll("\"", "").trim();
}
} else if (key.equals("Frames")) {
ms.sizeT = Integer.parseInt(value);
} else if (key.equals("Slices")) {
ms.sizeZ = Integer.parseInt(value);
} else if (key.equals("SlicesFirst")) {
if (value.equals("false")) {
ms.dimensionOrder = "XYCZT";
} else {
ms.dimensionOrder = "XYZCT";
}
} else if (key.equals("PixelSize_um")) {
p.pixelSize = new Double(value);
} else if (key.equals("z-step_um")) {
p.sliceThickness = new Double(value);
} else if (key.equals("Time")) {
p.time = value;
} else if (key.equals("Comment")) {
p.comment = value;
} else if (key.equals("FileName")) {
p.fileNameMap.put(new Index(slice), value);
if (p.baseTiff == null) {
p.baseTiff = value;
}
} else if (key.equals("Width")) {
ms.sizeX = Integer.parseInt(value);
} else if (key.equals("Height")) {
ms.sizeY = Integer.parseInt(value);
} else if (key.equals("IJType")) {
int type = Integer.parseInt(value);
switch(type) {
case 0:
ms.pixelType = FormatTools.UINT8;
break;
case 1:
ms.pixelType = FormatTools.UINT16;
break;
default:
throw new FormatException("Unknown type: " + type);
}
}
}
if (token.startsWith("\"FrameKey")) {
int dash = token.indexOf('-') + 1;
int nextDash = token.indexOf("-", dash);
slice[2] = Integer.parseInt(token.substring(dash, nextDash));
dash = nextDash + 1;
nextDash = token.indexOf("-", dash);
slice[1] = Integer.parseInt(token.substring(dash, nextDash));
dash = nextDash + 1;
slice[0] = Integer.parseInt(token.substring(dash, token.indexOf("\"", dash)));
token = st.nextToken().trim();
String key = "";
StringBuilder valueBuffer = new StringBuilder();
boolean valueArray = false;
int nestedCount = 0;
while (!token.startsWith("}") || nestedCount > 0) {
if (token.trim().endsWith("{")) {
nestedCount++;
token = st.nextToken().trim();
continue;
} else if (token.trim().startsWith("}")) {
nestedCount--;
token = st.nextToken().trim();
continue;
}
if (valueArray || token.trim().equals("],")) {
if (token.trim().equals("],")) {
valueArray = false;
} else {
valueBuffer.append(token.trim().replaceAll("\"", ""));
token = st.nextToken().trim();
continue;
}
} else {
int colon = token.indexOf(':');
key = token.substring(1, colon).trim();
valueBuffer.setLength(0);
valueBuffer.append(token.substring(colon + 1, token.length() - 1).trim().replaceAll("\"", ""));
key = key.replaceAll("\"", "");
if (token.trim().endsWith("[")) {
valueArray = true;
token = st.nextToken().trim();
continue;
}
}
String value = valueBuffer.toString();
addSeriesMeta(key, value);
if (key.equals("Exposure-ms")) {
p.exposureTime = new Time(Double.valueOf(value), UNITS.MILLISECOND);
} else if (key.equals("ElapsedTime-ms")) {
stamps.add(Double.valueOf(value));
} else if (key.equals("Core-Camera"))
p.cameraRef = value;
else if (key.equals(p.cameraRef + "-Binning")) {
if (value.indexOf('x') != -1)
p.binning = value;
else
p.binning = value + "x" + value;
} else if (key.equals(p.cameraRef + "-CameraID"))
p.detectorID = value;
else if (key.equals(p.cameraRef + "-CameraName")) {
p.detectorModel = value;
} else if (key.equals(p.cameraRef + "-Gain")) {
p.gain = (int) Double.parseDouble(value);
} else if (key.equals(p.cameraRef + "-Name")) {
p.detectorManufacturer = value;
} else if (key.equals(p.cameraRef + "-Temperature")) {
p.temperature = Double.parseDouble(value);
} else if (key.equals(p.cameraRef + "-CCDMode")) {
p.cameraMode = value;
} else if (key.startsWith("DAC-") && key.endsWith("-Volts")) {
p.voltage.add(new Double(value));
} else if (key.equals("FileName")) {
p.fileNameMap.put(new Index(slice), value);
Location realFile = new Location(parent, value);
if (realFile.exists()) {
if (p.tiffs == null) {
p.tiffs = new Vector<String>();
}
p.tiffs.add(realFile.getAbsolutePath());
}
if (p.baseTiff == null) {
p.baseTiff = value;
}
}
token = st.nextToken().trim();
}
} else if (token.startsWith("\"Coords-")) {
String path = token.substring(token.indexOf('-') + 1, token.lastIndexOf("\""));
int[] zct = new int[3];
int position = 0;
while (!token.startsWith("}")) {
int sep = token.indexOf(':');
if (sep > 0) {
String key = token.substring(0, sep);
String value = token.substring(sep + 1);
key = key.replaceAll("\"", "").trim();
value = value.replaceAll(",", "").trim();
if (key.equals("position")) {
position = Integer.parseInt(value);
} else if (key.equals("time")) {
zct[2] = Integer.parseInt(value);
} else if (key.equals("z")) {
zct[0] = Integer.parseInt(value);
} else if (key.equals("channel")) {
zct[1] = Integer.parseInt(value);
}
}
token = st.nextToken().trim();
}
Index idx = new Index(zct);
idx.position = position;
p.fileNameMap.put(idx, path);
}
}
p.timestamps = stamps.toArray(new Double[stamps.size()]);
Arrays.sort(p.timestamps);
if (new Location(parent, XML).exists()) {
p.xmlFile = new Location(parent, XML).getAbsolutePath();
parseXMLFile();
}
if (getSizeZ() == 0)
ms.sizeZ = 1;
if (getSizeT() == 0)
ms.sizeT = 1;
if (ms.dimensionOrder == null)
ms.dimensionOrder = "XYZCT";
ms.interleaved = false;
ms.rgb = false;
ms.littleEndian = false;
ms.imageCount = getSizeZ() * getSizeC() * getSizeT();
ms.indexed = false;
ms.falseColor = false;
ms.metadataComplete = true;
}
use of ome.units.quantity.Time in project bioformats by openmicroscopy.
the class BaseTiffReader method initMetadataStore.
/**
* Populates the metadata store using the data parsed in
* {@link #initStandardMetadata()} along with some further parsing done in
* the method itself.
*
* All calls to the active <code>MetadataStore</code> should be made in this
* method and <b>only</b> in this method. This is especially important for
* sub-classes that override the getters for pixel set array size, etc.
*/
protected void initMetadataStore() throws FormatException {
LOGGER.info("Populating OME metadata");
// the metadata store we're working with
MetadataStore store = makeFilterMetadata();
IFD firstIFD = ifds.get(0);
IFD exif = null;
if (ifds.get(0).containsKey(IFD.EXIF)) {
try {
IFDList exifIFDs = tiffParser.getExifIFDs();
if (exifIFDs.size() > 0) {
exif = exifIFDs.get(0);
}
tiffParser.fillInIFD(exif);
} catch (IOException e) {
LOGGER.debug("Could not read EXIF IFDs", e);
}
}
MetadataTools.populatePixels(store, this, exif != null);
// format the creation date to ISO 8601
String creationDate = getImageCreationDate();
String date = DateTools.formatDate(creationDate, DATE_FORMATS, ".");
if (creationDate != null && date == null) {
LOGGER.warn("unknown creation date format: {}", creationDate);
}
creationDate = date;
if (creationDate != null) {
store.setImageAcquisitionDate(new Timestamp(creationDate), 0);
}
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
// populate Experimenter
String artist = firstIFD.getIFDTextValue(IFD.ARTIST);
if (artist != null) {
String firstName = null, lastName = null;
int ndx = artist.indexOf(' ');
if (ndx < 0)
lastName = artist;
else {
firstName = artist.substring(0, ndx);
lastName = artist.substring(ndx + 1);
}
String email = firstIFD.getIFDStringValue(IFD.HOST_COMPUTER);
store.setExperimenterFirstName(firstName, 0);
store.setExperimenterLastName(lastName, 0);
store.setExperimenterEmail(email, 0);
store.setExperimenterID(MetadataTools.createLSID("Experimenter", 0), 0);
}
store.setImageDescription(firstIFD.getComment(), 0);
// set the X and Y pixel dimensions
double pixX = firstIFD.getXResolution();
double pixY = firstIFD.getYResolution();
String unit = getResolutionUnitFromComment(firstIFD);
Length sizeX = FormatTools.getPhysicalSizeX(pixX, unit);
Length sizeY = FormatTools.getPhysicalSizeY(pixY, unit);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
store.setPixelsPhysicalSizeZ(null, 0);
if (exif != null) {
if (exif.containsKey(IFD.EXPOSURE_TIME)) {
Object exp = exif.get(IFD.EXPOSURE_TIME);
if (exp instanceof TiffRational) {
Time exposure = new Time(((TiffRational) exp).doubleValue(), UNITS.SECOND);
for (int i = 0; i < getImageCount(); i++) {
store.setPlaneExposureTime(exposure, 0, i);
}
}
}
}
}
}
use of ome.units.quantity.Time 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);
}
}
}
}
Aggregations