using System; using System.Collections.Generic; namespace dataAnalize { /// /// 安捷伦数据MS文件,解析的实现类,具体协议信息,可以找对应的文献对应,这里不单独提供了。 /// /// 后续完善考虑: /// 1、 对于解析的数据,可以存放到实体类,然后统一进行输出。 /// 2、 转化效率上进行优化提升。 /// 3、 单例结构改造 or 静态初始化方法优化,模块封装更集中。 /// public class MsAnalyzeUtil { private static string _logFilePath = ""; /// /// 初始化分析方法 /// 可以改造为using方式,将具体操作都私有化,资源释放管理起来。 /// /// public static void Init(string logFilePath = "") { _logFilePath = logFilePath; } /**------------------- 文件解析的主要方法 -----------------------**/ /// /// 获取所有的色谱数据,包括其下质谱数据 /// /// 全部的数据 public static void GetChrom(byte[] allData) { OutResult("总体", "总字节数:" + allData.Length); int number = GetIntLitter(allData, 278, 281 - 278 + 1); // 色谱总数量 int startAddr = GetIntLitter(allData, 260, 263 - 260 + 1); //第一个色谱的地址 OutResult("头信息", string.Format("色谱数据信息: 色谱点数-{0}", number)); int startBit = 2 * (startAddr - 1); //第一个色谱的位地址 int startMass, time, abundance; for (int i = 0; i < number; i++) { startMass = GetIntLitter(allData, startBit, 4); time = GetIntLitter(allData, startBit + 4, 4); abundance = GetIntLitter(allData, startBit + 8, 4); OutResult("色谱", String.Format("{0,4}:[{3},{1},{2}]", i + 1, MsToMin(time), abundance, time)); GetAllMass(allData, startMass, i + 1); startBit = startBit + 12; } } /// /// 获取所有质谱数据 /// /// /// /// private static void GetAllMass(byte[] allData, int startAddr, int sNo) { int startBit = startAddr * 2; int time = GetIntLitter(allData, startBit, 4); int number = GetIntLitter(allData, startBit + 10, 2); int maxMass = GetIntLitter(allData, startBit + 12, 2); int maxAbundance = GetIntLitter(allData, startBit + 14, 2); OutResult("质谱数据", String.Format("{0,4}:保留时间-{1},质谱点数-{2},最高峰-[{3},{4}]", sNo, MsToMin(time), number, maxMass, maxAbundance)); Dictionary massPoints = new Dictionary(); string allPoints = ""; startBit = startBit + 16; int mass, abundance; for (int i = 0; i < number; i++) { mass = GetIntLitter(allData, startBit, 2); abundance = GetIntLitter(allData, startBit + 2, 2); abundance = abundance / 20; massPoints.Add(mass, abundance); allPoints += string.Format("[{0},{1}] ", mass, abundance); startBit = startBit + 4; } OutResult("质谱数据", String.Format("{0,4}:{1}", sNo, allPoints)); } /// /// 解析结果的输出 /// /// /// private static void OutResult(string type, string msg) { if (string.IsNullOrEmpty(_logFilePath)) { string str = string.Format("【{0}】 {1}", type, msg) + Environment.NewLine; FileHelper.AppendText(_logFilePath, str); } } /*----------- 对外的公开方法 不测试时,可以私有化 -------------*/ /// /// 在字节数组的指定位置获取数值 /// /// /// /// 可以为:2,4 /// public static int GetIntLitter(byte[] srcArr, int start, int count) { byte[] times = new byte[count]; Buffer.BlockCopy(srcArr, start, times, 0, count); Array.Reverse(times); if (count == 4) { int number = BitConverter.ToInt32(times, 0); return number; } else { int number = BitConverter.ToInt16(times, 0); return number; } } /// /// 在字节数组的指定位置获取数值 /// /// /// /// 可以为:4,8 /// public static double GetFloatLitter(byte[] srcArr, int start, int count) { byte[] times = new byte[count]; Buffer.BlockCopy(srcArr, start, times, 0, 4); Array.Reverse(times); if (count == 4) { double number = BitConverter.ToSingle(times, 0); return number; } else { double number = BitConverter.ToDouble(times, 0); return number; } } /// /// /// /// /// public static double MsToMin(int ms) { int sToMs = 60 * 1000; int m = ms / sToMs; double mx = (ms % sToMs) / (sToMs * 1.0); double min = Math.Round(m + mx, 5, MidpointRounding.AwayFromZero); return min; } } }