Search in sources :

Example 51 with PeakResult

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

the class ImageJ3DResultsViewer method createSphereSizeFromDeviations.

@Nullable
private static Point3f[] createSphereSizeFromDeviations(MemoryPeakResults results) {
    if (!results.hasDeviations()) {
        IJ.error(TITLE, "The results have no deviations");
        return null;
    }
    // Currently the rendering is in nm
    final TypeConverter<DistanceUnit> dc = results.getDistanceConverter(DistanceUnit.NM);
    final Point3f[] size = new Point3f[results.size()];
    final boolean failed = results.forEach(new PeakResultProcedureX() {

        int index;

        @Override
        public boolean execute(PeakResult peakResult) {
            final float x = peakResult.getParameterDeviation(PeakResult.X);
            final float y = peakResult.getParameterDeviation(PeakResult.Y);
            float z = peakResult.getParameterDeviation(PeakResult.Z);
            // This should be OK as 2D fitting should provide these.
            if (x == 0 || y == 0) {
                return true;
            }
            if (z == 0) {
                // Mean variance
                z = (float) Math.sqrt((x * x + y * y) / 2);
            }
            // z = (x + y) / 2; // Mean Std Dev
            size[index++] = new Point3f(dc.convert(x), dc.convert(y), dc.convert(z));
            return false;
        }
    });
    return (failed) ? null : size;
}
Also used : Point3f(org.scijava.vecmath.Point3f) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) PeakResultProcedureX(uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedureX) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 52 with PeakResult

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

the class ImageJ3DResultsViewer method reorder.

private static void reorder(int[] indices, ResultsMetaData data) {
    final MemoryPeakResults results = data.results;
    final LocalList<Point3f> points = data.points;
    final PeakResult[] originalPeakResults = results.toArray();
    final Point3f[] originalPoints = points.toArray(new Point3f[0]);
    // We need another array to store the output
    final PeakResult[] peakResults = new PeakResult[originalPeakResults.length];
    // Rewrite order
    for (int i = 0; i < indices.length; i++) {
        final int index = indices[i];
        points.unsafeSet(i, originalPoints[index]);
        peakResults[i] = originalPeakResults[index];
    }
    // Bulk update the results
    results.setSortAfterEnd(false);
    results.begin();
    results.addAll(peakResults);
    results.end();
    final Point3f[] sizes = data.sizes;
    if (sizes.length == indices.length) {
        final Point3f[] originalSizes = sizes.clone();
        // Rewrite order
        for (int i = 0; i < indices.length; i++) {
            final int index = indices[i];
            sizes[i] = originalSizes[index];
        }
    }
}
Also used : Point3f(org.scijava.vecmath.Point3f) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult)

Example 53 with PeakResult

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

the class FilterResults method filterResults.

/**
 * Apply the filters to the data.
 */
private void filterResults() {
    checkLimits();
    final MemoryPeakResults newResults = new MemoryPeakResults();
    newResults.copySettings(results);
    newResults.setName(results.getName() + " Filtered");
    // Initialise the mask
    CoordFilter maskFilter;
    final ImagePlus maskImp = WindowManager.getImage(filterSettings.getMaskTitle());
    if (maskImp != null) {
        final int maxx = maskImp.getWidth();
        final int maxy = maskImp.getHeight();
        final Rectangle bounds = results.getBounds();
        final double ox = bounds.getX();
        final double oy = bounds.getY();
        final double scaleX = bounds.getWidth() / maxx;
        final double scaleY = bounds.getHeight() / maxy;
        // Improve to allow stacks
        if (maskImp.getStackSize() > 1) {
            // 3D filter. The frame is mapped to the stack index.
            final ImageStack stack = maskImp.getImageStack();
            final ImageProcessor ip = stack.getProcessor(1);
            maskFilter = (t, x, y) -> {
                // Check stack index
                if (t >= 1 && t <= stack.size()) {
                    int ix = (int) ((x - ox) / scaleX);
                    int iy = (int) ((y - oy) / scaleY);
                    if (ix >= 0 && ix < maxx && iy >= 0 && iy < maxy) {
                        ip.setPixels(stack.getPixels(t));
                        return ip.get(iy * maxx + ix) != 0;
                    }
                }
                return false;
            };
        } else {
            // 2D filter.
            final ImageProcessor ip = maskImp.getProcessor();
            maskFilter = (t, x, y) -> {
                int ix = (int) ((x - ox) / scaleX);
                int iy = (int) ((y - oy) / scaleY);
                return (ix >= 0 && ix < maxx && iy >= 0 && iy < maxy && ip.get(iy * maxx + ix) != 0);
            };
        }
    } else {
        maskFilter = (t, x, y) -> true;
    }
    // Create the ticker with size+1 as we tick at the start of the loop
    final Ticker ticker = ImageJUtils.createTicker(results.size() + 1, 0);
    for (int i = 0, size = results.size(); i < size; i++) {
        ticker.tick();
        // We stored the drift=z, intensity=signal, background=snr
        if (sp.z[i] > filterSettings.getMaxDrift()) {
            continue;
        }
        if (sp.intensity[i] < filterSettings.getMinSignal()) {
            continue;
        }
        if (sp.background[i] < filterSettings.getMinSnr()) {
            continue;
        }
        final PeakResult peakResult = sp.peakResults[i];
        // Check the coordinates are inside the mask
        if (!maskFilter.match(peakResult.getFrame(), sp.x[i], sp.y[i])) {
            continue;
        }
        if (pp != null && pp.precisions[i] > maxPrecision) {
            continue;
        }
        if (wp != null) {
            final float width = wp.wx[i];
            if (width < filterSettings.getMinWidth() || width > filterSettings.getMaxWidth()) {
                continue;
            }
        }
        // Passed all filters. Add to the results
        newResults.add(peakResult);
    }
    ImageJUtils.finished(TextUtils.pleural(newResults.size(), "Filtered localisation"));
    MemoryPeakResults.addResults(newResults);
}
Also used : ImageProcessor(ij.process.ImageProcessor) ImageStack(ij.ImageStack) Ticker(uk.ac.sussex.gdsc.core.logging.Ticker) Rectangle(java.awt.Rectangle) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) ImagePlus(ij.ImagePlus) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult)

Example 54 with PeakResult

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

the class FilterResults method analyseResults.

/**
 * Analyse the results and determine the range for each filter.
 */
private boolean analyseResults() {
    IJ.showStatus("Analysing results ...");
    final ArrayList<String> error = new ArrayList<>();
    try {
        wp = new WidthResultProcedure(results, DistanceUnit.PIXEL);
        wp.getW();
        final float[] limits = MathUtils.limits(wp.wx);
        maxWidth = limits[1];
        minWidth = limits[0];
        averageWidth = MathUtils.sum(wp.wx) / wp.size();
    } catch (final DataException ex) {
        error.add(ex.getMessage());
        wp = null;
        maxWidth = minWidth = 0;
    }
    try {
        pp = new PrecisionResultProcedure(results);
        pp.getPrecision();
        final double[] limits = MathUtils.limits(pp.precisions);
        maxPrecision = limits[1];
        minPrecision = limits[0];
    } catch (final DataException ex) {
        error.add(ex.getMessage());
        pp = null;
        maxPrecision = minPrecision = 0;
    }
    try {
        sp = new StandardResultProcedure(results, DistanceUnit.PIXEL);
        sp.getXyr();
        // Re-use for convenience
        sp.intensity = new float[sp.x.length];
        sp.background = new float[sp.x.length];
        sp.z = new float[sp.x.length];
        for (int i = 0; i < sp.size(); i++) {
            if (i % 64 == 0) {
                IJ.showProgress(i, sp.size());
            }
            final PeakResult result = sp.peakResults[i];
            final float drift = getDrift(result, sp.x[i], sp.y[i]);
            if (maxDrift < drift) {
                maxDrift = drift;
            }
            if (minDrift > drift) {
                minDrift = drift;
            }
            final float signal = result.getIntensity();
            if (maxSignal < signal) {
                maxSignal = signal;
            }
            if (minSignal > signal) {
                minSignal = signal;
            }
            final float snr = getSnr(result);
            if (maxSnr < snr) {
                maxSnr = snr;
            }
            if (minSnr > snr) {
                minSnr = snr;
            }
            // for convenience
            sp.z[i] = drift;
            sp.intensity[i] = signal;
            sp.background[i] = snr;
        }
    } catch (final DataException ex) {
        error.add(ex.getMessage());
        sp = null;
    }
    if (error.size() == 3 || sp == null) {
        final StringBuilder sb = new StringBuilder("Unable to analyse the results:\n");
        for (final String s : error) {
            sb.append(s).append(".\n");
        }
        IJ.error(TITLE, sb.toString());
        return false;
    }
    ImageJUtils.finished();
    return true;
}
Also used : ArrayList(java.util.ArrayList) WidthResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.WidthResultProcedure) PrecisionResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.PrecisionResultProcedure) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) DataException(uk.ac.sussex.gdsc.core.data.DataException) StandardResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.StandardResultProcedure)

Example 55 with PeakResult

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

the class DrawClusters method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(TITLE, "No localisations in memory");
        return;
    }
    if (!showDialog()) {
        return;
    }
    // Load the results
    final MemoryPeakResults results = ResultsManager.loadInputResults(settings.inputOption, false, DistanceUnit.PIXEL);
    if (MemoryPeakResults.isEmpty(results)) {
        IJ.error(TITLE, "No results could be loaded");
        return;
    }
    // Get the traces
    final Trace[] traces = TraceManager.convert(results);
    if (traces == null || traces.length == 0) {
        IJ.error(TITLE, "No traces could be loaded");
        return;
    }
    // Filter traces to a min size
    int maxFrame = 0;
    int count = 0;
    final int myMaxSize = (settings.maxSize < settings.minSize) ? Integer.MAX_VALUE : settings.maxSize;
    final boolean myDrawLines = myMaxSize > 1 && settings.drawLines;
    for (int i = 0; i < traces.length; i++) {
        if (settings.expandToSingles) {
            traces[i].expandToSingles();
        }
        if (traces[i].size() >= settings.minSize && traces[i].size() <= myMaxSize) {
            traces[count++] = traces[i];
            traces[i].sort();
            if (maxFrame < traces[i].getTail().getFrame()) {
                maxFrame = traces[i].getTail().getFrame();
            }
        }
    }
    if (count == 0) {
        IJ.error(TITLE, "No traces achieved the size limits");
        return;
    }
    final String msg = String.format(TITLE + ": %d / %s (%s)", count, TextUtils.pleural(traces.length, "trace"), TextUtils.pleural(results.size(), "localisation"));
    IJ.showStatus(msg);
    final Rectangle bounds = results.getBounds(true);
    ImagePlus imp = WindowManager.getImage(settings.title);
    boolean isUseStackPosition = settings.useStackPosition;
    if (imp == null) {
        // Create a default image using 100 pixels as the longest edge
        final double maxD = (bounds.width > bounds.height) ? bounds.width : bounds.height;
        int width;
        int height;
        if (maxD == 0) {
            // Note that imageSize can be zero (for auto sizing)
            width = height = (settings.imageSize == 0) ? 20 : settings.imageSize;
        } else if (settings.imageSize == 0) {
            // Note that imageSize can be zero (for auto sizing)
            width = bounds.width;
            height = bounds.height;
        } else {
            width = (int) (settings.imageSize * bounds.width / maxD);
            height = (int) (settings.imageSize * bounds.height / maxD);
        }
        final ByteProcessor bp = new ByteProcessor(width, height);
        if (isUseStackPosition) {
            final ImageStack stack = new ImageStack(width, height, maxFrame);
            for (int i = 1; i <= maxFrame; i++) {
                // Do not clone as the image is empty
                stack.setPixels(bp.getPixels(), i);
            }
            imp = ImageJUtils.display(TITLE, stack);
        } else {
            imp = ImageJUtils.display(TITLE, bp);
        }
        // Enlarge
        final ImageWindow iw = imp.getWindow();
        for (int i = 9; i-- > 0 && iw.getWidth() < 500 && iw.getHeight() < 500; ) {
            iw.getCanvas().zoomIn(imp.getWidth() / 2, imp.getHeight() / 2);
        }
    // Check if the image has enough frames for all the traces
    } else if (maxFrame > imp.getNFrames()) {
        isUseStackPosition = false;
    }
    final float xScale = (float) (imp.getWidth() / bounds.getWidth());
    final float yScale = (float) (imp.getHeight() / bounds.getHeight());
    // Create ROIs and store data to sort them
    final Roi[] rois = new Roi[count];
    final int[][] frames = (isUseStackPosition) ? new int[count][] : null;
    final int[] indices = SimpleArrayUtils.natural(count);
    final double[] values = new double[count];
    for (int i = 0; i < count; i++) {
        final Trace trace = traces[i];
        final int npoints = trace.size();
        final float[] xpoints = new float[npoints];
        final float[] ypoints = new float[npoints];
        int ii = 0;
        if (frames != null) {
            frames[i] = new int[npoints];
        }
        for (int k = 0; k < trace.size(); k++) {
            final PeakResult result = trace.get(k);
            xpoints[ii] = (result.getXPosition() - bounds.x) * xScale;
            ypoints[ii] = (result.getYPosition() - bounds.y) * yScale;
            if (frames != null) {
                frames[i][ii] = result.getFrame();
            }
            ii++;
        }
        Roi roi;
        if (myDrawLines) {
            roi = new PolygonRoi(xpoints, ypoints, npoints, Roi.POLYLINE);
            if (settings.splineFit) {
                ((PolygonRoi) roi).fitSpline();
            }
        } else {
            roi = new OffsetPointRoi(xpoints, ypoints, npoints);
            ((PointRoi) roi).setShowLabels(false);
        }
        rois[i] = roi;
        switch(settings.sort) {
            case // Sort by ID
            1:
                values[i] = traces[i].getId();
                break;
            case // Sort by time
            2:
                values[i] = traces[i].getHead().getFrame();
                break;
            case // Sort by size descending
            3:
                values[i] = -traces[i].size();
                break;
            case // Sort by length descending
            4:
                values[i] = -roi.getLength();
                break;
            case // Mean Square Displacement
            5:
                values[i] = -traces[i].getMsd();
                break;
            case // Mean / Frame
            6:
                values[i] = -traces[i].getMeanDistance();
                break;
            // No sort
            case 0:
            default:
                break;
        }
    }
    if (settings.sort > 0) {
        SortUtils.sortIndices(indices, values, true);
    }
    // Draw the traces as ROIs on an overlay
    final Overlay o = new Overlay();
    final LUT lut = LutHelper.createLut(settings.lut);
    final double scale = 256.0 / count;
    if (frames != null) {
        // Add the tracks on the frames containing the results
        final boolean isHyperStack = imp.isDisplayedHyperStack();
        for (int i = 0; i < count; i++) {
            final int index = indices[i];
            final Color c = LutHelper.getColour(lut, (int) (i * scale));
            final PolygonRoi roi = (PolygonRoi) rois[index];
            roi.setFillColor(c);
            roi.setStrokeColor(c);
            // roi.setStrokeWidth(settings.lineWidth);
            roi.updateWideLine(settings.lineWidth);
            final FloatPolygon fp = roi.getNonSplineFloatPolygon();
            // For each frame in the track, add the ROI track and a point ROI for the current position
            for (int j = 0; j < frames[index].length; j++) {
                addToOverlay(o, (Roi) roi.clone(), isHyperStack, frames[index][j]);
                final PointRoi pointRoi = new OffsetPointRoi(fp.xpoints[j], fp.ypoints[j]);
                pointRoi.setPointType(3);
                pointRoi.setFillColor(c);
                pointRoi.setStrokeColor(Color.black);
                addToOverlay(o, pointRoi, isHyperStack, frames[index][j]);
            }
        }
    } else {
        // Add the tracks as a single overlay
        for (int i = 0; i < count; i++) {
            final Roi roi = rois[indices[i]];
            roi.setStrokeColor(new Color(lut.getRGB((int) (i * scale))));
            // roi.setStrokeWidth(settings.lineWidth);
            roi.updateWideLine(settings.lineWidth);
            o.add(roi);
        }
    }
    imp.setOverlay(o);
    IJ.showStatus(msg);
}
Also used : ByteProcessor(ij.process.ByteProcessor) ImageWindow(ij.gui.ImageWindow) Rectangle(java.awt.Rectangle) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) PolygonRoi(ij.gui.PolygonRoi) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) Overlay(ij.gui.Overlay) PointRoi(ij.gui.PointRoi) OffsetPointRoi(uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi) ImageStack(ij.ImageStack) OffsetPointRoi(uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi) Color(java.awt.Color) LUT(ij.process.LUT) ImagePlus(ij.ImagePlus) PolygonRoi(ij.gui.PolygonRoi) PointRoi(ij.gui.PointRoi) OffsetPointRoi(uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi) Roi(ij.gui.Roi) Trace(uk.ac.sussex.gdsc.smlm.results.Trace) FloatPolygon(ij.process.FloatPolygon)

Aggregations

PeakResult (uk.ac.sussex.gdsc.smlm.results.PeakResult)64 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)37 List (java.util.List)18 LocalList (uk.ac.sussex.gdsc.core.utils.LocalList)18 Rectangle (java.awt.Rectangle)17 Counter (uk.ac.sussex.gdsc.smlm.results.count.Counter)17 FrameCounter (uk.ac.sussex.gdsc.smlm.results.count.FrameCounter)17 PeakResultProcedure (uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure)17 ImagePlus (ij.ImagePlus)14 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)14 DistanceUnit (uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit)14 IJ (ij.IJ)13 ImageJUtils (uk.ac.sussex.gdsc.core.ij.ImageJUtils)12 PlugIn (ij.plugin.PlugIn)11 AtomicReference (java.util.concurrent.atomic.AtomicReference)10 SimpleArrayUtils (uk.ac.sussex.gdsc.core.utils.SimpleArrayUtils)10 SettingsManager (uk.ac.sussex.gdsc.smlm.ij.settings.SettingsManager)10 PointRoi (ij.gui.PointRoi)9 ArrayList (java.util.ArrayList)9 TypeConverter (uk.ac.sussex.gdsc.core.data.utils.TypeConverter)9