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, } /// /// 测温点位置 /// public enum EnumZoneNum { Center, CenterEdge, Edge } public class AKunTriggerChannelWaferTempData { /// /// 创建通道对应的单个晶圆温度对象 /// /// 晶圆编号 /// 测温设备通道编号 /// 当前晶圆对象的名称,Wafer or Tray,测温对象也能反馈Tray温度 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 } /// /// 通道编号,默认为1 /// 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; } /// /// 0表示无效晶圆代表Dummy晶圆或者空位,此位置的温度不能参与STC控温 /// public int PocketNum { get; set; } /// /// The reflection of 404nm /// public double Reflect1 { get; set; } /// /// The reflection of 633nm. /// public double Reflect2 { get; set; } /// /// The reflection of 950nm. /// public double Reflect3 { get; set; } public double Curvature { get; set; } /// /// false不参与控温,晶圆温度是否参与区域计算,不放片或者放Dummy时,不参与区域计算 /// 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 _waferTempDataList = new(); private static readonly object _lock = new object(); #region 重新整理温度解析 public bool ProcessReceivedData(string tcpReceive) { lock (_lock) { List tempDataList = new List(); 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 GetReflectValue() { List 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; } } }