use of uk.ac.sussex.gdsc.smlm.function.gaussian.HoltzerAstigmatismZModel in project GDSC-SMLM by aherbert.
the class CreateData method createPsfModel.
private PsfModel createPsfModel(List<LocalisationModelSet> localisationSets) {
// Allow reuse of the cached model
if (psfModelCache != null) {
return psfModelCache;
}
if (psfModelType == PSF_MODEL_IMAGE) {
return createImagePsf(localisationSets);
}
if (psfModelType == PSF_MODEL_ASTIGMATISM) {
astigmatismModel = AstigmatismModelManager.getModel(settings.getAstigmatismModel());
if (astigmatismModel == null) {
throw new IllegalArgumentException("Failed to load model: " + settings.getAstigmatismModel());
}
// Convert for simulation
try {
if (DoubleEquality.relativeError(astigmatismModel.getNmPerPixel(), settings.getPixelPitch()) > 1e-6) {
final String message = String.format("Astigmatism model '%s' calibration (%s nm) does not match pixel pitch (%s nm)", settings.getAstigmatismModel(), MathUtils.rounded(astigmatismModel.getNmPerPixel()), MathUtils.rounded(settings.getPixelPitch()));
// Optionally convert
final GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage(TextUtils.wrap(message + ". Created data is not suitable for fitting.", 80));
gd.addMessage(TextUtils.wrap("Click OK to continue anyway (i.e. draw the spot using the " + "correct nm width on the different sized pixels).", 80));
gd.showDialog();
if (gd.wasCanceled()) {
throw new IllegalArgumentException(message);
}
// Convert to nm
astigmatismModel = AstigmatismModelManager.convert(astigmatismModel, DistanceUnit.NM, DistanceUnit.NM);
// Reset pixel pitch. This will draw the spot using the correct size on the different size
// pixels.
astigmatismModel = astigmatismModel.toBuilder().setNmPerPixel(settings.getPixelPitch()).build();
}
// Convert for simulation in pixels
astigmatismModel = AstigmatismModelManager.convert(astigmatismModel, DistanceUnit.PIXEL, DistanceUnit.PIXEL);
return new GaussianPsfModel(AstigmatismModelManager.create(astigmatismModel));
} catch (final ConversionException ex) {
// Wrap so this can be caught as the same type
throw new IllegalArgumentException(ex);
}
}
final double d = settings.getDepthOfFocus() / settings.getPixelPitch();
if (psfModelType == PSF_MODEL_GAUSSIAN) {
final double sd = getPsfSd();
final double gamma = 0;
final HoltzerAstigmatismZModel zModel = HoltzerAstigmatismZModel.create(sd, sd, gamma, d, 0, 0, 0, 0);
final GaussianPsfModel m = new GaussianPsfModel(zModel);
// m.setRange(10);
return m;
}
// Default to Airy pattern
final double width = getPsfSd() / PsfCalculator.AIRY_TO_GAUSSIAN;
final AiryPsfModel m = new AiryPsfModel(width, width, d);
m.setRing(2);
return m;
}
use of uk.ac.sussex.gdsc.smlm.function.gaussian.HoltzerAstigmatismZModel in project GDSC-SMLM by aherbert.
the class FastMleJacobianGradient2ProcedureTest method gradientCalculatorComputesGradient.
@Override
@SeededTest
void gradientCalculatorComputesGradient(RandomSeed seed) {
gradientCalculatorComputesGradient(seed, 1, new SingleFreeCircularErfGaussian2DFunction(blockWidth, blockWidth));
gradientCalculatorComputesGradient(seed, 2, new MultiFreeCircularErfGaussian2DFunction(2, blockWidth, blockWidth));
// Use a reasonable z-depth function from the Smith, et al (2010) paper (page 377)
final double sx = 1.08;
final double sy = 1.01;
final double gamma = 0.389;
final double d = 0.531;
final double Ax = -0.0708;
final double Bx = -0.073;
final double Ay = 0.164;
final double By = 0.0417;
final HoltzerAstigmatismZModel zModel = HoltzerAstigmatismZModel.create(sx, sy, gamma, d, Ax, Bx, Ay, By);
gradientCalculatorComputesGradient(seed, 1, new SingleAstigmatismErfGaussian2DFunction(blockWidth, blockWidth, zModel));
}
use of uk.ac.sussex.gdsc.smlm.function.gaussian.HoltzerAstigmatismZModel in project GDSC-SMLM by aherbert.
the class FastMleGradient2ProcedureTest method gradientCalculatorComputesGradient.
@SeededTest
void gradientCalculatorComputesGradient(RandomSeed seed) {
gradientCalculatorComputesGradient(seed, new SingleFreeCircularErfGaussian2DFunction(blockWidth, blockWidth));
// Use a reasonable z-depth function from the Smith, et al (2010) paper (page 377)
final double sx = 1.08;
final double sy = 1.01;
final double gamma = 0.389;
final double d = 0.531;
final double Ax = -0.0708;
final double Bx = -0.073;
final double Ay = 0.164;
final double By = 0.0417;
final HoltzerAstigmatismZModel zModel = HoltzerAstigmatismZModel.create(sx, sy, gamma, d, Ax, Bx, Ay, By);
gradientCalculatorComputesGradient(seed, new SingleAstigmatismErfGaussian2DFunction(blockWidth, blockWidth, zModel));
}
use of uk.ac.sussex.gdsc.smlm.function.gaussian.HoltzerAstigmatismZModel in project GDSC-SMLM by aherbert.
the class AstigmatismModelManager method viewModel.
private void viewModel() {
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
final String[] models = listAstigmatismModels(false);
gd.addChoice("Model", models, pluginSettings.getSelected());
gd.addChoice("z_distance_unit", SettingsManager.getDistanceUnitNames(), pluginSettings.getZDistanceUnitValue());
gd.addChoice("s_distance_unit", SettingsManager.getDistanceUnitNames(), pluginSettings.getSDistanceUnitValue());
gd.addCheckbox("Show_depth_of_focus", pluginSettings.getShowDepthOfFocus());
gd.addCheckbox("Show_combined_width", pluginSettings.getShowCombinedWidth());
gd.addCheckbox("Show_PSF", pluginSettings.getShowPsf());
gd.addHelp(HelpUrls.getUrl("astigmatism-model-manager-view"));
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
final String name = gd.getNextChoice();
pluginSettings.setSelected(name);
pluginSettings.setZDistanceUnitValue(gd.getNextChoiceIndex());
pluginSettings.setSDistanceUnitValue(gd.getNextChoiceIndex());
pluginSettings.setShowDepthOfFocus(gd.getNextBoolean());
pluginSettings.setShowCombinedWidth(gd.getNextBoolean());
pluginSettings.setShowPsf(gd.getNextBoolean());
// Try and get the named resource
AstigmatismModel model = AstigmatismModelSettingsHolder.getSettings().getAstigmatismModelResourcesMap().get(name);
if (model == null) {
IJ.error(TITLE, "Failed to find astigmatism model: " + name);
return;
}
try {
model = convert(model, pluginSettings.getZDistanceUnit(), pluginSettings.getSDistanceUnit());
} catch (final ConversionException ex) {
ImageJUtils.log("Bad conversion (%s), defaulting to native model units", ex.getMessage());
}
ImageJUtils.log("Astigmatism model: %s\n%s", name, model);
// Plot the curve. Do this so we encompass twice the depth-of-field.
final double gamma = model.getGamma();
final double d = model.getD();
final double s0x = model.getS0X();
final double Ax = model.getAx();
final double Bx = model.getBx();
final double s0y = model.getS0Y();
final double Ay = model.getAy();
final double By = model.getBy();
final double range = Math.abs(gamma) + 1.5 * d;
final int n = 200;
final double step = range / n;
final double[] z = new double[2 * n + 1];
final double[] sx = new double[z.length];
final double[] sy = new double[z.length];
// Use the same class that is used during fitting
final HoltzerAstigmatismZModel m = HoltzerAstigmatismZModel.create(s0x, s0y, gamma, d, Ax, Bx, Ay, By);
for (int i = 0; i < z.length; i++) {
final double zz = -range + i * step;
z[i] = zz;
sx[i] = m.getSx(zz);
sy[i] = m.getSy(zz);
}
final String title = TITLE + " Width Curve";
final Plot plot = new Plot(title, "Z (" + UnitHelper.getShortName(model.getZDistanceUnit()) + ")", "Width (" + UnitHelper.getShortName(model.getSDistanceUnit()) + ")");
double[] limits = MathUtils.limits(sx);
limits = MathUtils.limits(limits, sy);
final double rangex = (z[z.length - 1] - z[0]) * 0.05;
final double rangey = (limits[1] - limits[0]) * 0.05;
final double miny = limits[0] - rangey;
final double maxy = limits[1] + rangey;
plot.setLimits(z[0] - rangex, z[z.length - 1] + rangex, miny, maxy);
plot.setColor(Color.RED);
plot.addPoints(z, sx, Plot.LINE);
plot.setColor(Color.BLUE);
plot.addPoints(z, sy, Plot.LINE);
plot.setColor(Color.YELLOW);
if (pluginSettings.getShowDepthOfFocus()) {
final double z0x = gamma;
final double z0y = -gamma;
plot.setColor(Color.RED.darker());
plot.drawDottedLine(z0x - d, miny, z0x - d, maxy, 4);
plot.drawDottedLine(z0x + d, miny, z0x + d, maxy, 4);
plot.setColor(Color.BLUE.darker());
plot.drawDottedLine(z0y - d, miny, z0y - d, maxy, 4);
plot.drawDottedLine(z0y + d, miny, z0y + d, maxy, 4);
}
String legend = "Sx\nSy";
if (pluginSettings.getShowCombinedWidth()) {
final double[] s = new double[z.length];
for (int i = 0; i < z.length; i++) {
s[i] = Gaussian2DPeakResultHelper.getStandardDeviation(sx[i], sy[i]);
}
plot.setColor(Color.GREEN);
plot.addPoints(z, s, Plot.LINE);
legend += "\tS";
}
plot.setColor(Color.BLACK);
plot.addLegend(legend);
plot.addLabel(0, 0, String.format("Model = %s (%s nm/pixel)", name, MathUtils.rounded(model.getNmPerPixel())));
ImageJUtils.display(title, plot);
if (!pluginSettings.getShowPsf()) {
return;
}
// Get pixel range using 3x[max SD]
final int width = 1 + 2 * ((int) Math.ceil(limits[1] * 3));
new ModelRenderer(name, model, m, range, width, plot).run();
}
Aggregations