Files
2026-01-16 19:20:19 +08:00

159 lines
6.6 KiB
C#
Raw Permalink 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;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Data
{
using System;
using System.Collections.Generic;
using System.Linq;
public class LaserFlashAnalyzer
{
/// <summary>
/// 查找激光触发点(信号突然上升的点)
/// </summary>
/// <param name="temperatureData">温度数据列表</param>
/// <param name="samplingFrequency">采样频率(Hz)uint类型</param>
/// <param name="noiseThreshold">噪声阈值(℃)</param>
/// <param name="windowSize">检测窗口大小(点数)</param>
/// <returns>触发点的索引位置</returns>
public int FindLaserTriggerPoint(List<double> temperatureData, uint samplingFrequency,
double noiseThreshold = 0.5, int windowSize = 5)
{
if (samplingFrequency == 0)
throw new ArgumentException("采样频率必须大于0", nameof(samplingFrequency));
// 计算时间间隔(秒)
double timeInterval = 1.0 / (double)samplingFrequency;
// 计算移动平均差分以检测突变
List<double> diffs = new List<double>();
for (int i = windowSize; i < temperatureData.Count; i++)
{
double prevAvg = temperatureData.Skip(i - windowSize).Take(windowSize).Average();
double currentAvg = temperatureData.Skip(i - windowSize + 1).Take(windowSize).Average();
diffs.Add(currentAvg - prevAvg);
}
// 找到差分超过阈值且是第一个显著上升的点
for (int i = 0; i < diffs.Count; i++)
{
if (diffs[i] > noiseThreshold * windowSize * timeInterval)
{
return i + windowSize;
}
}
throw new InvalidOperationException("无法确定激光触发点");
}
/// <summary>
/// 从触发点开始计算半升温时间
/// </summary>
/// <param name="temperatureData">温度数据列表</param>
/// <param name="samplingFrequency">采样频率(Hz)uint类型</param>
/// <param name="triggerIndex">触发点索引</param>
/// <returns>半升温时间(秒)</returns>
public double CalculateHalfRiseTimeFromTrigger(List<double> temperatureData,
uint samplingFrequency, int triggerIndex)
{
if (samplingFrequency == 0)
throw new ArgumentException("采样频率必须大于0", nameof(samplingFrequency));
if (triggerIndex < 0 || triggerIndex >= temperatureData.Count)
throw new ArgumentOutOfRangeException(nameof(triggerIndex));
double timeInterval = 1.0 / (double)samplingFrequency;
double baseline = temperatureData[triggerIndex];
double maxTemp = temperatureData.Skip(triggerIndex).Max();
double halfRiseTemp = baseline + (maxTemp - baseline) / 2.0;
// 查找跨越半升温点的两个数据点
int beforeIndex = -1, afterIndex = -1;
for (int i = triggerIndex; i < temperatureData.Count - 1; i++)
{
if (temperatureData[i] <= halfRiseTemp && temperatureData[i + 1] >= halfRiseTemp)
{
beforeIndex = i;
afterIndex = i + 1;
break;
}
}
if (beforeIndex == -1 || afterIndex == -1)
{
throw new InvalidOperationException("无法确定半升温点");
}
// 线性插值计算精确时间
double tempBefore = temperatureData[beforeIndex];
double tempAfter = temperatureData[afterIndex];
double timeRatio = (halfRiseTemp - tempBefore) / (tempAfter - tempBefore);
// 计算实际时间(秒)
double timeBefore = beforeIndex * timeInterval;
double timeAfter = afterIndex * timeInterval;
return timeBefore + (timeAfter - timeBefore) * timeRatio - triggerIndex * timeInterval;
}
/// <summary>
/// 综合分析方法
/// </summary>
/// <param name="temperatureData">温度数据列表</param>
/// <param name="samplingFrequency">采样频率(Hz)uint类型</param>
/// <returns>半升温时间(秒)</returns>
public double AnalyzeLaserFlashData(List<double> temperatureData, uint samplingFrequency)
{
int triggerIndex = FindLaserTriggerPoint(temperatureData, samplingFrequency);
Console.WriteLine($"检测到激光触发点: 索引={triggerIndex}, 时间={triggerIndex / (double)samplingFrequency:F6}s");
return CalculateHalfRiseTimeFromTrigger(temperatureData, samplingFrequency, triggerIndex);
}
}
// 使用示例
public class Program2
{
public static void Main2()
{
// 示例数据(平滑后的温度数据)
var temperatureData = new List<double> {
25.1, 25.0, 25.2, 25.1, 25.3, // 基线噪声
25.2, 25.8, 26.5, 27.8, 29.5, // 激光触发点在这附近
32.1, 35.8, 39.2, 42.0, 43.5, // 温度上升
43.2, 42.8, 42.0, 41.2 // 温度下降
};
uint samplingFrequency = 10000; // 10 kHz采样频率
var analyzer = new LaserFlashAnalyzer();
try
{
double tHalf = analyzer.AnalyzeLaserFlashData(temperatureData, samplingFrequency);
Console.WriteLine($"半升温时间: {tHalf:F6} 秒");
// 可选:显示更多信息
int triggerIndex = analyzer.FindLaserTriggerPoint(temperatureData, samplingFrequency);
double maxTemp = temperatureData.Skip(triggerIndex).Max();
double baseline = temperatureData[triggerIndex];
Console.WriteLine($"基线温度: {baseline:F2}℃, 最大温升: {maxTemp - baseline:F2}℃");
// 示例:使用不同的采样频率
uint highFreq = 1000000; // 1 MHz
Console.WriteLine($"\n模拟1MHz采样频率结果:");
double tHalfHighFreq = analyzer.CalculateHalfRiseTimeFromTrigger(
temperatureData, highFreq, triggerIndex);
Console.WriteLine($"半升温时间(1MHz): {tHalfHighFreq:F6} 秒");
}
catch (Exception ex)
{
Console.WriteLine($"分析失败: {ex.Message}");
}
}
}
}