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);
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 (lastId != benchmarkParameters.id) {
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, regionSize);
PeakFit.addPsfOptions(gd, fitConfig);
gd.addChoice("Fit_solver", SettingsManager.getFitSolverNames(), FitProtosHelper.getName(fitConfig.getFitSolver()));
gd.addChoice("Origin_XY", ORIGIN_XY, originXY, new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer value) {
originXY = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (originXY != 2) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Origin XY");
egd.addNumericField("Offset_X", offsetX, 2, 6, "nm");
egd.addNumericField("Offset_Y", offsetY, 2, 6, "nm");
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
offsetX = gd.getNextNumber();
offsetY = gd.getNextNumber();
return true;
}
});
gd.addChoice("Origin_Z", ORIGIN_Z, originZ, new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer value) {
originZ = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (originZ != 2) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Origin Z");
egd.addNumericField("Offset_Z", offsetZ, 2, 6, "nm");
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
offsetZ = gd.getNextNumber();
return true;
}
});
gd.addCheckbox("Zero_offset", zeroOffset);
gd.addNumericField("Offset_points", offsetPoints, 0, new OptionListener<Double>() {
@Override
public boolean collectOptions(Double value) {
offsetPoints = Math.max(0, value);
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (offsetPoints == 0) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Offset range");
egd.addSlider("Offset_range_x", 0, 2.5, offsetRangeX);
egd.addSlider("Offset_range_y", 0, 2.5, offsetRangeY);
egd.addSlider("Offset_range_z", 0, 2.5, offsetRangeZ);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
offsetRangeX = Math.max(0, egd.getNextNumber());
offsetRangeY = Math.max(0, egd.getNextNumber());
offsetRangeZ = Math.max(0, egd.getNextNumber());
return true;
}
});
gd.addCheckbox("Background_fitting", backgroundFitting, new OptionListener<Boolean>() {
@Override
public boolean collectOptions(Boolean value) {
backgroundFitting = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (!backgroundFitting) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Background fitting");
egd.addCheckbox("Estimate_background", estimateBackground);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
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", signalFitting, new OptionListener<Boolean>() {
@Override
public boolean collectOptions(Boolean value) {
signalFitting = value;
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
if (!signalFitting) {
return false;
}
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Signal fitting");
egd.addCheckbox("Estimate_signal", estimateSignal);
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
estimateSignal = egd.getNextBoolean();
return true;
}
});
gd.addCheckbox("Show_histograms", showHistograms);
gd.addCheckbox("Save_raw_data", saveRawData);
gd.addHelp(HelpUrls.getUrl("fit-benchmark-data"));
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
regionSize = (int) Math.abs(gd.getNextNumber());
fitConfig.setPsfType(PeakFit.getPsfTypeValues()[gd.getNextChoiceIndex()]);
// Some enum values are not supported
fitConfig.setFitSolver(SettingsManager.getFitSolverValues()[gd.getNextChoiceIndex()]);
originXY = gd.getNextChoiceIndex();
originZ = gd.getNextChoiceIndex();
zeroOffset = gd.getNextBoolean();
offsetPoints = Math.max(0, gd.getNextNumber());
backgroundFitting = gd.getNextBoolean();
signalFitting = gd.getNextBoolean();
showHistograms = gd.getNextBoolean();
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 (regionSize < 1) {
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 (showHistograms) {
final ExtendedGenericDialog gd2 = new ExtendedGenericDialog(TITLE);
gd2.addMessage("Select the histograms to display");
gd2.addNumericField("Histogram_bins", histogramBins, 0);
final double[] convert = getConversionFactors();
for (int i = 0; i < displayHistograms.length; i++) {
if (convert[i] != 0) {
gd2.addCheckbox(NAMES[i].replace(' ', '_'), displayHistograms[i]);
}
}
gd2.showDialog();
if (gd2.wasCanceled()) {
return false;
}
histogramBins = (int) Math.abs(gd2.getNextNumber());
for (int i = 0; i < displayHistograms.length; i++) {
if (convert[i] != 0) {
displayHistograms[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 = filterResult.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;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project GDSC-SMLM by aherbert.
the class DoubletAnalysis method saveTemplate.
/**
* Save PeakFit configuration template using the current benchmark settings.
*
* @param summary the summary
*/
private void saveTemplate(String summary) {
if (!settings.saveTemplate) {
return;
}
// Start with a clone of the filter settings
final FitEngineConfiguration config = new FitEngineConfiguration();
final FitConfiguration fitConfig = config.getFitConfiguration();
fitConfig.setFitSettings(filterFitConfig.getFitSettings());
// Copy settings used during fitting
updateConfiguration(config);
// Remove the PSF width to make the template generic
fitConfig.setInitialPeakStdDev(0);
fitConfig.setNmPerPixel(0);
fitConfig.setGain(0);
fitConfig.setNoise(0);
// This was done fitting all the results
config.setFailuresLimit(-1);
if (settings.useBenchmarkSettings) {
final FitEngineConfiguration pConfig = new FitEngineConfiguration();
// TODO - add option to use latest or the best
if (BenchmarkFilterAnalysis.updateConfiguration(pConfig, false)) {
config.setFailuresLimit(pConfig.getFailuresLimit());
}
}
// Set the residuals
fitConfig.setComputeResiduals(true);
// TODO - make the choice of the best residuals configurable
config.setResidualsThreshold(residualsScore.bestResiduals[2]);
final String filename = BenchmarkFilterAnalysis.getFilename("Template_File", settings.templateFilename);
if (filename != null) {
settings.templateFilename = filename;
final TemplateSettings.Builder settings = TemplateSettings.newBuilder();
getNotes(settings, summary);
settings.setFitEngineSettings(config.getFitEngineSettings());
if (!SettingsManager.toJson(settings.build(), filename, SettingsManager.FLAG_SILENT)) {
IJ.log("Unable to save the template configuration");
}
}
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project GDSC-SMLM by aherbert.
the class PeakFit method configureDataFilter.
/**
* Show a dialog to configure the data filter. The data filter type and the first data filter must
* ALREADY be set in the configuration. The subsequent filters are then configured, e.g. for
* difference and jury filters.
*
* <p>The updated settings are saved to the settings file. An error message is shown if the dialog
* is cancelled or the configuration is invalid.
*
* <p>If the configuration is for a per-pixel camera type (e.g. sCMOS) then the camera model will
* be loaded using the configured camera model name. This will be used to validate the filter to
* check the filter supports the per-pixel camera type.
*
* @param config the config
* @param flags the flags
* @return True if the configuration succeeded
*/
public static boolean configureDataFilter(final FitEngineConfiguration config, int flags) {
int numberOfFilters = 1;
int filterCount;
switch(config.getDataFilterType()) {
case JURY:
filterCount = Integer.MAX_VALUE;
break;
case DIFFERENCE:
filterCount = 2;
break;
case SINGLE:
default:
filterCount = 1;
}
final String[] filterNames = SettingsManager.getDataFilterMethodNames();
final DataFilterMethod[] filterValues = SettingsManager.getDataFilterMethodValues();
// Check we have at least the first filter.
if (config.getDataFiltersCount() == 0) {
throw new IllegalStateException("No primary filter is configured");
}
final FitEngineConfigurationProvider fitEngineConfigurationProvider = () -> config;
for (int i = 1; i < filterCount; i++) {
final int filter = i + 1;
final int ii = i;
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
if (filter == filterCount) {
// This is maximum filter count so no continue option
ImageJUtils.addMessage(gd, "Configure the %s filter.", FitProtosHelper.getName(config.getDataFilterType()));
} else {
gd.enableYesNoCancel("Add", "Continue");
ImageJUtils.addMessage(gd, "Configure the %s filter.\nClick continue to proceed with the current set of %d.", FitProtosHelper.getName(config.getDataFilterType()), i);
}
final String fieldName = "Spot_filter" + filter;
if (IJ.isMacro()) {
// Use blank default value so bad macro parameters return nothing
gd.addStringField(fieldName, "");
} else {
gd.addChoice(fieldName, filterNames, filterNames[config.getDataFilterMethod(ii, config.getDataFilterMethod(ii - 1)).ordinal()]);
}
addRelativeParameterOptions(gd, new RelativeParameterProvider(0, 4.5, "Smoothing" + filter, fitEngineConfigurationProvider, true) {
@Override
void setAbsolute(boolean absolute) {
// Get the current settings
final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
final DataFilterMethod m = c.getDataFilterMethod(ii);
final double smooth = c.getDataFilterParameter(ii).getValue();
// Reset with the new absolute value
c.setDataFilter(m, smooth, absolute, ii);
}
@Override
boolean isAbsolute() {
final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
return c.getDataFilterParameterAbsolute(ii, c.getDataFilterParameterAbsolute(ii - 1));
}
@Override
double getValue() {
final FitEngineConfiguration c = fitEngineConfigurationProvider.getFitEngineConfiguration();
return c.getDataFilterParameterValue(ii, c.getDataFilterParameterValue(ii - 1));
}
});
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
if (gd.wasOKed()) {
int filterIndex = -1;
if (IJ.isMacro()) {
final String filterName = gd.getNextString();
for (int j = 0; j < filterNames.length; j++) {
if (filterNames[j].equals(filterName)) {
filterIndex = j;
break;
}
}
if (filterIndex < 0) {
break;
}
} else {
filterIndex = gd.getNextChoiceIndex();
}
// Note: The absolute flag is set in extra options
config.setDataFilter(filterValues[filterIndex], Math.abs(gd.getNextNumber()), i);
gd.collectOptions();
numberOfFilters++;
} else {
break;
}
}
config.setNumberOfFilters(numberOfFilters);
if (BitFlagUtils.anyNotSet(flags, FLAG_NO_SAVE)) {
saveFitEngineSettings(config);
}
final FitConfiguration fitConfig = config.getFitConfiguration();
final CalibrationReader calibration = fitConfig.getCalibrationReader();
if (calibration.isScmos()) {
fitConfig.setCameraModel(CameraModelManager.load(fitConfig.getCameraModelName()));
}
try {
config.createSpotFilter();
} catch (final IllegalStateException ex) {
IJ.error(TITLE, ex.getMessage());
return false;
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.engine.FitEngineConfiguration in project GDSC-SMLM by aherbert.
the class PeakFit method showSimpleDialog.
private int showSimpleDialog() {
// Just support circular fitting
fitConfig.setPsf(PsfProtosHelper.defaultOneAxisGaussian2DPSF);
fitConfig.setFixedPsf(false);
// TODO - Support sCMOS camera. This may be 'too difficult' as the
// user will need to have created a per-pixel calibration image
final CalibrationWriter calibration = fitConfig.getCalibrationWriter();
final boolean requireCalibration = requireCalibration(calibration);
if (requireCalibration && !showCalibrationWizard(calibration, true)) {
return DONE;
}
// Present dialog with simple output options: Image, Table
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addHelp(HelpUrls.getUrl("simple-fit"));
gd.addMessage("Fit single-molecule localisations");
if (!requireCalibration) {
gd.addCheckbox("Use_current_calibration", true);
}
gd.addCheckbox("Show_table", settings.showTable);
gd.addCheckbox("Show_image", settings.showImage);
gd.showDialog();
if (gd.wasCanceled()) {
return DONE;
}
boolean useCurrentCalibration = true;
if (!requireCalibration) {
useCurrentCalibration = gd.getNextBoolean();
}
settings.showTable = gd.getNextBoolean();
settings.showImage = gd.getNextBoolean();
if (!useCurrentCalibration && !showCalibrationWizard(calibration, false)) {
return DONE;
}
// Restore fitting to default settings but maintain the calibrated width
final double sd = fitConfig.getInitialXSd();
config = new FitEngineConfiguration();
fitConfig = config.getFitConfiguration();
fitConfig.setInitialPeakStdDev(sd);
// Allow to move 1 SD
fitConfig.setCoordinateShiftFactor(1);
resultsSettings = ResultsSettings.newBuilder();
// Do simple results output. We only need to set non-default values.
resultsSettings.getResultsInMemorySettingsBuilder().setInMemory(true);
if (settings.showTable) {
final ResultsTableSettings.Builder tableSettings = resultsSettings.getResultsTableSettingsBuilder();
tableSettings.setShowTable(true);
}
if (settings.showImage) {
final ResultsImageSettings.Builder imageSettings = resultsSettings.getResultsImageSettingsBuilder();
imageSettings.setImageType(ResultsImageType.DRAW_INTENSITY);
imageSettings.setScale(Math.ceil(1024.0 / Math.max(bounds.width, bounds.height)));
imageSettings.setWeighted(true);
imageSettings.setEqualised(true);
}
// Log the settings we care about:
IJ.log(LOG_SPACER);
IJ.log("Peak Fit");
IJ.log(LOG_SPACER);
ImageJUtils.log("Pixel pitch = %s", MathUtils.rounded(calibration.getNmPerPixel(), 4));
ImageJUtils.log("Exposure Time = %s", MathUtils.rounded(calibration.getExposureTime(), 4));
ImageJUtils.log("PSF width = %s", MathUtils.rounded(fitConfig.getInitialXSd(), 4));
// Save
fitConfig.setCalibration(calibration.getCalibration());
saveFitEngineSettings();
SettingsManager.writeSettings(resultsSettings.build());
return FLAGS;
}
Aggregations