Helper.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Forms;
  6. using System.Reflection;
  7. using System.Threading.Tasks;
  8. using MathWorks.MATLAB.NET.Arrays;
  9. namespace Uestc.Auto6.Dso.Hardware.Calibration.Tool
  10. {
  11. class Helper
  12. {
  13. #region matlabInstalled
  14. private static bool matlabInstalled = false;
  15. public static void InitSystemInfo()
  16. {
  17. Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine;//注册表用于存储系统和应用程序的设置信息
  18. matlabInstalled = (regkey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\matlab.exe", false) != null);
  19. }
  20. public static bool bMatlabInstalled
  21. {
  22. get => matlabInstalled;
  23. private set
  24. {
  25. matlabInstalled = value;
  26. }
  27. }
  28. #endregion
  29. #region Reflection Defined Class
  30. public static List<Type> AllBatchTaskClass = null;
  31. public static List<Type> AllBatchTaskPartClass = null;
  32. public static List<Type> AllMatlabSourceCodePrePosProcessorClass = null;
  33. public static void InitDomainClass()
  34. {
  35. var q = from t in Assembly.GetExecutingAssembly().GetTypes()
  36. where t.IsClass
  37. && t.Namespace== "Uestc.Auto6.Dso.Hardware.Calibration.Tool"
  38. && t.BaseType.Name== "BatchTaskBase"
  39. select t;
  40. AllBatchTaskClass = q.ToList();
  41. var m = from t in Assembly.GetExecutingAssembly().GetTypes()
  42. where t.IsClass
  43. && t.Namespace == "Uestc.Auto6.Dso.Hardware.Calibration.Tool.BatchTask"
  44. && t.BaseType.Name == "BatchTaskPartBase"
  45. select t;
  46. AllBatchTaskPartClass = m.ToList();
  47. var n = from t in Assembly.GetExecutingAssembly().GetTypes()
  48. where t.IsClass
  49. && t.Namespace == "Uestc.Auto6.Dso.Hardware.Calibration.Tool"
  50. && t.Name.IndexOf("MatlabSourceCodePrePosProcessor")==0
  51. select t;
  52. AllMatlabSourceCodePrePosProcessorClass = n.ToList();
  53. }
  54. #endregion
  55. #region
  56. public static string TryConvertToString(string value)
  57. {
  58. if (value == null)
  59. return "";
  60. return value;
  61. }
  62. public static int TryConvertToInt(string value)
  63. {
  64. if (int.TryParse(value, out int int_value))
  65. return int_value;
  66. else
  67. return 0;
  68. }
  69. public static long TryConvertToLong(string value)
  70. {
  71. if (long.TryParse(value, out long int_value))
  72. return int_value;
  73. else
  74. return 0;
  75. }
  76. public static bool TryConvertToBoolean(string value)
  77. {
  78. return value switch
  79. {
  80. "true" => true,
  81. "TRUE" => true,
  82. "1" => true,
  83. _ => false,
  84. };
  85. }
  86. #endregion
  87. public static string[] SplitClassNameAndParameter(string nameAndParameter)
  88. {
  89. string tmpNameAndParameter = nameAndParameter.Trim();
  90. int firstSpacePos = tmpNameAndParameter.IndexOf(' ');
  91. if (firstSpacePos < 0)
  92. return null;
  93. string[] returnValue = new string[2];
  94. returnValue[0] = tmpNameAndParameter.Substring(0, firstSpacePos).Trim();
  95. returnValue[1] = tmpNameAndParameter.Substring(firstSpacePos, tmpNameAndParameter.Length - firstSpacePos).Trim();
  96. return returnValue;
  97. }
  98. public static bool CheckAndTipInstrumentSession(IInstrumentSession instrumentSession)
  99. {
  100. if (instrumentSession == null)
  101. {
  102. MessageBox.Show("请先连接待测试的示波器!");
  103. return false;
  104. }
  105. return true;
  106. }
  107. public static MethodInfo? GetGenerateCoefficientsMatlabDllFunc(Type type)
  108. {
  109. MethodInfo[] methodInfos = type.GetMethods();
  110. foreach (MethodInfo m in methodInfos)
  111. {
  112. if (m.ReturnType.Name == "MWArray")
  113. {
  114. if (m.GetParameters().Length == 2)
  115. return m;
  116. }
  117. }
  118. return null;
  119. }
  120. }
  121. internal class SineFitFunc
  122. {
  123. private static Double AVG1(Int16[] a)
  124. {
  125. Double avg = 0;
  126. Int32 i;
  127. Int32 M = a.Length;
  128. for (i = 0; i < M; i++)
  129. avg += a[i];
  130. avg /= M;
  131. return (avg);
  132. }
  133. private static Double AVG1(UInt16[] a)
  134. {
  135. Double avg = 0;
  136. Int32 i;
  137. Int32 M = a.Length;
  138. for (i = 0; i < M; i++)
  139. avg += a[i];
  140. avg /= M;
  141. return (avg);
  142. }
  143. private static Double AVG2(Double[] a)
  144. {
  145. Double avg = 0;
  146. Int32 i;
  147. Int32 M = a.Length;
  148. for (i = 0; i < M; i++)
  149. avg += a[i];
  150. avg /= M;
  151. return (avg);
  152. }
  153. private static Double SUM(ref Double[] a)
  154. {
  155. Int32 M = a.Length;
  156. Double sum = 0;
  157. Int32 i;
  158. for (i = 0; i < M; i++)
  159. sum += a[i];
  160. return (sum);
  161. }
  162. private static Double SPFH(ref Double[] a) //平方和
  163. {
  164. Double spfh = 0;
  165. Int32 i;
  166. Int32 M = a.Length;
  167. for (i = 0; i < M; i++)
  168. spfh += a[i] * a[i];
  169. return (spfh);
  170. }
  171. private static Double DCJ1(ref Int16[] a, ref Double[] b) //两数先相乘,再相加
  172. {
  173. Double dcj = 0;
  174. Int32 i;
  175. Int32 M = a.Length;
  176. for (i = 0; i < M; i++)
  177. dcj += a[i] * b[i];
  178. return (dcj);
  179. }
  180. private static Double DCJ1(ref UInt16[] a, ref Double[] b) //两数先相乘,再相加
  181. {
  182. Double dcj = 0;
  183. Int32 i;
  184. Int32 M = a.Length;
  185. for (i = 0; i < M; i++)
  186. dcj += a[i] * b[i];
  187. return (dcj);
  188. }
  189. private static Double DCJ2(ref Double[] a, ref Double[] b) //两数先相乘,再相加
  190. {
  191. Double dcj = 0;
  192. Int32 i;
  193. Int32 M = a.Length;
  194. for (i = 0; i < M; i++)
  195. dcj += a[i] * b[i];
  196. return (dcj);
  197. }
  198. private static Double[] m;
  199. private static Double[] n;
  200. private static Double a, b, c, d, e, f, g, h, p, q;
  201. private static Double parameterA(Int16[] y) //经验公式A*cos(w*tn)+B*sin(w*tn)+C,求系数A
  202. {
  203. Double An, Ad, A1;
  204. a = AVG1(y);
  205. b = AVG2(m);
  206. c = AVG2(n);
  207. d = DCJ1(ref y, ref m);
  208. e = DCJ2(ref m, ref n);
  209. f = DCJ1(ref y, ref n);
  210. g = SUM(ref m);
  211. h = SUM(ref n);
  212. p = SPFH(ref m);
  213. q = SPFH(ref n);
  214. An = (d - a * g) / (e - c * g) - (f - a * h) / (q - c * h);
  215. Ad = (p - b * g) / (e - c * g) - (e - b * h) / (q - c * h);
  216. A1 = An / Ad;
  217. return (A1);
  218. }
  219. private static Double parameterA(UInt16[] y) //经验公式A*cos(w*tn)+B*sin(w*tn)+C,求系数A
  220. {
  221. Double An, Ad, A1;
  222. a = AVG1(y);
  223. b = AVG2(m);
  224. c = AVG2(n);
  225. d = DCJ1(ref y, ref m);
  226. e = DCJ2(ref m, ref n);
  227. f = DCJ1(ref y, ref n);
  228. g = SUM(ref m);
  229. h = SUM(ref n);
  230. p = SPFH(ref m);
  231. q = SPFH(ref n);
  232. An = (d - a * g) / (e - c * g) - (f - a * h) / (q - c * h);
  233. Ad = (p - b * g) / (e - c * g) - (e - b * h) / (q - c * h);
  234. A1 = An / Ad;
  235. return (A1);
  236. }
  237. private static Double parameterB(Int16[] y) //求系数B
  238. {
  239. Double Bn, Bd, B1;
  240. Bn = (d - a * g) / (p - b * g) - (f - a * h) / (e - b * h);
  241. Bd = (e - c * g) / (p - b * g) - (q - c * h) / (e - b * h);
  242. B1 = Bn / Bd;
  243. return (B1);
  244. }
  245. private static Double parameterB(UInt16[] y) //求系数B
  246. {
  247. Double Bn, Bd, B1;
  248. Bn = (d - a * g) / (p - b * g) - (f - a * h) / (e - b * h);
  249. Bd = (e - c * g) / (p - b * g) - (q - c * h) / (e - b * h);
  250. B1 = Bn / Bd;
  251. return (B1);
  252. }
  253. private static Double A1, B1;
  254. private static Double parameterC(Int16[] y, double sampleByM_Sps, double signalFreqByMHz, Int32 M) //求系数C
  255. {
  256. Int32 i;
  257. Double C1;
  258. for (i = 0; i < M; i++)
  259. {
  260. m[i] = Math.Cos(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); //fx为输入正弦波频率,MHz为单位,每个AD1.25G采样率 2*Pi*fx/fs
  261. n[i] = Math.Sin(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz);
  262. }
  263. A1 = parameterA(y);
  264. B1 = parameterB(y);
  265. C1 = a - A1 * b - B1 * c;
  266. return (C1);
  267. }
  268. private static Double parameterC(UInt16[] y, double sampleByM_Sps, double signalFreqByMHz, Int32 M) //求系数C
  269. {
  270. Int32 i;
  271. Double C1;
  272. for (i = 0; i < M; i++)
  273. {
  274. m[i] = Math.Cos(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz); //fx为输入正弦波频率,MHz为单位,每个AD1.25G采样率 2*Pi*fx/fs
  275. n[i] = Math.Sin(2 * 3.141592 * sampleByM_Sps * i / signalFreqByMHz);
  276. }
  277. A1 = parameterA(y);
  278. B1 = parameterB(y);
  279. C1 = a - A1 * b - B1 * c;
  280. return (C1);
  281. }
  282. /// <summary>
  283. ///
  284. /// </summary>
  285. /// <param name="databuffer"></param>
  286. /// <param name="estationresult">返回的计算结果0-offset,1-gain,2-phase</param>
  287. /// <param name="sampleByM_Sps">以Msps表示的当前数据的采样率</param>
  288. /// <param name="signalFreqByMHz">MHz表示当前输入信号的频率</param>
  289. public static WaveOffsetGainPhase SineFit(Int16[] databuffer, double sampleByM_Sps, double signalFreqByMHz)
  290. {
  291. m = new Double[databuffer.Length];
  292. n = new Double[databuffer.Length];
  293. WaveOffsetGainPhase waveOffsetGainPhase = new();
  294. //正弦拟合计算偏置和增益
  295. waveOffsetGainPhase.Offset = parameterC(databuffer, signalFreqByMHz, sampleByM_Sps, databuffer.Length);//输入100MHz正弦波,偏置
  296. waveOffsetGainPhase.Gain = Math.Sqrt(A1 * A1 + B1 * B1);//增益
  297. if (A1 < 0)
  298. waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1));//相位
  299. else
  300. waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1) + 3.141592);
  301. return waveOffsetGainPhase;
  302. }
  303. /// <summary>
  304. ///
  305. /// </summary>
  306. /// <param name="databuffer"></param>
  307. /// <param name="estationresult">返回的计算结果0-offset,1-gain,2-phase</param>
  308. /// <param name="sampleByM_Sps">以Msps表示的当前数据的采样率</param>
  309. /// <param name="signalFreqByMHz">MHz表示当前输入信号的频率</param>
  310. public static WaveOffsetGainPhase SineFit(UInt16[] databuffer, double sampleByM_Sps, double signalFreqByMHz)
  311. {
  312. m = new Double[databuffer.Length];
  313. n = new Double[databuffer.Length];
  314. WaveOffsetGainPhase waveOffsetGainPhase = new();
  315. //正弦拟合计算偏置和增益
  316. waveOffsetGainPhase.Offset = parameterC(databuffer, signalFreqByMHz, sampleByM_Sps, databuffer.Length);//输入100MHz正弦波,偏置
  317. waveOffsetGainPhase.Gain = Math.Sqrt(A1 * A1 + B1 * B1);//增益
  318. if (A1 < 0)
  319. waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1)) * 1000000;//相位
  320. else
  321. waveOffsetGainPhase.Phase = (Math.Atan(-B1 / A1) + 3.141592) * 1000000;
  322. return waveOffsetGainPhase;
  323. }
  324. }
  325. public class WaveOffsetGainPhase
  326. {
  327. public double Offset;
  328. public double Gain;
  329. public double Phase;
  330. }
  331. }