Search in sources :

Example 6 with PointPair

use of uk.ac.sussex.gdsc.core.match.PointPair in project GDSC-SMLM by aherbert.

the class ResultsMatchCalculator method showResults.

@SuppressWarnings("null")
private void showResults(MemoryPeakResults results1, MemoryPeakResults results2, final List<PointPair> allMatches, int n1, int n2, final boolean doIdAnalysis1, final boolean doIdAnalysis2, TextWindow resultsWindow) {
    if (!settings.showTable) {
        return;
    }
    // Output the results
    Consumer<String> output;
    if (resultsWindow != null) {
        output = resultsWindow::append;
    } else {
        // Headless mode
        output = IJ::log;
        if (writeHeader.get()) {
            writeHeader.set(false);
            IJ.log(createResultsHeader(settings.idAnalysis));
        }
    }
    // We have the results for the largest distance.
    // Now reduce the distance threshold and recalculate the results
    final double[] distanceThresholds = getDistances(settings.distanceThreshold, settings.increments, settings.delta);
    final double[] pairDistances = getPairDistances(allMatches);
    // Re-use storage for the ID analysis
    TIntHashSet id1 = null;
    TIntHashSet id2 = null;
    TIntHashSet matchId1 = null;
    TIntHashSet matchId2 = null;
    final boolean doIdAnalysis = doIdAnalysis1 || doIdAnalysis2;
    if (doIdAnalysis) {
        if (doIdAnalysis1) {
            id1 = getIds(results1);
            matchId1 = new TIntHashSet(id1.size());
        }
        if (doIdAnalysis2) {
            id2 = getIds(results2);
            matchId2 = new TIntHashSet(id2.size());
        }
    }
    final StringBuilder sb = new StringBuilder();
    for (final double distanceThreshold : distanceThresholds) {
        double rms = 0;
        int tp2 = 0;
        final double d2 = distanceThreshold * distanceThreshold;
        for (final double d : pairDistances) {
            if (d <= d2) {
                rms += d;
                tp2++;
            }
        }
        // All non-true positives must be added to the false totals.
        final int fp2 = n2 - tp2;
        final int fn2 = n1 - tp2;
        // RMSD to be the root mean square deviation in a single dimension so divide by 2.
        // (This assumes 2D Euclidean distances.)
        final MatchResult result = new MatchResult(tp2, fp2, fn2, Math.sqrt(MathUtils.div0(rms / 2, tp2)));
        MatchResult idResult1 = null;
        MatchResult idResult2 = null;
        if (doIdAnalysis) {
            if (doIdAnalysis1) {
                matchId1.clear();
            }
            if (doIdAnalysis2) {
                matchId2.clear();
            }
            int index = 0;
            for (final PointPair pair : allMatches) {
                if (pairDistances[index++] <= d2) {
                    if (doIdAnalysis1) {
                        matchId1.add(((PeakResultPoint) pair.getPoint1()).getPeakResult().getId());
                    }
                    if (doIdAnalysis2) {
                        matchId2.add(((PeakResultPoint) pair.getPoint2()).getPeakResult().getId());
                    }
                }
            }
            // => Only the recall will be valid: tp / (tp + fn)
            if (doIdAnalysis1) {
                idResult1 = new MatchResult(matchId1.size(), 0, id1.size() - matchId1.size(), 0);
            }
            if (doIdAnalysis2) {
                idResult2 = new MatchResult(matchId2.size(), 0, id2.size() - matchId2.size(), 0);
            }
        }
        addResult(sb, settings.inputOption1, settings.inputOption2, distanceThreshold, result, idResult1, idResult2);
        output.accept(sb.toString());
    }
}
Also used : IJ(ij.IJ) MatchResult(uk.ac.sussex.gdsc.core.match.MatchResult) TIntHashSet(gnu.trove.set.hash.TIntHashSet) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) Point(java.awt.Point) PointPair(uk.ac.sussex.gdsc.core.match.PointPair) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)

Example 7 with PointPair

use of uk.ac.sussex.gdsc.core.match.PointPair in project GDSC-SMLM by aherbert.

the class TraceMatchCalculator method sort.

private List<? extends PointPair> sort(List<PointPair> pairs) {
    if (settings.sortIndex == 1) {
        // Sort by time
        final ArrayList<TimeComparablePointPair> newPairs = new ArrayList<>(pairs.size());
        for (final PointPair pair : pairs) {
            newPairs.add(new TimeComparablePointPair(pair));
        }
        Collections.sort(newPairs, TimeComparablePointPair::compare);
        return newPairs;
    }
    // Already sorted by score
    return pairs;
}
Also used : ArrayList(java.util.ArrayList) PointPair(uk.ac.sussex.gdsc.core.match.PointPair)

Example 8 with PointPair

use of uk.ac.sussex.gdsc.core.match.PointPair in project GDSC-SMLM by aherbert.

the class ResultsMatchCalculator method runCompareCoordinates.

@SuppressWarnings("null")
private void runCompareCoordinates(MemoryPeakResults results1, MemoryPeakResults results2) {
    final boolean requirePairs = settings.showPairs || settings.isSaveClassifications();
    final boolean saveMatched = settings.isSaveMatched();
    final boolean saveUnmatched = settings.isSaveUnmatched();
    final TextFilePeakResults fileResults = createFilePeakResults(results2);
    final List<PointPair> allMatches = new LinkedList<>();
    final List<PointPair> pairs = (requirePairs) ? new LinkedList<>() : null;
    final double maxDistance = settings.distanceThreshold + settings.increments * settings.delta;
    // Divide the results into time points
    final TIntObjectHashMap<List<Coordinate>> actualCoordinates = getCoordinates(results1, settings.coordinateMethod1);
    final TIntObjectHashMap<List<Coordinate>> predictedCoordinates = getCoordinates(results2, settings.coordinateMethod2);
    int n1 = 0;
    int n2 = 0;
    // Process each time point
    for (final int t : getTimepoints(actualCoordinates, predictedCoordinates)) {
        final Coordinate[] actual = getCoordinates(actualCoordinates, t);
        final Coordinate[] predicted = getCoordinates(predictedCoordinates, t);
        final List<Coordinate> tp = null;
        List<Coordinate> fp = null;
        List<Coordinate> fn = null;
        final List<PointPair> matches = new LinkedList<>();
        if (requirePairs) {
            fp = new LinkedList<>();
            fn = new LinkedList<>();
        }
        MatchCalculator.analyseResults2D(actual, predicted, maxDistance, tp, fp, fn, matches);
        // Aggregate
        n1 += actual.length;
        n2 += predicted.length;
        allMatches.addAll(matches);
        if (settings.showPairs) {
            pairs.addAll(matches);
            for (final Coordinate c : fn) {
                pairs.add(new PointPair(c, null));
            }
            for (final Coordinate c : fp) {
                pairs.add(new PointPair(null, c));
            }
        }
        if (fileResults != null) {
            // Matches are marked in the original value with 1 for true, 0 for false
            if (saveMatched) {
                for (final PointPair pair : matches) {
                    PeakResult result = ((PeakResultPoint) pair.getPoint2()).getPeakResult();
                    result = result.copy();
                    result.setOrigValue(1);
                    fileResults.add(result);
                }
            }
            if (saveUnmatched) {
                for (final Coordinate c : fp) {
                    PeakResult result = ((PeakResultPoint) c).getPeakResult();
                    result = result.copy();
                    result.setOrigValue(0);
                    fileResults.add(result);
                }
            }
        }
    }
    if (fileResults != null) {
        fileResults.end();
    }
    final boolean doIdAnalysis1 = settings.idAnalysis && haveIds(results1);
    final boolean doIdAnalysis2 = settings.idAnalysis && haveIds(results2);
    // Create output.
    // This supports headless mode with just the results table
    // or graphical mode with a results table and pairs window.
    final boolean headless = java.awt.GraphicsEnvironment.isHeadless();
    TextWindow resultsWindow = null;
    if (!headless) {
        resultsWindow = (settings.showTable) ? createResultsWindow(doIdAnalysis1 || doIdAnalysis2) : null;
        showPairs(results1, pairs, resultsWindow);
    }
    showResults(results1, results2, allMatches, n1, n2, doIdAnalysis1, doIdAnalysis2, resultsWindow);
    savePairs(results1, results2, allMatches);
}
Also used : TextFilePeakResults(uk.ac.sussex.gdsc.smlm.results.TextFilePeakResults) LinkedList(java.util.LinkedList) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) Point(java.awt.Point) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) TextWindow(ij.text.TextWindow) BufferedTextWindow(uk.ac.sussex.gdsc.core.ij.BufferedTextWindow) Coordinate(uk.ac.sussex.gdsc.core.match.Coordinate) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) PointPair(uk.ac.sussex.gdsc.core.match.PointPair) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)

Example 9 with PointPair

use of uk.ac.sussex.gdsc.core.match.PointPair in project GDSC-SMLM by aherbert.

the class ClassificationMatchCalculator method runCompareClassifications.

private void runCompareClassifications(MemoryPeakResults results1, MemoryPeakResults results2) {
    final List<PointPair> allMatches = new LinkedList<>();
    // Optionally exclude results which do not have an id and/or category
    Predicate<PeakResult> test = settings.useId == ClassAnalysis.IGNORE_ZERO ? r -> r.getId() != 0 : null;
    if (settings.useCategory == ClassAnalysis.IGNORE_ZERO) {
        final Predicate<PeakResult> test2 = r -> r.getCategory() != 0;
        test = test == null ? test2 : test.and(test2);
    } else if (test == null) {
        test = r -> true;
    }
    // Divide the results into time points
    final TIntObjectHashMap<List<PeakResultPoint>> coordinates1 = getCoordinates(results1, test);
    final TIntObjectHashMap<List<PeakResultPoint>> coordinates2 = getCoordinates(results2, test);
    // Process each time point
    int n1 = 0;
    int n2 = 0;
    for (final int t : getTimepoints(coordinates1, coordinates2)) {
        final Coordinate[] c1 = getCoordinates(coordinates1, t);
        final Coordinate[] c2 = getCoordinates(coordinates2, t);
        n1 += c1.length;
        n2 += c2.length;
        final List<PointPair> matches = new LinkedList<>();
        MatchCalculator.analyseResults3D(c1, c2, settings.matchDistance, null, null, null, matches);
        allMatches.addAll(matches);
    }
    if (allMatches.isEmpty()) {
        IJ.error(TITLE, "No localisation matches between the two results sets");
        return;
    }
    // Get the unique Ids and Categories in the matches.
    final Mapper ids = getMapper(allMatches, PeakResult::getId, settings.useId);
    final Mapper cats = getMapper(allMatches, PeakResult::getCategory, settings.useCategory);
    // Map id/category to an index = stride * cat + id
    final int stride = ids.size();
    // Any integer is allowed as an index
    if ((long) stride * cats.size() > 1L << 32) {
        IJ.error(TITLE, "Too many combinations of id and category to assigne unique labels");
        return;
    }
    // Extract indices
    final int[] set1 = new int[allMatches.size()];
    final int[] set2 = new int[allMatches.size()];
    int i = 0;
    for (final PointPair r : allMatches) {
        set1[i] = toIndex(stride, ids, cats, ((PeakResultPoint) r.getPoint1()).getPeakResult());
        set2[i] = toIndex(stride, ids, cats, ((PeakResultPoint) r.getPoint2()).getPeakResult());
        i++;
    }
    final Resequencer re = new Resequencer();
    re.setCacheMap(true);
    re.renumber(set1);
    re.renumber(set2);
    // Compare
    final RandIndex r = new RandIndex().compute(set1, set2);
    final TextWindow resultsWindow = ImageJUtils.refresh(resultsWindowRef, () -> new TextWindow(TITLE + " Results", "Results1\tResults2\tID\tCategory\tn1\tc1\tn2\tc2\tMatched\tRand Index\tAdjusted RI", "", 900, 300));
    try (BufferedTextWindow bw = new BufferedTextWindow(resultsWindow)) {
        final StringBuilder sb = new StringBuilder(2048);
        sb.append(results1.getName()).append('\t');
        sb.append(results2.getName()).append('\t');
        sb.append(ANALYSIS_OPTION[settings.useId.ordinal()]).append('\t');
        sb.append(ANALYSIS_OPTION[settings.useCategory.ordinal()]).append('\t');
        sb.append(n1).append('\t');
        sb.append(MathUtils.max(set1) + 1).append('\t');
        sb.append(n2).append('\t');
        sb.append(MathUtils.max(set2) + 1).append('\t');
        sb.append(set1.length).append('\t');
        sb.append(MathUtils.rounded(r.getRandIndex())).append('\t');
        sb.append(MathUtils.rounded(r.getAdjustedRandIndex())).append('\t');
        bw.append(sb.toString());
    }
}
Also used : PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) TIntObjectHashMap(gnu.trove.map.hash.TIntObjectHashMap) Arrays(java.util.Arrays) ConfigurationException(uk.ac.sussex.gdsc.smlm.data.config.ConfigurationException) Prefs(ij.Prefs) TextWindow(ij.text.TextWindow) FrameCounter(uk.ac.sussex.gdsc.smlm.results.count.FrameCounter) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) AtomicReference(java.util.concurrent.atomic.AtomicReference) ConversionException(com.thoughtworks.xstream.converters.ConversionException) TIntProcedure(gnu.trove.procedure.TIntProcedure) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) MathUtils(uk.ac.sussex.gdsc.core.utils.MathUtils) LinkedList(java.util.LinkedList) SettingsManager(uk.ac.sussex.gdsc.smlm.ij.settings.SettingsManager) RandIndex(uk.ac.sussex.gdsc.core.match.RandIndex) Predicate(java.util.function.Predicate) BufferedTextWindow(uk.ac.sussex.gdsc.core.ij.BufferedTextWindow) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) InputSource(uk.ac.sussex.gdsc.smlm.ij.plugins.ResultsManager.InputSource) ToIntFunction(java.util.function.ToIntFunction) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) NamedObject(uk.ac.sussex.gdsc.smlm.data.NamedObject) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) Coordinate(uk.ac.sussex.gdsc.core.match.Coordinate) TextUtils(uk.ac.sussex.gdsc.core.utils.TextUtils) TIntHashSet(gnu.trove.set.hash.TIntHashSet) XyzrResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.XyzrResultProcedure) List(java.util.List) PointPair(uk.ac.sussex.gdsc.core.match.PointPair) Resequencer(uk.ac.sussex.gdsc.core.match.Resequencer) ImageJUtils(uk.ac.sussex.gdsc.core.ij.ImageJUtils) IJ(ij.IJ) MatchCalculator(uk.ac.sussex.gdsc.core.match.MatchCalculator) PlugIn(ij.plugin.PlugIn) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) BufferedTextWindow(uk.ac.sussex.gdsc.core.ij.BufferedTextWindow) Resequencer(uk.ac.sussex.gdsc.core.match.Resequencer) RandIndex(uk.ac.sussex.gdsc.core.match.RandIndex) LinkedList(java.util.LinkedList) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) TextWindow(ij.text.TextWindow) BufferedTextWindow(uk.ac.sussex.gdsc.core.ij.BufferedTextWindow) Coordinate(uk.ac.sussex.gdsc.core.match.Coordinate) LinkedList(java.util.LinkedList) List(java.util.List) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) PointPair(uk.ac.sussex.gdsc.core.match.PointPair) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)

Example 10 with PointPair

use of uk.ac.sussex.gdsc.core.match.PointPair in project GDSC-SMLM by aherbert.

the class ClassificationMatchCalculator method getMapper.

/**
 * Gets the mapper that can create a value from a natural sequence starting from 0 for each unique
 * key in the results. If the analysis is set to ignore then a single mapping to zero is created.
 *
 * @param allMatches the all matches
 * @param fun the function to get the key value
 * @param analysis the type of analysis
 * @return the mapper
 */
private static Mapper getMapper(List<PointPair> allMatches, ToIntFunction<PeakResult> fun, ClassAnalysis analysis) {
    if (analysis == ClassAnalysis.IGNORE) {
        return Mapper.single();
    }
    // Find the unique values
    final TIntHashSet set = new TIntHashSet();
    for (final PointPair r : allMatches) {
        set.add(fun.applyAsInt(((PeakResultPoint) r.getPoint1()).getPeakResult()));
        set.add(fun.applyAsInt(((PeakResultPoint) r.getPoint2()).getPeakResult()));
    }
    // Edge case of 1 value
    if (set.size() == 1) {
        return Mapper.single();
    }
    // Map to a natural sequence from zero
    final int[] keys = set.toArray();
    Arrays.sort(keys);
    // Check if a discrete sequence already
    if (keys[keys.length - 1] - keys[0] == set.size() - 1) {
        return Mapper.offset(set.size(), keys[0]);
    }
    // Map each key to a value starting from 0
    final TIntIntHashMap map = new TIntIntHashMap(keys.length);
    for (final int k : keys) {
        map.put(k, map.size());
    }
    return new Mapper() {

        @Override
        public int size() {
            return map.size();
        }

        @Override
        public int map(int key) {
            return map.get(key);
        }
    };
}
Also used : PointPair(uk.ac.sussex.gdsc.core.match.PointPair) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) TIntHashSet(gnu.trove.set.hash.TIntHashSet) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)

Aggregations

PointPair (uk.ac.sussex.gdsc.core.match.PointPair)10 PeakResultPoint (uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)6 TextWindow (ij.text.TextWindow)4 Point (java.awt.Point)4 TIntHashSet (gnu.trove.set.hash.TIntHashSet)3 IJ (ij.IJ)3 ArrayList (java.util.ArrayList)3 BufferedTextWindow (uk.ac.sussex.gdsc.core.ij.BufferedTextWindow)3 Coordinate (uk.ac.sussex.gdsc.core.match.Coordinate)3 PeakResult (uk.ac.sussex.gdsc.smlm.results.PeakResult)3 TIntIntHashMap (gnu.trove.map.hash.TIntIntHashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 MatchResult (uk.ac.sussex.gdsc.core.match.MatchResult)2 MemoryPeakResults (uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults)2 TextFilePeakResults (uk.ac.sussex.gdsc.smlm.results.TextFilePeakResults)2 ConversionException (com.thoughtworks.xstream.converters.ConversionException)1 TIntObjectHashMap (gnu.trove.map.hash.TIntObjectHashMap)1 TIntProcedure (gnu.trove.procedure.TIntProcedure)1 Prefs (ij.Prefs)1