use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class DrawClusters method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "No localisations in memory");
return;
}
if (!showDialog())
return;
// Load the results
MemoryPeakResults results = ResultsManager.loadInputResults(inputOption, false);
if (results == null || results.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
return;
}
// Get the traces
Trace[] traces = TraceManager.convert(results);
if (traces == null || traces.length == 0) {
IJ.error(TITLE, "No traces could be loaded");
return;
}
// Filter traces to a min size
int maxFrame = 0;
int count = 0;
final int myMaxSize = (maxSize < minSize) ? Integer.MAX_VALUE : maxSize;
final boolean myDrawLines = (myMaxSize < 2) ? false : drawLines;
for (int i = 0; i < traces.length; i++) {
if (expandToSingles)
traces[i].expandToSingles();
if (traces[i].size() >= minSize && traces[i].size() <= myMaxSize) {
traces[count++] = traces[i];
traces[i].sort();
if (maxFrame < traces[i].getTail().getFrame())
maxFrame = traces[i].getTail().getFrame();
}
}
if (count == 0) {
IJ.error(TITLE, "No traces achieved the size limits");
return;
}
String msg = String.format(TITLE + ": %d / %s (%s)", count, Utils.pleural(traces.length, "trace"), Utils.pleural(results.size(), "localisation"));
IJ.showStatus(msg);
//Utils.log(msg);
Rectangle bounds = results.getBounds(true);
ImagePlus imp = WindowManager.getImage(title);
boolean isUseStackPosition = useStackPosition;
if (imp == null) {
// Create a default image using 100 pixels as the longest edge
double maxD = (bounds.width > bounds.height) ? bounds.width : bounds.height;
int w, h;
if (maxD == 0) {
// Note that imageSize can be zero (for auto sizing)
w = h = (imageSize == 0) ? 20 : imageSize;
} else {
// Note that imageSize can be zero (for auto sizing)
if (imageSize == 0) {
w = bounds.width;
h = bounds.height;
} else {
w = (int) (imageSize * bounds.width / maxD);
h = (int) (imageSize * bounds.height / maxD);
}
}
ByteProcessor bp = new ByteProcessor(w, h);
if (isUseStackPosition) {
ImageStack stack = new ImageStack(w, h, maxFrame);
for (int i = 1; i <= maxFrame; i++) // Do not clone as the image is empty
stack.setPixels(bp.getPixels(), i);
imp = Utils.display(TITLE, stack);
} else
imp = Utils.display(TITLE, bp);
// Enlarge
ImageWindow iw = imp.getWindow();
for (int i = 9; i-- > 0 && iw.getWidth() < 500 && iw.getHeight() < 500; ) {
iw.getCanvas().zoomIn(imp.getWidth() / 2, imp.getHeight() / 2);
}
} else {
// Check if the image has enough frames for all the traces
if (maxFrame > imp.getNFrames())
isUseStackPosition = false;
}
final float xScale = (float) (imp.getWidth() / bounds.getWidth());
final float yScale = (float) (imp.getHeight() / bounds.getHeight());
// Create ROIs and store data to sort them
Roi[] rois = new Roi[count];
int[][] frames = (isUseStackPosition) ? new int[count][] : null;
int[] indices = Utils.newArray(count, 0, 1);
double[] values = new double[count];
for (int i = 0; i < count; i++) {
Trace trace = traces[i];
int nPoints = trace.size();
float[] xPoints = new float[nPoints];
float[] yPoints = new float[nPoints];
int j = 0;
if (isUseStackPosition)
frames[i] = new int[nPoints];
for (PeakResult result : trace.getPoints()) {
xPoints[j] = (result.getXPosition() - bounds.x) * xScale;
yPoints[j] = (result.getYPosition() - bounds.y) * yScale;
if (isUseStackPosition)
frames[i][j] = result.getFrame();
j++;
}
Roi roi;
if (myDrawLines) {
roi = new PolygonRoi(xPoints, yPoints, nPoints, Roi.POLYLINE);
if (splineFit)
((PolygonRoi) roi).fitSpline();
} else {
roi = new PointRoi(xPoints, yPoints, nPoints);
((PointRoi) roi).setShowLabels(false);
}
rois[i] = roi;
switch(sort) {
case 0:
default:
break;
case // Sort by ID
1:
values[i] = traces[i].getId();
break;
case // Sort by time
2:
values[i] = traces[i].getHead().getFrame();
break;
case // Sort by size descending
3:
values[i] = -traces[i].size();
break;
case // Sort by length descending
4:
values[i] = -roi.getLength();
break;
case // Mean Square Displacement
5:
values[i] = -traces[i].getMSD();
break;
case // Mean / Frame
6:
values[i] = -traces[i].getMeanPerFrame();
break;
}
}
if (sort > 0)
Sort.sort(indices, values);
// Draw the traces as ROIs on an overlay
Overlay o = new Overlay();
LUT lut = LUTHelper.createLUT(DrawClusters.lut);
final double scale = 256.0 / count;
if (isUseStackPosition) {
// Add the tracks on the frames containing the results
final boolean isHyperStack = imp.isDisplayedHyperStack();
for (int i = 0; i < count; i++) {
final int index = indices[i];
final Color c = LUTHelper.getColour(lut, (int) (i * scale));
final PolygonRoi roi = (PolygonRoi) rois[index];
roi.setFillColor(c);
roi.setStrokeColor(c);
final FloatPolygon fp = roi.getNonSplineFloatPolygon();
// For each frame in the track, add the ROI track and a point ROI for the current position
for (int j = 0; j < frames[index].length; j++) {
addToOverlay(o, (Roi) roi.clone(), isHyperStack, frames[index][j]);
//PointRoi pointRoi = new PointRoi(pos.x + fp.xpoints[j], pos.y + fp.ypoints[j]);
PointRoi pointRoi = new PointRoi(fp.xpoints[j], fp.ypoints[j]);
pointRoi.setPointType(3);
pointRoi.setFillColor(c);
pointRoi.setStrokeColor(Color.black);
addToOverlay(o, pointRoi, isHyperStack, frames[index][j]);
}
}
} else {
// Add the tracks as a single overlay
for (int i = 0; i < count; i++) {
final Roi roi = rois[indices[i]];
roi.setStrokeColor(new Color(lut.getRGB((int) (i * scale))));
o.add(roi);
}
}
imp.setOverlay(o);
IJ.showStatus(msg);
}
use of ij.gui.Overlay 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);
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class ResultsImageSampler method getSample.
/**
* Gets the sample image. The image is a stack of the samples with an overlay of the localisation positions. The
* info property is set with details of the localisations and the image is calibrated.
*
* @param nNo
* the number of samples with no localisations
* @param nLow
* the number of samples with low localisations
* @param nHigh
* the number of samples with high localisations
* @return the sample image (could be null if no samples were made)
*/
public ImagePlus getSample(int nNo, int nLow, int nHigh) {
ImageStack out = new ImageStack(size, size);
if (!isValid())
return null;
list.clearf();
// empty
for (int i : Random.sample(nNo, no.length, r)) list.add(ResultsSample.createEmpty(no[i]));
// low
for (int i : Random.sample(nLow, lower, r)) list.add(data[i]);
// high
for (int i : Random.sample(nHigh, upper, r)) list.add(data[i + lower]);
if (list.isEmpty())
return null;
double nmPerPixel = 1;
if (results.getCalibration() != null) {
Calibration calibration = results.getCalibration();
if (calibration.hasNmPerPixel()) {
nmPerPixel = calibration.getNmPerPixel();
}
}
// Sort descending by number in the frame
ResultsSample[] sample = list.toArray(new ResultsSample[list.size()]);
Arrays.sort(sample, rcc);
int[] xyz = new int[3];
Rectangle stackBounds = new Rectangle(stack.getWidth(), stack.getHeight());
Overlay overlay = new Overlay();
float[] ox = new float[10], oy = new float[10];
StringBuilder sb = new StringBuilder();
if (nmPerPixel == 1)
sb.append("Sample X Y Z Signal\n");
else
sb.append("Sample X(nm) Y(nm) Z(nm) Signal\n");
for (ResultsSample s : sample) {
getXYZ(s.index, xyz);
// Construct the region to extract
Rectangle target = new Rectangle(xyz[0], xyz[1], size, size);
target = target.intersection(stackBounds);
if (target.width == 0 || target.height == 0)
continue;
// Extract the frame
int slice = xyz[2];
ImageProcessor ip = stack.getProcessor(slice);
// Cut out the desired pixels (some may be blank if the block overruns the source image)
ImageProcessor ip2 = ip.createProcessor(size, size);
for (int y = 0; y < target.height; y++) for (int x = 0, i = y * size, index = (y + target.y) * ip.getWidth() + target.x; x < target.width; x++, i++, index++) {
ip2.setf(i, ip.getf(index));
}
int size = s.size();
if (size > 0) {
int position = out.getSize() + 1;
// Create an ROI with the localisations
for (int i = 0; i < size; i++) {
PeakResult p = s.list.get(i);
ox[i] = p.getXPosition() - xyz[0];
oy[i] = p.getYPosition() - xyz[1];
sb.append(position).append(' ');
sb.append(Utils.rounded(ox[i] * nmPerPixel)).append(' ');
sb.append(Utils.rounded(oy[i] * nmPerPixel)).append(' ');
// Z can be stored in the error field
sb.append(Utils.rounded(p.error * nmPerPixel)).append(' ');
sb.append(Utils.rounded(p.getSignal())).append('\n');
}
PointRoi roi = new PointRoi(ox, oy, size);
roi.setPosition(position);
overlay.add(roi);
}
out.addSlice(String.format("Frame=%d @ %d,%d px (n=%d)", slice, xyz[0], xyz[1], size), ip2.getPixels());
}
if (out.getSize() == 0)
return null;
ImagePlus imp = new ImagePlus("Sample", out);
imp.setOverlay(overlay);
// Note: Only the info property can be saved to a TIFF file
imp.setProperty("Info", sb.toString());
if (nmPerPixel != 1) {
ij.measure.Calibration cal = new ij.measure.Calibration();
cal.setUnit("nm");
cal.pixelHeight = cal.pixelWidth = nmPerPixel;
imp.setCalibration(cal);
}
return imp;
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class BenchmarkSpotFilter method showOverlay.
private void showOverlay(ImagePlus imp, BenchmarkFilterResult filterResult) {
final Overlay o = new Overlay();
//int tp = 0, fp = 0, fn = 0, nn = 0;
filterResult.filterResults.forEachValue(new TObjectProcedure<FilterResult>() {
public boolean execute(FilterResult result) {
final int size = result.spots.length;
float[] tx = null, ty = null, fx = null, fy = null;
if (showTP) {
tx = new float[size];
ty = new float[size];
}
if (showFP) {
fx = new float[size];
fy = new float[size];
}
int t = 0, f = 0;
for (ScoredSpot s : result.spots) {
if (s.match) {
if (showTP) {
tx[t] = s.spot.x + 0.5f;
ty[t++] = s.spot.y + 0.5f;
}
} else {
if (showFP) {
fx[f] = s.spot.x + 0.5f;
fy[f++] = s.spot.y + 0.5f;
}
}
}
//fp += f;
if (showTP)
SpotFinderPreview.addRoi(result.frame, o, tx, ty, t, Color.green);
if (showFP)
SpotFinderPreview.addRoi(result.frame, o, fx, fy, f, Color.red);
if (showFN) {
// We need the FN ...
final PSFSpot[] actual = result.actual;
final boolean[] actualAssignment = result.actualAssignment;
//nn += actual.length;
final float[] nx = new float[actual.length];
final float[] ny = new float[actual.length];
int n = 0;
for (int i = 0; i < actual.length; i++) {
if (!actualAssignment[i]) {
nx[n] = actual[i].getX();
ny[n++] = actual[i].getY();
}
}
//fn += n;
SpotFinderPreview.addRoi(result.frame, o, nx, ny, n, Color.yellow);
}
return true;
}
});
//System.out.printf("TP=%d, FP=%d, FN=%d, N=%d (%d) %d\n", tp, fp, fn, tp + fn, results.size(), nn);
imp.setOverlay(o);
}
use of ij.gui.Overlay in project GDSC-SMLM by aherbert.
the class BenchmarkFilterAnalysis method showOverlay.
/**
* Show overlay.
*
* @param allAssignments
* The assignments generated from running the filter (or null)
* @param filter
* the filter
* @return The results from running the filter (or null)
*/
private PreprocessedPeakResult[] showOverlay(ArrayList<FractionalAssignment[]> allAssignments, DirectFilter filter) {
ImagePlus imp = CreateData.getImage();
if (imp == null)
return null;
// Run the filter manually to get the results that pass.
if (allAssignments == null)
allAssignments = getAssignments(filter);
final Overlay o = new Overlay();
// Do TP
final TIntHashSet actual = new TIntHashSet();
final TIntHashSet predicted = new TIntHashSet();
//int tp = 0, fp = 0, fn = 0;
for (FractionalAssignment[] assignments : allAssignments) {
if (assignments == null || assignments.length == 0)
continue;
float[] tx = null, ty = null;
int t = 0;
//tp += assignments.length;
if (showTP) {
tx = new float[assignments.length];
ty = new float[assignments.length];
}
int frame = 0;
for (int i = 0; i < assignments.length; i++) {
CustomFractionalAssignment c = (CustomFractionalAssignment) assignments[i];
IdPeakResult peak = (IdPeakResult) c.peak;
BasePreprocessedPeakResult spot = (BasePreprocessedPeakResult) c.peakResult;
actual.add(peak.uniqueId);
predicted.add(spot.getUniqueId());
frame = spot.getFrame();
if (showTP) {
tx[t] = spot.getX();
ty[t++] = spot.getY();
}
}
if (showTP)
SpotFinderPreview.addRoi(frame, o, tx, ty, t, Color.green);
}
float[] x = new float[10];
float[] y = new float[x.length];
float[] x2 = new float[10];
float[] y2 = new float[x2.length];
// Do FP (all remaining results that are not a TP)
PreprocessedPeakResult[] filterResults = null;
if (showFP) {
final MultiPathFilter multiPathFilter = createMPF(filter, minimalFilter);
//multiPathFilter.setDebugFile("/tmp/filter.txt");
filterResults = filterResults(multiPathFilter);
int frame = 0;
int c = 0;
int c2 = 0;
for (int i = 0; i < filterResults.length; i++) {
if (frame != filterResults[i].getFrame()) {
if (c != 0)
SpotFinderPreview.addRoi(frame, o, x, y, c, Color.red);
if (c2 != 0)
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
c = c2 = 0;
}
frame = filterResults[i].getFrame();
if (predicted.contains(filterResults[i].getUniqueId()))
continue;
if (filterResults[i].ignore()) {
if (x2.length == c2) {
x2 = Arrays.copyOf(x2, c2 * 2);
y2 = Arrays.copyOf(y2, c2 * 2);
}
x2[c2] = filterResults[i].getX();
y2[c2++] = filterResults[i].getY();
} else {
if (x.length == c) {
x = Arrays.copyOf(x, c * 2);
y = Arrays.copyOf(y, c * 2);
}
x[c] = filterResults[i].getX();
y[c++] = filterResults[i].getY();
}
}
//fp += c;
if (c != 0)
SpotFinderPreview.addRoi(frame, o, x, y, c, Color.red);
if (c2 != 0)
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
}
// Do TN (all remaining peaks that have not been matched)
if (showFN) {
final boolean checkBorder = (BenchmarkSpotFilter.lastAnalysisBorder != null && BenchmarkSpotFilter.lastAnalysisBorder.x != 0);
final float border, xlimit, ylimit;
if (checkBorder) {
final Rectangle lastAnalysisBorder = BenchmarkSpotFilter.lastAnalysisBorder;
border = lastAnalysisBorder.x;
xlimit = lastAnalysisBorder.x + lastAnalysisBorder.width;
ylimit = lastAnalysisBorder.y + lastAnalysisBorder.height;
} else
border = xlimit = ylimit = 0;
// Add the results to the lists
actualCoordinates.forEachEntry(new CustomTIntObjectProcedure(x, y, x2, y2) {
public boolean execute(int frame, IdPeakResult[] results) {
int c = 0, c2 = 0;
if (x.length <= results.length) {
x = new float[results.length];
y = new float[results.length];
}
if (x2.length <= results.length) {
x2 = new float[results.length];
y2 = new float[results.length];
}
for (int i = 0; i < results.length; i++) {
// Ignore those that were matched by TP
if (actual.contains(results[i].uniqueId))
continue;
if (checkBorder && outsideBorder(results[i], border, xlimit, ylimit)) {
x2[c2] = results[i].getXPosition();
y2[c2++] = results[i].getYPosition();
} else {
x[c] = results[i].getXPosition();
y[c++] = results[i].getYPosition();
}
}
//fn += c;
if (c != 0)
SpotFinderPreview.addRoi(frame, o, x, y, c, Color.yellow);
if (c2 != 0)
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.orange);
return true;
}
});
}
//System.out.printf("TP=%d, FP=%d, FN=%d, N=%d (%d)\n", tp, fp, fn, tp + fn, results.size());
imp.setOverlay(o);
return filterResults;
}
Aggregations