Search in sources :

Example 11 with DirectFilter

use of uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method componentAnalysis.

private void componentAnalysis(ComplexFilterScore bestFilterScore) {
    if (settings.componentAnalysis == 0) {
        return;
    }
    final Consumer<String> output = createComponentAnalysisWindow();
    final DirectFilter localBestFilter = bestFilterScore.getFilter();
    final String[] names = getNames(localBestFilter);
    // Skip disabled parameters
    int paramCount = localBestFilter.getNumberOfParameters();
    final boolean[] enable = new boolean[paramCount];
    final int[] map = new int[paramCount];
    for (int n = 0, i = 0; n < map.length; n++) {
        if (localBestFilter.getParameterValue(n) == localBestFilter.getDisabledParameterValue(n)) {
            // Mark to ignore
            enable[n] = true;
            paramCount--;
        } else {
            map[i++] = n;
        }
    }
    // Score the best filter just so we have the unique Ids of the results
    scoreComponents(localBestFilter, -1, paramCount, null, null, null, 0);
    final int[] uniqueIds1 = uniqueIds;
    final int uniqueIdCount1 = uniqueIdCount;
    // Limit to 12 params == 4095 combinations (this is the max for two multi filters combined)
    if (settings.componentAnalysis >= 3 && paramCount <= 12) {
        // Enumeration of combinations
        final long count = countComponentCombinations(paramCount);
        // Enumerate all combinations
        final ComplexFilterScore[] localScores = new ComplexFilterScore[(int) count];
        int index = 0;
        for (int k = 1; k <= paramCount; k++) {
            final Iterator<int[]> it = CombinatoricsUtils.combinationsIterator(paramCount, k);
            while (it.hasNext()) {
                final int[] combinations = it.next();
                final boolean[] enable2 = enable.clone();
                for (int i = 0; i < k; i++) {
                    combinations[i] = map[combinations[i]];
                    enable2[combinations[i]] = true;
                }
                final DirectFilter f = (DirectFilter) localBestFilter.create(enable2);
                localScores[index++] = scoreComponents(f, 0, k, combinations, enable2, uniqueIds1, uniqueIdCount1);
            }
        }
        // Report
        Arrays.sort(localScores, FilterScoreCompararor.INSTANCE);
        int lastSize = 0;
        for (int i = 0; i < localScores.length; i++) {
            if (settings.componentAnalysis == 3) {
                if (lastSize == localScores[i].size) {
                    // Only add the best result for each size
                    continue;
                }
                lastSize = localScores[i].size;
            }
            // Find the last component that was added
            if (localScores[i].size == 1) {
                localScores[i].index = localScores[i].combinations[0];
            } else {
                // For each size k, find the best result with k-1 components and set the add index
                // appropriately
                int add = -1;
                int target = -1;
                for (int l = 0; l < enable.length; l++) {
                    if (localScores[i].enable[l]) {
                        target++;
                    }
                }
                final int size1 = localScores[i].size - 1;
                for (int ii = 0; ii < i; ii++) {
                    if (localScores[ii].size < size1) {
                        continue;
                    }
                    if (localScores[ii].size > size1) {
                        // Broken
                        break;
                    }
                    // Count matches. It must be 1 less than the current result
                    int matches = 0;
                    for (int l = 0; l < enable.length; l++) {
                        if (localScores[i].enable[l] && localScores[ii].enable[l]) {
                            matches++;
                        }
                    }
                    if (matches == target) {
                        // Find the additional parameter added
                        for (int l = 0; l < enable.length; l++) {
                            if (localScores[i].enable[l]) {
                                if (!localScores[ii].enable[l]) {
                                    add = l;
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
                localScores[i].index = add;
            }
            addToComponentAnalysisWindow(output, localScores[i], bestFilterScore, names);
        }
        return;
    }
    // Preserve the option to output the best or all results if we fell through from above
    final int myComponentAnalysis = (settings.componentAnalysis >= 3) ? settings.componentAnalysis - 2 : settings.componentAnalysis;
    // Progressively add components until all are the same as the input bestFilter
    int enabled = 0;
    int[] previousCombinations = new int[0];
    for (int ii = 0; ii < paramCount; ii++) {
        // Create a set of filters by enabling each component that is not currently enabled.
        final ComplexFilterScore[] localScores = new ComplexFilterScore[paramCount - enabled];
        final int k = enabled + 1;
        for (int i = 0, j = 0; i < paramCount; i++) {
            final int n = map[i];
            if (enable[n]) {
                continue;
            }
            enable[n] = true;
            final DirectFilter f = (DirectFilter) localBestFilter.create(enable);
            enable[n] = false;
            final int[] combinations = new int[k];
            System.arraycopy(previousCombinations, 0, combinations, 0, previousCombinations.length);
            combinations[k - 1] = n;
            Arrays.sort(combinations);
            localScores[j++] = scoreComponents(f, n, k, combinations, null, uniqueIds1, uniqueIdCount1);
        }
        // Rank them
        Arrays.sort(localScores);
        for (int i = 0; i < localScores.length; i++) {
            addToComponentAnalysisWindow(output, localScores[i], bestFilterScore, names);
            if (myComponentAnalysis == 1) {
                // Only add the best result
                break;
            }
        }
        // Flag the best component added
        enable[localScores[0].index] = true;
        enabled++;
        previousCombinations = localScores[0].combinations;
    }
}
Also used : IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter)

Example 12 with DirectFilter

use of uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method runAnalysis.

private void runAnalysis(List<FilterSet> filterSets, ComplexFilterScore optimum, double rangeReduction) {
    filterAnalysisResult.plots.clear();
    filterAnalysisResult.bestFilter.clear();
    getCoordinateStore();
    filterAnalysisStopWatch = StopWatch.createStarted();
    IJ.showStatus("Analysing filters ...");
    int setNumber = 0;
    final DirectFilter currentOptimum = (optimum != null) ? optimum.result.filter : null;
    for (final FilterSet filterSet : filterSets) {
        setNumber++;
        if (filterAnalysis(filterSet, setNumber, currentOptimum, rangeReduction) < 0) {
            break;
        }
    }
    filterAnalysisStopWatch.stop();
    ImageJUtils.finished();
    final String timeString = filterAnalysisStopWatch.toString();
    IJ.log("Filter analysis time : " + timeString);
}
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)

Example 13 with DirectFilter

use of uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method scoreFilters.

@Nullable
private FilterScoreResult[] scoreFilters(FilterSet filterSet, boolean createTextResult) {
    if (filterSet.size() == 0) {
        return null;
    }
    initialiseScoring(filterSet);
    FilterScoreResult[] scoreResults = new FilterScoreResult[filterSet.size()];
    if (scoreResults.length == 1) {
        // No need to multi-thread this
        scoreResults[0] = scoreFilter((DirectFilter) filterSet.getFilters().get(0), defaultMinimalFilter, createTextResult, coordinateStore);
    } else {
        // Multi-thread score all the result
        final int nThreads = getThreads(scoreResults.length);
        final BlockingQueue<ScoreJob> 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 ScoreWorker worker = new ScoreWorker(jobs, scoreResults, createTextResult, (coordinateStore == null) ? null : coordinateStore.newInstance(), ticker);
            final Thread t = new Thread(worker);
            threads.add(t);
            t.start();
        }
        int index = 0;
        for (final Filter filter : filterSet.getFilters()) {
            if (IJ.escapePressed()) {
                break;
            }
            put(jobs, new ScoreJob((DirectFilter) filter, index++));
        }
        // Finish all the worker threads by passing in a null job
        for (int i = 0; i < threads.size(); i++) {
            put(jobs, new ScoreJob(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 : IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) Ticker(uk.ac.sussex.gdsc.core.logging.Ticker) LinkedList(java.util.LinkedList) ConcurrentRuntimeException(org.apache.commons.lang3.concurrent.ConcurrentRuntimeException) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) 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) Nullable(uk.ac.sussex.gdsc.core.annotation.Nullable)

Example 14 with DirectFilter

use of uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method reportResults.

private ComplexFilterScore reportResults(boolean newResults, List<ComplexFilterScore> filters) {
    if (filters.isEmpty()) {
        IJ.log("Warning: No filters pass the criteria");
        return null;
    }
    getCoordinateStore();
    Collections.sort(filters);
    FractionClassificationResult topFilterClassificationResult = null;
    ArrayList<FractionalAssignment[]> topFilterResults = null;
    String topFilterSummary = null;
    if (settings.showSummaryTable || settings.saveTemplate) {
        final Consumer<String> summaryWindow = createSummaryWindow();
        int count = 0;
        final double range = (settings.summaryDepth / simulationParameters.pixelPitch) * 0.5;
        final int[] np = { 0 };
        fitResultData.depthStats.forEach(depth -> {
            if (Math.abs(depth) < range) {
                np[0]++;
            }
        });
        for (final ComplexFilterScore fs : filters) {
            final ArrayList<FractionalAssignment[]> list = new ArrayList<>(fitResultData.resultsList.length);
            final FractionClassificationResult r = scoreFilter(fs.getFilter(), defaultMinimalFilter, fitResultData.resultsList, list, coordinateStore);
            final StringBuilder sb = createResult(fs.getFilter(), r);
            if (topFilterResults == null) {
                topFilterResults = list;
                topFilterClassificationResult = r;
            }
            // Show the recall at the specified depth. Sum the distance and signal factor of all scored
            // spots.
            int scored = 0;
            double tp = 0;
            double distance = 0;
            double sf = 0;
            double rmsd = 0;
            final SimpleRegression regression = new SimpleRegression(false);
            for (final FractionalAssignment[] assignments : list) {
                if (assignments == null) {
                    continue;
                }
                for (int i = 0; i < assignments.length; i++) {
                    final CustomFractionalAssignment c = (CustomFractionalAssignment) assignments[i];
                    if (Math.abs(c.peak.getZPosition()) <= range) {
                        tp += c.getScore();
                    }
                    distance += c.distToTarget;
                    sf += c.getSignalFactor();
                    rmsd += c.distToTarget * c.distToTarget;
                    regression.addData(c.peakResult.getSignal(), c.peak.getIntensity());
                }
                scored += assignments.length;
            }
            final double slope = regression.getSlope();
            sb.append('\t');
            sb.append(MathUtils.rounded(tp / np[0])).append('\t');
            sb.append(MathUtils.rounded(distance / scored)).append('\t');
            sb.append(MathUtils.rounded(sf / scored)).append('\t');
            // RMSD to be the root mean square deviation in a single dimension so divide by 2.
            // (This assumes 2D Euclidean distances.)
            sb.append(MathUtils.rounded(Math.sqrt(MathUtils.div0(rmsd / 2, scored)))).append('\t');
            sb.append(MathUtils.rounded(slope)).append('\t');
            if (fs.atLimit() != null) {
                sb.append(fs.atLimit());
            }
            String text = sb.toString();
            if (topFilterSummary == null) {
                topFilterSummary = text;
                if (!settings.showSummaryTable) {
                    break;
                }
            }
            if (fs.time != 0) {
                sb.append('\t');
                sb.append(fs.algorithm);
                sb.append('\t');
                sb.append(org.apache.commons.lang3.time.DurationFormatUtils.formatDurationHMS(fs.time));
            } else {
                sb.append("\t\t");
            }
            if (fs.paramTime != 0) {
                sb.append('\t');
                sb.append(fs.getParamAlgorithm());
                sb.append('\t');
                sb.append(org.apache.commons.lang3.time.DurationFormatUtils.formatDurationHMS(fs.paramTime));
            } else {
                sb.append("\t\t");
            }
            text = sb.toString();
            summaryWindow.accept(text);
            count++;
            if (settings.summaryTopN > 0 && count >= settings.summaryTopN) {
                break;
            }
        }
        // Add a spacer to the summary table if we have multiple results
        if (count > 1 && settings.showSummaryTable) {
            summaryWindow.accept("");
        }
    }
    final DirectFilter localBestFilter = filters.get(0).getFilter();
    if (settings.saveBestFilter) {
        saveFilter(localBestFilter);
    }
    if (topFilterClassificationResult == null) {
        topFilterResults = new ArrayList<>(fitResultData.resultsList.length);
        scoreFilter(localBestFilter, defaultMinimalFilter, fitResultData.resultsList, topFilterResults, coordinateStore);
    }
    if (newResults || filterAnalysisResult.scores.isEmpty()) {
        filterAnalysisResult.scores.add(new FilterResult(settings.failCount, residualsThreshold, settings.duplicateDistance, settings.duplicateDistanceAbsolute, filters.get(0)));
    }
    if (settings.saveTemplate) {
        saveTemplate(topFilterSummary);
    }
    showPlots();
    calculateSensitivity();
    topFilterResults = depthAnalysis(topFilterResults, localBestFilter);
    topFilterResults = scoreAnalysis(topFilterResults, localBestFilter);
    componentAnalysis(filters.get(0));
    PreprocessedPeakResult[] filterResults = null;
    if (isShowOverlay()) {
        filterResults = showOverlay(topFilterResults, localBestFilter);
    }
    saveResults(filterResults, localBestFilter);
    wo.tile();
    return filters.get(0);
}
Also used : IDirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter) DirectFilter(uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter) ArrayList(java.util.ArrayList) SimpleRegression(org.apache.commons.math3.stat.regression.SimpleRegression) PeakFractionalAssignment(uk.ac.sussex.gdsc.smlm.results.filter.PeakFractionalAssignment) FractionalAssignment(uk.ac.sussex.gdsc.core.match.FractionalAssignment) FractionClassificationResult(uk.ac.sussex.gdsc.core.match.FractionClassificationResult) BasePreprocessedPeakResult(uk.ac.sussex.gdsc.smlm.results.filter.BasePreprocessedPeakResult) PreprocessedPeakResult(uk.ac.sussex.gdsc.smlm.results.filter.PreprocessedPeakResult) BenchmarkSpotFilterResult(uk.ac.sussex.gdsc.smlm.ij.plugins.benchmark.BenchmarkSpotFilter.BenchmarkSpotFilterResult)

Example 15 with DirectFilter

use of uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter in project GDSC-SMLM by aherbert.

the class BenchmarkFilterAnalysis method shutdown.

@Override
public void shutdown() {
    // Report the score for the best filter
    final List<? extends Chromosome<FilterScore>> individuals = gaPopulation.getIndividuals();
    FilterScore max = null;
    for (final Chromosome<FilterScore> c : individuals) {
        final FilterScore f = c.getFitness();
        if (f != null && f.compareTo(max) < 0) {
            max = f;
        }
    }
    if (max == null) {
        return;
    }
    final DirectFilter filter = (DirectFilter) ((SimpleFilterScore) max).filter;
    // This filter may not have been part of the scored subset so use the entire results set for
    // reporting
    final FractionClassificationResult r = scoreFilter(filter, defaultMinimalFilter, gaResultsList, coordinateStore);
    final StringBuilder text = createResult(filter, r);
    add(text, gaIteration);
    gaWindow.accept(text.toString());
}
Also used : FilterScore(uk.ac.sussex.gdsc.smlm.results.filter.FilterScore) 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)

Aggregations

DirectFilter (uk.ac.sussex.gdsc.smlm.results.filter.DirectFilter)18 IDirectFilter (uk.ac.sussex.gdsc.smlm.results.filter.IDirectFilter)14 Filter (uk.ac.sussex.gdsc.smlm.results.filter.Filter)9 MultiPathFilter (uk.ac.sussex.gdsc.smlm.results.filter.MultiPathFilter)9 MaximaSpotFilter (uk.ac.sussex.gdsc.smlm.filters.MaximaSpotFilter)7 FilterSet (uk.ac.sussex.gdsc.smlm.results.filter.FilterSet)7 FractionClassificationResult (uk.ac.sussex.gdsc.core.match.FractionClassificationResult)6 ArrayList (java.util.ArrayList)5 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)5 Nullable (uk.ac.sussex.gdsc.core.annotation.Nullable)4 Checkbox (java.awt.Checkbox)3 LinkedList (java.util.LinkedList)3 ConcurrentRuntimeException (org.apache.commons.lang3.concurrent.ConcurrentRuntimeException)3 Ticker (uk.ac.sussex.gdsc.core.logging.Ticker)3 GenericDialog (ij.gui.GenericDialog)2 NonBlockingGenericDialog (ij.gui.NonBlockingGenericDialog)2 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)2 SimpleRegression (org.apache.commons.math3.stat.regression.SimpleRegression)2 BasePoint (uk.ac.sussex.gdsc.core.match.BasePoint)2 FractionalAssignment (uk.ac.sussex.gdsc.core.match.FractionalAssignment)2