159 lines
6.6 KiB
C#
159 lines
6.6 KiB
C#
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}");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|