Search in sources :

Example 1 with PointPair

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

the class SpotFinderPreview method run.

/*
	 * (non-Javadoc)
	 * 
	 * @see ij.plugin.filter.PlugInFilter#run(ij.process.ImageProcessor)
	 */
public void run(ImageProcessor ip) {
    Rectangle bounds = ip.getRoi();
    MaximaSpotFilter filter = config.createSpotFilter(true);
    // Crop to the ROI
    FloatProcessor fp = ip.crop().toFloat(0, null);
    float[] data = (float[]) fp.getPixels();
    int width = fp.getWidth();
    int height = fp.getHeight();
    Spot[] spots = filter.rank(data, width, height);
    data = filter.getPreprocessedData();
    fp = new FloatProcessor(width, height, data);
    ip = ip.duplicate();
    ip.insert(fp, bounds.x, bounds.y);
    //ip.resetMinAndMax();
    ip.setMinAndMax(fp.getMin(), fp.getMax());
    Overlay o = new Overlay();
    o.add(new ImageRoi(0, 0, ip));
    if (label != null) {
        // Get results for frame
        Coordinate[] actual = ResultsMatchCalculator.getCoordinates(actualCoordinates, imp.getCurrentSlice());
        Coordinate[] predicted = new Coordinate[spots.length];
        for (int i = 0; i < spots.length; i++) {
            predicted[i] = new BasePoint(spots[i].x + bounds.x, spots[i].y + bounds.y);
        }
        // Q. Should this use partial scoring with multi-matches allowed.
        // If so then this needs to be refactored out of the BenchmarkSpotFilter class.
        // TODO - compute AUC and max jaccard and plot			
        // Compute matches
        List<PointPair> matches = new ArrayList<PointPair>(Math.min(actual.length, predicted.length));
        List<Coordinate> FP = new ArrayList<Coordinate>(predicted.length);
        MatchResult result = MatchCalculator.analyseResults2D(actual, predicted, distance * fitConfig.getInitialPeakStdDev0(), null, FP, null, matches);
        // Show scores
        setLabel(String.format("P=%s, R=%s, J=%s", Utils.rounded(result.getPrecision()), Utils.rounded(result.getRecall()), Utils.rounded(result.getJaccard())));
        // Create Rois for TP and FP
        if (showTP) {
            float[] x = new float[matches.size()];
            float[] y = new float[x.length];
            int n = 0;
            for (PointPair pair : matches) {
                BasePoint p = (BasePoint) pair.getPoint2();
                x[n] = p.getX() + 0.5f;
                y[n] = p.getY() + 0.5f;
                n++;
            }
            addRoi(0, o, x, y, n, Color.green);
        }
        if (showFP) {
            float[] x = new float[predicted.length - matches.size()];
            float[] y = new float[x.length];
            int n = 0;
            for (Coordinate c : FP) {
                BasePoint p = (BasePoint) c;
                x[n] = p.getX() + 0.5f;
                y[n] = p.getY() + 0.5f;
                n++;
            }
            addRoi(0, o, x, y, n, Color.red);
        }
    } else {
        float[] x = new float[spots.length];
        float[] y = new float[x.length];
        for (int i = 0; i < spots.length; i++) {
            x[i] = spots[i].x + bounds.x + 0.5f;
            y[i] = spots[i].y + bounds.y + 0.5f;
        }
        PointRoi roi = new PointRoi(x, y);
        // Add options to configure colour and labels
        o.add(roi);
    }
    imp.setOverlay(o);
}
Also used : FloatProcessor(ij.process.FloatProcessor) Spot(gdsc.smlm.filters.Spot) BasePoint(gdsc.core.match.BasePoint) Rectangle(java.awt.Rectangle) ArrayList(java.util.ArrayList) ImageRoi(ij.gui.ImageRoi) MatchResult(gdsc.core.match.MatchResult) BasePoint(gdsc.core.match.BasePoint) Coordinate(gdsc.core.match.Coordinate) MaximaSpotFilter(gdsc.smlm.filters.MaximaSpotFilter) PointPair(gdsc.core.match.PointPair) Overlay(ij.gui.Overlay) PointRoi(ij.gui.PointRoi)

Example 2 with PointPair

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

the class TraceMatchCalculator method sort.

private List<? extends PointPair> sort(List<PointPair> pairs) {
    switch(sortIndex) {
        case // Sort by time
        1:
            ArrayList<TimeComparablePointPair> newPairs = new ArrayList<TimeComparablePointPair>(pairs.size());
            for (PointPair pair : pairs) {
                newPairs.add(new TimeComparablePointPair(pair));
            }
            Collections.sort(newPairs);
            return newPairs;
        default:
            // Already sorted by score
            return pairs;
    }
}
Also used : ArrayList(java.util.ArrayList) PointPair(gdsc.core.match.PointPair)

Example 3 with PointPair

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

the class ResultsMatchCalculator method getPairDistances.

private double[] getPairDistances(List<PointPair> pairs) {
    double[] d = new double[pairs.size()];
    int i = 0;
    for (PointPair pair : pairs) {
        d[i++] = pair.getXYDistance2();
    }
    return d;
}
Also used : PointPair(gdsc.core.match.PointPair) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint)

Example 4 with PointPair

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

the class ResultsMatchCalculator method compareCoordinates.

private void compareCoordinates(MemoryPeakResults results1, MemoryPeakResults results2, double dThreshold, int increments, double delta) {
    boolean requirePairs = showPairs || saveClassifications;
    FilePeakResults fileResults = createFilePeakResults(results2);
    List<PointPair> allMatches = new LinkedList<PointPair>();
    List<PointPair> pairs = (requirePairs) ? new LinkedList<PointPair>() : null;
    List<PeakResult> actualPoints = results1.getResults();
    List<PeakResult> predictedPoints = results2.getResults();
    double maxDistance = dThreshold + increments * delta;
    // Old implementation
    //// Process each time point
    //for (Integer t : getTimepoints(actualPoints, predictedPoints))
    //{
    //	Coordinate[] actual = getCoordinates(actualPoints, t);
    //	Coordinate[] predicted = getCoordinates(predictedPoints, t);
    // Divide the results into time points
    TIntObjectHashMap<ArrayList<Coordinate>> actualCoordinates = getCoordinates(actualPoints);
    TIntObjectHashMap<ArrayList<Coordinate>> predictedCoordinates = getCoordinates(predictedPoints);
    int n1 = 0;
    int n2 = 0;
    // Process each time point
    for (Integer t : getTimepoints(actualCoordinates, predictedCoordinates)) {
        Coordinate[] actual = getCoordinates(actualCoordinates, t);
        Coordinate[] predicted = getCoordinates(predictedCoordinates, t);
        List<Coordinate> TP = null;
        List<Coordinate> FP = null;
        List<Coordinate> FN = null;
        List<PointPair> matches = new LinkedList<PointPair>();
        if (requirePairs) {
            FP = new LinkedList<Coordinate>();
            FN = new LinkedList<Coordinate>();
        }
        MatchCalculator.analyseResults2D(actual, predicted, maxDistance, TP, FP, FN, matches);
        // Aggregate
        n1 += actual.length;
        n2 += predicted.length;
        allMatches.addAll(matches);
        if (showPairs) {
            pairs.addAll(matches);
            for (Coordinate c : FN) pairs.add(new PointPair(c, null));
            for (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 
            for (PointPair pair : matches) {
                PeakResult p = ((PeakResultPoint) pair.getPoint2()).peakResult;
                fileResults.add(p.getFrame(), p.origX, p.origY, 1, p.error, p.noise, p.params, null);
            }
            for (Coordinate c : FP) {
                PeakResult p = ((PeakResultPoint) c).peakResult;
                fileResults.add(p.getFrame(), p.origX, p.origY, 0, p.error, p.noise, p.params, null);
            }
        }
    }
    if (fileResults != null)
        fileResults.end();
    // XXX : DEBUGGING : Output for signal correlation and fitting analysis
    /*
		 * try
		 * {
		 * OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("/tmp/ResultsMatchCalculator.txt"));
		 * FilePeakResults r1 = new FilePeakResults("/tmp/" + results1.getName() + ".txt", false);
		 * FilePeakResults r2 = new FilePeakResults("/tmp/" + results2.getName() + ".txt", false);
		 * r1.begin();
		 * r2.begin();
		 * //OutputStreamWriter o2 = new OutputStreamWriter(new FileOutputStream("/tmp/"+results1.getName()+".txt"));
		 * //OutputStreamWriter o3 = new OutputStreamWriter(new FileOutputStream("/tmp/"+results2.getName()+".txt"));
		 * for (PointPair pair : allMatches)
		 * {
		 * PeakResult p1 = ((PeakResultPoint) pair.getPoint1()).peakResult;
		 * PeakResult p2 = ((PeakResultPoint) pair.getPoint2()).peakResult;
		 * r1.add(p1);
		 * r2.add(p2);
		 * o.write(Float.toString(p1.getSignal()));
		 * o.write('\t');
		 * o.write(Float.toString(p2.getSignal()));
		 * o.write('\n');
		 * }
		 * o.close();
		 * r1.end();
		 * r2.end();
		 * }
		 * catch (Exception e)
		 * {
		 * e.printStackTrace();
		 * }
		 */
    boolean doIdAnalysis1 = (idAnalysis) ? haveIds(results1) : false;
    boolean doIdAnalysis2 = (idAnalysis) ? haveIds(results2) : false;
    boolean doIdAnalysis = doIdAnalysis1 || doIdAnalysis2;
    // Create output
    if (!java.awt.GraphicsEnvironment.isHeadless()) {
        String header = createResultsHeader(doIdAnalysis);
        Utils.refreshHeadings(resultsWindow, header, true);
        if (showTable && (resultsWindow == null || !resultsWindow.isShowing())) {
            resultsWindow = new TextWindow(TITLE + " Results", header, "", 900, 300);
        }
        if (showPairs) {
            if (pairsWindow == null || !pairsWindow.isShowing()) {
                pairsWindow = new TextWindow(TITLE + " Pairs", createPairsHeader(pairs), "", 900, 300);
                if (resultsWindow != null) {
                    Point p = resultsWindow.getLocation();
                    p.y += resultsWindow.getHeight();
                    pairsWindow.setLocation(p);
                }
                pairPainter = new ImageROIPainter(pairsWindow.getTextPanel(), "", this);
            }
            pairsWindow.getTextPanel().clear();
            String title = "Results 1";
            if (results1.getSource() != null && results1.getSource().getOriginal().getName().length() > 0)
                title = results1.getSource().getOriginal().getName();
            pairPainter.setTitle(title);
            IJ.showStatus("Writing pairs table");
            IJ.showProgress(0);
            int c = 0;
            final int total = pairs.size();
            final int step = Utils.getProgressInterval(total);
            final ArrayList<String> list = new ArrayList<String>(total);
            boolean flush = true;
            for (PointPair pair : pairs) {
                if (++c % step == 0)
                    IJ.showProgress(c, total);
                list.add(addPairResult(pair));
                if (flush && c == 9) {
                    pairsWindow.getTextPanel().append(list);
                    list.clear();
                    flush = false;
                }
            }
            pairsWindow.getTextPanel().append(list);
            IJ.showProgress(1);
        }
    } else {
        if (writeHeader && showTable) {
            writeHeader = false;
            IJ.log(createResultsHeader(idAnalysis));
        }
    }
    if (!showTable)
        return;
    // We have the results for the largest distance.
    // Now reduce the distance threshold and recalculate the results
    double[] distanceThresholds = getDistances(dThreshold, increments, delta);
    double[] pairDistances = getPairDistances(allMatches);
    // Re-use storage for the ID analysis
    TIntHashSet id1 = null, id2 = null, matchId1 = null, matchId2 = null;
    if (doIdAnalysis) {
        if (doIdAnalysis1) {
            id1 = getIds(results1);
            matchId1 = new TIntHashSet(id1.size());
        }
        if (doIdAnalysis2) {
            id2 = getIds(results2);
            matchId2 = new TIntHashSet(id2.size());
        }
    }
    for (double distanceThreshold : distanceThresholds) {
        double rms = 0;
        int tp2 = 0;
        final double d2 = distanceThreshold * distanceThreshold;
        for (double d : pairDistances) {
            if (d <= d2) {
                rms += d;
                tp2++;
            }
        }
        // All non-true positives must be added to the false totals.
        int fp2 = n2 - tp2;
        int fn2 = n1 - tp2;
        MatchResult result = new MatchResult(tp2, fp2, fn2, (tp2 > 0) ? Math.sqrt(rms / tp2) : 0);
        MatchResult idResult1 = null, idResult2 = null;
        if (doIdAnalysis) {
            if (doIdAnalysis1)
                matchId1.clear();
            if (doIdAnalysis2)
                matchId2.clear();
            int i = 0;
            for (PointPair pair : allMatches) {
                if (pairDistances[i++] <= d2) {
                    if (doIdAnalysis1)
                        matchId1.add(((PeakResultPoint) pair.getPoint1()).peakResult.getId());
                    if (doIdAnalysis2)
                        matchId2.add(((PeakResultPoint) pair.getPoint2()).peakResult.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(inputOption1, inputOption2, distanceThreshold, result, idResult1, idResult2);
    }
}
Also used : ArrayList(java.util.ArrayList) MatchResult(gdsc.core.match.MatchResult) PeakResult(gdsc.smlm.results.PeakResult) TIntHashSet(gnu.trove.set.hash.TIntHashSet) PointPair(gdsc.core.match.PointPair) ImageROIPainter(gdsc.smlm.ij.utils.ImageROIPainter) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint) LinkedList(java.util.LinkedList) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint) FilePeakResults(gdsc.smlm.results.FilePeakResults) TextWindow(ij.text.TextWindow) Coordinate(gdsc.core.match.Coordinate)

Example 5 with PointPair

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

the class TraceMatchCalculator method compareCoordinates.

private void compareCoordinates(MemoryPeakResults results1, MemoryPeakResults results2, MemoryPeakResults results3, double dThreshold) {
    Pulse[] p1 = extractPulses(results1);
    Pulse[] p2 = extractPulses(results2);
    Pulse[] p3 = extractPulses(results3);
    List<Pulse> TP = null;
    List<Pulse> FP = null;
    List<Pulse> FN = null;
    List<PointPair> pairs = null;
    List<Pulse> TP2 = null;
    List<Pulse> FP2 = null;
    List<Pulse> FN2 = null;
    List<PointPair> pairs2 = null;
    if (showPairs) {
        pairs = new LinkedList<PointPair>();
        FP = new LinkedList<Pulse>();
        FN = new LinkedList<Pulse>();
        pairs2 = new LinkedList<PointPair>();
        FP2 = new LinkedList<Pulse>();
        FN2 = new LinkedList<Pulse>();
    }
    MatchResult result = MatchCalculator.analyseResults2D(p1, p2, dThreshold, TP, FP, FN, pairs);
    MatchResult result2 = MatchCalculator.analyseResults2D(p1, p3, dThreshold, TP2, FP2, FN2, pairs2);
    // Create output
    if (!java.awt.GraphicsEnvironment.isHeadless()) {
        if (resultsWindow == null || !resultsWindow.isShowing()) {
            resultsWindow = new TextWindow(TITLE + " Results", createResultsHeader(), "", 900, 300);
        }
        if (showPairs) {
            if (p3 == null) {
                // Produce a pairs output
                if (pairsWindow == null || !pairsWindow.isShowing()) {
                    pairsWindow = new TextWindow(TITLE + " Pairs", createPairsHeader(), "", 900, 300);
                    Point p = resultsWindow.getLocation();
                    p.y += resultsWindow.getHeight();
                    pairsWindow.setLocation(p);
                    pairPainter = new ImageROIPainter(pairsWindow.getTextPanel(), results1.getSource().getOriginal().getName(), this);
                }
                pairsWindow.getTextPanel().clear();
                pairPainter.setTitle(results1.getSource().getOriginal().getName());
                // Add the unmatched points
                for (Coordinate c : FN) pairs.add(new PointPair(c, null));
                for (Coordinate c : FP) pairs.add(new PointPair(null, c));
                List<? extends PointPair> sortedPairs = sort(pairs);
                for (PointPair pair : sortedPairs) addPairResult(pair);
            } else {
                // Produce a triple output
                if (triplesWindow == null || !triplesWindow.isShowing()) {
                    triplesWindow = new TextWindow(TITLE + " Triples", createTriplesHeader(), "", 900, 300);
                    Point p = resultsWindow.getLocation();
                    p.y += resultsWindow.getHeight();
                    triplesWindow.setLocation(p);
                    triplePainter = new ImageROIPainter(triplesWindow.getTextPanel(), results1.getSource().getName(), this);
                }
                triplesWindow.getTextPanel().clear();
                triplePainter.setTitle(results1.getSource().getOriginal().getName());
                HashMap<Pulse, Triple> map = new HashMap<Pulse, Triple>();
                ArrayList<Triple> triples = new ArrayList<Triple>(pairs.size());
                for (PointPair pair : pairs) {
                    Pulse p = (Pulse) pair.getPoint1();
                    Triple t = new Triple(p, (Pulse) pair.getPoint2(), null);
                    triples.add(t);
                    map.put(p, t);
                }
                // Complete the reference set of points
                for (Coordinate c : FN) {
                    Pulse p = (Pulse) c;
                    Triple t = new Triple(p, null, null);
                    triples.add(t);
                    map.put(p, t);
                }
                // Add the unmatched points
                for (Coordinate c : FP) triples.add(new Triple(null, (Pulse) c, null));
                for (Coordinate c : FP2) triples.add(new Triple(null, null, (Pulse) c));
                // Add the results from the second match
                for (PointPair pair : pairs2) {
                    Pulse p = (Pulse) pair.getPoint1();
                    Pulse pp = (Pulse) pair.getPoint2();
                    Triple t = map.get(p);
                    if (t != null) {
                        t.p3 = pp;
                    } else {
                        triples.add(new Triple(null, null, pp));
                    }
                }
                List<? extends Triple> sortedTriples = sort(triples);
                for (Triple t : sortedTriples) addTripleResult(t);
            }
        }
    } else {
        if (writeHeader) {
            writeHeader = false;
            IJ.log(createResultsHeader());
        }
    }
    addResult(inputOption1, inputOption2, dThreshold, result);
    if (p3 != null)
        addResult(inputOption1, inputOption3, dThreshold, result2);
}
Also used : HashMap(java.util.HashMap) Pulse(gdsc.core.match.Pulse) ArrayList(java.util.ArrayList) Point(java.awt.Point) MatchResult(gdsc.core.match.MatchResult) TextWindow(ij.text.TextWindow) Coordinate(gdsc.core.match.Coordinate) PointPair(gdsc.core.match.PointPair) ImageROIPainter(gdsc.smlm.ij.utils.ImageROIPainter)

Aggregations

PointPair (gdsc.core.match.PointPair)6 ArrayList (java.util.ArrayList)4 BasePoint (gdsc.core.match.BasePoint)3 Coordinate (gdsc.core.match.Coordinate)3 MatchResult (gdsc.core.match.MatchResult)3 Point (java.awt.Point)3 ImageROIPainter (gdsc.smlm.ij.utils.ImageROIPainter)2 TextWindow (ij.text.TextWindow)2 Pulse (gdsc.core.match.Pulse)1 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)1 Spot (gdsc.smlm.filters.Spot)1 FilePeakResults (gdsc.smlm.results.FilePeakResults)1 PeakResult (gdsc.smlm.results.PeakResult)1 TIntHashSet (gnu.trove.set.hash.TIntHashSet)1 ImageRoi (ij.gui.ImageRoi)1 Overlay (ij.gui.Overlay)1 PointRoi (ij.gui.PointRoi)1 FloatProcessor (ij.process.FloatProcessor)1 Rectangle (java.awt.Rectangle)1 HashMap (java.util.HashMap)1