using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Reflection; using System.Threading.Tasks; using MathWorks.MATLAB.NET.Arrays; namespace Uestc.Auto6.Dso.Hardware.Calibration.Tool { class Helper { #region matlabInstalled private static bool matlabInstalled = false; public static void InitSystemInfo() { Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine;//注册表用于存储系统和应用程序的设置信息 matlabInstalled = (regkey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\matlab.exe", false) != null); } public static bool bMatlabInstalled { get => matlabInstalled; private set { matlabInstalled = value; } } #endregion #region Reflection Defined Class public static List AllBatchTaskClass = null; public static List AllBatchTaskPartClass = null; public static List AllMatlabSourceCodePrePosProcessorClass = null; public static void InitDomainClass() { var q = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && t.Namespace== "Uestc.Auto6.Dso.Hardware.Calibration.Tool" && t.BaseType.Name== "BatchTaskBase" select t; AllBatchTaskClass = q.ToList(); var m = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && t.Namespace == "Uestc.Auto6.Dso.Hardware.Calibration.Tool.BatchTask" && t.BaseType.Name == "BatchTaskPartBase" select t; AllBatchTaskPartClass = m.ToList(); var n = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && t.Namespace == "Uestc.Auto6.Dso.Hardware.Calibration.Tool" && t.Name.IndexOf("MatlabSourceCodePrePosProcessor")==0 select t; AllMatlabSourceCodePrePosProcessorClass = n.ToList(); } #endregion #region public static string TryConvertToString(string value) { if (value == null) return ""; return value; } public static int TryConvertToInt(string value) { if (int.TryParse(value, out int int_value)) return int_value; else return 0; } public static long TryConvertToLong(string value) { if (long.TryParse(value, out long int_value)) return int_value; else return 0; } public static bool TryConvertToBoolean(string value) { return value switch { "true" => true, "TRUE" => true, "1" => true, _ => false, }; } #endregion public static string[] SplitClassNameAndParameter(string nameAndParameter) { string tmpNameAndParameter = nameAndParameter.Trim(); int firstSpacePos = tmpNameAndParameter.IndexOf(' '); if (firstSpacePos < 0) return null; string[] returnValue = new string[2]; returnValue[0] = tmpNameAndParameter.Substring(0, firstSpacePos).Trim(); returnValue[1] = tmpNameAndParameter.Substring(firstSpacePos, tmpNameAndParameter.Length - firstSpacePos).Trim(); return returnValue; } public static bool CheckAndTipInstrumentSession(IInstrumentSession instrumentSession) { if (instrumentSession == null) { MessageBox.Show("请先连接待测试的示波器!"); return false; } return true; } public static MethodInfo? GetGenerateCoefficientsMatlabDllFunc(Type type) { MethodInfo[] methodInfos = type.GetMethods(); foreach (MethodInfo m in methodInfos) { if (m.ReturnType.Name == "MWArray") { if (m.GetParameters().Length == 2) return m; } } return null; } } internal class SineFitFunc { private static Double AVG1(Int16[] a) { Double avg = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) avg += a[i]; avg /= M; return (avg); } private static Double AVG1(UInt16[] a) { Double avg = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) avg += a[i]; avg /= M; return (avg); } private static Double AVG2(Double[] a) { Double avg = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) avg += a[i]; avg /= M; return (avg); } private static Double SUM(ref Double[] a) { Int32 M = a.Length; Double sum = 0; Int32 i; for (i = 0; i < M; i++) sum += a[i]; return (sum); } private static Double SPFH(ref Double[] a) //平方和 { Double spfh = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) spfh += a[i] * a[i]; return (spfh); } private static Double DCJ1(ref Int16[] a, ref Double[] b) //两数先相乘,再相加 { Double dcj = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) dcj += a[i] * b[i]; return (dcj); } private static Double DCJ1(ref UInt16[] a, ref Double[] b) //两数先相乘,再相加 { Double dcj = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) dcj += a[i] * b[i]; return (dcj); } private static Double DCJ2(ref Double[] a, ref Double[] b) //两数先相乘,再相加 { Double dcj = 0; Int32 i; Int32 M = a.Length; for (i = 0; i < M; i++) dcj += a[i] * b[i]; return (dcj); } private static Double[] m; private static Double[] n; private static Double a, b, c, d, e, f, g, h, p, q; private static Double parameterA(Int16[] y) //经验公式A*cos(w*tn)+B*sin(w*tn)+C,求系数A { Double An, Ad, A1; a = AVG1(y); b = AVG2(m); c = AVG2(n); d = DCJ1(ref y, ref m); e = DCJ2(ref m, ref n); f = DCJ1(ref y, ref n); g = SUM(ref m); h = SUM(ref n); p = SPFH(ref m); q = SPFH(ref n); An = (d - a * g) / (e - c * g) - (f - a * h) / (q - c * h); Ad = (p - b * g) / (e - c * g) - (e - b * h) / (q - c * h); A1 = An / Ad; return (A1); } private static Double parameterA(UInt16[] y) //经验公式A*cos(w*tn)+B*sin(w*tn)+C,求系数A { Double An, Ad, A1; a = AVG1(y); b = AVG2(m); c = AVG2(n); d = DCJ1(ref y, ref m); e = DCJ2(ref m, ref n); f = DCJ1(ref y, ref n); g = SUM(ref m); h = SUM(ref n); p = SPFH(ref m); q = SPFH(ref n); An = (d - a * g) / (e - c * g) - (f - a * h) / (q - c * h); Ad = (p - b * g) / (e - c * g) - (e - b * h) / (q - c * h); A1 = An / Ad; return (A1); } private static Double parameterB(Int16[] y) //求系数B { Double Bn, Bd, B1; Bn = (d - a * g) / (p - b * g) - (f - a * h) / (e - b * h); Bd = (e - c * g) / (p - b * g) - (q - c * h) / (e - b * h); B1 = Bn / Bd; return (B1); } private static Double parameterB(UInt16[] y) //求系数B { Double Bn, Bd, B1; Bn = (d - a * g) / (p - b * g) - (f - a * h) / (e - b * h); Bd = (e - c * g) / (p - b * g) - (q - c * h) / (e - b * h); B1 = Bn / Bd; return (B1); } private static Double A1, B1; private static Double parameterC(Int16[] y, double sampleByM_Sps, double signalFreqByMHz, Int32 M) //求系数C { Int32 i; Double C1; for (i = 0; i < M; i++) { m[i] = Math.Cos(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); //fx为输入正弦波频率,MHz为单位,每个AD1.25G采样率 2*Pi*fx/fs n[i] = Math.Sin(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); } A1 = parameterA(y); B1 = parameterB(y); C1 = a - A1 * b - B1 * c; return (C1); } private static Double parameterC(UInt16[] y, double sampleByM_Sps, double signalFreqByMHz, Int32 M) //求系数C { Int32 i; Double C1; for (i = 0; i < M; i++) { m[i] = Math.Cos(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); //fx为输入正弦波频率,MHz为单位,每个AD1.25G采样率 2*Pi*fx/fs n[i] = Math.Sin(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); } A1 = parameterA(y); B1 = parameterB(y); C1 = a - A1 * b - B1 * c; return (C1); } /// /// /// /// /// 返回的计算结果0-offset,1-gain,2-phase /// 以Msps表示的当前数据的采样率 /// MHz表示当前输入信号的频率 public static WaveOffsetGainPhase SineFit(Int16[] databuffer, double sampleByM_Sps, double signalFreqByMHz) { m = new Double[databuffer.Length]; n = new Double[databuffer.Length]; WaveOffsetGainPhase waveOffsetGainPhase = new(); //正弦拟合计算偏置和增益 waveOffsetGainPhase.Offset = parameterC(databuffer, signalFreqByMHz, sampleByM_Sps, databuffer.Length);//输入100MHz正弦波,偏置 waveOffsetGainPhase.Gain = Math.Sqrt(A1 * A1 + B1 * B1);//增益 if (A1 < 0) waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1));//相位 else waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1) + 3.141592); return waveOffsetGainPhase; } /// /// /// /// /// 返回的计算结果0-offset,1-gain,2-phase /// 以Msps表示的当前数据的采样率 /// MHz表示当前输入信号的频率 public static WaveOffsetGainPhase SineFit(UInt16[] databuffer, double sampleByM_Sps, double signalFreqByMHz) { m = new Double[databuffer.Length]; n = new Double[databuffer.Length]; WaveOffsetGainPhase waveOffsetGainPhase = new(); //正弦拟合计算偏置和增益 waveOffsetGainPhase.Offset = parameterC(databuffer, signalFreqByMHz, sampleByM_Sps, databuffer.Length);//输入100MHz正弦波,偏置 waveOffsetGainPhase.Gain = Math.Sqrt(A1 * A1 + B1 * B1);//增益 if (A1 < 0) waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1)) * 1000000;//相位 else waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1) + 3.141592) * 1000000; return waveOffsetGainPhase; } } public class WaveOffsetGainPhase { public double Offset; public double Gain; public double Phase; } }