Search in sources :

Example 16 with MemoryPeakResults

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);
}
Also used : ArrayList(java.util.ArrayList) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) Plot2(ij.gui.Plot2) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) Statistics(gdsc.core.utils.Statistics) PeakResult(gdsc.smlm.results.PeakResult) Trace(gdsc.smlm.results.Trace) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults)

Example 17 with MemoryPeakResults

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());
}
Also used : MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ExtendedGenericDialog(ij.gui.ExtendedGenericDialog) ImagePlus(ij.ImagePlus)

Example 18 with MemoryPeakResults

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());
                }
            }
        }
    }
}
Also used : IJImageSource(gdsc.smlm.ij.IJImageSource) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) PeakResult(gdsc.smlm.results.PeakResult)

Example 19 with MemoryPeakResults

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;
}
Also used : GlobalSettings(gdsc.smlm.ij.settings.GlobalSettings) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) NonBlockingGenericDialog(ij.gui.NonBlockingGenericDialog)

Example 20 with MemoryPeakResults

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");
}
Also used : Scanner(java.util.Scanner) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) InputMismatchException(java.util.InputMismatchException) Point(java.awt.Point) Trace(gdsc.smlm.results.Trace) GenericDialog(ij.gui.GenericDialog) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)86 PeakResult (gdsc.smlm.results.PeakResult)40 Rectangle (java.awt.Rectangle)16 ArrayList (java.util.ArrayList)13 ExtendedPeakResult (gdsc.smlm.results.ExtendedPeakResult)10 ImagePlus (ij.ImagePlus)10 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)8 Statistics (gdsc.core.utils.Statistics)7 IJImageSource (gdsc.smlm.ij.IJImageSource)7 Calibration (gdsc.smlm.results.Calibration)7 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)7 FractionClassificationResult (gdsc.core.match.FractionClassificationResult)6 IJImagePeakResults (gdsc.smlm.ij.results.IJImagePeakResults)6 Trace (gdsc.smlm.results.Trace)6 LinkedList (java.util.LinkedList)6 BasePoint (gdsc.core.match.BasePoint)5 ImageStack (ij.ImageStack)5 Plot2 (ij.gui.Plot2)5 Point (java.awt.Point)5 ClusterPoint (gdsc.core.clustering.ClusterPoint)4