use of uk.ac.sussex.gdsc.core.clustering.Cluster 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;
}
use of uk.ac.sussex.gdsc.core.clustering.Cluster in project GDSC-SMLM by aherbert.
the class TraceMolecules method convertToTraces.
/**
* Convert the clusters from the clustering engine into traces composed of the original list of
* peak results.
*
* @param results the results
* @param clusters the clusters
* @return the traces
*/
public static Trace[] convertToTraces(MemoryPeakResults results, List<Cluster> clusters) {
final Trace[] traces = new Trace[clusters.size()];
int index = 0;
for (final Cluster cluster : clusters) {
final Trace trace = new Trace();
trace.setId(index + 1);
for (ClusterPoint point = cluster.getHeadClusterPoint(); point != null; point = point.getNext()) {
// The point Id was the position in the original results array
trace.add(results.get(point.getId()));
}
trace.sort();
traces[index++] = trace;
}
return traces;
}
use of uk.ac.sussex.gdsc.core.clustering.Cluster 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("");
}
use of uk.ac.sussex.gdsc.core.clustering.Cluster 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");
}
}
Aggregations