using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using Aitex.Common.Util; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.SCCore; namespace JetVirgoPM.PMs.RecipeExecutors { public class JetVirgoPMRecipeFileContext : IRecipeFileContext { public string GetRecipeDefiniton(string chamberType) { try { string recipeSchema = PathManager.GetCfgDir() + $@"\Recipe\JetVirgoPM\Process\RecipeFormat.xml"; XmlDocument xmlDom = new XmlDocument(); xmlDom.Load(recipeSchema); bool epdInstalled = SC.ContainsItem("System.SetUp.EPD.IsInstalled") && SC.GetValue($"System.SetUp.EPD.IsInstalled"); if (!epdInstalled) { var nodeEndPoint = xmlDom.SelectSingleNode( string.Format( "/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='System.SetUp.EPDInstalled']")) as XmlElement; if (nodeEndPoint != null) { nodeEndPoint.ParentNode.RemoveChild(nodeEndPoint); } } double rfPowerRange1 = SC.GetValue($"{chamberType}.Rf1.PowerRange"); double rfPowerRangeBias1 = SC.GetValue($"{chamberType}.BiasRf1.PowerRange"); bool rfEnablePulsing1 = SC.GetValue($"{chamberType}.Rf1.EnablePulsingFunction"); bool rfEnableBias1 = SC.GetValue($"{chamberType}.BiasRf1.EnableBiasRF"); var nodeRfPowerBias1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.SetPower']")) as XmlElement; var nodeMatchModeBias1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.SetMatchProcessMode']")) as XmlElement; var nodeMatchC1Bias1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.SetMatchPositionC1']")) as XmlElement; var nodeMatchC2Bias1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.SetMatchPositionC2']")) as XmlElement; var nodeRfPower1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf1.SetPower']")) as XmlElement; var nodeRfPowerBiasSoft1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.SoftTolerance']")) as XmlElement; var nodeRfPowerBiasHard1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf1.HardTolerance']")) as XmlElement; if (nodeRfPower1 != null) { nodeRfPower1.SetAttribute("Max", (int)rfPowerRange1 + ""); } if (nodeRfPowerBias1 != null) { nodeRfPowerBias1.SetAttribute("Max", (int)rfPowerRangeBias1 + ""); if (!rfEnableBias1) { nodeRfPowerBias1.ParentNode.RemoveChild(nodeRfPowerBias1); nodeMatchModeBias1.ParentNode.RemoveChild(nodeMatchModeBias1); nodeMatchC1Bias1.ParentNode.RemoveChild(nodeMatchC1Bias1); nodeMatchC2Bias1.ParentNode.RemoveChild(nodeMatchC2Bias1); nodeRfPowerBiasSoft1?.ParentNode.RemoveChild(nodeRfPowerBiasSoft1); nodeRfPowerBiasHard1?.ParentNode.RemoveChild(nodeRfPowerBiasHard1); } } if (!rfEnablePulsing1) { var node11 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf1.SetPulsingFrequency']")) as XmlElement; if (node11 != null) node11.ParentNode.RemoveChild(node11); var node21 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf1.SetPulsingDuty']")) as XmlElement; if (node21 != null) node21.ParentNode.RemoveChild(node21); //var node3 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step/Item[@ControlName='PulsingMode']")) as XmlElement; //if (node3 != null) // node3.ParentNode.RemoveChild(node3); } double rfPowerRange2 = SC.GetValue($"{chamberType}.Rf2.PowerRange"); double rfPowerRangeBias2 = SC.GetValue($"{chamberType}.BiasRf2.PowerRange"); bool rfEnablePulsing2 = SC.GetValue($"{chamberType}.Rf2.EnablePulsingFunction"); bool rfEnableBias2 = SC.GetValue($"{chamberType}.BiasRf2.EnableBiasRF"); var nodeRfPowerBias2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.SetPower']")) as XmlElement; var nodeMatchModeBias2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.SetMatchProcessMode']")) as XmlElement; var nodeMatchC1Bias2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.SetMatchPositionC1']")) as XmlElement; var nodeMatchC2Bias2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.SetMatchPositionC2']")) as XmlElement; var nodeRfPower2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf2.SetPower']")) as XmlElement; var nodeRfPowerBiasSoft2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.SoftTolerance']")) as XmlElement; var nodeRfPowerBiasHard2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='BiasRf2.HardTolerance']")) as XmlElement; if (nodeRfPower2 != null) { nodeRfPower2.SetAttribute("Max", (int)rfPowerRange2 + ""); } if (nodeRfPowerBias2 != null) { nodeRfPowerBias2.SetAttribute("Max", (int)rfPowerRangeBias2 + ""); if (!rfEnableBias2) { nodeRfPowerBias2.ParentNode.RemoveChild(nodeRfPowerBias2); nodeMatchModeBias2.ParentNode.RemoveChild(nodeMatchModeBias2); nodeMatchC1Bias2.ParentNode.RemoveChild(nodeMatchC1Bias2); nodeMatchC2Bias2.ParentNode.RemoveChild(nodeMatchC2Bias2); nodeRfPowerBiasSoft2?.ParentNode.RemoveChild(nodeRfPowerBiasSoft2); nodeRfPowerBiasHard2?.ParentNode.RemoveChild(nodeRfPowerBiasHard2); } } if (!rfEnablePulsing2) { var node12 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf2.SetPulsingFrequency']")) as XmlElement; if (node12 != null) node12.ParentNode.RemoveChild(node12); var node22 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='Rf2.SetPulsingDuty']")) as XmlElement; if (node22 != null) node22.ParentNode.RemoveChild(node22); //var node3 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step/Item[@ControlName='PulsingMode']")) as XmlElement; //if (node3 != null) // node3.ParentNode.RemoveChild(node3); } string gas1Name = SC.GetStringValue($"{chamberType}.MfcGas1.GasName"); bool gas1Enable = SC.GetValue($"{chamberType}.MfcGas1.Enable"); int gas1N2Scale = SC.GetValue($"{chamberType}.MfcGas1.MfcN2Scale"); double gas1ScaleFactor = SC.GetValue($"{chamberType}.MfcGas1.MfcScaleFactor"); var nodeGas1 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1']")) as XmlElement; var nodeGas1Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1.SoftTolerance']")) as XmlElement; var nodeGas1Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas1.HardTolerance']")) as XmlElement; if (nodeGas1 != null) { if (!gas1Enable) { nodeGas1.ParentNode.RemoveChild(nodeGas1); nodeGas1Soft.ParentNode.RemoveChild(nodeGas1Soft); nodeGas1Hard.ParentNode.RemoveChild(nodeGas1Hard); } else { nodeGas1.SetAttribute("DisplayName", "Gas1 " + gas1Name + " " + gas1N2Scale * gas1ScaleFactor + " " + "sccm"); nodeGas1.SetAttribute("Max", (int)(gas1N2Scale * gas1ScaleFactor) + ""); nodeGas1Soft.SetAttribute("DisplayName", $"{gas1Name} (Soft)(%)"); nodeGas1Hard.SetAttribute("DisplayName", $"{gas1Name} (Hard)(%)"); } } string gas2Name = SC.GetStringValue($"{chamberType}.MfcGas2.GasName"); bool gas2Enable = SC.GetValue($"{chamberType}.MfcGas2.Enable"); int gas2N2Scale = SC.GetValue($"{chamberType}.MfcGas2.MfcN2Scale"); double gas2ScaleFactor = SC.GetValue($"{chamberType}.MfcGas2.MfcScaleFactor"); var nodeGas2 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2']")) as XmlElement; var nodeGas2Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2.SoftTolerance']")) as XmlElement; var nodeGas2Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas2.HardTolerance']")) as XmlElement; if (nodeGas2 != null) { if (!gas2Enable) { nodeGas2.ParentNode.RemoveChild(nodeGas2); nodeGas2Soft.ParentNode.RemoveChild(nodeGas2Soft); nodeGas2Hard.ParentNode.RemoveChild(nodeGas2Hard); } else { nodeGas2.SetAttribute("DisplayName", "Gas2 " + gas2Name + " " + gas2N2Scale * gas2ScaleFactor + " " + "sccm"); nodeGas2.SetAttribute("Max", (int)(gas2N2Scale * gas2ScaleFactor) + ""); nodeGas2Soft.SetAttribute("DisplayName", $"{gas2Name} (Soft)(%)"); nodeGas2Hard.SetAttribute("DisplayName", $"{gas2Name} (Hard)(%)"); } } string gas3Name = SC.GetStringValue($"{chamberType}.MfcGas3.GasName"); bool gas3Enable = SC.GetValue($"{chamberType}.MfcGas3.Enable"); int gas3N2Scale = SC.GetValue($"{chamberType}.MfcGas3.MfcN2Scale"); double gas3ScaleFactor = SC.GetValue($"{chamberType}.MfcGas3.MfcScaleFactor"); var nodeGas3 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3']")) as XmlElement; var nodeGas3Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3.SoftTolerance']")) as XmlElement; var nodeGas3Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas3.HardTolerance']")) as XmlElement; if (nodeGas3 != null) { if (!gas3Enable) { nodeGas3.ParentNode.RemoveChild(nodeGas3); nodeGas3Soft.ParentNode.RemoveChild(nodeGas3Soft); nodeGas3Hard.ParentNode.RemoveChild(nodeGas3Hard); } else { nodeGas3.SetAttribute("DisplayName", "Gas3 " + gas3Name + " " + gas3N2Scale * gas3ScaleFactor + " " + "sccm"); nodeGas3.SetAttribute("Max", (int)(gas3N2Scale * gas3ScaleFactor) + ""); nodeGas3Soft.SetAttribute("DisplayName", $"{gas3Name} (Soft)(%)"); nodeGas3Hard.SetAttribute("DisplayName", $"{gas3Name} (Hard)(%)"); } } string gas4Name = SC.GetStringValue($"{chamberType}.MfcGas4.GasName"); bool gas4Enable = SC.GetValue($"{chamberType}.MfcGas4.Enable"); int gas4N2Scale = SC.GetValue($"{chamberType}.MfcGas4.MfcN2Scale"); double gas4ScaleFactor = SC.GetValue($"{chamberType}.MfcGas4.MfcScaleFactor"); var nodeGas4 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4']")) as XmlElement; var nodeGas4Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4.SoftTolerance']")) as XmlElement; var nodeGas4Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas4.HardTolerance']")) as XmlElement; if (nodeGas4 != null) { if (!gas4Enable) { nodeGas4.ParentNode.RemoveChild(nodeGas4); nodeGas4Soft.ParentNode.RemoveChild(nodeGas4Soft); nodeGas4Hard.ParentNode.RemoveChild(nodeGas4Hard); } else { nodeGas4.SetAttribute("DisplayName", "Gas4 " + gas4Name + " " + gas4N2Scale * gas4ScaleFactor + " " + "sccm"); nodeGas4.SetAttribute("Max", (int)(gas4N2Scale * gas4ScaleFactor) + ""); nodeGas4Soft.SetAttribute("DisplayName", $"{gas4Name} (Soft)(%)"); nodeGas4Hard.SetAttribute("DisplayName", $"{gas4Name} (Hard)(%)"); } } string gas5Name = SC.GetStringValue($"{chamberType}.MfcGas5.GasName"); bool gas5Enable = SC.GetValue($"{chamberType}.MfcGas5.Enable"); int gas5N2Scale = SC.GetValue($"{chamberType}.MfcGas5.MfcN2Scale"); double gas5ScaleFactor = SC.GetValue($"{chamberType}.MfcGas5.MfcScaleFactor"); var nodeGas5 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5']")) as XmlElement; var nodeGas5Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5.SoftTolerance']")) as XmlElement; var nodeGas5Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas5.HardTolerance']")) as XmlElement; if (nodeGas5 != null) { if (!gas5Enable) { nodeGas5.ParentNode.RemoveChild(nodeGas5); nodeGas5Soft.ParentNode.RemoveChild(nodeGas5Soft); nodeGas5Hard.ParentNode.RemoveChild(nodeGas5Hard); } else { nodeGas5.SetAttribute("DisplayName", "Gas5 " + gas5Name + " " + gas5N2Scale * gas5ScaleFactor + " " + "sccm"); nodeGas5.SetAttribute("Max", (int)(gas5N2Scale * gas5ScaleFactor) + ""); nodeGas5Soft.SetAttribute("DisplayName", $"{gas5Name} (Soft)(%)"); nodeGas5Hard.SetAttribute("DisplayName", $"{gas5Name} (Hard)(%)"); } } string gas6Name = SC.GetStringValue($"{chamberType}.MfcGas6.GasName"); bool gas6Enable = SC.GetValue($"{chamberType}.MfcGas6.Enable"); int gas6N2Scale = SC.GetValue($"{chamberType}.MfcGas6.MfcN2Scale"); double gas6ScaleFactor = SC.GetValue($"{chamberType}.MfcGas6.MfcScaleFactor"); var nodeGas6 = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas6']")) as XmlElement; var nodeGas6Soft = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas6.SoftTolerance']")) as XmlElement; var nodeGas6Hard = xmlDom.SelectSingleNode(string.Format("/Aitex/TableRecipeFormat/Catalog/Group/Step[@ControlName='MfcGas6.HardTolerance']")) as XmlElement; if (nodeGas6 != null) { if (!gas5Enable) { nodeGas6.ParentNode.RemoveChild(nodeGas6); nodeGas6Soft.ParentNode.RemoveChild(nodeGas6Soft); nodeGas6Hard.ParentNode.RemoveChild(nodeGas6Hard); } else { nodeGas6.SetAttribute("DisplayName", "Gas6 " + gas6Name + " " + gas6N2Scale + " " + "sccm"); nodeGas6.SetAttribute("Max", (int)(gas6N2Scale * gas6ScaleFactor) + ""); nodeGas6Soft.SetAttribute("DisplayName", $"{gas6Name} (Soft)(%)"); nodeGas6Hard.SetAttribute("DisplayName", $"{gas6Name} (Hard)(%)"); } } return xmlDom.OuterXml; } catch (Exception ex) { LOG.Write(ex); return ""; } } public IEnumerable GetRecipes(string path, bool includingUsedRecipe) { try { var recipes = new List(); string recipePath = PathManager.GetRecipeDir() + path + "\\"; if (!Directory.Exists(recipePath)) return recipes; var di = new DirectoryInfo(recipePath); var fis = di.GetFiles("*.rcp", SearchOption.AllDirectories); foreach (var fi in fis) { string str = fi.FullName.Substring(di.FullName.Length); str = str.Substring(0, str.LastIndexOf('.')); if (includingUsedRecipe || (!includingUsedRecipe && !str.Contains("HistoryRecipe\\"))) { recipes.Add(str); } } return recipes; } catch (Exception ex) { LOG.Write(ex); return new List(); } } public void PostInfoEvent(string message) { EV.PostMessage("System", EventEnum.GeneralInfo, message); } public void PostWarningEvent(string message) { EV.PostMessage("System", EventEnum.DefaultWarning, message); } public void PostAlarmEvent(string message) { EV.PostMessage("System", EventEnum.DefaultAlarm, message); } public void PostDialogEvent(string message) { EV.PostNotificationMessage(message); } public void PostInfoDialogMessage(string message) { EV.PostMessage("System", EventEnum.GeneralInfo, message); EV.PostPopDialogMessage(EventLevel.Information, "System Information", message); } public void PostWarningDialogMessage(string message) { EV.PostMessage("System", EventEnum.GeneralInfo, message); EV.PostPopDialogMessage(EventLevel.Warning, "System Warning", message); } public void PostAlarmDialogMessage(string message) { EV.PostMessage("System", EventEnum.GeneralInfo, message); EV.PostPopDialogMessage(EventLevel.Alarm, "System Alarm", message); } public string GetRecipeTemplate(string chamberId) { string schema = GetRecipeDefiniton(chamberId); XmlDocument dom = new XmlDocument(); dom.LoadXml(schema); XmlNode nodeTemplate = dom.SelectSingleNode("/Aitex/TableRecipeData"); return nodeTemplate.OuterXml; } } }