TaskService.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. using DevExpress.Internal.WinApi.Windows.UI.Notifications;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Configuration;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Web.Http.Results;
  12. using XdCxRhDW.Dto;
  13. namespace X3TaskServer54.Service
  14. {
  15. //业务逻辑处理类
  16. public class TaskService
  17. {
  18. private readonly string baseUrl;
  19. CancellationTokenSource cts;
  20. string DetectDir;
  21. string CapDir;
  22. string PosResDir;
  23. string StateDir;
  24. int MainSatCode, Adja1SatCode, Adja2SatCode;
  25. double[] MainSatXYZ, Adja1SatXYZ, Adja2SatXYZ;
  26. int PosDtoFactor;
  27. bool useGpuCg = false;
  28. public TaskService()
  29. {
  30. var posPlatformAddr = ConfigurationManager.AppSettings["PosPlatformAddr"].Trim();//like http://127.0.0.1:8091 or http://127.0.0.1:8091/
  31. if (posPlatformAddr.EndsWith("/"))
  32. this.baseUrl = posPlatformAddr + "api/";
  33. else
  34. this.baseUrl = posPlatformAddr + "/api/";
  35. DetectDir = ConfigurationManager.AppSettings["DetectDir"].Trim();
  36. CapDir = ConfigurationManager.AppSettings["CapDir"].Trim();
  37. PosResDir = ConfigurationManager.AppSettings["PosResDir"].Trim();
  38. StateDir = ConfigurationManager.AppSettings["StateRptDir"].Trim();
  39. var PosDtoFactorstr = ConfigurationManager.AppSettings["PosDtoFactor"].Trim();
  40. int.TryParse(PosDtoFactorstr, out PosDtoFactor);
  41. if (PosDtoFactor == 0) PosDtoFactor = 1;
  42. string useGpuStr = ConfigurationManager.AppSettings["UseGpuCg"];
  43. if (useGpuStr != null && useGpuStr.Trim() == "1")
  44. useGpuCg = true;
  45. }
  46. public void StartAsync(X3NoRefTaskHandleDto dto)
  47. {
  48. cts = new CancellationTokenSource();
  49. Task.Run(async () =>
  50. {
  51. LogHelper.Info($"【任务{dto.ID}】开始执行...");
  52. LogHelper.Info($"【任务{dto.ID}】检测结果目录[{DetectDir}]");
  53. LogHelper.Info($"【任务{dto.ID}】AD采集目录[{CapDir}]");
  54. LogHelper.Info($"【任务{dto.ID}】状态上报输出目录[{StateDir}]");
  55. //点击定位平台右上角查看接口可以在浏览器中查看平台提供的所有接口详细信息
  56. while (!cts.IsCancellationRequested)
  57. {
  58. try
  59. {
  60. #region 第1步,读取需要的配置信息
  61. if (!Directory.Exists(DetectDir))
  62. {
  63. await StopTask(dto.ID, EnumTaskStopType.Error, $"检测结果目录[{DetectDir}]不存在");
  64. return;
  65. }
  66. if (!Directory.Exists(CapDir))
  67. {
  68. await StopTask(dto.ID, EnumTaskStopType.Error, $"AD采集目录[{CapDir}]不存在");
  69. return;
  70. }
  71. Directory.CreateDirectory("DdcDir");
  72. Directory.CreateDirectory(PosResDir);
  73. Directory.CreateDirectory(StateDir);
  74. try
  75. {
  76. var mainInfo = ConfigurationManager.AppSettings["MainSatInfo"].Replace(",", ",").Trim();
  77. var adja1Info = ConfigurationManager.AppSettings["Adja1SatInfo"].Replace(",", ",").Trim();
  78. var adja2Info = ConfigurationManager.AppSettings["Adja2SatInfo"].Replace(",", ",").Trim();
  79. var arr1 = mainInfo.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
  80. var arr2 = adja1Info.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
  81. var arr3 = adja2Info.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
  82. MainSatCode = Convert.ToInt32(arr1[0]);
  83. Adja1SatCode = Convert.ToInt32(arr2[0]);
  84. Adja2SatCode = Convert.ToInt32(arr3[0]);
  85. MainSatXYZ = new double[3] { Convert.ToDouble(arr1[1]), Convert.ToDouble(arr1[2]), Convert.ToDouble(arr1[3]) };
  86. Adja1SatXYZ = new double[3] { Convert.ToDouble(arr2[1]), Convert.ToDouble(arr2[2]), Convert.ToDouble(arr2[3]) };
  87. Adja2SatXYZ = new double[3] { Convert.ToDouble(arr3[1]), Convert.ToDouble(arr3[2]), Convert.ToDouble(arr3[3]) };
  88. }
  89. catch
  90. {
  91. await StopTask(dto.ID, EnumTaskStopType.Error, $"任务处理服务配置文件卫星信息解析出错");
  92. return;
  93. }
  94. #endregion
  95. #region 第2步,扫描检测结果目录
  96. //同一个AD文件得到的不同频点的检测文件FlagNo相同
  97. var groupFiles = Directory.EnumerateFiles(DetectDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToCheckResFile(p))
  98. .GroupBy(m => Convert.ToInt64(m.DayTime.ToString("yyyyMMdd") + m.FlagNo)).OrderBy(m => m.Key);
  99. if (!groupFiles.Any())
  100. {
  101. LogHelper.Info($"【任务{dto.ID}】等待扫描文件...");
  102. await Task.Delay(10000);
  103. }
  104. foreach (var groupFile in groupFiles)//每一组文件代表同一个时刻的,gourpFile时相同时刻的不同频点的文件
  105. {
  106. if (cts.IsCancellationRequested) break;
  107. LogHelper.Info($"【任务{dto.ID}】正在解析序号为{groupFile.First().FlagNo}的检测引导文件");
  108. List<SlotsInfo> listSlotsInfo = new List<SlotsInfo>();//多个频点的时隙结果
  109. int idx = 0;
  110. DateTime adTime = DateTime.MinValue;
  111. foreach (var item in groupFile)
  112. {
  113. if (cts.IsCancellationRequested) break;
  114. var slotsInfo = SlotHelper.GetFileSlots(item.File);//某个频点的所有时隙
  115. adTime = slotsInfo.AdTime;
  116. if (idx == 0)
  117. LogHelper.Info($"【任务{dto.ID}】序号为{groupFile.First().FlagNo}的检测引导文件对应采集时刻{slotsInfo.AdTime:yyyyMMddHHmmss}");
  118. idx++;
  119. if (slotsInfo.Slots.Any())
  120. listSlotsInfo.Add(slotsInfo);
  121. else
  122. File.Delete(item.File);//删除没有信号的检测引导文件
  123. }
  124. var adFiles = Directory.EnumerateFiles(CapDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToAdFile(p))
  125. .Where(p => p.AdTime == adTime);
  126. if (!listSlotsInfo.Any())
  127. {
  128. //没有突发信号,删除所有对应时刻的采集文件
  129. foreach (var item in adFiles)
  130. {
  131. File.Delete(item.File);
  132. }
  133. continue;
  134. }
  135. if (adFiles.Count() != 3)
  136. {
  137. LogHelper.Warning($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻原始AD文件个数不为3,跳过此组文件");
  138. //AD数据不全,删除所有对应时刻的采集文件
  139. foreach (var item in adFiles)
  140. {
  141. File.Delete(item.File);
  142. }
  143. continue;
  144. }
  145. var first = listSlotsInfo.First();
  146. var sigs = listSlotsInfo.Select(p => new DDCSig() { FreqDownHz = (int)(p.FreqDownMHz * 1e6), Mult = (int)first.Multi, Slots = p });
  147. List<DDCFile> chDDCFiles = new List<DDCFile>();//同一个时刻多个频点多个通道的DDC数据
  148. LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻3路AD文件开始DDC处理开始,共{sigs.Count()}个频点...");
  149. Stopwatch sw = new Stopwatch();
  150. sw.Start();
  151. var listTask = new List<Task>();
  152. foreach (var adFile in adFiles)
  153. {
  154. var task = Task.Run(() =>
  155. {
  156. var ddcRes = DDCHelper.DDC(adFile.File, adFile.AdTime, adFile.ChNo, (long)(first.FsampleM * 1e6), (long)(227 * 1e6), "DdcDir", sigs);
  157. chDDCFiles.AddRange(StringToDDCFile(ddcRes));
  158. }, cts.Token);
  159. listTask.Add(task);
  160. }
  161. await Task.WhenAll(listTask);
  162. if (cts.IsCancellationRequested) break;
  163. sw.Stop();
  164. LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻3路AD文件DDC处理完成,耗时{sw.ElapsedMilliseconds}ms");
  165. if (!chDDCFiles.Any())
  166. {
  167. LogHelper.Error($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻3路AD文件DDC处理无结果");
  168. continue;
  169. }
  170. var groupDDCFiles = chDDCFiles.GroupBy(p => p.FreqDownMHz);
  171. listTask.Clear();
  172. foreach (var group in groupDDCFiles)
  173. {
  174. //group:同一个时刻同一个频点的多个通道数据
  175. var task = Task.Run(async () =>
  176. {
  177. var ch0File = group.Where(p => p.ChNo == 0).FirstOrDefault();
  178. var ch1File = group.Where(p => p.ChNo == 1).FirstOrDefault();
  179. var ch2File = group.Where(p => p.ChNo == 2).FirstOrDefault();
  180. if (ch0File == null)
  181. {
  182. LogHelper.Warning($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到主星信号ch0文件,跳过此组数据");
  183. return;
  184. }
  185. if (ch1File == null)
  186. {
  187. LogHelper.Warning($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到邻1星信号ch1文件,跳过此组数据");
  188. return;
  189. }
  190. if (ch2File == null)
  191. {
  192. LogHelper.Warning($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到邻2星信号ch2文件,跳过此组数据");
  193. return;
  194. }
  195. var sig = sigs.FirstOrDefault(p => p.FreqDownHz == (int)(group.Key * 1e6));
  196. if (cts.IsCancellationRequested) return;
  197. LogHelper.Info($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-CPU参估开始,共{sig.Slots.Slots.Count}个突发...");
  198. sw.Start();
  199. string mainFile = await HttpHelper.UploadFileAsync(ch0File.File, baseUrl, token: cts.Token);//主星文件
  200. string adja1File = await HttpHelper.UploadFileAsync(ch1File.File, baseUrl, token: cts.Token);//邻1星文件
  201. string adja2File = await HttpHelper.UploadFileAsync(ch2File.File, baseUrl, token: cts.Token);//邻2星文件
  202. var cgDto = new CpuCgMultiDto()
  203. {
  204. dtCenter = 0,
  205. dtRange = 40000,
  206. file1 = mainFile,
  207. file2 = adja1File,
  208. samplingRate = ch0File.Fs,
  209. smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList(),
  210. snrThreshold = 15,
  211. };
  212. var result1 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
  213. if (result1.code != 200)
  214. {
  215. LogHelper.Error($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星邻1星CPU参估出错.{result1.msg}");
  216. return;
  217. }
  218. cgDto = new CpuCgMultiDto()
  219. {
  220. dtCenter = 0,
  221. dtRange = 40000,
  222. file1 = mainFile,
  223. file2 = adja2File,
  224. samplingRate = ch0File.Fs,
  225. smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList(),
  226. snrThreshold = 15,
  227. };
  228. var result2 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
  229. sw.Stop();
  230. if (result2.code != 200)
  231. {
  232. LogHelper.Error($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星邻2星CPU参估出错.{result2.msg}");
  233. return;
  234. }
  235. LogHelper.Info($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-CPU参估完成,耗时{sw.ElapsedMilliseconds}ms");
  236. var data1 = result1.data;
  237. var data2 = result2.data;
  238. if (data1.Count != data2.Count || data1.Count != cgDto.smpPositions.Count)
  239. {
  240. LogHelper.Error($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-参估结果个数和检测结果个数不匹配");
  241. return;
  242. }
  243. sw.Start();
  244. for (int i = 0; i < data1.Count; i++)
  245. {
  246. try
  247. {
  248. if (cts.IsCancellationRequested) break;
  249. X3TwoDtoNoParPosDto x3 = new X3TwoDtoNoParPosDto()
  250. {
  251. TaskID = dto.ID,
  252. //SigTime = adTime.AddSeconds(data1[i].Smpstart / (double)ch0File.Fs),
  253. SigTime = adTime.AddSeconds(data1[i].TimeSeconds),
  254. MainCode = MainSatCode,
  255. Adja1Code = Adja1SatCode,
  256. Adja2Code = Adja2SatCode,
  257. MainX = MainSatXYZ[0],
  258. MainY = MainSatXYZ[1],
  259. MainZ = MainSatXYZ[2],
  260. Adja1X = Adja1SatXYZ[0],
  261. Adja1Y = Adja1SatXYZ[1],
  262. Adja1Z = Adja1SatXYZ[2],
  263. Adja2X = Adja2SatXYZ[0],
  264. Adja2Y = Adja2SatXYZ[1],
  265. Adja2Z = Adja2SatXYZ[2],
  266. Dto1 = PosDtoFactor * data1[i].Dt,
  267. Dfo1 = data1[i].Df,
  268. Snr1 = data1[i].Snr,
  269. Dto2 = PosDtoFactor * data2[i].Dt,
  270. Dfo2 = data2[i].Df,
  271. Snr2 = data2[i].Snr,
  272. SatTxLon = dto.CapLon,
  273. SatTxLat = dto.CapLat,
  274. FreqDown = ch0File.FreqDownMHz * 1e6,
  275. FreqUp = (ch0File.FreqDownMHz + 44) * 1e6,
  276. CheckRes = new CheckResDto()
  277. {
  278. FileName = Path.GetFileName(ch0File.File),
  279. SmpStart = sig.Slots.Slots[i].StartPoint,
  280. SmpCount = sig.Slots.Slots[i].Len,
  281. PosCheckType = EnumPosCheckTypeDto.DAMA,
  282. }
  283. };
  284. var result = await HttpHelper.PostRequestAsync<PosResDto>(baseUrl + "Pos/PosX3TwoDtoNoParAsync", x3);
  285. if (result.code != 200)
  286. {
  287. LogHelper.Error($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-时隙位置{data1[i].Smpstart}定位异常.{result.msg}");
  288. }
  289. else
  290. {
  291. var posRes = result.data;
  292. double posLon = posRes.PosLon;
  293. double posLat = posRes.PosLat;
  294. if (x3.Snr1 == 0 || x3.Snr2 == 0)
  295. {
  296. posLon = 0;
  297. posLat = 0;
  298. }
  299. StringBuilder sb = new StringBuilder();
  300. sb.Append($"{x3.SigTime:yyyy}\t");
  301. sb.Append($"{x3.SigTime:MM}\t");
  302. sb.Append($"{x3.SigTime:dd}\t");
  303. sb.Append($"{x3.SigTime:HH}\t");
  304. sb.Append($"{x3.SigTime:mm}\t");
  305. sb.Append($"{x3.SigTime:ss}\t");
  306. sb.Append($"{x3.SigTime:fff}\t");
  307. sb.Append($"{x3.CheckRes.SmpCount * 1000 / ch0File.Fs:D4}\t");//信号持续时间ms
  308. sb.Append($"{Convert.ToInt64(group.First().FreqDownMHz * 1e6):D12}\t");//下行频点
  309. sb.Append($"{Convert.ToInt64((group.First().FreqDownMHz + 44) * 1e6):D12}\t");//上行频点
  310. sb.Append($"{4}\t");//信号样式(暂定有这些1:CPM,2:BPSK,4:QPSK,9:其它),
  311. sb.Append($"{0:D4}\t");//目标序号
  312. sb.Append($"res\t");
  313. sb.Append($"{Convert.ToInt64(posLon * 1e6):D10}\t");
  314. sb.Append($"{Convert.ToInt64(posLat * 1e6):D10}\t");
  315. sb.Append($"{Convert.ToInt64(0 * 1e3):D8}\t");//定位误差km
  316. sb.Append($"{Convert.ToInt64(x3.Dto1 * 1e2):D10}\t");
  317. sb.Append($"{Convert.ToInt64(x3.Dfo1 * 1e2):D10}\t");
  318. sb.Append($"{Convert.ToInt64(x3.Snr1 * 1e2):D6}\t");
  319. sb.Append($"{Convert.ToInt64(x3.Dto2 * 1e2):D10}\t");
  320. sb.Append($"{Convert.ToInt64(x3.Dfo2 * 1e2):D10}\t");
  321. sb.Append($"{Convert.ToInt64(x3.Snr2 * 1e2):D6}\t");
  322. sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
  323. sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
  324. sb.Append($"{Convert.ToInt64(0 * 1e2):D6}\t");
  325. sb.Append($"{0:D8}\t");//长轴
  326. sb.Append($"{0:D8}\t");//短轴
  327. sb.Append($"{0:D7}\t");//倾角
  328. sb.Append($"{data1.Count:D2}\t");//时隙属性
  329. sb.Append($"{1}\t");//所属卫星
  330. sb.Append($"{950:D3}\t");//置信度
  331. sb.Append($"{3}\t");//定位体制(星地=3)
  332. sb.Append($"{1335:D12}");//符号速率bps 12个
  333. sb.Append("\r\n");
  334. string resFile = Path.Combine(PosResDir, $"高轨三星定位结果_{posRes.SigTime:yyyyMMdd}.txt");
  335. File.AppendAllText(resFile, sb.ToString());
  336. }
  337. }
  338. catch (Exception ex)
  339. {
  340. LogHelper.Error($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-时隙位置{data1[i].Smpstart}定位异常", ex);
  341. }
  342. }
  343. sw.Stop();
  344. LogHelper.Info($"【任务{dto.ID}】{adTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-定位完成,耗时{sw.ElapsedMilliseconds}ms");
  345. //删除DDC文件
  346. File.Delete(ch0File.File);
  347. File.Delete(ch1File.File);
  348. File.Delete(ch2File.File);
  349. }, cts.Token);
  350. listTask.Add(task);
  351. }
  352. await Task.WhenAll(listTask);
  353. }
  354. #endregion
  355. }
  356. catch (TaskCanceledException ex)
  357. {
  358. LogHelper.Warning($"【任务{dto.ID}】处理结束,用户手动终止", ex.InnerException);
  359. }
  360. catch (Exception ex)
  361. {
  362. if (ex.InnerException != null && ex.InnerException.GetType() == typeof(TaskCanceledException))
  363. LogHelper.Warning($"【任务{dto.ID}】处理结束,用户手动终止", ex.InnerException);
  364. else
  365. LogHelper.Error($"【任务{dto.ID}】任务执行出错", ex);
  366. continue;
  367. }
  368. }
  369. }, cts.Token);
  370. }
  371. public void Stop()
  372. {
  373. cts?.Cancel();
  374. }
  375. private async Task StopTask(int taskID, EnumTaskStopType type, string stopReason)
  376. {
  377. await Task.Delay(2000);
  378. if (type == EnumTaskStopType.Properly)
  379. {
  380. LogHelper.Info($"【任务{taskID}】{stopReason}");
  381. }
  382. else
  383. {
  384. LogHelper.Error($"【任务{taskID}】{stopReason}");
  385. }
  386. TaskStopHandleDto stopDto = new TaskStopHandleDto() { ID = taskID, StopType = type, StopReason = stopReason };
  387. var stopResp = await HttpHelper.PostRequestAsync(baseUrl + "Task/StopTask", stopDto);
  388. if (stopResp.code != 200)
  389. {
  390. LogHelper.Error($"【任务{taskID}】停止异常.{stopResp.msg}");
  391. }
  392. }
  393. private CheckResFile StringToCheckResFile(string file)
  394. {
  395. //YUFO_252.050MHz_20240409_1398.dat
  396. string fileName = Path.GetFileNameWithoutExtension(file).ToUpper();
  397. var arr = fileName.Split(new string[] { "_", "MHZ" }, StringSplitOptions.RemoveEmptyEntries);
  398. var dayTime = DateTime.ParseExact(arr[2], "yyyyMMdd", null);
  399. CheckResFile res = new CheckResFile()
  400. {
  401. DayTime = dayTime,
  402. File = file,
  403. FreqDownMHz = Convert.ToDouble(arr[1]),
  404. FlagNo = Convert.ToInt64(arr[3]),
  405. };
  406. return res;
  407. }
  408. private AdFile StringToAdFile(string file)
  409. {
  410. //20240409094240_ADC_ch02.dat
  411. var name = Path.GetFileNameWithoutExtension(file).ToUpper();
  412. var arr = name.Split(new string[] { "_", "CH" }, StringSplitOptions.RemoveEmptyEntries);
  413. var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
  414. AdFile adFile = new AdFile()
  415. {
  416. File = file,
  417. AdTime = time,
  418. ChNo = Convert.ToInt32(arr[2]),
  419. };
  420. return adFile;
  421. }
  422. public DDCFile StringToDDCFile(string file)
  423. {
  424. //20240409094240_252.025_C109375_ch0.dat
  425. var name = Path.GetFileNameWithoutExtension(file).ToUpper();
  426. var arr = name.Split(new string[] { "_", "MHz", "C", "H" }, StringSplitOptions.RemoveEmptyEntries);
  427. var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
  428. double freqDown = Convert.ToDouble(arr[1]);
  429. int fs = Convert.ToInt32(arr[2]);
  430. int chNo = Convert.ToInt32(arr[3]);
  431. return new DDCFile()
  432. {
  433. AdTime = time,
  434. ChNo = chNo,
  435. File = file,
  436. FreqDownMHz = freqDown,
  437. Fs = fs
  438. };
  439. }
  440. public List<DDCFile> StringToDDCFile(List<string> files)
  441. {
  442. List<DDCFile> list = new List<DDCFile>();
  443. foreach (var item in files)
  444. {
  445. list.Add(StringToDDCFile(item));
  446. }
  447. return list;
  448. }
  449. }
  450. }