use of uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class PeakFit method showResults.
/**
* Show results.
*/
protected void showResults() {
IJ.showProgress(1.0);
if (time >= 0) {
if (silent) {
results.end();
return;
}
// Check if we are sorting
IJ.showStatus("Finalising results ...");
for (final PeakResults r : results.toArray()) {
if (r instanceof MemoryPeakResults) {
if (((MemoryPeakResults) r).isSortAfterEnd()) {
IJ.showStatus("Sorting " + r.size() + " results ...");
}
break;
}
}
results.end();
final String textTime = TextUtils.nanosToString(time);
final String textRunTime = TextUtils.nanosToString(runTime);
final int size = getSize();
final String message = String.format("%s. Total fitting time = %s. Run time = %s", TextUtils.pleural(size, "localisation"), textTime, textRunTime);
if (resultsSettings.getLogProgress()) {
IJ.log(LOG_SPACER);
}
IJ.log(message);
IJ.showStatus(message);
} else {
IJ.showStatus("");
}
}
use of uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults 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 localImp = this.imp;
if (fitMaxima && singleFrame > 0 && source instanceof IJImageSource) {
final String title = source.getName();
localImp = WindowManager.getImage(title);
}
if (singleFrame > 0 && localImp != null) {
MemoryPeakResults memoryResults = null;
for (final PeakResults r : this.results.toArray()) {
if (r instanceof MemoryPeakResults) {
memoryResults = (MemoryPeakResults) r;
break;
}
}
if (memoryResults == null || memoryResults.size() == 0) {
return;
}
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
gd.addMessage("Add the fitted localisations as an overlay?");
gd.showDialog();
if (!gd.wasOKed()) {
return;
}
final LUT lut = LutHelper.createLut(LutColour.ICE);
final Overlay o = new Overlay();
final int size = memoryResults.size();
final Counter j = new Counter(size);
final ImagePlus finalImp = localImp;
memoryResults.forEach(DistanceUnit.PIXEL, (XyResultProcedure) (x, y) -> {
final PointRoi roi = new OffsetPointRoi(x, y);
final Color c = LutHelper.getColour(lut, j.decrementAndGet(), size);
roi.setStrokeColor(c);
roi.setFillColor(c);
if (finalImp.getStackSize() > 1) {
roi.setPosition(singleFrame);
}
o.add(roi);
});
localImp.setOverlay(o);
localImp.getWindow().toFront();
}
}
use of uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class PeakFit method setup.
@Override
public int setup(String arg, ImagePlus imp) {
SmlmUsageTracker.recordPlugin(this.getClass(), arg);
pluginFlags = FLAGS;
extraOptions = ImageJUtils.isExtraOptions();
maximaIdentification = StringUtils.contains(arg, "spot");
fitMaxima = StringUtils.contains(arg, "maxima");
simpleFit = StringUtils.contains(arg, "simple");
final boolean runSeries = StringUtils.contains(arg, "series");
ImageSource imageSource = null;
if (fitMaxima) {
// The image source will be found from the peak results.
if (!showMaximaDialog()) {
return DONE;
}
final MemoryPeakResults localResults = ResultsManager.loadInputResults(settings.inputOption, false, DistanceUnit.PIXEL);
if (localResults == null || localResults.size() == 0) {
IJ.error(TITLE, "No results could be loaded");
return DONE;
}
if (settings.fitAcrossAllFrames) {
// Allow the user to select a different image. The source will be set as per the
// main fit routine from the image (imp).
singleFrame = 0;
} else {
// Check for single frame
singleFrame = getSingleFrame(localResults);
// Forces the maxima to be used with their original source.
imp = null;
imageSource = localResults.getSource();
pluginFlags |= NO_IMAGE_REQUIRED;
}
} else if (runSeries) {
imp = null;
// Select input folder
final String inputDirectory = IJ.getDirectory("Select image series ...");
if (inputDirectory == null) {
return DONE;
}
// Load input series ...
SeriesOpener series;
if (extraOptions) {
final String helpKey = maximaIdentification ? "spot-finder-series" : "peak-fit-series";
series = SeriesOpener.create(inputDirectory, true, HelpUrls.getUrl(helpKey));
} else {
series = new SeriesOpener(inputDirectory);
}
if (series.getNumberOfImages() == 0) {
IJ.error(TITLE, "No images in the selected directory:\n" + inputDirectory);
return DONE;
}
final SeriesImageSource seriesImageSource = new SeriesImageSource(getName(series.getImageList()), series);
// TrackProgress logging is very verbose if the series has many images
// Status is used only when reading TIFF info.
// seriesImageSource.setTrackProgress(SimpleImageJTrackProgress.getInstance());
seriesImageSource.setTrackProgress(new TrackProgressAdaptor() {
@Override
public void status(String format, Object... args) {
ImageJUtils.showStatus(() -> String.format(format, args));
}
});
imageSource = seriesImageSource;
pluginFlags |= NO_IMAGE_REQUIRED;
}
// If the image source has not been set then use the input image
if (imageSource == null) {
if (imp == null) {
IJ.noImage();
return DONE;
}
// Check it is not a previous result
if (imp.getTitle().endsWith(ImageJImagePeakResults.IMAGE_SUFFIX)) {
IJImageSource ijImageSource = null;
// Check the image to see if it has an image source XML structure in the info property
final Object o = imp.getProperty("Info");
final Pattern pattern = Pattern.compile("Source: (<.*IJImageSource>.*<.*IJImageSource>)", Pattern.DOTALL);
final Matcher match = pattern.matcher((o == null) ? "" : o.toString());
if (match.find()) {
final ImageSource tmpSource = ImageSource.fromXml(match.group(1));
if (tmpSource instanceof IJImageSource) {
ijImageSource = (IJImageSource) tmpSource;
if (!ijImageSource.open()) {
ijImageSource = null;
} else {
imp = WindowManager.getImage(ijImageSource.getName());
}
}
}
if (ijImageSource == null) {
// Look for a parent using the title
final String parentTitle = imp.getTitle().substring(0, imp.getTitle().length() - ImageJImagePeakResults.IMAGE_SUFFIX.length() - 1);
final ImagePlus parentImp = WindowManager.getImage(parentTitle);
if (parentImp != null) {
ijImageSource = new IJImageSource(parentImp);
imp = parentImp;
}
}
String message = "The selected image may be a previous fit result";
if (ijImageSource != null) {
if (!TextUtils.isNullOrEmpty(ijImageSource.getName())) {
message += " of: \n \n" + ijImageSource.getName();
}
message += " \n \nFit the parent?";
} else {
message += " \n \nDo you want to continue?";
}
final YesNoCancelDialog d = new YesNoCancelDialog(null, TITLE, message);
if (ijImageSource == null) {
if (!d.yesPressed()) {
return DONE;
}
} else {
if (d.yesPressed()) {
imageSource = ijImageSource;
}
if (d.cancelPressed()) {
return DONE;
}
}
}
if (imageSource == null) {
try {
imageSource = new IJImageSource(imp);
} catch (final IllegalArgumentException ex) {
// This can happen if the image has an origin not in integer pixels
// e.g. the plugin is run on a plot
IJ.error(TITLE, "Error using image: " + imp.getTitle() + "\n \n" + ex.getMessage());
return DONE;
}
}
}
time = -1;
if (!initialiseImage(imageSource, getBounds(imp), false)) {
IJ.error(TITLE, "Failed to initialise the source image: " + imageSource.getName());
return DONE;
}
final int flags = showDialog(imp);
if ((flags & DONE) == 0) {
initialiseFitting();
}
return flags;
}
use of uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class TraceExporter method exportSpotOn.
private void exportSpotOn(MemoryPeakResults results) {
try (BufferedWriter out = Files.newBufferedWriter(Paths.get(settings.directory, results.getName() + ".csv"))) {
out.write("frame,t,trajectory,x,y");
out.newLine();
final TypeConverter<TimeUnit> converter = UnitConverterUtils.createConverter(TimeUnit.FRAME, TimeUnit.SECOND, results.getCalibrationReader().getExposureTime());
@SuppressWarnings("resource") final BufferedWriter writer = out;
results.forEach(DistanceUnit.UM, (XyrResultProcedure) (x, y, result) -> {
try {
if (result.hasEndFrame()) {
final String sId = Integer.toString(result.getId());
final String sx = Float.toString(x);
final String sy = Float.toString(y);
for (int t = result.getFrame(); t <= result.getEndFrame(); t++) {
writer.write(Integer.toString(t));
writer.write(",");
writer.write(Float.toString(converter.convert(t)));
writer.write(",");
writer.write(sId);
writer.write(",");
writer.write(sx);
writer.write(",");
writer.write(sy);
writer.newLine();
}
} else {
writer.write(Integer.toString(result.getFrame()));
writer.write(",");
writer.write(Float.toString(converter.convert(result.getFrame())));
writer.write(",");
writer.write(Integer.toString(result.getId()));
writer.write(",");
writer.write(Float.toString(x));
writer.write(",");
writer.write(Float.toString(y));
writer.newLine();
}
} catch (final IOException ex) {
throw new RuntimeException(ex);
}
});
} catch (final IOException | RuntimeException ex) {
handleException(ex);
}
}
use of uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults in project GDSC-SMLM by aherbert.
the class TraceExporter method exportVbSpt.
@SuppressWarnings("resource")
private void exportVbSpt(MemoryPeakResults results) {
// vbSPT file format:
// https://sourceforge.net/projects/vbspt/
// Matlab matrix file (.mat) containing at least one variable that is a cell
// array where each element, representing a trajectory, is a matrix
// where the rows define the coordinates in one, two or three dimensions
// in subsequent timesteps. The number of dimensions to be used for the
// analysis will be set by the runinputfile.
// The units are arbitrary but vbSPT starting estimates must be in the same
// units. Either nm or μm are recommended.
// 3 columns for n rows of localisations
// 1. x coordinate (μm)
// 2. y coordinate (μm)
// 3. z coordinate (μm)
//
// Note: An extra column is added containing the frame. This allows results to
// be uniquely identified using frame,x,y,z
// Count the IDs. Each new result ID will increment the count.
final FrameCounter idCounter = new FrameCounter(results.getFirst().getId() - 1);
results.forEach((PeakResultProcedure) result -> {
if (idCounter.advance(result.getId())) {
idCounter.increment();
}
});
// Create the cell array as 1xN
final Cell out = Mat5.newCell(1, idCounter.getCount());
// This will reset the counter to zero and ensure the current frame does not match
// in the event of a single track
idCounter.advanceAndReset(idCounter.currentFrame() + 1);
final boolean is3d = results.is3D();
// Write the tracks
final LocalList<double[]> list = new LocalList<>();
results.forEach(DistanceUnit.UM, (XyzrResultProcedure) (x, y, z, result) -> {
if (idCounter.advance(result.getId())) {
addTrack(out, idCounter.getCount() - 1, list, is3d);
idCounter.increment();
list.clear();
}
list.add(new double[] { x, y, z, result.getFrame() });
});
addTrack(out, idCounter.getCount() - 1, list, is3d);
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);
}
}
Aggregations