Search in sources :

Example 1 with Coordinate

use of gdsc.core.match.Coordinate 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 Coordinate

use of gdsc.core.match.Coordinate 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 3 with Coordinate

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

the class ResultsMatchCalculator method getCoordinates.

/**
	 * Build a map between the peak id (time point) and a list of coordinates
	 * 
	 * @param results
	 * @param integerCoordinates
	 *            True if the values should be rounded down to integers
	 * @return
	 */
public static TIntObjectHashMap<ArrayList<Coordinate>> getCoordinates(List<PeakResult> results, boolean integerCoordinates) {
    TIntObjectHashMap<ArrayList<Coordinate>> coords = new TIntObjectHashMap<ArrayList<Coordinate>>();
    if (results.size() > 0) {
        ResultsMatchCalculator instance = new ResultsMatchCalculator();
        // Do not use HashMap directly to build the coords object since there 
        // will be many calls to getEntry(). Instead sort the results and use 
        // a new list for each time point
        Collections.sort(results);
        int minT = results.get(0).getFrame();
        int maxT = results.get(results.size() - 1).getEndFrame();
        // Create lists
        ArrayList<ArrayList<Coordinate>> tmpCoords = new ArrayList<ArrayList<Coordinate>>(maxT - minT + 1);
        for (int t = minT; t <= maxT; t++) {
            tmpCoords.add(new ArrayList<Coordinate>());
        }
        // Add the results to the lists
        for (PeakResult p : results) {
            final float x, y;
            if (integerCoordinates) {
                x = (int) p.getXPosition();
                y = (int) p.getYPosition();
            } else {
                x = p.getXPosition();
                y = p.getYPosition();
            }
            for (int t = p.getFrame() - minT, i = p.getEndFrame() - p.getFrame() + 1; i-- > 0; t++) tmpCoords.get(t).add(instance.new PeakResultPoint(t + minT, x, y, p));
        }
        // Put in the map
        for (int t = minT, i = 0; t <= maxT; t++, i++) {
            coords.put(t, tmpCoords.get(i));
        }
    }
    return coords;
}
Also used : Coordinate(gdsc.core.match.Coordinate) TIntObjectHashMap(gnu.trove.map.hash.TIntObjectHashMap) ArrayList(java.util.ArrayList) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint) PeakResult(gdsc.smlm.results.PeakResult)

Example 4 with Coordinate

use of gdsc.core.match.Coordinate 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)

Example 5 with Coordinate

use of gdsc.core.match.Coordinate 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<ArrayList<Coordinate>> actualCoordinates, TIntObjectHashMap<ArrayList<Coordinate>> predictedCoordinates, double distance) {
    int tp = 0;
    int fp = 0;
    int fn = 0;
    // Process each time point
    for (Integer t : getTimepoints(actualCoordinates, predictedCoordinates)) {
        Coordinate[] actual = getCoordinates(actualCoordinates, t);
        Coordinate[] predicted = getCoordinates(predictedCoordinates, t);
        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(gdsc.core.match.Coordinate) MatchResult(gdsc.core.match.MatchResult) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint)

Aggregations

Coordinate (gdsc.core.match.Coordinate)6 BasePoint (gdsc.core.match.BasePoint)5 ArrayList (java.util.ArrayList)5 MatchResult (gdsc.core.match.MatchResult)4 Point (java.awt.Point)4 PointPair (gdsc.core.match.PointPair)3 ImageROIPainter (gdsc.smlm.ij.utils.ImageROIPainter)2 PeakResult (gdsc.smlm.results.PeakResult)2 Overlay (ij.gui.Overlay)2 TextWindow (ij.text.TextWindow)2 LinkedList (java.util.LinkedList)2 Pulse (gdsc.core.match.Pulse)1 FitWorker (gdsc.smlm.engine.FitWorker)1 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)1 Spot (gdsc.smlm.filters.Spot)1 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)1 FilePeakResults (gdsc.smlm.results.FilePeakResults)1 TIntObjectHashMap (gnu.trove.map.hash.TIntObjectHashMap)1 TIntProcedure (gnu.trove.procedure.TIntProcedure)1 TIntHashSet (gnu.trove.set.hash.TIntHashSet)1