use of 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();
int min = results.getHead().getFrame();
int max = results.getTail().getEndFrame();
// Trace results
double d = searchDistance / results.getCalibration().getNmPerPixel();
int range = max - min + 1;
if (maxDarkTime > 0)
range = FastMath.max(1, (int) Math.round(maxDarkTime * 1000 / msPerFrame));
IJTrackProgress tracker = new IJTrackProgress();
tracker.status("Analysing ...");
tracker.log("Analysing (d=%s nm (%s px) t=%s s (%d frames)) ...", Utils.rounded(searchDistance), Utils.rounded(d), Utils.rounded(range * msPerFrame / 1000.0), range);
Trace[] traces;
if (method == 0) {
TraceManager tm = new TraceManager(results);
tm.setTracker(tracker);
tm.traceMolecules(d, range);
traces = tm.getTraces();
} else {
ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), algorithms[method - 1], tracker);
List<PeakResult> peakResults = results.getResults();
ArrayList<Cluster> clusters = engine.findClusters(TraceMolecules.convertToClusterPoints(peakResults), d, range);
traces = TraceMolecules.convertToTraces(peakResults, clusters);
}
tracker.status("Computing histogram ...");
// Build dark-time histogram
int[] times = new int[range];
StoredData stats = new StoredData();
for (Trace trace : traces) {
if (trace.getNBlinks() > 1) {
for (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];
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;
y[i] = (100.0 * times[i]) / total;
if (// 100%
times[i] == total) {
truncate = i + 1;
break;
}
}
if (truncate > 0) {
x = Arrays.copyOf(x, truncate);
y = Arrays.copyOf(y, truncate);
}
String title = "Cumulative Dark-time";
Plot2 plot = new Plot2(title, "Time (ms)", "Percentile", x, y);
Utils.display(title, plot);
// Report percentile
for (int i = 0; i < y.length; i++) {
if (y[i] >= percentile) {
Utils.log("Dark-time Percentile %.1f @ %s ms = %s s", percentile, Utils.rounded(x[i]), Utils.rounded(x[i] / 1000));
break;
}
}
tracker.status("");
}
use of 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
ArrayList<ClusterPoint> points = new ArrayList<ClusterPoint>(molecules.size());
for (Molecule m : molecules) // Precision was used to store the molecule ID
points.add(ClusterPoint.newClusterPoint((int) m.precision, m.x, m.y, m.photons));
ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), ClusteringAlgorithm.PARTICLE_SINGLE_LINKAGE, new IJTrackProgress());
IJ.showStatus("Clustering to check inter-molecule distances");
engine.setTrackJoins(true);
ArrayList<Cluster> clusters = engine.findClusters(points, intraHist[0][p99]);
IJ.showStatus("");
if (clusters != null) {
double[] intraIdDistances = engine.getIntraIdDistances();
double[] interIdDistances = engine.getInterIdDistances();
int all = interIdDistances.length + intraIdDistances.length;
log(" * Fraction of inter-molecule particle linkage @ %s nm = %s %%", Utils.rounded(intraHist[0][p99], 4), (all > 0) ? Utils.rounded(100.0 * interIdDistances.length / all, 4) : "0");
// Show a double cumulative histogram plot
double[][] intraIdHist = Maths.cumulativeHistogram(intraIdDistances, false);
double[][] interIdHist = Maths.cumulativeHistogram(interIdDistances, false);
// Plot
String title = TITLE + " molecule linkage distance";
Plot2 plot = new Plot2(title, "Distance", "Frequency", intraIdHist[0], intraIdHist[1]);
double max = (intraIdHist[1].length > 0) ? intraIdHist[1][intraIdHist[1].length - 1] : 0;
if (interIdHist[1].length > 0)
max = FastMath.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], Plot2.LINE);
plot.setColor(Color.black);
Utils.display(title, plot);
} else {
log("Aborted clustering to check inter-molecule distances");
}
}
use of 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
*/
private HistogramData doClustering() {
// Perform clustering analysis to generate the histogram of cluster sizes
PCPALMAnalysis analysis = new PCPALMAnalysis();
ArrayList<Molecule> molecules = analysis.cropToRoi(WindowManager.getCurrentImage());
if (molecules.size() < 2) {
error("No results within the crop region");
return null;
}
Utils.log("Using %d molecules (Density = %s um^-2) @ %s nm", molecules.size(), Utils.rounded(molecules.size() / analysis.croppedArea), Utils.rounded(distance));
long s1 = System.nanoTime();
ClusteringEngine engine = new ClusteringEngine(1, clusteringAlgorithm, new IJTrackProgress());
if (multiThread)
engine.setThreadCount(Prefs.getThreads());
engine.setTracker(new IJTrackProgress());
IJ.showStatus("Clustering ...");
ArrayList<Cluster> clusters = engine.findClusters(convertToPoint(molecules), distance);
IJ.showStatus("");
if (clusters == null) {
Utils.log("Aborted");
return null;
}
nMolecules = molecules.size();
Utils.log("Finished : %d total clusters (%s ms)", clusters.size(), Utils.rounded((System.nanoTime() - s1) / 1e6));
// Save cluster centroids to a results set in memory. Then they can be plotted.
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(new Calibration(100, 1, PCPALMMolecules.seconds * 1000));
// Make the standard deviation such that the Gaussian volume will be 95% at the distance threshold
final float sd = (float) (distance / 1.959964);
int id = 0;
for (Cluster c : clusters) {
results.add(new ExtendedPeakResult((float) c.x, (float) c.y, sd, c.n, ++id));
}
MemoryPeakResults.addResults(results);
// Get the data for fitting
float[] values = new float[clusters.size()];
for (int i = 0; i < values.length; i++) values[i] = clusters.get(i).n;
float yMax = (int) Math.ceil(Maths.max(values));
int nBins = (int) (yMax + 1);
float[][] hist = Utils.calcHistogram(values, 0, yMax, nBins);
HistogramData histogramData = (calibrateHistogram) ? new HistogramData(hist, frames, area, units) : new HistogramData(hist);
saveHistogram(histogramData);
return histogramData;
}
use of gdsc.core.clustering.ClusteringEngine in project GDSC-SMLM by aherbert.
the class TraceMolecules method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "No localisations in memory");
return;
}
altKeyDown = Utils.isExtraOptions();
Trace[] traces = null;
int totalFiltered = 0;
if ("cluster".equals(arg)) {
// --=-=-=-=-=-
// Clustering
// --=-=-=-=-=-
outputName = "Cluster";
if (!showClusterDialog())
return;
ClusteringEngine engine = new ClusteringEngine(Prefs.getThreads(), settings.getClusteringAlgorithm(), new IJTrackProgress());
if (settings.splitPulses) {
engine.setPulseInterval(settings.pulseInterval);
if (settings.getTimeUnit() == TimeUnit.FRAME) {
if (settings.getTimeThreshold() > settings.pulseInterval) {
settings.setTimeThreshold(settings.pulseInterval);
}
} else {
if (timeInFrames(settings) > settings.pulseInterval) {
settings.setTimeThreshold(settings.pulseInterval * exposureTime);
}
}
}
ArrayList<Cluster> clusters = engine.findClusters(convertToClusterPoints(), settings.distanceThreshold / results.getCalibration().getNmPerPixel(), timeInFrames(settings));
if (clusters == null) {
Utils.log("Aborted");
return;
}
traces = convertToTraces(clusters);
} else {
// --=-=-=-=-=-
// Tracing
// --=-=-=-=-=-
outputName = "Trace";
if (!showDialog())
return;
TraceManager manager = new TraceManager(results);
manager.setTraceMode(settings.getTraceMode());
manager.setActivationFrameInterval(settings.pulseInterval);
manager.setActivationFrameWindow(settings.pulseWindow);
manager.setDistanceExclusion(settings.distanceExclusion / results.getCalibration().getNmPerPixel());
if (settings.optimise) {
// Optimise before configuring for a pulse interval
runOptimiser(manager);
}
if (settings.splitPulses) {
manager.setPulseInterval(settings.pulseInterval);
if (settings.getTimeUnit() == TimeUnit.FRAME) {
if (settings.getTimeThreshold() > settings.pulseInterval) {
settings.setTimeThreshold(settings.pulseInterval);
}
} else {
if (timeInFrames(settings) > settings.pulseInterval) {
settings.setTimeThreshold(settings.pulseInterval * exposureTime);
}
}
}
manager.setTracker(new IJTrackProgress());
manager.traceMolecules(settings.distanceThreshold / results.getCalibration().getNmPerPixel(), timeInFrames(settings));
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");
Trace[] multiTraces = getTraces(traces);
saveResults(results, multiTraces, outputName + " Multi");
// Save centroids
outputName += " Centroids";
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.saveTraces)
saveTraces(traces);
summarise(traces, totalFiltered, settings.distanceThreshold, timeInSeconds(settings));
IJ.showStatus(String.format("%d localisations => %d traces (%d filtered)", results.size(), tracedResults.size(), totalFiltered));
// Provide option to refit the traces as single peaks and save to memory
if (settings.refitOption)
fitTraces(results, traces);
}
Aggregations