Search in sources :

Example 21 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class PeakFit method configureFitSolver.

/**
	 * Show a dialog to configure the fit solver. The updated settings are saved to the settings file. An error
	 * message is shown if the dialog is cancelled or the configuration is invalid.
	 * 
	 * @param settings
	 * @param filename
	 * @param extraOptions
	 *            True if extra configuration options should be allowed
	 * @param ignoreCalibration
	 *            True if the calibration should not be configured
	 * @return True if the configuration succeeded
	 */
public static boolean configureFitSolver(GlobalSettings settings, String filename, boolean extraOptions, boolean ignoreCalibration) {
    FitEngineConfiguration config = settings.getFitEngineConfiguration();
    FitConfiguration fitConfig = config.getFitConfiguration();
    Calibration calibration = settings.getCalibration();
    boolean isBoundedLVM = fitConfig.getFitSolver() == FitSolver.LVM_MLE || fitConfig.getFitSolver() == FitSolver.BOUNDED_LVM || fitConfig.getFitSolver() == FitSolver.BOUNDED_LVM_WEIGHTED;
    if (fitConfig.getFitSolver() == FitSolver.MLE) {
        ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        gd.addMessage("Maximum Likelihood Estimation requires additional parameters");
        if (!ignoreCalibration) {
            gd.addNumericField("Camera_bias (ADUs)", calibration.getBias(), 2);
            gd.addCheckbox("Model_camera_noise", fitConfig.isModelCamera());
            gd.addNumericField("Read_noise (ADUs)", calibration.getReadNoise(), 2);
            gd.addNumericField("Amplification (ADU/electron)", calibration.getAmplification(), 2);
            gd.addCheckbox("EM-CCD", calibration.isEmCCD());
        }
        String[] searchNames = SettingsManager.getNames((Object[]) MaximumLikelihoodFitter.SearchMethod.values());
        gd.addChoice("Search_method", searchNames, searchNames[fitConfig.getSearchMethod().ordinal()]);
        gd.addStringField("Relative_threshold", "" + fitConfig.getRelativeThreshold());
        gd.addStringField("Absolute_threshold", "" + fitConfig.getAbsoluteThreshold());
        gd.addNumericField("Max_iterations", fitConfig.getMaxIterations(), 0);
        gd.addNumericField("Max_function_evaluations", fitConfig.getMaxFunctionEvaluations(), 0);
        if (extraOptions)
            gd.addCheckbox("Gradient_line_minimisation", fitConfig.isGradientLineMinimisation());
        gd.showDialog();
        if (gd.wasCanceled())
            return false;
        if (!ignoreCalibration) {
            calibration.setBias(Math.abs(gd.getNextNumber()));
            fitConfig.setModelCamera(gd.getNextBoolean());
            calibration.setReadNoise(Math.abs(gd.getNextNumber()));
            calibration.setAmplification(Math.abs(gd.getNextNumber()));
            calibration.setEmCCD(gd.getNextBoolean());
            fitConfig.setBias(calibration.getBias());
            fitConfig.setReadNoise(calibration.getReadNoise());
            fitConfig.setAmplification(calibration.getAmplification());
            fitConfig.setEmCCD(calibration.isEmCCD());
        }
        fitConfig.setSearchMethod(gd.getNextChoiceIndex());
        try {
            fitConfig.setRelativeThreshold(Math.abs(Double.parseDouble(gd.getNextString())));
            fitConfig.setAbsoluteThreshold(Math.abs(Double.parseDouble(gd.getNextString())));
        } catch (NumberFormatException e) {
            fitConfig.setRelativeThreshold(0);
            fitConfig.setAbsoluteThreshold(0);
        }
        fitConfig.setMaxIterations((int) gd.getNextNumber());
        fitConfig.setMaxFunctionEvaluations((int) gd.getNextNumber());
        if (extraOptions)
            fitConfig.setGradientLineMinimisation(gd.getNextBoolean());
        else
            // This option is for the Conjugate Gradient optimiser and makes it less stable
            fitConfig.setGradientLineMinimisation(false);
        if (filename != null)
            SettingsManager.saveSettings(settings, filename);
        try {
            Parameters.isAboveZero("Relative threshold", fitConfig.getRelativeThreshold());
            Parameters.isAboveZero("Absolute threshold", fitConfig.getAbsoluteThreshold());
            Parameters.isAboveZero("Max iterations", fitConfig.getMaxIterations());
            Parameters.isAboveZero("Max function evaluations", fitConfig.getMaxFunctionEvaluations());
            fitConfig.getFunctionSolver();
        } catch (IllegalArgumentException e) {
            IJ.error(TITLE, e.getMessage());
            return false;
        }
    } else if (isBoundedLVM || fitConfig.getFitSolver() == FitSolver.LVM || fitConfig.getFitSolver() == FitSolver.LVM_WEIGHTED) {
        boolean isWeightedLVM = fitConfig.getFitSolver() == FitSolver.LVM_WEIGHTED || fitConfig.getFitSolver() == FitSolver.BOUNDED_LVM_WEIGHTED;
        boolean requireGain = fitConfig.getFitSolver() == FitSolver.LVM_MLE;
        boolean requireBias = isWeightedLVM || requireGain;
        // Collect options for LVM fitting
        ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        gd.addMessage(fitConfig.getFitSolver().getShortName() + " requires additional parameters");
        String[] criteriaNames = SettingsManager.getNames((Object[]) FitCriteria.values());
        gd.addChoice("Fit_criteria", criteriaNames, criteriaNames[fitConfig.getFitCriteria().ordinal()]);
        gd.addNumericField("Significant_digits", fitConfig.getSignificantDigits(), 0);
        gd.addNumericField("Coord_delta", fitConfig.getDelta(), 4);
        gd.addNumericField("Lambda", fitConfig.getLambda(), 4);
        if (extraOptions)
            gd.addNumericField("Min_iterations", fitConfig.getMinIterations(), 0);
        gd.addNumericField("Max_iterations", fitConfig.getMaxIterations(), 0);
        // Extra parameters are needed for the weighted LVM
        if (isWeightedLVM && !ignoreCalibration) {
            gd.addMessage("Weighted LVM fitting requires a CCD camera noise model");
            gd.addNumericField("Read_noise (ADUs)", calibration.getReadNoise(), 2);
        }
        if (requireBias)
            gd.addNumericField("Camera_bias (ADUs)", calibration.getBias(), 2);
        if (requireGain)
            gd.addNumericField("Gain (ADU/photon)", calibration.getGain(), 2);
        if (isBoundedLVM) {
            gd.addCheckbox("Use_clamping", fitConfig.isUseClamping());
            gd.addCheckbox("Dynamic_clamping", fitConfig.isUseDynamicClamping());
            if (extraOptions) {
                gd.addNumericField("Clamp_background", fitConfig.getClampBackground(), 2);
                gd.addNumericField("Clamp_signal", fitConfig.getClampSignal(), 2);
                gd.addNumericField("Clamp_angle", fitConfig.getClampAngle(), 2);
                gd.addNumericField("Clamp_x", fitConfig.getClampX(), 2);
                gd.addNumericField("Clamp_y", fitConfig.getClampY(), 2);
                gd.addNumericField("Clamp_sd0", fitConfig.getClampXSD(), 2);
                gd.addNumericField("Clamp_sd1", fitConfig.getClampYSD(), 2);
            }
        }
        gd.showDialog();
        if (gd.wasCanceled())
            return false;
        fitConfig.setFitCriteria(gd.getNextChoiceIndex());
        fitConfig.setSignificantDigits((int) gd.getNextNumber());
        fitConfig.setDelta(gd.getNextNumber());
        fitConfig.setLambda(gd.getNextNumber());
        if (extraOptions)
            fitConfig.setMinIterations((int) gd.getNextNumber());
        fitConfig.setMaxIterations((int) gd.getNextNumber());
        if (isWeightedLVM && !ignoreCalibration) {
            calibration.setReadNoise(Math.abs(gd.getNextNumber()));
        }
        if (requireBias) {
            calibration.setBias(Math.abs(gd.getNextNumber()));
            fitConfig.setBias(calibration.getBias());
        }
        if (requireGain) {
            calibration.setGain(Math.abs(gd.getNextNumber()));
            fitConfig.setGain(calibration.getGain());
        }
        if (isBoundedLVM) {
            fitConfig.setUseClamping(gd.getNextBoolean());
            fitConfig.setUseDynamicClamping(gd.getNextBoolean());
            if (extraOptions) {
                fitConfig.setClampBackground(Math.abs(gd.getNextNumber()));
                fitConfig.setClampSignal(Math.abs(gd.getNextNumber()));
                fitConfig.setClampAngle(Math.abs(gd.getNextNumber()));
                fitConfig.setClampX(Math.abs(gd.getNextNumber()));
                fitConfig.setClampY(Math.abs(gd.getNextNumber()));
                fitConfig.setClampXSD(Math.abs(gd.getNextNumber()));
                fitConfig.setClampYSD(Math.abs(gd.getNextNumber()));
            }
        }
        if (isWeightedLVM && !ignoreCalibration) {
            fitConfig.setNoiseModel(CameraNoiseModel.createNoiseModel(calibration.getReadNoise(), calibration.getBias(), calibration.isEmCCD()));
        }
        if (filename != null)
            SettingsManager.saveSettings(settings, filename);
        try {
            Parameters.isAboveZero("Significant digits", fitConfig.getSignificantDigits());
            Parameters.isAboveZero("Delta", fitConfig.getDelta());
            Parameters.isAboveZero("Lambda", fitConfig.getLambda());
            Parameters.isAboveZero("Max iterations", fitConfig.getMaxIterations());
            fitConfig.getFunctionSolver();
        } catch (IllegalArgumentException e) {
            IJ.error(TITLE, e.getMessage());
            return false;
        }
    } else if (fitConfig.getFitSolver() == FitSolver.LVM_QUASI_NEWTON) {
        // No options yet for Apache LVM fitting. Save options for consistency
        if (filename != null)
            SettingsManager.saveSettings(settings, filename);
    }
    if (config.isIncludeNeighbours()) {
        if (!fitConfig.getFunctionSolver().isBounded()) {
            IJ.error(TITLE, "Including neighbours requires a bounded fit solver");
            return false;
        }
    }
    return true;
}
Also used : FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) Calibration(gdsc.smlm.results.Calibration) ExtendedGenericDialog(ij.gui.ExtendedGenericDialog)

Example 22 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class PSFEstimator method showDialog.

/**
	 * @param imp
	 * @return
	 */
private int showDialog(ImagePlus imp) {
    // Keep class variables for the parameters we are fitting 
    FitConfiguration fitConfig = config.getFitConfiguration();
    initialPeakStdDev0 = fitConfig.getInitialPeakStdDev0();
    initialPeakStdDev1 = fitConfig.getInitialPeakStdDev1();
    initialPeakAngle = fitConfig.getInitialAngle();
    if (!extraOptions) {
        interlacedData = false;
        integrateFrames = 1;
    }
    this.imp = imp;
    GenericDialog gd = new GenericDialog(TITLE);
    gd.addHelp(About.HELP_URL);
    gd.addMessage("Estimate 2D Gaussian to fit maxima");
    gd.addNumericField("Initial_StdDev0", initialPeakStdDev0, 3);
    gd.addNumericField("Initial_StdDev1", initialPeakStdDev1, 3);
    gd.addNumericField("Initial_Angle", initialPeakAngle, 3);
    gd.addNumericField("Number_of_peaks", settings.numberOfPeaks, 0);
    // pValue sets the smallest significance level probability level at which they are said to be different.
    // i.e. p <= pValue they are different
    // lower pValue means harder to be found different.
    // lower pValue means easier to be found the same.
    gd.addNumericField("p-Value", settings.pValue, 4);
    gd.addCheckbox("Update_preferences", settings.updatePreferences);
    gd.addCheckbox("Log_progress", settings.debugPSFEstimator);
    gd.addCheckbox("Iterate", settings.iterate);
    gd.addCheckbox("Show_histograms", settings.showHistograms);
    gd.addNumericField("Histogram_bins", settings.histogramBins, 0);
    String[] filterTypes = SettingsManager.getNames((Object[]) DataFilterType.values());
    gd.addChoice("Spot_filter_type", filterTypes, filterTypes[config.getDataFilterType().ordinal()]);
    String[] filterNames = SettingsManager.getNames((Object[]) DataFilter.values());
    gd.addChoice("Spot_filter", filterNames, filterNames[config.getDataFilter(0).ordinal()]);
    gd.addSlider("Smoothing", 0, 2.5, config.getSmooth(0));
    gd.addSlider("Search_width", 0.5, 2.5, config.getSearch());
    gd.addSlider("Border", 0.5, 2.5, config.getBorder());
    gd.addSlider("Fitting_width", 2, 4.5, config.getFitting());
    if (extraOptions) {
        gd.addCheckbox("Interlaced_data", optionInterlacedData);
        gd.addSlider("Integrate_frames", 1, 5, optionIntegrateFrames);
    }
    gd.addMessage("--- Gaussian fitting ---");
    Component splitLabel = gd.getMessage();
    String[] solverNames = SettingsManager.getNames((Object[]) FitSolver.values());
    gd.addChoice("Fit_solver", solverNames, solverNames[fitConfig.getFitSolver().ordinal()]);
    String[] functionNames = SettingsManager.getNames((Object[]) FitFunction.values());
    gd.addChoice("Fit_function", functionNames, functionNames[fitConfig.getFitFunction().ordinal()]);
    // Parameters specific to each Fit solver are collected in a second dialog 
    gd.addNumericField("Fail_limit", config.getFailuresLimit(), 0);
    gd.addCheckbox("Include_neighbours", config.isIncludeNeighbours());
    gd.addSlider("Neighbour_height", 0.01, 1, config.getNeighbourHeightThreshold());
    gd.addSlider("Residuals_threshold", 0.01, 1, config.getResidualsThreshold());
    gd.addMessage("--- Peak filtering ---\nDiscard fits that shift; are too low; or expand/contract");
    gd.addCheckbox("Smart_filter", fitConfig.isSmartFilter());
    gd.addCheckbox("Disable_simple_filter", fitConfig.isDisableSimpleFilter());
    gd.addSlider("Shift_factor", 0.01, 2, fitConfig.getCoordinateShiftFactor());
    gd.addNumericField("Signal_strength", fitConfig.getSignalStrength(), 2);
    gd.addNumericField("Min_photons", fitConfig.getMinPhotons(), 0);
    gd.addSlider("Min_width_factor", 0, 0.99, fitConfig.getMinWidthFactor());
    gd.addSlider("Width_factor", 1.01, 5, fitConfig.getWidthFactor());
    gd.addNumericField("Precision", fitConfig.getPrecisionThreshold(), 2);
    if (gd.getLayout() != null) {
        GridBagLayout grid = (GridBagLayout) gd.getLayout();
        int xOffset = 0, yOffset = 0;
        int lastY = -1, rowCount = 0;
        for (Component comp : gd.getComponents()) {
            // Check if this should be the second major column
            if (comp == splitLabel) {
                xOffset += 2;
                yOffset -= rowCount;
            }
            // Reposition the field
            GridBagConstraints c = grid.getConstraints(comp);
            if (lastY != c.gridy)
                rowCount++;
            lastY = c.gridy;
            c.gridx = c.gridx + xOffset;
            c.gridy = c.gridy + yOffset;
            c.insets.left = c.insets.left + 10 * xOffset;
            c.insets.top = 0;
            c.insets.bottom = 0;
            grid.setConstraints(comp, c);
        }
        if (IJ.isLinux())
            gd.setBackground(new Color(238, 238, 238));
    }
    gd.showDialog();
    if (gd.wasCanceled() || !readDialog(gd))
        return DONE;
    return flags;
}
Also used : GridBagConstraints(java.awt.GridBagConstraints) GridBagLayout(java.awt.GridBagLayout) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) GenericDialog(ij.gui.GenericDialog) Color(java.awt.Color) Component(java.awt.Component)

Example 23 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class PSFEstimator method readDialog.

private boolean readDialog(GenericDialog gd) {
    initialPeakStdDev0 = gd.getNextNumber();
    initialPeakStdDev1 = gd.getNextNumber();
    initialPeakAngle = gd.getNextNumber();
    settings.numberOfPeaks = (int) gd.getNextNumber();
    settings.pValue = gd.getNextNumber();
    settings.updatePreferences = gd.getNextBoolean();
    settings.debugPSFEstimator = gd.getNextBoolean();
    settings.iterate = gd.getNextBoolean();
    settings.showHistograms = gd.getNextBoolean();
    settings.histogramBins = (int) gd.getNextNumber();
    config.setDataFilterType(gd.getNextChoiceIndex());
    config.setDataFilter(gd.getNextChoiceIndex(), Math.abs(gd.getNextNumber()), 0);
    config.setSearch(gd.getNextNumber());
    config.setBorder(gd.getNextNumber());
    config.setFitting(gd.getNextNumber());
    if (extraOptions) {
        interlacedData = optionInterlacedData = gd.getNextBoolean();
        integrateFrames = optionIntegrateFrames = (int) gd.getNextNumber();
    }
    FitConfiguration fitConfig = config.getFitConfiguration();
    fitConfig.setFitSolver(gd.getNextChoiceIndex());
    fitConfig.setFitFunction(gd.getNextChoiceIndex());
    config.setFailuresLimit((int) gd.getNextNumber());
    config.setIncludeNeighbours(gd.getNextBoolean());
    config.setNeighbourHeightThreshold(gd.getNextNumber());
    config.setResidualsThreshold(gd.getNextNumber());
    fitConfig.setSmartFilter(gd.getNextBoolean());
    fitConfig.setDisableSimpleFilter(gd.getNextBoolean());
    fitConfig.setCoordinateShiftFactor(gd.getNextNumber());
    fitConfig.setSignalStrength(gd.getNextNumber());
    fitConfig.setMinPhotons(gd.getNextNumber());
    fitConfig.setMinWidthFactor(gd.getNextNumber());
    fitConfig.setWidthFactor(gd.getNextNumber());
    fitConfig.setPrecisionThreshold(gd.getNextNumber());
    if (gd.invalidNumber())
        return false;
    // Check arguments
    try {
        Parameters.isAboveZero("Initial SD0", initialPeakStdDev0);
        Parameters.isAboveZero("Initial SD1", initialPeakStdDev1);
        Parameters.isPositive("Initial angle", initialPeakAngle);
        Parameters.isPositive("Number of peaks", settings.numberOfPeaks);
        Parameters.isAboveZero("P-value", settings.pValue);
        Parameters.isEqualOrBelow("P-value", settings.pValue, 0.5);
        if (settings.showHistograms)
            Parameters.isAboveZero("Histogram bins", settings.histogramBins);
        Parameters.isAboveZero("Search width", config.getSearch());
        Parameters.isAboveZero("Fitting width", config.getFitting());
        Parameters.isPositive("Failures limit", config.getFailuresLimit());
        Parameters.isPositive("Neighbour height threshold", config.getNeighbourHeightThreshold());
        Parameters.isPositive("Residuals threshold", config.getResidualsThreshold());
        Parameters.isPositive("Coordinate Shift factor", fitConfig.getCoordinateShiftFactor());
        Parameters.isPositive("Signal strength", fitConfig.getSignalStrength());
        Parameters.isPositive("Min photons", fitConfig.getMinPhotons());
        Parameters.isPositive("Min width factor", fitConfig.getMinWidthFactor());
        Parameters.isPositive("Width factor", fitConfig.getWidthFactor());
    } catch (IllegalArgumentException e) {
        IJ.error(TITLE, e.getMessage());
        return false;
    }
    if (fitConfig.getFitFunction() != FitFunction.FREE && fitConfig.getFitFunction() != FitFunction.FREE_CIRCULAR && fitConfig.getFitFunction() != FitFunction.CIRCULAR) {
        String msg = "ERROR: A width-fitting function must be selected (i.e. not fixed-width fitting)";
        IJ.error(TITLE, msg);
        log(msg);
        return false;
    }
    final String filename = SettingsManager.getSettingsFilename();
    SettingsManager.saveSettings(globalSettings, filename);
    if (!PeakFit.configureSmartFilter(globalSettings, filename))
        return false;
    if (!PeakFit.configureDataFilter(globalSettings, filename, false))
        return false;
    if (!PeakFit.configureFitSolver(globalSettings, filename, false))
        return false;
    // Extra parameters are needed for interlaced data
    if (interlacedData) {
        gd = new GenericDialog(TITLE);
        gd.addMessage("Interlaced data requires a repeating pattern of frames to process.\n" + "Describe the regular repeat of the data:\n \n" + "Start = The first frame that contains data\n" + "Block = The number of continuous frames containing data\n" + "Skip = The number of continuous frames to ignore before the next data\n \n" + "E.G. 2:9:1 = Data was imaged from frame 2 for 9 frames, 1 frame to ignore, then repeat.");
        gd.addNumericField("Start", optionDataStart, 0);
        gd.addNumericField("Block", optionDataBlock, 0);
        gd.addNumericField("Skip", optionDataSkip, 0);
        gd.showDialog();
        if (gd.wasCanceled())
            return false;
        if (!gd.wasCanceled()) {
            dataStart = (int) gd.getNextNumber();
            dataBlock = (int) gd.getNextNumber();
            dataSkip = (int) gd.getNextNumber();
            if (dataStart > 0 && dataBlock > 0 && dataSkip > 0) {
                // Store options for next time
                optionInterlacedData = true;
                optionDataStart = dataStart;
                optionDataBlock = dataBlock;
                optionDataSkip = dataSkip;
            }
        } else {
            interlacedData = false;
        }
    }
    return true;
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration) GenericDialog(ij.gui.GenericDialog)

Example 24 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class GaussianFit method runFinal.

/**
	 * Perform fitting using the chosen maxima. Update the overlay if successful.
	 * 
	 * @param ip
	 *            The input image
	 */
private void runFinal(ImageProcessor ip) {
    ip.reset();
    Rectangle bounds = ip.getRoi();
    // Crop to the ROI
    float[] data = ImageConverter.getData(ip);
    int width = bounds.width;
    int height = bounds.height;
    // Sort the maxima
    float[] smoothData = data;
    if (getSmooth() > 0) {
        // Smoothing destructively modifies the data so create a copy
        smoothData = Arrays.copyOf(data, width * height);
        AverageFilter filter = new AverageFilter();
        //filter.blockAverage(smoothData, width, height, smooth);
        if (smooth <= border)
            filter.stripedBlockAverageInternal(smoothData, width, height, (float) smooth);
        else
            filter.stripedBlockAverage(smoothData, width, height, (float) smooth);
    }
    Sort.sort(maxIndices, smoothData);
    // Show the candidate peaks
    if (maxIndices.length > 0) {
        String message = String.format("Identified %d peaks", maxIndices.length);
        if (isLogProgress()) {
            IJ.log(message);
            for (int index : maxIndices) {
                IJ.log(String.format("  %.2f @ [%d,%d]", data[index], bounds.x + index % width, bounds.y + index / width));
            }
        }
        // Check whether to run if the number of peaks is large
        if (maxIndices.length > 10) {
            GenericDialog gd = new GenericDialog("Warning");
            gd.addMessage(message + "\nDo you want to fit?");
            gd.showDialog();
            if (gd.wasCanceled())
                return;
        }
    } else {
        IJ.log("No maxima identified");
        return;
    }
    results = new IJTablePeakResults(showDeviations, imp.getTitle() + " [" + imp.getCurrentSlice() + "]");
    results.begin();
    // Perform the Gaussian fit
    long ellapsed = 0;
    if (!singleFit) {
        if (isLogProgress())
            IJ.log("Combined fit");
        // Estimate height from smoothed data
        double[] estimatedHeights = new double[maxIndices.length];
        for (int i = 0; i < estimatedHeights.length; i++) estimatedHeights[i] = smoothData[maxIndices[i]];
        FitConfiguration config = new FitConfiguration();
        setupPeakFiltering(config);
        long time = System.nanoTime();
        double[] params = fitMultiple(data, width, height, maxIndices, estimatedHeights);
        ellapsed = System.nanoTime() - time;
        if (params != null) {
            // Copy all the valid parameters into a new array
            double[] validParams = new double[params.length];
            int c = 0;
            int validPeaks = 0;
            validParams[c++] = params[0];
            double[] initialParams = convertParameters(fitResult.getInitialParameters());
            double[] paramsDev = convertParameters(fitResult.getParameterStdDev());
            Rectangle regionBounds = new Rectangle();
            int[] xpoints = new int[maxIndices.length];
            int[] ypoints = new int[maxIndices.length];
            int nMaxima = 0;
            for (int i = 1, n = 0; i < params.length; i += 6, n++) {
                int y = maxIndices[n] / width;
                int x = maxIndices[n] % width;
                // Check the peak is a good fit
                if (filterResults && config.validatePeak(n, initialParams, params) != FitStatus.OK)
                    continue;
                if (showFit) {
                    // Copy the valid parameters
                    validPeaks++;
                    for (int ii = i, j = 0; j < 6; ii++, j++) validParams[c++] = params[ii];
                }
                double[] peakParams = extractParams(params, i);
                double[] peakParamsDev = extractParams(paramsDev, i);
                addResult(bounds, regionBounds, data, peakParams, peakParamsDev, nMaxima, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                double xf = peakParams[3];
                double yf = peakParams[4];
                xpoints[nMaxima] = (int) (xf + 0.5);
                ypoints[nMaxima] = (int) (yf + 0.5);
                nMaxima++;
            }
            setOverlay(nMaxima, xpoints, ypoints);
            // Draw the fit
            if (showFit && validPeaks != 0) {
                double[] pixels = new double[data.length];
                EllipticalGaussian2DFunction f = new EllipticalGaussian2DFunction(validPeaks, width, height);
                invertParameters(validParams);
                f.initialise(validParams);
                for (int x = 0; x < pixels.length; x++) pixels[x] = f.eval(x);
                FloatProcessor fp = new FloatProcessor(width, height, pixels);
                // Insert into a full size image
                FloatProcessor fp2 = new FloatProcessor(ip.getWidth(), ip.getHeight());
                fp2.insert(fp, bounds.x, bounds.y);
                Utils.display(TITLE, fp2);
            }
        } else {
            if (isLogProgress()) {
                IJ.log("Failed to fit " + Utils.pleural(maxIndices.length, "peak") + getReason(fitResult));
            }
            imp.setOverlay(null);
        }
    } else {
        if (isLogProgress())
            IJ.log("Individual fit");
        int nMaxima = 0;
        int[] xpoints = new int[maxIndices.length];
        int[] ypoints = new int[maxIndices.length];
        // Extract each peak and fit individually
        ImageExtractor ie = new ImageExtractor(data, width, height);
        float[] region = null;
        Gaussian2DFitter gf = createGaussianFitter(filterResults);
        for (int n = 0; n < maxIndices.length; n++) {
            int y = maxIndices[n] / width;
            int x = maxIndices[n] % width;
            long time = System.nanoTime();
            Rectangle regionBounds = ie.getBoxRegionBounds(x, y, singleRegionSize);
            region = ie.crop(regionBounds, region);
            int newIndex = (y - regionBounds.y) * regionBounds.width + x - regionBounds.x;
            if (isLogProgress()) {
                IJ.log("Fitting peak " + (n + 1));
            }
            double[] peakParams = fitSingle(gf, region, regionBounds.width, regionBounds.height, newIndex, smoothData[maxIndices[n]]);
            ellapsed += System.nanoTime() - time;
            // Output fit result
            if (peakParams != null) {
                double[] peakParamsDev = null;
                if (showDeviations) {
                    peakParamsDev = convertParameters(fitResult.getParameterStdDev());
                }
                addResult(bounds, regionBounds, data, peakParams, peakParamsDev, n, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                double xf = peakParams[3];
                double yf = peakParams[4];
                xpoints[nMaxima] = (int) (xf + 0.5);
                ypoints[nMaxima] = (int) (yf + 0.5);
                nMaxima++;
            } else {
                if (isLogProgress()) {
                    IJ.log("Failed to fit peak " + (n + 1) + getReason(fitResult));
                }
            }
        }
        // Update the overlay
        if (nMaxima > 0)
            setOverlay(nMaxima, xpoints, ypoints);
        else
            imp.setOverlay(null);
    }
    results.end();
    if (isLogProgress())
        IJ.log("Time = " + (ellapsed / 1000000.0) + "ms");
}
Also used : FloatProcessor(ij.process.FloatProcessor) EllipticalGaussian2DFunction(gdsc.smlm.function.gaussian.EllipticalGaussian2DFunction) Gaussian2DFitter(gdsc.smlm.fitting.Gaussian2DFitter) Rectangle(java.awt.Rectangle) AverageFilter(gdsc.smlm.filters.AverageFilter) IJTablePeakResults(gdsc.smlm.ij.results.IJTablePeakResults) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) GenericDialog(ij.gui.GenericDialog) ImageExtractor(gdsc.core.utils.ImageExtractor)

Example 25 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class GaussianFit method createGaussianFitter.

private Gaussian2DFitter createGaussianFitter(boolean simpleFiltering) {
    FitConfiguration config = new FitConfiguration();
    config.setMaxIterations(getMaxIterations());
    config.setSignificantDigits(getSignificantDigits());
    config.setDelta(getDelta());
    config.setInitialPeakStdDev(getInitialPeakStdDev());
    config.setComputeDeviations(showDeviations);
    config.setDuplicateDistance(0);
    // Set-up peak filtering only for single fitting
    config.setDisableSimpleFilter(!simpleFiltering);
    setupPeakFiltering(config);
    if (isLogProgress()) {
        config.setLog(new IJLogger());
    }
    if (getFitCriteria() >= 0 && getFitCriteria() < FitCriteria.values().length) {
        config.setFitCriteria(FitCriteria.values()[getFitCriteria()]);
    } else {
        config.setFitCriteria(FitCriteria.LEAST_SQUARED_ERROR);
    }
    if (getFitFunction() >= 0 && getFitFunction() < FitFunction.values().length) {
        config.setFitFunction(FitFunction.values()[getFitFunction()]);
    } else {
        config.setFitFunction(FitFunction.CIRCULAR);
    }
    config.setBackgroundFitting(fitBackground);
    return new Gaussian2DFitter(config);
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration) Gaussian2DFitter(gdsc.smlm.fitting.Gaussian2DFitter) IJLogger(gdsc.core.ij.IJLogger)

Aggregations

FitConfiguration (gdsc.smlm.fitting.FitConfiguration)32 FitEngineConfiguration (gdsc.smlm.engine.FitEngineConfiguration)16 GlobalSettings (gdsc.smlm.ij.settings.GlobalSettings)8 GenericDialog (ij.gui.GenericDialog)6 Rectangle (java.awt.Rectangle)5 BasePoint (gdsc.core.match.BasePoint)4 Calibration (gdsc.smlm.results.Calibration)4 MultiPathFilter (gdsc.smlm.results.filter.MultiPathFilter)4 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)4 IJLogger (gdsc.core.ij.IJLogger)3 Gaussian2DFitter (gdsc.smlm.fitting.Gaussian2DFitter)3 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)3 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)3 DirectFilter (gdsc.smlm.results.filter.DirectFilter)3 Checkbox (java.awt.Checkbox)3 ImageExtractor (gdsc.core.utils.ImageExtractor)2 FitEngine (gdsc.smlm.engine.FitEngine)2 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)2 FitResult (gdsc.smlm.fitting.FitResult)2 FitStatus (gdsc.smlm.fitting.FitStatus)2