Search in sources :

Example 11 with DistanceUnit

use of uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit in project GDSC-SMLM by aherbert.

the class CalibrationReaderTest method canGetDistanceConverter.

@Test
void canGetDistanceConverter() {
    final Calibration.Builder builder = Calibration.newBuilder();
    final DistanceCalibration.Builder distanceBuilder = builder.getDistanceCalibrationBuilder();
    distanceBuilder.setNmPerPixel(nmPerPixel);
    distanceBuilder.setDistanceUnit(DistanceUnit.PIXEL);
    final Calibration c = builder.build();
    final CalibrationReader reader = new CalibrationReader(c);
    final TypeConverter<DistanceUnit> distanceConverter = reader.getDistanceConverter(DistanceUnit.NM);
    Assertions.assertEquals(distanceConverter.from(), DistanceUnit.PIXEL);
    Assertions.assertEquals(distanceConverter.to(), DistanceUnit.NM);
    final TypeConverter<DistanceUnit> distanceConverter2 = CalibrationHelper.getDistanceConverter(c, DistanceUnit.NM);
    Assertions.assertEquals(distanceConverter2.from(), DistanceUnit.PIXEL);
    Assertions.assertEquals(distanceConverter2.to(), DistanceUnit.NM);
    Assertions.assertEquals(distanceConverter.getFunction(), distanceConverter2.getFunction());
}
Also used : DistanceCalibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.DistanceCalibration) Calibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration) DistanceCalibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.DistanceCalibration) IntensityCalibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.IntensityCalibration) AngleCalibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.AngleCalibration) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) Test(org.junit.jupiter.api.Test)

Example 12 with DistanceUnit

use of uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit in project GDSC-SMLM by aherbert.

the class DistanceUnitTest method check.

private static void check(double nmPerPixel, ExpectedUnit<DistanceUnit>... expectedUnits) {
    final int n = expectedUnits.length;
    TypeConverter<DistanceUnit> conv;
    for (int i = 0; i < n; i++) {
        final DistanceUnit u1 = expectedUnits[i].unit;
        final double v1 = expectedUnits[i].value;
        for (int j = 0; j < n; j++) {
            final DistanceUnit u2 = expectedUnits[j].unit;
            conv = UnitConverterUtils.createConverter(u1, u2, nmPerPixel);
            final double o = conv.convert(v1);
            Assertions.assertEquals(expectedUnits[j].value, o, 1e-5, () -> u1 + " to " + u2);
        }
    }
}
Also used : DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit)

Example 13 with DistanceUnit

use of uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit in project GDSC-SMLM by aherbert.

the class PsfProtosHelperTest method canConvertAstigmatismModel.

@Test
void canConvertAstigmatismModel() {
    // Use a reasonable z-depth function from the Smith, et al (2010) paper (page 377)
    final double sx = 1.08;
    final double sy = 1.01;
    final double gamma = 0.389;
    final double d = 0.531;
    final double Ax = -0.0708;
    final double Bx = -0.073;
    final double Ay = 0.164;
    final double By = 0.0417;
    final double nmPerPixel = 100;
    // Ax = Ay = 0;
    // Bx = By = 0;
    final DistanceUnit zDistanceUnit = DistanceUnit.UM;
    final DistanceUnit sDistanceUnit = DistanceUnit.PIXEL;
    final AstigmatismModel.Builder builder = AstigmatismModel.newBuilder();
    builder.setGamma(gamma);
    builder.setD(d);
    builder.setS0X(sx);
    builder.setAx(Ax);
    builder.setBx(Bx);
    builder.setS0Y(sy);
    builder.setAy(Ay);
    builder.setBy(By);
    builder.setZDistanceUnit(zDistanceUnit);
    builder.setSDistanceUnit(sDistanceUnit);
    builder.setNmPerPixel(nmPerPixel);
    final AstigmatismModel model1 = builder.build();
    final PSF psf = PsfProtosHelper.createPsf(model1, zDistanceUnit, sDistanceUnit);
    final AstigmatismModel model2 = PsfProtosHelper.createModel(psf, zDistanceUnit, sDistanceUnit, nmPerPixel);
    Assertions.assertEquals(model1, model2);
}
Also used : PSF(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSF) AstigmatismModel(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.AstigmatismModel) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) Test(org.junit.jupiter.api.Test)

Example 14 with DistanceUnit

use of uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit in project GDSC-SMLM by aherbert.

the class TraceDiffusion method showMultiDialog.

private boolean showMultiDialog(ArrayList<MemoryPeakResults> allResults) {
    multiMode = true;
    // Show a list box containing all the results. This should remember the last set of chosen
    // items.
    final MultiDialog md = ResultsManager.createMultiDialog(TITLE);
    md.setSelected(selectedRef.get());
    md.setHelpUrl(HelpUrls.getUrl("trace-diffusion-multi"));
    md.showDialog();
    if (md.wasCancelled()) {
        return false;
    }
    final List<String> selected = md.getSelectedResults();
    if (selected.isEmpty()) {
        IJ.error(TITLE, "No results were selected");
        return false;
    }
    selectedRef.set(selected);
    for (final String name : selected) {
        final MemoryPeakResults r = MemoryPeakResults.getResults(name);
        if (r != null) {
            allResults.add(r);
        }
    }
    if (allResults.isEmpty()) {
        return false;
    }
    // Check calibration exists for the first set of results
    if (!checkCalibration(allResults.get(0))) {
        return false;
    }
    // Check the calibration is the same for the rest
    final CalibrationReader cal = allResults.get(0).getCalibrationReader();
    final double nmPerPixel = cal.getNmPerPixel();
    final double exposureTime = cal.getExposureTime();
    final DistanceUnit distanceUnit = cal.getDistanceUnit();
    for (int i = 1; i < allResults.size(); i++) {
        final MemoryPeakResults results = allResults.get(i);
        if (!results.hasCalibration() || results.getCalibrationReader().getExposureTime() != exposureTime || results.getNmPerPixel() != nmPerPixel || results.getDistanceUnit() != distanceUnit) {
            IJ.error(TITLE, "The exposure time, pixel pitch and distance unit must match across all the results");
            return false;
        }
    }
    return true;
}
Also used : MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) CalibrationReader(uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) MultiDialog(uk.ac.sussex.gdsc.core.ij.gui.MultiDialog)

Example 15 with DistanceUnit

use of uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit in project GDSC-SMLM by aherbert.

the class TrackPopulationAnalysis method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(TITLE, "No localisations in memory");
        return;
    }
    settings = Settings.load();
    // Saved by reference so just save now
    settings.save();
    // Read in multiple traced datasets
    // All datasets must have the same pixel pitch and exposure time
    // Get parameters
    // Convert datasets to tracks
    // For each track compute the 4 local track features using the configured window
    // 
    // Optional:
    // Fit a multi-variate Gaussian mixture model to the data
    // (using the configured number of components/populations)
    // Assign each point in the track using the model.
    // Smooth the assignments.
    // 
    // The alternative is to use the localisation category to assign populations.
    // 
    // Plot histograms of each track parameter, coloured by component
    final List<MemoryPeakResults> combinedResults = new LocalList<>();
    if (!showInputDialog(combinedResults)) {
        return;
    }
    final boolean hasCategory = showHasCategoryDialog(combinedResults);
    if (!showDialog(hasCategory)) {
        return;
    }
    ImageJUtils.log(TITLE + "...");
    final List<Trace> tracks = getTracks(combinedResults, settings.window, settings.minTrackLength);
    if (tracks.isEmpty()) {
        IJ.error(TITLE, "No tracks. Please check the input data and min track length setting.");
        return;
    }
    final Calibration cal = combinedResults.get(0).getCalibration();
    final CalibrationReader cr = new CalibrationReader(cal);
    // Use micrometer / second
    final TypeConverter<DistanceUnit> distanceConverter = cr.getDistanceConverter(DistanceUnit.UM);
    final double exposureTime = cr.getExposureTime() / 1000.0;
    final Pair<int[], double[][]> trackData = extractTrackData(tracks, distanceConverter, exposureTime, hasCategory);
    final double[][] data = trackData.getValue();
    // Histogram the raw data.
    final Array2DRowRealMatrix raw = new Array2DRowRealMatrix(data, false);
    final WindowOrganiser wo = new WindowOrganiser();
    // Store the histogram data for plotting the components
    final double[][] columns = new double[FEATURE_NAMES.length][];
    final double[][] limits = new double[FEATURE_NAMES.length][];
    // Get column data
    for (int i = 0; i < FEATURE_NAMES.length; i++) {
        columns[i] = raw.getColumn(i);
        if (i == FEATURE_D) {
            // Plot using a logarithmic scale
            SimpleArrayUtils.apply(columns[i], Math::log10);
        }
        limits[i] = MathUtils.limits(columns[i]);
    }
    // Compute histogram bins
    final int[] bins = new int[FEATURE_NAMES.length];
    if (settings.histogramBins > 0) {
        Arrays.fill(bins, settings.histogramBins);
    } else {
        for (int i = 0; i < FEATURE_NAMES.length; i++) {
            bins[i] = HistogramPlot.getBins(StoredData.create(columns[i]), BinMethod.FD);
        }
        // Use the maximum so all histograms look the same
        Arrays.fill(bins, MathUtils.max(bins));
    }
    // Compute plots
    final Plot[] plots = new Plot[FEATURE_NAMES.length];
    for (int i = 0; i < FEATURE_NAMES.length; i++) {
        final double[][] hist = HistogramPlot.calcHistogram(columns[i], limits[i][0], limits[i][1], bins[i]);
        plots[i] = new Plot(TITLE + " " + FEATURE_NAMES[i], getFeatureLabel(i, i == FEATURE_D), "Frequency");
        plots[i].addPoints(hist[0], hist[1], Plot.BAR);
        ImageJUtils.display(plots[i].getTitle(), plots[i], ImageJUtils.NO_TO_FRONT, wo);
    }
    wo.tile();
    // The component for each data point
    int[] component;
    // The number of components
    int numComponents;
    // Data used to fit the Gaussian mixture model
    double[][] fitData;
    // The fitted model
    MixtureMultivariateGaussianDistribution model;
    if (hasCategory) {
        // Use the category as the component.
        // No fit data and no output model
        fitData = null;
        model = null;
        // The component is stored at the end of the raw track data.
        final int end = data[0].length - 1;
        component = Arrays.stream(data).mapToInt(d -> (int) d[end]).toArray();
        numComponents = MathUtils.max(component) + 1;
        // In the EM algorithm the probability of each data point is computed and normalised to
        // sum to 1. The normalised probabilities are averaged to create the weights.
        // Note the probability of each data point uses the previous weight and the algorithm
        // iterates.
        // This is not a fitted model but the input model so use
        // zero weights to indicate no fitting was performed.
        final double[] weights = new double[numComponents];
        // Remove the trailing component to show the 'model' in a table.
        createModelTable(Arrays.stream(data).map(d -> Arrays.copyOf(d, end)).toArray(double[][]::new), weights, component);
    } else {
        // Multivariate Gaussian mixture EM
        // Provide option to not use the anomalous exponent in the population mix.
        int sortDimension = SORT_DIMENSION;
        if (settings.ignoreAlpha) {
            // Remove index 0. This shifts the sort dimension.
            sortDimension--;
            fitData = Arrays.stream(data).map(d -> Arrays.copyOfRange(d, 1, d.length)).toArray(double[][]::new);
        } else {
            fitData = SimpleArrayUtils.deepCopy(data);
        }
        final MultivariateGaussianMixtureExpectationMaximization mixed = fitGaussianMixture(fitData, sortDimension);
        if (mixed == null) {
            IJ.error(TITLE, "Failed to fit a mixture model");
            return;
        }
        model = sortComponents(mixed.getFittedModel(), sortDimension);
        // For the best model, assign to the most likely population.
        component = assignData(fitData, model);
        // Table of the final model using the original data (i.e. not normalised)
        final double[] weights = model.getWeights();
        numComponents = weights.length;
        createModelTable(data, weights, component);
    }
    // Output coloured histograms of the populations.
    final LUT lut = LutHelper.createLut(settings.lutIndex);
    IntFunction<Color> colourMap;
    if (LutHelper.getColour(lut, 0).equals(Color.BLACK)) {
        colourMap = i -> LutHelper.getNonZeroColour(lut, i, 0, numComponents - 1);
    } else {
        colourMap = i -> LutHelper.getColour(lut, i, 0, numComponents - 1);
    }
    for (int i = 0; i < FEATURE_NAMES.length; i++) {
        // Extract the data for each component
        final double[] col = columns[i];
        final Plot plot = plots[i];
        for (int n = 0; n < numComponents; n++) {
            final StoredData feature = new StoredData();
            for (int j = 0; j < component.length; j++) {
                if (component[j] == n) {
                    feature.add(col[j]);
                }
            }
            if (feature.size() == 0) {
                continue;
            }
            final double[][] hist = HistogramPlot.calcHistogram(feature.values(), limits[i][0], limits[i][1], bins[i]);
            // Colour the points
            plot.setColor(colourMap.apply(n));
            plot.addPoints(hist[0], hist[1], Plot.BAR);
        }
        plot.updateImage();
    }
    createTrackDataTable(tracks, trackData, fitData, model, component, cal, colourMap);
// Analysis.
// Assign the original localisations to their track component.
// Q. What about the start/end not covered by the window?
// Save tracks as a dataset labelled with the sub-track ID?
// Output for the bound component and free components track parameters.
// Compute dwell times.
// Other ...
// Track analysis plugin:
// Extract all continuous segments of the same component.
// Produce MSD plot with error bars.
// Fit using FBM model.
}
Also used : LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) Array2DRowRealMatrix(org.apache.commons.math3.linear.Array2DRowRealMatrix) MixtureMultivariateGaussianDistribution(uk.ac.sussex.gdsc.smlm.math3.distribution.fitting.MultivariateGaussianMixtureExpectationMaximization.MixtureMultivariateGaussianDistribution) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) Plot(ij.gui.Plot) HistogramPlot(uk.ac.sussex.gdsc.core.ij.HistogramPlot) Color(java.awt.Color) LUT(ij.process.LUT) Calibration(uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration) WindowOrganiser(uk.ac.sussex.gdsc.core.ij.plugin.WindowOrganiser) CalibrationReader(uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader) Trace(uk.ac.sussex.gdsc.smlm.results.Trace) MultivariateGaussianMixtureExpectationMaximization(uk.ac.sussex.gdsc.smlm.math3.distribution.fitting.MultivariateGaussianMixtureExpectationMaximization) StoredData(uk.ac.sussex.gdsc.core.utils.StoredData)

Aggregations

DistanceUnit (uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit)21 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)7 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)6 IntensityUnit (uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.IntensityUnit)6 CalibrationReader (uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader)5 PeakResult (uk.ac.sussex.gdsc.smlm.results.PeakResult)5 IJ (ij.IJ)3 Plot (ij.gui.Plot)3 PlugIn (ij.plugin.PlugIn)3 ArrayList (java.util.ArrayList)3 ConversionException (uk.ac.sussex.gdsc.core.data.utils.ConversionException)3 TypeConverter (uk.ac.sussex.gdsc.core.data.utils.TypeConverter)3 MultiDialog (uk.ac.sussex.gdsc.core.ij.gui.MultiDialog)3 PeakResultProcedure (uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure)3 ImagePlus (ij.ImagePlus)2 PointRoi (ij.gui.PointRoi)2 Rectangle (java.awt.Rectangle)2 List (java.util.List)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 Test (org.junit.jupiter.api.Test)2