MoS2/Framework/MECF.Framework.RT.EquipmentLibrary/HardwareUnits/Temps/AKunTriggerTemp/AKunTriggerChannelWaferTempData.cs

288 lines
10 KiB
C#
Raw Normal View History

2026-08-18 14:04:28 +08:00
using Aitex.Core.RT.DataCenter;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
{
public enum DataType
{
Wafer,
Tray,
}
/// <summary>
/// 测温点位置
/// </summary>
public enum EnumZoneNum
{
Center,
CenterEdge,
Edge
}
public class AKunTriggerChannelWaferTempData
{
/// <summary>
/// 创建通道对应的单个晶圆温度对象
/// </summary>
/// <param name="waferNum">晶圆编号</param>
/// <param name="ch">测温设备通道编号</param>
/// <param name="name">当前晶圆对象的名称Wafer or Tray,测温对象也能反馈Tray温度</param>
public AKunTriggerChannelWaferTempData(int waferNum, int ch = 1, string name = "Wafer")
{
Detector = ch;
WaferNum = waferNum;
WaferName = $"CH{Detector}.{name}{waferNum}"; //eg: CH1.Wafer1 CH1.Wafer2 CH2.Wafer1 CH2.Wafer2
}
/// <summary>
/// 通道编号默认为1
/// </summary>
public int Detector { get; set; }
public string WaferName { get; set; }
public int WaferNum { get; set; }
public DataType Type { get; set; }
public double Temp { get; set; }
public int ZoneNum { get; set; }
public EnumZoneNum ZoneNumSelect { get; set; }
/// <summary>
/// 0表示无效晶圆代表Dummy晶圆或者空位此位置的温度不能参与STC控温
/// </summary>
public int PocketNum { get; set; }
/// <summary>
/// The reflection of 404nm
/// </summary>
public double Reflect1 { get; set; }
/// <summary>
/// The reflection of 633nm.
/// </summary>
public double Reflect2 { get; set; }
/// <summary>
/// The reflection of 950nm.
/// </summary>
public double Reflect3 { get; set; }
public double Curvature { get; set; }
/// <summary>
/// false不参与控温晶圆温度是否参与区域计算不放片或者放Dummy时不参与区域计算
/// </summary>
public bool CalZone { get; set; }
public void UpData(AKunTriggerChannelWaferTempData newData)
{
// 确保传入的 newData 对象不为空
if (newData == null)
{
throw new ArgumentNullException(nameof(newData));
}
Detector = newData.Detector;
WaferNum = newData.WaferNum;
Temp = newData.Temp;
ZoneNum = newData.ZoneNum;
ZoneNumSelect = newData.ZoneNumSelect;
Reflect1 = newData.Reflect1;
Curvature = newData.Curvature;
}
}
public class AKunTriggerTempDataManager(int waferNum, double minTemp)
{
private readonly int _waferNum = waferNum;
private double _minTemp = minTemp;
private List<AKunTriggerChannelWaferTempData> _waferTempDataList = new();
private static readonly object _lock = new object();
#region
public bool ProcessReceivedData(string tcpReceive)
{
lock (_lock)
{
List<AKunTriggerChannelWaferTempData> tempDataList = new List<AKunTriggerChannelWaferTempData>();
AKunTriggerChannelWaferTempData aKunChWaferTempData;
string[] keyValuePairs = tcpReceive.Split('\0');
for (int i = 0; i < keyValuePairs.Length - 1; i++)
{
aKunChWaferTempData = new AKunTriggerChannelWaferTempData(-999);
string[] keyValues = keyValuePairs[i].Split(',');
foreach (string pair in keyValues)
{
string[] keyValue = pair.Split('=');
switch (keyValue[0])
{
case "Detector":
aKunChWaferTempData.Detector = int.Parse(keyValue[1]);
break;
case "PocketNum":
aKunChWaferTempData.PocketNum = int.Parse(keyValue[1]);
break;
case "WaferNum":
aKunChWaferTempData.WaferNum = int.Parse(keyValue[1]);
break;
case "CalZone":
aKunChWaferTempData.CalZone = int.Parse(keyValue[1]) == 1;
break;
case "TTemp":
aKunChWaferTempData.Temp = double.Parse(keyValue[1]);
break;
case "ZoneNum":
aKunChWaferTempData.ZoneNum = int.Parse(keyValue[1]);
aKunChWaferTempData.ZoneNumSelect =
(EnumZoneNum)Enum.Parse(typeof(EnumZoneNum), keyValue[1]);
break;
case "Reflec1":
aKunChWaferTempData.Reflect1 = double.Parse(keyValue[1]);
break;
case "Reflec2":
aKunChWaferTempData.Reflect2 = double.Parse(keyValue[1]);
break;
case "Reflec3":
aKunChWaferTempData.Reflect3 = double.Parse(keyValue[1]);
break;
case "Curvature":
aKunChWaferTempData.Curvature = double.Parse(keyValue[1]);
break;
}
}
if (aKunChWaferTempData.WaferNum == -999)
return true;
tempDataList.Add(aKunChWaferTempData);
}
_waferTempDataList = tempDataList;
return true;
}
}
public bool[] GetCalZone()
{
bool[] calZone = new bool[_waferNum];
if (_waferTempDataList.Count < _waferNum)
return calZone;
for (int i = 0; i < _waferNum; i++) //只有前面几个数据,是需要统计是否参与计算
{
calZone[i] = _waferTempDataList[i].CalZone;
}
return calZone;
}
//public double[] GetWaferTemp()
//{
// double[] waferTemps = Enumerable.Repeat(_minTemp, _waferNum).ToArray();
// if (_waferTempDataList.Count < _waferNum)
// return waferTemps;
// int count = (_waferTempDataList.Count - 1) / _waferNum ;//分区数计算,最后一个数据是托盘的,所以减一,
// if ((_waferTempDataList.Count - 1) % _waferNum != 0)//分区数量不是整数,温度不解析防呆,
// return waferTemps;
// for (int i = 0; i < _waferNum; i++) //Wafer温度只取每个晶圆的第一个设置的中心温度
// {
// var index = i * count;
// waferTemps[i] = _waferTempDataList[index].Temp;//直接使用第一个中心温度作为中心温度
// //要求不判断中心点,只用第一个分区温度
// //for (int j = index; j < index + count ; j++)
// //{
// // if(_waferTempDataList[j].ZoneNum==0)
// // {
// // waferTemps[i] = _waferTempDataList[j].Temp;//有中心温度设置,获取第一个中心温度作为晶圆温度
// // break;
// // }
// //}
// }
// return waferTemps;
//}
public double[] GetWaferTemp()
{
double[] waferTemps = Enumerable.Repeat(_minTemp, _waferNum).ToArray();
if (_waferTempDataList.Count < _waferNum)
return waferTemps;
//这届
for (int i = 0; i < _waferNum; i++) //只有前面几个温度数据,才是需要统计的
{
waferTemps[i] = _waferTempDataList[i].Temp;
}
//_waferTempDataList[i].CalZone
//for (int i = 0; i < _waferNum; i++)
//{
// //根据编号,获取同一分区所有温度数据
// var tempCaches = _waferTempDataList.Where(item => item.PocketNum == i + 1);
// if (tempCaches != null && tempCaches.Count() > 0)
// {
// //同一分区所有温度数据查找第一个CalZone为true的温度数据
// var matchedItem = tempCaches.Where(item => item.CalZone).FirstOrDefault();
// if (matchedItem != null)
// waferTemps[i] = matchedItem.Temp;
// else
// waferTemps[i] = tempCaches.First().Temp;//未设置CalZone为true使用当前分区第一个数据作为默认温度值
// }
// else
// waferTemps[i] = -1;//没有分区温度是乱的无法解析,使用-1作为提示
//}
return waferTemps;
}
public double GetTrayTemp()
{
if (_waferTempDataList.Count == 0)
return _minTemp;
return _waferTempDataList[_waferTempDataList.Count - 1].Temp; //最后一个数据才是Tray温度
}
#endregion
public List<double[]> GetReflectValue()
{
List<double[]> reflectList = Enumerable.Range(0, _waferNum)
.Select(_ => new double[3]) // 每个数组默认元素为 0
.ToList();
if (_waferTempDataList.Count < _waferNum)
return reflectList;
for (int i = 0; i < _waferNum; i++) //只有前面几个反射率数据,才是需要统计的
{
var data = _waferTempDataList[i];
reflectList.Add([data.Reflect1, data.Reflect2, data.Reflect3]);
}
return reflectList;
}
}
}