Search in sources :

Example 6 with MultiPathFilter

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

the class BenchmarkFilterAnalysis method showOverlay.

/**
	 * Show overlay.
	 *
	 * @param allAssignments
	 *            The assignments generated from running the filter (or null)
	 * @param filter
	 *            the filter
	 * @return The results from running the filter (or null)
	 */
private PreprocessedPeakResult[] showOverlay(ArrayList<FractionalAssignment[]> allAssignments, DirectFilter filter) {
    ImagePlus imp = CreateData.getImage();
    if (imp == null)
        return null;
    // Run the filter manually to get the results that pass.
    if (allAssignments == null)
        allAssignments = getAssignments(filter);
    final Overlay o = new Overlay();
    // Do TP
    final TIntHashSet actual = new TIntHashSet();
    final TIntHashSet predicted = new TIntHashSet();
    //int tp = 0, fp = 0, fn = 0;
    for (FractionalAssignment[] assignments : allAssignments) {
        if (assignments == null || assignments.length == 0)
            continue;
        float[] tx = null, ty = null;
        int t = 0;
        //tp += assignments.length;
        if (showTP) {
            tx = new float[assignments.length];
            ty = new float[assignments.length];
        }
        int frame = 0;
        for (int i = 0; i < assignments.length; i++) {
            CustomFractionalAssignment c = (CustomFractionalAssignment) assignments[i];
            IdPeakResult peak = (IdPeakResult) c.peak;
            BasePreprocessedPeakResult spot = (BasePreprocessedPeakResult) c.peakResult;
            actual.add(peak.uniqueId);
            predicted.add(spot.getUniqueId());
            frame = spot.getFrame();
            if (showTP) {
                tx[t] = spot.getX();
                ty[t++] = spot.getY();
            }
        }
        if (showTP)
            SpotFinderPreview.addRoi(frame, o, tx, ty, t, Color.green);
    }
    float[] x = new float[10];
    float[] y = new float[x.length];
    float[] x2 = new float[10];
    float[] y2 = new float[x2.length];
    // Do FP (all remaining results that are not a TP)
    PreprocessedPeakResult[] filterResults = null;
    if (showFP) {
        final MultiPathFilter multiPathFilter = createMPF(filter, minimalFilter);
        //multiPathFilter.setDebugFile("/tmp/filter.txt");
        filterResults = filterResults(multiPathFilter);
        int frame = 0;
        int c = 0;
        int c2 = 0;
        for (int i = 0; i < filterResults.length; i++) {
            if (frame != filterResults[i].getFrame()) {
                if (c != 0)
                    SpotFinderPreview.addRoi(frame, o, x, y, c, Color.red);
                if (c2 != 0)
                    SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
                c = c2 = 0;
            }
            frame = filterResults[i].getFrame();
            if (predicted.contains(filterResults[i].getUniqueId()))
                continue;
            if (filterResults[i].ignore()) {
                if (x2.length == c2) {
                    x2 = Arrays.copyOf(x2, c2 * 2);
                    y2 = Arrays.copyOf(y2, c2 * 2);
                }
                x2[c2] = filterResults[i].getX();
                y2[c2++] = filterResults[i].getY();
            } else {
                if (x.length == c) {
                    x = Arrays.copyOf(x, c * 2);
                    y = Arrays.copyOf(y, c * 2);
                }
                x[c] = filterResults[i].getX();
                y[c++] = filterResults[i].getY();
            }
        }
        //fp += c;
        if (c != 0)
            SpotFinderPreview.addRoi(frame, o, x, y, c, Color.red);
        if (c2 != 0)
            SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
    }
    // Do TN (all remaining peaks that have not been matched)
    if (showFN) {
        final boolean checkBorder = (BenchmarkSpotFilter.lastAnalysisBorder != null && BenchmarkSpotFilter.lastAnalysisBorder.x != 0);
        final float border, xlimit, ylimit;
        if (checkBorder) {
            final Rectangle lastAnalysisBorder = BenchmarkSpotFilter.lastAnalysisBorder;
            border = lastAnalysisBorder.x;
            xlimit = lastAnalysisBorder.x + lastAnalysisBorder.width;
            ylimit = lastAnalysisBorder.y + lastAnalysisBorder.height;
        } else
            border = xlimit = ylimit = 0;
        // Add the results to the lists
        actualCoordinates.forEachEntry(new CustomTIntObjectProcedure(x, y, x2, y2) {

            public boolean execute(int frame, IdPeakResult[] results) {
                int c = 0, c2 = 0;
                if (x.length <= results.length) {
                    x = new float[results.length];
                    y = new float[results.length];
                }
                if (x2.length <= results.length) {
                    x2 = new float[results.length];
                    y2 = new float[results.length];
                }
                for (int i = 0; i < results.length; i++) {
                    // Ignore those that were matched by TP
                    if (actual.contains(results[i].uniqueId))
                        continue;
                    if (checkBorder && outsideBorder(results[i], border, xlimit, ylimit)) {
                        x2[c2] = results[i].getXPosition();
                        y2[c2++] = results[i].getYPosition();
                    } else {
                        x[c] = results[i].getXPosition();
                        y[c++] = results[i].getYPosition();
                    }
                }
                //fn += c;
                if (c != 0)
                    SpotFinderPreview.addRoi(frame, o, x, y, c, Color.yellow);
                if (c2 != 0)
                    SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.orange);
                return true;
            }
        });
    }
    //System.out.printf("TP=%d, FP=%d, FN=%d, N=%d (%d)\n", tp, fp, fn, tp + fn, results.size());
    imp.setOverlay(o);
    return filterResults;
}
Also used : BasePreprocessedPeakResult(gdsc.smlm.results.filter.BasePreprocessedPeakResult) Rectangle(java.awt.Rectangle) ImagePlus(ij.ImagePlus) TIntHashSet(gnu.trove.set.hash.TIntHashSet) FractionalAssignment(gdsc.core.match.FractionalAssignment) PeakFractionalAssignment(gdsc.smlm.results.filter.PeakFractionalAssignment) BasePreprocessedPeakResult(gdsc.smlm.results.filter.BasePreprocessedPeakResult) PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter) Overlay(ij.gui.Overlay)

Example 7 with MultiPathFilter

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

the class BenchmarkFilterAnalysis method scoreFilter.

private ParameterScoreResult scoreFilter(DirectFilter filter, DirectFilter minFilter, int failCount, double residualsThreshold, double duplicateDistance, CoordinateStore coordinateStore, boolean createTextResult) {
    final MultiPathFilter multiPathFilter = new MultiPathFilter(filter, minFilter, residualsThreshold);
    final FractionClassificationResult r = multiPathFilter.fractionScoreSubset(ga_resultsListToScore, failCount, nActual, null, null, coordinateStore);
    final double score = getScore(r);
    final double criteria = getCriteria(r);
    // Create the score output
    final String text = (createTextResult && criteria >= minCriteria) ? createResult(filter, r, buildResultsPrefix2(failCount, residualsThreshold, duplicateDistance)).toString() : null;
    double[] parameters = new double[] { failCount, residualsThreshold, duplicateDistance };
    return new ParameterScoreResult(score, criteria, parameters, text);
}
Also used : FractionClassificationResult(gdsc.core.match.FractionClassificationResult) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter)

Example 8 with MultiPathFilter

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

the class BenchmarkSpotFit method run.

/**
	 * Run the analysis non-interactively using the given filter settings.
	 *
	 * @param filter
	 *            the filter
	 * @param residualsThreshold
	 *            the residuals threshold
	 * @param failuresLimit
	 *            the failures limit
	 * @param duplicateDistance
	 *            the duplicate distance
	 */
public void run(DirectFilter filter, double residualsThreshold, int failuresLimit, double duplicateDistance) {
    multiFilter = new MultiPathFilter(filter, minimalFilter, residualsThreshold);
    config.setFailuresLimit(failuresLimit);
    fitConfig.setDuplicateDistance(duplicateDistance);
    clearFitResults();
    silent = true;
    if (!initialise())
        return;
    run();
}
Also used : MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter)

Example 9 with MultiPathFilter

use of gdsc.smlm.results.filter.MultiPathFilter 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)

Aggregations

MultiPathFilter (gdsc.smlm.results.filter.MultiPathFilter)9 FitConfiguration (gdsc.smlm.fitting.FitConfiguration)4 PreprocessedPeakResult (gdsc.smlm.results.filter.PreprocessedPeakResult)4 BasePoint (gdsc.core.match.BasePoint)3 FractionalAssignment (gdsc.core.match.FractionalAssignment)3 FitEngineConfiguration (gdsc.smlm.engine.FitEngineConfiguration)3 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)3 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)3 BasePreprocessedPeakResult (gdsc.smlm.results.filter.BasePreprocessedPeakResult)3 DirectFilter (gdsc.smlm.results.filter.DirectFilter)3 PeakFractionalAssignment (gdsc.smlm.results.filter.PeakFractionalAssignment)3 FractionClassificationResult (gdsc.core.match.FractionClassificationResult)2 GlobalSettings (gdsc.smlm.ij.settings.GlobalSettings)2 TIntHashSet (gnu.trove.set.hash.TIntHashSet)2 Checkbox (java.awt.Checkbox)2 Rectangle (java.awt.Rectangle)2 ImmutableFractionalAssignment (gdsc.core.match.ImmutableFractionalAssignment)1 FastCorrelator (gdsc.core.utils.FastCorrelator)1 ImageExtractor (gdsc.core.utils.ImageExtractor)1 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)1