use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class CreateData method showSummary.
private double showSummary(List<? extends FluorophoreSequenceModel> fluorophores, List<LocalisationModel> localisations) {
IJ.showStatus("Calculating statistics ...");
createSummaryTable();
Statistics[] stats = new Statistics[NAMES.length];
for (int i = 0; i < stats.length; i++) {
stats[i] = (settings.showHistograms || alwaysRemoveOutliers[i]) ? new StoredDataStatistics() : new Statistics();
}
// Find the largest timepoint
ImagePlus outputImp = WindowManager.getImage(benchmarkImageId);
int nFrames;
if (outputImp == null) {
sortLocalisationsByTime(localisations);
nFrames = localisations.get(localisations.size() - 1).getTime();
} else {
nFrames = outputImp.getStackSize();
}
int[] countHistogram = new int[nFrames + 1];
// Use the localisations that were drawn to create the sampled on/off times
rebuildNeighbours(localisations);
// Assume that there is at least one localisation
LocalisationModel first = localisations.get(0);
// The current localisation
int currentId = first.getId();
// The last time this localisation was on
int lastT = first.getTime();
// Number of blinks
int blinks = 0;
// On-time of current pulse
int currentT = 0;
double signal = 0;
final double centreOffset = settings.size * 0.5;
// Used to convert the sampled times in frames into seconds
final double framesPerSecond = 1000.0 / settings.exposureTime;
final double gain = (settings.getTotalGain() > 0) ? settings.getTotalGain() : 1;
for (LocalisationModel l : localisations) {
if (l.getData() == null)
System.out.println("No localisation data. This should not happen!");
final double noise = (l.getData() != null) ? l.getData()[1] : 1;
final double intensity = (l.getData() != null) ? l.getData()[4] : l.getIntensity();
final double intensityInPhotons = intensity / gain;
// Q. What if the noise is zero, i.e. no background photon / read noise?
// Just ignore it at current.
final double snr = intensity / noise;
stats[SIGNAL].add(intensityInPhotons);
stats[NOISE].add(noise / gain);
if (noise != 0)
stats[SNR].add(snr);
//if (l.isContinuous())
if (l.getNext() != null && l.getPrevious() != null) {
stats[SIGNAL_CONTINUOUS].add(intensityInPhotons);
if (noise != 0)
stats[SNR_CONTINUOUS].add(snr);
}
int id = l.getId();
// Check if this a new fluorophore
if (currentId != id) {
// Add previous fluorophore
stats[SAMPLED_BLINKS].add(blinks);
stats[SAMPLED_T_ON].add(currentT / framesPerSecond);
stats[TOTAL_SIGNAL].add(signal);
// Reset
blinks = 0;
currentT = 1;
currentId = id;
signal = intensityInPhotons;
} else {
signal += intensityInPhotons;
// Check if the current fluorophore pulse is broken (i.e. a blink)
if (l.getTime() - 1 > lastT) {
blinks++;
stats[SAMPLED_T_ON].add(currentT / framesPerSecond);
currentT = 1;
stats[SAMPLED_T_OFF].add(((l.getTime() - 1) - lastT) / framesPerSecond);
} else {
// Continuous on-time
currentT++;
}
}
lastT = l.getTime();
countHistogram[lastT]++;
stats[X].add((l.getX() - centreOffset) * settings.pixelPitch);
stats[Y].add((l.getY() - centreOffset) * settings.pixelPitch);
stats[Z].add(l.getZ() * settings.pixelPitch);
}
// Final fluorophore
stats[SAMPLED_BLINKS].add(blinks);
stats[SAMPLED_T_ON].add(currentT / framesPerSecond);
stats[TOTAL_SIGNAL].add(signal);
// Samples per frame
for (int t = 1; t < countHistogram.length; t++) stats[SAMPLES].add(countHistogram[t]);
if (fluorophores != null) {
for (FluorophoreSequenceModel f : fluorophores) {
stats[BLINKS].add(f.getNumberOfBlinks());
// On-time
for (double t : f.getOnTimes()) stats[T_ON].add(t);
// Off-time
for (double t : f.getOffTimes()) stats[T_OFF].add(t);
}
} else {
// show no blinks
stats[BLINKS].add(0);
stats[T_ON].add(1);
//stats[T_OFF].add(0);
}
if (results != null) {
final boolean emCCD = (settings.getEmGain() > 1);
// Convert depth-of-field to pixels
final double depth = settings.depthOfField / settings.pixelPitch;
for (PeakResult r : results.getResults()) {
final double precision = r.getPrecision(settings.pixelPitch, gain, emCCD);
stats[PRECISION].add(precision);
// The error stores the z-depth in pixels
if (Math.abs(r.error) < depth)
stats[PRECISION_IN_FOCUS].add(precision);
stats[WIDTH].add(r.getSD());
}
// Compute density per frame. Multithread for speed
if (settings.densityRadius > 0) {
IJ.showStatus("Calculating density ...");
ExecutorService threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
List<Future<?>> futures = new LinkedList<Future<?>>();
final ArrayList<float[]> coords = new ArrayList<float[]>();
int t = results.getHead().getFrame();
final Statistics densityStats = stats[DENSITY];
final float radius = (float) (settings.densityRadius * getHWHM());
final Rectangle bounds = results.getBounds();
currentIndex = 0;
finalIndex = results.getTail().getFrame();
// Store the density for each result.
int[] allDensity = new int[results.size()];
int allIndex = 0;
for (PeakResult r : results.getResults()) {
if (t != r.getFrame()) {
allIndex += runDensityCalculation(threadPool, futures, coords, densityStats, radius, bounds, allDensity, allIndex);
}
coords.add(new float[] { r.getXPosition(), r.getYPosition() });
t = r.getFrame();
}
runDensityCalculation(threadPool, futures, coords, densityStats, radius, bounds, allDensity, allIndex);
Utils.waitForCompletion(futures);
threadPool.shutdownNow();
threadPool = null;
IJ.showProgress(1);
// Split results into singles (density = 0) and clustered (density > 0)
MemoryPeakResults singles = copyMemoryPeakResults("No Density");
MemoryPeakResults clustered = copyMemoryPeakResults("Density");
int i = 0;
for (PeakResult r : results.getResults()) {
// Store density in the original value field
r.origValue = allDensity[i];
if (allDensity[i++] == 0)
singles.add(r);
else
clustered.add(r);
}
}
}
StringBuilder sb = new StringBuilder();
sb.append(datasetNumber).append("\t");
sb.append((fluorophores == null) ? localisations.size() : fluorophores.size()).append("\t");
sb.append(stats[SAMPLED_BLINKS].getN() + (int) stats[SAMPLED_BLINKS].getSum()).append("\t");
sb.append(localisations.size()).append("\t");
sb.append(nFrames).append("\t");
sb.append(Utils.rounded(areaInUm)).append("\t");
sb.append(Utils.rounded(localisations.size() / (areaInUm * nFrames), 4)).append("\t");
sb.append(Utils.rounded(getHWHM(), 4)).append("\t");
double s = getPsfSD();
sb.append(Utils.rounded(s, 4)).append("\t");
s *= settings.pixelPitch;
final double sa = PSFCalculator.squarePixelAdjustment(s, settings.pixelPitch) / settings.pixelPitch;
sb.append(Utils.rounded(sa, 4)).append("\t");
// Width not valid for the Image PSF
int nStats = (imagePSF) ? stats.length - 1 : stats.length;
for (int i = 0; i < nStats; i++) {
double centre = (alwaysRemoveOutliers[i]) ? ((StoredDataStatistics) stats[i]).getStatistics().getPercentile(50) : stats[i].getMean();
sb.append(Utils.rounded(centre, 4)).append("\t");
}
if (java.awt.GraphicsEnvironment.isHeadless()) {
IJ.log(sb.toString());
return stats[SIGNAL].getMean();
} else {
summaryTable.append(sb.toString());
}
// Show histograms
if (settings.showHistograms) {
IJ.showStatus("Calculating histograms ...");
boolean[] chosenHistograms = getChoosenHistograms();
WindowOrganiser wo = new WindowOrganiser();
boolean requireRetile = false;
for (int i = 0; i < NAMES.length; i++) {
if (chosenHistograms[i]) {
wo.add(Utils.showHistogram(TITLE, (StoredDataStatistics) stats[i], NAMES[i], (integerDisplay[i]) ? 1 : 0, (settings.removeOutliers || alwaysRemoveOutliers[i]) ? 2 : 0, settings.histogramBins * ((integerDisplay[i]) ? 100 : 1)));
requireRetile = requireRetile || Utils.isNewWindow();
}
}
wo.tile();
}
IJ.showStatus("");
return stats[SIGNAL].getMean();
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class CreateData method savePulses.
/**
* Create a set of results that represent the molecule continuous on-times (pulses)
*
* @param localisations
* @param results
* @param title
*/
private void savePulses(List<LocalisationModel> localisations, MemoryPeakResults results, String title) {
sortLocalisationsByIdThenTime(localisations);
MemoryPeakResults traceResults = copyMemoryPeakResults("Pulses");
LocalisationModel start = null;
int currentId = -1;
int n = 0;
float[] params = new float[7];
double noise = 0;
int lastT = -1;
for (LocalisationModel localisation : localisations) {
if (currentId != localisation.getId() || lastT + 1 != localisation.getTime()) {
if (n > 0) {
params[Gaussian2DFunction.BACKGROUND] /= n;
params[Gaussian2DFunction.X_POSITION] /= n;
params[Gaussian2DFunction.Y_POSITION] /= n;
params[Gaussian2DFunction.X_SD] /= n;
params[Gaussian2DFunction.Y_SD] /= n;
ExtendedPeakResult p = new ExtendedPeakResult(start.getTime(), (int) Math.round(start.getX()), (int) Math.round(start.getY()), 0, 0, (float) (Math.sqrt(noise)), params, null, lastT, currentId);
// if (p.getPrecision(107, 1) > 2000)
// {
// System.out.printf("Weird precision = %g (%d)\n", p.getPrecision(107, 1), n);
// }
traceResults.add(p);
}
start = localisation;
currentId = localisation.getId();
n = 0;
params = new float[7];
noise = 0;
}
final double[] data = localisation.getData();
params[Gaussian2DFunction.BACKGROUND] += data[0];
params[Gaussian2DFunction.X_POSITION] += localisation.getX();
params[Gaussian2DFunction.Y_POSITION] += localisation.getY();
params[Gaussian2DFunction.SIGNAL] += localisation.getIntensity();
noise += data[1] * data[1];
params[Gaussian2DFunction.X_SD] += data[2];
params[Gaussian2DFunction.Y_SD] += data[3];
n++;
lastT = localisation.getTime();
}
// Final pulse
if (n > 0) {
params[Gaussian2DFunction.BACKGROUND] /= n;
params[Gaussian2DFunction.X_POSITION] /= n;
params[Gaussian2DFunction.Y_POSITION] /= n;
params[Gaussian2DFunction.X_SD] /= n;
params[Gaussian2DFunction.Y_SD] /= n;
traceResults.add(new ExtendedPeakResult(start.getTime(), (int) Math.round(start.getX()), (int) Math.round(start.getY()), 0, 0, (float) (Math.sqrt(noise)), params, null, lastT, currentId));
}
traceResults.end();
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class ResultsManager method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (arg != null && arg.startsWith("clear")) {
Collection<MemoryPeakResults> allResults;
boolean removeAll = false;
if (arg.contains("multi")) {
MultiDialog md = new MultiDialog(TITLE, new MultiDialog.MemoryResultsItems());
md.addSelected(selected);
md.showDialog();
if (md.wasCanceled())
return;
selected = md.getSelectedResults();
if (selected.isEmpty())
return;
allResults = new ArrayList<MemoryPeakResults>(selected.size());
for (String name : selected) {
MemoryPeakResults r = MemoryPeakResults.getResults(name);
if (r != null)
allResults.add(r);
}
} else {
removeAll = true;
allResults = MemoryPeakResults.getAllResults();
}
if (allResults.isEmpty())
return;
long memorySize = 0;
int size = 0;
for (MemoryPeakResults results : allResults) {
memorySize += MemoryPeakResults.estimateMemorySize(results.getResults());
size += results.size();
}
String memory = MemoryPeakResults.memorySizeString(memorySize);
String count = Utils.pleural(size, "result");
String sets = Utils.pleural(allResults.size(), "set");
GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage(String.format("Do you want to remove %s from memory (%s, %s)?", count, sets, memory));
gd.enableYesNoCancel();
gd.showDialog();
if (!gd.wasOKed())
return;
if (removeAll)
MemoryPeakResults.clearMemory();
else {
for (MemoryPeakResults results : allResults) MemoryPeakResults.removeResults(results.getName());
}
SummariseResults.clearSummaryTable();
IJ.log(String.format("Cleared %s (%s, %s)", count, sets, memory));
return;
}
if (!showDialog())
return;
MemoryPeakResults results = loadResults(inputOption);
if (results == null || results.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
IJ.showStatus("");
return;
}
results = cropToRoi(results);
if (results.size() == 0) {
IJ.error(TITLE, "No results within the crop region");
return;
}
if (resultsSettings.resultsInMemory && fileInput)
MemoryPeakResults.addResults(results);
IJ.showStatus("Processing outputs ...");
Rectangle bounds = results.getBounds(true);
boolean showDeviations = resultsSettings.showDeviations && canShowDeviations(results);
boolean showEndFrame = canShowEndFrame(results);
boolean showId = canShowId(results);
// Display the configured output
PeakResultsList outputList = new PeakResultsList();
outputList.copySettings(results);
//String title = results.getSource();
//if (title == null || title.length() == 0)
// output.setSource(TITLE);
addTableResults(results, outputList, showDeviations, showEndFrame);
addImageResults(outputList, results.getName(), bounds, results.getNmPerPixel(), results.getGain());
addFileResults(outputList, showDeviations, showEndFrame, showId);
// Reduce to single object for speed
PeakResults output = (outputList.numberOfOutputs() == 1) ? outputList.toArray()[0] : outputList;
output.begin();
// Process in batches to provide progress
List<PeakResult> list = results.getResults();
int progress = 0;
int totalProgress = list.size();
int stepProgress = Utils.getProgressInterval(totalProgress);
TurboList<PeakResult> batch = new TurboList<PeakResult>(stepProgress);
for (PeakResult result : list) {
if (progress % stepProgress == 0) {
IJ.showProgress(progress, totalProgress);
}
progress++;
batch.addf(result);
if (batch.size() == stepProgress) {
output.addAll(batch);
batch.clearf();
if (isInterrupted())
break;
}
}
IJ.showProgress(1);
output.end();
IJ.showStatus(String.format("Processed %d result%s", results.size(), (results.size() > 1) ? "s" : ""));
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class PeakFit method addSingleFrameOverlay.
private void addSingleFrameOverlay() {
// If a single frame was processed add the peaks as an overlay if they are in memory
ImagePlus imp = this.imp;
if (fitMaxima && singleFrame > 0) {
if (source instanceof IJImageSource) {
String title = source.getName();
imp = WindowManager.getImage(title);
}
}
if (singleFrame > 0 && imp != null) {
MemoryPeakResults results = null;
for (PeakResults r : this.results.toArray()) if (r instanceof MemoryPeakResults) {
results = (MemoryPeakResults) r;
break;
}
if (results == null || results.size() == 0)
return;
ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
gd.addMessage("Add the fitted localisations as an overlay?");
gd.showDialog();
if (!gd.wasOKed())
return;
LUT lut = LUTHelper.createLUT(LutColour.ICE);
Overlay o = new Overlay();
ArrayList<PeakResult> list = (ArrayList<PeakResult>) results.getResults();
for (int i = 0, j = results.size() - 1; i < results.size(); i++, j--) {
PeakResult r = list.get(i);
PointRoi roi = new PointRoi(r.getXPosition(), r.getYPosition());
Color c = LUTHelper.getColour(lut, j, results.size());
roi.setStrokeColor(c);
roi.setFillColor(c);
if (imp.getStackSize() > 1)
roi.setPosition(singleFrame);
o.add(roi);
}
imp.setOverlay(o);
imp.getWindow().toFront();
}
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class TraceMatchCalculator 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;
}
if (!showDialog())
return;
// Load the results
MemoryPeakResults results1 = ResultsManager.loadInputResults(inputOption1, false);
MemoryPeakResults results2 = ResultsManager.loadInputResults(inputOption2, false);
MemoryPeakResults results3 = ResultsManager.loadInputResults(inputOption3, false);
if (results1 == null || results1.size() == 0 || results2 == null || results2.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
IJ.showStatus("");
return;
}
final long start = System.nanoTime();
compareCoordinates(results1, results2, results3, dThreshold);
double seconds = (System.nanoTime() - start) / 1000000000.0;
IJ.showStatus(String.format("%s = %ss", TITLE, Utils.rounded(seconds, 4)));
}
Aggregations