Search in sources :

Example 26 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class OptimumDistanceResultFilter method finalise.

/*
	 * (non-Javadoc)
	 * 
	 * @see gdsc.smlm.engine.filter.ResultFilter#finalise()
	 */
@Override
public void finalise() {
    // Note that there could be the same result allocated to two target positions
    // so find the unique results
    int[] uniqueIndices = new int[bestIndices.length];
    int unique = 0;
    for (int i = 0; i < bestIndices.length; i++) {
        if (bestFitResults[i] == null)
            continue;
        boolean found = false;
        for (int j = unique; j-- > 0; ) {
            if (bestIndices[uniqueIndices[j]] == bestIndices[i]) {
                found = true;
                break;
            }
        }
        if (!found)
            uniqueIndices[unique++] = i;
    }
    // The fit results and the indices must match so preserve the same order
    filteredCount = unique;
    filteredFitResults = new FitResult[unique];
    filteredIndices = new int[unique];
    for (int i = 0; i < unique; i++) {
        filteredFitResults[i] = bestFitResults[uniqueIndices[i]];
        filteredIndices[i] = bestIndices[uniqueIndices[i]];
    }
    // The peak results can be in any order so use a set to find the unique results
    if (unique > 0) {
        TreeSet<PeakResult> set = new TreeSet<PeakResult>();
        for (PeakResult r : bestPeakResults) {
            if (r != null)
                set.add(r);
        }
        peakResults = new ArrayList<PeakResult>(set.size());
        peakResults.addAll(set);
    } else {
        peakResults = new ArrayList<PeakResult>();
    }
}
Also used : TreeSet(java.util.TreeSet) PeakResult(gdsc.smlm.results.PeakResult)

Example 27 with PeakResult

use of gdsc.smlm.results.PeakResult 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 28 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class SpotAnalysis method saveTracesToFile.

private void saveTracesToFile(ArrayList<TraceResult> traceResults) {
    String resultsDirectory = IJ.getDirectory(TITLE);
    if (resultsDirectory == null)
        return;
    // Save the traces to a single file. 
    // Also save the blinks and on/off times into data files for histogram analysis
    BufferedWriter[] files = new BufferedWriter[5];
    try {
        files[0] = openBufferedWriter(resultsDirectory + "traces.txt", String.format("#ms/frame = %s\n#Id\tcx\tcy\tsignal\tn-Blinks\tStart\tStop\t...", Utils.rounded(msPerFrame, 3)));
        files[1] = openBufferedWriter(resultsDirectory + "tOn.txt", "");
        files[2] = openBufferedWriter(resultsDirectory + "tOff.txt", "");
        files[3] = openBufferedWriter(resultsDirectory + "blinks.txt", "");
        files[4] = openBufferedWriter(resultsDirectory + "signal.txt", "");
        for (TraceResult traceResult : traceResults) {
            StringBuffer sb = new StringBuffer();
            sb.append(traceResult.spot.frame).append("\t");
            sb.append(traceResult.trace.getHead().getXPosition()).append("\t");
            sb.append(traceResult.trace.getHead().getYPosition()).append("\t");
            sb.append(traceResult.spot.signal).append("\t");
            int nBlinks = traceResult.trace.getNBlinks() - 1;
            sb.append(nBlinks);
            int[] on = traceResult.trace.getOnTimes();
            int[] off = traceResult.trace.getOffTimes();
            int t = traceResult.trace.getHead().getFrame();
            for (int i = 0; i < on.length; i++) {
                writeLine(files[1], Double.toString(msPerFrame * on[i]));
                sb.append("\t").append(t).append("\t").append(t + on[i] - 1);
                if (off != null && i < off.length) {
                    writeLine(files[2], Double.toString(msPerFrame * off[i]));
                    t += on[i] + off[i];
                }
            }
            writeLine(files[0], sb.toString());
            writeLine(files[3], Integer.toString(nBlinks));
            writeLine(files[4], String.format("# Id=%d, Blinks=%d, Signal=%f", traceResult.spot.frame, nBlinks, traceResult.spot.signal));
            for (PeakResult r : traceResult.trace.getPoints()) writeLine(files[4], String.format("%d %f", r.getFrame(), r.getSignal()));
        }
    } catch (Exception e) {
        // Q. Add better handling of errors?
        e.printStackTrace();
        IJ.log("Failed to save traces to results directory: " + resultsDirectory);
    } finally {
        for (BufferedWriter tracesFile : files) {
            if (tracesFile != null) {
                try {
                    tracesFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
Also used : IOException(java.io.IOException) Point(java.awt.Point) PeakResult(gdsc.smlm.results.PeakResult) InputMismatchException(java.util.InputMismatchException) NoSuchElementException(java.util.NoSuchElementException) IOException(java.io.IOException) BufferedWriter(java.io.BufferedWriter)

Example 29 with PeakResult

use of gdsc.smlm.results.PeakResult 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 30 with PeakResult

use of gdsc.smlm.results.PeakResult in project GDSC-SMLM by aherbert.

the class TraceDiffusion method calculatePrecision.

/**
	 * Calculate the average precision of localisation in the traces
	 * 
	 * @param traces
	 * @param multi
	 */
private void calculatePrecision(Trace[] traces, boolean multi) {
    // Check the diffusion simulation for a precision
    if (DiffusionRateTest.isSimulated(results.getName()) && !multi) {
        precision = DiffusionRateTest.lastSimulatedPrecision;
    } else {
        // Get the average precision of the localisations
        precision = 0;
        final double nmPerPixel = results.getNmPerPixel();
        final double gain = results.getGain();
        final boolean emCCD = results.isEMCCD();
        int n = 0;
        for (Trace trace : traces) {
            for (PeakResult r : trace.getPoints()) precision += r.getPrecision(nmPerPixel, gain, emCCD);
            n += trace.size();
        }
        precision /= n;
    }
    if (precision > 100) {
        ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        gd.addMessage("The average precision of the traced results is " + Utils.rounded(precision, 4) + " nm.\nPlease verify the precision.");
        gd.addSlider("Precision (nm)", 5, 100, precision);
        gd.showDialog();
        if (!(gd.wasCanceled() || gd.invalidNumber())) {
            precision = Math.abs(gd.getNextNumber());
        }
    }
}
Also used : Trace(gdsc.smlm.results.Trace) ExtendedGenericDialog(ij.gui.ExtendedGenericDialog) PeakResult(gdsc.smlm.results.PeakResult)

Aggregations

PeakResult (gdsc.smlm.results.PeakResult)89 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)40 ExtendedPeakResult (gdsc.smlm.results.ExtendedPeakResult)18 Rectangle (java.awt.Rectangle)18 ArrayList (java.util.ArrayList)17 IdPeakResult (gdsc.smlm.results.IdPeakResult)13 ImagePlus (ij.ImagePlus)9 Point (java.awt.Point)9 Trace (gdsc.smlm.results.Trace)8 ImageStack (ij.ImageStack)7 FractionClassificationResult (gdsc.core.match.FractionClassificationResult)6 Calibration (gdsc.smlm.results.Calibration)6 PreprocessedPeakResult (gdsc.smlm.results.filter.PreprocessedPeakResult)6 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)6 BasePoint (gdsc.core.match.BasePoint)5 Statistics (gdsc.core.utils.Statistics)5 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)5 IJImagePeakResults (gdsc.smlm.ij.results.IJImagePeakResults)5 GenericDialog (ij.gui.GenericDialog)5 ImageProcessor (ij.process.ImageProcessor)5