Search in sources :

Example 26 with FitConfiguration

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

the class FitWorker method run.

/**
	 * Locate all the peaks in the image specified by the fit job
	 * <p>
	 * WARNING: The FitWorker fits a sub-region of the data for each maxima. It then updates the FitResult parameters
	 * with an offset reflecting the position. The initialParameters are not updated with this offset unless configured.
	 * 
	 * @param job
	 *            The fit job
	 */
public void run(FitJob job) {
    final long start = System.nanoTime();
    job.start();
    this.job = job;
    benchmarking = false;
    this.slice = job.slice;
    // Used for debugging
    //if (logger == null) logger = new gdsc.fitting.logging.ConsoleLogger();
    // Crop to the ROI
    cc = new CoordinateConverter(job.bounds);
    final int width = cc.dataBounds.width;
    final int height = cc.dataBounds.height;
    borderLimitX = width - border;
    borderLimitY = height - border;
    data = job.data;
    FitParameters params = job.getFitParameters();
    this.endT = (params != null) ? params.endT : -1;
    candidates = indentifySpots(job, width, height, params);
    if (candidates.size == 0) {
        finish(job, start);
        return;
    }
    fittedBackground = 0;
    // Always get the noise and store it with the results.
    if (params != null && !Float.isNaN(params.noise)) {
        noise = params.noise;
        fitConfig.setNoise(noise);
    } else if (calculateNoise) {
        noise = estimateNoise(width, height);
        fitConfig.setNoise(noise);
    }
    //System.out.printf("Slice %d : Noise = %g\n", slice, noise);
    if (logger != null)
        logger.info("Slice %d: Noise = %f", slice, noise);
    final ImageExtractor ie = new ImageExtractor(data, width, height);
    double[] region = null;
    if (params != null && params.fitTask == FitTask.MAXIMA_IDENITIFICATION) {
        final float sd0 = (float) fitConfig.getInitialPeakStdDev0();
        final float sd1 = (float) fitConfig.getInitialPeakStdDev1();
        for (int n = 0; n < candidates.getSize(); n++) {
            // Find the background using the perimeter of the data.
            // TODO - Perhaps the Gaussian Fitter should be used to produce the initial estimates but no actual fit done.
            // This would produce coords using the centre-of-mass.
            final Candidate candidate = candidates.get(n);
            final int x = candidate.x;
            final int y = candidate.y;
            final Rectangle regionBounds = ie.getBoxRegionBounds(x, y, fitting);
            region = ie.crop(regionBounds, region);
            final float b = (float) Gaussian2DFitter.getBackground(region, regionBounds.width, regionBounds.height, 1);
            // Offset the coords to the centre of the pixel. Note the bounds will be added later.
            // Subtract the background to get the amplitude estimate then convert to signal.
            final float amplitude = candidate.intensity - ((relativeIntensity) ? 0 : b);
            final float signal = (float) (amplitude * 2.0 * Math.PI * sd0 * sd1);
            final float[] peakParams = new float[] { b, signal, 0, x + 0.5f, y + 0.5f, sd0, sd1 };
            final int index = y * width + x;
            sliceResults.add(createResult(cc.fromDataToGlobalX(x), cc.fromDataToGlobalY(y), data[index], 0, noise, peakParams, null, n));
        }
    } else {
        initialiseFitting();
        // Smooth the data to provide initial background estimates
        final BlockAverageDataProcessor processor = new BlockAverageDataProcessor(1, 1);
        final float[] smoothedData = processor.process(data, width, height);
        final ImageExtractor ie2 = new ImageExtractor(smoothedData, width, height);
        // Allow the results to be filtered for certain peaks
        if (params != null && params.filter != null) {
            resultFilter = new DistanceResultFilter(params.filter, params.distanceThreshold, candidates.getlength());
        //filter = new OptimumDistanceResultFilter(params.filter, params.distanceThreshold, maxIndices.length);
        }
        // The SpotFitter is used to create a dynamic MultiPathFitResult object.
        // This is then passed to a multi-path filter. Thus the same fitting decision process 
        // is used when benchmarking and when running on actual data.
        // Note: The SpotFitter labels each PreprocessedFitResult using the offset in the FitResult object.
        // The initial params and deviations can then be extracted for the results that pass the filter.
        MultiPathFilter filter;
        IMultiPathFitResults multiPathResults = this;
        SelectedResultStore store = this;
        coordinateStore = coordinateStore.resize(width, height);
        if (params != null && params.fitTask == FitTask.BENCHMARKING) {
            // Run filtering as normal. However in the event that a candidate is missed or some
            // results are not generated we must generate them. This is done in the complete(int)
            // method if we set the benchmarking flag.
            benchmarking = true;
            // Filter using the benchmark filter
            filter = params.benchmarkFilter;
            if (filter == null) {
                // Create a default filter using the standard FitConfiguration to ensure sensible fits
                // are stored as the current slice results.
                // Note the current fit configuration for benchmarking may have minimal filtering settings
                // so we do not use that object.
                final FitConfiguration tmp = new FitConfiguration();
                final double residualsThreshold = 0.4;
                filter = new MultiPathFilter(tmp, createMinimalFilter(), residualsThreshold);
            }
        } else {
            // Filter using the configuration
            filter = new MultiPathFilter(fitConfig, createMinimalFilter(), config.getResidualsThreshold());
        }
        // If we are benchmarking then do not generate results dynamically since we will store all 
        // results in the fit job
        dynamicMultiPathFitResult = new DynamicMultiPathFitResult(ie, ie2, !benchmarking);
        // Debug where the fit config may be different between benchmarking and fitting
        if (slice == -1) {
            SettingsManager.saveFitEngineConfiguration(config, String.format("/tmp/config.%b.xml", benchmarking));
            Utils.write(String.format("/tmp/filter.%b.xml", benchmarking), filter.toXML());
            //filter.setDebugFile(String.format("/tmp/fitWorker.%b.txt", benchmarking));
            StringBuilder sb = new StringBuilder();
            sb.append((benchmarking) ? ((gdsc.smlm.results.filter.Filter) filter.getFilter()).toXML() : fitConfig.getSmartFilter().toXML()).append("\n");
            sb.append(((gdsc.smlm.results.filter.Filter) filter.getMinimalFilter()).toXML()).append("\n");
            sb.append(filter.residualsThreshold).append("\n");
            sb.append(config.getFailuresLimit()).append("\n");
            sb.append(fitConfig.getDuplicateDistance()).append("\n");
            if (spotFilter != null)
                sb.append(spotFilter.getDescription()).append("\n");
            sb.append("MaxCandidate = ").append(candidates.getSize()).append("\n");
            for (int i = 0; i < candidates.list.length; i++) {
                sb.append(String.format("Fit %d [%d,%d = %.1f]\n", i, candidates.get(i).x, candidates.get(i).y, candidates.get(i).intensity));
            }
            Utils.write(String.format("/tmp/candidates.%b.xml", benchmarking), sb.toString());
        }
        filter.select(multiPathResults, config.getFailuresLimit(), true, store, coordinateStore);
        if (logger != null)
            logger.info("Slice %d: %d / %d", slice, success, candidates.getSize());
        // Result filter post-processing
        if (resultFilter != null) {
            resultFilter.finalise();
            job.setResults(resultFilter.getResults());
            job.setIndices(resultFilter.getMaxIndices());
            for (int i = 0; i < resultFilter.getFilteredCount(); i++) {
                job.setFitResult(i, resultFilter.getFitResults()[i]);
            }
            sliceResults.clear();
            sliceResults.addAll(resultFilter.getResults());
        }
    }
    // Add the ROI bounds to the fitted peaks
    final float offsetx = cc.dataBounds.x;
    final float offsety = cc.dataBounds.y;
    for (int i = 0; i < sliceResults.size(); i++) {
        final PeakResult result = sliceResults.get(i);
        result.params[Gaussian2DFunction.X_POSITION] += offsetx;
        result.params[Gaussian2DFunction.Y_POSITION] += offsety;
    }
    this.results.addAll(sliceResults);
    finish(job, start);
}
Also used : Rectangle(java.awt.Rectangle) PreprocessedPeakResult(gdsc.smlm.results.filter.PreprocessedPeakResult) PeakResult(gdsc.smlm.results.PeakResult) IdPeakResult(gdsc.smlm.results.IdPeakResult) ExtendedPeakResult(gdsc.smlm.results.ExtendedPeakResult) ImageExtractor(gdsc.core.utils.ImageExtractor) BlockAverageDataProcessor(gdsc.smlm.filters.BlockAverageDataProcessor) DistanceResultFilter(gdsc.smlm.engine.filter.DistanceResultFilter) SelectedResultStore(gdsc.smlm.results.filter.MultiPathFilter.SelectedResultStore) MaximaSpotFilter(gdsc.smlm.filters.MaximaSpotFilter) ResultFilter(gdsc.smlm.engine.filter.ResultFilter) DistanceResultFilter(gdsc.smlm.engine.filter.DistanceResultFilter) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) MultiPathFilter(gdsc.smlm.results.filter.MultiPathFilter) IMultiPathFitResults(gdsc.smlm.results.filter.IMultiPathFitResults)

Example 27 with FitConfiguration

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

the class DoubletAnalysis method saveTemplate.

/**
	 * Save PeakFit configuration template using the current benchmark settings.
	 * 
	 * @param summary
	 */
private void saveTemplate(String summary) {
    if (!saveTemplate)
        return;
    // Start with a clone of the filter settings
    FitConfiguration fitConfig = filterFitConfig.clone();
    FitEngineConfiguration config = new FitEngineConfiguration(fitConfig);
    // Copy settings used during fitting
    updateConfiguration(config);
    // Remove the PSF width to make the template generic
    fitConfig.setInitialPeakStdDev(0);
    fitConfig.setNmPerPixel(0);
    fitConfig.setGain(0);
    fitConfig.setNoise(0);
    // This was done fitting all the results
    config.setFailuresLimit(-1);
    if (useBenchmarkSettings) {
        FitEngineConfiguration pConfig = new FitEngineConfiguration(new FitConfiguration());
        // TODO - add option to use latest or the best
        if (BenchmarkFilterAnalysis.updateConfiguration(pConfig, false))
            config.setFailuresLimit(pConfig.getFailuresLimit());
    }
    // Set the residuals
    fitConfig.setComputeResiduals(true);
    // TODO - make the choice of the best residuals configurable
    config.setResidualsThreshold(residualsScore.bestResiduals[2]);
    String filename = BenchmarkFilterAnalysis.getFilename("Template_File", templateFilename);
    if (filename != null) {
        templateFilename = filename;
        GlobalSettings settings = new GlobalSettings();
        settings.setNotes(getNotes(summary));
        settings.setFitEngineConfiguration(config);
        if (!SettingsManager.saveSettings(settings, filename, true))
            IJ.log("Unable to save the template configuration");
    }
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration) FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) GlobalSettings(gdsc.smlm.ij.settings.GlobalSettings)

Example 28 with FitConfiguration

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

the class BenchmarkFilterAnalysis method updateConfiguration.

/**
	 * Updates the given configuration using the latest settings used in benchmarking filtering. The residuals threshold
	 * will be copied only if the input FitConfiguration has isComputeResiduals() set to true.
	 *
	 * @param config
	 *            the configuration
	 * @param useLatest
	 *            Use the latest best filter. Otherwise use the highest scoring.
	 * @return true, if successful
	 */
public static boolean updateConfiguration(FitEngineConfiguration config, boolean useLatest) {
    if (scores.isEmpty())
        return false;
    FilterResult best;
    if (useLatest) {
        best = scores.get(scores.size() - 1);
    } else {
        best = getBestResult();
    }
    // New smart filter support
    final FitConfiguration fitConfig = config.getFitConfiguration();
    fitConfig.setDirectFilter(best.getFilter());
    if (fitConfig.isComputeResiduals()) {
        config.setResidualsThreshold(best.residualsThreshold);
        fitConfig.setComputeResiduals(true);
    } else {
        config.setResidualsThreshold(1);
        fitConfig.setComputeResiduals(false);
    }
    // Note:
    // We leave the simple filter settings alone. These may be enabled as well, e.g. by the BenchmarkSpotFit plugin
    // We could set the fail count range dynamically using a window around the best filter 
    config.setFailuresLimit(best.failCount);
    fitConfig.setDuplicateDistance(best.duplicateDistance);
    return true;
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration)

Example 29 with FitConfiguration

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

the class BenchmarkFilterAnalysis method saveTemplate.

/**
	 * Save PeakFit configuration template using the current benchmark settings.
	 * 
	 * @param topFilterSummary
	 */
private void saveTemplate(String topFilterSummary) {
    FitEngineConfiguration config = new FitEngineConfiguration(new FitConfiguration());
    if (!updateAllConfiguration(config, true)) {
        IJ.log("Unable to create the template configuration");
        return;
    }
    // Remove the PSF width to make the template generic
    config.getFitConfiguration().setInitialPeakStdDev(0);
    String filename = getFilename("Template_File", templateFilename);
    if (filename != null) {
        templateFilename = filename;
        Prefs.set(KEY_TEMPLATE_FILENAME, filename);
        GlobalSettings settings = new GlobalSettings();
        settings.setNotes(getNotes(topFilterSummary));
        settings.setFitEngineConfiguration(config);
        if (!SettingsManager.saveSettings(settings, filename, true)) {
            IJ.log("Unable to save the template configuration");
            return;
        }
        // Save some random frames from the test image data
        ImagePlus imp = CreateData.getImage();
        if (imp == null)
            return;
        // Get the number of frames
        final ImageStack stack = imp.getImageStack();
        if (sampler == null || sampler.getResults() != results) {
            sampler = new ResultsImageSampler(results, stack, 32);
            sampler.analyse();
        }
        if (!sampler.isValid())
            return;
        // Iteratively show the example until the user is happy.
        // Yes = OK, No = Repeat, Cancel = Do not save
        String keyNo = "nNo";
        String keyLow = "nLower";
        String keyHigh = "nHigher";
        if (Utils.isMacro()) {
            // Collect the options if running in a macro
            String options = Macro.getOptions();
            nNo = Integer.parseInt(Macro.getValue(options, keyNo, Integer.toString(nNo)));
            nLow = Integer.parseInt(Macro.getValue(options, keyLow, Integer.toString(nLow)));
            nHigh = Integer.parseInt(Macro.getValue(options, keyHigh, Integer.toString(nHigh)));
        } else {
            if (nLow + nHigh == 0)
                nLow = nHigh = 1;
        }
        final ImagePlus[] out = new ImagePlus[1];
        out[0] = sampler.getSample(nNo, nLow, nHigh);
        if (!Utils.isMacro()) {
            // Show the template results
            final ConfigurationTemplate configTemplate = new ConfigurationTemplate();
            // Interactively show the sample image data
            final boolean[] close = new boolean[1];
            final ImagePlus[] outImp = new ImagePlus[1];
            if (out[0] != null) {
                outImp[0] = display(out[0]);
                if (Utils.isNewWindow()) {
                    close[0] = true;
                    // Zoom a bit
                    ImageWindow iw = outImp[0].getWindow();
                    for (int i = 7; i-- > 0 && Math.max(iw.getWidth(), iw.getHeight()) < 512; ) {
                        iw.getCanvas().zoomIn(0, 0);
                    }
                }
                configTemplate.createResults(outImp[0]);
            }
            // TODO - fix this when a second sample is made as the results are not updated.
            ImageListener listener = new ImageListener() {

                public void imageOpened(ImagePlus imp) {
                }

                public void imageClosed(ImagePlus imp) {
                }

                public void imageUpdated(ImagePlus imp) {
                    if (imp != null && imp == outImp[0]) {
                        configTemplate.updateResults(imp.getCurrentSlice());
                    }
                }
            };
            ImagePlus.addImageListener(listener);
            // For the dialog
            String msg = String.format("Showing image data for the template example.\n \nSample Frames:\nEmpty = %d\nLower density = %d\nHigher density = %d\n", sampler.getNumberOfEmptySamples(), sampler.getNumberOfLowDensitySamples(), sampler.getNumberOfHighDensitySamples());
            // Turn off the recorder when the dialog is showing
            boolean record = Recorder.record;
            Recorder.record = false;
            NonBlockingGenericDialog gd = new NonBlockingGenericDialog(TITLE);
            gd.addMessage(msg);
            //gd.enableYesNoCancel(" Save ", " Resample ");
            gd.addSlider(keyNo, 0, 10, nNo);
            gd.addSlider(keyLow, 0, 10, nLow);
            gd.addSlider(keyHigh, 0, 10, nHigh);
            gd.addDialogListener(new DialogListener() {

                public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
                    // image the user has not seen.
                    if (e == null)
                        return true;
                    nNo = (int) gd.getNextNumber();
                    nLow = (int) gd.getNextNumber();
                    nHigh = (int) gd.getNextNumber();
                    out[0] = sampler.getSample(nNo, nLow, nHigh);
                    if (out[0] != null) {
                        outImp[0] = display(out[0]);
                        if (Utils.isNewWindow()) {
                            close[0] = true;
                            // Zoom a bit
                            ImageWindow iw = outImp[0].getWindow();
                            for (int i = 7; i-- > 0 && Math.max(iw.getWidth(), iw.getHeight()) < 512; ) {
                                iw.getCanvas().zoomIn(0, 0);
                            }
                        }
                        configTemplate.createResults(outImp[0]);
                    }
                    return true;
                }
            });
            gd.showDialog();
            if (gd.wasCanceled()) {
                out[0] = null;
                // For the recorder
                nNo = nLow = nHigh = 0;
            }
            if (close[0]) {
                // Because closing the image sets the stack pixels array to null
                if (out[0] != null)
                    out[0] = out[0].duplicate();
                outImp[0].close();
            }
            configTemplate.closeResults();
            ImagePlus.removeImageListener(listener);
            if (record) {
                Recorder.record = true;
                Recorder.recordOption(keyNo, Integer.toString(nNo));
                Recorder.recordOption(keyLow, Integer.toString(nLow));
                Recorder.recordOption(keyHigh, Integer.toString(nHigh));
            }
        }
        if (out[0] == null)
            return;
        ImagePlus example = out[0];
        filename = Utils.replaceExtension(filename, ".tif");
        IJ.save(example, filename);
    }
}
Also used : ResultsImageSampler(gdsc.smlm.ij.results.ResultsImageSampler) ImageWindow(ij.gui.ImageWindow) ImageStack(ij.ImageStack) ImageListener(ij.ImageListener) FitEngineConfiguration(gdsc.smlm.engine.FitEngineConfiguration) GlobalSettings(gdsc.smlm.ij.settings.GlobalSettings) NonBlockingGenericDialog(ij.gui.NonBlockingGenericDialog) ImagePlus(ij.ImagePlus) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) DialogListener(ij.gui.DialogListener) GenericDialog(ij.gui.GenericDialog) NonBlockingGenericDialog(ij.gui.NonBlockingGenericDialog) AWTEvent(java.awt.AWTEvent)

Example 30 with FitConfiguration

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

the class BenchmarkSpotFit method updateConfiguration.

/**
	 * Updates the given configuration using the latest 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.setFitting(config.getFitting());
    pFitConfig.setFitSolver(fitConfig.getFitSolver());
    pFitConfig.setFitFunction(fitConfig.getFitFunction());
    pConfig.setIncludeNeighbours(config.isIncludeNeighbours());
    pConfig.setNeighbourHeightThreshold(config.getNeighbourHeightThreshold());
    pFitConfig.setDuplicateDistance(fitConfig.getDuplicateDistance());
    if (computeDoublets) {
        //config.setComputeResiduals(true);
        pConfig.setResidualsThreshold(0);
        pFitConfig.setComputeResiduals(true);
    } else {
        pConfig.setResidualsThreshold(1);
        pFitConfig.setComputeResiduals(false);
    }
    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());
    pFitConfig.setSmartFilter(false);
    // We used simple filtering. Also we must set the width factors as these are used 
    // during fitting to set the bounds.
    pFitConfig.setDisableSimpleFilter(fitConfig.isDisableSimpleFilter());
    pFitConfig.setCoordinateShiftFactor(fitConfig.getCoordinateShiftFactor());
    pFitConfig.setSignalStrength(fitConfig.getSignalStrength());
    pFitConfig.setMinPhotons(fitConfig.getMinPhotons());
    pFitConfig.setMinWidthFactor(fitConfig.getMinWidthFactor());
    pFitConfig.setWidthFactor(fitConfig.getWidthFactor());
    pFitConfig.setPrecisionThreshold(fitConfig.getPrecisionThreshold());
    pFitConfig.setPrecisionUsingBackground(fitConfig.isPrecisionUsingBackground());
    return true;
}
Also used : FitConfiguration(gdsc.smlm.fitting.FitConfiguration)

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