Search in sources :

Example 1 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class PSFEstimator method calculateStatistics.

private boolean calculateStatistics(PeakFit fitter, double[] params, double[] params_dev) {
    debug("  Fitting PSF");
    swapStatistics();
    // Create the fit engine using the PeakFit plugin
    FitConfiguration fitConfig = config.getFitConfiguration();
    fitConfig.setInitialAngle((float) params[0]);
    fitConfig.setInitialPeakStdDev0((float) params[1]);
    fitConfig.setInitialPeakStdDev1((float) params[2]);
    ImageStack stack = imp.getImageStack();
    Rectangle roi = stack.getProcessor(1).getRoi();
    ImageSource source = new IJImageSource(imp);
    // Allow interlaced data by wrapping the image source
    if (interlacedData) {
        source = new InterlacedImageSource(source, dataStart, dataBlock, dataSkip);
    }
    // Allow frame aggregation by wrapping the image source
    if (integrateFrames > 1) {
        source = new AggregatedImageSource(source, integrateFrames);
    }
    fitter.initialiseImage(source, roi, true);
    fitter.addPeakResults(this);
    fitter.initialiseFitting();
    FitEngine engine = fitter.createFitEngine();
    // Use random slices
    int[] slices = new int[stack.getSize()];
    for (int i = 0; i < slices.length; i++) slices[i] = i + 1;
    Random rand = new Random();
    rand.shuffle(slices);
    IJ.showStatus("Fitting ...");
    // Use multi-threaded code for speed
    int i;
    for (i = 0; i < slices.length; i++) {
        int slice = slices[i];
        //debug("  Processing slice = %d\n", slice);
        IJ.showProgress(size(), settings.numberOfPeaks);
        ImageProcessor ip = stack.getProcessor(slice);
        // stack processor does not set the bounds required by ImageConverter
        ip.setRoi(roi);
        FitJob job = new FitJob(slice, ImageConverter.getData(ip), roi);
        engine.run(job);
        if (sampleSizeReached() || Utils.isInterrupted()) {
            break;
        }
    }
    if (Utils.isInterrupted()) {
        IJ.showProgress(1);
        engine.end(true);
        return false;
    }
    // Wait until we have enough results
    while (!sampleSizeReached() && !engine.isQueueEmpty()) {
        IJ.showProgress(size(), settings.numberOfPeaks);
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            break;
        }
    }
    // End now if we have enough samples
    engine.end(sampleSizeReached());
    IJ.showStatus("");
    IJ.showProgress(1);
    // This count will be an over-estimate given that the provider is ahead of the consumer
    // in this multi-threaded system
    debug("  Processed %d/%d slices (%d peaks)", i, slices.length, size());
    setParams(ANGLE, params, params_dev, sampleNew[ANGLE]);
    setParams(X, params, params_dev, sampleNew[X]);
    setParams(Y, params, params_dev, sampleNew[Y]);
    if (settings.showHistograms) {
        int[] idList = new int[NAMES.length];
        int count = 0;
        boolean requireRetile = false;
        for (int ii = 0; ii < 3; ii++) {
            if (sampleNew[ii].getN() == 0)
                continue;
            StoredDataStatistics stats = new StoredDataStatistics(sampleNew[ii].getValues());
            idList[count++] = Utils.showHistogram(TITLE, stats, NAMES[ii], 0, 0, settings.histogramBins, "Mean = " + Utils.rounded(stats.getMean()) + ". Median = " + Utils.rounded(sampleNew[ii].getPercentile(50)));
            requireRetile = requireRetile || Utils.isNewWindow();
        }
        if (requireRetile && count > 0) {
            new WindowOrganiser().tileWindows(Arrays.copyOf(idList, count));
        }
    }
    if (size() < 2) {
        log("ERROR: Insufficient number of fitted peaks, terminating ...");
        return false;
    }
    return true;
}
Also used : InterlacedImageSource(gdsc.smlm.results.InterlacedImageSource) AggregatedImageSource(gdsc.smlm.results.AggregatedImageSource) ImageStack(ij.ImageStack) Rectangle(java.awt.Rectangle) StoredDataStatistics(gdsc.core.utils.StoredDataStatistics) WindowOrganiser(ij.plugin.WindowOrganiser) IJImageSource(gdsc.smlm.ij.IJImageSource) ImageProcessor(ij.process.ImageProcessor) FitEngine(gdsc.smlm.engine.FitEngine) Random(gdsc.core.utils.Random) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) InterlacedImageSource(gdsc.smlm.results.InterlacedImageSource) ImageSource(gdsc.smlm.results.ImageSource) AggregatedImageSource(gdsc.smlm.results.AggregatedImageSource) IJImageSource(gdsc.smlm.ij.IJImageSource) FitJob(gdsc.smlm.engine.FitJob)

Example 2 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class PSFEstimator method setup.

/*
	 * (non-Javadoc)
	 * 
	 * @see ij.plugin.filter.PlugInFilter#setup(java.lang.String, ij.ImagePlus)
	 */
public int setup(String arg, ImagePlus imp) {
    SMLMUsageTracker.recordPlugin(this.getClass(), arg);
    extraOptions = Utils.isExtraOptions();
    if (imp == null) {
        IJ.noImage();
        return DONE;
    }
    globalSettings = SettingsManager.loadSettings();
    settings = globalSettings.getPsfEstimatorSettings();
    // Reset
    if (IJ.controlKeyDown()) {
        config = new FitEngineConfiguration(new FitConfiguration());
        globalSettings.setFitEngineConfiguration(config);
    } else {
        config = globalSettings.getFitEngineConfiguration();
    }
    Roi roi = imp.getRoi();
    if (roi != null && roi.getType() != Roi.RECTANGLE) {
        IJ.error("Rectangular ROI required");
        return DONE;
    }
    return showDialog(imp);
}
Also used : FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) Roi(ij.gui.Roi)

Example 3 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class DoubletAnalysis method updateConfiguration.

/**
	 * Updates the given configuration using the latest fitting settings used in benchmarking.
	 *
	 * @param pConfig
	 *            the configuration
	 * @return true, if successful
	 */
public static boolean updateConfiguration(FitEngineConfiguration pConfig) {
    final FitConfiguration pFitConfig = pConfig.getFitConfiguration();
    pFitConfig.setInitialPeakStdDev(fitConfig.getInitialPeakStdDev0());
    pConfig.copyDataFilter(config);
    pConfig.setSearch(config.getSearch());
    pConfig.setBorder(config.getBorder());
    pConfig.setFitting(config.getFitting());
    pFitConfig.setFitSolver(fitConfig.getFitSolver());
    pFitConfig.setFitFunction(fitConfig.getFitFunction());
    pConfig.setIncludeNeighbours(config.isIncludeNeighbours());
    pConfig.setNeighbourHeightThreshold(config.getNeighbourHeightThreshold());
    pFitConfig.setDuplicateDistance(fitConfig.getDuplicateDistance());
    pFitConfig.setMaxIterations(fitConfig.getMaxIterations());
    pFitConfig.setMaxFunctionEvaluations(fitConfig.getMaxFunctionEvaluations());
    // MLE settings
    pFitConfig.setModelCamera(fitConfig.isModelCamera());
    pFitConfig.setBias(0);
    pFitConfig.setReadNoise(0);
    pFitConfig.setAmplification(0);
    pFitConfig.setEmCCD(fitConfig.isEmCCD());
    pFitConfig.setSearchMethod(fitConfig.getSearchMethod());
    pFitConfig.setRelativeThreshold(fitConfig.getRelativeThreshold());
    pFitConfig.setAbsoluteThreshold(fitConfig.getAbsoluteThreshold());
    pFitConfig.setGradientLineMinimisation(fitConfig.isGradientLineMinimisation());
    // LSE settings
    pFitConfig.setFitCriteria(fitConfig.getFitCriteria());
    pFitConfig.setSignificantDigits(fitConfig.getSignificantDigits());
    pFitConfig.setDelta(fitConfig.getDelta());
    pFitConfig.setLambda(fitConfig.getLambda());
    return true;
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration)

Example 4 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class DoubletAnalysis method runAnalysis.

/**
	 * Run analysis.
	 */
private void runAnalysis() {
    if (doubletResults == null) {
        IJ.error(TITLE, "No doublet results in memory");
        return;
    }
    // Ask the user to set filters
    if (!showAnalysisDialog())
        return;
    showResults(doubletResults, analysisShowResults);
    // Store the effect of fitting as a doublet
    ArrayList<DoubletBonus> data = new ArrayList<DoubletBonus>(doubletResults.size());
    // True positive and False positives at residuals = 0
    double tp = 0;
    double fp = 0;
    Logger logger = (analysisLogging) ? new IJLogger() : null;
    // Get filters for the single and double fits
    // No coordinate shift for the doublet. We have already done simple checking of the 
    // coordinates to get the good=2 flag
    FitConfiguration filterFitConfig2 = filterFitConfig.clone();
    filterFitConfig2.setCoordinateShift(Integer.MAX_VALUE);
    final int size = 2 * config.getRelativeFitting() + 1;
    Rectangle regionBounds = new Rectangle(0, 0, size, size);
    final double otherDriftAngle = 180 - analysisDriftAngle;
    // Process all the results
    for (DoubletResult result : doubletResults) {
        // Filter the singles that would be accepted
        if (result.good1) {
            filterFitConfig.setNoise(result.noise);
            FitStatus fitStatus0 = filterFitConfig.validatePeak(0, result.fitResult1.getInitialParameters(), result.fitResult1.getParameters());
            double tp1 = 0, fp1 = 0;
            if (fitStatus0 == FitStatus.OK) {
                tp1 = result.tp1;
                fp1 = result.fp1;
            } else if (analysisLogging)
                logFailure(logger, 0, result, fitStatus0);
            // width diverged spots as OK for a doublet fit
            if ((fitStatus0 == FitStatus.OK || fitStatus0 == FitStatus.WIDTH_DIVERGED) && selectFit(result) && result.good2) {
                double tp2 = 0, fp2 = 0;
                // Basic spot criteria (SNR, Photons, width)
                filterFitConfig2.setNoise(result.noise);
                FitStatus fitStatus1 = filterFitConfig2.validatePeak(0, result.fitResult2.getInitialParameters(), result.fitResult2.getParameters());
                FitStatus fitStatus2 = filterFitConfig2.validatePeak(1, result.fitResult2.getInitialParameters(), result.fitResult2.getParameters());
                // Log basic failures
                boolean[] accept = new boolean[2];
                if (fitStatus1 == FitStatus.OK) {
                    accept[0] = true;
                } else if (analysisLogging)
                    logFailure(logger, 1, result, fitStatus1);
                if (fitStatus2 == FitStatus.OK) {
                    accept[1] = true;
                } else if (analysisLogging)
                    logFailure(logger, 2, result, fitStatus2);
                // We can filter each spot with criteria such as shift and the angle to the quadrant.
                if (accept[0] || accept[1]) {
                    if (result.gap < minGap) {
                        accept[0] = accept[1] = false;
                        if (analysisLogging)
                            logger.info("Reject Doublet (%.2f): Fitted coordinates below min gap (%g<%g)\n", result.getMaxScore(), result.gap, minGap);
                    }
                }
                if (accept[0] || accept[1]) {
                    // The logic in here will be copied to the FitWorker.quadrantAnalysis routine.
                    double[] params = result.fitResult1.getParameters();
                    double[] newParams = result.fitResult2.getParameters();
                    // Set up for shift filtering
                    double shift = filterFitConfig.getCoordinateShift();
                    if (shift == 0 || shift == Double.POSITIVE_INFINITY) {
                        // Allow the shift to span half of the fitted window.
                        shift = 0.5 * FastMath.min(regionBounds.width, regionBounds.height);
                    }
                    // Set an upper limit on the shift that is not too far outside the fit window
                    final double maxShiftX, maxShiftY;
                    final double factor = Gaussian2DFunction.SD_TO_HWHM_FACTOR;
                    if (fitConfig.isWidth0Fitting()) {
                        // Add the fitted standard deviation to the allowed shift
                        maxShiftX = regionBounds.width * 0.5 + factor * params[Gaussian2DFunction.X_SD];
                        maxShiftY = regionBounds.height * 0.5 + factor * params[Gaussian2DFunction.Y_SD];
                    } else {
                        // Add the configured standard deviation to the allowed shift
                        maxShiftX = regionBounds.width * 0.5 + factor * fitConfig.getInitialPeakStdDev0();
                        maxShiftY = regionBounds.height * 0.5 + factor * fitConfig.getInitialPeakStdDev1();
                    }
                    for (int n = 0; n < 2; n++) {
                        if (!accept[n])
                            continue;
                        // Reset
                        accept[n] = false;
                        final double xShift = newParams[Gaussian2DFunction.X_POSITION + n * 6] - params[Gaussian2DFunction.X_POSITION];
                        final double yShift = newParams[Gaussian2DFunction.Y_POSITION + n * 6] - params[Gaussian2DFunction.Y_POSITION];
                        if (Math.abs(xShift) > maxShiftX || Math.abs(yShift) > maxShiftY) {
                            if (analysisLogging)
                                logger.info("Reject P%d (%.2f): Fitted coordinates moved outside fit region (x=%g,y=%g)\n", n + 1, result.getMaxScore(), xShift, yShift);
                            continue;
                        }
                        if (Math.abs(xShift) > shift || Math.abs(yShift) > shift) {
                            // Allow up to a 45 degree difference to show the shift is along the vector
                            if (result.a[n] > analysisDriftAngle && result.a[n] < otherDriftAngle) {
                                if (analysisLogging)
                                    logger.info("Reject P%d (%.2f): Fitted coordinates moved into wrong quadrant (x=%g,y=%g,a=%f)", n + 1, result.getMaxScore(), xShift, yShift, result.a[n]);
                                continue;
                            }
                        // Note: The FitWorker also checks for drift to another candidate.
                        }
                        // This is OK
                        accept[n] = true;
                    }
                }
                if (accept[0]) {
                    tp2 += result.tp2a;
                    fp2 += result.fp2a;
                }
                if (accept[1]) {
                    tp2 += result.tp2b;
                    fp2 += result.fp2b;
                }
                if (accept[0] || accept[1]) {
                    tp += tp2;
                    fp += fp2;
                    // Store this as a doublet bonus
                    data.add(new DoubletBonus(result.getMaxScore(), result.getAvScore(), tp2 - tp1, fp2 - fp1));
                } else {
                    // No doublet fit so this will always be the single fit result
                    tp += tp1;
                    fp += fp1;
                }
            } else {
                // No doublet fit so this will always be the single fit result
                tp += tp1;
                fp += fp1;
            }
        }
    }
    // Compute the max Jaccard
    computeScores(data, tp, fp, numberOfMolecules, useMaxResiduals);
    if (showJaccardPlot)
        plotJaccard(residualsScore, (useMaxResiduals) ? _residualsScoreMax : _residualsScoreAv);
    createAnalysisTable();
    StringBuilder sb = new StringBuilder(analysisPrefix);
    sb.append(analysisTitle).append('\t');
    sb.append((useMaxResiduals) ? "Max" : "Average").append('\t');
    sb.append(SELECTION_CRITERIA[selectionCriteria]).append('\t');
    if (filterFitConfig.isSmartFilter()) {
        sb.append(filterFitConfig.getSmartFilterName()).append("\t\t\t\t\t\t\t\t");
    } else {
        sb.append('\t');
        sb.append(filterFitConfig.getCoordinateShiftFactor()).append('\t');
        sb.append(filterFitConfig.getSignalStrength()).append('\t');
        sb.append(filterFitConfig.getMinPhotons()).append('\t');
        sb.append(filterFitConfig.getMinWidthFactor()).append('\t');
        sb.append(filterFitConfig.getWidthFactor()).append('\t');
        sb.append(filterFitConfig.getPrecisionThreshold()).append('\t');
        sb.append(filterFitConfig.isPrecisionUsingBackground()).append('\t');
    }
    sb.append(analysisDriftAngle).append('\t');
    sb.append(minGap).append('\t');
    addJaccardScores(sb);
    analysisTable.append(sb.toString());
    saveTemplate(sb.toString());
}
Also used : ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) Logger(gdsc.core.logging.Logger) IJLogger(gdsc.core.ij.IJLogger) IJLogger(gdsc.core.ij.IJLogger) PeakResultPoint(gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint) BasePoint(gdsc.core.match.BasePoint) FitStatus(gdsc.smlm.fitting.FitStatus) FitConfiguration(gdsc.smlm.fitting.FitConfiguration)

Example 5 with FitConfiguration

use of gdsc.smlm.fitting.FitConfiguration in project GDSC-SMLM by aherbert.

the class DoubletAnalysis method itemStateChanged.

/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
	 */
public void itemStateChanged(ItemEvent e) {
    if (e.getSource() instanceof Choice) {
        // Update the settings from the template
        Choice choice = (Choice) e.getSource();
        String templateName = choice.getSelectedItem();
        // Get the configuration template
        GlobalSettings template = ConfigurationTemplate.getTemplate(templateName);
        if (textCoordinateShiftFactor != null) {
            if (template != null) {
                if (template.isFitEngineConfiguration()) {
                    FitConfiguration fitConfig = template.getFitEngineConfiguration().getFitConfiguration();
                    cbSmartFilter.setState(fitConfig.isSmartFilter());
                    textCoordinateShiftFactor.setText("" + fitConfig.getCoordinateShiftFactor());
                    textSignalStrength.setText("" + fitConfig.getSignalStrength());
                    textMinPhotons.setText("" + fitConfig.getMinPhotons());
                    textMinWidthFactor.setText("" + fitConfig.getMinWidthFactor());
                    textWidthFactor.setText("" + fitConfig.getWidthFactor());
                    textPrecisionThreshold.setText("" + fitConfig.getPrecisionThreshold());
                    cbLocalBackground.setState(fitConfig.isPrecisionUsingBackground());
                }
            } else {
                // Reset 
                cbSmartFilter.setState(false);
                textCoordinateShiftFactor.setText("0");
                textSignalStrength.setText("0");
                textMinPhotons.setText("0");
                textMinWidthFactor.setText("0");
                textWidthFactor.setText("0");
                textPrecisionThreshold.setText("0");
                cbLocalBackground.setState(false);
            }
        } else {
            if (template != null) {
                if (template.isFitEngineConfiguration()) {
                    boolean custom = ConfigurationTemplate.isCustomTemplate(templateName);
                    FitEngineConfiguration config2 = template.getFitEngineConfiguration();
                    FitConfiguration fitConfig2 = config2.getFitConfiguration();
                    if (custom && fitConfig2.getInitialPeakStdDev0() > 0)
                        textInitialPeakStdDev0.setText("" + fitConfig2.getInitialPeakStdDev0());
                    textDataFilterType.select(config2.getDataFilterType().ordinal());
                    textDataFilter.select(config2.getDataFilter(0).ordinal());
                    textSmooth.setText("" + config2.getSmooth(0));
                    textSearch.setText("" + config2.getSearch());
                    textBorder.setText("" + config2.getBorder());
                    textFitting.setText("" + config2.getFitting());
                    textFitSolver.select(fitConfig2.getFitSolver().ordinal());
                    textFitFunction.select(fitConfig2.getFitFunction().ordinal());
                    // Copy settings not in the dialog for the fit solver
                    fitConfig.setMaxIterations(fitConfig2.getMaxIterations());
                    fitConfig.setMaxFunctionEvaluations(fitConfig2.getMaxFunctionEvaluations());
                    // MLE settings
                    fitConfig.setModelCamera(fitConfig2.isModelCamera());
                    fitConfig.setSearchMethod(fitConfig2.getSearchMethod());
                    fitConfig.setRelativeThreshold(fitConfig2.getRelativeThreshold());
                    fitConfig.setAbsoluteThreshold(fitConfig2.getAbsoluteThreshold());
                    fitConfig.setGradientLineMinimisation(fitConfig2.isGradientLineMinimisation());
                    // LSE settings
                    fitConfig.setFitCriteria(fitConfig2.getFitCriteria());
                    fitConfig.setSignificantDigits(fitConfig2.getSignificantDigits());
                    fitConfig.setDelta(fitConfig2.getDelta());
                    fitConfig.setLambda(fitConfig2.getLambda());
                }
            } else {
            // Ignore
            }
        }
    } else if (e.getSource() instanceof Checkbox) {
        Checkbox checkbox = (Checkbox) e.getSource();
        if (!checkbox.getState())
            return;
        if (textCoordinateShiftFactor != null) {
            if (!updateFilterConfiguration(filterFitConfig))
                return;
            cbSmartFilter.setState(filterFitConfig.isSmartFilter());
            textCoordinateShiftFactor.setText("" + filterFitConfig.getCoordinateShiftFactor());
            textSignalStrength.setText("" + filterFitConfig.getSignalStrength());
            textMinPhotons.setText("" + filterFitConfig.getMinPhotons());
            textMinWidthFactor.setText("" + filterFitConfig.getMinWidthFactor());
            textWidthFactor.setText("" + filterFitConfig.getWidthFactor());
            textPrecisionThreshold.setText("" + filterFitConfig.getPrecisionThreshold());
            cbLocalBackground.setState(filterFitConfig.isPrecisionUsingBackground());
        } else {
            if (!updateFitConfiguration(config))
                return;
            textInitialPeakStdDev0.setText("" + fitConfig.getInitialPeakStdDev0());
            textDataFilterType.select(config.getDataFilterType().ordinal());
            textDataFilter.select(config.getDataFilter(0).ordinal());
            textSmooth.setText("" + config.getSmooth(0));
            textSearch.setText("" + config.getSearch());
            textBorder.setText("" + config.getBorder());
            textFitting.setText("" + config.getFitting());
            textFitSolver.select(fitConfig.getFitSolver().ordinal());
            textFitFunction.select(fitConfig.getFitFunction().ordinal());
            textMatchDistance.setText("" + matchDistance);
            textLowerDistance.setText("" + lowerDistance);
            textSignalFactor.setText("" + signalFactor);
            textLowerFactor.setText("" + lowerSignalFactor);
        }
    }
}
Also used : Choice(java.awt.Choice) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) Checkbox(java.awt.Checkbox) GlobalSettings(gdsc.smlm.ij.settings.GlobalSettings)

Aggregations

FitConfiguration (gdsc.smlm.fitting.FitConfiguration)32 FitEngineConfiguration (gdsc.smlm.engine.FitEngineConfiguration)16 GlobalSettings (gdsc.smlm.ij.settings.GlobalSettings)8 GenericDialog (ij.gui.GenericDialog)6 Rectangle (java.awt.Rectangle)5 BasePoint (gdsc.core.match.BasePoint)4 Calibration (gdsc.smlm.results.Calibration)4 MultiPathFilter (gdsc.smlm.results.filter.MultiPathFilter)4 ExtendedGenericDialog (ij.gui.ExtendedGenericDialog)4 IJLogger (gdsc.core.ij.IJLogger)3 Gaussian2DFitter (gdsc.smlm.fitting.Gaussian2DFitter)3 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)3 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)3 DirectFilter (gdsc.smlm.results.filter.DirectFilter)3 Checkbox (java.awt.Checkbox)3 ImageExtractor (gdsc.core.utils.ImageExtractor)2 FitEngine (gdsc.smlm.engine.FitEngine)2 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)2 FitResult (gdsc.smlm.fitting.FitResult)2 FitStatus (gdsc.smlm.fitting.FitStatus)2