// // OMEPlugin.java // /* OME Plugins for ImageJ: a collection of ImageJ plugins including the Download from OME and Upload to OME plugins. Copyright (C) 2005-@year@ Melissa Linkert, Philip Huettl and Curtis Rueden. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package loci.plugins.ome; import ij.IJ; import ij.Macro; import ij.Prefs; import ij.gui.GenericDialog; import ij.plugin.PlugIn; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Panel; import java.awt.TextField; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Vector; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JLabel; import loci.common.ReflectException; import loci.formats.FormatException; import loci.formats.FormatTools; import loci.formats.gui.AWTImageTools; import loci.formats.gui.BufferedImageReader; import loci.ome.io.OMECredentials; import loci.ome.io.OMEUtils; import loci.ome.io.OmeroReader; import loci.plugins.util.LibraryChecker; import loci.plugins.util.WindowTools; /** * OMEPlugin is the ImageJ Plugin that allows image import and exports from * OME and OMERO servers. * * <dl><dt><b>Source code:</b></dt> * <dd><a href="http://trac.openmicroscopy.org.uk/ome/browser/bioformats.git/components/ome-plugins/src/loci/plugins/ome/OMEPlugin.java">Trac</a>, * <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/ome-plugins/src/loci/plugins/ome/OMEPlugin.java;hb=HEAD">Gitweb</a></dd></dl> * * @author Philip Huettl pmhuettl at wisc.edu * @author Melissa Linkert melissa at glencoesoftware.com */ public class OMEPlugin implements PlugIn { // -- Fields -- private OMECredentials cred; private static boolean cancelPlugin; private String arg; // -- PlugIn API methods -- /** Executes the plugin. */ public void run(String arg) { if (IJ.debugMode) IJ.log("Downloading from OME or OMERO server"); if (!LibraryChecker.checkJava() || !LibraryChecker.checkImageJ()) return; HashSet missing = new HashSet(); LibraryChecker.checkLibrary(LibraryChecker.Library.BIO_FORMATS, missing); LibraryChecker.checkLibrary(LibraryChecker.Library.OME_JAVA_XML, missing); LibraryChecker.checkLibrary(LibraryChecker.Library.OME_JAVA_DS, missing); LibraryChecker.checkLibrary(LibraryChecker.Library.FORMS, missing); if (!LibraryChecker.checkMissing(missing)) { if (IJ.debugMode) IJ.log("Required libraries are missing, exiting."); return; } this.arg = arg; runPlugin(); } // -- OMEPlugin API methods -- /** * The getInput method prompts and receives user input to determine * the OME login fields and whether the stack is in the time or space domain */ private void getInput() { String server = Prefs.get("downloader.server", ""); String user = Prefs.get("downloader.user", ""); String port = Prefs.get("downloader.port", "1099"); String type = Prefs.get("downloader.type", "OME"); String pass = null; if (arg == null || arg.trim().equals("")) { GenericDialog gd = new GenericDialog("OME Login"); server = formatServerName(server); gd.addChoice("Server_type: ", new String[] {"OME", "OMERO"}, type); gd.addStringField("Server: ", server, 30); gd.addStringField("Port: ", port, 30); gd.addStringField("Username: ", user, 30); gd.addStringField("Password: ", "", 30); // star out the password field Vector v = gd.getStringFields(); ((TextField) v.get(3)).setEchoChar('*'); gd.showDialog(); if (gd.wasCanceled()) { cancelPlugin = true; return; } type = gd.getNextChoice(); server = gd.getNextString(); port = gd.getNextString(); user = gd.getNextString(); pass = gd.getNextString(); } else { server = Macro.getValue(arg, "server", server); user = Macro.getValue(arg, "username", user); port = Macro.getValue(arg, "port", port); type = Macro.getValue(arg, "server_type", type); pass = Macro.getValue(arg, "password", ""); } // do sanity check on server name if (type.equals("OME")) { server = "http://" + formatServerName(server) + "/shoola/"; } cred = new OMECredentials(server, user, pass); cred.port = port; cred.isOMERO = type.equals("OMERO"); if (IJ.debugMode) IJ.log("Attempting to log in to " + server + ":" + port); try { OMEUtils.login(cred); } catch (ReflectException e) { IJ.error("Login failed"); e.printStackTrace(); getInput(); } Prefs.set("downloader.server", server); Prefs.set("downloader.user", user); Prefs.set("downloader.port", port); Prefs.set("downloader.type", type); if (IJ.debugMode) IJ.log("Login successful!"); } public static void setPlugin(boolean isCancelled) { cancelPlugin = isCancelled; } /** Logout of OME database */ public void logout() { IJ.showStatus("OME: Logging out..."); IJ.showProgress(.99); OMEUtils.logout(cred.isOMERO); IJ.showStatus("OME: Completed"); if (IJ.debugMode) IJ.log("Logged out."); } // -- Download methods -- /** Does the work for downloading data from OME. */ public void runPlugin() { try { getInput(); if (cancelPlugin) { cancelPlugin = false; return; } // prompt for search criteria if (IJ.debugMode) IJ.log("Prompting for search criteria..."); String name = null, firstName = null, lastName = null, iname = null, created = null, id = null; if (arg == null || arg.trim().equals("")) { GenericDialog searchBox = new GenericDialog("Image search..."); if (!cred.isOMERO) { String[] names = OMEUtils.getAllExperimenters(cred.isOMERO); String[] tmp = names; names = new String[tmp.length + 1]; names[0] = ""; System.arraycopy(tmp, 0, names, 1, tmp.length); searchBox.addChoice("Experimenter: ", names, names[0]); } searchBox.addStringField("Image_name: ", ""); searchBox.addStringField("Creation date (yyyy-mm-dd): ", ""); searchBox.addStringField("Image_ID: ", ""); searchBox.showDialog(); if (searchBox.wasCanceled()) { if (IJ.debugMode) IJ.log("Search cancelled, returning."); cancelPlugin = true; return; } name = cred.isOMERO ? null : searchBox.getNextChoice(); iname = searchBox.getNextString(); created = searchBox.getNextString(); id = searchBox.getNextString(); } else { name = Macro.getValue(arg, "owner_name", ""); iname = Macro.getValue(arg, "image_name", ""); created = Macro.getValue(arg, "creation", ""); id = Macro.getValue(arg, "image_id", ""); } if (name != null && name.indexOf(",") != -1) { lastName = name.substring(0, name.indexOf(",")).trim(); firstName = name.substring(name.indexOf(",") + 2).trim(); } if (firstName != null && firstName.trim().equals("")) firstName = null; if (lastName != null && lastName.trim().equals("")) lastName = null; if (iname != null && iname.trim().equals("")) iname = null; if (created != null && created.trim().equals("")) created = null; if (id != null && id.trim().equals("")) id = null; if (IJ.debugMode) IJ.log("Search for matching images..."); // filter images based on search terms OMEUtils.filterPixels(firstName, lastName, iname, created, id, cred.isOMERO); // retrieve image selection(s) long[] images = null; if (arg == null || arg.trim().equals("")) { if (IJ.debugMode) IJ.log("Found images..."); images = showTable(cred); } if (images == null || images.length == 0) { if (IJ.debugMode) IJ.log("No images found!"); logout(); return; } // download into ImageJ for (int i=0; i<images.length; i++) { if (IJ.debugMode) IJ.log("Downloading image ID " + images[i]); String type = cred.isOMERO ? "OMERO server" : "OME server"; String file = "location=[" + type + "] open=[" + cred.server + (cred.isOMERO ? ":" + cred.port : "") + "?user=" + cred.username + "&password=" + cred.password + "&id=" + images[i] + "] " + arg; IJ.runPlugIn("loci.plugins.LociImporter", file); if (cancelPlugin) return; } logout(); } catch (NullPointerException e) { e.printStackTrace(); } catch (IllegalArgumentException f) { // do nothing; this means that the user cancelled the login procedure f.printStackTrace(); } catch (Exception exc) { IJ.setColumnHeadings("Errors"); IJ.write("An exception has occurred: \n" + exc.toString()); IJ.showStatus("Error uploading (see error console for details)"); exc.printStackTrace(); } IJ.showProgress(1); } // -- Helper methods -- private static String formatServerName(String server) { String rtn = server; if (rtn.startsWith("http:")) rtn = rtn.substring(5); while (rtn.startsWith("/")) rtn = rtn.substring(1); int slash = rtn.indexOf("/"); if (slash >= 0) rtn = rtn.substring(0, slash); int colon = rtn.indexOf(":"); if (colon >= 0) rtn = rtn.substring(0, colon); return rtn; } private long[] showTable(OMECredentials cred) throws ReflectException { long[] ids = OMEUtils.getAllIDs(cred.isOMERO); int[] x = OMEUtils.getAllWidths(cred.isOMERO); int[] y = OMEUtils.getAllHeights(cred.isOMERO); int[] z = OMEUtils.getAllZs(cred.isOMERO); int[] c = OMEUtils.getAllChannels(cred.isOMERO); int[] t = OMEUtils.getAllTs(cred.isOMERO); String[] types = OMEUtils.getAllTypes(cred.isOMERO); String[] names = OMEUtils.getAllNames(cred.isOMERO); String[] descr = OMEUtils.getAllDescriptions(cred.isOMERO); String[] created = OMEUtils.getAllDates(cred.isOMERO); BufferedImage[] thumbs = OMEUtils.getAllThumbnails(cred.isOMERO); if (ids.length == 0) { IJ.error("No images found!"); return ids; } GenericDialog gd = new GenericDialog("OME/OMERO Plugin"); GridBagLayout gdl = (GridBagLayout) gd.getLayout(); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; Panel[] p = new Panel[ids.length]; String[] tips = new String[ids.length]; for (int i=0; i<ids.length; i++) { if (names[i] == null) names[i] = ""; StringBuffer tip = new StringBuffer(); tip.append("<HTML>Name: "); tip.append(names[i]); tip.append("<BR>ID: "); tip.append(ids[i]); tip.append("<BR>Date Created: "); tip.append(created[i]); tip.append("<BR>Pixel type: "); tip.append(types[i]); tip.append("<BR>SizeX: "); tip.append(x[i]); tip.append("<BR>SizeY: "); tip.append(y[i]); tip.append("<BR>SizeZ: "); tip.append(z[i]); tip.append("<BR>SizeC: "); tip.append(c[i]); tip.append("<BR>SizeT: "); tip.append(t[i]); tip.append("<BR>Description: "); tip.append(descr[i]); tip.append("</HTML>"); tips[i] = tip.toString(); if (names[i].indexOf(File.separator) != -1) { names[i] = names[i].substring(names[i].lastIndexOf(File.separator) + 1); } gd.addCheckbox(names[i] + " (" + ids[i] + ")", false); p[i] = new Panel(); if (cred.isOMERO) { p[i].add(Box.createRigidArea(new Dimension(128, 128))); gbc.gridy = i; } else { gbc.gridy = i; if (thumbs[i] == null) { thumbs[i] = AWTImageTools.blankImage(64, 64, 1, FormatTools.UINT8); } JLabel label = new JLabel(new ImageIcon(thumbs[i])); label.setToolTipText(tips[i]); p[i].add(label); } gdl.setConstraints(p[i], gbc); gd.add(p[i]); } WindowTools.addScrollBars(gd); if (cred.isOMERO) { OMEROLoader l = new OMEROLoader(ids, cred, p, gd, tips); gd.showDialog(); l.stop(); } else gd.showDialog(); if (gd.wasCanceled()) return null; boolean[] checked = new boolean[ids.length]; int numChecked = 0; for (int i=0; i<ids.length; i++) { checked[i] = gd.getNextBoolean(); if (checked[i]) numChecked++; } long[] results = new long[numChecked]; int n = 0; for (int i=0; i<ids.length; i++) { if (checked[i]) results[n++] = ids[i]; } return results; } // -- Helper class -- class OMEROLoader implements Runnable { private long[] ids; private Panel[] p; private GenericDialog gd; private boolean stop; private Thread loader; private OMECredentials cred; private String[] tips; public OMEROLoader(long[] ids, OMECredentials cred, Panel[] p, GenericDialog gd, String[] tips) { this.ids = ids; this.p = p; this.gd = gd; this.cred = cred; this.tips = tips; loader = new Thread(this, "OMERO-ThumbLoader"); loader.start(); } public void stop() { if (loader == null) return; stop = true; try { loader.join(); loader = null; } catch (InterruptedException exc) { exc.printStackTrace(); } } public void run() { try { OmeroReader r = new OmeroReader(); BufferedImageReader bir = new BufferedImageReader(r); for (int i=0; i<ids.length; i++) { bir.setId("server=" + cred.server + "\nusername=" + cred.username + "\npassword=" + cred.password + "\nport=" + cred.port + "\nid=" + ids[i]); BufferedImage thumb = bir.openThumbImage(0); ImageIcon icon = new ImageIcon(thumb); p[i].removeAll(); JLabel label = new JLabel(icon); label.setToolTipText(tips[i]); p[i].add(label); if (gd != null) gd.validate(); } } catch (FormatException exc) { exc.printStackTrace(); } catch (IOException exc) { exc.printStackTrace(); } } } }