Search in sources :

Example 71 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class FilterAnalysis method showDialog.

private boolean showDialog(List<MemoryPeakResults> resultsList, boolean fileInput) {
    GenericDialog gd = new GenericDialog(TITLE);
    gd.addHelp(About.HELP_URL);
    int total = 0;
    int tp = 0;
    for (MemoryPeakResults r : resultsList) {
        total += r.size();
        for (PeakResult p : r.getResults()) if (p.origValue != 0)
            tp++;
    }
    gd.addMessage(String.format("%d files, %d results, %d True-Positives", resultsList.size(), total, tp));
    if (!fileInput) {
        gd.addCheckbox("SNR_filter", snrFilter);
        gd.addNumericField("Min_SNR", minSnr, 0);
        gd.addNumericField("Max_SNR", maxSnr, 0);
        gd.addNumericField("Min_Width", minWidth, 2);
        gd.addNumericField("Max_Width", maxWidth, 2);
        gd.addNumericField("Increment_Width", incWidth, 2);
        gd.addCheckbox("Precision_filter", precisionFilter);
        gd.addNumericField("Min_Precision", minPrecision, 0);
        gd.addNumericField("Max_Precision", maxPrecision, 0);
        gd.addCheckbox("Trace_filter", traceFilter);
        gd.addNumericField("Min_distance", minDistance, 2);
        gd.addNumericField("Max_distance", maxDistance, 2);
        gd.addNumericField("Increment_distance", incDistance, 2);
        gd.addNumericField("Min_time", minTime, 0);
        gd.addNumericField("Max_time", maxTime, 0);
        gd.addNumericField("Increment_time", incTime, 0);
        gd.addCheckbox("Hysteresis_SNR_filter", hysteresisSnrFilter);
        gd.addNumericField("Min_SNR_gap", minSnrGap, 0);
        gd.addNumericField("Max_SNR_gap", maxSnrGap, 0);
        gd.addNumericField("Increment_SNR_gap", incSnrGap, 0);
        gd.addCheckbox("Hysteresis_Precision_filter", hysteresisPrecisionFilter);
        gd.addNumericField("Min_Precision_gap", minPrecisionGap, 0);
        gd.addNumericField("Max_Precision_gap", maxPrecisionGap, 0);
        gd.addNumericField("Increment_Precision_gap", incPrecisionGap, 0);
        gd.addCheckbox("Save_filters", saveFilterSets);
    }
    gd.addCheckbox("Show_table", showResultsTable);
    gd.addSlider("Plot_top_n", 0, 20, plotTopN);
    gd.addCheckbox("Calculate_sensitivity", calculateSensitivity);
    gd.addSlider("Delta", 0.01, 1, delta);
    if (!fileInput) {
        // Re-arrange to 2 columns
        if (gd.getLayout() != null) {
            GridBagLayout grid = (GridBagLayout) gd.getLayout();
            Component splitLabel = (Component) gd.getCheckboxes().get(3);
            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;
                    rowCount = 0;
                }
                // 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, fileInput))
        return false;
    return true;
}
Also used : GridBagConstraints(java.awt.GridBagConstraints) GridBagLayout(java.awt.GridBagLayout) GenericDialog(ij.gui.GenericDialog) Color(java.awt.Color) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) Component(java.awt.Component) PeakResult(gdsc.smlm.results.PeakResult)

Example 72 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class FIRE method calculatePrecisionHistogram.

/**
	 * Calculate a histogram of the precision. The precision can be either stored in the results or calculated using the
	 * Mortensen formula. If the precision method for Q estimation is not fixed then the histogram is fitted with a
	 * Gaussian to create an initial estimate.
	 *
	 * @param precisionMethod
	 *            the precision method
	 * @return The precision histogram
	 */
private PrecisionHistogram calculatePrecisionHistogram() {
    boolean logFitParameters = false;
    String title = results.getName() + " Precision Histogram";
    // Check if the results has the precision already or if it can be computed.
    boolean canUseStored = canUseStoredPrecision(results);
    boolean canCalculatePrecision = canCalculatePrecision(results);
    // Set the method to compute a histogram. Default to the user selected option.
    PrecisionMethod m = null;
    if (canUseStored && precisionMethod == PrecisionMethod.STORED)
        m = precisionMethod;
    else if (canCalculatePrecision && precisionMethod == PrecisionMethod.CALCULATE)
        m = precisionMethod;
    if (m == null) {
        // We only have two choices so if one is available then select it.
        if (canUseStored)
            m = PrecisionMethod.STORED;
        else if (canCalculatePrecision)
            m = PrecisionMethod.CALCULATE;
        // If the user selected a method not available then log a warning
        if (m != null && precisionMethod != PrecisionMethod.FIXED) {
            IJ.log(String.format("%s : Selected precision method '%s' not available, switching to '%s'", TITLE, precisionMethod, m.getName()));
        }
        if (m == null) {
            // This does not matter if the user has provide a fixed input.
            if (precisionMethod == PrecisionMethod.FIXED) {
                PrecisionHistogram histogram = new PrecisionHistogram(title);
                histogram.mean = mean;
                histogram.sigma = sigma;
                return histogram;
            }
            // No precision
            return null;
        }
    }
    // We get here if we can compute precision.
    // Build the histogram 
    StoredDataStatistics precision = new StoredDataStatistics(results.size());
    if (m == PrecisionMethod.STORED) {
        for (PeakResult r : results.getResults()) {
            precision.add(r.getPrecision());
        }
    } else {
        final double nmPerPixel = results.getNmPerPixel();
        final double gain = results.getGain();
        final boolean emCCD = results.isEMCCD();
        for (PeakResult r : results.getResults()) {
            precision.add(r.getPrecision(nmPerPixel, gain, emCCD));
        }
    }
    //System.out.printf("Raw p = %f\n", precision.getMean());
    double yMin = Double.NEGATIVE_INFINITY, yMax = 0;
    // Set the min and max y-values using 1.5 x IQR 
    DescriptiveStatistics stats = precision.getStatistics();
    double lower = stats.getPercentile(25);
    double upper = stats.getPercentile(75);
    if (Double.isNaN(lower) || Double.isNaN(upper)) {
        if (logFitParameters)
            Utils.log("Error computing IQR: %f - %f", lower, upper);
    } else {
        double iqr = upper - lower;
        yMin = FastMath.max(lower - iqr, stats.getMin());
        yMax = FastMath.min(upper + iqr, stats.getMax());
        if (logFitParameters)
            Utils.log("  Data range: %f - %f. Plotting 1.5x IQR: %f - %f", stats.getMin(), stats.getMax(), yMin, yMax);
    }
    if (yMin == Double.NEGATIVE_INFINITY) {
        int n = 5;
        yMin = Math.max(stats.getMin(), stats.getMean() - n * stats.getStandardDeviation());
        yMax = Math.min(stats.getMax(), stats.getMean() + n * stats.getStandardDeviation());
        if (logFitParameters)
            Utils.log("  Data range: %f - %f. Plotting mean +/- %dxSD: %f - %f", stats.getMin(), stats.getMax(), n, yMin, yMax);
    }
    // Get the data within the range
    double[] data = precision.getValues();
    precision = new StoredDataStatistics(data.length);
    for (double d : data) {
        if (d < yMin || d > yMax)
            continue;
        precision.add(d);
    }
    int histogramBins = Utils.getBins(precision, Utils.BinMethod.SCOTT);
    float[][] hist = Utils.calcHistogram(precision.getFloatValues(), yMin, yMax, histogramBins);
    PrecisionHistogram histogram = new PrecisionHistogram(hist, precision, title);
    if (precisionMethod == PrecisionMethod.FIXED) {
        histogram.mean = mean;
        histogram.sigma = sigma;
        return histogram;
    }
    // Fitting of the histogram to produce the initial estimate
    // Extract non-zero data
    float[] x = Arrays.copyOf(hist[0], hist[0].length);
    float[] y = hist[1];
    int count = 0;
    float dx = (x[1] - x[0]) * 0.5f;
    for (int i = 0; i < y.length; i++) if (y[i] > 0) {
        x[count] = x[i] + dx;
        y[count] = y[i];
        count++;
    }
    x = Arrays.copyOf(x, count);
    y = Arrays.copyOf(y, count);
    // Sense check to fitted data. Get mean and SD of histogram
    double[] stats2 = Utils.getHistogramStatistics(x, y);
    if (logFitParameters)
        Utils.log("  Initial Statistics: %f +/- %f", stats2[0], stats2[1]);
    histogram.mean = stats2[0];
    histogram.sigma = stats2[1];
    // Standard Gaussian fit
    double[] parameters = fitGaussian(x, y);
    if (parameters == null) {
        Utils.log("  Failed to fit initial Gaussian");
        return histogram;
    }
    double newMean = parameters[1];
    double error = Math.abs(stats2[0] - newMean) / stats2[1];
    if (error > 3) {
        Utils.log("  Failed to fit Gaussian: %f standard deviations from histogram mean", error);
        return histogram;
    }
    if (newMean < yMin || newMean > yMax) {
        Utils.log("  Failed to fit Gaussian: %f outside data range %f - %f", newMean, yMin, yMax);
        return histogram;
    }
    if (logFitParameters)
        Utils.log("  Initial Gaussian: %f @ %f +/- %f", parameters[0], parameters[1], parameters[2]);
    histogram.mean = parameters[1];
    histogram.sigma = parameters[2];
    return histogram;
}
Also used : DescriptiveStatistics(org.apache.commons.math3.stat.descriptive.DescriptiveStatistics) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) PeakResult(gdsc.smlm.results.PeakResult) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint)

Example 73 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class FitWorker method run.

/**
	 * Locate all the peaks in the image specified by the fit job
	 * <p>
	 * WARNING: The FitWorker fits a sub-region of the data for each maxima. It then updates the FitResult parameters
	 * with an offset reflecting the position. The initialParameters are not updated with this offset unless configured.
	 * 
	 * @param job
	 *            The fit job
	 */
public void run(FitJob job) {
    final long start = System.nanoTime();
    job.start();
    this.job = job;
    benchmarking = false;
    this.slice = job.slice;
    // Used for debugging
    //if (logger == null) logger = new gdsc.fitting.logging.ConsoleLogger();
    // Crop to the ROI
    cc = new CoordinateConverter(job.bounds);
    final int width = cc.dataBounds.width;
    final int height = cc.dataBounds.height;
    borderLimitX = width - border;
    borderLimitY = height - border;
    data = job.data;
    FitParameters params = job.getFitParameters();
    this.endT = (params != null) ? params.endT : -1;
    candidates = indentifySpots(job, width, height, params);
    if (candidates.size == 0) {
        finish(job, start);
        return;
    }
    fittedBackground = 0;
    // Always get the noise and store it with the results.
    if (params != null && !Float.isNaN(params.noise)) {
        noise = params.noise;
        fitConfig.setNoise(noise);
    } else if (calculateNoise) {
        noise = estimateNoise(width, height);
        fitConfig.setNoise(noise);
    }
    //System.out.printf("Slice %d : Noise = %g\n", slice, noise);
    if (logger != null)
        logger.info("Slice %d: Noise = %f", slice, noise);
    final ImageExtractor ie = new ImageExtractor(data, width, height);
    double[] region = null;
    if (params != null && params.fitTask == FitTask.MAXIMA_IDENITIFICATION) {
        final float sd0 = (float) fitConfig.getInitialPeakStdDev0();
        final float sd1 = (float) fitConfig.getInitialPeakStdDev1();
        for (int n = 0; n < candidates.getSize(); n++) {
            // Find the background using the perimeter of the data.
            // TODO - Perhaps the Gaussian Fitter should be used to produce the initial estimates but no actual fit done.
            // This would produce coords using the centre-of-mass.
            final Candidate candidate = candidates.get(n);
            final int x = candidate.x;
            final int y = candidate.y;
            final Rectangle regionBounds = ie.getBoxRegionBounds(x, y, fitting);
            region = ie.crop(regionBounds, region);
            final float b = (float) Gaussian2DFitter.getBackground(region, regionBounds.width, regionBounds.height, 1);
            // Offset the coords to the centre of the pixel. Note the bounds will be added later.
            // Subtract the background to get the amplitude estimate then convert to signal.
            final float amplitude = candidate.intensity - ((relativeIntensity) ? 0 : b);
            final float signal = (float) (amplitude * 2.0 * Math.PI * sd0 * sd1);
            final float[] peakParams = new float[] { b, signal, 0, x + 0.5f, y + 0.5f, sd0, sd1 };
            final int index = y * width + x;
            sliceResults.add(createResult(cc.fromDataToGlobalX(x), cc.fromDataToGlobalY(y), data[index], 0, noise, peakParams, null, n));
        }
    } else {
        initialiseFitting();
        // Smooth the data to provide initial background estimates
        final BlockAverageDataProcessor processor = new BlockAverageDataProcessor(1, 1);
        final float[] smoothedData = processor.process(data, width, height);
        final ImageExtractor ie2 = new ImageExtractor(smoothedData, width, height);
        // Allow the results to be filtered for certain peaks
        if (params != null && params.filter != null) {
            resultFilter = new DistanceResultFilter(params.filter, params.distanceThreshold, candidates.getlength());
        //filter = new OptimumDistanceResultFilter(params.filter, params.distanceThreshold, maxIndices.length);
        }
        // The SpotFitter is used to create a dynamic MultiPathFitResult object.
        // This is then passed to a multi-path filter. Thus the same fitting decision process 
        // is used when benchmarking and when running on actual data.
        // Note: The SpotFitter labels each PreprocessedFitResult using the offset in the FitResult object.
        // The initial params and deviations can then be extracted for the results that pass the filter.
        MultiPathFilter filter;
        IMultiPathFitResults multiPathResults = this;
        SelectedResultStore store = this;
        coordinateStore = coordinateStore.resize(width, height);
        if (params != null && params.fitTask == FitTask.BENCHMARKING) {
            // Run filtering as normal. However in the event that a candidate is missed or some
            // results are not generated we must generate them. This is done in the complete(int)
            // method if we set the benchmarking flag.
            benchmarking = true;
            // Filter using the benchmark filter
            filter = params.benchmarkFilter;
            if (filter == null) {
                // Create a default filter using the standard FitConfiguration to ensure sensible fits
                // are stored as the current slice results.
                // Note the current fit configuration for benchmarking may have minimal filtering settings
                // so we do not use that object.
                final FitConfiguration tmp = new FitConfiguration();
                final double residualsThreshold = 0.4;
                filter = new MultiPathFilter(tmp, createMinimalFilter(), residualsThreshold);
            }
        } else {
            // Filter using the configuration
            filter = new MultiPathFilter(fitConfig, createMinimalFilter(), config.getResidualsThreshold());
        }
        // If we are benchmarking then do not generate results dynamically since we will store all 
        // results in the fit job
        dynamicMultiPathFitResult = new DynamicMultiPathFitResult(ie, ie2, !benchmarking);
        // Debug where the fit config may be different between benchmarking and fitting
        if (slice == -1) {
            SettingsManager.saveFitEngineConfiguration(config, String.format("/tmp/config.%b.xml", benchmarking));
            Utils.write(String.format("/tmp/filter.%b.xml", benchmarking), filter.toXML());
            //filter.setDebugFile(String.format("/tmp/fitWorker.%b.txt", benchmarking));
            StringBuilder sb = new StringBuilder();
            sb.append((benchmarking) ? ((gdsc.smlm.results.filter.Filter) filter.getFilter()).toXML() : fitConfig.getSmartFilter().toXML()).append("\n");
            sb.append(((gdsc.smlm.results.filter.Filter) filter.getMinimalFilter()).toXML()).append("\n");
            sb.append(filter.residualsThreshold).append("\n");
            sb.append(config.getFailuresLimit()).append("\n");
            sb.append(fitConfig.getDuplicateDistance()).append("\n");
            if (spotFilter != null)
                sb.append(spotFilter.getDescription()).append("\n");
            sb.append("MaxCandidate = ").append(candidates.getSize()).append("\n");
            for (int i = 0; i < candidates.list.length; i++) {
                sb.append(String.format("Fit %d [%d,%d = %.1f]\n", i, candidates.get(i).x, candidates.get(i).y, candidates.get(i).intensity));
            }
            Utils.write(String.format("/tmp/candidates.%b.xml", benchmarking), sb.toString());
        }
        filter.select(multiPathResults, config.getFailuresLimit(), true, store, coordinateStore);
        if (logger != null)
            logger.info("Slice %d: %d / %d", slice, success, candidates.getSize());
        // Result filter post-processing
        if (resultFilter != null) {
            resultFilter.finalise();
            job.setResults(resultFilter.getResults());
            job.setIndices(resultFilter.getMaxIndices());
            for (int i = 0; i < resultFilter.getFilteredCount(); i++) {
                job.setFitResult(i, resultFilter.getFitResults()[i]);
            }
            sliceResults.clear();
            sliceResults.addAll(resultFilter.getResults());
        }
    }
    // Add the ROI bounds to the fitted peaks
    final float offsetx = cc.dataBounds.x;
    final float offsety = cc.dataBounds.y;
    for (int i = 0; i < sliceResults.size(); i++) {
        final PeakResult result = sliceResults.get(i);
        result.params[Gaussian2DFunction.X_POSITION] += offsetx;
        result.params[Gaussian2DFunction.Y_POSITION] += offsety;
    }
    this.results.addAll(sliceResults);
    finish(job, start);
}
Also used : Rectangle(java.awt.Rectangle) PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) PeakResult(gdsc.smlm.results.PeakResult) IdPeakResult(gdsc.smlm.results.IdPeakResult) ExtendedPeakResult(gdsc.smlm.results.ExtendedPeakResult) ImageExtractor(gdsc.core.utils.ImageExtractor) BlockAverageDataProcessor(gdsc.smlm.filters.BlockAverageDataProcessor) DistanceResultFilter(gdsc.smlm.engine.filter.DistanceResultFilter) SelectedResultStore(gdsc.smlm.results.filter.MultiPathFilter.SelectedResultStore) MaximaSpotFilter(gdsc.smlm.filters.MaximaSpotFilter) ResultFilter(gdsc.smlm.engine.filter.ResultFilter) DistanceResultFilter(gdsc.smlm.engine.filter.DistanceResultFilter) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter) IMultiPathFitResults(gdsc.smlm.results.filter.IMultiPathFitResults)

Example 74 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class FitWorker method addSingleResult.

/**
	 * Add the result to the list. Only check for duplicates in the current results grid.
	 *
	 * @param candidateId
	 *            the candidate id
	 * @param peakParams
	 *            the peak params
	 * @param peakParamsDev
	 *            the peak params dev
	 * @param error
	 *            the error
	 * @param noise
	 *            the noise
	 * @return true, if successful
	 */
private boolean addSingleResult(int candidateId, float[] peakParams, float[] peakParamsDev, double error, float noise) {
    int x = candidates.get(candidateId).x;
    int y = candidates.get(candidateId).y;
    float value = data[y * cc.dataBounds.width + x];
    // This is obsolete as the multipathfilter now performs duplicate testing 
    //if (duplicateDistance2 > 0)
    //{
    //	// Check for duplicates
    //	final PeakResult[] neighbours = gridManager.getPeakResultNeighbours(x, y);
    //	for (int i = 0; i < neighbours.length; i++)
    //	{
    //		if (distance2(neighbours[i].params, peakParams) < duplicateDistance2)
    //		{
    //			if (logger != null)
    //				logger.info("[%d] Ignoring duplicate peak @ %.2f,%.2f", slice,
    //						peakParams[Gaussian2DFunction.X_POSITION], peakParams[Gaussian2DFunction.Y_POSITION]);
    //			//System.out.printf("Duplicate [%d] %.2f,%.2f == %.2f,%.2f\n", candidateId,
    //			//		peakParams[Gaussian2DFunction.X_POSITION], peakParams[Gaussian2DFunction.Y_POSITION], 
    //			//		neighbours[i].params[Gaussian2DFunction.X_POSITION], neighbours[i].params[Gaussian2DFunction.Y_POSITION]);
    //			return false;
    //		}
    //	}
    //}
    // Update to the global bounds.
    // (Note the global bounds will be added to the params at the end of processing the frame
    // so we leave those untouched)
    x = cc.fromDataToGlobalX(x);
    y = cc.fromDataToGlobalY(y);
    // This was fit OK so add it to the grid of results (so we do not fit it again)
    final PeakResult peakResult = createResult(x, y, value, error, noise, peakParams, peakParamsDev, candidateId);
    queueToGrid(peakResult);
    candidates.get(candidateId).fit = true;
    // Check if the position is inside the border tolerance
    if (insideBorder(peakParams[Gaussian2DFunction.X_POSITION], peakParams[Gaussian2DFunction.Y_POSITION])) {
        sliceResults.add(peakResult);
        fittedBackground += peakParams[Gaussian2DFunction.BACKGROUND];
    } else if (logger != null) {
        logger.info("[%d] Ignoring peak within image border @ %.2f,%.2f", slice, peakParams[Gaussian2DFunction.X_POSITION], peakParams[Gaussian2DFunction.Y_POSITION]);
    }
    return true;
}
Also used : PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) PeakResult(gdsc.smlm.results.PeakResult) IdPeakResult(gdsc.smlm.results.IdPeakResult) ExtendedPeakResult(gdsc.smlm.results.ExtendedPeakResult)

Example 75 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class FitWorker method add.

/*
	 * (non-Javadoc)
	 * 
	 * @see gdsc.smlm.results.filter.MultiPathFilter.SelectedResultStore#add(gdsc.smlm.results.filter.MultiPathFilter.
	 * SelectedResult)
	 */
public void add(SelectedResult selectedResult) {
    // TODO - Print the current state of the dynamicMultiPathFitResult to file.
    // This will allow debugging what is different between the benchmark fit and the PeakFit.
    // Output:
    // slice
    // candidate Id
    // Initial and final params for each fit result.
    // Details of the selected result.
    // Then try to figure out why the benchmark fit deviates from PeakFit.
    // Add to the slice results.
    final PreprocessedPeakResult[] results = selectedResult.results;
    if (results == null)
        return;
    final int currrentSize = sliceResults.size();
    final int candidateId = dynamicMultiPathFitResult.candidateId;
    final FitResult fitResult = (FitResult) selectedResult.fitResult.data;
    // The background for each result was the local background. We want the fitted global background
    final float background = (float) fitResult.getParameters()[0];
    final double[] dev = fitResult.getParameterStdDev();
    if (queueSize != 0)
        throw new RuntimeException("There are results queued already!");
    for (int i = 0; i < results.length; i++) {
        if (results[i].isExistingResult())
            continue;
        if (results[i].isNewResult()) {
            final double[] p = results[i].toGaussian2DParameters();
            // Store slice results relative to the data frame (not the global bounds)
            // Convert back so that 0,0 is the top left of the data bounds
            p[Gaussian2DFunction.X_POSITION] -= cc.dataBounds.x;
            p[Gaussian2DFunction.Y_POSITION] -= cc.dataBounds.y;
            final float[] params = new float[7];
            params[Gaussian2DFunction.BACKGROUND] = background;
            for (int j = 1; j < 7; j++) params[j] = (float) p[j];
            final float[] paramsDev;
            if (dev == null) {
                paramsDev = null;
            } else {
                paramsDev = new float[7];
                paramsDev[Gaussian2DFunction.BACKGROUND] = (float) dev[Gaussian2DFunction.BACKGROUND];
                final int offset = results[i].getId() * 6;
                for (int j = 1; j < 7; j++) paramsDev[j] = (float) dev[offset + j];
            }
            addSingleResult(results[i].getCandidateId(), params, paramsDev, fitResult.getError(), results[i].getNoise());
            if (logger != null) {
                // Show the shift, signal and width spread
                PreprocessedPeakResult peak = results[i];
                logger.info("Fit OK %d (%.1f,%.1f) [%d]: Shift = %.3f,%.3f : SNR = %.2f : Width = %.2f,%.2f", peak.getCandidateId(), peak.getX(), peak.getY(), peak.getId(), Math.sqrt(peak.getXRelativeShift2()), Math.sqrt(peak.getYRelativeShift2()), peak.getSNR(), peak.getXSDFactor(), peak.getYSDFactor());
            }
        } else {
        // This is a candidate that passed validation. Store the estimate as passing the primary filter.
        // We now do this is the pass() method.
        //storeEstimate(results[i].getCandidateId(), results[i], FILTER_RANK_PRIMARY);
        }
    }
    job.setFitResult(candidateId, fitResult);
    // Reporting
    if (this.counter != null) {
        FitType fitType = dynamicMultiPathFitResult.fitType;
        if (selectedResult.fitResult.getStatus() == 0) {
            fitType.setOK(true);
            if (dynamicMultiPathFitResult.getSuperMultiFitResult() == selectedResult.fitResult)
                fitType.setMultiOK(true);
            else if (dynamicMultiPathFitResult.getSuperMultiDoubletFitResult() == selectedResult.fitResult)
                fitType.setMultiDoubletOK(true);
            else if (dynamicMultiPathFitResult.getSuperDoubletFitResult() == selectedResult.fitResult)
                fitType.setDoubletOK(true);
        }
        add(fitType);
    }
    if (logger != null) {
        switch(fitResult.getStatus()) {
            case OK:
                // We log good results in the loop above. 
                break;
            case BAD_PARAMETERS:
            case FAILED_TO_ESTIMATE_WIDTH:
                logger.info("Bad parameters: %s", Arrays.toString(fitResult.getInitialParameters()));
                break;
            default:
                logger.info(fitResult.getStatus().toString());
                break;
        }
    }
    // Debugging
    if (logger2 != null) {
        double[] peakParams = fitResult.getParameters();
        if (peakParams != null) {
            // Parameters are the raw values from fitting the region. Convert for logging.
            peakParams = Arrays.copyOf(peakParams, peakParams.length);
            int npeaks = peakParams.length / 6;
            for (int i = 0; i < npeaks; i++) {
                peakParams[i * 6 + Gaussian2DFunction.X_POSITION] += cc.fromFitRegionToGlobalX();
                peakParams[i * 6 + Gaussian2DFunction.Y_POSITION] += cc.fromFitRegionToGlobalY();
                peakParams[i * 6 + Gaussian2DFunction.SHAPE] *= 180.0 / Math.PI;
            }
        }
        final int x = candidates.get(candidateId).x;
        final int y = candidates.get(candidateId).y;
        logger2.debug("%d:%d [%d,%d] %s (%s) = %s\n", slice, candidateId, cc.fromDataToGlobalX(x), cc.fromDataToGlobalY(y), fitResult.getStatus(), fitResult.getStatusData(), Arrays.toString(peakParams));
    }
    // Check if there were any new results
    int npeaks = sliceResults.size() - currrentSize;
    if (npeaks != 0) {
        success++;
        // Support for post-processing filter 
        if (resultFilter != null) {
            // Check all result peaks for the distance to the filter positions
            PeakResult[] peakResults = new PeakResult[npeaks];
            for (int i = sliceResults.size(); npeaks-- > 0; ) {
                peakResults[npeaks] = sliceResults.get(--i);
            }
            resultFilter.filter(fitResult, candidateId, peakResults);
        }
    }
}
Also used : PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) FitResult(gdsc.smlm.fitting.FitResult) MultiPathFitResult(gdsc.smlm.results.filter.MultiPathFitResult) PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) PeakResult(gdsc.smlm.results.PeakResult) IdPeakResult(gdsc.smlm.results.IdPeakResult) ExtendedPeakResult(gdsc.smlm.results.ExtendedPeakResult)

Aggregations

PeakResult (gdsc.smlm.results.PeakResult)89 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)40 ExtendedPeakResult (gdsc.smlm.results.ExtendedPeakResult)18 Rectangle (java.awt.Rectangle)18 ArrayList (java.util.ArrayList)17 IdPeakResult (gdsc.smlm.results.IdPeakResult)13 ImagePlus (ij.ImagePlus)9 Point (java.awt.Point)9 Trace (gdsc.smlm.results.Trace)8 ImageStack (ij.ImageStack)7 FractionClassificationResult (gdsc.core.match.FractionClassificationResult)6 Calibration (gdsc.smlm.results.Calibration)6 PreprocessedPeakResult (gdsc.smlm.results.filter.PreprocessedPeakResult)6 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)6 BasePoint (gdsc.core.match.BasePoint)5 Statistics (gdsc.core.utils.Statistics)5 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)5 IJImagePeakResults (gdsc.smlm.ij.results.IJImagePeakResults)5 GenericDialog (ij.gui.GenericDialog)5 ImageProcessor (ij.process.ImageProcessor)5