Search in sources :

Example 1 with PeakResultStoreList

use of uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList in project GDSC-SMLM by aherbert.

the class PulseActivationAnalysis method createActivations.

/**
 * Creates the activations. This splits the input traces into continuous chains of localisations.
 * Each chain is an activation. A new activation is created if there are more than the configured
 * number of dark frames since the last localisation. The start frame for the activation defines
 * the channel the activation is assigned to (this may be channel 0 if the start frame is not in a
 * pulse start frame).
 */
@SuppressWarnings("null")
private void createActivations() {
    final LocalList<Activation> activations = new LocalList<>(traces.length);
    // Activations are only counted if there are at least
    // n frames between localisations.
    final int n = settings.darkFramesForNewActivation + 1;
    for (final Trace trace : traces) {
        // Time-order
        trace.sort();
        final PeakResultStoreList points = trace.getPoints();
        // Define the frame for a new activation
        int nextActivationStartFrame = Integer.MIN_VALUE;
        Trace current = null;
        int channel = 0;
        for (int j = 0; j < points.size(); j++) {
            final PeakResult p = points.get(j);
            // Check if this is an activation
            if (p.getFrame() >= nextActivationStartFrame) {
                if (current != null) {
                    // Store the last
                    activations.add(new Activation(current, channel));
                }
                // Create a new activation
                current = new Trace(p);
                channel = getChannel(p);
            } else {
                // This is the same chain of localisations
                current.add(p);
            }
            nextActivationStartFrame = p.getEndFrame() + n;
        }
        if (current != null) {
            activations.add(new Activation(current, channel));
        }
    }
    save(activations);
}
Also used : Trace(uk.ac.sussex.gdsc.smlm.results.Trace) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) PeakResultStoreList(uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList) IdPeakResult(uk.ac.sussex.gdsc.smlm.results.IdPeakResult) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult)

Example 2 with PeakResultStoreList

use of uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList in project GDSC-SMLM by aherbert.

the class TraceDiffusion method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    jumpDistanceParametersRef.set(null);
    extraOptions = ImageJUtils.isExtraOptions();
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(TITLE, "No localisations in memory");
        return;
    }
    settings = Settings.load();
    // Saved by reference so just save now
    settings.save();
    final ArrayList<MemoryPeakResults> allResults = new ArrayList<>();
    // Option to pick multiple input datasets together using a list box.
    if ("multi".equals(arg) && !showMultiDialog(allResults)) {
        return;
    }
    // This shows the dialog for selecting trace options
    if (!showTraceDialog(allResults)) {
        return;
    }
    if (allResults.isEmpty()) {
        return;
    }
    ImageJUtils.log(TITLE + "...");
    // - Trace each single dataset (and store in memory)
    // - Combine trace results held in memory
    final Trace[] traces = getTraces(allResults);
    // This still allows a zero entry in the results table.
    if (traces.length > 0 && !showDialog()) {
        return;
    }
    final int count = traces.length;
    double[] fitMsdResult = null;
    int numberOfDataPoints = 0;
    double[][] jdParams = null;
    if (count > 0) {
        calculatePrecision(traces, allResults.size() > 1);
        // --- MSD Analysis ---
        // Conversion constants
        final double px2ToUm2 = MathUtils.pow2(results.getCalibrationReader().getNmPerPixel()) / 1e6;
        final double px2ToUm2PerSecond = px2ToUm2 / exposureTime;
        // Get the maximum trace length
        int length = clusteringSettings.getMinimumTraceLength();
        if (!clusteringSettings.getTruncate()) {
            for (final Trace trace : traces) {
                if (length < trace.size()) {
                    length = trace.size();
                }
            }
        }
        // Get the localisation error (4s^2) in um^2
        final double error = (clusteringSettings.getPrecisionCorrection()) ? 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 (clusteringSettings.getMsdCorrection()) {
            factors = new double[length];
            for (int t = 1; t < length; t++) {
                factors[t] = JumpDistanceAnalysis.getConversionfactor(t);
            }
        } else {
            factors = SimpleArrayUtils.newArray(length, 0.0, 1.0);
        }
        // Extract the mean-squared distance statistics
        final Statistics[] stats = new Statistics[length];
        for (int i = 0; i < stats.length; i++) {
            stats[i] = new Statistics();
        }
        final ArrayList<double[]> distances = (settings.saveTraceDistances || settings.displayTraceLength) ? new ArrayList<>(traces.length) : null;
        // Store all the jump distances at the specified interval
        final StoredDataStatistics jumpDistances = new StoredDataStatistics();
        final int jumpDistanceInterval = clusteringSettings.getJumpDistance();
        // Compute squared distances
        final StoredDataStatistics msdPerMoleculeAllVsAll = new StoredDataStatistics();
        final StoredDataStatistics msdPerMoleculeAdjacent = new StoredDataStatistics();
        for (final Trace trace : traces) {
            final PeakResultStoreList results = trace.getPoints();
            // Sum the MSD and the time
            final int traceLength = (clusteringSettings.getTruncate()) ? clusteringSettings.getMinimumTraceLength() : trace.size();
            // Get the mean for each time separation
            final double[] sumDistance = new double[traceLength + 1];
            final double[] sumTime = new double[sumDistance.length];
            // Do the distances to the origin (saving if necessary)
            final float x0 = results.get(0).getXPosition();
            final float y0 = results.get(0).getYPosition();
            if (distances != null) {
                final double[] msd = new double[traceLength - 1];
                for (int j = 1; j < traceLength; j++) {
                    final int t = j;
                    final double d = distance2(x0, y0, 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(x0, y0, results.get(j));
                    if (t == jumpDistanceInterval) {
                        jumpDistances.add(px2ToUm2 * d);
                    }
                    sumDistance[t] += d;
                    sumTime[t] += t;
                }
            }
            if (clusteringSettings.getInternalDistances()) {
                // 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;
            final double sumD_adjacent = Math.max(0, sumDistance[1] - error) * factors[1];
            double sumT = 0;
            final double 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 (settings.saveTraceDistances || (clusteringSettings.getShowHistograms() && settings.displayDHistogram)) {
            dperMoleculeAllVsAll = calculateDiffusionCoefficient(msdPerMoleculeAllVsAll);
            dperMoleculeAdjacent = calculateDiffusionCoefficient(msdPerMoleculeAdjacent);
        }
        if (settings.saveTraceDistances) {
            saveTraceDistances(traces.length, distances, msdPerMoleculeAllVsAll, msdPerMoleculeAdjacent, dperMoleculeAllVsAll, dperMoleculeAdjacent);
        }
        if (settings.displayTraceLength) {
            final StoredDataStatistics lengths = calculateTraceLengths(distances);
            showHistogram(lengths, "Trace length (um)");
        }
        if (settings.displayTraceSize) {
            final StoredDataStatistics sizes = calculateTraceSizes(traces);
            showHistogram(sizes, "Trace size", true);
        }
        // Plot the per-trace histogram of MSD and D
        if (clusteringSettings.getShowHistograms()) {
            if (settings.displayMsdHistogram) {
                showHistogram(msdPerMoleculeAllVsAll, "MSD/Molecule (all-vs-all)");
                showHistogram(msdPerMoleculeAdjacent, "MSD/Molecule (adjacent)");
            }
            if (settings.displayDHistogram) {
                showHistogram(dperMoleculeAllVsAll, "D/Molecule (all-vs-all)");
                showHistogram(dperMoleculeAdjacent, "D/Molecule (adjacent)");
            }
        }
        // Calculate the mean squared distance (MSD)
        final double[] x = new double[stats.length];
        final double[] y = new double[x.length];
        final 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;
        }
        final String title = TITLE + " MSD";
        final Plot plot = plotMsd(x, y, sd, title);
        // Fit the MSD using a linear fit
        fitMsdResult = fitMsd(x, y, title, plot);
        // Jump Distance analysis
        if (settings.saveRawData) {
            saveStatistics(jumpDistances, "Jump Distance", "Distance (um^2)", false);
        }
        // Calculate the cumulative jump-distance histogram
        final double[][] jdHistogram = JumpDistanceAnalysis.cumulativeHistogram(jumpDistances.getValues());
        // Always show the jump distance histogram
        jdTitle = TITLE + " Jump Distance";
        jdPlot = new Plot(jdTitle, "Distance (um^2)", "Cumulative Probability");
        jdPlot.addPoints(jdHistogram[0], jdHistogram[1], Plot.LINE);
        display(jdTitle, jdPlot);
        // Fit Jump Distance cumulative probability
        numberOfDataPoints = jumpDistances.getN();
        jdParams = fitJumpDistance(jumpDistances, jdHistogram);
        jumpDistanceParametersRef.set(jdParams);
    }
    summarise(traces, fitMsdResult, numberOfDataPoints, jdParams);
}
Also used : PeakResultStoreList(uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList) Plot(ij.gui.Plot) ArrayList(java.util.ArrayList) StoredDataStatistics(uk.ac.sussex.gdsc.core.utils.StoredDataStatistics) StoredDataStatistics(uk.ac.sussex.gdsc.core.utils.StoredDataStatistics) Statistics(uk.ac.sussex.gdsc.core.utils.Statistics) Trace(uk.ac.sussex.gdsc.smlm.results.Trace) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)

Example 3 with PeakResultStoreList

use of uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList in project GDSC-SMLM by aherbert.

the class PeakResultTableModelFrameDemo method main.

/**
 * Launch the application.
 *
 * @param args the arguments
 */
public static void main(String[] args) {
    final SplitMix r = SplitMix.new64(System.currentTimeMillis());
    final int n = 20;
    final ListSelectionModel selectionModel = new DefaultListSelectionModel();
    EventQueue.invokeLater((Runnable) () -> {
        try {
            final PeakResultStoreList store = new ArrayPeakResultStore(10);
            for (int i = n; i-- > 0; ) {
                store.add(new PeakResult(r.nextInt(), r.nextInt(), r.nextInt(), r.nextFloat(), r.nextDouble(), r.nextFloat(), r.nextFloat(), PeakResult.createParams(r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat()), null));
            }
            final CalibrationWriter cw = new CalibrationWriter();
            cw.setNmPerPixel(100);
            cw.setCountPerPhoton(10);
            cw.setDistanceUnit(DistanceUnit.PIXEL);
            cw.setIntensityUnit(IntensityUnit.COUNT);
            final ResultsTableSettings.Builder tableSettings = ResultsTableSettings.newBuilder();
            tableSettings.setDistanceUnit(DistanceUnit.NM);
            tableSettings.setIntensityUnit(IntensityUnit.PHOTON);
            tableSettings.setShowFittingData(true);
            tableSettings.setShowNoiseData(true);
            tableSettings.setShowPrecision(true);
            tableSettings.setRoundingPrecision(4);
            final PeakResultTableModel model = new PeakResultTableModel(store, cw.getCalibration(), null, tableSettings.build());
            final PeakResultTableModelFrame d = new PeakResultTableModelFrame(model, null, selectionModel);
            d.setTitle("D");
            d.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
            d.setVisible(true);
            // Selecting in one list activates the other list
            final PeakResultTableModelFrame d2 = new PeakResultTableModelFrame(model, null, selectionModel);
            d2.setTitle("D2");
            // Since we have the same selection model we need the same row sorter,
            // otherwise the selection is scrambled by sorting.
            // The alternative would be to get the source for the selection event (the table)
            // and get the row sorter to do the mapping.
            // However this breaks deletion of data as the row sorter double processes the deletion.
            // Basically only one table can use the same selection model when sorting is desired.
            // d2.table.setRowSorter(d.table.getRowSorter())
            d2.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
            d2.setVisible(true);
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
    });
}
Also used : PeakResultStoreList(uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList) SplitMix(uk.ac.sussex.gdsc.core.utils.rng.SplitMix) ListSelectionModel(javax.swing.ListSelectionModel) DefaultListSelectionModel(javax.swing.DefaultListSelectionModel) CalibrationWriter(uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter) DefaultListSelectionModel(javax.swing.DefaultListSelectionModel) ArrayPeakResultStore(uk.ac.sussex.gdsc.smlm.results.ArrayPeakResultStore) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult)

Aggregations

PeakResultStoreList (uk.ac.sussex.gdsc.smlm.results.PeakResultStoreList)3 PeakResult (uk.ac.sussex.gdsc.smlm.results.PeakResult)2 Trace (uk.ac.sussex.gdsc.smlm.results.Trace)2 Plot (ij.gui.Plot)1 ArrayList (java.util.ArrayList)1 DefaultListSelectionModel (javax.swing.DefaultListSelectionModel)1 ListSelectionModel (javax.swing.ListSelectionModel)1 LocalList (uk.ac.sussex.gdsc.core.utils.LocalList)1 Statistics (uk.ac.sussex.gdsc.core.utils.Statistics)1 StoredDataStatistics (uk.ac.sussex.gdsc.core.utils.StoredDataStatistics)1 SplitMix (uk.ac.sussex.gdsc.core.utils.rng.SplitMix)1 CalibrationWriter (uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter)1 ArrayPeakResultStore (uk.ac.sussex.gdsc.smlm.results.ArrayPeakResultStore)1 IdPeakResult (uk.ac.sussex.gdsc.smlm.results.IdPeakResult)1 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)1