use of uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi in project GDSC-SMLM by aherbert.
the class GaussianFit method setOverlay.
/**
* Show the points as an overlay.
*
* @param npoints the number of points
* @param xpoints the x points
* @param ypoints the y points
*/
private void setOverlay(int npoints, float[] xpoints, float[] ypoints) {
final PointRoi roi = new OffsetPointRoi(xpoints, ypoints, npoints);
final Color strokeColor = Color.yellow;
final Color fillColor = Color.green;
roi.setStrokeColor(strokeColor);
roi.setFillColor(fillColor);
roi.setShowLabels(false);
imp.setOverlay(roi, strokeColor, 2, fillColor);
}
use of uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi in project GDSC-SMLM by aherbert.
the class SpotAnalysis method updateCurrentSlice.
private void updateCurrentSlice(int slice) {
if (slice != currentSlice) {
currentSlice = slice;
final double signal = getSignal(slice);
final double noise = smoothSd[slice - 1];
currentLabel.setText(String.format("Frame %d: Signal = %s, SNR = %s", slice, MathUtils.rounded(signal, 4), MathUtils.rounded(signal / noise, 3)));
drawProfiles();
// Fit the PSF using a Gaussian
final FitConfiguration fitConfiguration = new FitConfiguration();
fitConfiguration.setPsf(PsfProtosHelper.defaultOneAxisGaussian2DPSF);
fitConfiguration.setFixedPsf(true);
fitConfiguration.setBackgroundFitting(true);
fitConfiguration.setSignalStrength(0);
fitConfiguration.setCoordinateShift(rawImp.getWidth() / 4.0f);
fitConfiguration.setComputeResiduals(false);
fitConfiguration.setComputeDeviations(false);
final Gaussian2DFitter gf = new Gaussian2DFitter(fitConfiguration);
double[] params = new double[1 + Gaussian2DFunction.PARAMETERS_PER_PEAK];
final double psfWidth = Double.parseDouble(widthTextField.getText());
params[Gaussian2DFunction.BACKGROUND] = smoothMean[slice - 1];
params[Gaussian2DFunction.SIGNAL] = (gain * signal);
params[Gaussian2DFunction.X_POSITION] = rawImp.getWidth() / 2.0f;
params[Gaussian2DFunction.Y_POSITION] = rawImp.getHeight() / 2.0f;
params[Gaussian2DFunction.X_SD] = params[Gaussian2DFunction.Y_SD] = psfWidth;
float[] data = (float[]) rawImp.getImageStack().getProcessor(slice).getPixels();
FitResult fitResult = gf.fit(SimpleArrayUtils.toDouble(data), rawImp.getWidth(), rawImp.getHeight(), 1, params, new boolean[1]);
if (fitResult.getStatus() == FitStatus.OK) {
params = fitResult.getParameters();
final double spotSignal = params[Gaussian2DFunction.SIGNAL] / gain;
rawFittedLabel.setText(String.format("Raw fit: Signal = %s, SNR = %s", MathUtils.rounded(spotSignal, 4), MathUtils.rounded(spotSignal / noise, 3)));
ImageRoiPainter.addRoi(rawImp, slice, new OffsetPointRoi(params[Gaussian2DFunction.X_POSITION], params[Gaussian2DFunction.Y_POSITION]));
} else {
rawFittedLabel.setText("");
rawImp.setOverlay(null);
}
// Fit the PSF using a Gaussian
if (blurImp == null) {
return;
}
params = new double[1 + Gaussian2DFunction.PARAMETERS_PER_PEAK];
params[Gaussian2DFunction.BACKGROUND] = (float) smoothMean[slice - 1];
params[Gaussian2DFunction.SIGNAL] = (float) (gain * signal);
params[Gaussian2DFunction.X_POSITION] = rawImp.getWidth() / 2.0f;
params[Gaussian2DFunction.Y_POSITION] = rawImp.getHeight() / 2.0f;
params[Gaussian2DFunction.X_SD] = params[Gaussian2DFunction.Y_SD] = psfWidth;
data = (float[]) blurImp.getImageStack().getProcessor(slice).getPixels();
fitResult = gf.fit(SimpleArrayUtils.toDouble(data), rawImp.getWidth(), rawImp.getHeight(), 1, params, new boolean[1]);
if (fitResult.getStatus() == FitStatus.OK) {
params = fitResult.getParameters();
final double spotSignal = params[Gaussian2DFunction.SIGNAL] / gain;
blurFittedLabel.setText(String.format("Blur fit: Signal = %s, SNR = %s", MathUtils.rounded(spotSignal, 4), MathUtils.rounded(spotSignal / noise, 3)));
ImageRoiPainter.addRoi(blurImp, slice, new OffsetPointRoi(params[Gaussian2DFunction.X_POSITION], params[Gaussian2DFunction.Y_POSITION]));
} else {
blurFittedLabel.setText("");
blurImp.setOverlay(null);
}
}
}
use of uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi in project GDSC-SMLM by aherbert.
the class SpotFinderPreview method addRoi.
/**
* Adds the roi to the overlay.
*
* @param frame the frame
* @param overlay the overlay
* @param x the x coordinates
* @param y the y coordinates
* @param npoints the number of points
* @param colour the colour
* @param pointType the point type
* @param size the size
* @see PointRoi#setPosition(int)
* @see PointRoi#setPointType(int)
* @see PointRoi#setFillColor(Color)
* @see PointRoi#setStrokeColor(Color)
* @see PointRoi#setSize(int)
*/
public static void addRoi(int frame, Overlay overlay, float[] x, float[] y, int npoints, Color colour, int pointType, int size) {
if (npoints == 0) {
return;
}
final PointRoi roi = new OffsetPointRoi(x, y, npoints);
roi.setPointType(pointType);
roi.setFillColor(colour);
roi.setStrokeColor(colour);
if (frame != 0) {
roi.setPosition(frame);
}
if (size != 0) {
roi.setSize(size);
}
overlay.add(roi);
}
use of uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi in project GDSC-SMLM by aherbert.
the class DrawClusters method run.
@Override
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
final MemoryPeakResults results = ResultsManager.loadInputResults(settings.inputOption, false, DistanceUnit.PIXEL);
if (MemoryPeakResults.isEmpty(results)) {
IJ.error(TITLE, "No results could be loaded");
return;
}
// Get the traces
final 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 = (settings.maxSize < settings.minSize) ? Integer.MAX_VALUE : settings.maxSize;
final boolean myDrawLines = myMaxSize > 1 && settings.drawLines;
for (int i = 0; i < traces.length; i++) {
if (settings.expandToSingles) {
traces[i].expandToSingles();
}
if (traces[i].size() >= settings.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;
}
final String msg = String.format(TITLE + ": %d / %s (%s)", count, TextUtils.pleural(traces.length, "trace"), TextUtils.pleural(results.size(), "localisation"));
IJ.showStatus(msg);
final Rectangle bounds = results.getBounds(true);
ImagePlus imp = WindowManager.getImage(settings.title);
boolean isUseStackPosition = settings.useStackPosition;
if (imp == null) {
// Create a default image using 100 pixels as the longest edge
final double maxD = (bounds.width > bounds.height) ? bounds.width : bounds.height;
int width;
int height;
if (maxD == 0) {
// Note that imageSize can be zero (for auto sizing)
width = height = (settings.imageSize == 0) ? 20 : settings.imageSize;
} else if (settings.imageSize == 0) {
// Note that imageSize can be zero (for auto sizing)
width = bounds.width;
height = bounds.height;
} else {
width = (int) (settings.imageSize * bounds.width / maxD);
height = (int) (settings.imageSize * bounds.height / maxD);
}
final ByteProcessor bp = new ByteProcessor(width, height);
if (isUseStackPosition) {
final ImageStack stack = new ImageStack(width, height, maxFrame);
for (int i = 1; i <= maxFrame; i++) {
// Do not clone as the image is empty
stack.setPixels(bp.getPixels(), i);
}
imp = ImageJUtils.display(TITLE, stack);
} else {
imp = ImageJUtils.display(TITLE, bp);
}
// Enlarge
final 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);
}
// Check if the image has enough frames for all the traces
} else 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
final Roi[] rois = new Roi[count];
final int[][] frames = (isUseStackPosition) ? new int[count][] : null;
final int[] indices = SimpleArrayUtils.natural(count);
final double[] values = new double[count];
for (int i = 0; i < count; i++) {
final Trace trace = traces[i];
final int npoints = trace.size();
final float[] xpoints = new float[npoints];
final float[] ypoints = new float[npoints];
int ii = 0;
if (frames != null) {
frames[i] = new int[npoints];
}
for (int k = 0; k < trace.size(); k++) {
final PeakResult result = trace.get(k);
xpoints[ii] = (result.getXPosition() - bounds.x) * xScale;
ypoints[ii] = (result.getYPosition() - bounds.y) * yScale;
if (frames != null) {
frames[i][ii] = result.getFrame();
}
ii++;
}
Roi roi;
if (myDrawLines) {
roi = new PolygonRoi(xpoints, ypoints, npoints, Roi.POLYLINE);
if (settings.splineFit) {
((PolygonRoi) roi).fitSpline();
}
} else {
roi = new OffsetPointRoi(xpoints, ypoints, npoints);
((PointRoi) roi).setShowLabels(false);
}
rois[i] = roi;
switch(settings.sort) {
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].getMeanDistance();
break;
// No sort
case 0:
default:
break;
}
}
if (settings.sort > 0) {
SortUtils.sortIndices(indices, values, true);
}
// Draw the traces as ROIs on an overlay
final Overlay o = new Overlay();
final LUT lut = LutHelper.createLut(settings.lut);
final double scale = 256.0 / count;
if (frames != null) {
// 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);
// roi.setStrokeWidth(settings.lineWidth);
roi.updateWideLine(settings.lineWidth);
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]);
final PointRoi pointRoi = new OffsetPointRoi(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))));
// roi.setStrokeWidth(settings.lineWidth);
roi.updateWideLine(settings.lineWidth);
o.add(roi);
}
}
imp.setOverlay(o);
IJ.showStatus(msg);
}
use of uk.ac.sussex.gdsc.core.ij.gui.OffsetPointRoi in project GDSC-SMLM by aherbert.
the class ImageRoiPainter method appendRoi.
/**
* Adds a new ROI to the overlay using the coordinates from start to end (non-inclusive).
*
* @param x the x
* @param y the y
* @param slice the slice
* @param indices the indices
* @param overlay the o
* @param start the start
* @param end the end
*/
private static void appendRoi(float[] x, float[] y, int[] slice, int[] indices, Overlay overlay, int start, int end) {
final int p = end - start;
final float[] x2 = new float[p];
final float[] y2 = new float[p];
for (int j = start, ii = 0; j < end; j++, ii++) {
x2[ii] = x[indices[j]];
y2[ii] = y[indices[j]];
}
final PointRoi roi = new OffsetPointRoi(x2, y2, p);
roi.setPosition(slice[indices[start]]);
overlay.add(roi);
}
Aggregations