/** * Attempts to import the given file IDs using Bio-Formats, as a single group. Pixels are saved to * the pixels file designated by OMEIS, and an OME-XML metadata block describing the successfully * imported data is dumped to standard output. */ public void importIds(int[] fileIds) throws OmeisException, FormatException, IOException { boolean doLittle = isLittleEndian(); Arrays.sort(fileIds); // set up file path mappings String[] ids = new String[fileIds.length]; for (int i = 0; i < fileIds.length; i++) { Hashtable fileInfo = getFileInfo(fileIds[i]); ids[i] = (String) fileInfo.get("Name"); String path = getLocalFilePath(fileIds[i]); Location.mapId(ids[i], path); } // read file group String id = ids[0]; String path = Location.getMappedId(id); if (DEBUG) log("Reading file '" + id + "' --> " + path); // verify that all given file IDs were grouped by the reader reader.setId(id); String[] used = reader.getUsedFiles(); if (used == null) { throw new FormatException("Invalid file list for " + path); } if (used.length != ids.length) { throw new FormatException( "File list length mismatch for " + path + ": used=" + a2s(used) + "; ids=" + a2s(ids)); } boolean[] done = new boolean[ids.length]; int numLeft = ids.length; for (int i = 0; i < used.length; i++) { for (int j = 0; j < ids.length; j++) { if (done[j]) continue; if (used[i].equals(ids[j])) { done[j] = true; numLeft--; break; } } } if (numLeft > 0) { throw new FormatException("File list does not correspond to ID list for " + path); } int seriesCount = reader.getSeriesCount(); // get DOM and Pixels elements for the file's OME-XML metadata OMENode ome = (OMENode) omexmlMeta.getRoot(); Document omeDoc = ome.getDOMElement().getOwnerDocument(); Vector pix = DOMUtil.findElementList("Pixels", omeDoc); if (pix.size() != seriesCount) { throw new FormatException( "Pixels element count (" + pix.size() + ") does not match series count (" + seriesCount + ") for '" + id + "'"); } if (DEBUG) log(seriesCount + " series detected."); for (int s = 0; s < seriesCount; s++) { reader.setSeries(s); // gather pixels information for this series int sizeX = reader.getSizeX(); int sizeY = reader.getSizeY(); int sizeZ = reader.getSizeZ(); int sizeC = reader.getSizeC(); int sizeT = reader.getSizeT(); int pixelType = reader.getPixelType(); int bytesPerPixel; boolean isSigned, isFloat; switch (pixelType) { case FormatTools.INT8: bytesPerPixel = 1; isSigned = true; isFloat = false; break; case FormatTools.UINT8: bytesPerPixel = 1; isSigned = false; isFloat = false; break; case FormatTools.INT16: bytesPerPixel = 2; isSigned = true; isFloat = false; break; case FormatTools.UINT16: bytesPerPixel = 2; isSigned = false; isFloat = false; break; case FormatTools.INT32: bytesPerPixel = 4; isSigned = true; isFloat = false; break; case FormatTools.UINT32: bytesPerPixel = 4; isSigned = false; isFloat = false; break; case FormatTools.FLOAT: bytesPerPixel = 4; isSigned = true; isFloat = true; break; case FormatTools.DOUBLE: bytesPerPixel = 8; isSigned = true; isFloat = true; break; default: throw new FormatException( "Unknown pixel type for '" + id + "' series #" + s + ": " + pixelType); } boolean little = reader.isLittleEndian(); boolean swap = doLittle != little && bytesPerPixel > 1 && !isFloat; // ask OMEIS to allocate new pixels file int pixelsId = newPixels(sizeX, sizeY, sizeZ, sizeC, sizeT, bytesPerPixel, isSigned, isFloat); String pixelsPath = getLocalPixelsPath(pixelsId); if (DEBUG) { log("Series #" + s + ": id=" + pixelsId + ", path=" + pixelsPath); } // write pixels to file FileOutputStream out = new FileOutputStream(pixelsPath); int imageCount = reader.getImageCount(); if (DEBUG) { log( "Processing " + imageCount + " planes (sizeZ=" + sizeZ + ", sizeC=" + sizeC + ", sizeT=" + sizeT + "): "); } // OMEIS expects XYZCT order -- // interleaved RGB files will be handled a bit more slowly due to this // ordering (ChannelSeparator must read each plane three times), but // caching performed by the OS helps some for (int t = 0; t < sizeT; t++) { for (int c = 0; c < sizeC; c++) { for (int z = 0; z < sizeZ; z++) { int ndx = reader.getIndex(z, c, t); if (DEBUG) { log("Reading plane #" + ndx + ": z=" + z + ", c=" + c + ", t=" + t); } byte[] plane = reader.openBytes(ndx); if (swap) { // swap endianness for (int b = 0; b < plane.length; b += bytesPerPixel) { for (int k = 0; k < bytesPerPixel / 2; k++) { int i1 = b + k; int i2 = b + bytesPerPixel - k - 1; byte b1 = plane[i1]; byte b2 = plane[i2]; plane[i1] = b2; plane[i2] = b1; } } } out.write(plane); } } } out.close(); if (DEBUG) log("[done]"); // tell OMEIS we're done pixelsId = finishPixels(pixelsId); if (DEBUG) log("finishPixels called (new id=" + pixelsId + ")"); // get SHA1 hash for finished pixels String sha1 = getPixelsSHA1(pixelsId); if (DEBUG) log("SHA1=" + sha1); // inject important extra attributes into proper Pixels element Element pixels = (Element) pix.elementAt(s); pixels.setAttribute("FileSHA1", sha1); pixels.setAttribute("ImageServerID", "" + pixelsId); pixels.setAttribute("DimensionOrder", "XYZCT"); // ignored anyway String pType = pixels.getAttribute("PixelType"); if (pType.startsWith("u")) { pixels.setAttribute("PixelType", pType.replace('u', 'U')); } if (DEBUG) log("Pixel attributes injected."); } reader.close(); // accumulate XML into buffer ByteArrayOutputStream xml = new ByteArrayOutputStream(); try { DOMUtil.writeXML(xml, omeDoc); } catch (javax.xml.transform.TransformerException exc) { throw new FormatException(exc); } // output OME-XML to standard output xml.close(); String xmlString = new String(xml.toByteArray()); if (DEBUG) log(xmlString); if (http) printHttpResponseHeader(); System.out.println(xmlString); }
/** Constructs a Filament node with an associated DOM element beneath a given parent. */ public FilamentNode(OMEXMLNode parent, boolean attach) { super(DOMUtil.createChild(parent.getDOMElement(), "Filament", attach)); }
/** Constructs a Projection node with an associated DOM element beneath a given parent. */ public ProjectionNode(OMEXMLNode parent, boolean attach) { super(DOMUtil.createChild(parent.getDOMElement(), "Projection", attach)); }
/** Constructs a EmFilter node with an associated DOM element beneath a given parent. */ public EmFilterNode(OMEXMLNode parent, boolean attach) { super(DOMUtil.createChild(parent.getDOMElement(), "EmFilter", attach)); }
/** Constructs a Thumbnail node with an associated DOM element beneath a given parent. */ public ThumbnailNode(OMEXMLNode parent, boolean attach) { super(DOMUtil.createChild(parent.getDOMElement(), "Thumbnail", attach)); }
/** Constructs a Objective node with an associated DOM element beneath a given parent. */ public ObjectiveNode(OMEXMLNode parent, boolean attach) { super(DOMUtil.createChild(parent.getDOMElement(), "Objective", attach)); }