Search in sources :

Example 26 with Statistics

use of gdsc.core.utils.Statistics in project GDSC-SMLM by aherbert.

the class BenchmarkSpotFilter method getStats.

private double[][] getStats(ArrayList<BatchResult[]> batchResults) {
    if (selection < 2)
        return null;
    double[][] stats = new double[2][2];
    for (int index = 0; index < stats.length; index++) {
        Statistics s = new Statistics();
        for (BatchResult[] batchResult : batchResults) {
            if (batchResult == null || batchResult.length == 0)
                continue;
            for (int i = 0; i < batchResult.length; i++) {
                s.add(batchResult[i].getScore(index));
            }
        }
        stats[index][0] = s.getMean();
        stats[index][1] = s.getStandardDeviation();
    }
    return stats;
}
Also used : Statistics(gdsc.core.utils.Statistics) PeakResultPoint(gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint) BasePoint(gdsc.core.match.BasePoint)

Example 27 with Statistics

use of gdsc.core.utils.Statistics in project GDSC-SMLM by aherbert.

the class BenchmarkSmartSpotRanking method summariseResults.

private void summariseResults(TIntObjectHashMap<RankResults> rankResults) {
    createTable();
    // Summarise the ranking results. 
    StringBuilder sb = new StringBuilder(BenchmarkSpotFilter.resultPrefix);
    // nP and nN is the fractional score of the spot candidates 
    addCount(sb, nP + nN);
    addCount(sb, nP);
    addCount(sb, nN);
    addCount(sb, fP);
    addCount(sb, fN);
    final double[] counter1 = new double[2];
    final int[] counter2 = new int[2];
    filterCandidates.forEachValue(new TObjectProcedure<FilterCandidates>() {

        public boolean execute(FilterCandidates result) {
            counter1[0] += result.np;
            counter1[1] += result.nn;
            counter2[0] += result.p;
            counter2[1] += result.n;
            return true;
        }
    });
    double tp = counter1[0];
    double fp = counter1[1];
    int cTP = counter2[0];
    int cFP = counter2[2];
    //		// This should be the same
    //		double tp2 = 0;
    //		double fp2 = 0;
    //		int cTP2 = 0, cFP2 = 0;
    //		for (RankResults rr : rankResults.values())
    //		{
    //			for (ScoredSpot spot : rr.spots)
    //			{
    //				if (spot.match)
    //					cTP2++;
    //				else
    //					cFP2++;
    //				tp2 += spot.getScore();
    //				fp2 += spot.antiScore();
    //			}
    //		}
    //		if (tp != tp2 || fp != fp2 || cTP != cTP2 || cFP != cFP2)
    //			System.out.println("Error counting");
    // The fraction of positive and negative candidates that were included
    add(sb, (100.0 * cTP) / nP);
    add(sb, (100.0 * cFP) / nN);
    // Add counts of the the candidates
    add(sb, cTP + cFP);
    add(sb, cTP);
    add(sb, cFP);
    // Add fractional counts of the the candidates
    add(sb, tp + fp);
    add(sb, tp);
    add(sb, fp);
    // Materialise rankeResults
    final int[] frames = new int[rankResults.size()];
    final RankResults[] results = new RankResults[rankResults.size()];
    final int[] counter = new int[1];
    rankResults.forEachEntry(new TIntObjectProcedure<RankResults>() {

        public boolean execute(int a, RankResults b) {
            frames[counter[0]] = a;
            results[counter[0]] = b;
            counter[0]++;
            return true;
        }
    });
    // Summarise actual and candidate spots per frame
    Statistics actual = new Statistics();
    Statistics candidates = new Statistics();
    for (RankResults rr : results) {
        actual.add(rr.zPosition.length);
        candidates.add(rr.spots.length);
    }
    add(sb, actual.getMean());
    add(sb, actual.getStandardDeviation());
    add(sb, candidates.getMean());
    add(sb, candidates.getStandardDeviation());
    String resultPrefix = sb.toString();
    // ---
    // TODO
    // Add good label to spot candidates and have the benchmark spot filter respect this before applying the fail count limit.
    // Correlation between intensity and SNR ...
    // SNR is very good at low density
    // SNR fails at high density. The SNR estimate is probably wrong for high intensity spots.
    // Triangle is very good when there are a large number of good spots in a region of the image (e.g. a mask is used).
    // Triangle is poor when there are few good spots in an image.
    // Perhaps we can estimate the density of the spots and choose the correct thresholding method?
    // ---
    // Do a full benchmark through different Spot SNR, image sizes, densities and mask structures and see if there are patterns
    // for a good threshold method.		
    // --- 
    // Allow using the fitted results from benchmark spot fit. Will it make a difference if we fit the candidates (some will fail
    // if weak).
    // Can this be done by allowing the user to select the input (spot candidates or fitted positions)?
    // Perhaps I need to produce a precision estimate for all simulated spots and then only use those that achieve a certain 
    // precision, i.e. are reasonably in focus. Can this be done? Does the image PSF have a width estimate for the entire stack?
    // Perhaps I should filter, fit and then filter all spots using no fail count. These then become the spots to work with
    // for creating a smart fail count filter. 
    // ---
    // Pre-compute the results and have optional sort
    ArrayList<ScoredResult> list = new ArrayList<ScoredResult>(methodNames.length);
    for (int i = 0; i < methodNames.length; i++) {
        tp = 0;
        fp = 0;
        double tn = 0;
        int itp = 0;
        int ifp = 0;
        int itn = 0;
        Statistics s = new Statistics();
        long time = 0;
        for (RankResults rr : results) {
            RankResult r = rr.results.get(i);
            // Some results will not have a threshold
            if (!Float.isInfinite(r.t))
                s.add(r.t);
            time += r.time;
            tp += r.f.getTP();
            fp += r.f.getFP();
            tn += r.f.getTN();
            itp += r.c.getTP();
            ifp += r.c.getFP();
            itn += r.c.getTN();
        }
        sb.setLength(0);
        sb.append(resultPrefix);
        add(sb, methodNames[i]);
        if (methodNames[i].startsWith("SNR"))
            sb.append("\t");
        else
            add(sb, compactBins);
        add(sb, s.getMean());
        add(sb, s.getStandardDeviation());
        add(sb, Utils.timeToString(time / 1e6));
        // TP are all accepted candidates that can be matched to a spot
        // FP are all accepted candidates that cannot be matched to a spot
        // TN are all accepted candidates that cannot be matched to a spot
        // FN = The number of missed spots
        // Raw counts of match or no-match
        FractionClassificationResult f1 = new FractionClassificationResult(itp, ifp, itn, simulationParameters.molecules - itp);
        double s1 = addScores(sb, f1);
        // Fractional scoring
        FractionClassificationResult f2 = new FractionClassificationResult(tp, fp, tn, simulationParameters.molecules - tp);
        double s2 = addScores(sb, f2);
        // Store for sorting
        list.add(new ScoredResult(i, (useFractionScores) ? s2 : s1, sb.toString()));
    }
    if (list.isEmpty())
        return;
    Collections.sort(list);
    if (summaryTable.getTextPanel().getLineCount() > 0)
        summaryTable.append("");
    for (ScoredResult r : list) summaryTable.append(r.result);
    if (showOverlay) {
        int bestMethod = list.get(0).i;
        Overlay o = new Overlay();
        for (int j = 0; j < results.length; j++) {
            int frame = frames[j];
            //FilterCandidates candidates = filterCandidates.get(frame);
            RankResults rr = results[j];
            RankResult r = rr.results.get(bestMethod);
            int[] x1 = new int[r.good.length];
            int[] y1 = new int[r.good.length];
            int c1 = 0;
            int[] x2 = new int[r.good.length];
            int[] y2 = new int[r.good.length];
            int c2 = 0;
            int[] x3 = new int[r.good.length];
            int[] y3 = new int[r.good.length];
            int c3 = 0;
            int[] x4 = new int[r.good.length];
            int[] y4 = new int[r.good.length];
            int c4 = 0;
            for (int i = 0; i < x1.length; i++) {
                if (r.good[i] == TP) {
                    x1[c1] = rr.spots[i].spot.x;
                    y1[c1] = rr.spots[i].spot.y;
                    c1++;
                } else if (r.good[i] == FP) {
                    x2[c2] = rr.spots[i].spot.x;
                    y2[c2] = rr.spots[i].spot.y;
                    c2++;
                } else if (r.good[i] == TN) {
                    x3[c3] = rr.spots[i].spot.x;
                    y3[c3] = rr.spots[i].spot.y;
                    c3++;
                } else if (r.good[i] == FN) {
                    x4[c4] = rr.spots[i].spot.x;
                    y4[c4] = rr.spots[i].spot.y;
                    c4++;
                }
            }
            addToOverlay(o, frame, x1, y1, c1, Color.green);
            addToOverlay(o, frame, x2, y2, c2, Color.red);
            //addToOverlay(o, frame, x3, y3, c3, new Color(153, 255, 153)); // light green
            // light red
            addToOverlay(o, frame, x4, y4, c4, new Color(255, 153, 153));
        }
        imp.setOverlay(o);
    }
}
Also used : Color(java.awt.Color) ArrayList(java.util.ArrayList) Statistics(gdsc.core.utils.Statistics) PeakResultPoint(gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint) FractionClassificationResult(gdsc.core.match.FractionClassificationResult) Overlay(ij.gui.Overlay)

Example 28 with Statistics

use of gdsc.core.utils.Statistics 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 29 with Statistics

use of gdsc.core.utils.Statistics in project GDSC-SMLM by aherbert.

the class PSFDrift method computeDrift.

private void computeDrift() {
    // Create a grid of XY offset positions between 0-1 for PSF insert
    final double[] grid = new double[gridSize];
    for (int i = 0; i < grid.length; i++) grid[i] = (double) i / gridSize;
    // Configure fitting region
    final int w = 2 * regionSize + 1;
    centrePixel = w / 2;
    // Check region size using the image PSF
    double newPsfWidth = (double) imp.getWidth() / scale;
    if (Math.ceil(newPsfWidth) > w)
        Utils.log(TITLE + ": Fitted region size (%d) is smaller than the scaled PSF (%.1f)", w, newPsfWidth);
    // Create robust PSF fitting settings
    final double a = psfSettings.nmPerPixel * scale;
    final double sa = PSFCalculator.squarePixelAdjustment(psfSettings.nmPerPixel * (psfSettings.fwhm / Gaussian2DFunction.SD_TO_FWHM_FACTOR), a);
    fitConfig.setInitialPeakStdDev(sa / a);
    fitConfig.setBackgroundFitting(backgroundFitting);
    fitConfig.setNotSignalFitting(false);
    fitConfig.setComputeDeviations(false);
    fitConfig.setDisableSimpleFilter(true);
    // Create the PSF over the desired z-depth
    int depth = (int) Math.round(zDepth / psfSettings.nmPerSlice);
    int startSlice = psfSettings.zCentre - depth;
    int endSlice = psfSettings.zCentre + depth;
    int nSlices = imp.getStackSize();
    startSlice = (startSlice < 1) ? 1 : (startSlice > nSlices) ? nSlices : startSlice;
    endSlice = (endSlice < 1) ? 1 : (endSlice > nSlices) ? nSlices : endSlice;
    ImagePSFModel psf = createImagePSF(startSlice, endSlice);
    int minz = startSlice - psfSettings.zCentre;
    int maxz = endSlice - psfSettings.zCentre;
    final int nZ = maxz - minz + 1;
    final int gridSize2 = grid.length * grid.length;
    total = nZ * gridSize2;
    // Store all the fitting results
    int nStartPoints = getNumberOfStartPoints();
    results = new double[total * nStartPoints][];
    // TODO - Add ability to iterate this, adjusting the current offset in the PSF
    // each iteration
    // Create a pool of workers
    int nThreads = Prefs.getThreads();
    BlockingQueue<Job> jobs = new ArrayBlockingQueue<Job>(nThreads * 2);
    List<Worker> workers = new LinkedList<Worker>();
    List<Thread> threads = new LinkedList<Thread>();
    for (int i = 0; i < nThreads; i++) {
        Worker worker = new Worker(jobs, psf, w, fitConfig);
        Thread t = new Thread(worker);
        workers.add(worker);
        threads.add(t);
        t.start();
    }
    // Fit 
    Utils.showStatus("Fitting ...");
    final int step = Utils.getProgressInterval(total);
    outer: for (int z = minz, i = 0; z <= maxz; z++) {
        for (int x = 0; x < grid.length; x++) for (int y = 0; y < grid.length; y++, i++) {
            if (IJ.escapePressed()) {
                break outer;
            }
            put(jobs, new Job(z, grid[x], grid[y], i));
            if (i % step == 0) {
                IJ.showProgress(i, total);
            }
        }
    }
    // If escaped pressed then do not need to stop the workers, just return
    if (Utils.isInterrupted()) {
        IJ.showProgress(1);
        return;
    }
    // Finish all the worker threads by passing in a null job
    for (int i = 0; i < threads.size(); i++) {
        put(jobs, new Job());
    }
    // Wait for all to finish
    for (int i = 0; i < threads.size(); i++) {
        try {
            threads.get(i).join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    threads.clear();
    IJ.showProgress(1);
    IJ.showStatus("");
    // Plot the average and SE for the drift curve
    // Plot the recall
    double[] zPosition = new double[nZ];
    double[] avX = new double[nZ];
    double[] seX = new double[nZ];
    double[] avY = new double[nZ];
    double[] seY = new double[nZ];
    double[] recall = new double[nZ];
    for (int z = minz, i = 0; z <= maxz; z++, i++) {
        Statistics statsX = new Statistics();
        Statistics statsY = new Statistics();
        for (int s = 0; s < nStartPoints; s++) {
            int resultPosition = i * gridSize2 + s * total;
            final int endResultPosition = resultPosition + gridSize2;
            while (resultPosition < endResultPosition) {
                if (results[resultPosition] != null) {
                    statsX.add(results[resultPosition][0]);
                    statsY.add(results[resultPosition][1]);
                }
                resultPosition++;
            }
        }
        zPosition[i] = z * psfSettings.nmPerSlice;
        avX[i] = statsX.getMean();
        seX[i] = statsX.getStandardError();
        avY[i] = statsY.getMean();
        seY[i] = statsY.getStandardError();
        recall[i] = (double) statsX.getN() / (nStartPoints * gridSize2);
    }
    // Find the range from the z-centre above the recall limit 
    int centre = 0;
    for (int slice = startSlice, i = 0; slice <= endSlice; slice++, i++) {
        if (slice == psfSettings.zCentre) {
            centre = i;
            break;
        }
    }
    if (recall[centre] < recallLimit)
        return;
    int start = centre, end = centre;
    for (int i = centre; i-- > 0; ) {
        if (recall[i] < recallLimit)
            break;
        start = i;
    }
    for (int i = centre; ++i < recall.length; ) {
        if (recall[i] < recallLimit)
            break;
        end = i;
    }
    int iterations = 1;
    LoessInterpolator loess = null;
    if (smoothing > 0)
        loess = new LoessInterpolator(smoothing, iterations);
    double[][] smoothx = displayPlot("Drift X", "X (nm)", zPosition, avX, seX, loess, start, end);
    double[][] smoothy = displayPlot("Drift Y", "Y (nm)", zPosition, avY, seY, loess, start, end);
    displayPlot("Recall", "Recall", zPosition, recall, null, null, start, end);
    WindowOrganiser wo = new WindowOrganiser();
    wo.tileWindows(idList);
    // Ask the user if they would like to store them in the image
    GenericDialog gd = new GenericDialog(TITLE);
    gd.enableYesNoCancel();
    gd.hideCancelButton();
    startSlice = psfSettings.zCentre - (centre - start);
    endSlice = psfSettings.zCentre + (end - centre);
    gd.addMessage(String.format("Save the drift to the PSF?\n \nSlices %d (%s nm) - %d (%s nm) above recall limit", startSlice, Utils.rounded(zPosition[start]), endSlice, Utils.rounded(zPosition[end])));
    gd.addMessage("Optionally average the end points to set drift outside the limits.\n(Select zero to ignore)");
    gd.addSlider("Number_of_points", 0, 10, positionsToAverage);
    gd.showDialog();
    if (gd.wasOKed()) {
        positionsToAverage = Math.abs((int) gd.getNextNumber());
        ArrayList<PSFOffset> offset = new ArrayList<PSFOffset>();
        final double pitch = psfSettings.nmPerPixel;
        int j = 0, jj = 0;
        for (int i = start, slice = startSlice; i <= end; slice++, i++) {
            j = findCentre(zPosition[i], smoothx, j);
            if (j == -1) {
                Utils.log("Failed to find the offset for depth %.2f", zPosition[i]);
                continue;
            }
            // The offset should store the difference to the centre in pixels so divide by the pixel pitch
            double cx = smoothx[1][j] / pitch;
            double cy = smoothy[1][j] / pitch;
            jj = findOffset(slice, jj);
            if (jj != -1) {
                cx += psfSettings.offset[jj].cx;
                cy += psfSettings.offset[jj].cy;
            }
            offset.add(new PSFOffset(slice, cx, cy));
        }
        addMissingOffsets(startSlice, endSlice, nSlices, offset);
        psfSettings.offset = offset.toArray(new PSFOffset[offset.size()]);
        psfSettings.addNote(TITLE, String.format("Solver=%s, Region=%d", PeakFit.getSolverName(fitConfig), regionSize));
        imp.setProperty("Info", XmlUtils.toXML(psfSettings));
    }
}
Also used : PSFOffset(gdsc.smlm.ij.settings.PSFOffset) ArrayList(java.util.ArrayList) WindowOrganiser(ij.plugin.WindowOrganiser) Statistics(gdsc.core.utils.Statistics) LinkedList(java.util.LinkedList) LoessInterpolator(org.apache.commons.math3.analysis.interpolation.LoessInterpolator) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) GenericDialog(ij.gui.GenericDialog) ImagePSFModel(gdsc.smlm.model.ImagePSFModel)

Example 30 with Statistics

use of gdsc.core.utils.Statistics in project GDSC-SMLM by aherbert.

the class PSFCreator method getBackground.

private float getBackground(int n, float[][] spot) {
    // Get the average value of the first and last n frames
    Statistics first = new Statistics();
    Statistics last = new Statistics();
    for (int i = 0; i < startBackgroundFrames; i++) {
        first.add(spot[i]);
    }
    for (int i = 0, j = spot.length - 1; i < endBackgroundFrames; i++, j--) {
        last.add(spot[j]);
    }
    float av = (float) ((first.getSum() + last.getSum()) / (first.getN() + last.getN()));
    Utils.log("  Spot %d Background: First %d = %.2f, Last %d = %.2f, av = %.2f", n, startBackgroundFrames, first.getMean(), endBackgroundFrames, last.getMean(), av);
    return av;
}
Also used : Statistics(gdsc.core.utils.Statistics) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) DescriptiveStatistics(org.apache.commons.math3.stat.descriptive.DescriptiveStatistics) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint)

Aggregations

Statistics (gdsc.core.utils.Statistics)32 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)14 ArrayList (java.util.ArrayList)10 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)7 WindowOrganiser (ij.plugin.WindowOrganiser)7 Plot2 (ij.gui.Plot2)6 PeakResult (gdsc.smlm.results.PeakResult)5 ImageStack (ij.ImageStack)5 Point (java.awt.Point)5 DescriptiveStatistics (org.apache.commons.math3.stat.descriptive.DescriptiveStatistics)5 BasePoint (gdsc.core.match.BasePoint)4 Trace (gdsc.smlm.results.Trace)4 Well19937c (org.apache.commons.math3.random.Well19937c)4 Gaussian2DFunction (gdsc.smlm.function.gaussian.Gaussian2DFunction)3 ImagePlus (ij.ImagePlus)3 Rectangle (java.awt.Rectangle)3 ExecutorService (java.util.concurrent.ExecutorService)3 Future (java.util.concurrent.Future)3 RandomDataGenerator (org.apache.commons.math3.random.RandomDataGenerator)3 SummaryStatistics (org.apache.commons.math3.stat.descriptive.SummaryStatistics)3