use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class CreateData method showSimulationParametersDialog.
private SimulationParameters showSimulationParametersDialog(ImagePlus imp, MemoryPeakResults results) {
final int molecules = results.size();
// Get the missing parameters from the user
boolean fullSimulation = false;
double sd = -1;
if (!results.convertToPreferredUnits()) {
IJ.error(TITLE, String.format("Results should be in the preferred units (%s,%s)", UnitHelper.getName(MemoryPeakResults.PREFERRED_DISTANCE_UNIT), UnitHelper.getName(MemoryPeakResults.PREFERRED_INTENSITY_UNIT)));
return null;
}
// Get these from the data
final RawResultProcedure sp = new RawResultProcedure(results);
sp.getBixyz();
final float[] signal = sp.intensity;
float[] limits = MathUtils.limits(signal);
final double minSignal = limits[0];
final double maxSignal = limits[1];
final double signalPerFrame = MathUtils.sum(signal) / molecules;
final float[] depths = sp.z;
limits = MathUtils.limits(depths);
float depth = Math.max(Math.abs(limits[0]), Math.abs(limits[1]));
final boolean fixedDepth = Double.compare(limits[0], limits[1]) == 0;
final CalibrationWriter cal = results.getCalibrationWriter();
final String iUnits = " " + UnitHelper.getName(cal.getIntensityUnit());
final String zUnits = " " + UnitHelper.getName(cal.getDistanceUnit());
// Get this from the user
double background = -1;
// Use last simulation parameters for missing settings.
// This is good if we are re-running the plugin to load data.
Rectangle lastCameraBounds = null;
if (simulationParameters != null && simulationParameters.isLoaded()) {
fullSimulation = simulationParameters.fullSimulation;
sd = simulationParameters.sd;
background = simulationParameters.background;
if (!cal.hasBias()) {
cal.setBias(simulationParameters.bias);
}
if (!cal.hasCountPerPhoton()) {
cal.setCountPerPhoton(simulationParameters.gain);
}
if (!cal.hasQuantumEfficiency()) {
cal.setQuantumEfficiency(simulationParameters.qe);
}
if (!cal.hasReadNoise()) {
cal.setReadNoise(simulationParameters.readNoise);
}
if (!cal.hasCameraType()) {
cal.setCameraType(simulationParameters.cameraType);
}
if (!cal.hasNmPerPixel()) {
cal.setNmPerPixel(simulationParameters.pixelPitch);
}
if (!cal.hasCameraModelName()) {
cal.setCameraModelName(simulationParameters.cameraModelName);
}
lastCameraBounds = simulationParameters.cameraBounds;
}
// Show a dialog to confirm settings
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
final StringBuilder sb = new StringBuilder();
sb.append("Results contain ").append(TextUtils.pleural(molecules, "molecule")).append('\n');
sb.append("Min signal = ").append(MathUtils.rounded(minSignal)).append(iUnits).append('\n');
sb.append("Max signal = ").append(MathUtils.rounded(maxSignal)).append(iUnits).append('\n');
sb.append("Av signal = ").append(MathUtils.rounded(signalPerFrame)).append(iUnits).append('\n');
if (fixedDepth) {
sb.append("Fixed depth = ").append(MathUtils.rounded(depth)).append(zUnits).append('\n');
}
gd.addMessage(sb.toString());
gd.addCheckbox("Flourophore_simulation", fullSimulation);
gd.addNumericField("Gaussian_SD", sd, 3, 8, "nm");
gd.addNumericField("Pixel_pitch", cal.getNmPerPixel(), 3, 8, "nm");
gd.addNumericField("Background", background, 3, 8, "photon");
// Camera type does not need the full simulation settings. Plus the units are different
// so just re-implement.
gd.addChoice("Camera_type", SettingsManager.getCameraTypeNames(), CalibrationProtosHelper.getName(cal.getCameraType()), new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer field) {
cal.setCameraType(SettingsManager.getCameraTypeValues()[field]);
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
final CameraType cameraType = cal.getCameraType();
final boolean isCcd = CalibrationProtosHelper.isCcdCameraType(cameraType);
final ExtendedGenericDialog egd = new ExtendedGenericDialog(TITLE, null);
if (isCcd) {
egd.addNumericField("Total_gain", cal.getCountPerPhoton(), 3, 8, "count/photon");
egd.addNumericField("Quantum_efficiency", cal.getQuantumEfficiency(), 3, 8, "e-/photon");
egd.addNumericField("Read_noise", cal.getReadNoise(), 3, 8, "count");
egd.addNumericField("Bias", cal.getBias(), 3, 8, "count");
} else if (cameraType == CameraType.SCMOS) {
final String[] models = CameraModelManager.listCameraModels(true);
egd.addChoice("Camera_model_name", models, cal.getCameraModelName());
egd.addNumericField("Quantum_efficiency", cal.getQuantumEfficiency(), 2, 6, "electron/photon");
} else {
IJ.error("Unsupported camera type " + CalibrationProtosHelper.getName(cameraType));
return false;
}
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
if (isCcd) {
cal.setCountPerPhoton(egd.getNextNumber());
cal.setQuantumEfficiency(egd.getNextNumber());
cal.setReadNoise(egd.getNextNumber());
cal.setBias(egd.getNextNumber());
} else if (cameraType == CameraType.SCMOS) {
cal.setCameraModelName(egd.getNextChoice());
cal.setQuantumEfficiency(Math.abs(egd.getNextNumber()));
}
return true;
}
});
if (!fixedDepth) {
gd.addNumericField("Depth", depth, 3, 8, "pixel");
}
gd.addHelp(HelpUrls.getUrl("load-benchmark-data"));
gd.showDialog();
if (gd.wasCanceled()) {
return null;
}
fullSimulation = gd.getNextBoolean();
sd = gd.getNextNumber();
cal.setNmPerPixel(gd.getNextNumber());
background = gd.getNextNumber();
cal.setCameraType(SettingsManager.getCameraTypeValues()[gd.getNextChoiceIndex()]);
float myDepth = depth;
if (!fixedDepth) {
myDepth = (float) gd.getNextNumber();
if (myDepth < depth) {
IJ.error(TITLE, String.format("Input depth is smaller than the depth guessed from the data: %f < %f", myDepth, depth));
return null;
}
depth = myDepth;
}
gd.collectOptions();
// Validate settings
Rectangle modelBounds = null;
try {
ParameterUtils.isAboveZero("Gaussian SD", sd);
ParameterUtils.isAboveZero("Pixel pitch", cal.getNmPerPixel());
ParameterUtils.isPositive("Background", background);
ParameterUtils.isAboveZero("Quantum efficiency", cal.getQuantumEfficiency());
ParameterUtils.isEqualOrBelow("Quantum efficiency", cal.getQuantumEfficiency(), 1);
if (cal.isCcdCamera()) {
ParameterUtils.isAboveZero("Total gain", cal.getCountPerPhoton());
ParameterUtils.isPositive("Read noise", cal.getReadNoise());
ParameterUtils.isPositive("Bias", cal.getBias());
} else if (cal.isScmos()) {
// Load the model
cameraModel = CameraModelManager.load(cal.getCameraModelName());
if (cameraModel == null) {
IJ.error(TITLE, "Unknown camera model for name: " + cal.getCameraModelName());
return null;
}
int ox = 0;
int oy = 0;
if (lastCameraBounds != null) {
ox = lastCameraBounds.x;
oy = lastCameraBounds.y;
}
cameraModel = PeakFit.cropCameraModel(cameraModel, new Rectangle(ox, oy, imp.getWidth(), imp.getHeight()), null, false);
modelBounds = cameraModel.getBounds();
final IJImageSource imageSource = (IJImageSource) results.getSource();
imageSource.setOrigin(modelBounds.x, modelBounds.y);
cal.clearGlobalCameraSettings();
} else {
IJ.error(TITLE, "Unknown camera type: " + cal.getCameraType());
return null;
}
} catch (final IllegalArgumentException ex) {
IJ.error(TITLE, ex.getMessage());
return null;
}
// Store calibration
results.setCalibration(cal.getCalibration());
final double a = cal.getNmPerPixel();
final double bias = cal.getBias();
final double gain = cal.getCountPerPhoton();
final double readNoise = cal.getReadNoise();
final double qe = cal.getQuantumEfficiency();
// Note: The calibration will throw an exception if the converter cannot be created.
// This is OK as the data will be invalid.
// Convert +/- depth to total depth in nm
depth = cal.getDistanceConverter(DistanceUnit.NM).convert(depth * 2);
// Compute total background variance in photons
final double backgroundVariance = background;
// Do not add EM-CCD noise factor. The Mortensen formula also includes this factor
// so this is "double-counting" the EM-CCD.
// if (emCCD)
// backgroundVariance *= 2;
// Read noise is in ADUs. Convert to Photons to get contribution to background variance
final double readNoiseInPhotons = readNoise / gain;
// Get the expected value at each pixel in photons. Assuming a Poisson distribution this
// is equal to the total variance at the pixel.
final double b2 = backgroundVariance + readNoiseInPhotons * readNoiseInPhotons;
// Convert values to photons
final TypeConverter<IntensityUnit> ic = cal.getIntensityConverter(IntensityUnit.PHOTON);
final SimulationParameters p = new SimulationParameters(molecules, fullSimulation, sd, a, ic.convert(minSignal), ic.convert(maxSignal), ic.convert(signalPerFrame), depth, fixedDepth, bias, gain, qe, readNoise, cal.getCameraType(), cal.getCameraModelName(), modelBounds, background, b2, createPsf(sd / a));
p.loaded = true;
return p;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class DoubletAnalysis method showDialog.
/**
* Show dialog.
*
* @return true, if successful
*/
private boolean showDialog() {
ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
final String helpKey = "doublet-analysis";
settings = Settings.load();
config = configRef.get().createCopy();
final FitConfiguration fitConfig = config.getFitConfiguration();
final double sa = getSa();
ImageJUtils.addMessage(gd, "Fits the benchmark image created by CreateData plugin.\nPSF width = %s, adjusted = %s", MathUtils.rounded(simulationParameters.sd / simulationParameters.pixelPitch), MathUtils.rounded(sa));
// For each new benchmark width, reset the PSF width to the square pixel adjustment
if (lastId.get() != simulationParameters.id) {
final double w = sa;
settings.matchDistance = w * Gaussian2DFunction.SD_TO_HWHM_FACTOR;
settings.lowerDistance = 0.5 * settings.matchDistance;
fitConfig.setInitialPeakStdDev(w);
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.setCameraModel(CreateData.getCameraModel(simulationParameters));
fitConfig.setCalibration(cal.getCalibration());
}
// Support for using templates
final String[] templates = ConfigurationTemplate.getTemplateNames(true);
gd.addChoice("Template", templates, templates[0]);
// Allow the settings from the benchmark analysis to be used
gd.addCheckbox("Benchmark_settings", settings.useBenchmarkSettings);
// Collect options for fitting
PeakFit.addPsfOptions(gd, fitConfig);
final PeakFit.SimpleFitEngineConfigurationProvider provider = new PeakFit.SimpleFitEngineConfigurationProvider(config);
PeakFit.addDataFilterOptions(gd, provider);
PeakFit.addSearchOptions(gd, provider);
PeakFit.addBorderOptions(gd, provider);
PeakFit.addFittingOptions(gd, provider);
gd.addChoice("Fit_solver", SettingsManager.getFitSolverNames(), fitConfig.getFitSolver().ordinal());
gd.addSlider("Iteration_increase", 1, 4.5, settings.iterationIncrease);
gd.addCheckbox("Ignore_with_neighbours", settings.ignoreWithNeighbours);
gd.addCheckbox("Show_overlay", settings.showOverlay);
gd.addCheckbox("Show_histograms", settings.showHistograms);
gd.addCheckbox("Show_results", settings.showResults);
gd.addCheckbox("Show_Jaccard_Plot", settings.showJaccardPlot);
gd.addCheckbox("Use_max_residuals", settings.useMaxResiduals);
gd.addNumericField("Match_distance", settings.matchDistance, 2);
gd.addNumericField("Lower_distance", settings.lowerDistance, 2);
gd.addNumericField("Signal_factor", settings.signalFactor, 2);
gd.addNumericField("Lower_factor", settings.lowerSignalFactor, 2);
gd.addChoice("Matching", Settings.MATCHING_METHODS, settings.matchingMethod);
// Add a mouse listener to the config file field
if (ImageJUtils.isShowGenericDialog()) {
final Vector<TextField> numerics = gd.getNumericFields();
final Vector<Choice> choices = gd.getChoices();
final Iterator<TextField> nu = numerics.iterator();
final Iterator<Choice> ch = choices.iterator();
ch.next().addItemListener(this);
final Checkbox b = (Checkbox) gd.getCheckboxes().get(0);
b.addItemListener(this);
textPsf = ch.next();
textDataFilterType = ch.next();
textDataFilter = ch.next();
textSmooth = nu.next();
textSearch = nu.next();
textBorder = nu.next();
textFitting = nu.next();
textFitSolver = ch.next();
// Iteration increase
nu.next();
textMatchDistance = nu.next();
textLowerDistance = nu.next();
textSignalFactor = nu.next();
textLowerFactor = nu.next();
}
gd.addHelp(HelpUrls.getUrl(helpKey));
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
// Ignore the template
gd.getNextChoice();
settings.useBenchmarkSettings = gd.getNextBoolean();
fitConfig.setPsfType(PeakFit.getPsfTypeValues()[gd.getNextChoiceIndex()]);
config.setDataFilterType(gd.getNextChoiceIndex());
config.setDataFilter(gd.getNextChoiceIndex(), Math.abs(gd.getNextNumber()), false, 0);
config.setSearch(gd.getNextNumber());
config.setBorder(gd.getNextNumber());
config.setFitting(gd.getNextNumber());
// Some enum values are not supported
fitConfig.setFitSolver(SettingsManager.getFitSolverValues()[gd.getNextChoiceIndex()]);
// Avoid stupidness. Note: We are mostly ignoring the validation result and
// checking the results for the doublets manually.
// Realistically we cannot fit lower than this
fitConfig.setMinPhotons(15);
// Set the width factors to help establish bounds for bounded fitters
fitConfig.setMinWidthFactor(1.0 / 10);
fitConfig.setMaxWidthFactor(10);
settings.iterationIncrease = gd.getNextNumber();
settings.ignoreWithNeighbours = gd.getNextBoolean();
settings.showOverlay = gd.getNextBoolean();
settings.showHistograms = gd.getNextBoolean();
settings.showResults = gd.getNextBoolean();
settings.showJaccardPlot = gd.getNextBoolean();
settings.useMaxResiduals = gd.getNextBoolean();
settings.matchDistance = Math.abs(gd.getNextNumber());
settings.lowerDistance = Math.abs(gd.getNextNumber());
settings.signalFactor = Math.abs(gd.getNextNumber());
settings.lowerSignalFactor = Math.abs(gd.getNextNumber());
settings.matchingMethod = gd.getNextChoiceIndex();
gd.collectOptions();
settings.save();
configRef.set(config);
if (gd.invalidNumber()) {
return false;
}
if (settings.lowerDistance > settings.matchDistance) {
settings.lowerDistance = settings.matchDistance;
}
if (settings.lowerSignalFactor > settings.signalFactor) {
settings.lowerSignalFactor = settings.signalFactor;
}
if (settings.useBenchmarkSettings && !updateFitConfiguration(config)) {
return false;
}
boolean configure = true;
if (settings.useBenchmarkSettings) {
// Only configure the fit solver if not in a macro
configure = Macro.getOptions() == null;
}
if (configure && !PeakFit.configurePsfModel(config)) {
return false;
}
if (configure && !PeakFit.configureFitSolver(config, IJImageSource.getBounds(imp), null, PeakFit.FLAG_NO_SAVE)) {
return false;
}
lastId.set(simulationParameters.id);
if (settings.showHistograms) {
gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Select the histograms to display");
for (int i = 0; i < Settings.NAMES.length; i++) {
gd.addCheckbox(Settings.NAMES[i].replace(' ', '_'), settings.displayHistograms[i]);
}
for (int i = 0; i < Settings.NAMES2.length; i++) {
gd.addCheckbox(Settings.NAMES2[i].replace(' ', '_'), settings.displayHistograms[i + Settings.NAMES.length]);
}
gd.addHelp(HelpUrls.getUrl(helpKey));
gd.showDialog();
if (gd.wasCanceled()) {
return false;
}
for (int i = 0; i < settings.displayHistograms.length; i++) {
settings.displayHistograms[i] = gd.getNextBoolean();
}
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class ImageJAbstractPeakResults method setCalibration.
/**
* Sets the calibration.
*
* @param nmPerPixel the nm per pixel
* @param gain the gain
*/
public void setCalibration(double nmPerPixel, double gain) {
final CalibrationWriter cw = getCalibrationWriterSafe();
cw.setNmPerPixel(nmPerPixel);
cw.setCountPerPhoton(gain);
setCalibration(cw.getCalibration());
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class BlinkEstimatorTest method estimateBlinking.
private TIntHashSet estimateBlinking(UniformRandomProvider rg, double blinkingRate, double ton, double toff, int particles, double fixedFraction, boolean timeAtLowerBound, boolean doAssert) {
Assumptions.assumeTrue(TestSettings.allow(TestComplexity.MAXIMUM));
final SpatialIllumination activationIllumination = new UniformIllumination(100);
int totalSteps = 100;
final double eAct = totalSteps * 0.3 * activationIllumination.getAveragePhotons();
final ImageModel imageModel = new ActivationEnergyImageModel(eAct, activationIllumination, ton, 0, toff, 0, blinkingRate, rg);
final double[] max = new double[] { 256, 256, 32 };
final double[] min = new double[3];
final SpatialDistribution distribution = new UniformDistribution(min, max, rg.nextInt());
final List<CompoundMoleculeModel> compounds = new ArrayList<>(1);
final CompoundMoleculeModel c = new CompoundMoleculeModel(1, 0, 0, 0, Arrays.asList(new MoleculeModel(0, 0, 0, 0)));
c.setDiffusionRate(diffusionRate);
c.setDiffusionType(DiffusionType.RANDOM_WALK);
compounds.add(c);
final List<CompoundMoleculeModel> molecules = imageModel.createMolecules(compounds, particles, distribution, false);
// Activate fluorophores
final List<? extends FluorophoreSequenceModel> fluorophores = imageModel.createFluorophores(molecules, totalSteps);
totalSteps = checkTotalSteps(totalSteps, fluorophores);
final List<LocalisationModel> localisations = imageModel.createImage(molecules, fixedFraction, totalSteps, photons, 0.5, false);
// // Remove localisations to simulate missed counts.
// List<LocalisationModel> newLocalisations = new
// ArrayList<LocalisationModel>(localisations.size());
// boolean[] id = new boolean[fluorophores.size() + 1];
// Statistics photonStats = new Statistics();
// for (LocalisationModel l : localisations)
// {
// photonStats.add(l.getIntensity());
// // Remove by intensity threshold and optionally at random.
// if (l.getIntensity() < minPhotons || rand.nextDouble() < pDelete)
// continue;
// newLocalisations.add(l);
// id[l.getId()] = true;
// }
// localisations = newLocalisations;
// logger.info("Photons = %f", photonStats.getMean());
//
// List<FluorophoreSequenceModel> newFluorophores = new
// ArrayList<FluorophoreSequenceModel>(fluorophores.size());
// for (FluorophoreSequenceModel f : fluorophores)
// {
// if (id[f.getId()])
// newFluorophores.add(f);
// }
// fluorophores = newFluorophores;
final MemoryPeakResults results = new MemoryPeakResults();
final CalibrationWriter calibration = new CalibrationWriter();
calibration.setNmPerPixel(pixelPitch);
calibration.setExposureTime(msPerFrame);
calibration.setCountPerPhoton(1);
results.setCalibration(calibration.getCalibration());
results.setPsf(PsfHelper.create(PSFType.ONE_AXIS_GAUSSIAN_2D));
final float b = 0;
float intensity;
final float z = 0;
for (final LocalisationModel l : localisations) {
// Remove by intensity threshold and optionally at random.
if (l.getIntensity() < minPhotons || rg.nextDouble() < probabilityDelete) {
continue;
}
final int frame = l.getTime();
intensity = (float) l.getIntensity();
final float x = (float) l.getX();
final float y = (float) l.getY();
final float[] params = Gaussian2DPeakResultHelper.createParams(b, intensity, x, y, z, psfWidth);
results.add(frame, 0, 0, 0, 0, 0, 0, params, null);
}
// Add random localisations
// Intensity doesn't matter at the moment for tracing
intensity = (float) photons;
for (int i = (int) (localisations.size() * probabilityAdd); i-- > 0; ) {
final int frame = 1 + rg.nextInt(totalSteps);
final float x = (float) (rg.nextDouble() * max[0]);
final float y = (float) (rg.nextDouble() * max[1]);
final float[] params = Gaussian2DPeakResultHelper.createParams(b, intensity, x, y, z, psfWidth);
results.add(frame, 0, 0, 0, 0, 0, 0, params, null);
}
// Get actual simulated stats ...
final Statistics statsNBlinks = new Statistics();
final Statistics statsTOn = new Statistics();
final Statistics statsTOff = new Statistics();
final Statistics statsSampledNBlinks = new Statistics();
final Statistics statsSampledTOn = new Statistics();
final StoredDataStatistics statsSampledTOff = new StoredDataStatistics();
for (final FluorophoreSequenceModel f : fluorophores) {
statsNBlinks.add(f.getNumberOfBlinks());
statsTOn.add(f.getOnTimes());
statsTOff.add(f.getOffTimes());
final int[] on = f.getSampledOnTimes();
statsSampledNBlinks.add(on.length);
statsSampledTOn.add(on);
statsSampledTOff.add(f.getSampledOffTimes());
}
logger.info(FunctionUtils.getSupplier("N = %d (%d), N-blinks = %f, tOn = %f, tOff = %f, Fixed = %f", fluorophores.size(), localisations.size(), blinkingRate, ton, toff, fixedFraction));
logger.info(FunctionUtils.getSupplier("Actual N-blinks = %f (%f), tOn = %f (%f), tOff = %f (%f), 95%% = %f, max = %f", statsNBlinks.getMean(), statsSampledNBlinks.getMean(), statsTOn.getMean(), statsSampledTOn.getMean(), statsTOff.getMean(), statsSampledTOff.getMean(), statsSampledTOff.getStatistics().getPercentile(95), statsSampledTOff.getStatistics().getMax()));
logger.info("-=-=--=-");
final BlinkEstimator be = new BlinkEstimator();
be.setMaxDarkTime((int) (toff * 10));
be.setMsPerFrame(msPerFrame);
be.setRelativeDistance(false);
final double d = ImageModel.getRandomMoveDistance(diffusionRate);
be.setSearchDistance((fixedFraction < 1) ? Math.sqrt(2 * d * d) * 3 : 0);
be.setTimeAtLowerBound(timeAtLowerBound);
// Assertions.assertTrue("Max dark time must exceed the dark time of the data (otherwise no
// plateau)",
// be.maxDarkTime > statsSampledTOff.getStatistics().getMax());
final int nMolecules = fluorophores.size();
if (usePopulationStatistics) {
blinkingRate = statsNBlinks.getMean();
toff = statsTOff.getMean();
} else {
blinkingRate = statsSampledNBlinks.getMean();
toff = statsSampledTOff.getMean();
}
// See if any fitting regime gets a correct answer
final TIntHashSet ok = new TIntHashSet();
for (int numberOfFittedPoints = MIN_FITTED_POINTS; numberOfFittedPoints <= MAX_FITTED_POINTS; numberOfFittedPoints++) {
be.setNumberOfFittedPoints(numberOfFittedPoints);
be.computeBlinkingRate(results, true);
final double moleculesError = DoubleEquality.relativeError(nMolecules, be.getNMolecules());
final double blinksError = DoubleEquality.relativeError(blinkingRate, be.getNBlinks());
final double offError = DoubleEquality.relativeError(toff * msPerFrame, be.getTOff());
logger.info(FunctionUtils.getSupplier("Error %d: N = %f, blinks = %f, tOff = %f : %f", numberOfFittedPoints, moleculesError, blinksError, offError, (moleculesError + blinksError + offError) / 3));
if (moleculesError < relativeError && blinksError < relativeError && offError < relativeError) {
ok.add(numberOfFittedPoints);
logger.info("-=-=--=-");
logger.info(FunctionUtils.getSupplier("*** Correct at %d fitted points ***", numberOfFittedPoints));
if (doAssert) {
break;
}
}
// if (!be.isIncreaseNFittedPoints())
// break;
}
logger.info("-=-=--=-");
if (doAssert) {
Assertions.assertFalse(ok.isEmpty());
}
// relativeError);
return ok;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class FitEngineConfiguration method configureOutputUnits.
/**
* Configure the output units from fitting using the current calibration and fit solver settings.
*
* <p>This method should be called before the calibration is passed to any object that will handle
* the fitting output.
*
* <p>It will update the calibration units and the precision method to match that used by
* precision filter.
*/
public void configureOutputUnits() {
final FitConfiguration fitConfig = getFitConfiguration();
// If there is no calibration then the writer will just have the defaults
final CalibrationWriter calibration = fitConfig.getCalibrationWriterReference();
// Fitting is always done pixels and radians
calibration.setDistanceUnit(DistanceUnit.PIXEL);
calibration.setAngleUnit(AngleUnit.RADIAN);
// Most fitters fit in photons unless we have no calibration.
IntensityUnit intensityUnit = IntensityUnit.PHOTON;
if (fitConfig.isFitCameraCounts()) {
intensityUnit = IntensityUnit.COUNT;
}
calibration.setIntensityUnit(intensityUnit);
// This initialises the calibration precision method
fitConfig.getFilterPrecisionMethod();
}
Aggregations