use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class DensityImage method createDensityManager.
private DensityManager createDensityManager(MemoryPeakResults results) {
if (results == null || results.size() == 0)
throw new IllegalArgumentException("Results are null or empty");
final float[] xcoord = new float[results.size()];
final float[] ycoord = new float[xcoord.length];
ArrayList<PeakResult> peakResults = (ArrayList<PeakResult>) results.getResults();
for (int i = 0; i < xcoord.length; i++) {
PeakResult result = peakResults.get(i);
xcoord[i] = result.getXPosition();
ycoord[i] = result.getYPosition();
}
return new DensityManager(xcoord, ycoord, results.getBounds());
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class DensityImage method plotResults.
/**
* Draw an image of the density for each localisation. Optionally filter results below a threshold.
*
* @param results
* @param density
* @param scoreCalculator
* @return
*/
private int plotResults(MemoryPeakResults results, float[] density, ScoreCalculator scoreCalculator) {
// Filter results using 5x higher than average density of the sample in a 150nm radius:
// Annibale, et al (2011). Identification of clustering artifacts in photoactivated localization microscopy.
// Nature Methods, 8, pp527-528
MemoryPeakResults newResults = null;
// No filtering
float densityThreshold = Float.NEGATIVE_INFINITY;
if (filterLocalisations) {
densityThreshold = scoreCalculator.getThreshold();
newResults = new MemoryPeakResults();
newResults.copySettings(results);
newResults.setName(results.getName() + " Density Filter");
}
// Draw an image - Use error so that a floating point value can be used on a single pixel
List<PeakResult> peakResults = results.getResults();
IJImagePeakResults image = ImagePeakResultsFactory.createPeakResultsImage(ResultsImage.ERROR, false, false, results.getName() + " Density", results.getBounds(), results.getNmPerPixel(), results.getGain(), imageScale, 0, (cumulativeImage) ? ResultsMode.ADD : ResultsMode.MAX);
image.setDisplayFlags(image.getDisplayFlags() | IJImagePeakResults.DISPLAY_NEGATIVES);
image.setLutName("grays");
image.begin();
for (int i = 0; i < density.length; i++) {
if (density[i] < densityThreshold)
continue;
PeakResult r = peakResults.get(i);
image.add(0, 0, 0, 0, density[i], 0, r.params, null);
if (newResults != null)
newResults.add(r);
}
image.end();
// Add to memory
if (newResults != null && newResults.size() > 0)
MemoryPeakResults.addResults(newResults);
return image.size();
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class DensityImage method cropBorder.
/**
* Remove any results which fall in the radius border added around the ROI. Results are modified in place and a new
* density array is returned.
*
* @param results
* @param density
* @return
*/
private int[] cropBorder(MemoryPeakResults results, int[] density) {
if (roiBounds == null)
return density;
final float minX = (int) (scaledRoiMinX);
final float maxX = (int) Math.ceil(scaledRoiMaxX);
final float minY = (int) (scaledRoiMinY);
final float maxY = (int) Math.ceil(scaledRoiMaxY);
// Clone the results then add back those that are within the bounds
PeakResult[] peakResults = results.toArray();
results.begin();
int count = 0;
for (int i = 0; i < peakResults.length; i++) {
PeakResult peakResult = peakResults[i];
float x = peakResult.params[Gaussian2DFunction.X_POSITION];
float y = peakResult.params[Gaussian2DFunction.Y_POSITION];
if (x < minX || x > maxX || y < minY || y > maxY)
continue;
results.add(peakResult);
density[count++] = density[i];
}
results.end();
results.setBounds(new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)));
return Arrays.copyOf(density, count);
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class DensityImage method cropWithBorder.
/**
* Crop the results to the ROI. Add a border using the sampling radius so that counts do not have to be approximated
* (i.e. all spots around the edge of the ROI will have a complete image to sample from). The results are modified
* in place.
*
* @param results
* @param isWithin
* Set to true if the added border is within the original bounds (i.e. no adjustment for missing counts
* is required)
* @return
*/
private MemoryPeakResults cropWithBorder(MemoryPeakResults results, boolean[] isWithin) {
isWithin[0] = false;
if (roiBounds == null)
return results;
// Adjust bounds relative to input results image:
// Use the ROI relative to the frame the ROI is drawn on.
// Map those fractional coordinates back to the original data bounds.
Rectangle bounds = results.getBounds();
double xscale = (double) roiImageWidth / bounds.width;
double yscale = (double) roiImageHeight / bounds.height;
// Compute relative to the results bounds (if present)
scaledRoiMinX = bounds.x + roiBounds.x / xscale;
scaledRoiMaxX = scaledRoiMinX + roiBounds.width / xscale;
scaledRoiMinY = bounds.y + roiBounds.y / yscale;
scaledRoiMaxY = scaledRoiMinY + roiBounds.height / yscale;
// Allow for the border
final float minX = (int) (scaledRoiMinX - radius);
final float maxX = (int) Math.ceil(scaledRoiMaxX + radius);
final float minY = (int) (scaledRoiMinY - radius);
final float maxY = (int) Math.ceil(scaledRoiMaxY + radius);
// Create a new set of results within the bounds
MemoryPeakResults newResults = new MemoryPeakResults();
newResults.begin();
for (PeakResult peakResult : results.getResults()) {
float x = peakResult.params[Gaussian2DFunction.X_POSITION];
float y = peakResult.params[Gaussian2DFunction.Y_POSITION];
if (x < minX || x > maxX || y < minY || y > maxY)
continue;
newResults.add(peakResult);
}
newResults.end();
newResults.copySettings(results);
newResults.setBounds(new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)));
isWithin[0] = minX >= bounds.x && minY >= bounds.y && maxX <= (bounds.x + bounds.width) && maxY <= (bounds.y + bounds.height);
return newResults;
}
use of gdsc.smlm.results.PeakResult 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("");
}
Aggregations