public static void SavitzkyGolay(SavitzkyGolayParameters parameters, Altaxo.Data.DataColumn yCol, Altaxo.Data.DataColumn xCol) { double spacing = 1; if (xCol is Data.INumericColumn) { Calc.LinearAlgebra.VectorSpacingEvaluator calcspace = new Calc.LinearAlgebra.VectorSpacingEvaluator(Calc.LinearAlgebra.DataColumnWrapper.ToROVector(xCol)); if (!calcspace.HasValidSpaces || calcspace.HasInvalidSpaces) { Current.Gui.ErrorMessageBox(string.Format("The x-column {0} contains invalid spaces (is not equally spaced)", xCol.Name)); return; } if (calcspace.RelativeSpaceDeviation > 1E-2) { if (!Current.Gui.YesNoMessageBox( string.Format("The x-column {0} is not equally spaced, the deviation is {1}, the mean spacing is {2}. Continue anyway?", xCol.Name, calcspace.RelativeSpaceDeviation, calcspace.SpaceMeanValue), "Continue?", true)) return; } spacing = calcspace.SpaceMeanValue; } Calc.Regression.SavitzkyGolay filter = new SavitzkyGolay(parameters); using (var suspendToken = yCol.SuspendGetToken()) { filter.Apply(DataColumnWrapper.ToROVectorCopy(yCol), DataColumnWrapper.ToVector(yCol)); if (parameters.DerivativeOrder > 0) { double factor = Math.Pow(1 / spacing, parameters.DerivativeOrder) * Calc.GammaRelated.Fac(parameters.DerivativeOrder); yCol.Data = yCol * factor; } suspendToken.Dispose(); } }
public static void SavitzkyGolayFiltering(WorksheetController ctrl) { if(ctrl.SelectedDataColumns.Count==0) return; object paramobject = new SavitzkyGolayParameters(); if(!Current.Gui.ShowDialog(ref paramobject,"Savitzky-Golay parameters")) return; SavitzkyGolayParameters parameters = (SavitzkyGolayParameters)paramobject; Altaxo.Data.DataColumn yCol = ctrl.Doc.DataColumns[ctrl.SelectedDataColumns[0]]; Altaxo.Data.DataColumn xCol = ctrl.Doc.DataColumns.FindXColumnOf(yCol); double spacing = 1; if(xCol is Data.INumericColumn) { Calc.LinearAlgebra.VectorSpacingEvaluator calcspace = new Calc.LinearAlgebra.VectorSpacingEvaluator(Calc.LinearAlgebra.DataColumnWrapper.ToROVector(xCol)); if(!calcspace.HasValidSpaces || calcspace.HasInvalidSpaces) { Current.Gui.ErrorMessageBox(string.Format("The x-column {0} contains invalid spaces (is not equally spaced)",xCol.Name)); return; } if(calcspace.RelativeSpaceDeviation>1E-2) { System.Windows.Forms.DialogResult dlgresult = System.Windows.Forms.MessageBox.Show(Current.MainWindow, string.Format("The x-column {0} is not equally spaced, the deviation is {1}, the mean spacing is {2}. Continue anyway?", xCol.Name, calcspace.RelativeSpaceDeviation, calcspace.SpaceMeanValue), "Continue?",System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question, System.Windows.Forms.MessageBoxDefaultButton.Button1); if(dlgresult==System.Windows.Forms.DialogResult.No) return; } spacing = calcspace.SpaceMeanValue; } Calc.Regression.SavitzkyGolay filter = new SavitzkyGolay(parameters); yCol.Suspend(); filter.Apply(DataColumnWrapper.ToROVectorCopy(yCol),DataColumnWrapper.ToVector(yCol)); if(parameters.DerivativeOrder>0) { double factor = Math.Pow(1/spacing,parameters.DerivativeOrder)*Calc.GammaRelated.Fac(parameters.DerivativeOrder); yCol.Data = yCol*factor; } yCol.Resume(); }
protected virtual void CalculateFixedSignal(out double[] fixedSignalGeneratorInput) { double[] arrayToFixFrom; if (AlgorithmParams.SignalToFix == FixBasedOnTypes.FirstInput) { arrayToFixFrom = IterationsData[0].SignalsData[SignalTypes.SignalGeneratorOutput]; } else { arrayToFixFrom = IterationsData[CurrentIterationIndex].SignalsData[SignalTypes.SignalGeneratorOutput]; } for (int i = 0; i < PeriodLength; i++) { double signalAmp = IterationsData[CurrentIterationIndex].SignalsAmplitude[Experiments.SignalTypes.PhotodiodeOutput]; double actualError = IterationsData[CurrentIterationIndex].OutputError[i] * signalAmp; if (Math.Abs(actualError) < AlgorithmParams.MaxErrorToFixFrom) { IterationsData[CurrentIterationIndex].FixValue[i] = 0; } double dfdi = 0.5 * Math.Sin(2 * i * Math.PI / PeriodLength); dfdi = (1 + AlgorithmParams.EpsilonFactor) / (dfdi + AlgorithmParams.EpsilonFactor); if (AlgorithmParams.UseDerivativeFix) { //need to check later ob without abs as it was originally. IterationsData[CurrentIterationIndex].FixValue[i] *= Math.Abs(dfdi); } IterationsData[CurrentIterationIndex].FixedInput[i] = Math.Round(arrayToFixFrom[i] + IterationsData[CurrentIterationIndex].FixValue[i]); if (IterationsData[CurrentIterationIndex].FixedInput[i] < 0) { IterationsData[CurrentIterationIndex].FixedInput[i] = 0; } if (IterationsData[CurrentIterationIndex].FixedInput[i] > AlgorithmParams.DigitzerParams.DigitizerLevels) { IterationsData[CurrentIterationIndex].FixedInput[i] = AlgorithmParams.DigitzerParams.DigitizerLevels; } } if (AlgorithmParams.SavitzkyGolayFilterOrder > 0) { int dataLength = IterationsData[CurrentIterationIndex].FixedInput.Length; double oldMax = IterationsData[CurrentIterationIndex].FixedInput.Max(); double oldMin = IterationsData[CurrentIterationIndex].FixedInput.Min(); double oldDelta = oldMax - oldMin; SavitzkyGolayParameters sgParam = new SavitzkyGolayParameters(); sgParam.DerivativeOrder = 0; sgParam.NumberOfPoints = AlgorithmParams.SavitzkyGolayFilterLength; sgParam.PolynomialOrder = AlgorithmParams.SavitzkyGolayFilterOrder; SavitzkyGolay sgAlgo = new SavitzkyGolay(sgParam); double[] tmpSignal = new double[dataLength * 3]; double[] smoothSignal = new double[dataLength * 3]; double[] a = new double[5]; for (int i = 0; i < 3; i++) { Array.Copy(IterationsData[CurrentIterationIndex].FixedInput, 0, tmpSignal, i * dataLength, dataLength); } sgAlgo.Apply(tmpSignal, smoothSignal); Array.Copy(smoothSignal, dataLength, IterationsData[CurrentIterationIndex].FixedInput, 0, dataLength); double newMax = 0; double newMin = 0; if (AlgorithmParams.RescaleAfterSmoothing) { double newAmplitude; newMax = IterationsData[CurrentIterationIndex].FixedInput.Max(); newMin = IterationsData[CurrentIterationIndex].FixedInput.Min(); IterationsData[CurrentIterationIndex].FixedInput = SignalDigitizer.NormalizeSignal(IterationsData[CurrentIterationIndex].FixedInput, new DigitzerParameters(DigitizingMethods.Absolute, 0, 0, 1, false), out newAmplitude).ToArray(); IterationsData[CurrentIterationIndex].FixedInput = IterationsData[CurrentIterationIndex].FixedInput.Select(fixValue => (fixValue * oldDelta) + oldMin).ToArray(); } IterationsData[CurrentIterationIndex].FixedInput = IterationsData[CurrentIterationIndex].FixedInput.Select(x => Math.Round(x)).ToArray(); newMax = IterationsData[CurrentIterationIndex].FixedInput.Max(); newMin = IterationsData[CurrentIterationIndex].FixedInput.Min(); } fixedSignalGeneratorInput = IterationsData[CurrentIterationIndex].FixedInput; }