Search in sources :

Example 1 with FitStatus

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

the class DoubletAnalysis method runAnalysis.

/**
	 * Run analysis.
	 */
private void runAnalysis() {
    if (doubletResults == null) {
        IJ.error(TITLE, "No doublet results in memory");
        return;
    }
    // Ask the user to set filters
    if (!showAnalysisDialog())
        return;
    showResults(doubletResults, analysisShowResults);
    // Store the effect of fitting as a doublet
    ArrayList<DoubletBonus> data = new ArrayList<DoubletBonus>(doubletResults.size());
    // True positive and False positives at residuals = 0
    double tp = 0;
    double fp = 0;
    Logger logger = (analysisLogging) ? new IJLogger() : null;
    // Get filters for the single and double fits
    // No coordinate shift for the doublet. We have already done simple checking of the 
    // coordinates to get the good=2 flag
    FitConfiguration filterFitConfig2 = filterFitConfig.clone();
    filterFitConfig2.setCoordinateShift(Integer.MAX_VALUE);
    final int size = 2 * config.getRelativeFitting() + 1;
    Rectangle regionBounds = new Rectangle(0, 0, size, size);
    final double otherDriftAngle = 180 - analysisDriftAngle;
    // Process all the results
    for (DoubletResult result : doubletResults) {
        // Filter the singles that would be accepted
        if (result.good1) {
            filterFitConfig.setNoise(result.noise);
            FitStatus fitStatus0 = filterFitConfig.validatePeak(0, result.fitResult1.getInitialParameters(), result.fitResult1.getParameters());
            double tp1 = 0, fp1 = 0;
            if (fitStatus0 == FitStatus.OK) {
                tp1 = result.tp1;
                fp1 = result.fp1;
            } else if (analysisLogging)
                logFailure(logger, 0, result, fitStatus0);
            // width diverged spots as OK for a doublet fit
            if ((fitStatus0 == FitStatus.OK || fitStatus0 == FitStatus.WIDTH_DIVERGED) && selectFit(result) && result.good2) {
                double tp2 = 0, fp2 = 0;
                // Basic spot criteria (SNR, Photons, width)
                filterFitConfig2.setNoise(result.noise);
                FitStatus fitStatus1 = filterFitConfig2.validatePeak(0, result.fitResult2.getInitialParameters(), result.fitResult2.getParameters());
                FitStatus fitStatus2 = filterFitConfig2.validatePeak(1, result.fitResult2.getInitialParameters(), result.fitResult2.getParameters());
                // Log basic failures
                boolean[] accept = new boolean[2];
                if (fitStatus1 == FitStatus.OK) {
                    accept[0] = true;
                } else if (analysisLogging)
                    logFailure(logger, 1, result, fitStatus1);
                if (fitStatus2 == FitStatus.OK) {
                    accept[1] = true;
                } else if (analysisLogging)
                    logFailure(logger, 2, result, fitStatus2);
                // We can filter each spot with criteria such as shift and the angle to the quadrant.
                if (accept[0] || accept[1]) {
                    if (result.gap < minGap) {
                        accept[0] = accept[1] = false;
                        if (analysisLogging)
                            logger.info("Reject Doublet (%.2f): Fitted coordinates below min gap (%g<%g)\n", result.getMaxScore(), result.gap, minGap);
                    }
                }
                if (accept[0] || accept[1]) {
                    // The logic in here will be copied to the FitWorker.quadrantAnalysis routine.
                    double[] params = result.fitResult1.getParameters();
                    double[] newParams = result.fitResult2.getParameters();
                    // Set up for shift filtering
                    double shift = filterFitConfig.getCoordinateShift();
                    if (shift == 0 || shift == Double.POSITIVE_INFINITY) {
                        // Allow the shift to span half of the fitted window.
                        shift = 0.5 * FastMath.min(regionBounds.width, regionBounds.height);
                    }
                    // Set an upper limit on the shift that is not too far outside the fit window
                    final double maxShiftX, maxShiftY;
                    final double factor = Gaussian2DFunction.SD_TO_HWHM_FACTOR;
                    if (fitConfig.isWidth0Fitting()) {
                        // Add the fitted standard deviation to the allowed shift
                        maxShiftX = regionBounds.width * 0.5 + factor * params[Gaussian2DFunction.X_SD];
                        maxShiftY = regionBounds.height * 0.5 + factor * params[Gaussian2DFunction.Y_SD];
                    } else {
                        // Add the configured standard deviation to the allowed shift
                        maxShiftX = regionBounds.width * 0.5 + factor * fitConfig.getInitialPeakStdDev0();
                        maxShiftY = regionBounds.height * 0.5 + factor * fitConfig.getInitialPeakStdDev1();
                    }
                    for (int n = 0; n < 2; n++) {
                        if (!accept[n])
                            continue;
                        // Reset
                        accept[n] = false;
                        final double xShift = newParams[Gaussian2DFunction.X_POSITION + n * 6] - params[Gaussian2DFunction.X_POSITION];
                        final double yShift = newParams[Gaussian2DFunction.Y_POSITION + n * 6] - params[Gaussian2DFunction.Y_POSITION];
                        if (Math.abs(xShift) > maxShiftX || Math.abs(yShift) > maxShiftY) {
                            if (analysisLogging)
                                logger.info("Reject P%d (%.2f): Fitted coordinates moved outside fit region (x=%g,y=%g)\n", n + 1, result.getMaxScore(), xShift, yShift);
                            continue;
                        }
                        if (Math.abs(xShift) > shift || Math.abs(yShift) > shift) {
                            // Allow up to a 45 degree difference to show the shift is along the vector
                            if (result.a[n] > analysisDriftAngle && result.a[n] < otherDriftAngle) {
                                if (analysisLogging)
                                    logger.info("Reject P%d (%.2f): Fitted coordinates moved into wrong quadrant (x=%g,y=%g,a=%f)", n + 1, result.getMaxScore(), xShift, yShift, result.a[n]);
                                continue;
                            }
                        // Note: The FitWorker also checks for drift to another candidate.
                        }
                        // This is OK
                        accept[n] = true;
                    }
                }
                if (accept[0]) {
                    tp2 += result.tp2a;
                    fp2 += result.fp2a;
                }
                if (accept[1]) {
                    tp2 += result.tp2b;
                    fp2 += result.fp2b;
                }
                if (accept[0] || accept[1]) {
                    tp += tp2;
                    fp += fp2;
                    // Store this as a doublet bonus
                    data.add(new DoubletBonus(result.getMaxScore(), result.getAvScore(), tp2 - tp1, fp2 - fp1));
                } else {
                    // No doublet fit so this will always be the single fit result
                    tp += tp1;
                    fp += fp1;
                }
            } else {
                // No doublet fit so this will always be the single fit result
                tp += tp1;
                fp += fp1;
            }
        }
    }
    // Compute the max Jaccard
    computeScores(data, tp, fp, numberOfMolecules, useMaxResiduals);
    if (showJaccardPlot)
        plotJaccard(residualsScore, (useMaxResiduals) ? _residualsScoreMax : _residualsScoreAv);
    createAnalysisTable();
    StringBuilder sb = new StringBuilder(analysisPrefix);
    sb.append(analysisTitle).append('\t');
    sb.append((useMaxResiduals) ? "Max" : "Average").append('\t');
    sb.append(SELECTION_CRITERIA[selectionCriteria]).append('\t');
    if (filterFitConfig.isSmartFilter()) {
        sb.append(filterFitConfig.getSmartFilterName()).append("\t\t\t\t\t\t\t\t");
    } else {
        sb.append('\t');
        sb.append(filterFitConfig.getCoordinateShiftFactor()).append('\t');
        sb.append(filterFitConfig.getSignalStrength()).append('\t');
        sb.append(filterFitConfig.getMinPhotons()).append('\t');
        sb.append(filterFitConfig.getMinWidthFactor()).append('\t');
        sb.append(filterFitConfig.getWidthFactor()).append('\t');
        sb.append(filterFitConfig.getPrecisionThreshold()).append('\t');
        sb.append(filterFitConfig.isPrecisionUsingBackground()).append('\t');
    }
    sb.append(analysisDriftAngle).append('\t');
    sb.append(minGap).append('\t');
    addJaccardScores(sb);
    analysisTable.append(sb.toString());
    saveTemplate(sb.toString());
}
Also used : ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) Logger(gdsc.core.logging.Logger) IJLogger(gdsc.core.ij.IJLogger) IJLogger(gdsc.core.ij.IJLogger) PeakResultPoint(gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint) BasePoint(gdsc.core.match.BasePoint) FitStatus(gdsc.smlm.fitting.FitStatus) FitConfiguration(gdsc.smlm.fitting.FitConfiguration)

Example 2 with FitStatus

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

the class BaseFunctionSolver method fit.

/*
	 * (non-Javadoc)
	 * 
	 * @see gdsc.smlm.fitting.FunctionSolver#fit(double[], double[], double[], double[])
	 */
public FitStatus fit(double[] y, double[] y_fit, double[] a, double[] a_dev) {
    // Reset the results
    numberOfFittedPoints = y.length;
    iterations = 0;
    evaluations = 0;
    value = 0;
    lastY = null;
    lastA = null;
    preProcess();
    FitStatus status = computeFit(y, y_fit, a, a_dev);
    if (status == FitStatus.OK) {
        if (lastY == null)
            lastY = y;
        if (lastA == null)
            lastA = a;
        postProcess();
    }
    return status;
}
Also used : FitStatus(gdsc.smlm.fitting.FitStatus)

Example 3 with FitStatus

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

the class NonLinearFit method computeFit.

/**
	 * Uses Levenberg-Marquardt method to fit a nonlinear model with coefficients (a) for a
	 * set of data points (x, y).
	 * <p>
	 * It is assumed that the data points x[i] corresponding to y[i] are consecutive integers from zero.
	 *
	 * @param y
	 *            Set of n data points to fit (input)
	 * @param y_fit
	 *            Fitted data points (output)
	 * @param a
	 *            Set of m coefficients (input/output)
	 * @param a_dev
	 *            Standard deviation of the set of m coefficients (output)
	 * @return The fit status
	 */
public FitStatus computeFit(double[] y, double[] y_fit, final double[] a, final double[] a_dev) {
    int n = y.length;
    final int nparams = f.gradientIndices().length;
    // Create dynamically for the parameter sizes
    calculator = GradientCalculatorFactory.newCalculator(nparams, isMLE());
    // Initialise storage. 
    // Note that covar and da are passed to EJMLLinerSolver and so must be the correct size. 
    beta = new double[nparams];
    da = new double[nparams];
    covar = new double[nparams][nparams];
    alpha = new double[nparams][nparams];
    ap = new double[a.length];
    // Store the { best, previous, new } sum-of-squares values 
    sumOfSquaresWorking = new double[3];
    boolean copyYfit = false;
    if (isMLE()) {
        // We must have positive data
        y = ensurePositive(n, y);
        // Store the function values for use in computing the log likelihood
        lastY = y;
        if (y_fit == null) {
            // Re-use space
            if (lastY_fit == null || lastY_fit.length < y.length)
                lastY_fit = new double[y.length];
            y_fit = lastY_fit;
            // We will not need to copy y_fit later since lastY_fit is used direct
            copyYfit = false;
        }
    }
    final FitStatus result = doFit(n, y, y_fit, a, a_dev, sc);
    this.evaluations = this.iterations = sc.getIteration();
    if (isMLE()) {
        // code may modify it
        if (copyYfit) {
            if (lastY_fit == null || lastY_fit.length < y.length)
                lastY_fit = new double[y.length];
            System.arraycopy(y_fit, 0, lastY_fit, 0, y.length);
        }
    }
    return result;
}
Also used : FitStatus(gdsc.smlm.fitting.FitStatus)

Example 4 with FitStatus

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

the class TraceMolecules method fitTraces.

private void fitTraces(MemoryPeakResults results, Trace[] traces) {
    // Check if the original image is open and the fit configuration can be extracted
    ImageSource source = results.getSource();
    if (source == null)
        return;
    if (!source.open())
        return;
    FitEngineConfiguration config = (FitEngineConfiguration) XmlUtils.fromXML(results.getConfiguration());
    if (config == null)
        return;
    // Show a dialog asking if the traces should be refit
    ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    gd.addMessage("Do you want to fit the traces as a single peak using a combined image?");
    gd.addCheckbox("Fit_closest_to_centroid", !fitOnlyCentroid);
    gd.addSlider("Distance_threshold", 0.01, 3, distanceThreshold);
    gd.addSlider("Expansion_factor", 1, 4.5, expansionFactor);
    // Allow fitting settings to be adjusted
    FitConfiguration fitConfig = config.getFitConfiguration();
    gd.addMessage("--- Gaussian fitting ---");
    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());
    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()]);
    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);
    gd.addNumericField("Max_iterations", fitConfig.getMaxIterations(), 0);
    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.addSlider("Duplicate_distance", 0, 1.5, fitConfig.getDuplicateDistance());
    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);
    gd.addCheckbox("Debug_failures", debugFailures);
    gd.showDialog();
    if (!gd.wasOKed()) {
        source.close();
        return;
    }
    // Get parameters for the fit
    fitOnlyCentroid = !gd.getNextBoolean();
    distanceThreshold = (float) gd.getNextNumber();
    expansionFactor = (float) 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());
    fitConfig.setFitSolver(gd.getNextChoiceIndex());
    fitConfig.setFitFunction(gd.getNextChoiceIndex());
    fitConfig.setFitCriteria(gd.getNextChoiceIndex());
    fitConfig.setSignificantDigits((int) gd.getNextNumber());
    fitConfig.setDelta(gd.getNextNumber());
    fitConfig.setLambda(gd.getNextNumber());
    fitConfig.setMaxIterations((int) gd.getNextNumber());
    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());
    // Check arguments
    try {
        Parameters.isAboveZero("Distance threshold", distanceThreshold);
        Parameters.isAbove("Expansion factor", expansionFactor, 1);
        Parameters.isAboveZero("Search_width", config.getSearch());
        Parameters.isAboveZero("Fitting_width", config.getFitting());
        Parameters.isAboveZero("Significant digits", fitConfig.getSignificantDigits());
        Parameters.isAboveZero("Delta", fitConfig.getDelta());
        Parameters.isAboveZero("Lambda", fitConfig.getLambda());
        Parameters.isAboveZero("Max iterations", fitConfig.getMaxIterations());
        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());
        Parameters.isPositive("Precision threshold", fitConfig.getPrecisionThreshold());
    } catch (IllegalArgumentException e) {
        IJ.error(TITLE, e.getMessage());
        source.close();
        return;
    }
    debugFailures = gd.getNextBoolean();
    if (!PeakFit.configureSmartFilter(globalSettings, filename))
        return;
    if (!PeakFit.configureDataFilter(globalSettings, filename, false))
        return;
    if (!PeakFit.configureFitSolver(globalSettings, filename, false))
        return;
    // Adjust settings for a single maxima
    config.setIncludeNeighbours(false);
    fitConfig.setDuplicateDistance(0);
    // Create a fit engine
    MemoryPeakResults refitResults = new MemoryPeakResults();
    refitResults.copySettings(results);
    refitResults.setName(results.getName() + " Trace Fit");
    refitResults.setSortAfterEnd(true);
    refitResults.begin();
    // No border since we know where the peaks are and we must not miss them due to truncated searching 
    FitEngine engine = new FitEngine(config, refitResults, Prefs.getThreads(), FitQueue.BLOCKING);
    // Either : Only fit the centroid
    // or     : Extract a bigger region, allowing all fits to run as normal and then 
    //          find the correct spot using Euclidian distance.
    // Set up the limits
    final double stdDev = FastMath.max(fitConfig.getInitialPeakStdDev0(), fitConfig.getInitialPeakStdDev1());
    float fitWidth = (float) (stdDev * config.getFitting() * ((fitOnlyCentroid) ? 1 : expansionFactor));
    IJ.showStatus("Refitting traces ...");
    List<JobItem> jobItems = new ArrayList<JobItem>(traces.length);
    int singles = 0;
    int fitted = 0;
    for (int n = 0; n < traces.length; n++) {
        Trace trace = traces[n];
        if (n % 32 == 0)
            IJ.showProgress(n, traces.length);
        // Skip traces with one peak
        if (trace.size() == 1) {
            singles++;
            // Use the synchronized method to avoid thread clashes with the FitEngine
            refitResults.addSync(trace.getHead());
            continue;
        }
        Rectangle bounds = new Rectangle();
        double[] combinedNoise = new double[1];
        float[] data = buildCombinedImage(source, trace, fitWidth, bounds, combinedNoise, false);
        if (data == null)
            continue;
        // Fit the combined image
        FitParameters params = new FitParameters();
        params.noise = (float) combinedNoise[0];
        float[] centre = trace.getCentroid();
        if (fitOnlyCentroid) {
            int newX = (int) Math.round(centre[0]) - bounds.x;
            int newY = (int) Math.round(centre[1]) - bounds.y;
            params.maxIndices = new int[] { newY * bounds.width + newX };
        } else {
            params.filter = new ArrayList<float[]>();
            params.filter.add(new float[] { centre[0] - bounds.x, centre[1] - bounds.y });
            params.distanceThreshold = distanceThreshold;
        }
        // This is not needed since the bounds are passed using the FitJob
        //params.setOffset(new float[] { bounds.x, bounds.y });
        int startT = trace.getHead().getFrame();
        params.endT = trace.getTail().getFrame();
        ParameterisedFitJob job = new ParameterisedFitJob(n, params, startT, data, bounds);
        jobItems.add(new JobItem(job, trace, centre));
        engine.run(job);
        fitted++;
    }
    engine.end(false);
    IJ.showStatus("");
    IJ.showProgress(1);
    // Check the success ...
    FitStatus[] values = FitStatus.values();
    int[] statusCount = new int[values.length + 1];
    ArrayList<String> names = new ArrayList<String>(Arrays.asList(SettingsManager.getNames((Object[]) values)));
    names.add(String.format("No maxima within %.2f of centroid", distanceThreshold));
    int separated = 0;
    int success = 0;
    final int debugLimit = 3;
    for (JobItem jobItem : jobItems) {
        int id = jobItem.getId();
        ParameterisedFitJob job = jobItem.job;
        Trace trace = jobItem.trace;
        int[] indices = job.getIndices();
        FitResult fitResult = null;
        int status;
        if (indices.length < 1) {
            status = values.length;
        } else if (indices.length > 1) {
            // Choose the first OK result. This is all that matters for the success reporting
            for (int n = 0; n < indices.length; n++) {
                if (job.getFitResult(n).getStatus() == FitStatus.OK) {
                    fitResult = job.getFitResult(n);
                    break;
                }
            }
            // Otherwise use the closest failure. 
            if (fitResult == null) {
                final float[] centre = traces[id].getCentroid();
                double minD = Double.POSITIVE_INFINITY;
                for (int n = 0; n < indices.length; n++) {
                    // Since the fit has failed we use the initial parameters
                    final double[] params = job.getFitResult(n).getInitialParameters();
                    final double dx = params[Gaussian2DFunction.X_POSITION] - centre[0];
                    final double dy = params[Gaussian2DFunction.Y_POSITION] - centre[1];
                    final double d = dx * dx + dy * dy;
                    if (minD > d) {
                        minD = d;
                        fitResult = job.getFitResult(n);
                    }
                }
            }
            status = fitResult.getStatus().ordinal();
        } else {
            fitResult = job.getFitResult(0);
            status = fitResult.getStatus().ordinal();
        }
        // All jobs have only one peak
        statusCount[status]++;
        // Debug why any fits failed
        if (fitResult == null || fitResult.getStatus() != FitStatus.OK) {
            refitResults.addAll(trace.getPoints());
            separated += trace.size();
            if (debugFailures) {
                FitStatus s = (fitResult == null) ? FitStatus.UNKNOWN : fitResult.getStatus();
                // Only display the first n per category to limit the number of images
                double[] noise = new double[1];
                if (statusCount[status] <= debugLimit) {
                    Rectangle bounds = new Rectangle();
                    buildCombinedImage(source, trace, fitWidth, bounds, noise, true);
                    float[] centre = trace.getCentroid();
                    Utils.display(String.format("Trace %d (n=%d) : x=%f,y=%f", id, trace.size(), centre[0], centre[1]), slices);
                    switch(s) {
                        case INSUFFICIENT_PRECISION:
                            float precision = (Float) fitResult.getStatusData();
                            IJ.log(String.format("Trace %d (n=%d) : %s = %f", id, trace.size(), names.get(status), precision));
                            break;
                        case INSUFFICIENT_SIGNAL:
                            if (noise[0] == 0)
                                noise[0] = getCombinedNoise(trace);
                            float snr = (Float) fitResult.getStatusData();
                            IJ.log(String.format("Trace %d (n=%d) : %s = %f (noise=%.2f)", id, trace.size(), names.get(status), snr, noise[0]));
                            break;
                        case COORDINATES_MOVED:
                        case OUTSIDE_FIT_REGION:
                        case WIDTH_DIVERGED:
                            float[] shift = (float[]) fitResult.getStatusData();
                            IJ.log(String.format("Trace %d (n=%d) : %s = %.3f,%.3f", id, trace.size(), names.get(status), shift[0], shift[1]));
                            break;
                        default:
                            IJ.log(String.format("Trace %d (n=%d) : %s", id, trace.size(), names.get(status)));
                            break;
                    }
                }
            }
        } else {
            success++;
            if (debugFailures) {
                // Only display the first n per category to limit the number of images
                double[] noise = new double[1];
                if (statusCount[status] <= debugLimit) {
                    Rectangle bounds = new Rectangle();
                    buildCombinedImage(source, trace, fitWidth, bounds, noise, true);
                    float[] centre = trace.getCentroid();
                    Utils.display(String.format("Trace %d (n=%d) : x=%f,y=%f", id, trace.size(), centre[0], centre[1]), slices);
                }
            }
        }
    }
    IJ.log(String.format("Trace fitting : %d singles : %d / %d fitted : %d separated", singles, success, fitted, separated));
    if (separated > 0) {
        IJ.log("Reasons for fit failure :");
        // Start at i=1 to skip FitStatus.OK
        for (int i = 1; i < statusCount.length; i++) {
            if (statusCount[i] != 0)
                IJ.log("  " + names.get(i) + " = " + statusCount[i]);
        }
    }
    refitResults.end();
    MemoryPeakResults.addResults(refitResults);
    source.close();
}
Also used : FitParameters(gdsc.smlm.engine.FitParameters) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) FitStatus(gdsc.smlm.fitting.FitStatus) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ParameterisedFitJob(gdsc.smlm.engine.ParameterisedFitJob) FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) ExtendedGenericDialog(ij.gui.ExtendedGenericDialog) ClusterPoint(gdsc.core.clustering.ClusterPoint) Trace(gdsc.smlm.results.Trace) FitEngine(gdsc.smlm.engine.FitEngine) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) FitResult(gdsc.smlm.fitting.FitResult) ImageSource(gdsc.smlm.results.ImageSource)

Example 5 with FitStatus

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

the class BaseFunctionSolverTest method fitGaussian.

double[] fitGaussian(FunctionSolver solver, double[] data, double[] params, double[] expected) {
    //System.out.printf("%s : Expected %s\n", solver.getClass().getSimpleName(), Arrays.toString(expected));
    params = params.clone();
    FitStatus status = solver.fit(data, null, params, null);
    if (status != FitStatus.OK)
        Assert.assertTrue(String.format("Fit Failed: %s i=%d: %s != %s", status.toString(), solver.getIterations(), Arrays.toString(params), Arrays.toString(expected)), false);
    return params;
}
Also used : FitStatus(gdsc.smlm.fitting.FitStatus)

Aggregations

FitStatus (gdsc.smlm.fitting.FitStatus)5 FitConfiguration (gdsc.smlm.fitting.FitConfiguration)2 Rectangle (java.awt.Rectangle)2 ArrayList (java.util.ArrayList)2 ClusterPoint (gdsc.core.clustering.ClusterPoint)1 IJLogger (gdsc.core.ij.IJLogger)1 Logger (gdsc.core.logging.Logger)1 BasePoint (gdsc.core.match.BasePoint)1 FitEngine (gdsc.smlm.engine.FitEngine)1 FitEngineConfiguration (gdsc.smlm.engine.FitEngineConfiguration)1 FitParameters (gdsc.smlm.engine.FitParameters)1 ParameterisedFitJob (gdsc.smlm.engine.ParameterisedFitJob)1 FitResult (gdsc.smlm.fitting.FitResult)1 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)1 ImageSource (gdsc.smlm.results.ImageSource)1 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)1 Trace (gdsc.smlm.results.Trace)1 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)1