use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class BenchmarkSmartSpotRanking method summariseResults.
private void summariseResults(TIntObjectHashMap<RankResults> rankResults) {
createTable();
// Summarise the ranking results.
StringBuilder sb = new StringBuilder(BenchmarkSpotFilter.resultPrefix);
// nP and nN is the fractional score of the spot candidates
addCount(sb, nP + nN);
addCount(sb, nP);
addCount(sb, nN);
addCount(sb, fP);
addCount(sb, fN);
final double[] counter1 = new double[2];
final int[] counter2 = new int[2];
filterCandidates.forEachValue(new TObjectProcedure<FilterCandidates>() {
public boolean execute(FilterCandidates result) {
counter1[0] += result.np;
counter1[1] += result.nn;
counter2[0] += result.p;
counter2[1] += result.n;
return true;
}
});
double tp = counter1[0];
double fp = counter1[1];
int cTP = counter2[0];
int cFP = counter2[2];
// // This should be the same
// double tp2 = 0;
// double fp2 = 0;
// int cTP2 = 0, cFP2 = 0;
// for (RankResults rr : rankResults.values())
// {
// for (ScoredSpot spot : rr.spots)
// {
// if (spot.match)
// cTP2++;
// else
// cFP2++;
// tp2 += spot.getScore();
// fp2 += spot.antiScore();
// }
// }
// if (tp != tp2 || fp != fp2 || cTP != cTP2 || cFP != cFP2)
// System.out.println("Error counting");
// The fraction of positive and negative candidates that were included
add(sb, (100.0 * cTP) / nP);
add(sb, (100.0 * cFP) / nN);
// Add counts of the the candidates
add(sb, cTP + cFP);
add(sb, cTP);
add(sb, cFP);
// Add fractional counts of the the candidates
add(sb, tp + fp);
add(sb, tp);
add(sb, fp);
// Materialise rankeResults
final int[] frames = new int[rankResults.size()];
final RankResults[] results = new RankResults[rankResults.size()];
final int[] counter = new int[1];
rankResults.forEachEntry(new TIntObjectProcedure<RankResults>() {
public boolean execute(int a, RankResults b) {
frames[counter[0]] = a;
results[counter[0]] = b;
counter[0]++;
return true;
}
});
// Summarise actual and candidate spots per frame
Statistics actual = new Statistics();
Statistics candidates = new Statistics();
for (RankResults rr : results) {
actual.add(rr.zPosition.length);
candidates.add(rr.spots.length);
}
add(sb, actual.getMean());
add(sb, actual.getStandardDeviation());
add(sb, candidates.getMean());
add(sb, candidates.getStandardDeviation());
String resultPrefix = sb.toString();
// ---
// TODO
// Add good label to spot candidates and have the benchmark spot filter respect this before applying the fail count limit.
// Correlation between intensity and SNR ...
// SNR is very good at low density
// SNR fails at high density. The SNR estimate is probably wrong for high intensity spots.
// Triangle is very good when there are a large number of good spots in a region of the image (e.g. a mask is used).
// Triangle is poor when there are few good spots in an image.
// Perhaps we can estimate the density of the spots and choose the correct thresholding method?
// ---
// Do a full benchmark through different Spot SNR, image sizes, densities and mask structures and see if there are patterns
// for a good threshold method.
// ---
// Allow using the fitted results from benchmark spot fit. Will it make a difference if we fit the candidates (some will fail
// if weak).
// Can this be done by allowing the user to select the input (spot candidates or fitted positions)?
// Perhaps I need to produce a precision estimate for all simulated spots and then only use those that achieve a certain
// precision, i.e. are reasonably in focus. Can this be done? Does the image PSF have a width estimate for the entire stack?
// Perhaps I should filter, fit and then filter all spots using no fail count. These then become the spots to work with
// for creating a smart fail count filter.
// ---
// Pre-compute the results and have optional sort
ArrayList<ScoredResult> list = new ArrayList<ScoredResult>(methodNames.length);
for (int i = 0; i < methodNames.length; i++) {
tp = 0;
fp = 0;
double tn = 0;
int itp = 0;
int ifp = 0;
int itn = 0;
Statistics s = new Statistics();
long time = 0;
for (RankResults rr : results) {
RankResult r = rr.results.get(i);
// Some results will not have a threshold
if (!Float.isInfinite(r.t))
s.add(r.t);
time += r.time;
tp += r.f.getTP();
fp += r.f.getFP();
tn += r.f.getTN();
itp += r.c.getTP();
ifp += r.c.getFP();
itn += r.c.getTN();
}
sb.setLength(0);
sb.append(resultPrefix);
add(sb, methodNames[i]);
if (methodNames[i].startsWith("SNR"))
sb.append("\t");
else
add(sb, compactBins);
add(sb, s.getMean());
add(sb, s.getStandardDeviation());
add(sb, Utils.timeToString(time / 1e6));
// TP are all accepted candidates that can be matched to a spot
// FP are all accepted candidates that cannot be matched to a spot
// TN are all accepted candidates that cannot be matched to a spot
// FN = The number of missed spots
// Raw counts of match or no-match
FractionClassificationResult f1 = new FractionClassificationResult(itp, ifp, itn, simulationParameters.molecules - itp);
double s1 = addScores(sb, f1);
// Fractional scoring
FractionClassificationResult f2 = new FractionClassificationResult(tp, fp, tn, simulationParameters.molecules - tp);
double s2 = addScores(sb, f2);
// Store for sorting
list.add(new ScoredResult(i, (useFractionScores) ? s2 : s1, sb.toString()));
}
if (list.isEmpty())
return;
Collections.sort(list);
if (summaryTable.getTextPanel().getLineCount() > 0)
summaryTable.append("");
for (ScoredResult r : list) summaryTable.append(r.result);
if (showOverlay) {
int bestMethod = list.get(0).i;
Overlay o = new Overlay();
for (int j = 0; j < results.length; j++) {
int frame = frames[j];
//FilterCandidates candidates = filterCandidates.get(frame);
RankResults rr = results[j];
RankResult r = rr.results.get(bestMethod);
int[] x1 = new int[r.good.length];
int[] y1 = new int[r.good.length];
int c1 = 0;
int[] x2 = new int[r.good.length];
int[] y2 = new int[r.good.length];
int c2 = 0;
int[] x3 = new int[r.good.length];
int[] y3 = new int[r.good.length];
int c3 = 0;
int[] x4 = new int[r.good.length];
int[] y4 = new int[r.good.length];
int c4 = 0;
for (int i = 0; i < x1.length; i++) {
if (r.good[i] == TP) {
x1[c1] = rr.spots[i].spot.x;
y1[c1] = rr.spots[i].spot.y;
c1++;
} else if (r.good[i] == FP) {
x2[c2] = rr.spots[i].spot.x;
y2[c2] = rr.spots[i].spot.y;
c2++;
} else if (r.good[i] == TN) {
x3[c3] = rr.spots[i].spot.x;
y3[c3] = rr.spots[i].spot.y;
c3++;
} else if (r.good[i] == FN) {
x4[c4] = rr.spots[i].spot.x;
y4[c4] = rr.spots[i].spot.y;
c4++;
}
}
addToOverlay(o, frame, x1, y1, c1, Color.green);
addToOverlay(o, frame, x2, y2, c2, Color.red);
//addToOverlay(o, frame, x3, y3, c3, new Color(153, 255, 153)); // light green
// light red
addToOverlay(o, frame, x4, y4, c4, new Color(255, 153, 153));
}
imp.setOverlay(o);
}
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class OverlayImage method addImage.
/**
* Adapted from ij.plugins.OverlayCommands#addImage(boolean) with the additional option for setting the zero pixels
* to transparent.
*/
void addImage() {
ImagePlus imp = IJ.getImage();
int[] wList = WindowManager.getIDList();
if (wList == null || wList.length < 2) {
IJ.error("Add Image...", "The command requires at least two open images.");
return;
}
String[] titles = new String[wList.length];
int count = 0;
for (int i = 0; i < wList.length; i++) {
ImagePlus imp2 = WindowManager.getImage(wList[i]);
if (imp2 != null && imp2 != imp && imp.getWidth() >= imp2.getWidth() && imp.getHeight() >= imp2.getHeight())
titles[count++] = imp2.getTitle();
}
if (count < 1) {
IJ.error("Add Image...", "The command requires at least one valid overlay image.");
return;
}
titles = Arrays.copyOf(titles, count);
int x = 0, y = 0;
Roi roi = imp.getRoi();
if (roi != null && roi.isArea()) {
Rectangle r = roi.getBounds();
x = r.x;
y = r.y;
}
GenericDialog gd = new GenericDialog("Add Image...");
gd.addChoice("Image to add:", titles, title);
gd.addNumericField("X location:", x, 0);
gd.addNumericField("Y location:", y, 0);
gd.addNumericField("Opacity (0-100%):", opacity, 0);
gd.addCheckbox("Transparent background", transparent);
gd.addCheckbox("Replace overlay", replace);
gd.showDialog();
if (gd.wasCanceled())
return;
title = gd.getNextChoice();
x = (int) gd.getNextNumber();
y = (int) gd.getNextNumber();
opacity = (int) gd.getNextNumber();
transparent = gd.getNextBoolean();
replace = gd.getNextBoolean();
ImagePlus overlay = WindowManager.getImage(title);
if (overlay == imp) {
IJ.error("Add Image...", "Image to be added cannot be the same as\n\"" + imp.getTitle() + "\".");
return;
}
if (overlay.getWidth() > imp.getWidth() && overlay.getHeight() > imp.getHeight()) {
IJ.error("Add Image...", "Image to be added cannnot be larger than\n\"" + imp.getTitle() + "\".");
return;
}
ImageRoi roi2 = new ImageRoi(x, y, overlay.getProcessor());
roi2.setZeroTransparent(transparent);
roi2.setName(overlay.getShortTitle());
if (opacity != 100)
roi2.setOpacity(opacity / 100.0);
Overlay overlayList = imp.getOverlay();
if (overlayList == null || replace)
overlayList = new Overlay();
overlayList.add(roi2);
imp.setOverlay(overlayList);
Undo.setup(Undo.OVERLAY_ADDITION, imp);
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class DoubletAnalysis method run.
/**
* Run.
*/
private void run() {
doubletResults = null;
final ImageStack stack = imp.getImageStack();
// Get the coordinates per frame
TIntObjectHashMap<ArrayList<Coordinate>> actualCoordinates = ResultsMatchCalculator.getCoordinates(results.getResults(), false);
final long[] sumCount = new long[1];
actualCoordinates.forEachValue(new TObjectProcedure<ArrayList<Coordinate>>() {
public boolean execute(ArrayList<Coordinate> list) {
sumCount[0] += list.size();
return true;
}
});
final double density = 1e6 * sumCount[0] / (simulationParameters.a * simulationParameters.a * results.getBounds().getWidth() * results.getBounds().getHeight() * actualCoordinates.size());
// Create a pool of workers
final int nThreads = Prefs.getThreads();
final BlockingQueue<Integer> jobs = new ArrayBlockingQueue<Integer>(nThreads * 2);
List<Worker> workers = new LinkedList<Worker>();
List<Thread> threads = new LinkedList<Thread>();
Overlay overlay = (showOverlay) ? new Overlay() : null;
for (int i = 0; i < nThreads; i++) {
Worker worker = new Worker(jobs, stack, actualCoordinates, fitConfig, overlay);
Thread t = new Thread(worker);
workers.add(worker);
threads.add(t);
t.start();
}
// Fit the frames
long runTime = System.nanoTime();
totalProgress = actualCoordinates.size();
stepProgress = Utils.getProgressInterval(totalProgress);
progress = 0;
actualCoordinates.forEachKey(new TIntProcedure() {
public boolean execute(int frame) {
put(jobs, frame);
return true;
}
});
// Finish all the worker threads by passing in a null job
for (int i = 0; i < threads.size(); i++) {
put(jobs, -1);
}
// Wait for all to finish
for (int i = 0; i < threads.size(); i++) {
try {
threads.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
threads.clear();
threads = null;
IJ.showProgress(1);
IJ.showStatus("Collecting results ...");
runTime = System.nanoTime() - runTime;
// Collect the results
int cic = 0, daic = 0, dbic = 0;
ArrayList<DoubletResult> results = null;
int maxH = 0, maxH2 = 0, maxH3 = 0;
for (Worker worker : workers) {
if (results == null)
results = worker.results;
else
results.addAll(worker.results);
cic += worker.cic;
daic += worker.daic;
dbic += worker.dbic;
maxH = Maths.max(maxH, worker.spotHistogram.length);
for (int k = 0; k < 3; k++) {
maxH2 = Maths.max(maxH2, worker.neighbourHistogram[k].length);
maxH3 = Maths.max(maxH3, worker.almostNeighbourHistogram[k].length);
}
}
if (cic > 0)
System.out.printf("Difference AIC %d, BIC %d, Total %d\n", daic, dbic, cic);
if (showHistograms) {
double[] spotHistogram = new double[maxH];
double[] resultHistogram = new double[maxH];
double[][] neighbourHistogram = new double[3][maxH2];
double[][] almostNeighbourHistogram = new double[3][maxH3];
for (Worker worker : workers) {
final int[] h1a = worker.spotHistogram;
final int[] h1b = worker.resultHistogram;
for (int j = 0; j < h1a.length; j++) {
spotHistogram[j] += h1a[j];
resultHistogram[j] += h1b[j];
}
final int[][] h2 = worker.neighbourHistogram;
final int[][] h3 = worker.almostNeighbourHistogram;
for (int k = 0; k < 3; k++) {
for (int j = 0; j < h2[k].length; j++) neighbourHistogram[k][j] += h2[k][j];
for (int j = 0; j < h3[k].length; j++) almostNeighbourHistogram[k][j] += h3[k][j];
}
}
showHistogram(0, spotHistogram);
showHistogram(1, resultHistogram);
showHistogram(2, neighbourHistogram[0]);
showHistogram(3, neighbourHistogram[1]);
showHistogram(4, neighbourHistogram[2]);
showHistogram(5, almostNeighbourHistogram[0]);
showHistogram(6, almostNeighbourHistogram[1]);
showHistogram(7, almostNeighbourHistogram[2]);
}
workers.clear();
workers = null;
if (overlay != null)
imp.setOverlay(overlay);
MemoryPeakResults.freeMemory();
Collections.sort(results);
summariseResults(results, density, runTime);
windowOrganiser.tile();
IJ.showStatus("");
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class PeakFit method addSingleFrameOverlay.
private void addSingleFrameOverlay() {
// If a single frame was processed add the peaks as an overlay if they are in memory
ImagePlus imp = this.imp;
if (fitMaxima && singleFrame > 0) {
if (source instanceof IJImageSource) {
String title = source.getName();
imp = WindowManager.getImage(title);
}
}
if (singleFrame > 0 && imp != null) {
MemoryPeakResults results = null;
for (PeakResults r : this.results.toArray()) if (r instanceof MemoryPeakResults) {
results = (MemoryPeakResults) r;
break;
}
if (results == null || results.size() == 0)
return;
ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
gd.addMessage("Add the fitted localisations as an overlay?");
gd.showDialog();
if (!gd.wasOKed())
return;
LUT lut = LUTHelper.createLUT(LutColour.ICE);
Overlay o = new Overlay();
ArrayList<PeakResult> list = (ArrayList<PeakResult>) results.getResults();
for (int i = 0, j = results.size() - 1; i < results.size(); i++, j--) {
PeakResult r = list.get(i);
PointRoi roi = new PointRoi(r.getXPosition(), r.getYPosition());
Color c = LUTHelper.getColour(lut, j, results.size());
roi.setStrokeColor(c);
roi.setFillColor(c);
if (imp.getStackSize() > 1)
roi.setPosition(singleFrame);
o.add(roi);
}
imp.setOverlay(o);
imp.getWindow().toFront();
}
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class ImageROIPainter method addRoi.
public static void addRoi(ImagePlus imp, int slice, PointRoi roi) {
if (imp != null && slice > 0 && slice <= imp.getStackSize()) {
imp.setSlice(slice);
if (imp.getWindow() != null)
imp.getWindow().toFront();
if (roi != null) {
if (imp.getStackSize() > 1)
roi.setPosition(slice);
Overlay o = new Overlay(roi);
o.setStrokeColor(Color.green);
imp.setOverlay(o);
} else {
imp.setOverlay(null);
}
}
}
Aggregations