use of ij.gui.GenericDialog in project GDSC-SMLM by aherbert.
the class PsfCreator method createInteractivePlots.
private void createInteractivePlots(ImageStack psf, int zCentre, double nmPerPixel, double psfWidth) {
this.psf = psf;
this.zCentre = zCentre;
this.psfNmPerPixel = nmPerPixel;
this.psfWidth = psfWidth;
this.slice = zCentre;
this.distanceThreshold = psfWidth * 3;
final GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage("Plot the cumulative signal verses distance from the PSF centre.\n \nZ-centre = " + zCentre + "\nPSF width = " + MathUtils.rounded(psfWidth) + " nm");
gd.addSlider("Slice", 1, psf.getSize(), slice);
final double maxDistance = (psf.getWidth() / 1.414213562) * nmPerPixel;
gd.addSlider("Distance", 0, maxDistance, distanceThreshold);
gd.addCheckbox("Normalise", normalise);
gd.addDialogListener(new InteractivePlotListener());
if (!IJ.isMacro()) {
drawPlots(true);
}
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
drawPlots(true);
}
use of ij.gui.GenericDialog in project GDSC-SMLM by aherbert.
the class RenameResults method showDialog.
private boolean showDialog() {
final GenericDialog gd = new GenericDialog(TITLE);
gd.addHelp(HelpUrls.getUrl("rename-results"));
gd.addMessage("To rename the results in memory update the second name field as desired.\n" + "(Note the semi-colon at the end of the line is needed for macro recording.)");
final StringBuilder sb = new StringBuilder();
for (final String name : MemoryPeakResults.getResultNames()) {
sb.append(name).append(" = ").append(name).append(";\n");
}
gd.addTextAreas(sb.toString(), null, 20, 80);
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
renameText = gd.getNextText();
return true;
}
use of ij.gui.GenericDialog in project GDSC-SMLM by aherbert.
the class ResultsManager method collectOptions.
private static void collectOptions(PeakResultsReader reader, ResultOption[] options) {
final GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage("Options required for file format: " + reader.getFormat().getName());
for (final ResultOption option : options) {
if (option.hasValues()) {
final String[] items = new String[option.values.length];
for (int i = 0; i < items.length; i++) {
items[i] = option.values[i].toString();
}
gd.addChoice(getOptionName(option), items, option.getValue().toString());
} else if (option.getValue() instanceof Number) {
final Number n = (Number) option.getValue();
if (n.doubleValue() == n.intValue()) {
gd.addNumericField(getOptionName(option), n.intValue(), 0);
} else {
final String value = n.toString();
int sig = 0;
int index = value.indexOf('.');
if (index != -1) {
// There is a decimal point. Count the digits after it
while (++index < value.length()) {
if (!Character.isDigit(value.charAt(index))) {
// A non-digit character after the decimal point is for scientific notation
sig = -sig;
break;
}
sig++;
}
}
gd.addNumericField(getOptionName(option), n.doubleValue(), sig);
}
} else if (option.getValue() instanceof String) {
gd.addStringField(getOptionName(option), (String) option.getValue());
} else if (option.getValue() instanceof Boolean) {
gd.addCheckbox(getOptionName(option), (Boolean) option.getValue());
} else {
IJ.log(TITLE + ": Unsupported reader option: " + option.name + "=" + option.getValue().toString());
}
}
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
try {
for (final ResultOption option : options) {
if (option.hasValues()) {
option.setValue(option.values[gd.getNextChoiceIndex()]);
} else if (option.getValue() instanceof Number) {
final double d = gd.getNextNumber();
// Convert to the correct type using the String value constructor for the number
option.setValue(option.getValue().getClass().getConstructor(String.class).newInstance(Double.toString(d)));
} else if (option.getValue() instanceof String) {
option.setValue(gd.getNextString());
} else if (option.getValue() instanceof Boolean) {
option.setValue(gd.getNextBoolean());
}
}
reader.setOptions(options);
} catch (final Exception ex) {
// This can occur if the options are not valid
IJ.log(TITLE + ": Failed to configure reader options: " + ex.getMessage());
}
}
use of ij.gui.GenericDialog in project GDSC-SMLM by aherbert.
the class ResultsManager method runClearMemory.
private static void runClearMemory(String arg) {
if (MemoryPeakResults.isMemoryEmpty()) {
IJ.error(TITLE, "There are no fitting results in memory");
IJ.showStatus("");
return;
}
Collection<MemoryPeakResults> allResults;
boolean removeAll = false;
String helpKey = "clear-memory-results";
if (arg.contains("multi")) {
helpKey += "-multi";
final MultiDialog md = createMultiDialog(TITLE);
md.setSelected(lastSelected.get());
md.setHelpUrl(HelpUrls.getUrl(helpKey));
md.showDialog();
if (md.wasCancelled()) {
return;
}
final List<String> selected = md.getSelectedResults();
if (selected.isEmpty()) {
return;
}
lastSelected.set(selected);
allResults = new ArrayList<>(selected.size());
for (final String name : selected) {
final MemoryPeakResults r = MemoryPeakResults.getResults(name);
if (r != null) {
allResults.add(r);
}
}
} else {
removeAll = true;
allResults = MemoryPeakResults.getAllResults();
}
if (allResults.isEmpty()) {
return;
}
long memorySize = 0;
int size = 0;
for (final MemoryPeakResults results : allResults) {
memorySize += MemoryPeakResults.estimateMemorySize(results);
size += results.size();
}
final String memory = TextUtils.bytesToString(memorySize);
final String count = TextUtils.pleural(size, "result");
final String sets = TextUtils.pleural(allResults.size(), "set");
final GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage(String.format("Do you want to remove %s from memory (%s, %s)?", count, sets, memory));
gd.addHelp(HelpUrls.getUrl(helpKey));
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
if (removeAll) {
MemoryPeakResults.clearMemory();
} else {
for (final MemoryPeakResults results : allResults) {
MemoryPeakResults.removeResults(results.getName());
}
}
SummariseResults.clearSummaryTable();
ImageJUtils.log("Cleared %s (%s, %s)", count, sets, memory);
}
use of ij.gui.GenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method runMaximaFitting.
/**
* Load the selected results from memory. All multiple frame results are added directly to the
* results. All single frame results are added to a list of candidate maxima per frame and fitted
* using the configured parameters.
*/
private void runMaximaFitting() {
final MemoryPeakResults memoryResults = ResultsManager.loadInputResults(settings.inputOption, false, DistanceUnit.PIXEL);
if (memoryResults == null || memoryResults.size() == 0) {
log("No results for maxima fitting");
return;
}
// The total frames (for progress reporting)
int totalFrames;
// A function that can convert a frame into a set of candidate indices
final IntFunction<int[]> frameToMaxIndices;
// The frames to process (should be sorted ascending)
Supplier<IntStream> frames;
// Support fitting all time frames with the same results.
if (settings.fitAcrossAllFrames) {
// Check if the input spans multiple frames
if (getSingleFrame(memoryResults) == 0) {
final int min = memoryResults.getMinFrame();
final int max = memoryResults.getMaxFrame();
final GenericDialog gd = new GenericDialog(TITLE);
gd.enableYesNoCancel();
gd.hideCancelButton();
ImageJUtils.addMessage(gd, "Candidate maxima for fitting span multiple frames (%d-%d).\n \n" + "Please confirm the %s are correct.", min, max, TextUtils.pleural(memoryResults.size(), "candidate"));
gd.showDialog();
if (!gd.wasOKed()) {
return;
}
}
final int[] maxIndices = getMaxIndices(Arrays.asList(memoryResults.toArray()));
// This may not work correctly if using for example a series image source that
// incorrectly estimates the number of frames
totalFrames = source.getFrames();
frameToMaxIndices = frame -> maxIndices;
frames = () -> IntStream.rangeClosed(1, totalFrames);
} else {
// Build a map between the time-frame and the results in that frame.
final Map<Integer, List<PeakResult>> map = Arrays.stream(memoryResults.toArray()).parallel().filter(peakResult -> peakResult.getFrame() == peakResult.getEndFrame()).collect(Collectors.groupingBy(PeakResult::getFrame));
totalFrames = map.size();
// Build a function that can convert a frame into a set of candidate indices
frameToMaxIndices = frame -> getMaxIndices(map.get(frame));
frames = () -> map.keySet().stream().mapToInt(Integer::intValue).sorted();
}
final ImageStack stack = (extraSettings.showProcessedFrames) ? new ImageStack(bounds.width, bounds.height) : null;
// Use the FitEngine to allow multi-threading.
final FitEngine engine = createFitEngine(getNumberOfThreads(totalFrames));
if (engine == null) {
return;
}
final int step = ImageJUtils.getProgressInterval(totalFrames);
// No crop bounds are supported.
// To pre-process data for noise estimation
final boolean isFitCameraCounts = fitConfig.isFitCameraCounts();
final CameraModel cameraModel = fitConfig.getCameraModel();
runTime = System.nanoTime();
final AtomicBoolean shutdown = new AtomicBoolean();
final String format = String.format("Slice: %%d / %d (Results=%%d)", totalFrames);
frames.get().forEachOrdered(slice -> {
if (shutdown.get() || escapePressed()) {
shutdown.set(true);
return;
}
final float[] data = source.get(slice);
if (data == null) {
shutdown.set(true);
return;
}
if (slice % step == 0) {
if (ImageJUtils.showStatus(() -> String.format(format, slice, results.size()))) {
IJ.showProgress(slice, totalFrames);
}
}
// We must pre-process the data before noise estimation
final float[] data2 = data.clone();
if (isFitCameraCounts) {
cameraModel.removeBias(data2);
} else {
cameraModel.removeBiasAndGain(data2);
}
final float noise = FitWorker.estimateNoise(data2, source.getWidth(), source.getHeight(), config.getNoiseMethod());
if (stack != null) {
stack.addSlice(String.format("Frame %d - %d", source.getStartFrameNumber(), source.getEndFrameNumber()), data);
}
// Get the frame number from the source to allow for interlaced and aggregated data
engine.run(createMaximaFitJob(frameToMaxIndices.apply(slice), source.getStartFrameNumber(), source.getEndFrameNumber(), data, bounds, noise));
});
engine.end(shutdown.get());
time = engine.getTime();
runTime = System.nanoTime() - runTime;
if (stack != null) {
ImageJUtils.display("Processed frames", stack);
}
showResults();
source.close();
}
Aggregations