public virtual void UpdateScan(double[] rampData, double[] scanData, bool shouldBlock) { LatestScanData = scanData; lockBlocked = shouldBlock; if (!lockBlocked) { switch (lState) { case LaserState.LOCKED: LorentzianFit newFit = FitWithPreviousAsBestGuess(rampData, scanData); double dataPeakCentre = rampData[Array.IndexOf(scanData, scanData.Max())]; bool fitTooNarrow = newFit.Width < 0.001; // Sometimes fit seems to break and give a tiny width bool fitTooFarFromMax = Math.Abs(newFit.Centre - dataPeakCentre) / newFit.Width > 1; if (fitTooNarrow || fitTooFarFromMax) { newFit = FitUsingDataForBestGuess(rampData, scanData); } Fit = newFit; break; case LaserState.LOCKING: Fit = FitUsingDataForBestGuess(rampData, scanData); Lock(); break; case LaserState.FREE: break; } } }
protected LorentzianFit FitUsingDataForBestGuess(double[] rampData, double[] scanData) { double background = scanData.Min(); double maximum = scanData.Max(); double amplitude = maximum - background; double centre = rampData[Array.IndexOf(scanData, maximum)]; double width = (rampData.Max() - rampData.Min()) / 20; LorentzianFit bestGuessFit = new LorentzianFit(background, amplitude, centre, width); return(CavityScanFitHelper.FitLorentzianToData(rampData, scanData, bestGuessFit)); }
private static LorentzianFit fitFailSafe(LorentzianFit fit, double lowerLimit, double upperLimit) { if (fit.Centre < lowerLimit) { fit.Centre = lowerLimit; } else if (fit.Centre > upperLimit) { fit.Centre = upperLimit; } return(fit); }
public static LorentzianFit FitLorentzianToData(double[] voltages, double[] signal, LorentzianFit bestGuess) { LorentzianFitter lorentzianFitter = new LorentzianFitter(); lorentzianFitter.Fit(voltages, signal, new double[] { bestGuess.Background, bestGuess.Amplitude, bestGuess.Centre, bestGuess.Width }); double[] coefficients = lorentzianFitter.Parameters; LorentzianFit fit = new LorentzianFit(coefficients[0], coefficients[1], coefficients[2], coefficients[3]); double minCentrePosition = voltages.Min(); double maxCentrePosition = voltages.Max(); fit = fitFailSafe(fit, minCentrePosition, maxCentrePosition); return(fit); }
/// <summary> /// A helper function. generates a bunch of points from a some fit coefficients. /// </summary> /// <param name="cavityVoltages"></param> /// <param name="fitCoefficients"></param> /// <returns></returns> public static double[] CreatePointsFromFit(double[] cavityVoltages, LorentzianFit fit) { double[] fitPoints = new double[cavityVoltages.Length]; double n = fit.Background; double q = fit.Amplitude; double c = fit.Centre; double w = fit.Width; for (int i = 0; i < cavityVoltages.Length; i++) { if (w == 0) { w = 0.001; // watch out for divide by zero } fitPoints[i] = n + q * (1 / (1 + (((cavityVoltages[i] - c) * (cavityVoltages[i] - c)) / ((w / 2) * (w / 2))))); } return(fitPoints); }