package gdsc.smlm.ij.plugins; import gdsc.core.ij.Utils; import gdsc.core.utils.TextUtils; import gdsc.smlm.ij.settings.FilterSettings; import gdsc.smlm.ij.settings.GlobalSettings; import gdsc.smlm.ij.settings.SettingsManager; import gdsc.smlm.results.MemoryPeakResults; import gdsc.smlm.results.filter.ANRFilter; import gdsc.smlm.results.filter.ANRFilter2; import gdsc.smlm.results.filter.AndFilter; import gdsc.smlm.results.filter.CoordinateFilter; import gdsc.smlm.results.filter.EShiftFilter; import gdsc.smlm.results.filter.Filter; import gdsc.smlm.results.filter.MultiFilter; import gdsc.smlm.results.filter.MultiFilter2; import gdsc.smlm.results.filter.MultiHysteresisFilter; import gdsc.smlm.results.filter.MultiHysteresisFilter2; import gdsc.smlm.results.filter.OrFilter; import gdsc.smlm.results.filter.PrecisionFilter; import gdsc.smlm.results.filter.PrecisionFilter2; import gdsc.smlm.results.filter.PrecisionHysteresisFilter; import gdsc.smlm.results.filter.SBRFilter; import gdsc.smlm.results.filter.SNRFilter; import gdsc.smlm.results.filter.SNRFilter2; import gdsc.smlm.results.filter.SNRHysteresisFilter; import gdsc.smlm.results.filter.ShiftFilter; import gdsc.smlm.results.filter.SignalFilter; import gdsc.smlm.results.filter.TraceFilter; import gdsc.smlm.results.filter.WidthFilter; import gdsc.smlm.results.filter.WidthFilter2; import gdsc.smlm.utils.XmlUtils; import ij.IJ; import ij.gui.GenericDialog; import ij.plugin.PlugIn; import java.awt.Checkbox; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; /*----------------------------------------------------------------------------- * GDSC SMLM Software * * Copyright (C) 2013 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 3 of the License, or * (at your option) any later version. *---------------------------------------------------------------------------*/ import gdsc.smlm.ij.plugins.ResultsManager.InputSource; /** * Filters PeakFit results that are stored in memory using the configured filters. */ public class FreeFilterResults implements PlugIn, ItemListener { private static final String TITLE = "Free Filter Results"; private static String inputOption = ""; private FilterSettings filterSettings; private MemoryPeakResults results; /* * (non-) * * @see ij.plugin.PlugIn#run(java.lang.String) */ public void run(String arg) { SMLMUsageTracker.recordPlugin(this.getClass(), arg); if (MemoryPeakResults.isMemoryEmpty()) { // Ask user if they want to show the demo filters GenericDialog gd = new GenericDialog(TITLE); gd.enableYesNoCancel(); gd.hideCancelButton(); gd.addMessage("No results in memory. Show the demo filters?"); gd.showDialog(); if (gd.wasOKed()) logDemoFilters(TITLE); return; } if (!showDialog()) return; results = ResultsManager.loadInputResults(inputOption, false); if (results == null || results.size() == 0) { IJ.error(TITLE, "No results could be loaded"); IJ.showStatus(""); return; } // Filter results Filter filter = Filter.fromXML(filterSettings.freeFilter); if (filter != null) { MemoryPeakResults newResults = filter.filter(results); if (newResults.size() > 0) { newResults.setName(results.getName() + " Free Filtered"); MemoryPeakResults.addResults(newResults); } IJ.showStatus(String.format("Filtered %d results to %d", results.size(), newResults.size())); } else { IJ.showStatus("ERROR: Unable to create filter"); } } private boolean showDialog() { GenericDialog gd = new GenericDialog(TITLE); gd.addHelp(About.HELP_URL); gd.addMessage("Select a dataset to filter"); ResultsManager.addInput(gd, inputOption, InputSource.MEMORY); GlobalSettings gs = SettingsManager.loadSettings(); filterSettings = gs.getFilterSettings(); String text; try { text = XmlUtils.prettyPrintXml(filterSettings.freeFilter); } catch (Exception e) { text = filterSettings.freeFilter; } gd.addTextAreas(text, null, 20, 80); gd.addCheckbox("Show_demo_filters", false); if (Utils.isShowGenericDialog()) { Checkbox cb = (Checkbox) gd.getCheckboxes().get(0); cb.addItemListener(this); } gd.showDialog(); if (gd.wasCanceled()) return false; inputOption = ResultsManager.getInputSource(gd); filterSettings.freeFilter = gd.getNextText(); boolean demoFilters = gd.getNextBoolean(); if (demoFilters) { logDemoFilters(TITLE); return false; } return SettingsManager.saveSettings(gs); } public void itemStateChanged(ItemEvent e) { // When the checkbox is clicked, output the list of available filters to the ImageJ log Checkbox cb = (Checkbox) e.getSource(); if (cb.getState()) { cb.setState(false); logDemoFilters(TITLE); } } public static void logDemoFilters(String title) { comment(title + " example filters"); IJ.log(""); comment("Filters are described using XML"); comment("Multiple filters can be combined using AND/OR filters"); IJ.log(""); comment("Single filters"); IJ.log(""); demo(new WidthFilter(2)); demo(new WidthFilter2(0.7, 2)); demo(new SBRFilter(15)); demo(new ShiftFilter(0.7)); demo(new EShiftFilter(0.8)); demo(new SignalFilter(1000)); demo(new SNRFilter(10)); demo(new SNRFilter2(10, 0.7, 2)); demo(new ANRFilter(11)); demo(new ANRFilter2(11, 0.75, 1.95)); demo(new PrecisionFilter(30)); demo(new PrecisionFilter2(30)); demo(new SNRHysteresisFilter(50, 1, 2, 1, 10, 20)); demo(new PrecisionHysteresisFilter(2, 0, 1, 0, 20, 30)); demo(new TraceFilter(0.5, 1)); demo(new CoordinateFilter(15.5f, 234.5f, 80.99f, 133f)); demo(new MultiFilter(30, 45f, 0.7, 1.5, 0.5, 0.6, 45)); demo(new MultiFilter2(30, 45f, 0.7, 1.5, 0.5, 0.6, 45)); demo(new MultiHysteresisFilter(2, 0, 1, 0, 20, 10, 40f, 20f, 0.8, 0.2, 1.2, 0.4, 0.3, 0.8, 20, 30)); demo(new MultiHysteresisFilter2(2, 0, 2, 1, 20, 10, 40f, 20f, 0.8, 0.2, 1.2, 0.4, 0.3, 0.8, 20, 30)); comment("Combined filters"); IJ.log(""); demo(new AndFilter(new SNRFilter(10), new WidthFilter(2))); demo(new OrFilter(new SNRFilter(10), new PrecisionFilter(30))); demo(new OrFilter(new AndFilter(new SNRFilter(10), new PrecisionFilter(30)), new TraceFilter(0.5, 1))); } private static void demo(Filter filter) { comment(filter.getClass().getSimpleName() + ": " + filter.getDescription()); IJ.log(filter.toXML()); IJ.log(""); } private static void comment(String text) { IJ.log(TextUtils.wrap("<!-- " + text + " -->", 80)); } }