Search in sources :

Example 11 with Nullable

use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method score.

@Nullable
@Override
public SearchResult<FilterScore>[] score(double[][] points) {
    gaIteration++;
    SimpleFilterScore max = filterScoreOptimum;
    final FilterScoreResult[] scoreResults = scoreFilters(setStrength(new FilterSet(searchSpaceToFilters(points))), false);
    if (scoreResults == null) {
        return null;
    }
    @SuppressWarnings("unchecked") final SearchResult<FilterScore>[] scores = new SearchResult[scoreResults.length];
    for (int index = 0; index < scoreResults.length; index++) {
        final FilterScoreResult scoreResult = scoreResults[index];
        final SimpleFilterScore result = new SimpleFilterScore(scoreResult, true, scoreResult.criteria >= minCriteria);
        if (result.compareTo(max) < 0) {
            max = result;
        }
        scores[index] = new SearchResult<>(result.result.filter.getParameters(), result);
    }
    filterScoreOptimum = max;
    // Add the best filter to the table
    // This filter may not have been part of the scored subset so use the entire results set for
    // reporting
    final DirectFilter filter = max.result.filter;
    final FractionClassificationResult r = scoreFilter(filter, defaultMinimalFilter, gaResultsList, coordinateStore);
    final StringBuilder text = createResult(filter, r);
    add(text, gaIteration);
    gaWindow.accept(text.toString());
    return scores;
}
Also used : FilterSet(uk.ac.sussex.gdsc.smlm.results.filter.FilterSet) IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) FractionClassificationResult(uk.ac.sussex.gdsc.core.match.FractionClassificationResult) SearchResult(uk.ac.sussex.gdsc.smlm.search.SearchResult) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 12 with Nullable

use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method readFilterSets.

@Nullable
@SuppressWarnings("unchecked")
private List<FilterSet> readFilterSets() {
    if (extraOptions) {
        final MultiPathFilter multiFilter = BenchmarkSpotFit.getMultiFilter();
        if (multiFilter != null) {
            final IDirectFilter f = multiFilter.getFilter();
            if (f instanceof DirectFilter) {
                final GenericDialog gd = new GenericDialog(TITLE);
                gd.addMessage("Use an identical filter to " + BenchmarkSpotFit.TITLE);
                gd.enableYesNoCancel();
                gd.hideCancelButton();
                gd.showDialog();
                if (gd.wasOKed()) {
                    final List<FilterSet> filterSets = new ArrayList<>(1);
                    final List<Filter> filters = new ArrayList<>(1);
                    filters.add((DirectFilter) f);
                    final FilterSet filterSet = new FilterSet(filters);
                    filterSets.add(filterSet);
                    resetParametersFromFitting();
                    createResultsPrefix2();
                    return filterSets;
                }
            }
        }
    }
    GUIFilterSettings filterSettings = SettingsManager.readGuiFilterSettings(0);
    final String filename = ImageJUtils.getFilename("Filter_File", filterSettings.getFilterSetFilename());
    if (filename != null) {
        IJ.showStatus("Reading filters ...");
        filterSettings = filterSettings.toBuilder().setFilterSetFilename(filename).build();
        // Allow the filters to be cached
        final Triple<String, Long, List<FilterSet>> filterCache = lastFilterList.get();
        if (isSameFile(filename, filterCache)) {
            final GenericDialog gd = new GenericDialog(TITLE);
            gd.hideCancelButton();
            gd.addMessage("The same filter file was selected.");
            gd.addCheckbox("Re-use_filters", settings.reUseFilters);
            gd.showDialog();
            if (!gd.wasCanceled()) {
                settings.reUseFilters = gd.getNextBoolean();
                if (settings.reUseFilters) {
                    SettingsManager.writeSettings(filterSettings);
                    return filterCache.getRight();
                }
            }
        }
        final File file = new File(filename);
        try (BufferedReader input = new BufferedReader(new UnicodeReader(new FileInputStream(file), null))) {
            // Use the instance so we can catch the exception
            final Object o = FilterXStreamUtils.getXStreamInstance().fromXML(input);
            if (!(o instanceof List<?>)) {
                IJ.log("No filter sets defined in the specified file: " + filename);
                return null;
            }
            SettingsManager.writeSettings(filterSettings);
            List<FilterSet> filterSets = (List<FilterSet>) o;
            if (containsStandardFilters(filterSets)) {
                IJ.log("Filter sets must contain 'Direct' filters");
                return null;
            }
            // Check they are not empty lists
            final List<FilterSet> filterSets2 = new LinkedList<>();
            for (final FilterSet filterSet : filterSets) {
                if (filterSet.size() != 0) {
                    filterSets2.add(filterSet);
                } else {
                    IJ.log("Filter set empty: " + filterSet.getName());
                }
            }
            if (filterSets2.isEmpty()) {
                IJ.log("All Filter sets are empty");
                return null;
            }
            // Maintain the same list type
            filterSets.clear();
            filterSets.addAll(filterSets2);
            // Option to enumerate filters
            filterSets = expandFilters(filterSets);
            // Save for re-use
            lastFilterList.set(Triple.of(filename, getLastModified(file), filterSets));
            return filterSets;
        } catch (final Exception ex) {
            IJ.log("Unable to load the filter sets from file: " + ex.getMessage());
        } finally {
            IJ.showStatus("");
        }
    }
    return null;
}
Also used : FilterSet(uk.ac.sussex.gdsc.smlm.results.filter.FilterSet) IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) ArrayList(java.util.ArrayList) IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) UnicodeReader(uk.ac.sussex.gdsc.core.utils.UnicodeReader) FileInputStream(java.io.FileInputStream) LinkedList(java.util.LinkedList) ConcurrentRuntimeException(org.apache.commons.lang3.concurrent.ConcurrentRuntimeException) GUIFilterSettings(uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.GUIFilterSettings) Filter(uk.ac.sussex.gdsc.smlm.results.filter.Filter) IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) MultiPathFilter(uk.ac.sussex.gdsc.smlm.results.filter.MultiPathFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) MaximaSpotFilter(uk.ac.sussex.gdsc.smlm.filters.MaximaSpotFilter) GenericDialog(ij.gui.GenericDialog) NonBlockingGenericDialog(ij.gui.NonBlockingGenericDialog) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) MultiPathFilter(uk.ac.sussex.gdsc.smlm.results.filter.MultiPathFilter) BufferedReader(java.io.BufferedReader) ArrayList(java.util.ArrayList) SettingsList(uk.ac.sussex.gdsc.core.utils.SettingsList) List(java.util.List) LinkedList(java.util.LinkedList) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) File(java.io.File) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 13 with Nullable

use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method scoreFilters.

/**
 * Score filters.
 *
 * @param points the points (must be sorted by duplicate distance)
 * @param createTextResult set to true to create the text result
 * @return the score results
 */
@Nullable
private ParameterScoreResult[] scoreFilters(double[][] points, boolean createTextResult) {
    if (points == null || points.length == 0) {
        return null;
    }
    gaResultsListToScore = gaResultsList;
    gaSubset = false;
    ParameterScoreResult[] scoreResults = new ParameterScoreResult[points.length];
    if (scoreResults.length == 1) {
        // No need to multi-thread this
        final int failCount = (int) Math.round(points[0][0]);
        final double residualsThreshold = points[0][1];
        final double duplicateDistance = points[0][2];
        scoreResults[0] = scoreFilter(searchScoreFilter, defaultMinimalFilter, failCount, residualsThreshold, duplicateDistance, createCoordinateStore(duplicateDistance), createTextResult);
    } else {
        // Multi-thread score all the result
        final int nThreads = getThreads(scoreResults.length);
        final BlockingQueue<ParameterScoreJob> jobs = new ArrayBlockingQueue<>(nThreads * 2);
        final List<Thread> threads = new LinkedList<>();
        final Ticker ticker = ImageJUtils.createTicker(scoreResults.length, nThreads, "Scoring Filters");
        for (int i = 0; i < nThreads; i++) {
            final ParameterScoreWorker worker = new ParameterScoreWorker(jobs, scoreResults, createTextResult, ticker);
            final Thread t = new Thread(worker);
            threads.add(t);
            t.start();
        }
        ticker.start();
        for (int i = 0; i < points.length; i++) {
            if (IJ.escapePressed()) {
                break;
            }
            put(jobs, new ParameterScoreJob(points[i], i));
        }
        // Finish all the worker threads by passing in a null job
        for (int i = 0; i < threads.size(); i++) {
            put(jobs, new ParameterScoreJob(null, -1));
        }
        // Wait for all to finish
        for (int i = 0; i < threads.size(); i++) {
            try {
                threads.get(i).join();
            } catch (final InterruptedException ex) {
                Logger.getLogger(BenchmarkFilterAnalysis.class.getName()).log(Level.WARNING, "Interrupted!", ex);
                Thread.currentThread().interrupt();
                throw new ConcurrentRuntimeException("Unexpected interruption", ex);
            }
        }
        threads.clear();
        ImageJUtils.finished();
        // In case the threads were interrupted
        if (ImageJUtils.isInterrupted()) {
            scoreResults = null;
        }
    }
    finishScoring();
    return scoreResults;
}
Also used : Ticker(uk.ac.sussex.gdsc.core.logging.Ticker) LinkedList(java.util.LinkedList) ConcurrentRuntimeException(org.apache.commons.lang3.concurrent.ConcurrentRuntimeException) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 14 with Nullable

use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method showOverlay.

/**
 * Show overlay.
 *
 * <ul>
 *
 * <li>Green = TP
 *
 * <li>Red = FP
 *
 * <li>Magenta = FP (Ignored from analysis)
 *
 * <li>Yellow = FN
 *
 * <li>Orange = FN (Outside border)
 *
 * </ul>
 *
 * @param allAssignments The assignments generated from running the filter (or null)
 * @param filter the filter
 * @return The results from running the filter (or null)
 */
@Nullable
@SuppressWarnings("null")
private PreprocessedPeakResult[] showOverlay(ArrayList<FractionalAssignment[]> allAssignments, DirectFilter filter) {
    final ImagePlus imp = CreateData.getImage();
    if (imp == null) {
        return null;
    }
    // Run the filter manually to get the results that pass.
    if (allAssignments == null) {
        allAssignments = getAssignments(filter);
    }
    final Overlay o = new Overlay();
    // Do TP
    final TIntHashSet actual = new TIntHashSet();
    final TIntHashSet predicted = new TIntHashSet();
    for (final FractionalAssignment[] assignments : allAssignments) {
        if (assignments == null || assignments.length == 0) {
            continue;
        }
        float[] tx = null;
        float[] ty = null;
        int count = 0;
        if (settings.showTP) {
            tx = new float[assignments.length];
            ty = new float[assignments.length];
        }
        int frame = 0;
        for (int i = 0; i < assignments.length; i++) {
            final CustomFractionalAssignment c = (CustomFractionalAssignment) assignments[i];
            final UniqueIdPeakResult peak = (UniqueIdPeakResult) c.peak;
            final BasePreprocessedPeakResult spot = (BasePreprocessedPeakResult) c.peakResult;
            actual.add(peak.uniqueId);
            predicted.add(spot.getUniqueId());
            frame = spot.getFrame();
            if (settings.showTP) {
                tx[count] = spot.getX();
                ty[count++] = spot.getY();
            }
        }
        if (settings.showTP) {
            SpotFinderPreview.addRoi(frame, o, tx, ty, count, Color.green);
        }
    }
    float[] x = new float[10];
    float[] y = new float[x.length];
    float[] x2 = new float[10];
    float[] y2 = new float[x2.length];
    // Do FP (all remaining results that are not a TP)
    PreprocessedPeakResult[] filterResults = null;
    if (settings.showFP) {
        final MultiPathFilter multiPathFilter = createMpf(filter, defaultMinimalFilter);
        filterResults = filterResults(multiPathFilter);
        int frame = 0;
        int c1 = 0;
        int c2 = 0;
        for (int i = 0; i < filterResults.length; i++) {
            if (frame != filterResults[i].getFrame()) {
                if (c1 != 0) {
                    SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.red);
                }
                if (c2 != 0) {
                    SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
                }
                c1 = c2 = 0;
            }
            frame = filterResults[i].getFrame();
            if (predicted.contains(filterResults[i].getUniqueId())) {
                continue;
            }
            if (filterResults[i].ignore()) {
                if (x2.length == c2) {
                    x2 = Arrays.copyOf(x2, c2 * 2);
                    y2 = Arrays.copyOf(y2, c2 * 2);
                }
                x2[c2] = filterResults[i].getX();
                y2[c2++] = filterResults[i].getY();
            } else {
                if (x.length == c1) {
                    x = Arrays.copyOf(x, c1 * 2);
                    y = Arrays.copyOf(y, c1 * 2);
                }
                x[c1] = filterResults[i].getX();
                y[c1++] = filterResults[i].getY();
            }
        }
        if (c1 != 0) {
            SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.red);
        }
        if (c2 != 0) {
            SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
        }
    }
    // Do FN (all remaining peaks that have not been matched)
    if (settings.showFN) {
        final boolean checkBorder = (filterResult.analysisBorder != null && filterResult.analysisBorder.x != 0);
        final float border;
        final float xlimit;
        final float ylimit;
        if (checkBorder) {
            final Rectangle lastAnalysisBorder = filterResult.analysisBorder;
            border = lastAnalysisBorder.x;
            xlimit = lastAnalysisBorder.x + lastAnalysisBorder.width;
            ylimit = lastAnalysisBorder.y + lastAnalysisBorder.height;
        } else {
            border = xlimit = ylimit = 0;
        }
        // Add the results to the lists
        actualCoordinates.forEachEntry(new CustomTIntObjectProcedure(x, y, x2, y2) {

            @Override
            public boolean execute(int frame, UniqueIdPeakResult[] results) {
                int c1 = 0;
                int c2 = 0;
                if (x.length <= results.length) {
                    x = new float[results.length];
                    y = new float[results.length];
                }
                if (x2.length <= results.length) {
                    x2 = new float[results.length];
                    y2 = new float[results.length];
                }
                for (int i = 0; i < results.length; i++) {
                    // Ignore those that were matched by TP
                    if (actual.contains(results[i].uniqueId)) {
                        continue;
                    }
                    if (checkBorder && outsideBorder(results[i], border, xlimit, ylimit)) {
                        x2[c2] = results[i].getXPosition();
                        y2[c2++] = results[i].getYPosition();
                    } else {
                        x[c1] = results[i].getXPosition();
                        y[c1++] = results[i].getYPosition();
                    }
                }
                if (c1 != 0) {
                    SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.yellow);
                }
                if (c2 != 0) {
                    SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.orange);
                }
                return true;
            }
        });
    }
    imp.setOverlay(o);
    return filterResults;
}
Also used : BasePreprocessedPeakResult(uk.ac.sussex.gdsc.smlm.results.filter.BasePreprocessedPeakResult) Rectangle(java.awt.Rectangle) ImagePlus(ij.ImagePlus) TIntHashSet(gnu.trove.set.hash.TIntHashSet) PeakFractionalAssignment(uk.ac.sussex.gdsc.smlm.results.filter.PeakFractionalAssignment) FractionalAssignment(uk.ac.sussex.gdsc.core.match.FractionalAssignment) BasePreprocessedPeakResult(uk.ac.sussex.gdsc.smlm.results.filter.BasePreprocessedPeakResult) PreprocessedPeakResult(uk.ac.sussex.gdsc.smlm.results.filter.PreprocessedPeakResult) MultiPathFilter(uk.ac.sussex.gdsc.smlm.results.filter.MultiPathFilter) Overlay(ij.gui.Overlay) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 15 with Nullable

use of uk.ac.sussex.gdsc.core.annotation.Nullable in project GDSC-SMLM by aherbert.

the class DriftCalculator method calculateUsingImageStack.

/**
 * Calculates drift using images from a reference stack aligned to the overall z-projection.
 *
 * @param stack the stack
 * @param limits the limits
 * @return the drift { dx[], dy[] }
 */
@Nullable
private double[][] calculateUsingImageStack(ImageStack stack, int[] limits) {
    // Update the limits using the stack size
    final int upperT = settings.startFrame + settings.frameSpacing * (stack.getSize() - 1);
    limits[1] = Math.max(limits[1], upperT);
    // TODO - Truncate the stack if there are far too many frames for the localisation limits
    tracker.status("Constructing images");
    executor = Executors.newFixedThreadPool(Prefs.getThreads());
    // Built an image and FHT image for each slice
    final ImageProcessor[] images = new ImageProcessor[stack.getSize()];
    final Fht[] fhtImages = new Fht[stack.getSize()];
    final List<Future<?>> futures = new LinkedList<>();
    final Ticker ticker = Ticker.createStarted(tracker, images.length, true);
    final int imagesPerThread = getImagesPerThread(images);
    final AlignImagesFft aligner = new AlignImagesFft();
    final FloatProcessor referenceIp = stack.getProcessor(1).toFloat(0, null);
    // We do not care about the window method because this processor will not
    // actually be used for alignment, it is a reference for the FHT size
    aligner.initialiseReference(referenceIp, WindowMethod.NONE, false);
    for (int i = 0; i < images.length; i += imagesPerThread) {
        futures.add(executor.submit(new ImageFhtInitialiser(stack, images, aligner, fhtImages, i, i + imagesPerThread, ticker)));
    }
    ConcurrencyUtils.waitForCompletionUnchecked(futures);
    tracker.progress(1);
    if (tracker.isEnded()) {
        return null;
    }
    final double[] dx = new double[limits[1] + 1];
    final double[] dy = new double[dx.length];
    final double[] originalDriftTimePoints = new double[dx.length];
    final int[] blockT = new int[stack.getSize()];
    for (int i = 0, t = settings.startFrame; i < stack.getSize(); i++, t += settings.frameSpacing) {
        originalDriftTimePoints[t] = 1;
        blockT[i] = t;
    }
    final double smoothing = updateSmoothingParameter(originalDriftTimePoints);
    lastdx = null;
    // For the first iteration calculate drift to the first image in the stack
    // (since the average projection may have a large drift blurring the image)
    double change = calculateDriftUsingImageStack(referenceIp, images, fhtImages, blockT, dx, dy, originalDriftTimePoints, smoothing, settings.iterations);
    if (Double.isNaN(change) || tracker.isEnded()) {
        return null;
    }
    plotDrift(limits, dx, dy);
    ImageJUtils.log("Drift Calculator : Initial drift " + MathUtils.rounded(change));
    for (int i = 1; i <= settings.maxIterations; i++) {
        change = calculateDriftUsingImageStack(null, images, fhtImages, blockT, dx, dy, originalDriftTimePoints, smoothing, settings.iterations);
        if (Double.isNaN(change)) {
            return null;
        }
        plotDrift(limits, dx, dy);
        if (converged(i, change, getTotalDrift(dx, dy, originalDriftTimePoints))) {
            break;
        }
    }
    if (tracker.isEnded()) {
        return null;
    }
    plotDrift(limits, dx, dy);
    return new double[][] { dx, dy };
}
Also used : FloatProcessor(ij.process.FloatProcessor) Ticker(uk.ac.sussex.gdsc.core.logging.Ticker) Point(java.awt.Point) LinkedList(java.util.LinkedList) ImageProcessor(ij.process.ImageProcessor) Fht(uk.ac.sussex.gdsc.core.ij.process.Fht) Future(java.util.concurrent.Future) AlignImagesFft(uk.ac.sussex.gdsc.core.ij.AlignImagesFft) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Aggregations

Nullable (uk.ac.sussex.gdsc.core.annotation.Nullable)49 Point (java.awt.Point)10 ArrayList (java.util.ArrayList)8 LinkedList (java.util.LinkedList)6 ImagePlus (ij.ImagePlus)5 Rectangle (java.awt.Rectangle)5 FloatProcessor (ij.process.FloatProcessor)4 ImageProcessor (ij.process.ImageProcessor)4 ConvergenceException (org.apache.commons.math3.exception.ConvergenceException)4 TooManyIterationsException (org.apache.commons.math3.exception.TooManyIterationsException)4 FractionalAssignment (uk.ac.sussex.gdsc.core.match.FractionalAssignment)4 DirectFilter (uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter)4 IDirectFilter (uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter)4 Plot (ij.gui.Plot)3 File (java.io.File)3 ConcurrentRuntimeException (org.apache.commons.lang3.concurrent.ConcurrentRuntimeException)3 LeastSquaresBuilder (org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder)3 Optimum (org.apache.commons.math3.fitting.leastsquares.LeastSquaresOptimizer.Optimum)3 LeastSquaresProblem (org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem)3 LevenbergMarquardtOptimizer (org.apache.commons.math3.fitting.leastsquares.LevenbergMarquardtOptimizer)3