use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class TraceDiffusion method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
jumpDistanceParameters = null;
extraOptions = Utils.isExtraOptions();
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "No localisations in memory");
return;
}
ArrayList<MemoryPeakResults> allResults = new ArrayList<MemoryPeakResults>();
// Option to pick multiple input datasets together using a list box.
if ("multi".equals(arg)) {
if (!showMultiDialog(allResults))
return;
}
// This shows the dialog for selecting trace options
if (!showTraceDialog(allResults))
return;
if (// Sense check
allResults.isEmpty())
return;
Utils.log(TITLE + "...");
// This optionally collects additional datasets then gets the traces:
// - Trace each single dataset (and store in memory)
// - Combine trace results held in memory
Trace[] traces = getTraces(allResults);
// This still allows a zero entry in the results table.
if (traces.length > 0)
if (!showDialog())
return;
int count = traces.length;
double[] fitMSDResult = null;
int n = 0;
double[][] jdParams = null;
if (count > 0) {
calculatePrecision(traces, allResults.size() > 1);
//--- MSD Analysis ---
// Conversion constants
final double px2ToUm2 = results.getCalibration().getNmPerPixel() * results.getCalibration().getNmPerPixel() / 1e6;
final double px2ToUm2PerSecond = px2ToUm2 / exposureTime;
// Get the maximum trace length
int length = settings.minimumTraceLength;
if (!settings.truncate) {
for (Trace trace : traces) {
if (length < trace.size())
length = trace.size();
}
}
// Get the localisation error (4s^2) in um^2
final double error = (settings.precisionCorrection) ? 4 * precision * precision / 1e6 : 0;
// Pre-calculate MSD correction factors. This accounts for the fact that the distance moved
// in the start/end frames is reduced due to the averaging of the particle location over the
// entire frame into a single point. The true MSD may be restored by applying a factor.
// Note: These are used for the calculation of the diffusion coefficients per molecule and
// the MSD passed to the Jump Distance analysis. However the error is not included in the
// jump distance analysis so will be subtracted from the fitted D coefficients later.
final double[] factors;
if (settings.msdCorrection) {
factors = new double[length];
for (int t = 1; t < length; t++) factors[t] = JumpDistanceAnalysis.getConversionfactor(t);
} else {
factors = Utils.newArray(length, 0.0, 1.0);
}
// Extract the mean-squared distance statistics
Statistics[] stats = new Statistics[length];
for (int i = 0; i < stats.length; i++) stats[i] = new Statistics();
ArrayList<double[]> distances = (saveTraceDistances || displayTraceLength) ? new ArrayList<double[]>(traces.length) : null;
// Store all the jump distances at the specified interval
StoredDataStatistics jumpDistances = new StoredDataStatistics();
final int jumpDistanceInterval = settings.jumpDistance;
// Compute squared distances
StoredDataStatistics msdPerMoleculeAllVsAll = new StoredDataStatistics();
StoredDataStatistics msdPerMoleculeAdjacent = new StoredDataStatistics();
for (Trace trace : traces) {
ArrayList<PeakResult> results = trace.getPoints();
// Sum the MSD and the time
final int traceLength = (settings.truncate) ? settings.minimumTraceLength : trace.size();
// Get the mean for each time separation
double[] sumDistance = new double[traceLength + 1];
double[] sumTime = new double[sumDistance.length];
// Do the distances to the origin (saving if necessary)
{
final float x = results.get(0).getXPosition();
final float y = results.get(0).getYPosition();
if (distances != null) {
double[] msd = new double[traceLength - 1];
for (int j = 1; j < traceLength; j++) {
final int t = j;
final double d = distance2(x, y, results.get(j));
msd[j - 1] = px2ToUm2 * d;
if (t == jumpDistanceInterval)
jumpDistances.add(msd[j - 1]);
sumDistance[t] += d;
sumTime[t] += t;
}
distances.add(msd);
} else {
for (int j = 1; j < traceLength; j++) {
final int t = j;
final double d = distance2(x, y, results.get(j));
if (t == jumpDistanceInterval)
jumpDistances.add(px2ToUm2 * d);
sumDistance[t] += d;
sumTime[t] += t;
}
}
}
if (settings.internalDistances) {
// Do the internal distances
for (int i = 1; i < traceLength; i++) {
final float x = results.get(i).getXPosition();
final float y = results.get(i).getYPosition();
for (int j = i + 1; j < traceLength; j++) {
final int t = j - i;
final double d = distance2(x, y, results.get(j));
if (t == jumpDistanceInterval)
jumpDistances.add(px2ToUm2 * d);
sumDistance[t] += d;
sumTime[t] += t;
}
}
// Add the average distance per time separation to the population
for (int t = 1; t < traceLength; t++) {
// Note: (traceLength - t) == count
stats[t].add(sumDistance[t] / (traceLength - t));
}
} else {
// Add the distance per time separation to the population
for (int t = 1; t < traceLength; t++) {
stats[t].add(sumDistance[t]);
}
}
// Fix this for the precision and MSD adjustment.
// It may be necessary to:
// - sum the raw distances for each time interval (this is sumDistance[t])
// - subtract the precision error
// - apply correction factor for the n-frames to get actual MSD
// - sum the actual MSD
double sumD = 0, sumD_adjacent = Math.max(0, sumDistance[1] - error) * factors[1];
double sumT = 0, sumT_adjacent = sumTime[1];
for (int t = 1; t < traceLength; t++) {
sumD += Math.max(0, sumDistance[t] - error) * factors[t];
sumT += sumTime[t];
}
// Calculate the average displacement for the trace (do not simply use the largest
// time separation since this will miss moving molecules that end up at the origin)
msdPerMoleculeAllVsAll.add(px2ToUm2PerSecond * sumD / sumT);
msdPerMoleculeAdjacent.add(px2ToUm2PerSecond * sumD_adjacent / sumT_adjacent);
}
StoredDataStatistics dPerMoleculeAllVsAll = null;
StoredDataStatistics dPerMoleculeAdjacent = null;
if (saveTraceDistances || (settings.showHistograms && displayDHistogram)) {
dPerMoleculeAllVsAll = calculateDiffusionCoefficient(msdPerMoleculeAllVsAll);
dPerMoleculeAdjacent = calculateDiffusionCoefficient(msdPerMoleculeAdjacent);
}
if (saveTraceDistances) {
saveTraceDistances(traces.length, distances, msdPerMoleculeAllVsAll, msdPerMoleculeAdjacent, dPerMoleculeAllVsAll, dPerMoleculeAdjacent);
}
if (displayTraceLength) {
StoredDataStatistics lengths = calculateTraceLengths(distances);
showHistogram(lengths, "Trace length (um)");
}
if (displayTraceSize) {
StoredDataStatistics sizes = calculateTraceSizes(traces);
showHistogram(sizes, "Trace size", true);
}
// Plot the per-trace histogram of MSD and D
if (settings.showHistograms) {
if (displayMSDHistogram) {
showHistogram(msdPerMoleculeAllVsAll, "MSD/Molecule (all-vs-all)");
showHistogram(msdPerMoleculeAdjacent, "MSD/Molecule (adjacent)");
}
if (displayDHistogram) {
showHistogram(dPerMoleculeAllVsAll, "D/Molecule (all-vs-all)");
showHistogram(dPerMoleculeAdjacent, "D/Molecule (adjacent)");
}
}
// Calculate the mean squared distance (MSD)
double[] x = new double[stats.length];
double[] y = new double[x.length];
double[] sd = new double[x.length];
// Intercept is the 4s^2 (in um^2)
y[0] = 4 * precision * precision / 1e6;
for (int i = 1; i < stats.length; i++) {
x[i] = i * exposureTime;
y[i] = stats[i].getMean() * px2ToUm2;
//sd[i] = stats[i].getStandardDeviation() * px2ToUm2;
sd[i] = stats[i].getStandardError() * px2ToUm2;
}
String title = TITLE + " MSD";
Plot2 plot = plotMSD(x, y, sd, title);
// Fit the MSD using a linear fit
fitMSDResult = fitMSD(x, y, title, plot);
// Jump Distance analysis
if (saveRawData)
saveStatistics(jumpDistances, "Jump Distance", "Distance (um^2)", false);
// Calculate the cumulative jump-distance histogram
double[][] jdHistogram = JumpDistanceAnalysis.cumulativeHistogram(jumpDistances.getValues());
// Always show the jump distance histogram
jdTitle = TITLE + " Jump Distance";
jdPlot = new Plot2(jdTitle, "Distance (um^2)", "Cumulative Probability", jdHistogram[0], jdHistogram[1]);
display(jdTitle, jdPlot);
// Fit Jump Distance cumulative probability
n = jumpDistances.getN();
jumpDistanceParameters = jdParams = fitJumpDistance(jumpDistances, jdHistogram);
}
summarise(traces, fitMSDResult, n, jdParams);
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class SplitResults 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, "There are no fitting results in memory");
return;
}
String[] items = Utils.getImageList(Utils.GREY_8_16);
if (items.length == 0) {
IJ.error(TITLE, "There are no suitable mask images");
return;
}
// Show a dialog allowing the results set to be filtered
ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Select a dataset to split");
ResultsManager.addInput(gd, inputOption, InputSource.MEMORY);
gd.addChoice("Object_mask", items, objectMask);
gd.addCheckbox("Show_object_mask", showObjectMask);
gd.addCheckbox("Non_mask_dataset", nonMaskDataset);
gd.showDialog();
if (gd.wasCanceled())
return;
inputOption = ResultsManager.getInputSource(gd);
objectMask = gd.getNextChoice();
showObjectMask = gd.getNextBoolean();
nonMaskDataset = gd.getNextBoolean();
MemoryPeakResults results = ResultsManager.loadInputResults(inputOption, false);
if (results == null || results.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
return;
}
ImagePlus imp = WindowManager.getImage(objectMask);
if (imp == null) {
IJ.error(TITLE, "No object mask could be found");
return;
}
splitResults(results, imp.getProcessor());
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class SpotAnalysis method addCandidateFrames.
private void addCandidateFrames(String title) {
for (MemoryPeakResults r : MemoryPeakResults.getAllResults()) {
if (r.getSource() instanceof IJImageSource && r.getSource().getName().equals(title)) {
float minx = areaBounds.x;
float maxx = minx + areaBounds.width;
float miny = areaBounds.y;
float maxy = miny + areaBounds.height;
for (PeakResult p : r.getResults()) {
if (p.getXPosition() >= minx && p.getXPosition() <= maxx && p.getYPosition() >= miny && p.getYPosition() <= maxy) {
candidateFrames.add(p.getFrame());
}
}
}
}
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class SpotFinderPreview method showDialog.
/*
* (non-Javadoc)
*
* @see ij.plugin.filter.ExtendedPlugInFilter#showDialog(ij.ImagePlus, java.lang.String,
* ij.plugin.filter.PlugInFilterRunner)
*/
public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
this.o = imp.getOverlay();
this.imp = imp;
String filename = SettingsManager.getSettingsFilename();
GlobalSettings settings = SettingsManager.loadSettings(filename);
config = settings.getFitEngineConfiguration();
fitConfig = config.getFitConfiguration();
NonBlockingGenericDialog gd = new NonBlockingGenericDialog(TITLE);
gd.addHelp(About.HELP_URL);
gd.addMessage("Preview candidate maxima");
String[] templates = ConfigurationTemplate.getTemplateNames(true);
gd.addChoice("Template", templates, templates[0]);
gd.addStringField("Config_file", filename, 40);
gd.addNumericField("Initial_StdDev0", fitConfig.getInitialPeakStdDev0(), 3);
String[] filterTypes = SettingsManager.getNames((Object[]) DataFilterType.values());
gd.addChoice("Spot_filter_type", filterTypes, filterTypes[config.getDataFilterType().ordinal()]);
String[] filterNames = SettingsManager.getNames((Object[]) DataFilter.values());
gd.addChoice("Spot_filter", filterNames, filterNames[config.getDataFilter(0).ordinal()]);
gd.addSlider("Smoothing", 0, 2.5, config.getSmooth(0));
gd.addSlider("Search_width", 0.5, 2.5, config.getSearch());
gd.addSlider("Border", 0.5, 2.5, config.getBorder());
// Find if this image was created with ground truth data
if (imp.getID() == CreateData.getImageId()) {
MemoryPeakResults results = CreateData.getResults();
if (results != null) {
gd.addSlider("Match_distance", 0, 2.5, distance);
gd.addCheckbox("Show TP", showTP);
gd.addCheckbox("Show FP", showFP);
gd.addMessage("");
label = (Label) gd.getMessage();
// Integer coords
actualCoordinates = ResultsMatchCalculator.getCoordinates(results.getResults(), true);
}
}
if (!(IJ.isMacro() || java.awt.GraphicsEnvironment.isHeadless())) {
// Listen for changes to an image
ImagePlus.addImageListener(this);
}
gd.addPreviewCheckbox(pfr);
gd.addDialogListener(this);
gd.hideCancelButton();
gd.setOKLabel("Close");
gd.showDialog();
if (!(IJ.isMacro() || java.awt.GraphicsEnvironment.isHeadless()))
ImagePlus.removeImageListener(this);
if (!gd.wasCanceled()) {
filename = gd.getNextString();
if (SettingsManager.saveSettings(settings, filename, true))
SettingsManager.saveSettingsFilename(filename);
else
IJ.error(TITLE, "Failed to save settings to file " + filename);
}
// Reset
imp.setOverlay(o);
return DONE;
}
use of gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class SpotAnalysis method saveTraces.
private void saveTraces() {
if (!onFrames.isEmpty() && updated) {
GenericDialog gd = new GenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
gd.addMessage("The list contains unsaved selected frames.\n \nDo you want to continue?");
gd.showDialog();
if (!gd.wasOKed())
return;
}
// For all spots in the results window, get the ID and then save the traces to memory
if (!resultsWindowShowing())
return;
// Create a results set in memory
MemoryPeakResults results = new MemoryPeakResults();
results.setName(TITLE);
results.begin();
MemoryPeakResults.addResults(results);
ArrayList<TraceResult> traceResults = new ArrayList<TraceResult>(resultsWindow.getTextPanel().getLineCount());
for (int i = 0; i < resultsWindow.getTextPanel().getLineCount(); i++) {
String line = resultsWindow.getTextPanel().getLine(i);
Scanner s = new Scanner(line);
s.useDelimiter("\t");
int id = -1;
double signal = -1;
// Be careful as the text panel may not contain what we expect, i.e. empty lines, etc
if (s.hasNextInt()) {
id = s.nextInt();
try {
// cx
s.nextDouble();
// cy
s.nextDouble();
signal = s.nextDouble();
} catch (InputMismatchException e) {
// Ignore
} catch (NoSuchElementException e) {
// Ignore
}
}
s.close();
if (id != -1 && signal != -1) {
Trace trace = traces.get(id);
if (trace != null) {
results.addAll(trace.getPoints());
traceResults.add(new TraceResult(new Spot(id, signal), trace));
}
}
}
results.end();
saveTracesToFile(traceResults);
IJ.showStatus("Saved traces");
}
Aggregations