package gdsc.foci.controller; /*----------------------------------------------------------------------------- * GDSC Plugins for ImageJ * * Copyright (C) 2011 Alex Herbert * Genome Damage and Stability Centre * University of Sussex, UK * * 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. *---------------------------------------------------------------------------*/ import gdsc.foci.FindFoci; import gdsc.foci.FindFociResult; import gdsc.foci.FindFociResults; import gdsc.foci.model.FindFociModel; import ij.ImagePlus; import ij.ImageStack; import ij.WindowManager; import ij.gui.GenericDialog; import ij.process.ImageProcessor; import java.util.ArrayList; import java.util.List; /** * Allows ImageJ to run the {@link gdsc.foci.FindFoci } algorithm and return the results. */ public class FindMaximaController extends ImageJController { private ArrayList<FindFociResult> resultsArray = new ArrayList<FindFociResult>(); private ImageStack activeImageStack = null; private int activeChannel = 1; private int activeFrame = 1; public FindMaximaController(FindFociModel model) { super(model); } /* * Allow N-Dimensional images. The controller can detect this and prompt the user for the desired channel and frame * for analysis. * * @see gdsc.foci.controller.ImageJController#updateImageList() */ @Override public void updateImageList() { int noOfImages = WindowManager.getImageCount(); List<String> imageList = new ArrayList<String>(noOfImages); for (int id : gdsc.core.ij.Utils.getIDList()) { ImagePlus imp = WindowManager.getImage(id); // Image must be 8-bit/16-bit/32-bit if (imp != null && (imp.getType() == ImagePlus.GRAY8 || imp.getType() == ImagePlus.GRAY16 || imp.getType() == ImagePlus.GRAY32)) { // Check it is not one the result images String imageTitle = imp.getTitle(); if (!imageTitle.endsWith(FindFoci.TITLE)) { imageList.add(imageTitle); } } } model.setImageList(imageList); // Get the selected image String title = model.getSelectedImage(); ImagePlus imp = WindowManager.getImage(title); model.setMaskImageList(FindFoci.buildMaskList(imp)); } /* * Allow N-dimensional images. Prompt for the channel and frame. * * @see gdsc.foci.controller.FindFociController#run() */ @Override public void run() { resultsArray = new ArrayList<FindFociResult>(); // Get the selected image String title = model.getSelectedImage(); ImagePlus imp = WindowManager.getImage(title); if (null == imp) { return; } if (!FindFoci.isSupported(imp.getBitDepth())) { return; } // Allow N-dimensional images. Prompt for the channel and frame. if (imp.getNChannels() != 1 || imp.getNFrames() != 1) { GenericDialog gd = new GenericDialog("Select Channel/Frame"); gd.addMessage("Stack detected.\nPlease select the channel/frame."); String[] channels = getChannels(imp); String[] frames = getFrames(imp); if (channels.length > 1) gd.addChoice("Channel", channels, channels[channels.length >= activeChannel ? activeChannel - 1 : 0]); if (frames.length > 1) gd.addChoice("Frame", frames, frames[frames.length >= activeFrame ? activeFrame - 1 : 0]); gd.showDialog(); if (gd.wasCanceled()) return; // Extract the channel/frame activeChannel = (channels.length > 1) ? gd.getNextChoiceIndex() + 1 : 1; activeFrame = (frames.length > 1) ? gd.getNextChoiceIndex() + 1 : 1; activeImageStack = extractImage(imp, activeChannel, activeFrame); imp = new ImagePlus("", activeImageStack); } else { activeImageStack = imp.getStack(); } // Set-up the FindFoci variables String maskImage = model.getMaskImage(); int backgroundMethod = model.getBackgroundMethod(); double backgroundParameter = model.getBackgroundParameter(); String thresholdMethod = model.getThresholdMethod(); String statisticsMode = model.getStatisticsMode(); int searchMethod = model.getSearchMethod(); double searchParameter = model.getSearchParameter(); int minSize = model.getMinSize(); boolean minimumAboveSaddle = model.isMinimumAboveSaddle(); boolean connectedAboveSaddle = model.isConnectedAboveSaddle(); int peakMethod = model.getPeakMethod(); double peakParameter = model.getPeakParameter(); int sortMethod = model.getSortMethod(); int maxPeaks = model.getMaxPeaks(); int showMask = model.getShowMask(); boolean overlayMask = model.isOverlayMask(); boolean showTable = model.isShowTable(); boolean clearTable = model.isClearTable(); boolean markMaxima = model.isMarkMaxima(); boolean markROIMaxima = model.isMarkROIMaxima(); boolean markUsingOverlay = model.isMarkUsingOverlay(); boolean hideLabels = model.isHideLabels(); boolean showLogMessages = model.isShowLogMessages(); double gaussianBlur = model.getGaussianBlur(); int centreMethod = model.getCentreMethod(); double centreParameter = model.getCentreParameter(); double fractionParameter = model.getFractionParameter(); int outputType = FindFoci.getOutputMaskFlags(showMask); if (overlayMask) outputType += FindFoci.OUTPUT_OVERLAY_MASK; if (showTable) outputType += FindFoci.OUTPUT_RESULTS_TABLE; if (clearTable) outputType += FindFoci.OUTPUT_CLEAR_RESULTS_TABLE; if (markMaxima) outputType += FindFoci.OUTPUT_ROI_SELECTION; if (markROIMaxima) outputType += FindFoci.OUTPUT_MASK_ROI_SELECTION; if (markUsingOverlay) outputType += FindFoci.OUTPUT_ROI_USING_OVERLAY; if (hideLabels) outputType += FindFoci.OUTPUT_HIDE_LABELS; if (showLogMessages) outputType += FindFoci.OUTPUT_LOG_MESSAGES; int options = 0; if (minimumAboveSaddle) options |= FindFoci.OPTION_MINIMUM_ABOVE_SADDLE; if (connectedAboveSaddle) options |= FindFoci.OPTION_CONTIGUOUS_ABOVE_SADDLE; if (statisticsMode.equalsIgnoreCase("inside")) options |= FindFoci.OPTION_STATS_INSIDE; else if (statisticsMode.equalsIgnoreCase("outside")) options |= FindFoci.OPTION_STATS_OUTSIDE; if (outputType == 0) { return; } model.setUnchanged(); ImagePlus mask = WindowManager.getImage(maskImage); FindFoci ff = new FindFoci(); FindFociResults results = ff.findMaxima(imp, mask, backgroundMethod, backgroundParameter, thresholdMethod, searchMethod, searchParameter, maxPeaks, minSize, peakMethod, peakParameter, outputType, sortMethod, options, gaussianBlur, centreMethod, centreParameter, fractionParameter); if (results != null) { ArrayList<FindFociResult> newResultsArray = results.results; if (newResultsArray != null) resultsArray = newResultsArray; } } private String[] getChannels(ImagePlus imp) { int c = imp.getNChannels(); String[] result = new String[c]; for (int i = 0; i < c; i++) result[i] = Integer.toString(i + 1); return result; } private String[] getFrames(ImagePlus imp) { int c = imp.getNFrames(); String[] result = new String[c]; for (int i = 0; i < c; i++) result[i] = Integer.toString(i + 1); return result; } private ImageStack extractImage(ImagePlus imp, int channel, int frame) { int slices = imp.getNSlices(); ImageStack stack = new ImageStack(imp.getWidth(), imp.getHeight()); ImageStack inputStack = imp.getImageStack(); for (int slice = 1; slice <= slices; slice++) { // Convert to a short processor ImageProcessor ip = inputStack.getProcessor(imp.getStackIndex(channel, slice, frame)); stack.addSlice(null, ip); } return stack; } /* * (non-Javadoc) * * @see gdsc.foci.controller.FindFociController#run() */ @Override public void preview() { // Do nothing } /* * (non-Javadoc) * * @see gdsc.foci.controller.FindFociController#endPreview() */ public void endPreview() { // Do nothing } /** * @return the resultsArray */ public ArrayList<FindFociResult> getResultsArray() { return resultsArray; } /** * Gets the active image stack used within the find foci algorithm. This will be the sub-image stack if an * N-dimensional image was processed. * * @return The active image stack */ public ImageStack getActiveImageStack() { return activeImageStack; } /** * @return the activeChannel */ public int getActiveChannel() { return activeChannel; } /** * @return the activeFrame */ public int getActiveFrame() { return activeFrame; } }