Search in sources :

Example 1 with MatchResult

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

the class TraceMatchCalculator method compareCoordinates.

@SuppressWarnings("null")
private void compareCoordinates(MemoryPeakResults results1, MemoryPeakResults results2, MemoryPeakResults results3, double distanceThreshold) {
    final Pulse[] p1 = extractPulses(results1);
    final Pulse[] p2 = extractPulses(results2);
    final Pulse[] p3 = extractPulses(results3);
    final List<Pulse> tp = null;
    List<Pulse> fp = null;
    List<Pulse> fn = null;
    List<PointPair> pairs = null;
    final List<Pulse> tp2 = null;
    List<Pulse> fp2 = null;
    List<Pulse> fn2 = null;
    List<PointPair> pairs2 = null;
    if (settings.showPairs) {
        pairs = new LinkedList<>();
        fp = new LinkedList<>();
        fn = new LinkedList<>();
        pairs2 = new LinkedList<>();
        fp2 = new LinkedList<>();
        fn2 = new LinkedList<>();
    }
    final MatchResult result = MatchCalculator.analyseResults2D(p1, p2, distanceThreshold, tp, fp, fn, pairs);
    final MatchResult result2 = MatchCalculator.analyseResults2D(p1, p3, distanceThreshold, tp2, fp2, fn2, pairs2);
    // Create output
    Consumer<String> resultsOutput;
    if (!java.awt.GraphicsEnvironment.isHeadless()) {
        final TextWindow resultsWindow = ImageJUtils.refresh(resultsWindowRef, () -> new TextWindow(TITLE + " Results", createResultsHeader(), "", 900, 300));
        resultsOutput = resultsWindow::append;
        if (settings.showPairs) {
            if (p3 == null) {
                // Produce a pairs output
                final WindowAndPainter wap = refresh(pairsWindowRef, true, resultsWindow, results1);
                // Add the unmatched points
                WindowManager.getIDList();
                for (final Coordinate c : fn) {
                    pairs.add(new PointPair(c, null));
                }
                for (final Coordinate c : fp) {
                    pairs.add(new PointPair(null, c));
                }
                final List<? extends PointPair> sortedPairs = sort(pairs);
                for (final PointPair pair : sortedPairs) {
                    addPairResult(wap.textWindow, pair);
                }
            } else {
                // Produce a triple output
                final WindowAndPainter wap = refresh(triplesWindowRef, false, resultsWindow, results1);
                final HashMap<Pulse, Triple> map = new HashMap<>();
                final ArrayList<Triple> triples = new ArrayList<>(pairs.size());
                for (final PointPair pair : pairs) {
                    final Pulse p = (Pulse) pair.getPoint1();
                    final Triple t = new Triple(p, (Pulse) pair.getPoint2(), null);
                    triples.add(t);
                    map.put(p, t);
                }
                // Complete the reference set of points
                for (final Coordinate c : fn) {
                    final Pulse p = (Pulse) c;
                    final Triple t = new Triple(p, null, null);
                    triples.add(t);
                    map.put(p, t);
                }
                // Add the unmatched points
                for (final Coordinate c : fp) {
                    triples.add(new Triple(null, (Pulse) c, null));
                }
                for (final Coordinate c : fp2) {
                    triples.add(new Triple(null, null, (Pulse) c));
                }
                // Add the results from the second match
                for (final PointPair pair : pairs2) {
                    final Pulse p = (Pulse) pair.getPoint1();
                    final Pulse pp = (Pulse) pair.getPoint2();
                    final Triple triple = map.get(p);
                    if (triple != null) {
                        triple.p3 = pp;
                    } else {
                        triples.add(new Triple(null, null, pp));
                    }
                }
                final List<? extends Triple> sortedTriples = sort(triples);
                for (final Triple t : sortedTriples) {
                    addTripleResult(wap.textWindow, t);
                }
            }
        }
    } else {
        if (writeHeader.compareAndSet(true, false)) {
            IJ.log(createResultsHeader());
        }
        resultsOutput = IJ::log;
    }
    final StringBuilder sb = new StringBuilder();
    addResult(resultsOutput, sb, settings.inputOption1, settings.inputOption2, distanceThreshold, result);
    if (p3 != null) {
        addResult(resultsOutput, sb, settings.inputOption1, settings.inputOption3, distanceThreshold, result2);
    }
}
Also used : IJ(ij.IJ) HashMap(java.util.HashMap) Pulse(uk.ac.sussex.gdsc.core.match.Pulse) ArrayList(java.util.ArrayList) MatchResult(uk.ac.sussex.gdsc.core.match.MatchResult) TextWindow(ij.text.TextWindow) Coordinate(uk.ac.sussex.gdsc.core.match.Coordinate) PointPair(uk.ac.sussex.gdsc.core.match.PointPair)

Example 2 with MatchResult

use of uk.ac.sussex.gdsc.core.match.MatchResult 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 3 with MatchResult

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

the class ResultsMatchCalculator method compareCoordinates.

/**
 * Compare the coordinates on a frame-by-frame basis.
 *
 * @param actualCoordinates the actual coordinates
 * @param predictedCoordinates the predicted coordinates
 * @param distance the distance
 * @return the match result
 */
public static MatchResult compareCoordinates(TIntObjectHashMap<List<Coordinate>> actualCoordinates, TIntObjectHashMap<List<Coordinate>> predictedCoordinates, double distance) {
    int tp = 0;
    int fp = 0;
    int fn = 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 MatchResult r = MatchCalculator.analyseResults2D(actual, predicted, distance);
        // Aggregate
        tp += r.getTruePositives();
        fp += r.getFalsePositives();
        fn += r.getFalseNegatives();
    }
    return new MatchResult(tp, fp, fn, 0);
}
Also used : Coordinate(uk.ac.sussex.gdsc.core.match.Coordinate) MatchResult(uk.ac.sussex.gdsc.core.match.MatchResult) PeakResultPoint(uk.ac.sussex.gdsc.smlm.results.PeakResultPoint) Point(java.awt.Point)

Aggregations

MatchResult (uk.ac.sussex.gdsc.core.match.MatchResult)3 IJ (ij.IJ)2 Point (java.awt.Point)2 Coordinate (uk.ac.sussex.gdsc.core.match.Coordinate)2 PointPair (uk.ac.sussex.gdsc.core.match.PointPair)2 PeakResultPoint (uk.ac.sussex.gdsc.smlm.results.PeakResultPoint)2 TIntHashSet (gnu.trove.set.hash.TIntHashSet)1 TextWindow (ij.text.TextWindow)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Pulse (uk.ac.sussex.gdsc.core.match.Pulse)1