use of uk.ac.sussex.gdsc.smlm.fitting.nonlinear.FastMleSteppingFunctionSolver in project GDSC-SMLM by aherbert.
the class FitConfiguration method createFunctionSolver.
private BaseFunctionSolver createFunctionSolver() {
if (gaussianFunction == null) {
// Other code may want to call getFunctionSolver() to see if exceptions are thrown
// so create a dummy function so we can return a function solver.
gaussianFunction = createGaussianFunction(1, 1, 1);
}
if (getFitSolverValue() == FitSolver.MLE_VALUE) {
// Only support CCD/EM-CCD at the moment
if (!calibration.isCcdCamera()) {
throw new IllegalStateException("CCD/EM-CCD camera is required for fit solver: " + getFitSolver());
}
// This requires the gain
if (gain <= 0) {
throw new IllegalStateException("The gain is required for fit solver: " + getFitSolver());
}
final MaximumLikelihoodFitter.SearchMethod searchMethod = convertSearchMethod();
// Only the Poisson likelihood function supports gradients
if (searchMethod.usesGradients() && isModelCamera()) {
throw new IllegalStateException(String.format("The derivative based search method '%s' can only be used with the " + "'%s' likelihood function, i.e. no model camera noise", searchMethod, MaximumLikelihoodFitter.LikelihoodFunction.POISSON));
}
final MaximumLikelihoodFitter fitter = new MaximumLikelihoodFitter(gaussianFunction);
fitter.setRelativeThreshold(getRelativeThreshold());
fitter.setAbsoluteThreshold(getAbsoluteThreshold());
fitter.setMaxEvaluations(getMaxFunctionEvaluations());
fitter.setMaxIterations(getMaxIterations());
fitter.setSearchMethod(searchMethod);
fitter.setGradientLineMinimisation(isGradientLineMinimisation());
// Specify the likelihood function to use
if (isModelCamera()) {
// Set the camera read noise.
// Do not check if this is set as 0 is a valid option.
fitter.setSigma(calibration.getReadNoise());
if (emCcd) {
// EMCCD = Poisson+Gamma+Gaussian
fitter.setLikelihoodFunction(MaximumLikelihoodFitter.LikelihoodFunction.POISSON_GAMMA_GAUSSIAN);
} else {
// CCD = Poisson+Gaussian
fitter.setLikelihoodFunction(MaximumLikelihoodFitter.LikelihoodFunction.POISSON_GAUSSIAN);
}
} else {
fitter.setLikelihoodFunction(MaximumLikelihoodFitter.LikelihoodFunction.POISSON);
}
// All models use the amplification gain (i.e. how many ADUs/electron)
if (!calibration.hasCountPerElectron()) {
throw new IllegalStateException("The amplification is required for the fit solver: " + getFitSolver());
}
fitter.setAlpha(1.0 / calibration.getCountPerElectron());
return fitter;
}
// All the remaining solvers are based on the stepping function solver
final ToleranceChecker tc = getToleranceChecker();
final ParameterBounds bounds = new ParameterBounds(gaussianFunction);
if (isUseClamping()) {
setClampValues(bounds);
}
SteppingFunctionSolver solver;
switch(getFitSolverValue()) {
case FitSolver.LVM_LSE_VALUE:
solver = new LseLvmSteppingFunctionSolver(gaussianFunction, tc, bounds);
break;
case FitSolver.LVM_MLE_VALUE:
checkCameraCalibration();
solver = new MleLvmSteppingFunctionSolver(gaussianFunction, tc, bounds);
break;
case FitSolver.LVM_WLSE_VALUE:
checkCameraCalibration();
solver = new WLseLvmSteppingFunctionSolver(gaussianFunction, tc, bounds);
break;
case FitSolver.FAST_MLE_VALUE:
checkCameraCalibration();
// This may throw a class cast exception if the function does not support
// the Gradient2Function interface
solver = new FastMleSteppingFunctionSolver((Gradient2Function) gaussianFunction, tc, bounds);
break;
default:
throw new IllegalStateException("Unknown fit solver: " + getFitSolver());
}
if (solver instanceof LvmSteppingFunctionSolver) {
((LvmSteppingFunctionSolver) solver).setInitialLambda(getLambda());
} else if (solver instanceof FastMleSteppingFunctionSolver) {
((FastMleSteppingFunctionSolver) solver).setLineSearchMethod(convertLineSearchMethod());
}
return solver;
}
Aggregations