use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter 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.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class PeakResultTableModelFrameDemo method main.
/**
* Launch the application.
*
* @param args the arguments
*/
public static void main(String[] args) {
final SplitMix r = SplitMix.new64(System.currentTimeMillis());
final int n = 20;
final ListSelectionModel selectionModel = new DefaultListSelectionModel();
EventQueue.invokeLater((Runnable) () -> {
try {
final PeakResultStoreList store = new ArrayPeakResultStore(10);
for (int i = n; i-- > 0; ) {
store.add(new PeakResult(r.nextInt(), r.nextInt(), r.nextInt(), r.nextFloat(), r.nextDouble(), r.nextFloat(), r.nextFloat(), PeakResult.createParams(r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat(), r.nextFloat()), null));
}
final CalibrationWriter cw = new CalibrationWriter();
cw.setNmPerPixel(100);
cw.setCountPerPhoton(10);
cw.setDistanceUnit(DistanceUnit.PIXEL);
cw.setIntensityUnit(IntensityUnit.COUNT);
final ResultsTableSettings.Builder tableSettings = ResultsTableSettings.newBuilder();
tableSettings.setDistanceUnit(DistanceUnit.NM);
tableSettings.setIntensityUnit(IntensityUnit.PHOTON);
tableSettings.setShowFittingData(true);
tableSettings.setShowNoiseData(true);
tableSettings.setShowPrecision(true);
tableSettings.setRoundingPrecision(4);
final PeakResultTableModel model = new PeakResultTableModel(store, cw.getCalibration(), null, tableSettings.build());
final PeakResultTableModelFrame d = new PeakResultTableModelFrame(model, null, selectionModel);
d.setTitle("D");
d.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
d.setVisible(true);
// Selecting in one list activates the other list
final PeakResultTableModelFrame d2 = new PeakResultTableModelFrame(model, null, selectionModel);
d2.setTitle("D2");
// Since we have the same selection model we need the same row sorter,
// otherwise the selection is scrambled by sorting.
// The alternative would be to get the source for the selection event (the table)
// and get the row sorter to do the mapping.
// However this breaks deletion of data as the row sorter double processes the deletion.
// Basically only one table can use the same selection model when sorting is desired.
// d2.table.setRowSorter(d.table.getRowSorter())
d2.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
d2.setVisible(true);
} catch (final Exception ex) {
ex.printStackTrace();
}
});
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class DoubletAnalysis method updateFitConfiguration.
private boolean updateFitConfiguration(FitEngineConfiguration config) {
// Do this first as it sets the initial SD
if (!BenchmarkSpotFit.updateConfiguration(config)) {
IJ.error(TITLE, "Unable to use the benchmark spot fit configuration");
return false;
}
final FitConfiguration fitConfig = config.getFitConfiguration();
final CalibrationWriter cal = new CalibrationWriter(fitConfig.getCalibration());
cal.setNmPerPixel(simulationParameters.pixelPitch);
cal.setCountPerPhoton(simulationParameters.gain);
cal.setQuantumEfficiency(simulationParameters.qe);
cal.setExposureTime(100);
cal.setReadNoise(simulationParameters.readNoise);
cal.setBias(simulationParameters.bias);
cal.setCameraType(simulationParameters.cameraType);
fitConfig.setCalibration(cal.getCalibration());
if (!BenchmarkSpotFilter.updateConfiguration(config)) {
IJ.error(TITLE, "Unable to use the benchmark spot filter configuration");
return false;
}
// Make sure all spots are fit
config.setFailuresLimit(-1);
// same as the filter analysis
if (BenchmarkFilterAnalysis.getDistanceInPixels() > 0) {
settings.matchDistance = BenchmarkFilterAnalysis.getDistanceInPixels();
settings.lowerDistance = BenchmarkFilterAnalysis.getLowerDistanceInPixels();
settings.signalFactor = BenchmarkFilterAnalysis.getSignalFactor();
settings.lowerSignalFactor = BenchmarkFilterAnalysis.getLowerSignalFactor();
} else {
// Use the fit analysis distance if no filter analysis has been run
settings.matchDistance = BenchmarkSpotFit.getDistanceInPixels();
settings.lowerDistance = BenchmarkSpotFit.getLowerDistanceInPixels();
settings.signalFactor = settings.lowerSignalFactor = BenchmarkSpotFit.getSignalFactor();
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class MalkFilePeakResults method begin.
@Override
public synchronized void begin() {
// Ensure we write out in nm and photons if possible.
if (hasCalibration()) {
// Copy it so it can be modified
final CalibrationWriter cw = new CalibrationWriter(getCalibration());
// Create converters
try {
toNmConverter = cw.getDistanceConverter(DistanceUnit.NM);
cw.setDistanceUnit(DistanceUnit.NM);
} catch (final ConversionException ex) {
// Gracefully fail so ignore this
}
try {
toPhotonConverter = cw.getIntensityConverter(IntensityUnit.PHOTON);
cw.setIntensityUnit(IntensityUnit.PHOTON);
} catch (final ConversionException ex) {
// Gracefully fail so ignore this
}
setCalibration(cw.getCalibration());
}
// The data loses PSF information so reset this to a custom type with
// no additional parameters.
setPsf(PsfHelper.create(PSFType.CUSTOM));
super.begin();
// Create converters to avoid null pointers
if (toNmConverter == null) {
toNmConverter = new IdentityTypeConverter<>(null);
}
if (toPhotonConverter == null) {
toPhotonConverter = new IdentityTypeConverter<>(null);
}
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class ResultsManager method checkCalibration.
/**
* Check the calibration of the results exists, if not then prompt for it with a dialog.
*
* <p>The calibration is rechecked after the dialog is shown.
*
* <p>Missing calibration is written to the Logger for the the class.
*
* @param results The results
* @param reader Used to determine the file type
* @return True if OK; false if calibration is missing
*/
private static boolean checkCalibration(MemoryPeakResults results, PeakResultsReader reader) {
// Check for Calibration
final String msg = (results.hasCalibration()) ? "partially calibrated" : "uncalibrated";
final CalibrationWriter calibration = results.getCalibrationWriterSafe();
final Settings settings = Settings.load();
boolean missing = isEssentialCalibrationMissing(calibration, settings);
if (missing) {
logger.info(() -> "Results are " + msg + ". Requesting input.");
final Rectangle2D.Float dataBounds = results.getDataBounds(null);
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
ImageJUtils.addMessage(gd, "Results are %s.\nData bounds = (%s,%s) to (%s,%s)", msg, MathUtils.rounded(dataBounds.x), MathUtils.rounded(dataBounds.y), MathUtils.rounded(dataBounds.y + dataBounds.getWidth()), MathUtils.rounded(dataBounds.x + dataBounds.getHeight()));
gd.addChoice("Calibration_distance_unit", SettingsManager.getDistanceUnitNames(), calibration.getDistanceUnitValue());
gd.addChoice("Calibration_intensity_unit", SettingsManager.getIntensityUnitNames(), calibration.getIntensityUnitValue());
gd.addNumericField("Calibration (nm/px)", calibration.getNmPerPixel(), 2);
gd.addNumericField("Exposure_time (ms)", calibration.getExposureTime(), 2);
PeakFit.addCameraOptions(gd, calibration);
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
calibration.setDistanceUnit(SettingsManager.getDistanceUnitValues()[gd.getNextChoiceIndex()]);
calibration.setIntensityUnit(SettingsManager.getIntensityUnitValues()[gd.getNextChoiceIndex()]);
calibration.setNmPerPixel(Math.abs(gd.getNextNumber()));
calibration.setExposureTime(Math.abs(gd.getNextNumber()));
calibration.setCameraType(SettingsManager.getCameraTypeValues()[gd.getNextChoiceIndex()]);
gd.collectOptions();
if (calibration.getCameraType() == CameraType.SCMOS) {
calibration.clearGlobalCameraSettings();
}
missing = isEssentialCalibrationMissing(calibration, settings);
// Save for next time ...
settings.inputNmPerPixel = calibration.getNmPerPixel();
settings.inputExposureTime = calibration.getExposureTime();
if (calibration.isCcdCamera()) {
settings.inputGain = calibration.getCountPerPhoton();
}
settings.save();
results.setCalibration(calibration.getCalibration());
}
// Only OK if nothing is missing
return !missing;
}
Aggregations