Search in sources :

Example 1 with ClusteringEngine

use of uk.ac.sussex.gdsc.core.clustering.ClusteringEngine in project GDSC-SMLM by aherbert.

the class PcPalmClusters method doClustering.

/**
 * Extract the results from the PCPALM molecules using the area ROI and then do clustering to
 * obtain the histogram of molecules per cluster.
 *
 * @return the histogram data
 */
private HistogramData doClustering() {
    // Perform clustering analysis to generate the histogram of cluster sizes
    final PcPalmAnalysis analysis = new PcPalmAnalysis();
    final List<Molecule> molecules = analysis.cropToRoi(WindowManager.getCurrentImage(), moleculesResults);
    if (molecules.size() < 2) {
        error("No results within the crop region");
        return null;
    }
    ImageJUtils.log("Using %d molecules (Density = %s um^-2) @ %s nm", molecules.size(), MathUtils.rounded(molecules.size() / analysis.croppedArea), MathUtils.rounded(settings.distance));
    final long s1 = System.nanoTime();
    final ClusteringEngine engine = new ClusteringEngine(1, clusteringAlgorithm, SimpleImageJTrackProgress.getInstance());
    if (settings.multiThread) {
        engine.setThreadCount(Prefs.getThreads());
    }
    engine.setTracker(SimpleImageJTrackProgress.getInstance());
    IJ.showStatus("Clustering ...");
    final List<Cluster> clusters = engine.findClusters(convertToPoint(molecules), settings.distance);
    IJ.showStatus("");
    if (clusters == null) {
        ImageJUtils.log("Aborted");
        return null;
    }
    numberOfMolecules = molecules.size();
    ImageJUtils.log("Finished : %d total clusters (%s ms)", clusters.size(), MathUtils.rounded((System.nanoTime() - s1) / 1e6));
    // Save cluster centroids to a results set in memory. Then they can be plotted.
    final MemoryPeakResults results = new MemoryPeakResults(clusters.size());
    results.setName(TITLE);
    // Set an arbitrary calibration so that the lifetime of the results is stored in the exposure
    // time
    // The results will be handled as a single mega-frame containing all localisation.
    results.setCalibration(CalibrationHelper.create(100, 1, moleculesResults.seconds * 1000));
    int id = 0;
    for (final Cluster c : clusters) {
        results.add(new ExtendedPeakResult((float) c.getX(), (float) c.getY(), c.getSize(), ++id));
    }
    MemoryPeakResults.addResults(results);
    // Get the data for fitting
    final float[] values = new float[clusters.size()];
    for (int i = 0; i < values.length; i++) {
        values[i] = clusters.get(i).getSize();
    }
    final float yMax = (int) Math.ceil(MathUtils.max(values));
    final int nBins = (int) (yMax + 1);
    final float[][] hist = HistogramPlot.calcHistogram(values, 0, yMax, nBins);
    final HistogramData histogramData = (settings.calibrateHistogram) ? new HistogramData(hist, settings.frames, settings.area, Settings.UNITS[settings.units]) : new HistogramData(hist);
    saveHistogram(histogramData);
    return histogramData;
}
Also used : ExtendedPeakResult(uk.ac.sussex.gdsc.smlm.results.ExtendedPeakResult) Cluster(uk.ac.sussex.gdsc.core.clustering.Cluster) ClusterPoint(uk.ac.sussex.gdsc.core.clustering.ClusterPoint) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) ClusteringEngine(uk.ac.sussex.gdsc.core.clustering.ClusteringEngine)

Example 2 with ClusteringEngine

use of uk.ac.sussex.gdsc.core.clustering.ClusteringEngine in project GDSC-SMLM by aherbert.

the class DarkTimeAnalysis method analyse.

private void analyse(MemoryPeakResults results) {
    // Find min and max time frames
    results.sort();
    final int min = results.getFirstFrame();
    final int max = results.getLastFrame();
    // Trace results:
    // TODO - The search distance could have units to avoid assuming the results are in pixels
    final double d = settings.searchDistance / results.getCalibrationReader().getNmPerPixel();
    int range = max - min + 1;
    if (settings.maxDarkTime > 0) {
        range = Math.max(1, (int) Math.round(settings.maxDarkTime * 1000 / msPerFrame));
    }
    final TrackProgress tracker = SimpleImageJTrackProgress.getInstance();
    tracker.status("Analysing ...");
    tracker.log("Analysing (d=%s nm (%s px) t=%s s (%d frames)) ...", MathUtils.rounded(settings.searchDistance), MathUtils.rounded(d), MathUtils.rounded(range * msPerFrame / 1000.0), range);
    Trace[] traces;
    if (settings.method == 0) {
        final TraceManager tm = new TraceManager(results);
        tm.setTracker(tracker);
        tm.traceMolecules(d, range);
        traces = tm.getTraces();
    } else {
        final ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), algorithms[settings.method - 1], tracker);
        final List<Cluster> clusters = engine.findClusters(TraceMolecules.convertToClusterPoints(results), d, range);
        traces = TraceMolecules.convertToTraces(results, clusters);
    }
    tracker.status("Computing histogram ...");
    // Build dark-time histogram
    final int[] times = new int[range];
    final StoredData stats = new StoredData();
    for (final Trace trace : traces) {
        if (trace.getBlinks() > 1) {
            for (final int t : trace.getOffTimes()) {
                times[t]++;
            }
            stats.add(trace.getOffTimes());
        }
    }
    plotDarkTimeHistogram(stats);
    // Cumulative histogram
    for (int i = 1; i < times.length; i++) {
        times[i] += times[i - 1];
    }
    final int total = times[times.length - 1];
    // Plot dark-time up to 100%
    double[] x = new double[range];
    double[] y = new double[range];
    int truncate = 0;
    for (int i = 0; i < x.length; i++) {
        x[i] = i * msPerFrame;
        if (times[i] == total) {
            // Final value at 100%
            y[i] = 100.0;
            truncate = i + 1;
            break;
        }
        y[i] = (100.0 * times[i]) / total;
    }
    if (truncate > 0) {
        x = Arrays.copyOf(x, truncate);
        y = Arrays.copyOf(y, truncate);
    }
    final String title = "Cumulative Dark-time";
    final Plot plot = new Plot(title, "Time (ms)", "Percentile");
    plot.addPoints(x, y, Plot.LINE);
    ImageJUtils.display(title, plot);
    // Report percentile
    for (int i = 0; i < y.length; i++) {
        if (y[i] >= settings.percentile) {
            ImageJUtils.log("Dark-time Percentile %.1f @ %s ms = %s s", settings.percentile, MathUtils.rounded(x[i]), MathUtils.rounded(x[i] / 1000));
            break;
        }
    }
    tracker.status("");
}
Also used : Plot(ij.gui.Plot) SimpleImageJTrackProgress(uk.ac.sussex.gdsc.core.ij.SimpleImageJTrackProgress) TrackProgress(uk.ac.sussex.gdsc.core.logging.TrackProgress) Cluster(uk.ac.sussex.gdsc.core.clustering.Cluster) TraceManager(uk.ac.sussex.gdsc.smlm.results.TraceManager) Trace(uk.ac.sussex.gdsc.smlm.results.Trace) StoredData(uk.ac.sussex.gdsc.core.utils.StoredData) ClusteringEngine(uk.ac.sussex.gdsc.core.clustering.ClusteringEngine)

Example 3 with ClusteringEngine

use of uk.ac.sussex.gdsc.core.clustering.ClusteringEngine in project GDSC-SMLM by aherbert.

the class TraceMolecules method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(pluginTitle, "No localisations in memory");
        return;
    }
    altKeyDown = ImageJUtils.isExtraOptions();
    Trace[] traces = null;
    int totalFiltered = 0;
    if ("dynamic".equals(arg)) {
        // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        // Dynamic Mutliple Target Tracing
        // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        outputName = "Dynamic Trace";
        if (!showDynamicTraceDialog()) {
            return;
        }
        final DmttConfiguration config = createDmttConfiguration();
        traces = new DynamicMultipleTargetTracing(results).traceMolecules(config).toArray(new Trace[0]);
    } else if ("cluster".equals(arg)) {
        // -=-=-=-=-=
        // Clustering
        // -=-=-=-=-=
        outputName = "Cluster";
        if (!showClusterDialog()) {
            return;
        }
        final ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), getClusteringAlgorithm(settings.getClusteringAlgorithm()), SimpleImageJTrackProgress.getInstance());
        if (settings.getSplitPulses()) {
            engine.setPulseInterval(settings.getPulseInterval());
            limitTimeThreshold(settings.getPulseInterval());
        }
        final List<Cluster> clusters = engine.findClusters(convertToClusterPoints(), getDistance(settings.getDistanceThreshold(), results.getCalibration()), timeThresholdInFrames());
        if (clusters == null) {
            ImageJUtils.log("Aborted");
            return;
        }
        traces = convertToTraces(clusters);
    } else {
        // -=-=-=-
        // Tracing
        // -=-=-=-
        outputName = "Trace";
        if (!showDialog()) {
            return;
        }
        final TraceManager manager = new TraceManager(results);
        manager.setTraceMode(getTraceMode(settings.getTraceMode()));
        manager.setActivationFrameInterval(settings.getPulseInterval());
        manager.setActivationFrameWindow(settings.getPulseWindow());
        manager.setDistanceExclusion(getDistance(settings.getDistanceExclusion(), results.getCalibration()));
        if (settings.getOptimise()) {
            // Optimise before configuring for a pulse interval
            runOptimiser(manager);
        }
        if (settings.getSplitPulses()) {
            manager.setPulseInterval(settings.getPulseInterval());
            limitTimeThreshold(settings.getPulseInterval());
        }
        manager.setTracker(SimpleImageJTrackProgress.getInstance());
        manager.traceMolecules(getDistance(settings.getDistanceThreshold(), results.getCalibration()), timeThresholdInFrames());
        traces = manager.getTraces();
        totalFiltered = manager.getTotalFiltered();
    }
    // --=-=-=-=-=-
    // Results processing
    // --=-=-=-=-=-
    outputName += (outputName.endsWith("e") ? "" : "e") + "d";
    saveResults(results, traces, outputName);
    // Save singles + single localisations in a trace
    saveCentroidResults(results, getSingles(traces), outputName + " Singles");
    final Trace[] multiTraces = getTraces(traces);
    saveResults(results, multiTraces, outputName + " Multi");
    // Save centroids
    outputName += " Centroids";
    final MemoryPeakResults tracedResults = saveCentroidResults(results, traces, outputName);
    // Save traces separately
    saveCentroidResults(results, multiTraces, outputName + " Multi");
    // Sort traces by time to assist the results source in extracting frames sequentially.
    // Do this before saving to assist in debugging using the saved traces file.
    sortByTime(traces);
    if (settings.getSaveTraces()) {
        saveTraces(traces);
    }
    summarise(createSummaryTable(), traces, totalFiltered, settings.getDistanceThreshold(), timeThresholdInSeconds());
    IJ.showStatus(String.format("%d localisations => %d traces (%d filtered)", results.size(), tracedResults.size(), totalFiltered));
}
Also used : Trace(uk.ac.sussex.gdsc.smlm.results.Trace) DmttConfiguration(uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration) DynamicMultipleTargetTracing(uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing) List(java.util.List) ArrayList(java.util.ArrayList) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) ClusteringEngine(uk.ac.sussex.gdsc.core.clustering.ClusteringEngine) TraceManager(uk.ac.sussex.gdsc.smlm.results.TraceManager) ClusterPoint(uk.ac.sussex.gdsc.core.clustering.ClusterPoint)

Example 4 with ClusteringEngine

use of uk.ac.sussex.gdsc.core.clustering.ClusteringEngine in project GDSC-SMLM by aherbert.

the class PcPalmMolecules method performDistanceAnalysis.

private void performDistanceAnalysis(double[][] intraHist, int p99) {
    // We want to know the fraction of distances between molecules at the 99th percentile
    // that are intra- rather than inter-molecule.
    // Do single linkage clustering of closest pair at this distance and count the number of
    // links that are inter and intra.
    // Convert molecules for clustering
    final ArrayList<ClusterPoint> points = new ArrayList<>(settings.molecules.size());
    for (final Molecule m : settings.molecules) {
        // Precision was used to store the molecule ID
        points.add(ClusterPoint.newClusterPoint((int) m.precision, m.x, m.y, m.photons));
    }
    final ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), ClusteringAlgorithm.PARTICLE_SINGLE_LINKAGE, SimpleImageJTrackProgress.getInstance());
    IJ.showStatus("Clustering to check inter-molecule distances");
    engine.setTrackJoins(true);
    final List<Cluster> clusters = engine.findClusters(points, intraHist[0][p99]);
    IJ.showStatus("");
    if (clusters != null) {
        final double[] intraIdDistances = engine.getIntraIdDistances();
        final double[] interIdDistances = engine.getInterIdDistances();
        final int all = interIdDistances.length + intraIdDistances.length;
        log("  * Fraction of inter-molecule particle linkage @ %s nm = %s %%", MathUtils.rounded(intraHist[0][p99], 4), (all > 0) ? MathUtils.rounded(100.0 * interIdDistances.length / all, 4) : "0");
        // Show a double cumulative histogram plot
        final double[][] intraIdHist = MathUtils.cumulativeHistogram(intraIdDistances, false);
        final double[][] interIdHist = MathUtils.cumulativeHistogram(interIdDistances, false);
        // Plot
        final String title = TITLE + " molecule linkage distance";
        final Plot plot = new Plot(title, "Distance", "Frequency");
        plot.addPoints(intraIdHist[0], intraIdHist[1], Plot.LINE);
        double max = (intraIdHist[1].length > 0) ? intraIdHist[1][intraIdHist[1].length - 1] : 0;
        if (interIdHist[1].length > 0) {
            max = Math.max(max, interIdHist[1][interIdHist[1].length - 1]);
        }
        plot.setLimits(0, intraIdHist[0][intraIdHist[0].length - 1], 0, max);
        plot.setColor(Color.blue);
        plot.addPoints(interIdHist[0], interIdHist[1], Plot.LINE);
        plot.setColor(Color.black);
        plot.addLegend("Intra-molecule\nInter-molecule");
        ImageJUtils.display(title, plot);
    } else {
        log("Aborted clustering to check inter-molecule distances");
    }
}
Also used : Plot(ij.gui.Plot) HistogramPlot(uk.ac.sussex.gdsc.core.ij.HistogramPlot) TDoubleArrayList(gnu.trove.list.array.TDoubleArrayList) ArrayList(java.util.ArrayList) Cluster(uk.ac.sussex.gdsc.core.clustering.Cluster) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) ClusterPoint(uk.ac.sussex.gdsc.core.clustering.ClusterPoint) ClusteringEngine(uk.ac.sussex.gdsc.core.clustering.ClusteringEngine) ClusterPoint(uk.ac.sussex.gdsc.core.clustering.ClusterPoint)

Aggregations

ClusteringEngine (uk.ac.sussex.gdsc.core.clustering.ClusteringEngine)4 Cluster (uk.ac.sussex.gdsc.core.clustering.Cluster)3 ClusterPoint (uk.ac.sussex.gdsc.core.clustering.ClusterPoint)3 Plot (ij.gui.Plot)2 ArrayList (java.util.ArrayList)2 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)2 Trace (uk.ac.sussex.gdsc.smlm.results.Trace)2 TraceManager (uk.ac.sussex.gdsc.smlm.results.TraceManager)2 TDoubleArrayList (gnu.trove.list.array.TDoubleArrayList)1 List (java.util.List)1 WeightedObservedPoint (org.apache.commons.math3.fitting.WeightedObservedPoint)1 HistogramPlot (uk.ac.sussex.gdsc.core.ij.HistogramPlot)1 SimpleImageJTrackProgress (uk.ac.sussex.gdsc.core.ij.SimpleImageJTrackProgress)1 TrackProgress (uk.ac.sussex.gdsc.core.logging.TrackProgress)1 StoredData (uk.ac.sussex.gdsc.core.utils.StoredData)1 DynamicMultipleTargetTracing (uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing)1 DmttConfiguration (uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration)1 ExtendedPeakResult (uk.ac.sussex.gdsc.smlm.results.ExtendedPeakResult)1