use of uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure in project GDSC-SMLM by aherbert.
the class CropResults method roiCropResults.
private void roiCropResults() {
final MemoryPeakResults newResults = createNewResults();
// These bounds are integer. But this is because the results are meant to come from an image.
final Rectangle integerBounds = results.getBounds(true);
final ImagePlus imp = WindowManager.getImage(settings.getRoiImage());
if (imp == null) {
IJ.error(TITLE, "No ROI image: " + settings.getRoiImage());
return;
}
final CoordinatePredicate roiTest = CoordinatePredicateUtils.createContainsPredicate(imp.getRoi());
if (roiTest == null) {
IJ.error(TITLE, "Not an area ROI");
return;
}
// Scale the results to the size of the image with the ROI
final int roiImageWidth = imp.getWidth();
final int roiImageHeight = imp.getHeight();
final double ox = integerBounds.getX();
final double oy = integerBounds.getY();
final double xscale = roiImageWidth / integerBounds.getWidth();
final double yscale = roiImageHeight / integerBounds.getHeight();
final Predicate<PeakResult> testZ = getZFilter();
results.forEach(DistanceUnit.PIXEL, (XyrResultProcedure) (x, y, result) -> {
if (roiTest.test((x - ox) * xscale, (y - oy) * yscale) && testZ.test(result)) {
newResults.add(result);
}
});
if (settings.getPreserveBounds()) {
newResults.setBounds(integerBounds);
} else {
newResults.setBounds(null);
newResults.getBounds(true);
}
IJ.showStatus(newResults.size() + " Cropped localisations");
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure in project GDSC-SMLM by aherbert.
the class SplitResults method splitResults.
private void splitResults(MemoryPeakResults results, ImageProcessor ip) {
IJ.showStatus("Splitting " + TextUtils.pleural(results.size(), "result"));
// Create an object mask
final ObjectAnalyzer objectAnalyzer = new ObjectAnalyzer(ip, false);
final int maxx = ip.getWidth();
final int maxy = ip.getHeight();
final Rectangle bounds = results.getBounds();
final double ox = bounds.getX();
final double oy = bounds.getY();
final double scaleX = bounds.getWidth() / maxx;
final double scaleY = bounds.getHeight() / maxy;
// Create a results set for each object
final int maxObject = objectAnalyzer.getMaxObject();
final MemoryPeakResults[] resultsSet = new MemoryPeakResults[maxObject + 1];
for (int object = 0; object <= maxObject; object++) {
final MemoryPeakResults newResults = new MemoryPeakResults();
newResults.copySettings(results);
newResults.setName(results.getName() + " " + object);
resultsSet[object] = newResults;
}
final int[] mask = objectAnalyzer.getObjectMask();
if (settings.showObjectMask) {
final ImageProcessor objectIp = (maxObject <= 255) ? new ByteProcessor(maxx, maxy) : new ShortProcessor(maxx, maxy);
for (int i = 0; i < mask.length; i++) {
objectIp.set(i, mask[i]);
}
final ImagePlus imp = ImageJUtils.display(settings.objectMask + " Objects", objectIp);
imp.setDisplayRange(0, maxObject);
imp.updateAndDraw();
}
// Process the results mapping them to their objects
final Counter i = new Counter();
final int size = results.size();
final int step = ImageJUtils.getProgressInterval(size);
results.forEach(DistanceUnit.PIXEL, (XyrResultProcedure) (xx, yy, result) -> {
if (i.incrementAndGet() % step == 0) {
IJ.showProgress(i.getCount(), size);
}
// Map to the mask objects
final int object;
final int x = (int) ((xx - ox) / scaleX);
final int y = (int) ((yy - oy) / scaleY);
if (x < 0 || x >= maxx || y < 0 || y >= maxy) {
object = 0;
} else {
final int index = y * maxx + x;
// is within the bounds of the image processor?
if (index < 0 || index >= mask.length) {
object = 0;
} else {
object = mask[index];
}
}
resultsSet[object].add(result);
});
IJ.showProgress(1);
// Add the new results sets to memory
i.reset();
for (int object = (settings.nonMaskDataset) ? 0 : 1; object <= maxObject; object++) {
if (resultsSet[object].isNotEmpty()) {
MemoryPeakResults.addResults(resultsSet[object]);
i.increment();
}
}
IJ.showStatus("Split " + TextUtils.pleural(results.size(), "result") + " into " + TextUtils.pleural(i.getCount(), "set"));
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure in project GDSC-SMLM by aherbert.
the class TraceExporter method exportAnaDda.
@SuppressWarnings("resource")
private void exportAnaDda(MemoryPeakResults results) {
// anaDDA list of tracked localisations file format:
// https://github.com/HohlbeinLab/anaDDA
// Matlab matrix file.
// 5 columns for n rows of localisations
// 1. x coordinate (μm)
// 2. y coordinate (μm)
// 3. frame number
// 4. track id
// 5. frame time (s)
// Count the number of localisations including start/end frames
final Counter row = new Counter();
results.forEach((PeakResultProcedure) result -> {
row.increment(getLength(result));
});
// Create the matrix
final int rows = row.getCount();
final Matrix out = Mat5.newMatrix(rows, 5);
// Set up column offsets
final int col1 = rows * 1;
final int col2 = rows * 2;
final int col3 = rows * 3;
final int col4 = rows * 4;
// Frame time in seconds. This is not the frame time point converted to seconds
// but the exposure duration of the frame.
final double frameTime = results.getCalibrationReader().getExposureTime() / 1000;
row.reset();
results.forEach(DistanceUnit.UM, (XyrResultProcedure) (x, y, result) -> {
if (result.hasEndFrame()) {
for (int t = result.getFrame(); t <= result.getEndFrame(); t++) {
final int index = row.getAndIncrement();
out.setDouble(index, x);
out.setDouble(index + col1, y);
out.setDouble(index + col2, t);
out.setDouble(index + col3, result.getId());
out.setDouble(index + col4, frameTime);
}
} else {
// Column major index: row + rows * col
final int index = row.getAndIncrement();
out.setDouble(index, x);
out.setDouble(index + col1, y);
out.setDouble(index + col2, result.getFrame());
out.setDouble(index + col3, result.getId());
out.setDouble(index + col4, frameTime);
}
});
try (MatFile matFile = Mat5.newMatFile()) {
matFile.addArray("tracks", out);
Mat5.writeToFile(matFile, Paths.get(settings.directory, results.getName() + ".mat").toFile());
} catch (final IOException ex) {
handleException(ex);
}
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure in project GDSC-SMLM by aherbert.
the class DensityImage method cropWithBorder.
/**
* Crop the results to the ROI. Add a border using the sampling radius so that counts do not have
* to be approximated (i.e. all spots around the edge of the ROI will have a complete image to
* sample from). The results are modified in place.
*
* @param results the results
* @param isWithin Set to true if the added border is within the original bounds (i.e. no
* adjustment for missing counts is required)
* @return the cropped results
*/
private MemoryPeakResults cropWithBorder(MemoryPeakResults results, boolean[] isWithin) {
isWithin[0] = false;
if (roiBounds == null) {
return results;
}
// Adjust bounds relative to input results image:
// Use the ROI relative to the frame the ROI is drawn on.
// Map those fractional coordinates back to the original data bounds.
final Rectangle bounds = results.getBounds();
final double xscale = (double) roiImageWidth / bounds.width;
final double yscale = (double) roiImageHeight / bounds.height;
// Compute relative to the results bounds (if present)
scaledRoiMinX = bounds.x + roiBounds.x / xscale;
scaledRoiMaxX = scaledRoiMinX + roiBounds.width / xscale;
scaledRoiMinY = bounds.y + roiBounds.y / yscale;
scaledRoiMaxY = scaledRoiMinY + roiBounds.height / yscale;
// Allow for the border
final float minX = (int) (scaledRoiMinX - settings.radius);
final float maxX = (int) Math.ceil(scaledRoiMaxX + settings.radius);
final float minY = (int) (scaledRoiMinY - settings.radius);
final float maxY = (int) Math.ceil(scaledRoiMaxY + settings.radius);
// Create a new set of results within the bounds
final MemoryPeakResults newResults = new MemoryPeakResults();
newResults.begin();
results.forEach(DistanceUnit.PIXEL, (XyrResultProcedure) (x, y, result) -> {
if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
newResults.add(result);
}
});
newResults.end();
newResults.copySettings(results);
newResults.setBounds(new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)));
isWithin[0] = minX >= bounds.x && minY >= bounds.y && maxX <= (bounds.x + bounds.width) && maxY <= (bounds.y + bounds.height);
return newResults;
}
use of uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure in project GDSC-SMLM by aherbert.
the class Fire method cropToRoi.
private MemoryPeakResults cropToRoi(MemoryPeakResults results) {
if (roiBounds == null) {
return results;
}
// Adjust bounds relative to input results image
final Rectangle bounds = results.getBounds(true);
final double xscale = (double) roiImageWidth / bounds.width;
final double yscale = (double) roiImageHeight / bounds.height;
final float minX = (float) (bounds.x + roiBounds.x / xscale);
final float maxX = (float) (minX + roiBounds.width / xscale);
final float minY = (float) (bounds.y + (roiBounds.y / yscale));
final float maxY = (float) (minY + roiBounds.height / yscale);
// Create a new set of results within the bounds
final MemoryPeakResults newResults = new MemoryPeakResults();
newResults.begin();
results.forEach(DistanceUnit.PIXEL, (XyrResultProcedure) (x, y, result) -> {
if (x < minX || x > maxX || y < minY || y > maxY) {
return;
}
newResults.add(result);
});
newResults.end();
newResults.copySettings(results);
newResults.setBounds(new Rectangle((int) minX, (int) minY, (int) Math.ceil(maxX - minX), (int) Math.ceil(maxY - minY)));
return newResults;
}
Aggregations