Search in sources :

Example 26 with FitConfiguration

use of uk.ac.sussex.gdsc.smlm.engine.FitConfiguration in project GDSC-SMLM by aherbert.

the class PsfEstimator method calculateStatistics.

private boolean calculateStatistics(PeakFit fitter, double[] params, double[] paramsDev) {
    debug("  Fitting PSF");
    swapStatistics();
    // Create the fit engine using the PeakFit plugin
    final FitConfiguration fitConfig = config.getFitConfiguration();
    fitConfig.setInitialPeakStdDev0((float) params[1]);
    try {
        fitConfig.setInitialPeakStdDev1((float) params[2]);
        fitConfig.setInitialAngle((float) Math.toRadians(params[0]));
    } catch (IllegalStateException ex) {
    // Ignore this as the current PSF is not a 2 axis and theta Gaussian PSF
    }
    final ImageStack stack = imp.getImageStack();
    final 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();
    final FitEngine engine = fitter.createFitEngine();
    // Use random slices
    final int[] slices = new int[stack.getSize()];
    for (int i = 0; i < slices.length; i++) {
        slices[i] = i + 1;
    }
    RandomUtils.shuffle(slices, UniformRandomProviders.create());
    IJ.showStatus("Fitting ...");
    // Use multi-threaded code for speed
    int sliceIndex;
    for (sliceIndex = 0; sliceIndex < slices.length; sliceIndex++) {
        final int slice = slices[sliceIndex];
        IJ.showProgress(size(), settings.getNumberOfPeaks());
        final ImageProcessor ip = stack.getProcessor(slice);
        // stack processor does not set the bounds required by ImageConverter
        ip.setRoi(roi);
        final FitJob job = new FitJob(slice, ImageJImageConverter.getData(ip), roi);
        engine.run(job);
        if (sampleSizeReached() || ImageJUtils.isInterrupted()) {
            break;
        }
    }
    if (ImageJUtils.isInterrupted()) {
        IJ.showProgress(1);
        engine.end(true);
        return false;
    }
    // Wait until we have enough results
    while (!sampleSizeReached() && !engine.isQueueEmpty()) {
        IJ.showProgress(size(), settings.getNumberOfPeaks());
        try {
            Thread.sleep(50);
        } catch (final InterruptedException ex) {
            Thread.currentThread().interrupt();
            throw new ConcurrentRuntimeException("Unexpected interruption", ex);
        }
    }
    // End now if we have enough samples
    engine.end(sampleSizeReached());
    ImageJUtils.finished();
    // 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)", sliceIndex, slices.length, size());
    setParams(ANGLE, params, paramsDev, sampleNew[ANGLE]);
    setParams(X, params, paramsDev, sampleNew[X]);
    setParams(Y, params, paramsDev, sampleNew[Y]);
    if (settings.getShowHistograms()) {
        final HistogramPlotBuilder builder = new HistogramPlotBuilder(TITLE).setNumberOfBins(settings.getHistogramBins());
        final WindowOrganiser wo = new WindowOrganiser();
        for (int ii = 0; ii < 3; ii++) {
            if (sampleNew[ii].getN() == 0) {
                continue;
            }
            final StoredDataStatistics stats = StoredDataStatistics.create(sampleNew[ii].getValues());
            builder.setData(stats).setName(NAMES[ii]).setPlotLabel("Mean = " + MathUtils.rounded(stats.getMean()) + ". Median = " + MathUtils.rounded(sampleNew[ii].getPercentile(50))).show(wo);
        }
        wo.tile();
    }
    if (size() < 2) {
        log("ERROR: Insufficient number of fitted peaks, terminating ...");
        return false;
    }
    return true;
}
Also used : InterlacedImageSource(uk.ac.sussex.gdsc.smlm.results.InterlacedImageSource) AggregatedImageSource(uk.ac.sussex.gdsc.smlm.results.AggregatedImageSource) ImageStack(ij.ImageStack) Rectangle(java.awt.Rectangle) StoredDataStatistics(uk.ac.sussex.gdsc.core.utils.StoredDataStatistics) HistogramPlotBuilder(uk.ac.sussex.gdsc.core.ij.HistogramPlot.HistogramPlotBuilder) WindowOrganiser(uk.ac.sussex.gdsc.core.ij.plugin.WindowOrganiser) IJImageSource(uk.ac.sussex.gdsc.smlm.ij.IJImageSource) ImageProcessor(ij.process.ImageProcessor) FitEngine(uk.ac.sussex.gdsc.smlm.engine.FitEngine) ConcurrentRuntimeException(org.apache.commons.lang3.concurrent.ConcurrentRuntimeException) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) ImageSource(uk.ac.sussex.gdsc.smlm.results.ImageSource) IJImageSource(uk.ac.sussex.gdsc.smlm.ij.IJImageSource) InterlacedImageSource(uk.ac.sussex.gdsc.smlm.results.InterlacedImageSource) AggregatedImageSource(uk.ac.sussex.gdsc.smlm.results.AggregatedImageSource) FitJob(uk.ac.sussex.gdsc.smlm.engine.FitJob)

Example 27 with FitConfiguration

use of uk.ac.sussex.gdsc.smlm.engine.FitConfiguration in project GDSC-SMLM by aherbert.

the class PsfEstimator method showDialog.

/**
 * Show dialog.
 *
 * @param imp the imp
 * @return the int
 */
private int showDialog(ImagePlus imp) {
    // Keep class variables for the parameters we are fitting
    final FitConfiguration fitConfig = config.getFitConfiguration();
    initialPeakStdDev0 = 1;
    initialPeakStdDev1 = 1;
    initialPeakAngle = 0;
    try {
        initialPeakStdDev0 = fitConfig.getInitialXSd();
        initialPeakStdDev1 = fitConfig.getInitialYSd();
        initialPeakAngle = fitConfig.getInitialAngle();
    } catch (final IllegalStateException | ConfigurationException ex) {
    // Ignore this as the current PSF is not a 2 axis and theta Gaussian PSF
    }
    if (!extraOptions) {
        interlacedData = false;
        integrateFrames = 1;
    }
    this.imp = imp;
    final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    gd.addHelp(HelpUrls.getUrl("psf-estimator"));
    gd.addMessage("Estimate 2D Gaussian to fit maxima");
    gd.addNumericField("Initial_StdDev0", initialPeakStdDev0, 3);
    gd.addNumericField("Initial_StdDev1", initialPeakStdDev1, 3);
    gd.addNumericField("Initial_Angle", initialPeakAngle, 3);
    gd.addNumericField("Number_of_peaks", settings.getNumberOfPeaks(), 0);
    // pValue sets the smallest significance level probability level at which they are said to be
    // different.
    // i.e. p <= pValue they are different
    // lower pValue means harder to be found different.
    // lower pValue means easier to be found the same.
    gd.addNumericField("p-Value", settings.getPValue(), 4);
    gd.addCheckbox("Update_preferences", settings.getUpdatePreferences());
    gd.addCheckbox("Log_progress", settings.getDebugPsfEstimator());
    gd.addCheckbox("Iterate", settings.getIterate());
    gd.addCheckbox("Show_histograms", settings.getShowHistograms());
    gd.addNumericField("Histogram_bins", settings.getHistogramBins(), 0);
    PeakFit.addCameraOptions(gd, fitConfig);
    PeakFit.addPsfOptions(gd, fitConfig);
    final PeakFit.SimpleFitEngineConfigurationProvider provider = new PeakFit.SimpleFitEngineConfigurationProvider(config);
    PeakFit.addDataFilterOptions(gd, provider);
    PeakFit.addSearchOptions(gd, provider);
    PeakFit.addBorderOptions(gd, provider);
    PeakFit.addFittingOptions(gd, provider);
    if (extraOptions) {
        pluginSettings = Settings.load();
        gd.addCheckbox("Interlaced_data", pluginSettings.interlacedData);
        gd.addSlider("Integrate_frames", 1, 5, pluginSettings.integrateFrames);
    }
    gd.addMessage("--- Gaussian fitting ---");
    gd.addChoice("Fit_solver", SettingsManager.getFitSolverNames(), FitProtosHelper.getName(fitConfig.getFitSolver()));
    // Parameters specific to each Fit solver are collected in a second dialog
    gd.addNumericField("Fail_limit", config.getFailuresLimit(), 0);
    gd.addNumericField("Pass_rate", config.getPassRate(), 2);
    gd.addCheckbox("Include_neighbours", config.isIncludeNeighbours());
    gd.addSlider("Neighbour_height", 0.01, 1, config.getNeighbourHeightThreshold());
    gd.addSlider("Residuals_threshold", 0.01, 1, config.getResidualsThreshold());
    gd.addMessage("--- Peak filtering ---\nDiscard fits that shift; are too low; or expand/contract");
    gd.addCheckbox("Smart_filter", fitConfig.isSmartFilter());
    gd.addCheckbox("Disable_simple_filter", fitConfig.isDisableSimpleFilter());
    gd.addSlider("Shift_factor", 0.01, 2, fitConfig.getCoordinateShiftFactor());
    gd.addNumericField("Signal_strength", fitConfig.getSignalStrength(), 2);
    gd.addNumericField("Min_photons", fitConfig.getMinPhotons(), 0);
    gd.addSlider("Min_width_factor", 0, 0.99, fitConfig.getMinWidthFactor());
    gd.addSlider("Width_factor", 1, 4.5, fitConfig.getMaxWidthFactor());
    PeakFit.addPrecisionOptions(gd, new PeakFit.SimpleFitConfigurationProvider(fitConfig));
    gd.showDialog();
    if (gd.wasCanceled() || !readDialog(gd)) {
        return DONE;
    }
    return FLAGS;
}
Also used : ConfigurationException(uk.ac.sussex.gdsc.smlm.data.config.ConfigurationException) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)

Example 28 with FitConfiguration

use of uk.ac.sussex.gdsc.smlm.engine.FitConfiguration in project GDSC-SMLM by aherbert.

the class PeakFit method addPsfOptions.

/**
 * Adds the PSF options.
 *
 * <p>Note that if an astigmatic PSF is selected then the model must be created with
 * {@link #configurePsfModel(FitEngineConfiguration, int)}.
 *
 * @param gd the dialog
 * @param fitConfigurationProvider the fit configuration provider
 */
public static void addPsfOptions(final ExtendedGenericDialog gd, final FitConfigurationProvider fitConfigurationProvider) {
    final FitConfiguration fitConfig = fitConfigurationProvider.getFitConfiguration();
    gd.addChoice("PSF", getPsfTypeNames(), PsfProtosHelper.getName(fitConfig.getPsfType()), new OptionListener<Integer>() {

        @Override
        public boolean collectOptions(Integer field) {
            final FitConfiguration fitConfig = fitConfigurationProvider.getFitConfiguration();
            fitConfig.setPsfType(PeakFit.getPsfTypeValues()[field]);
            return collectOptions(false);
        }

        @Override
        public boolean collectOptions() {
            return collectOptions(true);
        }

        private boolean collectOptions(boolean silent) {
            final FitConfiguration localFitConfig = fitConfigurationProvider.getFitConfiguration();
            final PSFType psfType = localFitConfig.getPsfType();
            final ExtendedGenericDialog egd = new ExtendedGenericDialog("PSF Options", null);
            PSF oldPsf = null;
            if (psfType == PSFType.ASTIGMATIC_GAUSSIAN_2D) {
                // The PSF is entirely defined in the model
                String[] list = AstigmatismModelManager.listAstigmatismModels(false, localFitConfig.getCalibrationReader().getNmPerPixel(), 0.1);
                // In case the calibration has not been updated
                if (list.length == 0) {
                    list = AstigmatismModelManager.listAstigmatismModels(false, true);
                }
                egd.addChoice("Z-model", list, localFitConfig.getPsfModelName());
            } else {
                // Collect the PSF parameters
                oldPsf = localFitConfig.getPsf();
                for (int i = 0; i < oldPsf.getParametersCount(); i++) {
                    final PSFParameter p = oldPsf.getParameters(i);
                    egd.addNumericField(String.format("PSF_parameter_%d (%s)", i + 1, p.getName()), p.getValue(), 3);
                }
                if (psfType == PSFType.ONE_AXIS_GAUSSIAN_2D) {
                    egd.addCheckbox("Fixed", localFitConfig.isFixedPsf());
                }
            }
            egd.setSilent(silent);
            egd.showDialog(true, gd);
            if (egd.wasCanceled()) {
                return false;
            }
            if (psfType == PSFType.ASTIGMATIC_GAUSSIAN_2D) {
                // The PSF is entirely defined in the model
                localFitConfig.setPsfModelName(egd.getNextChoice());
                return true;
            }
            @SuppressWarnings("null") final PSF.Builder b = oldPsf.toBuilder();
            final int n = b.getParametersCount();
            for (int i = 0; i < n; i++) {
                b.getParametersBuilder(i).setValue(egd.getNextNumber());
            }
            final PSF newPsf = b.build();
            localFitConfig.setPsf(newPsf);
            boolean changed = !oldPsf.equals(newPsf);
            if (psfType == PSFType.ONE_AXIS_GAUSSIAN_2D) {
                final boolean newFixed = egd.getNextBoolean();
                changed = changed || (newFixed != localFitConfig.isFixedPsf());
                localFitConfig.setFixedPsf(newFixed);
            }
            return changed;
        }
    });
}
Also used : PSF(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSF) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) PSFParameter(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSFParameter) PSFType(uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSFType) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)

Example 29 with FitConfiguration

use of uk.ac.sussex.gdsc.smlm.engine.FitConfiguration in project GDSC-SMLM by aherbert.

the class PeakFit method configureDataFilter.

/**
 * Show a dialog to configure the data filter. The data filter type and the first data filter must
 * ALREADY be set in the configuration. The subsequent filters are then configured, e.g. for
 * difference and jury filters.
 *
 * <p>The updated settings are saved to the settings file. An error message is shown if the dialog
 * is cancelled or the configuration is invalid.
 *
 * <p>If the configuration is for a per-pixel camera type (e.g. sCMOS) then the camera model will
 * be loaded using the configured camera model name. This will be used to validate the filter to
 * check the filter supports the per-pixel camera type.
 *
 * @param config the config
 * @param flags the flags
 * @return True if the configuration succeeded
 */
public static boolean configureDataFilter(final FitEngineConfiguration config, int flags) {
    int numberOfFilters = 1;
    int filterCount;
    switch(config.getDataFilterType()) {
        case JURY:
            filterCount = Integer.MAX_VALUE;
            break;
        case DIFFERENCE:
            filterCount = 2;
            break;
        case SINGLE:
        default:
            filterCount = 1;
    }
    final String[] filterNames = SettingsManager.getDataFilterMethodNames();
    final DataFilterMethod[] filterValues = SettingsManager.getDataFilterMethodValues();
    // Check we have at least the first filter.
    if (config.getDataFiltersCount() == 0) {
        throw new IllegalStateException("No primary filter is configured");
    }
    final FitEngineConfigurationProvider fitEngineConfigurationProvider = () -> config;
    for (int i = 1; i < filterCount; i++) {
        final int filter = i + 1;
        final int ii = i;
        final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        if (filter == filterCount) {
            // This is maximum filter count so no continue option
            ImageJUtils.addMessage(gd, "Configure the %s filter.", FitProtosHelper.getName(config.getDataFilterType()));
        } else {
            gd.enableYesNoCancel("Add", "Continue");
            ImageJUtils.addMessage(gd, "Configure the %s filter.\nClick continue to proceed with the current set of %d.", FitProtosHelper.getName(config.getDataFilterType()), i);
        }
        final String fieldName = "Spot_filter" + filter;
        if (IJ.isMacro()) {
            // Use blank default value so bad macro parameters return nothing
            gd.addStringField(fieldName, "");
        } else {
            gd.addChoice(fieldName, filterNames, filterNames[config.getDataFilterMethod(ii, config.getDataFilterMethod(ii - 1)).ordinal()]);
        }
        addRelativeParameterOptions(gd, new RelativeParameterProvider(0, 4.5, "Smoothing" + filter, fitEngineConfigurationProvider, true) {

            @Override
            void setAbsolute(boolean absolute) {
                // Get the current settings
                final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
                final DataFilterMethod m = c.getDataFilterMethod(ii);
                final double smooth = c.getDataFilterParameter(ii).getValue();
                // Reset with the new absolute value
                c.setDataFilter(m, smooth, absolute, ii);
            }

            @Override
            boolean isAbsolute() {
                final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
                return c.getDataFilterParameterAbsolute(ii, c.getDataFilterParameterAbsolute(ii - 1));
            }

            @Override
            double getValue() {
                final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
                return c.getDataFilterParameterValue(ii, c.getDataFilterParameterValue(ii - 1));
            }
        });
        gd.showDialog();
        if (gd.wasCanceled()) {
            return false;
        }
        if (gd.wasOKed()) {
            int filterIndex = -1;
            if (IJ.isMacro()) {
                final String filterName = gd.getNextString();
                for (int j = 0; j < filterNames.length; j++) {
                    if (filterNames[j].equals(filterName)) {
                        filterIndex = j;
                        break;
                    }
                }
                if (filterIndex < 0) {
                    break;
                }
            } else {
                filterIndex = gd.getNextChoiceIndex();
            }
            // Note: The absolute flag is set in extra options
            config.setDataFilter(filterValues[filterIndex], Math.abs(gd.getNextNumber()), i);
            gd.collectOptions();
            numberOfFilters++;
        } else {
            break;
        }
    }
    config.setNumberOfFilters(numberOfFilters);
    if (BitFlagUtils.anyNotSet(flags, FLAG_NO_SAVE)) {
        saveFitEngineSettings(config);
    }
    final FitConfiguration fitConfig = config.getFitConfiguration();
    final CalibrationReader calibration = fitConfig.getCalibrationReader();
    if (calibration.isScmos()) {
        fitConfig.setCameraModel(CameraModelManager.load(fitConfig.getCameraModelName()));
    }
    try {
        config.createSpotFilter();
    } catch (final IllegalStateException ex) {
        IJ.error(TITLE, ex.getMessage());
        return false;
    }
    return true;
}
Also used : FitEngineConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) CalibrationReader(uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader) DataFilterMethod(uk.ac.sussex.gdsc.smlm.data.config.FitProtos.DataFilterMethod) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration)

Example 30 with FitConfiguration

use of uk.ac.sussex.gdsc.smlm.engine.FitConfiguration in project GDSC-SMLM by aherbert.

the class PsfCreator method fitSpot.

private MemoryPeakResults fitSpot(ImageStack stack, final int width, final int height, final int x, final int y) {
    Rectangle regionBounds = null;
    // Create a fit engine
    final MemoryPeakResults results = new MemoryPeakResults();
    final FitConfiguration fitConfig = config.getFitConfiguration();
    results.setCalibration(fitConfig.getCalibration());
    results.setPsf(fitConfig.getPsf());
    results.setSortAfterEnd(true);
    results.begin();
    final int threadCount = Prefs.getThreads();
    final FitEngine engine = FitEngine.create(config, SynchronizedPeakResults.create(results, threadCount), threadCount, FitQueue.BLOCKING);
    for (int slice = 1; slice <= stack.getSize(); slice++) {
        // Extract the region from each frame
        final ImageExtractor ie = ImageExtractor.wrap((float[]) stack.getPixels(slice), width, height);
        if (regionBounds == null) {
            regionBounds = ie.getBoxRegionBounds(x, y, boxRadius);
        }
        final float[] region = ie.crop(regionBounds);
        // Fit only a spot in the centre
        final FitParameters params = new FitParameters();
        params.maxIndices = new int[] { boxRadius * regionBounds.width + boxRadius };
        final ParameterisedFitJob job = new ParameterisedFitJob(slice, params, slice, region, regionBounds);
        // jobItems.add(job);
        engine.run(job);
    }
    engine.end(false);
    results.end();
    return results;
}
Also used : FitParameters(uk.ac.sussex.gdsc.smlm.engine.FitParameters) FitEngine(uk.ac.sussex.gdsc.smlm.engine.FitEngine) ParameterisedFitJob(uk.ac.sussex.gdsc.smlm.engine.ParameterisedFitJob) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) Rectangle(java.awt.Rectangle) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) ImageExtractor(uk.ac.sussex.gdsc.core.utils.ImageExtractor) Point(java.awt.Point) BasePoint(uk.ac.sussex.gdsc.core.match.BasePoint)

Aggregations

FitConfiguration (uk.ac.sussex.gdsc.smlm.engine.FitConfiguration)32 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)11 FitEngineConfiguration (uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration)9 BasePoint (uk.ac.sussex.gdsc.core.match.BasePoint)8 PeakResultPoint (uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)7 Checkbox (java.awt.Checkbox)6 Rectangle (java.awt.Rectangle)5 CalibrationWriter (uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter)5 ArrayList (java.util.ArrayList)4 ImageStack (ij.ImageStack)3 TextField (java.awt.TextField)3 ConcurrentRuntimeException (org.apache.commons.lang3.concurrent.ConcurrentRuntimeException)3 StoredDataStatistics (uk.ac.sussex.gdsc.core.utils.StoredDataStatistics)3 PSF (uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSF)3 BenchmarkSpotFilterResult (uk.ac.sussex.gdsc.smlm.ij.plugins.benchmark.BenchmarkSpotFilter.BenchmarkSpotFilterResult)3 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)3 TIntObjectHashMap (gnu.trove.map.hash.TIntObjectHashMap)2 Choice (java.awt.Choice)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2