use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project gdsc-smlm by aherbert.
the class SpotFinderPreview method showDialog.
@Override
public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
settings = Settings.load();
this.overlay = imp.getOverlay();
this.imp = imp;
// Saved by reference so do it once now
settings.save();
// The image is locked by the PlugInFilterRunner so unlock it to allow scroll.
// This should be OK as the image data is not modified and only the overlay is
// adjusted. If another plugin changes the image then the preview should update
// the overlay and it will be obvious to the user to turn this plugin off.
imp.unlock();
config = SettingsManager.readFitEngineConfiguration(0);
fitConfig = config.getFitConfiguration();
gd = new NonBlockingExtendedGenericDialog(TITLE);
gd.addHelp(HelpUrls.getUrl("spot-finder-preview"));
gd.addMessage("Preview candidate maxima");
final String[] templates = ConfigurationTemplate.getTemplateNames(true);
gd.addChoice("Template", templates, templates[0]);
final String[] models = CameraModelManager.listCameraModels(true);
gd.addChoice("Camera_model_name", models, fitConfig.getCameraModelName());
PeakFit.addPsfOptions(gd, (FitConfigurationProvider) () -> fitConfig);
final PeakFit.SimpleFitEngineConfigurationProvider provider = new PeakFit.SimpleFitEngineConfigurationProvider(config);
PeakFit.addDataFilterOptions(gd, provider);
gd.addChoice("Spot_filter_2", SettingsManager.getDataFilterMethodNames(), config.getDataFilterMethod(1, settings.defaultDataFilterMethod).ordinal());
PeakFit.addRelativeParameterOptions(gd, new RelativeParameterProvider(2.5, 4.5, "Smoothing_2", provider) {
@Override
void setAbsolute(boolean absolute) {
final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
final DataFilterMethod m = c.getDataFilterMethod(1, settings.defaultDataFilterMethod);
final double smooth = c.getDataFilterParameterValue(1, settings.defaultSmooth);
c.setDataFilter(m, smooth, absolute, 1);
}
@Override
boolean isAbsolute() {
return fitEngineConfigurationProvider.getFitEngineConfiguration().getDataFilterParameterAbsolute(1, false);
}
@Override
double getValue() {
return fitEngineConfigurationProvider.getFitEngineConfiguration().getDataFilterParameterValue(1, settings.defaultSmooth);
}
});
PeakFit.addSearchOptions(gd, provider);
PeakFit.addBorderOptions(gd, provider);
// Find if this image was created with ground truth data
if (imp.getID() == CreateData.getImageId()) {
final MemoryPeakResults results = CreateData.getResults();
if (results != null) {
gd.addSlider("Match_distance", 0, 2.5, settings.distance);
gd.addSlider("Lower_match_distance (%)", 0, 100, settings.lowerDistance);
gd.addCheckbox("Multiple_matches", settings.multipleMatches);
gd.addCheckbox("Show_TP", settings.showTP);
gd.addCheckbox("Show_FP", settings.showFP);
gd.addMessage("");
label = (Label) gd.getMessage();
final boolean integerCoords = false;
actualCoordinates = ResultsMatchCalculator.getCoordinates(results, integerCoords);
}
}
if (label == null) {
// If no ground truth data add options to show the spots by their rank
// and number of neighbours
gd.addSlider("Top_N", 0, 100, settings.topN);
topNScrollBar = gd.getLastScrollbar();
gd.addSlider("Select", 0, 100, settings.select);
selectScrollBar = gd.getLastScrollbar();
gd.addSlider("Neigbour_radius", 0, 10, settings.neighbourRadius);
}
ImageListener imageListener = null;
if (ImageJUtils.isShowGenericDialog()) {
// Listen for changes in the dialog options
gd.addOptionCollectedListener(event -> {
// Just run on the current processor
if (preview) {
run(imp.getProcessor());
}
});
// Listen for changes to an image
imageListener = new ImageAdapter() {
@Override
public void imageUpdated(ImagePlus imp) {
if (SpotFinderPreview.this.imp.getID() == imp.getID() && preview && imp.getCurrentSlice() != currentSlice && filter != null) {
run(imp.getProcessor(), filter);
}
}
};
ImagePlus.addImageListener(imageListener);
// Support template settings
final Vector<TextField> numerics = gd.getNumericFields();
final Vector<Choice> choices = gd.getChoices();
final Iterator<TextField> nu = numerics.iterator();
final Iterator<Choice> ch = choices.iterator();
final Choice textTemplate = ch.next();
textTemplate.removeItemListener(gd);
textTemplate.removeKeyListener(gd);
textTemplate.addItemListener(this::itemStateChanged);
textCameraModelName = ch.next();
textPsf = ch.next();
textDataFilterType = ch.next();
textDataFilterMethod = ch.next();
textSmooth = nu.next();
textDataFilterMethod2 = ch.next();
textSmooth2 = nu.next();
textSearch = nu.next();
textBorder = nu.next();
}
gd.addPreviewCheckbox(pfr);
gd.addDialogListener(this::dialogItemChanged);
gd.setOKLabel("Save");
gd.setCancelLabel("Close");
gd.showDialog();
if (imageListener != null) {
ImagePlus.removeImageListener(imageListener);
}
if (!gd.wasCanceled() && !SettingsManager.writeSettings(config, SettingsManager.FLAG_SILENT)) {
IJ.error(TITLE, "Failed to save settings");
}
// Reset
imp.setOverlay(overlay);
return DONE;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project gdsc-smlm by aherbert.
the class BenchmarkFilterAnalysis method showDialog.
private boolean showDialog(int optimiseParameters) {
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
final boolean showOptimiseFilter = (optimiseParameters & FLAG_OPTIMISE_FILTER) != 0;
final boolean showOptimiseParams = (optimiseParameters & FLAG_OPTIMISE_PARAMS) != 0;
final String helpKey = showOptimiseParams ? "benchmark-filter-parameters" : "benchmark-filter-analysis";
addSimulationData(gd);
// TODO - Make minimal filter configurable?
gd.addSlider("Fail_count", 0, 20, settings.failCount);
if (showOptimiseParams) {
gd.addNumericField("Min_fail_count", settings.minFailCount, 0);
gd.addNumericField("Max_fail_count", settings.maxFailCount, 0);
}
if (computeDoublets) {
gd.addSlider("Residuals_threshold", 0.01, 1, settings.residualsThreshold);
if (showOptimiseParams) {
gd.addNumericField("Min_residuals_threshold", settings.minResidualsThreshold, 2);
gd.addNumericField("Max_residuals_threshold", settings.maxResidualsThreshold, 2);
}
}
final FitEngineConfiguration tmp = FitEngineConfiguration.create();
tmp.setDuplicateDistance(settings.duplicateDistance);
tmp.setDuplicateDistanceAbsolute(settings.duplicateDistanceAbsolute);
PeakFit.addDuplicateDistanceOptions(gd, new PeakFit.SimpleFitEngineConfigurationProvider(tmp));
if (showOptimiseParams) {
gd.addNumericField("Min_duplicate_distance", settings.minDuplicateDistance, 2);
gd.addNumericField("Max_duplicate_distance", settings.maxDuplicateDistance, 2);
}
gd.addCheckbox("Reset", settings.reset);
gd.addCheckbox("Show_table", settings.showResultsTable);
gd.addCheckbox("Show_summary", settings.showSummaryTable);
gd.addCheckbox("Clear_tables", settings.clearTables);
gd.addSlider("Summary_top_n", 0, 20, settings.summaryTopN);
gd.addNumericField("Summary_depth (nm)", settings.summaryDepth, 0);
gd.addSlider("Plot_top_n", 0, 20, settings.plotTopN);
gd.addCheckbox("Save_best_filter", settings.saveBestFilter);
gd.addCheckbox("Save_template", settings.saveTemplate);
gd.addCheckbox("Calculate_sensitivity", settings.calculateSensitivity);
gd.addSlider("Delta", 0.01, 1, settings.delta);
gd.addMessage("Match scoring");
gd.addChoice("Criteria", Settings.COLUMNS, settings.criteriaIndex);
gd.addNumericField("Criteria_limit", settings.criteriaLimit, 4);
gd.addChoice("Score", Settings.COLUMNS, settings.scoreIndex);
ImageJUtils.addMessage(gd, "Fitting match distance = %s nm; signal factor = %s", MathUtils.rounded(spotFitResults.distanceInPixels * simulationParameters.pixelPitch), MathUtils.rounded(fitSignalFactor));
gd.addSlider("Upper_match_distance (%)", 0, 100, settings.upperMatchDistance);
gd.addSlider("Partial_match_distance (%)", 0, 100, settings.partialMatchDistance);
gd.addSlider("Upper_signal_factor (%)", 0, 100, settings.upperSignalFactor);
gd.addSlider("Partial_signal_factor (%)", 0, 100, settings.partialSignalFactor);
if (!simulationParameters.fixedDepth) {
gd.addCheckbox("Depth_recall_analysis", settings.depthRecallAnalysis);
}
gd.addCheckbox("Score_analysis", settings.scoreAnalysis);
gd.addChoice("Component_analysis", Settings.COMPONENT_ANALYSIS_OPTIONS, settings.componentAnalysis);
if (showOptimiseFilter) {
gd.addChoice("Evolve", Settings.EVOLVE_OPTIONS, settings.evolve);
gd.addCheckbox("Repeat_evolve", settings.repeatEvolve);
}
if (showOptimiseParams) {
gd.addChoice("Search", Settings.SEARCH_OPTIONS, settings.searchParam);
gd.addCheckbox("Repeat_search", settings.repeatSearch);
}
gd.addStringField("Title", settings.resultsTitle, 20);
final String[] labels = { "Show_TP", "Show_FP", "Show_FN" };
gd.addCheckboxGroup(1, 3, labels, new boolean[] { settings.showTP, settings.showFP, settings.showFN });
gd.addHelp(HelpUrls.getUrl(helpKey));
gd.showDialog();
if (gd.wasCanceled() || !readDialog(gd, optimiseParameters, tmp) || !selectTableColumns()) {
return false;
}
// We may have to read the results again if the ranking option has changed.
// Also we must read the results with the maximum duplicate distance we may encounter.
final double dd = settings.duplicateDistance;
if (showOptimiseParams) {
settings.duplicateDistance = settings.maxDuplicateDistance;
}
readResults();
settings.duplicateDistance = dd;
return true;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project gdsc-smlm by aherbert.
the class BenchmarkFilterAnalysis method readResults.
private MultiPathFitResults[] readResults() {
// Extract all the results in memory into a list per frame. This can be cached
boolean update = false;
Pair<Integer, CustomInt2ObjectOpenHashMap<UniqueIdPeakResult[]>> coords = COORDINATE_CACHE.get();
if (coords.getKey() != simulationParameters.id) {
coords = Pair.of(simulationParameters.id, getCoordinates(results));
COORDINATE_CACHE.set(coords);
update = true;
}
actualCoordinates = coords.getValue();
spotFitResults = BenchmarkSpotFit.getBenchmarkSpotFitResults();
FitResultData localFitResultData = FIT_RESULTS_DATA_CACHE.get();
final SettingsList scoreSettings = new SettingsList(settings.partialMatchDistance, settings.upperMatchDistance, settings.partialSignalFactor, settings.upperSignalFactor);
final boolean equalScoreSettings = scoreSettings.equals(localFitResultData.scoreSettings);
if (update || localFitResultData.fittingId != spotFitResults.id || !equalScoreSettings || localFitResultData.differentSettings(settings)) {
IJ.showStatus("Reading results ...");
if (localFitResultData.fittingId < 0) {
// Copy the settings from the fitter if this is the first run.
// This just starts the plugin with sensible settings.
// Q. Should this be per new simulation or fitting result instead?
final FitEngineConfiguration config = BenchmarkSpotFit.getFitEngineConfiguration();
settings.failCount = config.getFailuresLimit();
settings.duplicateDistance = config.getDuplicateDistance();
settings.duplicateDistanceAbsolute = config.getDuplicateDistanceAbsolute();
settings.residualsThreshold = (BenchmarkSpotFit.getComputeDoublets()) ? BenchmarkSpotFit.getMultiFilter().residualsThreshold : 1;
}
// This functionality is for choosing the optimum filter for the given scoring metric.
if (!equalScoreSettings) {
filterAnalysisResult.scores.clear();
}
localFitResultData = new FitResultData(spotFitResults.id, scoreSettings, settings);
// @formatter:off
// -=-=-=-
// The scoring is designed to find the best fitter+filter combination for the given spot
// candidates. The ideal combination would correctly fit+pick all the candidate positions
// that are close to a localisation.
//
// Use the following scoring scheme for all candidates:
//
// Candidates
// +----------------------------------------+
// | Actual matches |
// | +-----------+ TN |
// | | FN | |
// | | +---------- |
// | | | TP | | Fitted |
// | +-----------+ | spots |
// | | FP | |
// | +---------+ |
// +----------------------------------------+
//
// Candidates = All the spot candidates
// Actual matches = Any spot candidate or fitted spot candidate that matches a localisation
// Fitted spots = Any spot candidate that was successfully fitted
//
// TP = A spot candidate that was fitted and matches a localisation and is accepted
// FP = A spot candidate that was fitted but does not match a localisation and is accepted
// FN = A spot candidate that failed to be fitted but matches a localisation
// = A spot candidate that was fitted and matches a localisation and is rejected
// TN = A spot candidate that failed to be fitted and does not match a localisation
// = A spot candidate that was fitted and does not match a localisation and is rejected
//
// When fitting only produces one result it is possible to compute the TN score.
// Since unfitted candidates can only be TN or FN we could accumulate these scores and cache
// them. This was the old method of benchmarking single spot fitting and allowed more scores
// to be computed.
//
// When fitting produces multiple results then we have to score each fit result against all
// possible actual results and keep a record of the scores. These can then be assessed when
// the specific results have been chosen by result filtering.
//
// Using a distance ramped scoring function the degree of match can be varied from 0 to 1.
// Using a signal-factor ramped scoring function the degree of fitted can be varied from 0
// to 1. When using ramped scoring functions the fractional allocation of scores using the
// above scheme is performed, i.e. candidates are treated as if they both match and unmatch.
// This results in an equivalent to multiple analysis using different thresholds and averaging
// of the scores.
//
// The totals TP+FP+TN+FN must equal the number of spot candidates. This allows different
// fitting methods to be compared since the total number of candidates is the same.
//
// Precision = TP / (TP+FP) : This is always valid as a minimum criteria score
// Recall = TP / (TP+FN) : This is valid between different fitting methods since a
// method that fits more spots will have a potentially lower FN
// Jaccard = TP / (TP+FN+FP) : This is valid between fitting methods
//
// -=-=-=-
// As an alternative scoring system, different fitting methods can be compared using the same
// TP value but calculating FN = localisations - TP and FP as Positives - TP. This creates a
// score against the original number of simulated molecules using everything that was passed
// through the filter (Positives). This score is comparable when a different spot candidate
// filter has been used and the total number of candidates is different, e.g. Mean filtering
// vs. Gaussian filtering
// -=-=-=-
// @formatter:on
final RampedScore distanceScore = RampedScore.of(spotFitResults.distanceInPixels * settings.upperMatchDistance / 100.0, spotFitResults.distanceInPixels * settings.partialMatchDistance / 100.0, false);
localFitResultData.lowerDistanceInPixels = distanceScore.edge1;
localFitResultData.distanceInPixels = distanceScore.edge0;
final double matchDistance = MathUtils.pow2(localFitResultData.distanceInPixels);
localFitResultData.resultsPrefix3 = "\t" + MathUtils.rounded(distanceScore.edge1 * simulationParameters.pixelPitch) + "\t" + MathUtils.rounded(distanceScore.edge0 * simulationParameters.pixelPitch);
localFitResultData.limitRange = ", d=" + MathUtils.rounded(distanceScore.edge1 * simulationParameters.pixelPitch) + "-" + MathUtils.rounded(distanceScore.edge0 * simulationParameters.pixelPitch);
// Signal factor must be greater than 1
final RampedScore signalScore;
final double spotSignalFactor = BenchmarkSpotFit.getSignalFactor();
if (spotSignalFactor > 0 && settings.upperSignalFactor > 0) {
signalScore = RampedScore.of(spotSignalFactor * settings.upperSignalFactor / 100.0, spotSignalFactor * settings.partialSignalFactor / 100.0, false);
localFitResultData.lowerSignalFactor = signalScore.edge1;
localFitResultData.signalFactor = signalScore.edge0;
localFitResultData.resultsPrefix3 += "\t" + MathUtils.rounded(signalScore.edge1) + "\t" + MathUtils.rounded(signalScore.edge0);
localFitResultData.limitRange += ", s=" + MathUtils.rounded(signalScore.edge1) + "-" + MathUtils.rounded(signalScore.edge0);
} else {
signalScore = null;
localFitResultData.resultsPrefix3 += "\t0\t0";
localFitResultData.lowerSignalFactor = localFitResultData.signalFactor = 0;
}
// Store all the results
final ArrayList<MultiPathFitResults> multiPathFitResults = new ArrayList<>(spotFitResults.fitResults.size());
final List<MultiPathFitResults> syncResults = Collections.synchronizedList(multiPathFitResults);
// This could be multi-threaded ...
final int nThreads = getThreads(spotFitResults.fitResults.size());
final BlockingQueue<Job> jobs = new ArrayBlockingQueue<>(nThreads * 2);
final List<FitResultsWorker> workers = new LinkedList<>();
final List<Thread> threads = new LinkedList<>();
final AtomicInteger uniqueId = new AtomicInteger();
final CoordinateStore localCoordinateStore = createCoordinateStore();
final Ticker ticker = ImageJUtils.createTicker(spotFitResults.fitResults.size(), nThreads, null);
for (int i = 0; i < nThreads; i++) {
final FitResultsWorker worker = new FitResultsWorker(jobs, syncResults, matchDistance, distanceScore, signalScore, uniqueId, localCoordinateStore.newInstance(), ticker, actualCoordinates);
final Thread t = new Thread(worker);
workers.add(worker);
threads.add(t);
t.start();
}
spotFitResults.fitResults.int2ObjectEntrySet().forEach(e -> put(jobs, new Job(e.getIntKey(), e.getValue())));
// Finish all the worker threads by passing in a null job
for (int i = threads.size(); i-- != 0; ) {
put(jobs, new Job(0, null));
}
// Wait for all to finish
for (int i = 0; i < threads.size(); i++) {
try {
threads.get(i).join();
final FitResultsWorker worker = workers.get(i);
localFitResultData.matches += worker.matches;
localFitResultData.fittedResults += worker.included;
localFitResultData.totalResults += worker.total;
localFitResultData.notDuplicateCount += worker.notDuplicateCount;
localFitResultData.newResultCount += worker.newResultCount;
localFitResultData.countActual += worker.includedActual;
if (i == 0) {
localFitResultData.depthStats = worker.depthStats;
localFitResultData.depthFitStats = worker.depthFitStats;
localFitResultData.signalFactorStats = worker.signalFactorStats;
localFitResultData.distanceStats = worker.distanceStats;
} else {
localFitResultData.depthStats.add(worker.depthStats);
localFitResultData.depthFitStats.add(worker.depthFitStats);
localFitResultData.signalFactorStats.add(worker.signalFactorStats);
localFitResultData.distanceStats.add(worker.distanceStats);
}
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
throw new ConcurrentRuntimeException("Unexpected interrupt", ex);
}
}
threads.clear();
ImageJUtils.finished();
localFitResultData.maxUniqueId = uniqueId.get();
localFitResultData.resultsList = multiPathFitResults.toArray(new MultiPathFitResults[0]);
Arrays.sort(localFitResultData.resultsList, (o1, o2) -> Integer.compare(o1.getFrame(), o2.getFrame()));
MultiPathFilter.resetValidationFlag(localFitResultData.resultsList);
FIT_RESULTS_DATA_CACHE.set(localFitResultData);
}
fitResultData = localFitResultData;
return localFitResultData.resultsList;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project GDSC-SMLM by aherbert.
the class BenchmarkFit method showDialog.
private boolean showDialog() {
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
settings = Settings.load();
// Save back by reference
settings.save();
final double sa = getSa();
ImageJUtils.addMessage(gd, "Fits the benchmark image created by CreateData plugin.\nPSF width = %s, adjusted = %s", MathUtils.rounded(benchmarkParameters.sd / benchmarkParameters.pixelPitch), MathUtils.rounded(sa));
final FitEngineConfiguration config = SettingsManager.readFitEngineConfiguration(0);
fitConfig = config.getFitConfiguration();
fitConfig.setNmPerPixel(benchmarkParameters.pixelPitch);
// For each new benchmark width, reset the PSF width to the square pixel adjustment
if (settings.lastId != benchmarkParameters.id) {
settings.lastId = benchmarkParameters.id;
fitConfig.setInitialPeakStdDev(benchmarkParameters.sd / benchmarkParameters.pixelPitch);
// The adjusted width is only relevant when using a single point approximation
// for a Gaussian over the pixel. Using the ERF function computes the actual
// integral over the pixel.
// fitConfig.setInitialPeakStdDev(sa);
// Set the PSF. This requires the CreateData plugin to store the most appropriate
// PSF used for the simulation.
fitConfig.setPsf(benchmarkParameters.psf);
}
gd.addSlider("Region_size", 2, 20, settings.regionSize);
PeakFit.addPsfOptions(gd, fitConfig);
gd.addChoice("Fit_solver", SettingsManager.getFitSolverNames(), FitProtosHelper.getName(fitConfig.getFitSolver()));
gd.addChoice("Origin_XY", Settings.ORIGIN_XY, settings.originXY, new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer value) {
settings.originXY = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (settings.originXY != 2) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Origin XY");
egd.addNumericField("Offset_X", settings.offsetX, 2, 6, "nm");
egd.addNumericField("Offset_Y", settings.offsetY, 2, 6, "nm");
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
settings.offsetX = gd.getNextNumber();
settings.offsetY = gd.getNextNumber();
return true;
}
});
gd.addChoice("Origin_Z", Settings.ORIGIN_Z, settings.originZ, new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer value) {
settings.originZ = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (settings.originZ != 2) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Origin Z");
egd.addNumericField("Offset_Z", settings.offsetZ, 2, 6, "nm");
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
settings.offsetZ = gd.getNextNumber();
return true;
}
});
gd.addCheckbox("Zero_offset", settings.zeroOffset);
gd.addNumericField("Offset_points", settings.offsetPoints, 0, new OptionListener<Double>() {
@Override
public boolean collectOptions(Double value) {
settings.offsetPoints = Math.max(0, value);
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (settings.offsetPoints == 0) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Offset range");
egd.addSlider("Offset_range_x", 0, 2.5, settings.offsetRangeX);
egd.addSlider("Offset_range_y", 0, 2.5, settings.offsetRangeY);
egd.addSlider("Offset_range_z", 0, 2.5, settings.offsetRangeZ);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
settings.offsetRangeX = Math.max(0, egd.getNextNumber());
settings.offsetRangeY = Math.max(0, egd.getNextNumber());
settings.offsetRangeZ = Math.max(0, egd.getNextNumber());
return true;
}
});
gd.addCheckbox("Background_fitting", settings.backgroundFitting, new OptionListener<Boolean>() {
@Override
public boolean collectOptions(Boolean value) {
settings.backgroundFitting = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (!settings.backgroundFitting) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Background fitting");
egd.addCheckbox("Estimate_background", settings.estimateBackground);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
settings.estimateBackground = egd.getNextBoolean();
return true;
}
});
gd.addMessage("Signal fitting can be disabled for " + PsfProtosHelper.getName(PSFType.ONE_AXIS_GAUSSIAN_2D) + " function");
gd.addCheckbox("Signal_fitting", settings.signalFitting, new OptionListener<Boolean>() {
@Override
public boolean collectOptions(Boolean value) {
settings.signalFitting = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (!settings.signalFitting) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Signal fitting");
egd.addCheckbox("Estimate_signal", settings.estimateSignal);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
settings.estimateSignal = egd.getNextBoolean();
return true;
}
});
gd.addCheckbox("Show_histograms", settings.showHistograms);
gd.addCheckbox("Save_raw_data", settings.saveRawData);
gd.addHelp(HelpUrls.getUrl("fit-benchmark-data"));
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
settings.regionSize = (int) Math.abs(gd.getNextNumber());
fitConfig.setPsfType(PeakFit.getPsfTypeValues()[gd.getNextChoiceIndex()]);
// Some enum values are not supported
fitConfig.setFitSolver(SettingsManager.getFitSolverValues()[gd.getNextChoiceIndex()]);
settings.originXY = gd.getNextChoiceIndex();
settings.originZ = gd.getNextChoiceIndex();
settings.zeroOffset = gd.getNextBoolean();
settings.offsetPoints = Math.max(0, gd.getNextNumber());
settings.backgroundFitting = gd.getNextBoolean();
settings.signalFitting = gd.getNextBoolean();
settings.showHistograms = gd.getNextBoolean();
settings.saveRawData = gd.getNextBoolean();
gd.collectOptions();
// Do this before the call to is3D()
if (!PeakFit.configurePsfModel(config)) {
return false;
}
getStartPoints(fitConfig.is3D());
if (startPoints.length == 0) {
IJ.error(TITLE, "No initial fitting positions");
return false;
}
if (settings.regionSize < 1) {
settings.regionSize = 1;
}
if (gd.invalidNumber()) {
return false;
}
// Initialise the correct calibration
final CalibrationWriter calibration = new CalibrationWriter(fitConfig.getCalibration());
calibration.setNmPerPixel(benchmarkParameters.pixelPitch);
calibration.setCountPerPhoton(benchmarkParameters.gain);
calibration.setQuantumEfficiency(benchmarkParameters.qe);
calibration.setBias(benchmarkParameters.bias);
calibration.setCameraType(benchmarkParameters.cameraType);
calibration.setReadNoise(benchmarkParameters.readNoise);
calibration.setExposureTime(1000);
fitConfig.setCalibration(calibration.getCalibration());
fitConfig.setCameraModelName(benchmarkParameters.cameraModelName);
if (!PeakFit.configureFitSolver(config, IJImageSource.getBounds(imp), null, 0)) {
return false;
}
if (settings.showHistograms) {
final ExtendedGenericDialog gd2 = new ExtendedGenericDialog(TITLE);
gd2.addMessage("Select the histograms to display");
gd2.addNumericField("Histogram_bins", settings.histogramBins, 0);
final double[] convert = getConversionFactors();
for (int i = 0; i < DISPLAY_HISTOGRAMS.length; i++) {
if (convert[i] != 0) {
gd2.addCheckbox(NAMES[i].replace(' ', '_'), DISPLAY_HISTOGRAMS[i]);
}
}
gd2.showDialog();
if (gd2.wasCanceled()) {
return false;
}
settings.histogramBins = (int) Math.abs(gd2.getNextNumber());
for (int i = 0; i < DISPLAY_HISTOGRAMS.length; i++) {
if (convert[i] != 0) {
DISPLAY_HISTOGRAMS[i] = gd2.getNextBoolean();
}
}
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project GDSC-SMLM by aherbert.
the class BenchmarkSpotFilter method updateConfiguration.
/**
* Updates the given configuration using the latest settings used in benchmarking.
*
* @param config the configuration
* @return true, if successful
*/
public static boolean updateConfiguration(FitEngineConfiguration config) {
final BenchmarkSpotFilterResult result = FILTER_RESULT.get();
if (result == null) {
return false;
}
final FitEngineConfiguration latestConfig = result.config;
config.setDataFilterType(latestConfig.getDataFilterType());
final int nFilters = latestConfig.getNumberOfFilters();
for (int n = 0; n < nFilters; n++) {
final RelativeParameter p = latestConfig.getDataFilterParameter(n);
config.setDataFilter(latestConfig.getDataFilterMethod(n), p.getValue(), p.getAbsolute(), n);
}
config.setSearch(latestConfig.getSearch(), latestConfig.getSearchAbsolute());
config.setBorder(latestConfig.getBorder(), latestConfig.getBorderAbsolute());
return true;
}
Aggregations