Search in sources :

Example 6 with ClassificationResult

use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.

the class Filter method score.

/**
	 * Filter the results and return the performance score. Allows benchmarking the filter by marking the results as
	 * true or false.
	 * <p>
	 * Any input PeakResult with an original value that is not zero will be treated as a true result, all other results
	 * are false. The filter is run and the results are marked as true positive, false negative and false positive.
	 * 
	 * @param resultsList
	 *            a list of results to analyse
	 * @param tn
	 *            The initial true negatives (used when the results have been pre-filtered)
	 * @param fn
	 *            The initial false negatives (used when the results have been pre-filtered)
	 * @return
	 */
public ClassificationResult score(List<MemoryPeakResults> resultsList, int tn, int fn) {
    int tp = 0, fp = 0;
    for (MemoryPeakResults peakResults : resultsList) {
        setup(peakResults);
        for (PeakResult peak : peakResults.getResults()) {
            final boolean isTrue = peak.origValue != 0;
            boolean isPositive = accept(peak);
            if (isTrue) {
                if (isPositive)
                    // true positive
                    tp++;
                else
                    // false negative
                    fn++;
            } else {
                if (isPositive)
                    // false positive
                    fp++;
                else
                    // true negative
                    tn++;
            }
        }
        end();
    }
    return new ClassificationResult(tp, fp, tn, fn);
}
Also used : MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ClassificationResult(gdsc.core.match.ClassificationResult) FractionClassificationResult(gdsc.core.match.FractionClassificationResult) PeakResult(gdsc.smlm.results.PeakResult)

Example 7 with ClassificationResult

use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.

the class FilterAnalysis method calculateSensitivity.

private void calculateSensitivity(List<MemoryPeakResults> resultsList) {
    if (!calculateSensitivity)
        return;
    if (!bestFilter.isEmpty()) {
        IJ.showStatus("Calculating sensitivity ...");
        createSensitivityWindow();
        int currentIndex = 0;
        for (String type : bestFilterOrder) {
            IJ.showProgress(currentIndex++, bestFilter.size());
            Filter filter = bestFilter.get(type).filter;
            ClassificationResult s = filter.score(resultsList);
            String message = type + "\t\t\t" + Utils.rounded(s.getJaccard(), 4) + "\t\t" + Utils.rounded(s.getPrecision(), 4) + "\t\t" + Utils.rounded(s.getRecall(), 4);
            if (isHeadless) {
                IJ.log(message);
            } else {
                sensitivityWindow.append(message);
            }
            // List all the parameters that can be adjusted.
            final int parameters = filter.getNumberOfParameters();
            for (int index = 0; index < parameters; index++) {
                // For each parameter compute as upward + downward delta and get the average gradient
                Filter higher = filter.adjustParameter(index, delta);
                Filter lower = filter.adjustParameter(index, -delta);
                ClassificationResult sHigher = higher.score(resultsList);
                ClassificationResult sLower = lower.score(resultsList);
                StringBuilder sb = new StringBuilder();
                sb.append("\t").append(filter.getParameterName(index)).append("\t");
                sb.append(Utils.rounded(filter.getParameterValue(index), 4)).append("\t");
                double dx1 = higher.getParameterValue(index) - filter.getParameterValue(index);
                double dx2 = filter.getParameterValue(index) - lower.getParameterValue(index);
                addSensitivityScore(sb, s.getJaccard(), sHigher.getJaccard(), sLower.getJaccard(), dx1, dx2);
                addSensitivityScore(sb, s.getPrecision(), sHigher.getPrecision(), sLower.getPrecision(), dx1, dx2);
                addSensitivityScore(sb, s.getRecall(), sHigher.getRecall(), sLower.getRecall(), dx1, dx2);
                if (isHeadless) {
                    IJ.log(sb.toString());
                } else {
                    sensitivityWindow.append(sb.toString());
                }
            }
        }
        String message = "-=-=-=-";
        if (isHeadless) {
            IJ.log(message);
        } else {
            sensitivityWindow.append(message);
        }
        IJ.showProgress(1);
        IJ.showStatus("");
    }
}
Also used : Filter(gdsc.smlm.results.filter.Filter) OrFilter(gdsc.smlm.results.filter.OrFilter) FilenameFilter(java.io.FilenameFilter) AndFilter(gdsc.smlm.results.filter.AndFilter) WidthFilter(gdsc.smlm.results.filter.WidthFilter) SNRFilter(gdsc.smlm.results.filter.SNRFilter) PrecisionHysteresisFilter(gdsc.smlm.results.filter.PrecisionHysteresisFilter) TraceFilter(gdsc.smlm.results.filter.TraceFilter) PrecisionFilter(gdsc.smlm.results.filter.PrecisionFilter) SNRHysteresisFilter(gdsc.smlm.results.filter.SNRHysteresisFilter) ClassificationResult(gdsc.core.match.ClassificationResult)

Example 8 with ClassificationResult

use of gdsc.core.match.ClassificationResult in project GDSC-SMLM by aherbert.

the class FilterAnalysis method run.

private int run(FilterSet filterSet, List<MemoryPeakResults> resultsList, int count, final int total) {
    double[] xValues = (isHeadless) ? null : new double[filterSet.size()];
    double[] yValues = (isHeadless) ? null : new double[filterSet.size()];
    int i = 0;
    filterSet.sort();
    // Track if all the filters are the same type. If so then we can calculate the sensitivity of each parameter.
    String type = null;
    boolean allSameType = true;
    Filter maxFilter = null;
    double maxScore = -1;
    for (Filter filter : filterSet.getFilters()) {
        if (count++ % 16 == 0)
            IJ.showProgress(count, total);
        ClassificationResult s = run(filter, resultsList);
        if (type == null)
            type = filter.getType();
        else if (!type.equals(filter.getType()))
            allSameType = false;
        final double jaccard = s.getJaccard();
        if (filter == null || maxScore < jaccard) {
            maxScore = jaccard;
            maxFilter = filter;
        }
        if (!isHeadless) {
            xValues[i] = filter.getNumericalValue();
            yValues[i++] = jaccard;
        }
    }
    if (allSameType && calculateSensitivity) {
        FilterScore filterScore = bestFilter.get(type);
        if (filterScore != null) {
            if (filterScore.score < maxScore)
                filterScore.update(maxFilter, maxScore);
        } else {
            bestFilter.put(type, new FilterScore(maxFilter, maxScore));
            bestFilterOrder.add(type);
        }
    }
    // Add spacer at end of each result set
    if (isHeadless) {
        if (showResultsTable)
            IJ.log("");
    } else {
        if (showResultsTable)
            resultsWindow.append("");
        if (plotTopN > 0) {
            // Check the xValues are unique. Since the filters have been sorted by their
            // numeric value we only need to compare adjacent entries.
            boolean unique = true;
            for (int ii = 0; ii < xValues.length - 1; ii++) {
                if (xValues[ii] == xValues[ii + 1]) {
                    unique = false;
                    break;
                }
            }
            String xAxisName = filterSet.getValueName();
            // Check the values all refer to the same property
            for (Filter filter : filterSet.getFilters()) {
                if (!xAxisName.equals(filter.getNumericalValueName())) {
                    unique = false;
                    break;
                }
            }
            if (!unique) {
                // If not unique then renumber them and use an arbitrary label
                xAxisName = "Filter";
                for (int ii = 0; ii < xValues.length; ii++) xValues[ii] = ii + 1;
            }
            String title = filterSet.getName();
            // Check if a previous filter set had the same name, update if necessary
            NamedPlot p = getNamedPlot(title);
            if (p == null)
                plots.add(new NamedPlot(title, xAxisName, xValues, yValues));
            else
                p.updateValues(xAxisName, xValues, yValues);
            if (plots.size() > plotTopN) {
                Collections.sort(plots);
                p = plots.remove(plots.size() - 1);
            }
        }
    }
    return count;
}
Also used : Filter(gdsc.smlm.results.filter.Filter) OrFilter(gdsc.smlm.results.filter.OrFilter) FilenameFilter(java.io.FilenameFilter) AndFilter(gdsc.smlm.results.filter.AndFilter) WidthFilter(gdsc.smlm.results.filter.WidthFilter) SNRFilter(gdsc.smlm.results.filter.SNRFilter) PrecisionHysteresisFilter(gdsc.smlm.results.filter.PrecisionHysteresisFilter) TraceFilter(gdsc.smlm.results.filter.TraceFilter) PrecisionFilter(gdsc.smlm.results.filter.PrecisionFilter) SNRHysteresisFilter(gdsc.smlm.results.filter.SNRHysteresisFilter) ClassificationResult(gdsc.core.match.ClassificationResult)

Aggregations

ClassificationResult (gdsc.core.match.ClassificationResult)8 FractionClassificationResult (gdsc.core.match.FractionClassificationResult)5 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)3 PeakResult (gdsc.smlm.results.PeakResult)3 AndFilter (gdsc.smlm.results.filter.AndFilter)2 Filter (gdsc.smlm.results.filter.Filter)2 OrFilter (gdsc.smlm.results.filter.OrFilter)2 PrecisionFilter (gdsc.smlm.results.filter.PrecisionFilter)2 PrecisionHysteresisFilter (gdsc.smlm.results.filter.PrecisionHysteresisFilter)2 SNRFilter (gdsc.smlm.results.filter.SNRFilter)2 SNRHysteresisFilter (gdsc.smlm.results.filter.SNRHysteresisFilter)2 TraceFilter (gdsc.smlm.results.filter.TraceFilter)2 WidthFilter (gdsc.smlm.results.filter.WidthFilter)2 FilenameFilter (java.io.FilenameFilter)2