use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method configureZFilter.
/**
* Show a dialog to configure the results z filter. The updated settings are saved to the settings
* file.
*
* <p>If the fit configuration PSF is not 3D or the simple filter is disabled then this method
* returns true. If it is enabled then a dialog is shown to input the configuration for the z
* filter.
*
* <p>Note: The PSF and any z-model must be correctly configured for fitting in pixel units.
*
* @param config the config
* @param flags the flags
* @return true, if successful
*/
public static boolean configureZFilter(FitEngineConfiguration config, int flags) {
final FitConfiguration fitConfig = config.getFitConfiguration();
if (fitConfig.isDisableSimpleFilter() || !fitConfig.is3D()) {
return true;
}
// Create a converter to map the model units in pixels to nm for the dialog.
// Note the output units of pixels may not yet be set in the calibration so we assume it is
// pixels.
final TypeConverter<DistanceUnit> c = UnitConverterUtils.createConverter(DistanceUnit.PIXEL, DistanceUnit.NM, fitConfig.getCalibrationReader().getNmPerPixel());
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("3D filter");
gd.addNumericField("Min_z", c.convert(fitConfig.getMinZ()), 0, 6, "nm");
gd.addNumericField("Max_z", c.convert(fitConfig.getMaxZ()), 0, 6, "nm");
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
final double minZ = gd.getNextNumber();
final double maxZ = gd.getNextNumber();
if (gd.invalidNumber() || minZ > maxZ) {
IJ.error(TITLE, "Min Z must be equal or below the max Z");
return false;
}
// Map back
fitConfig.setMinZ(c.convertBack(minZ));
fitConfig.setMaxZ(c.convertBack(maxZ));
if (BitFlagUtils.anyNotSet(flags, FLAG_NO_SAVE)) {
SettingsManager.writeSettings(config, 0);
}
return true;
}
use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method getGain.
private static boolean getGain(CalibrationWriter calibration) {
final ExtendedGenericDialog gd = newWizardDialog("Enter the bias and total gain.", "This is usually supplied with your camera certificate. The bias is a fixed offset added" + " to the camera counts. The gain indicates how many Analogue-to-Digital-Units (Count)" + " are recorded at the pixel for each photon registered on the sensor.", "The gain is usually expressed using the product of the EM-gain (if applicable), the" + " camera gain and the sensor quantum efficiency.", "A value of 1 means no conversion to photons will occur.");
// TODO - Add a wizard to allow calculation of total gain from EM-gain, camera gain and QE
gd.addNumericField("Camera_bias", calibration.getBias(), 2, 6, "Count");
gd.addNumericField("Gain", calibration.getCountPerPhoton(), 2, 6, "Count/photon");
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
calibration.setBias(Math.abs(gd.getNextNumber()));
calibration.setCountPerPhoton(Math.abs(gd.getNextNumber()));
return true;
}
use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method showCalibrationWizard.
private boolean showCalibrationWizard(CalibrationWriter calibration, boolean showIntroduction) {
if (showIntroduction) {
// Currently we do not support a sCMOS camera.
// If this is set then the settings must have been created in Peak Fit and not
// the calibration wizard.
final ArrayList<String> msgs = new ArrayList<>();
if (calibration.isScmos()) {
msgs.add("The configuration file specifies a sCMOS camera. " + "This is only supported in the Peak Fit plugin.");
msgs.add("Continuing with the wizard will overwrite the current cofiguration.");
msgs.add("Press Cancel to close the wizard. " + "You can then run Peak Fit with the current configuration.");
} else {
msgs.add("No configuration file could be loaded.");
msgs.add("Please follow the configuration wizard to calibrate.");
}
final ExtendedGenericDialog gd = newWizardDialog(msgs.toArray(new String[0]));
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
}
if (!getCameraType(calibration)) {
return false;
}
if (!getPixelPitch(calibration)) {
return false;
}
if (!getGain(calibration)) {
return false;
}
if (!getExposureTime(calibration)) {
return false;
}
if (!getPeakWidth(calibration)) {
return false;
}
// Check parameters
try {
ParameterUtils.isAboveZero("nm per pixel", calibration.getNmPerPixel());
// We allow bias to be zero
ParameterUtils.isAboveZero("Gain", calibration.getCountPerPhoton());
ParameterUtils.isAboveZero("Exposure time", calibration.getExposureTime());
ParameterUtils.isAboveZero("Initial SD", fitConfig.getInitialXSd());
} catch (final IllegalArgumentException ex) {
IJ.error(TITLE, ex.getMessage());
return false;
}
return true;
}
use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method getPeakWidth.
private boolean getPeakWidth(final CalibrationWriter calibration) {
final ExtendedGenericDialog gd = newWizardDialog("Enter the expected peak width in pixels.", "A point source of light will not be focussed perfectly by the microscope but will appear" + " as a spread out peak. This Point Spread Function (PSF) can be modelled using a" + " 2D Gaussian curve.", "An optimised optical system (lens and camera sensor) should have a peak standard" + " deviation of approximately 1 pixel when in focus. This allows the fitting routine" + " to have enough data to identify the centre of the peak without spreading the light" + " over too many pixels (which increases noise).", "The peak width can be estimated using the wavelength of light emitted by the single" + " molecules and the parameters of the microscope. Use a PSF calculator by clicking" + " the checkbox below:");
gd.addNumericField("Gaussian_SD", fitConfig.getInitialXSd(), 3);
// Add ability to run the PSF Calculator to get the width
if (ImageJUtils.isShowGenericDialog()) {
final TextField textInitialPeakStdDev0 = (TextField) gd.getNumericFields().get(0);
gd.addAndGetButton("Run PSF calculator", event -> {
// Run the PSF Calculator
calculatorSettings = calculatorSettings.toBuilder().setPixelPitch(calibration.getNmPerPixel() / 1000.0).setMagnification(1).setBeamExpander(1).build();
final double sd = new PsfCalculator().calculate(calculatorSettings, true);
if (sd > 0) {
textInitialPeakStdDev0.setText(Double.toString(sd));
}
});
}
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
fitConfig.setInitialPeakStdDev(Math.abs(gd.getNextNumber()));
return true;
}
use of uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog in project GDSC-SMLM by aherbert.
the class PeakFit method readDialog.
private boolean readDialog(ExtendedGenericDialog gd, boolean isCrop) {
// Ignore the template
gd.getNextChoice();
final CalibrationWriter calibration = fitConfig.getCalibrationWriter();
calibration.setCameraType(SettingsManager.getCameraTypeValues()[gd.getNextChoiceIndex()]);
calibration.setNmPerPixel(Math.abs(gd.getNextNumber()));
calibration.setExposureTime(Math.abs(gd.getNextNumber()));
fitConfig.setCalibration(calibration.getCalibration());
// The simple fix is to create a plugin to allow the configuration to be changed for results.
if (isCrop) {
ignoreBoundsForNoise = extraSettings.optionIgnoreBoundsForNoise = gd.getNextBoolean();
}
fitConfig.setPsfType(PeakFit.getPsfTypeValues()[gd.getNextChoiceIndex()]);
config.setDataFilterType(gd.getNextChoiceIndex());
// Note: The absolute flag is set in extra options
config.setDataFilter(gd.getNextChoiceIndex(), Math.abs(gd.getNextNumber()), 0);
config.setSearch(gd.getNextNumber());
config.setBorder(gd.getNextNumber());
config.setFitting(gd.getNextNumber());
if (extraOptions && !fitMaxima) {
extraSettings.interlacedData = gd.getNextBoolean();
extraSettings.integrateFrames = (int) gd.getNextNumber();
}
if (!maximaIdentification) {
// Some enum values are not supported
fitConfig.setFitSolver(SettingsManager.getFitSolverValues()[gd.getNextChoiceIndex()]);
if (extraOptions) {
fitConfig.setBackgroundFitting(gd.getNextBoolean());
}
config.setFailuresLimit((int) gd.getNextNumber());
config.setPassRate(gd.getNextNumber());
config.setIncludeNeighbours(gd.getNextBoolean());
config.setNeighbourHeightThreshold(gd.getNextNumber());
config.setResidualsThreshold(gd.getNextNumber());
config.setDuplicateDistance(gd.getNextNumber());
fitConfig.setSmartFilter(gd.getNextBoolean());
fitConfig.setDisableSimpleFilter(gd.getNextBoolean());
fitConfig.setCoordinateShiftFactor(gd.getNextNumber());
fitConfig.setSignalStrength(gd.getNextNumber());
fitConfig.setMinPhotons(gd.getNextNumber());
if (extraOptions) {
fitConfig.setNoise(gd.getNextNumber());
config.setNoiseMethod(gd.getNextChoiceIndex());
}
fitConfig.setMinWidthFactor(gd.getNextNumber());
fitConfig.setMaxWidthFactor(gd.getNextNumber());
fitConfig.setPrecisionThreshold(gd.getNextNumber());
}
resultsSettings.setLogProgress(gd.getNextBoolean());
if (!maximaIdentification) {
resultsSettings.setShowDeviations(gd.getNextBoolean());
}
resultsSettings.getResultsTableSettingsBuilder().setShowTable(gd.getNextBoolean());
resultsSettings.getResultsImageSettingsBuilder().setImageTypeValue(gd.getNextChoiceIndex());
if (extraOptions) {
extraSettings.showProcessedFrames = gd.getNextBoolean();
}
resultsSettings.getResultsFileSettingsBuilder().setFileFormatValue(gd.getNextChoiceIndex());
resultsSettings.getResultsFileSettingsBuilder().setResultsDirectory(gd.getNextString());
resultsSettings.getResultsInMemorySettingsBuilder().setInMemory(gd.getNextBoolean());
if (extraOptions) {
settings.fractionOfThreads = Math.abs(gd.getNextNumber());
}
gd.collectOptions();
// Save to allow dialog state to be maintained even with invalid parameters
saveFitEngineSettings();
SettingsManager.writeSettings(resultsSettings.build());
if (gd.invalidNumber()) {
return false;
}
// Check arguments
try {
// No check on camera calibration. This is left to the FitConfiguration to
// error if the settings are incorrect
ParameterUtils.isAboveZero("nm per pixel", calibration.getNmPerPixel());
ParameterUtils.isAboveZero("Exposure time", calibration.getExposureTime());
if (fitConfig.getPsfTypeValue() != PSFType.ASTIGMATIC_GAUSSIAN_2D_VALUE) {
ParameterUtils.isAboveZero("Initial SD0", fitConfig.getInitialXSd());
if (fitConfig.getPsf().getParametersCount() > 1) {
ParameterUtils.isAboveZero("Initial SD1", fitConfig.getInitialYSd());
}
}
ParameterUtils.isAboveZero("Search_width", config.getSearch());
ParameterUtils.isAboveZero("Fitting_width", config.getFitting());
if (extraOptions && !fitMaxima) {
ParameterUtils.isPositive("Integrate frames", extraSettings.integrateFrames);
}
if (!maximaIdentification) {
// This can be negative to disable, i.e. fit everything
// Parameters.isPositive("Failures limit", config.getFailuresLimit())
ParameterUtils.isPositive("Neighbour height threshold", config.getNeighbourHeightThreshold());
ParameterUtils.isPositive("Residuals threshold", config.getResidualsThreshold());
ParameterUtils.isPositive("Duplicate distance", config.getDuplicateDistance());
if (!fitConfig.isDisableSimpleFilter()) {
ParameterUtils.isPositive("Coordinate Shift factor", fitConfig.getCoordinateShiftFactor());
ParameterUtils.isPositive("Signal strength", fitConfig.getSignalStrength());
ParameterUtils.isPositive("Min photons", fitConfig.getMinPhotons());
}
if (extraOptions) {
ParameterUtils.isPositive("Noise", fitConfig.getNoise());
}
if (!fitConfig.isDisableSimpleFilter()) {
ParameterUtils.isPositive("Min width factor", fitConfig.getMinWidthFactor());
ParameterUtils.isPositive("Width factor", fitConfig.getMaxWidthFactor());
ParameterUtils.isPositive("Precision threshold", fitConfig.getPrecisionThreshold());
if (fitConfig.getPrecisionThreshold() > 0) {
if (fitConfig.getPrecisionMethod() == PrecisionMethod.PRECISION_METHOD_NA) {
throw new IllegalArgumentException("Precision filter requires a precision method");
}
if (fitConfig.isPrecisionUsingBackground() && calibration.isCcdCamera() && (calibration.getBias() == 0 || !calibration.hasCountPerPhoton())) {
throw new IllegalArgumentException("Precision using the local background requires the camera bias");
}
}
}
}
final ResultsImageSettings.Builder imageSettings = resultsSettings.getResultsImageSettingsBuilder();
if (imageSettings.getImageType() == ResultsImageType.DRAW_INTENSITY_AVERAGE_PRECISION || imageSettings.getImageType() == ResultsImageType.DRAW_LOCALISATIONS_AVERAGE_PRECISION) {
ParameterUtils.isAboveZero("Image precision", imageSettings.getAveragePrecision());
}
ParameterUtils.isAboveZero("Image scale", imageSettings.getScale());
if (extraOptions) {
ParameterUtils.isPositive("Image rolling window", imageSettings.getRollingWindowSize());
}
} catch (final IllegalArgumentException ex) {
IJ.error(TITLE, ex.getMessage());
return false;
}
final int flags = (extraOptions) ? FLAG_EXTRA_OPTIONS : 0;
// If precision filtering then we need the camera bias
if (!maximaIdentification) {
if (!configurePsfModel(config, flags)) {
return false;
}
if (!configureResultsFilter(config, flags)) {
return false;
}
}
if (!configureDataFilter(config, flags)) {
return false;
}
// Second dialog for solver dependent parameters
if (!maximaIdentification && !configureFitSolver(config, source.getBounds(), bounds, flags)) {
return false;
}
// Extra parameters are needed for interlaced data
if (extraSettings.interlacedData) {
gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Interlaced data requires a repeating pattern of frames to process.\n" + "Describe the regular repeat of the data:\n \n" + "Start = The first frame that contains data\n" + "Block = The number of continuous frames containing data\n" + "Skip = The number of continuous frames to ignore before the next data\n \n" + "E.G. 2:9:1 = Data was imaged from frame 2 for 9 frames, 1 frame to ignore," + " then repeat.");
gd.addNumericField("Start", extraSettings.dataStart, 0);
gd.addNumericField("Block", extraSettings.dataBlock, 0);
gd.addNumericField("Skip", extraSettings.dataSkip, 0);
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
if (!gd.wasCanceled()) {
extraSettings.dataStart = (int) gd.getNextNumber();
extraSettings.dataBlock = (int) gd.getNextNumber();
extraSettings.dataSkip = (int) gd.getNextNumber();
if (extraSettings.dataStart > 0 && extraSettings.dataBlock > 0 && extraSettings.dataSkip > 0) {
// Store options for next time
extraSettings.save();
}
} else {
extraSettings.interlacedData = false;
}
}
final boolean result = saveFitEngineSettings();
if (!result) {
IJ.error(TITLE, "Failed to save settings");
}
return result;
}
Aggregations