public static double[] GradientTowardsMinimalErrorForGaussian(double peak, double sigma, ushort[] samples, double center, GaussianFitOptions2 options) { var vec = new double[2]; var used = 0; for (var x = 0; x < samples.Length; x++) { var distance = (x - center); if (distance <= 5) { continue; } var distanceSquared = distance * distance; var sample = samples[x]; var sChange = Photometry2.SigmaSlopeFromDerivative((double)sample, (double)x, center, sigma, peak); var pChange = Photometry2.PeakSlopeFromDerivative((double)sample, (double)x, center, sigma, peak); if (double.IsPositiveInfinity(sChange) || double.IsNegativeInfinity(sChange)) { throw new ArgumentException(); } if (double.IsPositiveInfinity(pChange) || double.IsNegativeInfinity(pChange)) { throw new ArgumentException(); } vec[0] += (1 * sChange); vec[1] += (1 * pChange); used++; } vec[0] /= used; vec[1] /= used; return(vec); }
public static double[] GradientTowardsMinimalErrorForGaussian(double peak, double sigma, ushort[] samples, double center, GaussianFitOptions2 options) { var vec = new double[2]; var used = 0; for (var x = 0; x < samples.Length; x++) { var distance = (x - center); if (distance > 10) { continue; } var distanceSquared = distance * distance; if (distanceSquared == 0) { continue; } var sample = samples[x]; if (sample == peak) { continue; } var sigmaSample = GaussianSigmaFromSample(peak, distanceSquared, sample); var peakSample = GaussianPeakFromSample(distanceSquared, sigma, sample); var sChange = GaussianSigmaErrorSlopeFunction(distanceSquared, peak, sigmaSample, sigma); var pChange = GaussianPeakErrorSlopeFunction(peakSample, peak, sigma); if (double.IsPositiveInfinity(sChange) || double.IsNegativeInfinity(sChange)) { throw new ArgumentException(); } vec[0] += (-1 * sChange); vec[1] += (-1 * pChange); used++; } vec[0] /= used; vec[1] /= used; return(vec); }
public static GaussianFit FindGaussianPSF(ushort[] samples, double peak, double center, GaussianFitOptions2 options) { var width = options.StartSigma; var widthStep = 1.0; var peakStep = 1.0; var iterations = 0; for (iterations = 0; iterations < options.MaxIterations && Math.Abs(widthStep) > options.MinimumChangeThreshold; iterations++) { var direction = GradientTowardsMinimalErrorForGaussian(peak, width, samples, center, options); widthStep = options.IterationStepSize * direction[0]; width = width + widthStep; //peakStep = options.IterationStepSize * direction[1]; //peak = peak + peakStep; if (width < .1) { Debug.WriteLine($"Error: sigma got too small"); return(new GaussianFit { Result = GaussianFitResult.Error }); } else if (width > 20) { Debug.WriteLine($"Error: sigma got too large"); return(new GaussianFit { Result = GaussianFitResult.Error }); } if (peak < 0) { Debug.WriteLine($"Error: peak got too small"); return(new GaussianFit { Result = GaussianFitResult.Error }); } PrintResiduals(samples, peak, center, width); } return(new GaussianFit { Width = width, Peak = peak, Iterations = iterations, Result = iterations == options.MaxIterations ? GaussianFitResult.IterationsMaxed : GaussianFitResult.StepMinimumReached }); }
public static GaussianFit FindGaussianPSF(ushort[] samples, double peak, double center, GaussianFitOptions2 options) { var width = 1.0; var widthStep = 1.0; var iterations = 0; for (iterations = 0; iterations < options.MaxIterations && Math.Abs(widthStep) > options.MinimumChangeThreshold; iterations++) { var direction = GradientTowardsMinimalErrorForGaussian(peak, width, samples, center, options); widthStep = options.IterationStepSize * direction[0]; width = width + widthStep; if (width < .1) { return(new GaussianFit { Result = GaussianFitResult.Error }); } else if (width > 20) { return(new GaussianFit { Result = GaussianFitResult.Error }); } if (peak < 0) { return(new GaussianFit { Result = GaussianFitResult.Error }); } } return(new GaussianFit { Width = width, Peak = peak, Iterations = iterations, Result = iterations == options.MaxIterations ? GaussianFitResult.IterationsMaxed : GaussianFitResult.StepMinimumReached }); }