Search in sources :

Example 1 with ExtendedGenericDialog

use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.

the class CreateData method showLoadDialog.

/**
 * Show a dialog allowing the parameters for a benchmark simulation to be loaded.
 *
 * @return True if the parameters were collected
 */
private static boolean showLoadDialog() {
    final String[] images = ImageJUtils.getImageList(ImageJUtils.GREY_SCALE);
    if (images.length == 0) {
        IJ.error(TITLE, "No greyscale benchmark images");
        return false;
    }
    final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    gd.addChoice("Image", images, benchmarkImage);
    gd.addFilenameField("Results_file", benchmarkFile);
    gd.addMessage(TextUtils.wrap("Specify if the results are preprocessed. This is true only if the simulation was " + "previously loaded and then saved to a GDSC SMLM file format from memory. Set to " + "false to load using a universal results loader.", 80));
    gd.addCheckbox("Preprocessed_results", benchmarkAuto);
    gd.addHelp(HelpUrls.getUrl("load-benchmark-data"));
    gd.showDialog();
    if (gd.wasCanceled()) {
        return false;
    }
    benchmarkImage = gd.getNextChoice();
    benchmarkFile = gd.getNextString();
    benchmarkAuto = gd.getNextBoolean();
    Prefs.set(KEY_BENCHMARK_IMAGE, benchmarkImage);
    Prefs.set(KEY_BENCHMARK_RESULTS_FILE, benchmarkFile);
    return true;
}
Also used : ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)

Example 2 with ExtendedGenericDialog

use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.

the class BenchmarkSpotFit method showDialog.

private boolean showDialog() {
    ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    gd.addHelp(HelpUrls.getUrl("fit-spot-data"));
    ImageJUtils.addMessage(gd, "Fit candidate spots in the benchmark image created by " + CreateData.TITLE + " plugin\nand identified by the " + BenchmarkSpotFilter.TITLE + " plugin.\nPSF width = %s nm (Square pixel adjustment = %s nm)\n \n" + "Configure the fitting:", MathUtils.rounded(simulationParameters.sd), MathUtils.rounded(getSa()));
    gd.addSlider("Fraction_positives", 50, 100, settings.fractionPositives);
    gd.addSlider("Fraction_negatives_after_positives", 0, 100, settings.fractionNegativesAfterAllPositives);
    gd.addSlider("Min_negatives_after_positives", 0, 30, settings.negativesAfterAllPositives);
    gd.addSlider("Match_distance", 0.5, 3.5, settings.distance);
    gd.addSlider("Lower_distance", 0, 3.5, settings.lowerDistance);
    gd.addSlider("Match_signal", 0, 3.5, settings.signalFactor);
    gd.addSlider("Lower_signal", 0, 3.5, settings.lowerSignalFactor);
    final FitEngineConfigurationProvider fitEngineConfigurationProvider = new PeakFit.SimpleFitEngineConfigurationProvider(config);
    // Collect options for fitting
    final double sa = getSa();
    final FitConfiguration fitConfig = config.getFitConfiguration();
    fitConfig.setInitialPeakStdDev(MathUtils.round(sa / simulationParameters.pixelPitch));
    PeakFit.addPsfOptions(gd, fitConfig);
    PeakFit.addFittingOptions(gd, fitEngineConfigurationProvider);
    gd.addChoice("Fit_solver", SettingsManager.getFitSolverNames(), FitProtosHelper.getName(fitConfig.getFitSolver()));
    gd.addMessage("Multi-path filter (used to pick optimum results during fitting)");
    // Allow loading the best filter for these results
    final boolean benchmarkSettingsCheckbox = BenchmarkSpotFitResult.fitResultsId.get() == BenchmarkFilterAnalysis.getLastFittingId();
    Checkbox cbBenchmark = null;
    if (benchmarkSettingsCheckbox) {
        // This should always be an opt-in decision. Otherwise the user cannot use the previous
        // settings.
        cbBenchmark = gd.addAndGetCheckbox("Benchmark_settings", false);
    }
    gd.addTextAreas(XmlUtils.convertQuotes(multiFilter.toXml()), null, 6, 60);
    textFailLimit = gd.addAndGetNumericField("Fail_limit", config.getFailuresLimit(), 0);
    cbIncludeNeighbours = gd.addAndGetCheckbox("Include_neighbours", config.isIncludeNeighbours());
    gd.addAndGetSlider("Neighbour_height", 0.01, 1, config.getNeighbourHeightThreshold());
    textNeighbourHeight = gd.getLastTextField();
    cbComputeDoublets = gd.addAndGetCheckbox("Compute_doublets", settings.computeDoublets);
    PeakFit.addDuplicateDistanceOptions(gd, fitEngineConfigurationProvider);
    gd.addCheckbox("Show_score_histograms", settings.showFilterScoreHistograms);
    gd.addCheckbox("Show_correlation", settings.showCorrelation);
    gd.addCheckbox("Plot_rank_by_intensity", settings.rankByIntensity);
    gd.addCheckbox("Save_filter_range", settings.saveFilterRange);
    if (extraOptions) {
    // No extra options
    }
    // Add a mouse listener to the config file field
    if (cbBenchmark != null && ImageJUtils.isShowGenericDialog()) {
        taFilterXml = gd.getTextArea1();
        cbBenchmark.addItemListener(this);
    }
    gd.showDialog();
    if (gd.wasCanceled()) {
        return false;
    }
    settings.fractionPositives = Math.abs(gd.getNextNumber());
    settings.fractionNegativesAfterAllPositives = Math.abs(gd.getNextNumber());
    settings.negativesAfterAllPositives = (int) Math.abs(gd.getNextNumber());
    settings.distance = Math.abs(gd.getNextNumber());
    settings.lowerDistance = Math.abs(gd.getNextNumber());
    settings.signalFactor = Math.abs(gd.getNextNumber());
    settings.lowerSignalFactor = Math.abs(gd.getNextNumber());
    fitConfig.setPsfType(PeakFit.getPsfTypeValues()[gd.getNextChoiceIndex()]);
    config.setFitting(gd.getNextNumber());
    // Some enum values are not supported
    fitConfig.setFitSolver(SettingsManager.getFitSolverValues()[gd.getNextChoiceIndex()]);
    boolean myUseBenchmarkSettings = false;
    if (benchmarkSettingsCheckbox) {
        // useBenchmarkSettings =
        myUseBenchmarkSettings = gd.getNextBoolean();
    }
    // Read dialog settings
    final String xml = gd.getNextText();
    final int failLimit = (int) gd.getNextNumber();
    final boolean includeNeighbours = gd.getNextBoolean();
    final double neighbourHeightThreshold = gd.getNextNumber();
    final boolean myComputeDoublets = gd.getNextBoolean();
    final double myDuplicateDistance = gd.getNextNumber();
    gd.collectOptions();
    MultiPathFilter myMultiFilter = null;
    if (myUseBenchmarkSettings && !ImageJUtils.isShowGenericDialog()) {
        // Only copy the benchmark settings if not interactive
        final FitEngineConfiguration tmp = new FitEngineConfiguration();
        final FitConfiguration tmpFitConfig = tmp.getFitConfiguration();
        // Collect the residuals threshold
        tmpFitConfig.setComputeResiduals(true);
        if (BenchmarkFilterAnalysis.updateConfiguration(tmp, false)) {
            config.setFailuresLimit(tmp.getFailuresLimit());
            config.setIncludeNeighbours(tmp.isIncludeNeighbours());
            config.setNeighbourHeightThreshold(tmp.getNeighbourHeightThreshold());
            settings.computeDoublets = (tmp.getResidualsThreshold() < 1);
            config.setDuplicateDistance(tmp.getDuplicateDistance());
            config.setDuplicateDistanceAbsolute(tmp.getDuplicateDistanceAbsolute());
            final DirectFilter primaryFilter = tmpFitConfig.getSmartFilter();
            final double residualsThreshold = tmp.getResidualsThreshold();
            myMultiFilter = new MultiPathFilter(primaryFilter, FitWorker.createMinimalFilter(tmpFitConfig.getFilterPrecisionMethod()), residualsThreshold);
        }
    } else {
        myMultiFilter = MultiPathFilter.fromXml(xml);
        config.setFailuresLimit(failLimit);
        config.setIncludeNeighbours(includeNeighbours);
        config.setNeighbourHeightThreshold(neighbourHeightThreshold);
        settings.computeDoublets = myComputeDoublets;
        config.setDuplicateDistance(myDuplicateDistance);
    }
    if (myMultiFilter == null) {
        gd = new ExtendedGenericDialog(TITLE);
        gd.addMessage("The multi-path filter was invalid.\n \nContinue with a default filter?");
        gd.enableYesNoCancel();
        gd.hideCancelButton();
        gd.showDialog();
        if (!gd.wasOKed()) {
            return false;
        }
    } else {
        multiFilter = myMultiFilter;
    }
    if (settings.computeDoublets) {
        config.setResidualsThreshold(0);
        fitConfig.setComputeResiduals(true);
    } else {
        config.setResidualsThreshold(1);
        fitConfig.setComputeResiduals(false);
    }
    settings.showFilterScoreHistograms = gd.getNextBoolean();
    settings.showCorrelation = gd.getNextBoolean();
    settings.rankByIntensity = gd.getNextBoolean();
    settings.saveFilterRange = gd.getNextBoolean();
    // Avoid stupidness, i.e. things that move outside the fit window and are bad widths
    // TODO - Fix this for simple or smart filter...
    fitConfig.setDisableSimpleFilter(false);
    // Realistically we cannot fit lower than this
    fitConfig.setMinPhotons(15);
    // Disable shift as candidates may be re-mapped to alternative candidates so the initial
    // position is wrong.
    fitConfig.setCoordinateShiftFactor(0);
    fitConfig.setMinWidthFactor(1.0 / 5);
    fitConfig.setMaxWidthFactor(5);
    // Disable the direct filter
    fitConfig.setDirectFilter(null);
    if (extraOptions) {
    // No extra options
    }
    if (gd.invalidNumber()) {
        return false;
    }
    if (settings.lowerDistance > settings.distance) {
        settings.lowerDistance = settings.distance;
    }
    if (settings.lowerSignalFactor > settings.signalFactor) {
        settings.lowerSignalFactor = settings.signalFactor;
    }
    // Distances relative to sa (not s) as this is the same as the BenchmarkSpotFilter plugin
    distanceInPixels = settings.distance * sa / simulationParameters.pixelPitch;
    lowerDistanceInPixels = settings.lowerDistance * sa / simulationParameters.pixelPitch;
    // Copy simulation defaults if a new simulation.
    // if (lastSimulationId.get() != simulationParameters.id) {
    // This is needed to configure the fit solver.
    fitConfig.setNmPerPixel(simulationParameters.pixelPitch);
    fitConfig.setGain(simulationParameters.gain);
    fitConfig.setQuantumEfficiency(simulationParameters.qe);
    fitConfig.setReadNoise(simulationParameters.readNoise);
    fitConfig.setBias(simulationParameters.bias);
    fitConfig.setCameraType(simulationParameters.cameraType);
    fitConfig.setCameraModel(CreateData.getCameraModel(simulationParameters));
    // }
    if (!PeakFit.configurePsfModel(config)) {
        return false;
    }
    return PeakFit.configureFitSolver(config, IJImageSource.getBounds(imp), null, (extraOptions) ? PeakFit.FLAG_EXTRA_OPTIONS : 0);
}
Also used : FitEngineConfigurationProvider(uk.ac.sussex.gdsc.smlm.ij.plugins.PeakFit.FitEngineConfigurationProvider) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) Checkbox(java.awt.Checkbox) FitEngineConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) MultiPathFilter(uk.ac.sussex.gdsc.smlm.results.filter.MultiPathFilter) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) BasePoint(uk.ac.sussex.gdsc.core.match.BasePoint)

Example 3 with ExtendedGenericDialog

use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.

the class BenchmarkSpotFilter method showDialog.

private boolean showDialog() {
    final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    settings = Settings.load();
    config = settings.config;
    final StringBuilder sb = new StringBuilder();
    sb.append("Finds spots in the benchmark image created by CreateData plugin.\n");
    final double s = simulationParameters.sd / simulationParameters.pixelPitch;
    final double sa = getSa() / simulationParameters.pixelPitch;
    sb.append("PSF width = ").append(MathUtils.rounded(s)).append(" px (sa = ").append(MathUtils.rounded(sa)).append(" px). HWHM = ").append(MathUtils.rounded(s * Gaussian2DFunction.SD_TO_HWHM_FACTOR)).append(" px\n");
    sb.append("Simulation depth = ").append(MathUtils.rounded(simulationParameters.depth)).append(" nm");
    if (simulationParameters.fixedDepth) {
        sb.append(" (fixed)");
    }
    sb.append("\n \nConfigure the spot filter:");
    gd.addMessage(sb.toString());
    if (batchMode) {
        // Support enumeration of single/difference spot filters
        gd.addCheckbox("Mean", settings.batchMean);
        gd.addCheckbox("Gaussian", settings.batchGaussian);
        gd.addCheckbox("Circular", settings.batchCircular);
        gd.addCheckbox("Median", settings.batchMedian);
        // For difference filters we set the smoothing for the second filter
        // using only one distance
        gd.addMessage("Difference filter settings:");
        gd.addCheckbox("Difference_filter", settings.differenceFilter);
        gd.addSlider("Difference_smoothing", 1.5, 5, settings.differenceSmooth);
        gd.addMessage("Local maxima search settings:");
        gd.addSlider("Min_search_width", 1, 4, settings.minSearch);
        gd.addSlider("Max_search_width", 1, 4, settings.maxSearch);
        gd.addCheckbox("Filter_relative_distances (to HWHM)", settings.filterRelativeDistances);
    } else {
        gd.addChoice("Spot_filter_type", SettingsManager.getDataFilterTypeNames(), config.getDataFilterType().ordinal());
        gd.addChoice("Spot_filter", SettingsManager.getDataFilterMethodNames(), config.getDataFilterMethod(0).ordinal());
        gd.addCheckbox("Filter_relative_distances (to HWHM)", !config.getDataFilterParameterAbsolute(0));
        gd.addSlider("Smoothing", 0, 2.5, config.getDataFilterParameterValue(0));
        gd.addSlider("Search_width", 1, 4, settings.search);
    }
    gd.addSlider("Border", 0, 5, settings.border);
    gd.addMessage("Scoring options:");
    gd.addCheckbox("Score_relative_distances (to HWHM)", settings.scoreRelativeDistances);
    gd.addSlider("Analysis_border", 0, 5, settings.analysisBorder);
    gd.addCheckbox("Hard_border", settings.hardBorder);
    gd.addChoice("Matching_method", Settings.MATCHING_METHOD, settings.matchingMethod);
    gd.addSlider("Match_distance", 0.5, 3.5, settings.upperDistance);
    gd.addSlider("Lower_distance", 0, 3.5, settings.lowerDistance);
    gd.addSlider("Signal_factor", 0, 3.5, settings.upperSignalFactor);
    gd.addSlider("Lower_factor", 0, 3.5, settings.lowerSignalFactor);
    gd.addSlider("Recall_fraction", 50, 100, settings.recallFraction);
    if (!batchMode) {
        gd.addCheckbox("Show_plots", settings.showPlot);
        gd.addCheckbox("Plot_rank_by_intensity", settings.rankByIntensity);
        gd.addCheckbox("Show_failures_plots", settings.showFailuresPlot);
        gd.addCheckbox("Show_TP", settings.showTP);
        gd.addCheckbox("Show_FP", settings.showFP);
        gd.addCheckbox("Show_FN", settings.showFN);
    }
    if (extraOptions) {
        gd.addCheckbox("Debug", settings.debug);
    }
    if (batchMode) {
        gd.addHelp(HelpUrls.getUrl("filter-spot-data-batch"));
    } else {
        gd.addHelp(HelpUrls.getUrl("filter-spot-data"));
    }
    gd.showDialog();
    if (gd.wasCanceled()) {
        return false;
    }
    // Here we use PSF stored in the results if supported (i.e. a Gaussian).
    // The results are likely to come from the CreateData simulation.
    final PSF psf = results.getPsf();
    if (PsfHelper.isGaussian2D(psf)) {
        config.getFitConfiguration().setPsf(results.getPsf());
    } else {
        config.getFitConfiguration().setInitialPeakStdDev(s);
    }
    if (batchMode) {
        settings.batchMean = gd.getNextBoolean();
        settings.batchGaussian = gd.getNextBoolean();
        settings.batchCircular = gd.getNextBoolean();
        settings.batchMedian = gd.getNextBoolean();
        if (!(settings.batchMean || settings.batchGaussian || settings.batchCircular || settings.batchMedian)) {
            return false;
        }
        settings.differenceFilter = gd.getNextBoolean();
        settings.differenceSmooth = gd.getNextNumber();
        settings.minSearch = (int) gd.getNextNumber();
        settings.maxSearch = (int) gd.getNextNumber();
        settings.filterRelativeDistances = gd.getNextBoolean();
    } else {
        config.setDataFilterType(SettingsManager.getDataFilterTypeValues()[gd.getNextChoiceIndex()]);
        final int filterIndex = gd.getNextChoiceIndex();
        settings.filterRelativeDistances = gd.getNextBoolean();
        final double smoothing = Math.abs(gd.getNextNumber());
        config.setDataFilter(SettingsManager.getDataFilterMethodValues()[filterIndex], MathUtils.roundUsingDecimalPlaces(smoothing, 3), !settings.filterRelativeDistances, 0);
        settings.search = gd.getNextNumber();
    }
    settings.border = gd.getNextNumber();
    settings.scoreRelativeDistances = gd.getNextBoolean();
    settings.analysisBorder = Math.abs(gd.getNextNumber());
    settings.hardBorder = gd.getNextBoolean();
    settings.matchingMethod = gd.getNextChoiceIndex();
    settings.upperDistance = Math.abs(gd.getNextNumber());
    settings.lowerDistance = Math.abs(gd.getNextNumber());
    settings.upperSignalFactor = Math.abs(gd.getNextNumber());
    settings.lowerSignalFactor = Math.abs(gd.getNextNumber());
    settings.recallFraction = Math.abs(gd.getNextNumber());
    if (!batchMode) {
        settings.showPlot = gd.getNextBoolean();
        settings.rankByIntensity = gd.getNextBoolean();
        settings.showFailuresPlot = gd.getNextBoolean();
        settings.showTP = gd.getNextBoolean();
        settings.showFP = gd.getNextBoolean();
        settings.showFN = gd.getNextBoolean();
    }
    if (extraOptions) {
        settings.debug = gd.getNextBoolean();
    }
    settings.save();
    if (gd.invalidNumber()) {
        return false;
    }
    if (settings.lowerDistance > settings.upperDistance) {
        settings.lowerDistance = settings.upperDistance;
    }
    if (settings.lowerSignalFactor > settings.upperSignalFactor) {
        settings.lowerSignalFactor = settings.upperSignalFactor;
    }
    // Set border here so that the results are consistent with single-filter mode.
    config.setBorder(MathUtils.roundUsingDecimalPlaces(settings.border, 3), !settings.filterRelativeDistances);
    if (!batchMode) {
        // Single filter ...
        config.setSearch(MathUtils.roundUsingDecimalPlaces(settings.search, 3), !settings.filterRelativeDistances);
        // Allow more complicated filters to be configured
        if (!PeakFit.configureDataFilter(config, PeakFit.FLAG_NO_SAVE)) {
            return false;
        }
    }
    int analysisBorder;
    if (settings.scoreRelativeDistances) {
        // Convert distance to PSF standard deviation units
        final double hwhmMax = config.getHwhmMax();
        matchDistance = settings.upperDistance * hwhmMax;
        lowerMatchDistance = settings.lowerDistance * hwhmMax;
        analysisBorder = (int) (settings.analysisBorder * hwhmMax);
    } else {
        matchDistance = settings.upperDistance;
        lowerMatchDistance = settings.lowerDistance;
        analysisBorder = (int) settings.analysisBorder;
    }
    if (analysisBorder > 0) {
        border = new Rectangle(analysisBorder, analysisBorder, imp.getWidth() - 2 * analysisBorder, imp.getHeight() - 2 * analysisBorder);
    } else {
        border = new Rectangle(imp.getWidth(), imp.getHeight());
    }
    return true;
}
Also used : PSF(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSF) Rectangle(java.awt.Rectangle) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) BasePoint(uk.ac.sussex.gdsc.core.match.BasePoint)

Example 4 with ExtendedGenericDialog

use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.

the class BenchmarkSpotFilter method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    extraOptions = ImageJUtils.isExtraOptions();
    batchMode = "batch".equals(arg);
    simulationParameters = CreateData.getSimulationParameters();
    if (simulationParameters == null) {
        IJ.error(TITLE, "No benchmark spot parameters in memory");
        return;
    }
    imp = CreateData.getImage();
    if (imp == null) {
        IJ.error(TITLE, "No benchmark image");
        return;
    }
    results = CreateData.getResults();
    if (results == null) {
        IJ.error(TITLE, "No benchmark results in memory");
        return;
    }
    // Set-up for the simulation
    try {
        if (results.getCalibration() == null) {
            throw new ConfigurationException("Require calibrated results");
        }
        if (results.getCalibrationReader().getDistanceUnit() != DistanceUnit.PIXEL) {
            throw new ConfigurationException("Require results in pixel distance units");
        }
        if (results.getCalibrationReader().getIntensityUnit() != IntensityUnit.PHOTON) {
            throw new ConfigurationException("Require results in photon units");
        }
        // This plugin is heavily reliant on the results being represented as a
        // Gaussian2D function.
        final int flags = Gaussian2DPeakResultHelper.AMPLITUDE | Gaussian2DPeakResultHelper.PIXEL_AMPLITUDE;
        calculator = Gaussian2DPeakResultHelper.create(results.getPsf(), results.getCalibration(), flags);
        cameraModel = CreateData.getCameraModel(simulationParameters);
    } catch (final ConfigurationException ex) {
        IJ.error(TITLE, "Bad configuration: " + ex.getMessage());
        return;
    }
    if (!showDialog()) {
        return;
    }
    // Get the simulation results into a list per frame
    simulationCoords = getSimulationCoordinates();
    // Clear old results to free memory
    BenchmarkSpotFilterResult localFilterResult;
    filterResult.set(null);
    // For graphs
    windowOrganiser = new WindowOrganiser();
    if (batchMode) {
        // Clear the cached results if the setting changed
        final SettingsList settingList = new SettingsList(simulationParameters.id, settings.filterRelativeDistances, // search, maxSearch, // Ignore search distance for smart caching
        settings.border, settings.scoreRelativeDistances, settings.analysisBorder, settings.hardBorder, settings.matchingMethod, settings.upperDistance, settings.lowerDistance, settings.upperSignalFactor, settings.lowerSignalFactor, settings.recallFraction);
        final ArrayList<BatchResult[]> cachedResults = getCachedBatchResults(settingList);
        // Batch mode to test enumeration of filters
        final double sd = simulationParameters.sd / simulationParameters.pixelPitch;
        final int limit = (int) Math.floor(3 * sd);
        // This should be in integers otherwise we may repeat search box sizes
        final int[] searchParam = SimpleArrayUtils.newArray(settings.maxSearch - settings.minSearch + 1, settings.minSearch, 1);
        // Continuous parameters
        final double[] pEmpty = new double[0];
        final double[] mParam = (settings.batchMean) ? getRange(limit, 0.05) : pEmpty;
        final double[] gParam = (settings.batchGaussian) ? getRange(limit, 0.05) : pEmpty;
        // Less continuous parameters
        final double[] cParam = (settings.batchCircular) ? getRange(limit, 0.5) : pEmpty;
        // Discrete parameters
        final double[] medParam = (settings.batchMedian) ? getRange(limit, 1) : pEmpty;
        setupProgress((long) imp.getImageStackSize() * searchParam.length * (mParam.length + gParam.length + cParam.length + medParam.length), "Frame");
        ArrayList<BatchResult[]> batchResults = new ArrayList<>(cachedResults.size());
        double param2 = 0;
        if (settings.differenceFilter && settings.differenceSmooth > 0) {
            if (settings.filterRelativeDistances) {
                // Convert to absolute for batch run
                param2 = MathUtils.roundUsingDecimalPlaces(settings.differenceSmooth * config.getHwhmMin(), 3);
            } else {
                // Already an absolute value
                param2 = settings.differenceSmooth;
            }
            config.setDataFilterType(DataFilterType.DIFFERENCE);
        } else {
            config.setDataFilterType(DataFilterType.SINGLE);
        }
        for (final int search : searchParam) {
            // Batch runs use absolute distance
            config.setSearch(search, true);
            // Allow re-use of these if they are cached to allow quick reanalysis of results.
            if (settings.batchMean) {
                batchResults.add(getOrCompute(cachedResults, DataFilterMethod.MEAN, mParam, search, param2));
            }
            if (settings.batchGaussian) {
                batchResults.add(getOrCompute(cachedResults, DataFilterMethod.GAUSSIAN, gParam, search, param2));
            }
            if (settings.batchCircular) {
                batchResults.add(getOrCompute(cachedResults, DataFilterMethod.CIRCULAR_MEAN, cParam, search, param2));
            }
            if (settings.batchMean) {
                batchResults.add(getOrCompute(cachedResults, DataFilterMethod.MEDIAN, medParam, search, param2));
            }
        }
        IJ.showProgress(-1);
        IJ.showStatus("");
        if (ImageJUtils.isInterrupted()) {
            return;
        }
        // Save the results in a cache
        setCachedBatchResults(settingList, cachedResults);
        // Analysis options
        final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        final boolean haveCached = cachedResults.size() > batchResults.size();
        if (haveCached) {
            gd.addCheckbox("Use_cached_results", settings.useCached);
        }
        gd.addMessage("Choose performance plots:");
        for (int i = 0; i < settings.batchPlot.length; i++) {
            gd.addCheckbox(Settings.batchPlotNames[i], settings.batchPlot[i]);
        }
        gd.addChoice("Selection", Settings.SELECTION_METHOD, settings.selectionMethod);
        gd.addCheckbox("Show_plots", settings.showPlot);
        gd.addCheckbox("Plot_rank_by_intensity", settings.rankByIntensity);
        gd.addCheckbox("Show_failures_plots", settings.showFailuresPlot);
        gd.addCheckbox("Show_TP", settings.showTP);
        gd.addCheckbox("Show_FP", settings.showFP);
        gd.addCheckbox("Show_FN", settings.showFN);
        gd.addHelp(HelpUrls.getUrl("filter-spot-data-batch"));
        gd.showDialog();
        if (gd.wasCanceled()) {
            return;
        }
        if (haveCached) {
            settings.useCached = gd.getNextBoolean();
            if (settings.useCached) {
                batchResults = cachedResults;
            }
        }
        for (int i = 0; i < settings.batchPlot.length; i++) {
            settings.batchPlot[i] = gd.getNextBoolean();
        }
        settings.selectionMethod = gd.getNextChoiceIndex();
        settings.showPlot = gd.getNextBoolean();
        settings.rankByIntensity = gd.getNextBoolean();
        settings.showFailuresPlot = gd.getNextBoolean();
        settings.showTP = gd.getNextBoolean();
        settings.showFP = gd.getNextBoolean();
        settings.showFN = gd.getNextBoolean();
        // Plot charts
        for (int i = 0; i < settings.batchPlot.length; i++) {
            plot(i, batchResults);
        }
        // Store in global singleton
        localFilterResult = analyse(batchResults);
    } else {
        // Single filter mode
        setupProgress(imp.getImageStackSize(), "Frame");
        localFilterResult = runAnalysis(config);
    }
    ImageJUtils.clearSlowProgress();
    IJ.showStatus("");
    if (localFilterResult == null) {
        return;
    }
    // Store the latest result
    filterResult.set(localFilterResult);
    // Debugging the matches
    if (settings.debug) {
        addSpotsToMemory(localFilterResult.filterResults);
    }
    if (settings.showFailuresPlot) {
        showFailuresPlot(localFilterResult);
    }
    if (settings.showPlot) {
        showPlot(localFilterResult);
    }
    if (isShowOverlay()) {
        showOverlay(imp, localFilterResult);
    }
    windowOrganiser.tile();
}
Also used : SettingsList(uk.ac.sussex.gdsc.core.utils.SettingsList) ConfigurationException(uk.ac.sussex.gdsc.smlm.data.config.ConfigurationException) ArrayList(java.util.ArrayList) WindowOrganiser(uk.ac.sussex.gdsc.core.ij.plugin.WindowOrganiser) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) BasePoint(uk.ac.sussex.gdsc.core.match.BasePoint)

Example 5 with ExtendedGenericDialog

use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.

the class CreateData method showSimulationParametersDialog.

private SimulationParameters showSimulationParametersDialog(ImagePlus imp, MemoryPeakResults results) {
    final int molecules = results.size();
    // Get the missing parameters from the user
    boolean fullSimulation = false;
    double sd = -1;
    if (!results.convertToPreferredUnits()) {
        IJ.error(TITLE, String.format("Results should be in the preferred units (%s,%s)", UnitHelper.getName(MemoryPeakResults.PREFERRED_DISTANCE_UNIT), UnitHelper.getName(MemoryPeakResults.PREFERRED_INTENSITY_UNIT)));
        return null;
    }
    // Get these from the data
    final RawResultProcedure sp = new RawResultProcedure(results);
    sp.getBixyz();
    final float[] signal = sp.intensity;
    float[] limits = MathUtils.limits(signal);
    final double minSignal = limits[0];
    final double maxSignal = limits[1];
    final double signalPerFrame = MathUtils.sum(signal) / molecules;
    final float[] depths = sp.z;
    limits = MathUtils.limits(depths);
    float depth = Math.max(Math.abs(limits[0]), Math.abs(limits[1]));
    final boolean fixedDepth = Double.compare(limits[0], limits[1]) == 0;
    final CalibrationWriter cal = results.getCalibrationWriter();
    final String iUnits = " " + UnitHelper.getName(cal.getIntensityUnit());
    final String zUnits = " " + UnitHelper.getName(cal.getDistanceUnit());
    // Get this from the user
    double background = -1;
    // Use last simulation parameters for missing settings.
    // This is good if we are re-running the plugin to load data.
    Rectangle lastCameraBounds = null;
    if (simulationParameters != null && simulationParameters.isLoaded()) {
        fullSimulation = simulationParameters.fullSimulation;
        sd = simulationParameters.sd;
        background = simulationParameters.background;
        if (!cal.hasBias()) {
            cal.setBias(simulationParameters.bias);
        }
        if (!cal.hasCountPerPhoton()) {
            cal.setCountPerPhoton(simulationParameters.gain);
        }
        if (!cal.hasQuantumEfficiency()) {
            cal.setQuantumEfficiency(simulationParameters.qe);
        }
        if (!cal.hasReadNoise()) {
            cal.setReadNoise(simulationParameters.readNoise);
        }
        if (!cal.hasCameraType()) {
            cal.setCameraType(simulationParameters.cameraType);
        }
        if (!cal.hasNmPerPixel()) {
            cal.setNmPerPixel(simulationParameters.pixelPitch);
        }
        if (!cal.hasCameraModelName()) {
            cal.setCameraModelName(simulationParameters.cameraModelName);
        }
        lastCameraBounds = simulationParameters.cameraBounds;
    }
    // Show a dialog to confirm settings
    final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    final StringBuilder sb = new StringBuilder();
    sb.append("Results contain ").append(TextUtils.pleural(molecules, "molecule")).append('\n');
    sb.append("Min signal = ").append(MathUtils.rounded(minSignal)).append(iUnits).append('\n');
    sb.append("Max signal = ").append(MathUtils.rounded(maxSignal)).append(iUnits).append('\n');
    sb.append("Av signal = ").append(MathUtils.rounded(signalPerFrame)).append(iUnits).append('\n');
    if (fixedDepth) {
        sb.append("Fixed depth = ").append(MathUtils.rounded(depth)).append(zUnits).append('\n');
    }
    gd.addMessage(sb.toString());
    gd.addCheckbox("Flourophore_simulation", fullSimulation);
    gd.addNumericField("Gaussian_SD", sd, 3, 8, "nm");
    gd.addNumericField("Pixel_pitch", cal.getNmPerPixel(), 3, 8, "nm");
    gd.addNumericField("Background", background, 3, 8, "photon");
    // Camera type does not need the full simulation settings. Plus the units are different
    // so just re-implement.
    gd.addChoice("Camera_type", SettingsManager.getCameraTypeNames(), CalibrationProtosHelper.getName(cal.getCameraType()), new OptionListener<Integer>() {

        @Override
        public boolean collectOptions(Integer field) {
            cal.setCameraType(SettingsManager.getCameraTypeValues()[field]);
            return collectOptions(false);
        }

        @Override
        public boolean collectOptions() {
            return collectOptions(true);
        }

        private boolean collectOptions(boolean silent) {
            final CameraType cameraType = cal.getCameraType();
            final boolean isCcd = CalibrationProtosHelper.isCcdCameraType(cameraType);
            final ExtendedGenericDialog egd = new ExtendedGenericDialog(TITLE, null);
            if (isCcd) {
                egd.addNumericField("Total_gain", cal.getCountPerPhoton(), 3, 8, "count/photon");
                egd.addNumericField("Quantum_efficiency", cal.getQuantumEfficiency(), 3, 8, "e-/photon");
                egd.addNumericField("Read_noise", cal.getReadNoise(), 3, 8, "count");
                egd.addNumericField("Bias", cal.getBias(), 3, 8, "count");
            } else if (cameraType == CameraType.SCMOS) {
                final String[] models = CameraModelManager.listCameraModels(true);
                egd.addChoice("Camera_model_name", models, cal.getCameraModelName());
                egd.addNumericField("Quantum_efficiency", cal.getQuantumEfficiency(), 2, 6, "electron/photon");
            } else {
                IJ.error("Unsupported camera type " + CalibrationProtosHelper.getName(cameraType));
                return false;
            }
            egd.setSilent(silent);
            egd.showDialog(true, gd);
            if (egd.wasCanceled()) {
                return false;
            }
            if (isCcd) {
                cal.setCountPerPhoton(egd.getNextNumber());
                cal.setQuantumEfficiency(egd.getNextNumber());
                cal.setReadNoise(egd.getNextNumber());
                cal.setBias(egd.getNextNumber());
            } else if (cameraType == CameraType.SCMOS) {
                cal.setCameraModelName(egd.getNextChoice());
                cal.setQuantumEfficiency(Math.abs(egd.getNextNumber()));
            }
            return true;
        }
    });
    if (!fixedDepth) {
        gd.addNumericField("Depth", depth, 3, 8, "pixel");
    }
    gd.addHelp(HelpUrls.getUrl("load-benchmark-data"));
    gd.showDialog();
    if (gd.wasCanceled()) {
        return null;
    }
    fullSimulation = gd.getNextBoolean();
    sd = gd.getNextNumber();
    cal.setNmPerPixel(gd.getNextNumber());
    background = gd.getNextNumber();
    cal.setCameraType(SettingsManager.getCameraTypeValues()[gd.getNextChoiceIndex()]);
    float myDepth = depth;
    if (!fixedDepth) {
        myDepth = (float) gd.getNextNumber();
        if (myDepth < depth) {
            IJ.error(TITLE, String.format("Input depth is smaller than the depth guessed from the data: %f < %f", myDepth, depth));
            return null;
        }
        depth = myDepth;
    }
    gd.collectOptions();
    // Validate settings
    Rectangle modelBounds = null;
    try {
        ParameterUtils.isAboveZero("Gaussian SD", sd);
        ParameterUtils.isAboveZero("Pixel pitch", cal.getNmPerPixel());
        ParameterUtils.isPositive("Background", background);
        ParameterUtils.isAboveZero("Quantum efficiency", cal.getQuantumEfficiency());
        ParameterUtils.isEqualOrBelow("Quantum efficiency", cal.getQuantumEfficiency(), 1);
        if (cal.isCcdCamera()) {
            ParameterUtils.isAboveZero("Total gain", cal.getCountPerPhoton());
            ParameterUtils.isPositive("Read noise", cal.getReadNoise());
            ParameterUtils.isPositive("Bias", cal.getBias());
        } else if (cal.isScmos()) {
            // Load the model
            cameraModel = CameraModelManager.load(cal.getCameraModelName());
            if (cameraModel == null) {
                IJ.error(TITLE, "Unknown camera model for name: " + cal.getCameraModelName());
                return null;
            }
            int ox = 0;
            int oy = 0;
            if (lastCameraBounds != null) {
                ox = lastCameraBounds.x;
                oy = lastCameraBounds.y;
            }
            cameraModel = PeakFit.cropCameraModel(cameraModel, new Rectangle(ox, oy, imp.getWidth(), imp.getHeight()), null, false);
            modelBounds = cameraModel.getBounds();
            final IJImageSource imageSource = (IJImageSource) results.getSource();
            imageSource.setOrigin(modelBounds.x, modelBounds.y);
            cal.clearGlobalCameraSettings();
        } else {
            IJ.error(TITLE, "Unknown camera type: " + cal.getCameraType());
            return null;
        }
    } catch (final IllegalArgumentException ex) {
        IJ.error(TITLE, ex.getMessage());
        return null;
    }
    // Store calibration
    results.setCalibration(cal.getCalibration());
    final double a = cal.getNmPerPixel();
    final double bias = cal.getBias();
    final double gain = cal.getCountPerPhoton();
    final double readNoise = cal.getReadNoise();
    final double qe = cal.getQuantumEfficiency();
    // Note: The calibration will throw an exception if the converter cannot be created.
    // This is OK as the data will be invalid.
    // Convert +/- depth to total depth in nm
    depth = cal.getDistanceConverter(DistanceUnit.NM).convert(depth * 2);
    // Compute total background variance in photons
    final double backgroundVariance = background;
    // Do not add EM-CCD noise factor. The Mortensen formula also includes this factor
    // so this is "double-counting" the EM-CCD.
    // if (emCCD)
    // backgroundVariance *= 2;
    // Read noise is in ADUs. Convert to Photons to get contribution to background variance
    final double readNoiseInPhotons = readNoise / gain;
    // Get the expected value at each pixel in photons. Assuming a Poisson distribution this
    // is equal to the total variance at the pixel.
    final double b2 = backgroundVariance + readNoiseInPhotons * readNoiseInPhotons;
    // Convert values to photons
    final TypeConverter<IntensityUnit> ic = cal.getIntensityConverter(IntensityUnit.PHOTON);
    final SimulationParameters p = new SimulationParameters(molecules, fullSimulation, sd, a, ic.convert(minSignal), ic.convert(maxSignal), ic.convert(signalPerFrame), depth, fixedDepth, bias, gain, qe, readNoise, cal.getCameraType(), cal.getCameraModelName(), modelBounds, background, b2, createPsf(sd / a));
    p.loaded = true;
    return p;
}
Also used : RawResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.RawResultProcedure) Rectangle(java.awt.Rectangle) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) ReadHint(uk.ac.sussex.gdsc.smlm.results.ImageSource.ReadHint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IJImageSource(uk.ac.sussex.gdsc.smlm.ij.IJImageSource) CalibrationWriter(uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter) IntensityUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.IntensityUnit) CameraType(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.CameraType)

Aggregations

ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)151 NonBlockingExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.NonBlockingExtendedGenericDialog)38 CalibrationWriter (uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter)21 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)14 Checkbox (java.awt.Checkbox)13 ImagePlus (ij.ImagePlus)12 File (java.io.File)11 Rectangle (java.awt.Rectangle)10 TextField (java.awt.TextField)10 ResultsImageSettings (uk.ac.sussex.gdsc.smlm.data.config.ResultsProtos.ResultsImageSettings)10 FitConfiguration (uk.ac.sussex.gdsc.smlm.engine.FitConfiguration)10 Choice (java.awt.Choice)9 ArrayList (java.util.ArrayList)9 DistanceUnit (uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit)9 LocalList (uk.ac.sussex.gdsc.core.utils.LocalList)8 CalibrationReader (uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader)7 ResultsSettings (uk.ac.sussex.gdsc.smlm.data.config.ResultsProtos.ResultsSettings)7 ResultsTableSettings (uk.ac.sussex.gdsc.smlm.data.config.ResultsProtos.ResultsTableSettings)7 IJ (ij.IJ)6 GenericDialog (ij.gui.GenericDialog)5