use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class SplitResults method splitResults.
private void splitResults(MemoryPeakResults results, ImageProcessor ip) {
IJ.showStatus("Splitting " + Utils.pleural(results.size(), "result"));
// Create an object mask
ObjectAnalyzer objectAnalyzer = new ObjectAnalyzer(ip, false);
final int maxx = ip.getWidth();
final int maxy = ip.getHeight();
final float scaleX = (float) results.getBounds().width / maxx;
final float scaleY = (float) results.getBounds().height / maxy;
// Create a results set for each object
final int maxObject = objectAnalyzer.getMaxObject();
MemoryPeakResults[] resultsSet = new MemoryPeakResults[maxObject + 1];
for (int object = 0; object <= maxObject; object++) {
MemoryPeakResults newResults = new MemoryPeakResults();
newResults.copySettings(results);
newResults.setName(results.getName() + " " + object);
resultsSet[object] = newResults;
}
final int[] mask = objectAnalyzer.getObjectMask();
if (showObjectMask) {
ImageProcessor objectIp = (maxObject <= 255) ? new ByteProcessor(maxx, maxy) : new ShortProcessor(maxx, maxy);
for (int i = 0; i < mask.length; i++) objectIp.set(i, mask[i]);
ImagePlus imp = Utils.display(objectMask + " Objects", objectIp);
imp.setDisplayRange(0, maxObject);
imp.updateAndDraw();
}
// Process the results mapping them to their objects
int i = 0;
final int size = results.size();
final int step = Utils.getProgressInterval(size);
for (PeakResult result : results.getResults()) {
if (++i % step == 0)
IJ.showProgress(i, size);
// Map to the mask objects
final int object;
int x = (int) (result.getXPosition() / scaleX);
int y = (int) (result.getYPosition() / scaleY);
if (x < 0 || x >= maxx || y < 0 || y >= maxy) {
object = 0;
} else {
final int index = y * maxx + x;
if (index < 0 || index >= mask.length)
object = 0;
else
object = mask[index];
}
resultsSet[object].add(result);
}
IJ.showProgress(1);
// Add the new results sets to memory
i = 0;
for (int object = (nonMaskDataset) ? 0 : 1; object <= maxObject; object++) {
if (!resultsSet[object].isEmpty()) {
MemoryPeakResults.addResults(resultsSet[object]);
i++;
}
}
IJ.showStatus("Split " + Utils.pleural(results.size(), "result") + " into " + Utils.pleural(i, "set"));
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class TraceMolecules method buildCombinedImage.
private float[] buildCombinedImage(ImageSource source, Trace trace, float fitWidth, Rectangle bounds, double[] combinedNoise, boolean createStack) {
final int w = source.getWidth();
final int h = source.getHeight();
// Get the coordinates and the spot bounds
float[] centre = trace.getCentroid(CentroidMethod.SIGNAL_WEIGHTED);
int minX = (int) Math.floor(centre[0] - fitWidth);
int maxX = (int) Math.ceil(centre[0] + fitWidth);
int minY = (int) Math.floor(centre[1] - fitWidth);
int maxY = (int) Math.ceil(centre[1] + fitWidth);
// Account for crops at the edge of the image
minX = FastMath.max(0, minX);
maxX = FastMath.min(w, maxX);
minY = FastMath.max(0, minY);
maxY = FastMath.min(h, maxY);
int width = maxX - minX;
int height = maxY - minY;
if (width <= 0 || height <= 0) {
// The centre must be outside the image width and height
return null;
}
bounds.x = minX;
bounds.y = minY;
bounds.width = width;
bounds.height = height;
if (createStack)
slices = new ImageStack(width, height);
// Combine the images. Subtract the fitted background to zero the image.
float[] data = new float[width * height];
float sumBackground = 0;
double noise = 0;
for (PeakResult result : trace.getPoints()) {
noise += result.noise * result.noise;
float[] sourceData = source.get(result.getFrame(), bounds);
final float background = result.getBackground();
sumBackground += background;
for (int i = 0; i < data.length; i++) {
data[i] += sourceData[i] - background;
}
if (createStack)
slices.addSlice(new FloatProcessor(width, height, sourceData, null));
}
if (createStack) {
// Add a final image that is the average of the individual slices. This allows
// it to be visualised in the same intensity scale.
float[] data2 = Arrays.copyOf(data, data.length);
final int size = slices.getSize();
sumBackground /= size;
for (int i = 0; i < data2.length; i++) data2[i] = sumBackground + data2[i] / size;
slices.addSlice(new FloatProcessor(width, height, data2, null));
}
// Combined noise is the sqrt of the sum-of-squares
combinedNoise[0] = Math.sqrt(noise);
return data;
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class TraceMolecules method runOptimiser.
private void runOptimiser(TraceManager manager) {
// Get an estimate of the number of molecules without blinking
SummaryStatistics stats = new SummaryStatistics();
final double nmPerPixel = this.results.getNmPerPixel();
final double gain = this.results.getGain();
final boolean emCCD = this.results.isEMCCD();
for (PeakResult result : this.results.getResults()) stats.addValue(result.getPrecision(nmPerPixel, gain, emCCD));
// Use twice the precision to get the initial distance threshold
// Use 2.5x sigma as per the PC-PALM protocol in Sengupta, et al (2013) Nature Protocols 8, 345
double dEstimate = stats.getMean() * 2.5 / nmPerPixel;
int n = manager.traceMolecules(dEstimate, 1);
if (!getParameters(n, dEstimate))
return;
// TODO - Convert the distance threshold to use nm instead of pixels?
List<double[]> results = runTracing(manager, settings.minDistanceThreshold, settings.maxDistanceThreshold, settings.minTimeThreshold, settings.maxTimeThreshold, settings.optimiserSteps);
// Compute fractional difference from the true value:
// Use blinking rate directly or the estimated number of molecules
double nReference;
int statistic;
if (optimiseBlinkingRate) {
nReference = settings.blinkingRate;
statistic = 3;
IJ.log(String.format("Estimating blinking rate: %.2f", nReference));
} else {
nReference = n / settings.blinkingRate;
statistic = 2;
IJ.log(String.format("Estimating number of molecules: %d / %.2f = %.2f", n, settings.blinkingRate, nReference));
}
for (double[] result : results) {
//System.out.printf("%g %g = %g\n", result[0], result[1], result[2]);
if (optimiseBlinkingRate)
result[2] = (nReference - result[statistic]) / nReference;
else
result[2] = (result[statistic] - nReference) / nReference;
}
// Locate the optimal parameters with a fit of the zero contour
boolean found = findOptimalParameters(results);
createPlotResults(results);
if (!found)
return;
// Make fractional difference absolute so that lowest is best
for (double[] result : results) result[2] = Math.abs(result[2]);
// Set the optimal thresholds using the lowest value
double[] best = new double[] { 0, 0, Double.MAX_VALUE };
for (double[] result : results) if (best[2] > result[2])
best = result;
settings.distanceThreshold = best[0];
// The optimiser works using frames so convert back to the correct units
double convert = (settings.getTimeUnit() == TimeUnit.SECOND) ? exposureTime : 1;
settings.setTimeThreshold(settings.getTimeThreshold() * convert);
IJ.log(String.format("Optimal fractional difference @ D-threshold=%g, T-threshold=%f (%d frames)", settings.distanceThreshold, timeInSeconds(settings), timeInFrames(settings)));
SettingsManager.saveSettings(globalSettings);
}
use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.
the class TraceMolecules method convertToClusterPoints.
/**
* Convert a list of peak results into points for the clustering engine
*
* @param peakResults
* @return
*/
public static List<ClusterPoint> convertToClusterPoints(List<PeakResult> peakResults) {
ArrayList<ClusterPoint> points = new ArrayList<ClusterPoint>(peakResults.size());
int id = 0;
for (PeakResult p : peakResults) points.add(ClusterPoint.newTimeClusterPoint(id++, p.getXPosition(), p.getYPosition(), p.getSignal(), p.getFrame(), p.getEndFrame()));
return points;
}
Aggregations