MsAnalyzeDemo/dataAnalize/MsAnalyzeUtil.cs
2025-03-27 13:52:42 +08:00

176 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
namespace dataAnalize
{
/// <summary>
/// 安捷伦数据MS文件解析的实现类具体协议信息可以找对应的文献对应这里不单独提供了。
///
/// 后续完善考虑:
/// 1、 对于解析的数据,可以存放到实体类,然后统一进行输出。
/// 2、 转化效率上进行优化提升。
/// 3、 单例结构改造 or 静态初始化方法优化,模块封装更集中。
/// </summary>
public class MsAnalyzeUtil
{
private static string _logFilePath = "";
/// <summary>
/// 初始化分析方法
/// 可以改造为using方式将具体操作都私有化资源释放管理起来。
/// </summary>
/// <param name="logFilePath"></param>
public static void Init(string logFilePath = "")
{
_logFilePath = logFilePath;
}
/**------------------- 文件解析的主要方法 -----------------------**/
/// <summary>
/// 获取所有的色谱数据,包括其下质谱数据
/// </summary>
/// <param name="allData">全部的数据</param>
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;
}
}
/// <summary>
/// 获取所有质谱数据
/// </summary>
/// <param name="allData"></param>
/// <param name="startAddr"></param>
/// <param name="sNo"></param>
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<int, int> massPoints = new Dictionary<int, int>();
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));
}
/// <summary>
/// 解析结果的输出
/// </summary>
/// <param name="type"></param>
/// <param name="msg"></param>
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);
}
}
/*----------- 对外的公开方法 不测试时,可以私有化 -------------*/
/// <summary>
/// 在字节数组的指定位置获取数值
/// </summary>
/// <param name="srcArr"></param>
/// <param name="start"></param>
/// <param name="count">可以为24</param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 在字节数组的指定位置获取数值
/// </summary>
/// <param name="srcArr"></param>
/// <param name="start"></param>
/// <param name="count">可以为48</param>
/// <returns></returns>
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;
}
}
/// <summary>
///
/// </summary>
/// <param name="ms"></param>
/// <returns></returns>
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;
}
}
}