Search in sources :

Example 1 with WeightedObservedPoints

use of org.apache.commons.math3.fitting.WeightedObservedPoints in project GDSC-SMLM by aherbert.

the class MeanVarianceTest method run.

/*
	 * (non-Javadoc)
	 * 
	 * @see ij.plugin.PlugIn#run(java.lang.String)
	 */
public void run(String arg) {
    SMLMUsageTracker.recordPlugin(this.getClass(), arg);
    if (Utils.isExtraOptions()) {
        ImagePlus imp = WindowManager.getCurrentImage();
        if (imp.getStackSize() > 1) {
            GenericDialog gd = new GenericDialog(TITLE);
            gd.addMessage("Perform single image analysis on the current image?");
            gd.addNumericField("Bias", _bias, 0);
            gd.showDialog();
            if (gd.wasCanceled())
                return;
            singleImage = true;
            _bias = Math.abs(gd.getNextNumber());
        } else {
            IJ.error(TITLE, "Single-image mode requires a stack");
            return;
        }
    }
    List<ImageSample> images;
    String inputDirectory = "";
    if (singleImage) {
        IJ.showStatus("Loading images...");
        images = getImages();
        if (images.size() == 0) {
            IJ.error(TITLE, "Not enough images for analysis");
            return;
        }
    } else {
        inputDirectory = IJ.getDirectory("Select image series ...");
        if (inputDirectory == null)
            return;
        SeriesOpener series = new SeriesOpener(inputDirectory, false, 0);
        series.setVariableSize(true);
        if (series.getNumberOfImages() < 3) {
            IJ.error(TITLE, "Not enough images in the selected directory");
            return;
        }
        if (!IJ.showMessageWithCancel(TITLE, String.format("Analyse %d images, first image:\n%s", series.getNumberOfImages(), series.getImageList()[0]))) {
            return;
        }
        IJ.showStatus("Loading images");
        images = getImages(series);
        if (images.size() < 3) {
            IJ.error(TITLE, "Not enough images for analysis");
            return;
        }
        if (images.get(0).exposure != 0) {
            IJ.error(TITLE, "First image in series must have exposure 0 (Bias image)");
            return;
        }
    }
    boolean emMode = (arg != null && arg.contains("em"));
    GenericDialog gd = new GenericDialog(TITLE);
    gd.addMessage("Set the output options:");
    gd.addCheckbox("Show_table", showTable);
    gd.addCheckbox("Show_charts", showCharts);
    if (emMode) {
        // Ask the user for the camera gain ...
        gd.addMessage("Estimating the EM-gain requires the camera gain without EM readout enabled");
        gd.addNumericField("Camera_gain (ADU/e-)", cameraGain, 4);
    }
    gd.showDialog();
    if (gd.wasCanceled())
        return;
    showTable = gd.getNextBoolean();
    showCharts = gd.getNextBoolean();
    if (emMode) {
        cameraGain = gd.getNextNumber();
    }
    IJ.showStatus("Computing mean & variance");
    final double nImages = images.size();
    for (int i = 0; i < images.size(); i++) {
        IJ.showStatus(String.format("Computing mean & variance %d/%d", i + 1, images.size()));
        images.get(i).compute(singleImage, i / nImages, (i + 1) / nImages);
    }
    IJ.showProgress(1);
    IJ.showStatus("Computing results");
    // Allow user to input multiple bias images
    int start = 0;
    Statistics biasStats = new Statistics();
    Statistics noiseStats = new Statistics();
    final double bias;
    if (singleImage) {
        bias = _bias;
    } else {
        while (start < images.size()) {
            ImageSample sample = images.get(start);
            if (sample.exposure == 0) {
                biasStats.add(sample.means);
                for (PairSample pair : sample.samples) {
                    noiseStats.add(pair.variance);
                }
                start++;
            } else
                break;
        }
        bias = biasStats.getMean();
    }
    // Get the mean-variance data
    int total = 0;
    for (int i = start; i < images.size(); i++) total += images.get(i).samples.size();
    if (showTable && total > 2000) {
        gd = new GenericDialog(TITLE);
        gd.addMessage("Table output requires " + total + " entries.\n \nYou may want to disable the table.");
        gd.addCheckbox("Show_table", showTable);
        gd.showDialog();
        if (gd.wasCanceled())
            return;
        showTable = gd.getNextBoolean();
    }
    TextWindow results = (showTable) ? createResultsWindow() : null;
    double[] mean = new double[total];
    double[] variance = new double[mean.length];
    Statistics gainStats = (singleImage) ? new StoredDataStatistics(total) : new Statistics();
    final WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = (singleImage) ? 0 : start, j = 0; i < images.size(); i++) {
        StringBuilder sb = (showTable) ? new StringBuilder() : null;
        ImageSample sample = images.get(i);
        for (PairSample pair : sample.samples) {
            if (j % 16 == 0)
                IJ.showProgress(j, total);
            mean[j] = pair.getMean();
            variance[j] = pair.variance;
            // Gain is in ADU / e
            double gain = variance[j] / (mean[j] - bias);
            gainStats.add(gain);
            obs.add(mean[j], variance[j]);
            if (emMode) {
                gain /= (2 * cameraGain);
            }
            if (showTable) {
                sb.append(sample.title).append("\t");
                sb.append(sample.exposure).append("\t");
                sb.append(pair.slice1).append("\t");
                sb.append(pair.slice2).append("\t");
                sb.append(IJ.d2s(pair.mean1, 2)).append("\t");
                sb.append(IJ.d2s(pair.mean2, 2)).append("\t");
                sb.append(IJ.d2s(mean[j], 2)).append("\t");
                sb.append(IJ.d2s(variance[j], 2)).append("\t");
                sb.append(Utils.rounded(gain, 4)).append("\n");
            }
            j++;
        }
        if (showTable)
            results.append(sb.toString());
    }
    IJ.showProgress(1);
    if (singleImage) {
        StoredDataStatistics stats = (StoredDataStatistics) gainStats;
        Utils.log(TITLE);
        if (emMode) {
            double[] values = stats.getValues();
            MathArrays.scaleInPlace(0.5, values);
            stats = new StoredDataStatistics(values);
        }
        if (showCharts) {
            // Plot the gain over time
            String title = TITLE + " Gain vs Frame";
            Plot2 plot = new Plot2(title, "Slice", "Gain", Utils.newArray(gainStats.getN(), 1, 1.0), stats.getValues());
            PlotWindow pw = Utils.display(title, plot);
            // Show a histogram
            String label = String.format("Mean = %s, Median = %s", Utils.rounded(stats.getMean()), Utils.rounded(stats.getMedian()));
            int id = Utils.showHistogram(TITLE, stats, "Gain", 0, 1, 100, true, label);
            if (Utils.isNewWindow()) {
                Point point = pw.getLocation();
                point.x = pw.getLocation().x;
                point.y += pw.getHeight();
                WindowManager.getImage(id).getWindow().setLocation(point);
            }
        }
        Utils.log("Single-image mode: %s camera", (emMode) ? "EM-CCD" : "Standard");
        final double gain = stats.getMedian();
        if (emMode) {
            final double totalGain = gain;
            final double emGain = totalGain / cameraGain;
            Utils.log("  Gain = 1 / %s (ADU/e-)", Utils.rounded(cameraGain, 4));
            Utils.log("  EM-Gain = %s", Utils.rounded(emGain, 4));
            Utils.log("  Total Gain = %s (ADU/e-)", Utils.rounded(totalGain, 4));
        } else {
            cameraGain = gain;
            Utils.log("  Gain = 1 / %s (ADU/e-)", Utils.rounded(cameraGain, 4));
        }
    } else {
        IJ.showStatus("Computing fit");
        // Sort
        int[] indices = rank(mean);
        mean = reorder(mean, indices);
        variance = reorder(variance, indices);
        // Compute optimal coefficients.
        // a - b x
        final double[] init = { 0, 1 / gainStats.getMean() };
        final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(2).withStartPoint(init);
        final double[] best = fitter.fit(obs.toList());
        // Construct the polynomial that best fits the data.
        final PolynomialFunction fitted = new PolynomialFunction(best);
        if (showCharts) {
            // Plot mean verses variance. Gradient is gain in ADU/e.
            String title = TITLE + " results";
            Plot2 plot = new Plot2(title, "Mean", "Variance");
            double[] xlimits = Maths.limits(mean);
            double[] ylimits = Maths.limits(variance);
            double xrange = (xlimits[1] - xlimits[0]) * 0.05;
            if (xrange == 0)
                xrange = 0.05;
            double yrange = (ylimits[1] - ylimits[0]) * 0.05;
            if (yrange == 0)
                yrange = 0.05;
            plot.setLimits(xlimits[0] - xrange, xlimits[1] + xrange, ylimits[0] - yrange, ylimits[1] + yrange);
            plot.setColor(Color.blue);
            plot.addPoints(mean, variance, Plot2.CROSS);
            plot.setColor(Color.red);
            plot.addPoints(new double[] { mean[0], mean[mean.length - 1] }, new double[] { fitted.value(mean[0]), fitted.value(mean[mean.length - 1]) }, Plot2.LINE);
            Utils.display(title, plot);
        }
        final double avBiasNoise = Math.sqrt(noiseStats.getMean());
        Utils.log(TITLE);
        Utils.log("  Directory = %s", inputDirectory);
        Utils.log("  Bias = %s +/- %s (ADU)", Utils.rounded(bias, 4), Utils.rounded(avBiasNoise, 4));
        Utils.log("  Variance = %s + %s * mean", Utils.rounded(best[0], 4), Utils.rounded(best[1], 4));
        if (emMode) {
            final double emGain = best[1] / (2 * cameraGain);
            // Noise is standard deviation of the bias image divided by the total gain (in ADU/e-)
            final double totalGain = emGain * cameraGain;
            Utils.log("  Read Noise = %s (e-) [%s (ADU)]", Utils.rounded(avBiasNoise / totalGain, 4), Utils.rounded(avBiasNoise, 4));
            Utils.log("  Gain = 1 / %s (ADU/e-)", Utils.rounded(1 / cameraGain, 4));
            Utils.log("  EM-Gain = %s", Utils.rounded(emGain, 4));
            Utils.log("  Total Gain = %s (ADU/e-)", Utils.rounded(totalGain, 4));
        } else {
            // Noise is standard deviation of the bias image divided by the gain (in ADU/e-)
            cameraGain = best[1];
            final double readNoise = avBiasNoise / cameraGain;
            Utils.log("  Read Noise = %s (e-) [%s (ADU)]", Utils.rounded(readNoise, 4), Utils.rounded(readNoise * cameraGain, 4));
            Utils.log("  Gain = 1 / %s (ADU/e-)", Utils.rounded(1 / cameraGain, 4));
        }
    }
    IJ.showStatus("");
}
Also used : StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) PlotWindow(ij.gui.PlotWindow) PolynomialFunction(org.apache.commons.math3.analysis.polynomials.PolynomialFunction) SeriesOpener(gdsc.smlm.ij.utils.SeriesOpener) Plot2(ij.gui.Plot2) Point(java.awt.Point) ImagePlus(ij.ImagePlus) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) Statistics(gdsc.core.utils.Statistics) Point(java.awt.Point) PolynomialCurveFitter(org.apache.commons.math3.fitting.PolynomialCurveFitter) WeightedObservedPoints(org.apache.commons.math3.fitting.WeightedObservedPoints) TextWindow(ij.text.TextWindow) GenericDialog(ij.gui.GenericDialog)

Example 2 with WeightedObservedPoints

use of org.apache.commons.math3.fitting.WeightedObservedPoints in project GDSC-SMLM by aherbert.

the class FIRE method runQEstimation.

private void runQEstimation() {
    IJ.showStatus(TITLE + " ...");
    if (!showQEstimationInputDialog())
        return;
    MemoryPeakResults results = ResultsManager.loadInputResults(inputOption, false);
    if (results == null || results.size() == 0) {
        IJ.error(TITLE, "No results could be loaded");
        return;
    }
    if (results.getCalibration() == null) {
        IJ.error(TITLE, "The results are not calibrated");
        return;
    }
    results = cropToRoi(results);
    if (results.size() < 2) {
        IJ.error(TITLE, "No results within the crop region");
        return;
    }
    initialise(results, null);
    // We need localisation precision.
    // Build a histogram of the localisation precision.
    // Get the initial mean and SD and plot as a Gaussian.
    PrecisionHistogram histogram = calculatePrecisionHistogram();
    if (histogram == null) {
        IJ.error(TITLE, "No localisation precision available.\n \nPlease choose " + PrecisionMethod.FIXED + " and enter a precision mean and SD.");
        return;
    }
    StoredDataStatistics precision = histogram.precision;
    //String name = results.getName();
    double fourierImageScale = SCALE_VALUES[imageScaleIndex];
    int imageSize = IMAGE_SIZE_VALUES[imageSizeIndex];
    // Create the image and compute the numerator of FRC. 
    // Do not use the signal so results.size() is the number of localisations.
    IJ.showStatus("Computing FRC curve ...");
    FireImages images = createImages(fourierImageScale, imageSize, false);
    // DEBUGGING - Save the two images to disk. Load the images into the Matlab 
    // code that calculates the Q-estimation and make this plugin match the functionality.
    //IJ.save(new ImagePlus("i1", images.ip1), "/scratch/i1.tif");
    //IJ.save(new ImagePlus("i2", images.ip2), "/scratch/i2.tif");
    FRC frc = new FRC();
    frc.progress = progress;
    frc.setFourierMethod(fourierMethod);
    frc.setSamplingMethod(samplingMethod);
    frc.setPerimeterSamplingFactor(perimeterSamplingFactor);
    FRCCurve frcCurve = frc.calculateFrcCurve(images.ip1, images.ip2, images.nmPerPixel);
    if (frcCurve == null) {
        IJ.error(TITLE, "Failed to compute FRC curve");
        return;
    }
    IJ.showStatus("Running Q-estimation ...");
    // Note:
    // The method implemented here is based on Matlab code provided by Bernd Rieger.
    // The idea is to compute the spurious correlation component of the FRC Numerator
    // using an initial estimate of distribution of the localisation precision (assumed 
    // to be Gaussian). This component is the contribution of repeat localisations of 
    // the same molecule to the numerator and is modelled as an exponential decay
    // (exp_decay). The component is scaled by the Q-value which
    // is the average number of times a molecule is seen in addition to the first time.
    // At large spatial frequencies the scaled component should match the numerator,
    // i.e. at high resolution (low FIRE number) the numerator is made up of repeat 
    // localisations of the same molecule and not actual structure in the image.
    // The best fit is where the numerator equals the scaled component, i.e. num / (q*exp_decay) == 1.
    // The FRC Numerator is plotted and Q can be determined by
    // adjusting Q and the precision mean and SD to maximise the cost function.
    // This can be done interactively by the user with the effect on the FRC curve
    // dynamically updated and displayed.
    // Compute the scaled FRC numerator
    double qNorm = (1 / frcCurve.mean1 + 1 / frcCurve.mean2);
    double[] frcnum = new double[frcCurve.getSize()];
    for (int i = 0; i < frcnum.length; i++) {
        FRCCurveResult r = frcCurve.get(i);
        frcnum[i] = qNorm * r.getNumerator() / r.getNumberOfSamples();
    }
    // Compute the spatial frequency and the region for curve fitting
    double[] q = FRC.computeQ(frcCurve, false);
    int low = 0, high = q.length;
    while (high > 0 && q[high - 1] > maxQ) high--;
    while (low < q.length && q[low] < minQ) low++;
    // Require we fit at least 10% of the curve
    if (high - low < q.length * 0.1) {
        IJ.error(TITLE, "Not enough points for Q estimation");
        return;
    }
    // Obtain initial estimate of Q plateau height and decay.
    // This can be done by fitting the precision histogram and then fixing the mean and sigma.
    // Or it can be done by allowing the precision to be sampled and the mean and sigma
    // become parameters for fitting.
    // Check if we can sample precision values
    boolean sampleDecay = precision != null && FIRE.sampleDecay;
    double[] exp_decay;
    if (sampleDecay) {
        // Random sample of precision values from the distribution is used to 
        // construct the decay curve
        int[] sample = Random.sample(10000, precision.getN(), new Well19937c());
        final double four_pi2 = 4 * Math.PI * Math.PI;
        double[] pre = new double[q.length];
        for (int i = 1; i < q.length; i++) pre[i] = -four_pi2 * q[i] * q[i];
        // Sample
        final int n = sample.length;
        double[] hq = new double[n];
        for (int j = 0; j < n; j++) {
            // Scale to SR pixels
            double s2 = precision.getValue(sample[j]) / images.nmPerPixel;
            s2 *= s2;
            for (int i = 1; i < q.length; i++) hq[i] += FastMath.exp(pre[i] * s2);
        }
        for (int i = 1; i < q.length; i++) hq[i] /= n;
        exp_decay = new double[q.length];
        exp_decay[0] = 1;
        for (int i = 1; i < q.length; i++) {
            double sinc_q = sinc(Math.PI * q[i]);
            exp_decay[i] = sinc_q * sinc_q * hq[i];
        }
    } else {
        // Note: The sigma mean and std should be in the units of super-resolution 
        // pixels so scale to SR pixels
        exp_decay = computeExpDecay(histogram.mean / images.nmPerPixel, histogram.sigma / images.nmPerPixel, q);
    }
    // Smoothing
    double[] smooth;
    if (loessSmoothing) {
        // Note: This computes the log then smooths it 
        double bandwidth = 0.1;
        int robustness = 0;
        double[] l = new double[exp_decay.length];
        for (int i = 0; i < l.length; i++) {
            // Original Matlab code computes the log for each array.
            // This is equivalent to a single log on the fraction of the two.
            // Perhaps the two log method is more numerically stable.
            //l[i] = Math.log(Math.abs(frcnum[i])) - Math.log(exp_decay[i]);
            l[i] = Math.log(Math.abs(frcnum[i] / exp_decay[i]));
        }
        try {
            LoessInterpolator loess = new LoessInterpolator(bandwidth, robustness);
            smooth = loess.smooth(q, l);
        } catch (Exception e) {
            IJ.error(TITLE, "LOESS smoothing failed");
            return;
        }
    } else {
        // Note: This smooths the curve before computing the log 
        double[] norm = new double[exp_decay.length];
        for (int i = 0; i < norm.length; i++) {
            norm[i] = frcnum[i] / exp_decay[i];
        }
        // Median window of 5 == radius of 2
        MedianWindow mw = new MedianWindow(norm, 2);
        smooth = new double[exp_decay.length];
        for (int i = 0; i < norm.length; i++) {
            smooth[i] = Math.log(Math.abs(mw.getMedian()));
            mw.increment();
        }
    }
    // Fit with quadratic to find the initial guess.
    // Note: example Matlab code frc_Qcorrection7.m identifies regions of the 
    // smoothed log curve with low derivative and only fits those. The fit is 
    // used for the final estimate. Fitting a subset with low derivative is not 
    // implemented here since the initial estimate is subsequently optimised 
    // to maximise a cost function. 
    Quadratic curve = new Quadratic();
    SimpleCurveFitter fit = SimpleCurveFitter.create(curve, new double[2]);
    WeightedObservedPoints points = new WeightedObservedPoints();
    for (int i = low; i < high; i++) points.add(q[i], smooth[i]);
    double[] estimate = fit.fit(points.toList());
    double qValue = FastMath.exp(estimate[0]);
    //System.out.printf("Initial q-estimate = %s => %.3f\n", Arrays.toString(estimate), qValue);
    // This could be made an option. Just use for debugging
    boolean debug = false;
    if (debug) {
        // Plot the initial fit and the fit curve
        double[] qScaled = FRC.computeQ(frcCurve, true);
        double[] line = new double[q.length];
        for (int i = 0; i < q.length; i++) line[i] = curve.value(q[i], estimate);
        String title = TITLE + " Initial fit";
        Plot2 plot = new Plot2(title, "Spatial Frequency (nm^-1)", "FRC Numerator");
        String label = String.format("Q = %.3f", qValue);
        plot.addPoints(qScaled, smooth, Plot.LINE);
        plot.setColor(Color.red);
        plot.addPoints(qScaled, line, Plot.LINE);
        plot.setColor(Color.black);
        plot.addLabel(0, 0, label);
        Utils.display(title, plot, Utils.NO_TO_FRONT);
    }
    if (fitPrecision) {
        // Q - Should this be optional?
        if (sampleDecay) {
            // If a sample of the precision was used to construct the data for the initial fit 
            // then update the estimate using the fit result since it will be a better start point. 
            histogram.sigma = precision.getStandardDeviation();
            // Normalise sum-of-squares to the SR pixel size
            double meanSumOfSquares = (precision.getSumOfSquares() / (images.nmPerPixel * images.nmPerPixel)) / precision.getN();
            histogram.mean = images.nmPerPixel * Math.sqrt(meanSumOfSquares - estimate[1] / (4 * Math.PI * Math.PI));
        }
        // Do a multivariate fit ...
        SimplexOptimizer opt = new SimplexOptimizer(1e-6, 1e-10);
        PointValuePair p = null;
        MultiPlateauness f = new MultiPlateauness(frcnum, q, low, high);
        double[] initial = new double[] { histogram.mean / images.nmPerPixel, histogram.sigma / images.nmPerPixel, qValue };
        p = findMin(p, opt, f, scale(initial, 0.1));
        p = findMin(p, opt, f, scale(initial, 0.5));
        p = findMin(p, opt, f, initial);
        p = findMin(p, opt, f, scale(initial, 2));
        p = findMin(p, opt, f, scale(initial, 10));
        if (p != null) {
            double[] point = p.getPointRef();
            histogram.mean = point[0] * images.nmPerPixel;
            histogram.sigma = point[1] * images.nmPerPixel;
            qValue = point[2];
        }
    } else {
        // If so then this should be optional.
        if (sampleDecay) {
            if (precisionMethod != PrecisionMethod.FIXED) {
                histogram.sigma = precision.getStandardDeviation();
                // Normalise sum-of-squares to the SR pixel size
                double meanSumOfSquares = (precision.getSumOfSquares() / (images.nmPerPixel * images.nmPerPixel)) / precision.getN();
                histogram.mean = images.nmPerPixel * Math.sqrt(meanSumOfSquares - estimate[1] / (4 * Math.PI * Math.PI));
            }
            exp_decay = computeExpDecay(histogram.mean / images.nmPerPixel, histogram.sigma / images.nmPerPixel, q);
        }
        // Estimate spurious component by promoting plateauness.
        // The Matlab code used random initial points for a Simplex optimiser.
        // A Brent line search should be pretty deterministic so do simple repeats.
        // However it will proceed downhill so if the initial point is wrong then 
        // it will find a sub-optimal result.
        UnivariateOptimizer o = new BrentOptimizer(1e-3, 1e-6);
        Plateauness f = new Plateauness(frcnum, exp_decay, low, high);
        UnivariatePointValuePair p = null;
        p = findMin(p, o, f, qValue, 0.1);
        p = findMin(p, o, f, qValue, 0.2);
        p = findMin(p, o, f, qValue, 0.333);
        p = findMin(p, o, f, qValue, 0.5);
        // Do some Simplex repeats as well
        SimplexOptimizer opt = new SimplexOptimizer(1e-6, 1e-10);
        p = findMin(p, opt, f, qValue * 0.1);
        p = findMin(p, opt, f, qValue * 0.5);
        p = findMin(p, opt, f, qValue);
        p = findMin(p, opt, f, qValue * 2);
        p = findMin(p, opt, f, qValue * 10);
        if (p != null)
            qValue = p.getPoint();
    }
    QPlot qplot = new QPlot(frcCurve, qValue, low, high);
    // Interactive dialog to estimate Q (blinking events per flourophore) using 
    // sliders for the mean and standard deviation of the localisation precision.
    showQEstimationDialog(histogram, qplot, frcCurve, images.nmPerPixel);
    IJ.showStatus(TITLE + " complete");
}
Also used : BrentOptimizer(org.apache.commons.math3.optim.univariate.BrentOptimizer) Plot2(ij.gui.Plot2) Well19937c(org.apache.commons.math3.random.Well19937c) PointValuePair(org.apache.commons.math3.optim.PointValuePair) UnivariatePointValuePair(org.apache.commons.math3.optim.univariate.UnivariatePointValuePair) LoessInterpolator(org.apache.commons.math3.analysis.interpolation.LoessInterpolator) WeightedObservedPoints(org.apache.commons.math3.fitting.WeightedObservedPoints) SimplexOptimizer(org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) MedianWindow(gdsc.core.utils.MedianWindow) SimpleCurveFitter(org.apache.commons.math3.fitting.SimpleCurveFitter) FRCCurveResult(gdsc.smlm.ij.frc.FRC.FRCCurveResult) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) UnivariatePointValuePair(org.apache.commons.math3.optim.univariate.UnivariatePointValuePair) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) TooManyEvaluationsException(org.apache.commons.math3.exception.TooManyEvaluationsException) FRCCurve(gdsc.smlm.ij.frc.FRC.FRCCurve) FRC(gdsc.smlm.ij.frc.FRC) UnivariateOptimizer(org.apache.commons.math3.optim.univariate.UnivariateOptimizer)

Example 3 with WeightedObservedPoints

use of org.apache.commons.math3.fitting.WeightedObservedPoints in project GDSC-SMLM by aherbert.

the class FIRE method fitGaussian.

/**
	 * Fit gaussian.
	 *
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 * @return new double[] { norm, mean, sigma }
	 */
private double[] fitGaussian(float[] x, float[] y) {
    WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = 0; i < x.length; i++) obs.add(x[i], y[i]);
    Collection<WeightedObservedPoint> observations = obs.toList();
    GaussianCurveFitter fitter = GaussianCurveFitter.create().withMaxIterations(2000);
    GaussianCurveFitter.ParameterGuesser guess = new GaussianCurveFitter.ParameterGuesser(observations);
    double[] initialGuess = null;
    try {
        initialGuess = guess.guess();
        return fitter.withStartPoint(initialGuess).fit(observations);
    } catch (TooManyEvaluationsException e) {
        // Use the initial estimate
        return initialGuess;
    } catch (Exception e) {
        // Just in case there is another exception type, or the initial estimate failed
        return null;
    }
}
Also used : WeightedObservedPoints(org.apache.commons.math3.fitting.WeightedObservedPoints) TooManyEvaluationsException(org.apache.commons.math3.exception.TooManyEvaluationsException) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) GaussianCurveFitter(org.apache.commons.math3.fitting.GaussianCurveFitter) TooManyEvaluationsException(org.apache.commons.math3.exception.TooManyEvaluationsException)

Example 4 with WeightedObservedPoints

use of org.apache.commons.math3.fitting.WeightedObservedPoints in project GDSC-SMLM by aherbert.

the class PCPALMMolecules method fitGaussian.

private double[] fitGaussian(float[] x, float[] y) {
    WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = 0; i < x.length; i++) obs.add(x[i], y[i]);
    Collection<WeightedObservedPoint> observations = obs.toList();
    GaussianCurveFitter fitter = GaussianCurveFitter.create().withMaxIterations(2000);
    GaussianCurveFitter.ParameterGuesser guess = new GaussianCurveFitter.ParameterGuesser(observations);
    double[] initialGuess = null;
    try {
        initialGuess = guess.guess();
        return fitter.withStartPoint(initialGuess).fit(observations);
    } catch (TooManyEvaluationsException e) {
        // Use the initial estimate
        return initialGuess;
    } catch (Exception e) {
        // Just in case there is another exception type, or the initial estimate failed
        return null;
    }
}
Also used : WeightedObservedPoints(org.apache.commons.math3.fitting.WeightedObservedPoints) TooManyEvaluationsException(org.apache.commons.math3.exception.TooManyEvaluationsException) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) ClusterPoint(gdsc.core.clustering.ClusterPoint) GaussianCurveFitter(org.apache.commons.math3.fitting.GaussianCurveFitter) TooManyEvaluationsException(org.apache.commons.math3.exception.TooManyEvaluationsException)

Aggregations

WeightedObservedPoints (org.apache.commons.math3.fitting.WeightedObservedPoints)4 TooManyEvaluationsException (org.apache.commons.math3.exception.TooManyEvaluationsException)3 WeightedObservedPoint (org.apache.commons.math3.fitting.WeightedObservedPoint)3 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)2 Plot2 (ij.gui.Plot2)2 GaussianCurveFitter (org.apache.commons.math3.fitting.GaussianCurveFitter)2 ClusterPoint (gdsc.core.clustering.ClusterPoint)1 MedianWindow (gdsc.core.utils.MedianWindow)1 Statistics (gdsc.core.utils.Statistics)1 FRC (gdsc.smlm.ij.frc.FRC)1 FRCCurve (gdsc.smlm.ij.frc.FRC.FRCCurve)1 FRCCurveResult (gdsc.smlm.ij.frc.FRC.FRCCurveResult)1 SeriesOpener (gdsc.smlm.ij.utils.SeriesOpener)1 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)1 ImagePlus (ij.ImagePlus)1 GenericDialog (ij.gui.GenericDialog)1 PlotWindow (ij.gui.PlotWindow)1 TextWindow (ij.text.TextWindow)1 Point (java.awt.Point)1 LoessInterpolator (org.apache.commons.math3.analysis.interpolation.LoessInterpolator)1