using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Caliburn.Micro; using Caliburn.Micro.Core; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.DataCenter; using MECF.Framework.UI.Client.CenterViews.Editors.Sequence; using MECF.Framework.UI.Client.ClientBase; using OpenSEMI.ClientBase; using OpenSEMI.ClientBase.Command; using RecipeEditorLib.DGExtension.CustomColumn; using RecipeEditorLib.RecipeModel.Params; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe { public class ProcessTypeFileItem : NotifiableItem { public string ProcessType { get; set; } public ObservableCollection FileListByProcessType { get; set; } public ProcessTypeFileItem() { FileListByProcessType = new ObservableCollection(); } } public class ChamberTypeItem : NotifiableItem { public string ChamberType { get; set; } public ObservableCollection FileListByChamberType { get; set; } public ChamberTypeItem() { FileListByChamberType = new ObservableCollection(); } } /*public class RecipeEditorViewModel : BaseModel { public enum FlowMode { Purge, Vent, Run, Close, } public bool IsPermission { get => this.Permission == 3; }//&& RtStatus != "AutoRunning"; private ICommand _RenameFolderCommand; public ICommand RenameFolderCommand { get { if (this._RenameFolderCommand == null) this._RenameFolderCommand = new BaseCommand(() => this.RenameFolder()); return this._RenameFolderCommand; } } private ICommand _DeleteFolderCommand; public ICommand DeleteFolderCommand { get { if (this._DeleteFolderCommand == null) this._DeleteFolderCommand = new BaseCommand(() => this.DeleteFolder()); return this._DeleteFolderCommand; } } private ICommand _NewFolderCommand; public ICommand NewFolderCommand { get { if (this._NewFolderCommand == null) this._NewFolderCommand = new BaseCommand(() => this.NewFolder()); return this._NewFolderCommand; } } private ICommand _NewFolderRootCommand; public ICommand NewFolderRootCommand { get { if (this._NewFolderRootCommand == null) this._NewFolderRootCommand = new BaseCommand(() => this.NewFolderRoot()); return this._NewFolderRootCommand; } } private ICommand _NewRecipeCommand; public ICommand NewRecipeCommand { get { if (this._NewRecipeCommand == null) this._NewRecipeCommand = new BaseCommand(() => this.NewRecipe()); return this._NewRecipeCommand; } } private ICommand _NewRecipeRootCommand; public ICommand NewRecipeRootCommand { get { if (this._NewRecipeRootCommand == null) this._NewRecipeRootCommand = new BaseCommand(() => this.NewRecipeRoot()); return this._NewRecipeRootCommand; } } private ICommand _RenameRecipeCommand; public ICommand RenameRecipeCommand { get { if (this._RenameRecipeCommand == null) this._RenameRecipeCommand = new BaseCommand(() => this.RenameRecipe()); return this._RenameRecipeCommand; } } private ICommand _DeleteRecipeCommand; public ICommand DeleteRecipeCommand { get { if (this._DeleteRecipeCommand == null) this._DeleteRecipeCommand = new BaseCommand(() => this.DeleteRecipe()); return this._DeleteRecipeCommand; } } private ICommand _SaveAsRecipeCommand; public ICommand SaveAsRecipeCommand { get { if (this._SaveAsRecipeCommand == null) this._SaveAsRecipeCommand = new BaseCommand(() => this.SaveAsRecipe()); return this._SaveAsRecipeCommand; } } public ObservableCollection ProcessTypeFileList { get; set; } public RecipeData CurrentRecipe { get; private set; } public FileNode CurrentFileNode { get; set; } private bool IsChanged { get { return editMode == EditMode.Edit || CurrentRecipe.IsChanged; } } public ObservableCollection Columns { get; set; } public Dictionary PopSettingColumns { get; set; } public ObservableCollection ColumnsTolerance { get; set; } public Dictionary> DicColunms { get; set; } public bool EnableNew { get; set; } public bool EnableReName { get; set; } public bool EnableCopy { get; set; } public bool EnableDelete { get; set; } public bool EnableSave { get; set; } public bool EnableStep { get; set; } public bool EnableReload { get; set; } public bool EnableSaveToAll { get; set; } public bool EnableSaveTo { get; set; } private RecipeFormatBuilder _columnBuilder = new RecipeFormatBuilder(); private EditMode editMode; private RecipeProvider _recipeProvider = new RecipeProvider(); public ObservableCollection ChamberType { get; set; } public int ChamberTypeIndexSelection { get; set; } public int ProcessTypeIndexSelection { get; set; } public string CurrentChamberType { get { return ChamberType[ChamberTypeIndexSelection]; } } public string CurrentProcessType { get { return ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType; } } public Visibility MultiChamberVisibility { get; set; } public Visibility ToleranceVisibility { get; set; } public ObservableCollection Chambers { get; set; } public string SelectedChamber { get; set; } public object View { get; set; } protected override void OnInitialize() { base.OnInitialize(); var chamberType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedChamberType"); if (chamberType == null) { ChamberType = new ObservableCollection() { "Default" }; } else { ChamberType = new ObservableCollection(((string)(chamberType)).Split(',')); } ChamberTypeIndexSelection = 0; //Etch:Process,Clean,Chuck,Dechuck;CVD:Process,Clean; var processType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedProcessType"); if (processType == null) { processType = "Process,Routine,Clean"; } ProcessTypeFileList = new ObservableCollection(); string[] recipeProcessType = ((string)processType).Split(','); for (int i = 0; i < recipeProcessType.Length; i++) { var type = new ProcessTypeFileItem(); type.ProcessType = recipeProcessType[i]; var prefix = $"{ChamberType[ChamberTypeIndexSelection]}\\{recipeProcessType[i]}"; var recipes = _recipeProvider.GetXmlRecipeList(prefix); type.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, "", false, recipes)[0].Files; ProcessTypeFileList.Add(type); } DicColunms = new Dictionary>(); UpdateRecipeFormat(); } protected override void OnActivate() { base.OnActivate(); } protected override void OnDeactivate(bool close) { base.OnDeactivate(close); if (this.IsChanged) { if (DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} content is changed, do you want to save it?") == DialogButton.Yes) { this.SaveRecipe(); } } } protected override void OnViewLoaded(object view) { View = view; base.OnViewLoaded(view); RecipeFormatBuilder.ApplyTemplate((UserControl)view, this.Columns); RecipeEditorView u = (RecipeEditorView)view; u.dgCustom.Columns.Clear(); u.ToleranceGrid.Columns.Clear(); this.Columns.Apply((c) => { c.Header = c; u.dgCustom.Columns.Add(c); }); RecipeFormatBuilder.ApplyTemplate((UserControl)view, this.ColumnsTolerance); ColumnsTolerance.Apply((c) => { c.Header = c; u.ToleranceGrid.Columns.Add(c); }); u.dgCustom.ItemsSource = this.CurrentRecipe.Steps; u.ToleranceGrid.ItemsSource = this.CurrentRecipe.StepTolerances; u.dgCustom.LostFocus += DgCustom_LostFocus; u.dgCustom.FrozenColumnCount = 4; } private void DgCustom_LostFocus(object sender, RoutedEventArgs e) { for (int selectIndex = 0; selectIndex < this.CurrentRecipe.Steps.Count; selectIndex++) { int previousIndex = selectIndex == 0 ? 0 : selectIndex - 1; int currentIndex = selectIndex; int nextIndex = selectIndex == this.CurrentRecipe.Steps.Count - 1 ? selectIndex : selectIndex + 1; var previousStep = this.CurrentRecipe.Steps[previousIndex]; var currentStep = this.CurrentRecipe.Steps[currentIndex]; var nextStep = this.CurrentRecipe.Steps[nextIndex]; double.TryParse((currentStep[3] as DoubleParam).Value, out double stepTime); PurgeRunSwitch(previousStep, currentStep, nextStep); FixedFlowSplitRatio(currentStep); NotIntallDevice(currentStep); if (stepTime > 0) { //CalRecipeParameter(previousStep, currentStep, stepTime); CalRecipeParameterForRunVent(previousStep, currentStep, stepTime); } } } private void PurgeRunSwitch(RecipeStep previousStep, RecipeStep currentStep, RecipeStep nextStep) { var previousSiH4FlowMode = previousStep[50] as ComboxParam; var previousTCSFlowMode = previousStep[54] as ComboxParam; var previousHClFlowMode = previousStep[64] as ComboxParam; var previousC2H4FlowMode = previousStep[81] as ComboxParam; var previousN2FlowMode = previousStep[98] as ComboxParam; var previousN2HighFlowMode = previousStep[103] as ComboxParam; var previousTMAFlowMode = previousStep[111] as ComboxParam; var currentSiH4FlowMode = currentStep[50] as ComboxParam; var currentTCSFlowMode = currentStep[54] as ComboxParam; var currentHClFlowMode = currentStep[64] as ComboxParam; var currentC2H4FlowMode = currentStep[81] as ComboxParam; var currentN2FlowMode = currentStep[98] as ComboxParam; var currentN2HighFlowMode = currentStep[103] as ComboxParam; var currentTMAFlowMode = currentStep[111] as ComboxParam; var nextSiH4FlowMode = nextStep[50] as ComboxParam; var nextTCSFlowMode = nextStep[54] as ComboxParam; var nextHClFlowMode = nextStep[64] as ComboxParam; var nextC2H4FlowMode = nextStep[81] as ComboxParam; var nextN2FlowMode = nextStep[98] as ComboxParam; var nextN2HighFlowMode = nextStep[103] as ComboxParam; var nextTMAFlowMode = nextStep[111] as ComboxParam; List previousFlowMode = new List() { previousSiH4FlowMode, previousTCSFlowMode, previousHClFlowMode, previousC2H4FlowMode, previousN2FlowMode,previousN2FlowMode, previousN2HighFlowMode, previousTMAFlowMode}; List currentFlowMode = new List() { currentSiH4FlowMode, currentTCSFlowMode, currentHClFlowMode, currentC2H4FlowMode, currentN2FlowMode,currentN2FlowMode, currentN2HighFlowMode, currentTMAFlowMode}; List nextFlowMode = new List() { nextSiH4FlowMode, nextTCSFlowMode, nextHClFlowMode, nextC2H4FlowMode, nextN2FlowMode,nextN2FlowMode, nextN2HighFlowMode, nextTMAFlowMode}; for (int i = 0; i < currentFlowMode.Count; i++) { if (previousFlowMode[i].Value == FlowMode.Run.ToString() && currentFlowMode[i].Value == FlowMode.Purge.ToString() || previousFlowMode[i].Value == FlowMode.Purge.ToString() && currentFlowMode[i].Value == FlowMode.Run.ToString()) { MessageBox.Show("Flow mode 'Run' and 'Purge' can't switch directly", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); currentFlowMode[i].Value = FlowMode.Vent.ToString(); return; } if (nextFlowMode[i].Value == FlowMode.Run.ToString() && currentFlowMode[i].Value == FlowMode.Purge.ToString() || nextFlowMode[i].Value == FlowMode.Purge.ToString() && currentFlowMode[i].Value == FlowMode.Run.ToString()) { MessageBox.Show("Flow mode 'Run' and 'Purge' can't switch directly", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); currentFlowMode[i].Value = FlowMode.Vent.ToString(); return; } } } private void FixedFlowSplitRatio(RecipeStep currentStep) { bool isRatioDiff = false; var currentFixedFlowSplitRatio = currentStep[43] as ComboxParam; var currentGlobalSplitRatio = currentStep[44] as StringParam; var currentSHTotalFlowSplitRatio = currentStep[45] as StringParam; var currentSiSourSplitRatio = currentStep[68] as StringParam; var currentCSourSplitRatio = currentStep[85] as StringParam; var currentDopeSplitRatio = currentStep[119] as StringParam; if (currentFixedFlowSplitRatio.Value == "Enable") { if (currentSHTotalFlowSplitRatio.Value != currentGlobalSplitRatio.Value) { currentSHTotalFlowSplitRatio.Value = currentGlobalSplitRatio.Value; isRatioDiff = true; } if (currentSiSourSplitRatio.Value != currentGlobalSplitRatio.Value) { currentSiSourSplitRatio.Value = currentGlobalSplitRatio.Value; isRatioDiff = true; } if (currentCSourSplitRatio.Value != currentGlobalSplitRatio.Value) { currentCSourSplitRatio.Value = currentGlobalSplitRatio.Value; isRatioDiff = true; } if (currentDopeSplitRatio.Value != currentGlobalSplitRatio.Value) { currentDopeSplitRatio.Value = currentGlobalSplitRatio.Value; isRatioDiff = true; } } if (isRatioDiff) { MessageBox.Show("Fixed flow-Split ratio is actived, Global ratio is the value for all modules ratio", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); } } private void NotIntallDevice(RecipeStep currentStep) { var currentTMAFlowMode = currentStep[111] as ComboxParam; var currentGRPurgeCl = currentStep[146] as ComboxParam; var currentGRPurgeHClFlow = currentStep[148] as DoubleParam; if (currentTMAFlowMode.Value != FlowMode.Purge.ToString()) { currentTMAFlowMode.Value = FlowMode.Purge.ToString(); MessageBox.Show("TMA is not install, only Purge mode is valid", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); } if (currentGRPurgeCl.Value != "Disable") { currentGRPurgeCl.Value = "Disable"; MessageBox.Show("GR Purge Cl is not install, only Disable is valid", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); } double.TryParse(currentGRPurgeHClFlow.Value, out double value); if (value != 0) { currentGRPurgeHClFlow.Value = "0"; MessageBox.Show("GR Purge HCl Flow is not install, lock the value as zero", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning); } } private void CalRecipeParameter(RecipeStep previousStep, RecipeStep currentStep, double stepTime) { #region Temp.Setting double.TryParse((previousStep[8] as DoubleParam).Value, out double previousSusMidTemp); double.TryParse((previousStep[9] as DoubleParam).Value, out double previousSusInnerTemp); double.TryParse((previousStep[10] as DoubleParam).Value, out double previousSusOutterTemp); double.TryParse((previousStep[11] as DoubleParam).Value, out double previousWWTemp); double.TryParse((currentStep[8] as DoubleParam).Value, out double currentSusMidTemp); double.TryParse((currentStep[9] as DoubleParam).Value, out double currentSusInnerTemp); double.TryParse((currentStep[10] as DoubleParam).Value, out double currentSusOutterTemp); double.TryParse((currentStep[11] as DoubleParam).Value, out double currentWWTemp); (currentStep[12] as DoubleParam).Value = ((currentSusMidTemp - previousSusMidTemp) / stepTime).ToString("F1"); (currentStep[13] as DoubleParam).Value = ((currentSusInnerTemp - previousSusInnerTemp) / stepTime).ToString("F1"); (currentStep[14] as DoubleParam).Value = ((currentSusOutterTemp - previousSusOutterTemp) / stepTime).ToString("F1"); (currentStep[15] as DoubleParam).Value = ((currentWWTemp - previousWWTemp) / stepTime).ToString("F1"); #endregion #region Heater Output double.TryParse((previousStep[17] as DoubleParam).Value, out double previousSusMidOP); double.TryParse((previousStep[18] as DoubleParam).Value, out double previousSusInnerOP); double.TryParse((previousStep[19] as DoubleParam).Value, out double previousSusOutterOP); double.TryParse((previousStep[20] as DoubleParam).Value, out double previousSusComOP); double.TryParse((previousStep[21] as DoubleParam).Value, out double previousWWBottomOP); double.TryParse((previousStep[22] as DoubleParam).Value, out double previousWWMidOP); double.TryParse((previousStep[23] as DoubleParam).Value, out double previousWWTopOP); double.TryParse((previousStep[24] as DoubleParam).Value, out double previousWWComOP); double.TryParse((currentStep[17] as DoubleParam).Value, out double currentSusMidOP); double.TryParse((currentStep[18] as DoubleParam).Value, out double currentSusInnerOP); double.TryParse((currentStep[19] as DoubleParam).Value, out double currentSusOutterOP); double.TryParse((currentStep[29] as DoubleParam).Value, out double currentSusComOP); double.TryParse((currentStep[21] as DoubleParam).Value, out double currentWWBottomOP); double.TryParse((currentStep[22] as DoubleParam).Value, out double currentWWMidOP); double.TryParse((currentStep[23] as DoubleParam).Value, out double currentWWTopOP); double.TryParse((currentStep[24] as DoubleParam).Value, out double currentWWComOP); (currentStep[25] as DoubleParam).Value = ((currentSusMidOP - previousSusMidOP) / stepTime).ToString("F1"); (currentStep[26] as DoubleParam).Value = ((currentSusInnerOP - previousSusInnerOP) / stepTime).ToString("F1"); (currentStep[27] as DoubleParam).Value = ((currentSusOutterOP - previousSusOutterOP) / stepTime).ToString("F1"); (currentStep[28] as DoubleParam).Value = ((currentWWBottomOP - previousWWBottomOP) / stepTime).ToString("F1"); (currentStep[29] as DoubleParam).Value = ((currentWWMidOP - previousWWMidOP) / stepTime).ToString("F1"); (currentStep[30] as DoubleParam).Value = ((currentWWTopOP - previousWWTopOP) / stepTime).ToString("F1"); #endregion #region Pressure Rotation double.TryParse((previousStep[32] as DoubleParam).Value, out double previousPresSet); double.TryParse((previousStep[34] as DoubleParam).Value, out double previousRotationSet); double.TryParse((currentStep[32] as DoubleParam).Value, out double currentPresSet); double.TryParse((currentStep[34] as DoubleParam).Value, out double currentRotationSet); (currentStep[33] as DoubleParam).Value = ((currentPresSet - previousPresSet) / stepTime).ToString("F1"); (currentStep[35] as DoubleParam).Value = ((currentRotationSet - previousRotationSet) / stepTime).ToString("F1"); #endregion #region SH Total flow double.TryParse((previousStep[39] as DoubleParam).Value, out double previousSHTotalFlow); double.TryParse((currentStep[39] as DoubleParam).Value, out double currentSHTotalFlow); (currentStep[40] as DoubleParam).Value = ((currentSHTotalFlow - previousSHTotalFlow) / stepTime).ToString("F1"); string[] arrGlobalSplitRatio = (currentStep[42] as StringParam).Value.Split(':'); double[] currentGlobalSplitRatio = new double[3]; if (arrGlobalSplitRatio.Length == 3) { double.TryParse(arrGlobalSplitRatio[0], out currentGlobalSplitRatio[0]); double.TryParse(arrGlobalSplitRatio[1], out currentGlobalSplitRatio[1]); double.TryParse(arrGlobalSplitRatio[2], out currentGlobalSplitRatio[2]); } string[] arrSHTotalFlowSplitRatio = (currentStep[43] as StringParam).Value.Split(':'); double[] currentSHTotalFlowSplitRatio = new double[3]; if (arrSHTotalFlowSplitRatio.Length == 3) { double.TryParse(arrSHTotalFlowSplitRatio[0], out currentSHTotalFlowSplitRatio[0]); double.TryParse(arrSHTotalFlowSplitRatio[1], out currentSHTotalFlowSplitRatio[1]); double.TryParse(arrSHTotalFlowSplitRatio[2], out currentSHTotalFlowSplitRatio[2]); } #endregion #region Si Source double.TryParse((previousStep[45] as DoubleParam).Value, out double previousSiSourTotalFlow); double.TryParse((previousStep[49] as DoubleParam).Value, out double previousSiH4Flow); double.TryParse((previousStep[53] as DoubleParam).Value, out double previousTCSBubbLowFlow); double.TryParse((previousStep[54] as DoubleParam).Value, out double previousTCSBubbHighFlow); double.TryParse((previousStep[55] as DoubleParam).Value, out double previousTCSPushFlow); double.TryParse((previousStep[56] as DoubleParam).Value, out double previousTCSBubbPres); double.TryParse((previousStep[63] as DoubleParam).Value, out double previousHClFlow); double.TryParse((previousStep[67] as DoubleParam).Value, out double previousSiSourPushFlow); double.TryParse((previousStep[68] as DoubleParam).Value, out double previousSiSourInnerFlow); double.TryParse((previousStep[69] as DoubleParam).Value, out double previousSiSourMidFlow); double.TryParse((previousStep[70] as DoubleParam).Value, out double previousSiSourPreSplitPres); double.TryParse((currentStep[49] as DoubleParam).Value, out double currentSiH4Flow); double.TryParse((currentStep[53] as DoubleParam).Value, out double currentTCSBubbLowFlow); double.TryParse((currentStep[54] as DoubleParam).Value, out double currentTCSBubbHighFlow); double.TryParse((currentStep[55] as DoubleParam).Value, out double currentTCSPushFlow); double.TryParse((currentStep[56] as DoubleParam).Value, out double currentTCSBubbPres); double.TryParse((currentStep[63] as DoubleParam).Value, out double currentHClFlow); string[] arrSiSourSplitRatio = (currentStep[66] as StringParam).Value.Split(':'); double[] currentSiSourSplitRatio = new double[3]; if (arrSiSourSplitRatio.Length == 3) { double.TryParse(arrSiSourSplitRatio[0], out currentSiSourSplitRatio[0]); double.TryParse(arrSiSourSplitRatio[1], out currentSiSourSplitRatio[1]); double.TryParse(arrSiSourSplitRatio[2], out currentSiSourSplitRatio[2]); } double.TryParse((currentStep[67] as DoubleParam).Value, out double currentSiSourPushFlow); double.TryParse((currentStep[70] as DoubleParam).Value, out double currentSiSourPreSplitPres); (currentStep[50] as DoubleParam).Value = ((currentSiH4Flow - previousSiH4Flow) / stepTime).ToString("F1"); (currentStep[57] as DoubleParam).Value = ((currentTCSBubbLowFlow - previousTCSBubbLowFlow) / stepTime).ToString("F1"); (currentStep[58] as DoubleParam).Value = ((currentTCSBubbHighFlow - previousTCSBubbHighFlow) / stepTime).ToString("F1"); (currentStep[59] as DoubleParam).Value = ((currentTCSPushFlow - previousTCSPushFlow) / stepTime).ToString("F1"); (currentStep[60] as DoubleParam).Value = ((currentTCSBubbPres - previousTCSBubbPres) / stepTime).ToString("F1"); (currentStep[64] as DoubleParam).Value = ((currentHClFlow - previousHClFlow) / stepTime).ToString("F1"); string SiH4FlowMode = (currentStep[48] as ComboxParam).Value; string TCSFlowMode = (currentStep[52] as ComboxParam).Value; string HClFlowMode = (currentStep[62] as ComboxParam).Value; double TCSFlow = 0; double TCS_Eff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{SelectedChamber}.Efficiency.TCS-Eff"); if (TCSFlowMode == FlowMode.Run.ToString() || TCSFlowMode == FlowMode.Vent.ToString()) TCSFlow = (currentTCSBubbHighFlow + currentTCSBubbLowFlow) * TCS_Eff + currentTCSPushFlow; else if (TCSFlowMode == FlowMode.Purge.ToString()) TCSFlow = currentTCSBubbHighFlow + currentTCSBubbLowFlow + currentTCSPushFlow; double currentSiSourTotalFlow = currentSiSourPushFlow + (SiH4FlowMode == FlowMode.Run.ToString() ? currentSiH4Flow : 0) + (TCSFlowMode == FlowMode.Run.ToString() ? TCSFlow : 0) + (HClFlowMode == FlowMode.Run.ToString() ? currentHClFlow : 0); (currentStep[45] as DoubleParam).Value = currentSiSourTotalFlow.ToString("F1"); (currentStep[46] as DoubleParam).Value = ((currentSiSourTotalFlow - previousSiSourTotalFlow) / stepTime).ToString("F1"); double currentSiSourInnerFlow = 0; double currentSiSourMidFlow = 0; if (currentSiSourSplitRatio.Length == 3) { double rationSum = currentSiSourSplitRatio[0] + currentSiSourSplitRatio[1] + currentSiSourSplitRatio[2]; currentSiSourInnerFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[0]; currentSiSourMidFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[1]; } (currentStep[68] as DoubleParam).Value = currentSiSourInnerFlow.ToString("F1"); (currentStep[69] as DoubleParam).Value = currentSiSourMidFlow.ToString("F1"); (currentStep[71] as DoubleParam).Value = ((currentSiSourPushFlow - previousSiSourPushFlow) / stepTime).ToString("F1"); (currentStep[72] as DoubleParam).Value = ((currentSiSourInnerFlow - previousSiSourInnerFlow) / stepTime).ToString("F1"); (currentStep[73] as DoubleParam).Value = ((currentSiSourMidFlow - previousSiSourMidFlow) / stepTime).ToString("F1"); (currentStep[74] as DoubleParam).Value = ((currentSiSourPreSplitPres - previousSiSourPreSplitPres) / stepTime).ToString("F1"); #endregion #region C Source double.TryParse((previousStep[76] as DoubleParam).Value, out double previousCSourTotalFlow); double.TryParse((previousStep[80] as DoubleParam).Value, out double previousC2H4Flow); double.TryParse((previousStep[84] as DoubleParam).Value, out double previousCSourPushFlow); double.TryParse((previousStep[85] as DoubleParam).Value, out double previousCSourInnerFlow); double.TryParse((previousStep[86] as DoubleParam).Value, out double previousCSourMidFlow); double.TryParse((previousStep[87] as DoubleParam).Value, out double previousCSourPreSplitPres); double.TryParse((currentStep[80] as DoubleParam).Value, out double currentC2H4Flow); string[] arrCSourSplitRatio = (currentStep[83] as StringParam).Value.Split(':'); double[] currentCSourSplitRatio = new double[3]; if (arrCSourSplitRatio.Length == 3) { double.TryParse(arrCSourSplitRatio[0], out currentCSourSplitRatio[0]); double.TryParse(arrCSourSplitRatio[1], out currentCSourSplitRatio[1]); double.TryParse(arrCSourSplitRatio[2], out currentCSourSplitRatio[2]); } double.TryParse((currentStep[84] as DoubleParam).Value, out double currentCSourPushFlow); double.TryParse((currentStep[87] as DoubleParam).Value, out double currentCSourPreSplitPres); (currentStep[81] as DoubleParam).Value = ((currentC2H4Flow - previousC2H4Flow) / stepTime).ToString("F1"); string C2H4FlowMode = (currentStep[79] as ComboxParam).Value; double currentCSourTotalFlow = currentCSourPushFlow + (C2H4FlowMode == FlowMode.Run.ToString() ? currentC2H4Flow : 0); (currentStep[76] as DoubleParam).Value = currentCSourTotalFlow.ToString("F1"); (currentStep[77] as DoubleParam).Value = ((currentCSourTotalFlow - previousCSourTotalFlow) / stepTime).ToString("F1"); double currentCSourInnerFlow = 0; double currentCSourMidFlow = 0; if (currentCSourSplitRatio.Length == 3) { double ratioSum = currentCSourSplitRatio[0] + currentCSourSplitRatio[1] + currentCSourSplitRatio[2]; currentCSourInnerFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[0]; currentCSourMidFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[1]; } (currentStep[85] as DoubleParam).Value = currentCSourInnerFlow.ToString("F1"); (currentStep[86] as DoubleParam).Value = currentCSourMidFlow.ToString("F1"); (currentStep[88] as DoubleParam).Value = ((currentCSourPushFlow - previousCSourPushFlow) / stepTime).ToString("F1"); (currentStep[89] as DoubleParam).Value = ((currentCSourInnerFlow - previousCSourInnerFlow) / stepTime).ToString("F1"); (currentStep[90] as DoubleParam).Value = ((currentCSourMidFlow - previousCSourMidFlow) / stepTime).ToString("F1"); (currentStep[91] as DoubleParam).Value = ((currentCSourPreSplitPres - previousCSourPreSplitPres) / stepTime).ToString("F1"); #endregion #region Dope double.TryParse((previousStep[93] as DoubleParam).Value, out double previousDopeTotalFlow); double.TryParse((previousStep[97] as DoubleParam).Value, out double previousN2LowFlow); double.TryParse((previousStep[98] as DoubleParam).Value, out double previousDiluFlowForN2); double.TryParse((previousStep[99] as DoubleParam).Value, out double previousDilutedN2Flow); double.TryParse((previousStep[100] as DoubleParam).Value, out double previousN2PostDiluPres); double.TryParse((previousStep[102] as DoubleParam).Value, out double previousN2HighFlow); double.TryParse((previousStep[110] as DoubleParam).Value, out double previousTMABubbFlow); double.TryParse((previousStep[111] as DoubleParam).Value, out double previousTMAPush); double.TryParse((previousStep[112] as DoubleParam).Value, out double previousTMABubbPres); double.TryParse((previousStep[118] as DoubleParam).Value, out double previousDopePushFlow); double.TryParse((previousStep[119] as DoubleParam).Value, out double previousDopeInnerFlow); double.TryParse((previousStep[120] as DoubleParam).Value, out double previousDopeMidFlow); double.TryParse((previousStep[121] as DoubleParam).Value, out double previousDopePreSplitPres); double.TryParse((currentStep[97] as DoubleParam).Value, out double currentN2LowFlow); double.TryParse((currentStep[98] as DoubleParam).Value, out double currentDiluFlowForN2); double.TryParse((currentStep[99] as DoubleParam).Value, out double currentDilutedN2Flow); double.TryParse((currentStep[100] as DoubleParam).Value, out double currentN2PostDiluPres); double.TryParse((currentStep[102] as DoubleParam).Value, out double currentN2HighFlow); double.TryParse((currentStep[110] as DoubleParam).Value, out double currentTMABubbFlow); double.TryParse((currentStep[111] as DoubleParam).Value, out double currentTMAPush); double.TryParse((currentStep[112] as DoubleParam).Value, out double currentTMABubbPres); string[] arrDopeSplitRatio = (currentStep[117] as StringParam).Value.Split(':'); double[] currentDopeSplitRatio = new double[3]; if (arrDopeSplitRatio.Length == 3) { double.TryParse(arrDopeSplitRatio[0], out currentDopeSplitRatio[0]); double.TryParse(arrDopeSplitRatio[1], out currentDopeSplitRatio[1]); double.TryParse(arrDopeSplitRatio[2], out currentDopeSplitRatio[2]); } double.TryParse((currentStep[118] as DoubleParam).Value, out double currentDopePushFlow); double.TryParse((currentStep[121] as DoubleParam).Value, out double currentDopePreSplitPres); (currentStep[103] as DoubleParam).Value = ((currentN2LowFlow - previousN2LowFlow) / stepTime).ToString("F1"); (currentStep[104] as DoubleParam).Value = ((currentDiluFlowForN2 - previousDiluFlowForN2) / stepTime).ToString("F1"); (currentStep[105] as DoubleParam).Value = ((currentDilutedN2Flow - previousDilutedN2Flow) / stepTime).ToString("F1"); (currentStep[106] as DoubleParam).Value = ((currentN2PostDiluPres - previousN2PostDiluPres) / stepTime).ToString("F1"); (currentStep[107] as DoubleParam).Value = ((currentN2HighFlow - previousN2HighFlow) / stepTime).ToString("F1"); (currentStep[113] as DoubleParam).Value = ((currentTMABubbFlow - previousTMABubbFlow) / stepTime).ToString("F1"); (currentStep[114] as DoubleParam).Value = ((currentTMAPush - previousTMAPush) / stepTime).ToString("F1"); (currentStep[115] as DoubleParam).Value = ((currentTMABubbPres - previousTMABubbPres) / stepTime).ToString("F1"); string N2FlowMode = (currentStep[96] as ComboxParam).Value; string N2HighFlowMode = (currentStep[101] as ComboxParam).Value; string TMAFlowMode = (currentStep[109] as ComboxParam).Value; double TMAFlow = 0; double TMA_Eff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{SelectedChamber}.Efficiency.TMA-Eff"); if (TMAFlowMode == FlowMode.Run.ToString() || TMAFlowMode == FlowMode.Vent.ToString()) TMAFlow = currentTMABubbFlow * TMA_Eff + currentTMAPush; else if (TMAFlowMode == FlowMode.Purge.ToString()) TMAFlow = currentTMABubbFlow + currentTMAPush; double currentDopeTotalFlow = currentDopePushFlow + (N2FlowMode == FlowMode.Run.ToString() ? currentDilutedN2Flow + (N2HighFlowMode == "Enable" ? currentN2HighFlow : 0) : 0) + (TMAFlowMode == FlowMode.Run.ToString() ? TMAFlow : 0); (currentStep[93] as DoubleParam).Value = currentDopeTotalFlow.ToString("F1"); (currentStep[94] as DoubleParam).Value = ((currentDopeTotalFlow - previousDopeTotalFlow) / stepTime).ToString("F1"); double currentDopeInnerFlow = 0; double currentDopeMidFlow = 0; if (currentDopeSplitRatio.Length == 3) { double ratioSum = currentDopeSplitRatio[0] + currentDopeSplitRatio[1] + currentDopeSplitRatio[2]; currentDopeInnerFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[0]; currentDopeMidFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[1]; } (currentStep[119] as DoubleParam).Value = currentDopeInnerFlow.ToString("F1"); (currentStep[120] as DoubleParam).Value = currentDopeMidFlow.ToString("F1"); (currentStep[122] as DoubleParam).Value = ((currentDopePushFlow - previousDopePushFlow) / stepTime).ToString("F1"); (currentStep[123] as DoubleParam).Value = ((currentDopeInnerFlow - previousDopeInnerFlow) / stepTime).ToString("F1"); (currentStep[124] as DoubleParam).Value = ((currentDopeMidFlow - previousDopeMidFlow) / stepTime).ToString("F1"); (currentStep[125] as DoubleParam).Value = ((currentDopePreSplitPres - previousDopePreSplitPres) / stepTime).ToString("F1"); #endregion #region SH Supp. Flow double.TryParse((previousStep[127] as DoubleParam).Value, out double previousSHSuppTotalFlow); double.TryParse((previousStep[129] as DoubleParam).Value, out double previousSHInnerFlow); double.TryParse((previousStep[130] as DoubleParam).Value, out double previousSHMidFlow); double.TryParse((previousStep[131] as DoubleParam).Value, out double previousSHOutterFlow); double.TryParse((previousStep[135] as DoubleParam).Value, out double previousInnerSuppFlow); double.TryParse((previousStep[136] as DoubleParam).Value, out double previousMidSuppFlow); double.TryParse((previousStep[137] as DoubleParam).Value, out double previousOutterSuppFlow); double currentSHSuppTotalFlow = currentSHTotalFlow - currentSiSourTotalFlow - currentCSourTotalFlow - currentDopeTotalFlow; double sumSHTotalFlowSplitRatio = currentSHTotalFlowSplitRatio[0] + currentSHTotalFlowSplitRatio[1] + currentSHTotalFlowSplitRatio[2]; double currentSHInnerFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[0]; double currentSHMidFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[1]; double currentSHOutterFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[2]; double currentInnerSuppFlow = currentSHInnerFlow - currentSiSourInnerFlow - currentCSourInnerFlow - currentDopeInnerFlow; double currentMidSuppFlow = currentSHMidFlow - currentSiSourMidFlow - currentCSourMidFlow - currentDopeMidFlow; double currentOutterSuppFlow = currentSHSuppTotalFlow - currentInnerSuppFlow - currentMidSuppFlow; (currentStep[127] as DoubleParam).Value = currentSHSuppTotalFlow.ToString("F1"); (currentStep[128] as DoubleParam).Value = ((currentSHSuppTotalFlow - previousSHSuppTotalFlow) / stepTime).ToString("F1"); (currentStep[129] as DoubleParam).Value = currentSHInnerFlow.ToString("F1"); (currentStep[130] as DoubleParam).Value = currentSHMidFlow.ToString("F1"); (currentStep[131] as DoubleParam).Value = currentSHOutterFlow.ToString("F1"); (currentStep[132] as DoubleParam).Value = ((currentSHInnerFlow - previousSHInnerFlow) / stepTime).ToString("F1"); (currentStep[133] as DoubleParam).Value = ((currentSHMidFlow - previousSHMidFlow) / stepTime).ToString("F1"); (currentStep[134] as DoubleParam).Value = ((currentSHOutterFlow - previousSHOutterFlow) / stepTime).ToString("F1"); (currentStep[135] as DoubleParam).Value = currentInnerSuppFlow.ToString("F1"); (currentStep[136] as DoubleParam).Value = currentMidSuppFlow.ToString("F1"); (currentStep[137] as DoubleParam).Value = currentOutterSuppFlow.ToString("F1"); (currentStep[138] as DoubleParam).Value = ((currentInnerSuppFlow - previousInnerSuppFlow) / stepTime).ToString("F1"); (currentStep[139] as DoubleParam).Value = ((currentMidSuppFlow - previousMidSuppFlow) / stepTime).ToString("F1"); (currentStep[140] as DoubleParam).Value = ((currentOutterSuppFlow - previousOutterSuppFlow) / stepTime).ToString("F1"); #endregion #region SH Periphery Purge double.TryParse((previousStep[142] as DoubleParam).Value, out double previousSHPurgeFlow); double.TryParse((previousStep[145] as DoubleParam).Value, out double previousGRPurgeMainFlow); double.TryParse((previousStep[146] as DoubleParam).Value, out double previousGRPurgeHClFlow); double.TryParse((currentStep[142] as DoubleParam).Value, out double currentSHPurgeFlow); double.TryParse((currentStep[145] as DoubleParam).Value, out double currentGRPurgeMainFlow); double.TryParse((currentStep[146] as DoubleParam).Value, out double currentGRPurgeHClFlow); (currentStep[147] as DoubleParam).Value = ((currentSHPurgeFlow - previousSHPurgeFlow) / stepTime).ToString("F1"); (currentStep[148] as DoubleParam).Value = ((currentGRPurgeMainFlow - previousGRPurgeMainFlow) / stepTime).ToString("F1"); (currentStep[149] as DoubleParam).Value = ((currentGRPurgeHClFlow - previousGRPurgeHClFlow) / stepTime).ToString("F1"); #endregion #region Chamber Periphery Purge double.TryParse((previousStep[151] as DoubleParam).Value, out double previousHeaterUpPurgeFlow); double.TryParse((previousStep[152] as DoubleParam).Value, out double previousChamberPurgeFlow); double.TryParse((previousStep[153] as DoubleParam).Value, out double previousRotationUpPurgeFlow); double.TryParse((previousStep[154] as DoubleParam).Value, out double previousShutterPurgeFlow); double.TryParse((previousStep[155] as DoubleParam).Value, out double previousHeaterWFPurgeFlow); double.TryParse((currentStep[151] as DoubleParam).Value, out double currentHeaterUpPurgeFlow); double.TryParse((currentStep[152] as DoubleParam).Value, out double currentChamberPurgeFlow); double.TryParse((currentStep[153] as DoubleParam).Value, out double currentRotationUpPurgeFlow); double.TryParse((currentStep[154] as DoubleParam).Value, out double currentShutterPurgeFlow); double.TryParse((currentStep[155] as DoubleParam).Value, out double currentHeaterWFPurgeFlow); (currentStep[156] as DoubleParam).Value = ((currentHeaterUpPurgeFlow - previousHeaterUpPurgeFlow) / stepTime).ToString("F1"); (currentStep[157] as DoubleParam).Value = ((currentChamberPurgeFlow - previousChamberPurgeFlow) / stepTime).ToString("F1"); (currentStep[158] as DoubleParam).Value = ((currentRotationUpPurgeFlow - previousRotationUpPurgeFlow) / stepTime).ToString("F1"); (currentStep[159] as DoubleParam).Value = ((currentShutterPurgeFlow - previousShutterPurgeFlow) / stepTime).ToString("F1"); (currentStep[160] as DoubleParam).Value = ((currentHeaterWFPurgeFlow - previousHeaterWFPurgeFlow) / stepTime).ToString("F1"); #endregion #region Vent Flow double.TryParse((previousStep[162] as DoubleParam).Value, out double previousTotalVentFlow); double.TryParse((previousStep[163] as DoubleParam).Value, out double previousVentPushFlow); double.TryParse((previousStep[164] as DoubleParam).Value, out double previousVentPreExhaustPres); double.TryParse((currentStep[162] as DoubleParam).Value, out double currentTotalVentFlow); double.TryParse((currentStep[164] as DoubleParam).Value, out double currentVentPreExhaustPres); double currentSiSourTotalFlowForPurge = (SiH4FlowMode != FlowMode.Run.ToString() ? currentSiH4Flow : 0) + (TCSFlowMode != FlowMode.Run.ToString() ? TCSFlow : 0) + (HClFlowMode != FlowMode.Run.ToString() ? currentHClFlow : 0); double currentCSourTotalFlowForPurge = (C2H4FlowMode != FlowMode.Run.ToString() ? currentC2H4Flow : 0); double N2Flow = 0; if (N2FlowMode == FlowMode.Run.ToString()) N2Flow = currentN2LowFlow + currentDiluFlowForN2 - currentDilutedN2Flow; else if (N2FlowMode == FlowMode.Purge.ToString() || N2FlowMode == FlowMode.Vent.ToString()) N2Flow = currentN2LowFlow + currentDiluFlowForN2 + (N2HighFlowMode == "Enable" ? currentN2HighFlow : 0); double currentDopeTotalFlowForPurge = N2Flow + (TMAFlowMode != FlowMode.Run.ToString() ? TMAFlow : 0); double currentVentPushFlow = currentTotalVentFlow - currentSiSourTotalFlowForPurge - currentCSourTotalFlowForPurge - currentDopeTotalFlowForPurge; (currentStep[163] as DoubleParam).Value = currentVentPushFlow.ToString("F1"); (currentStep[165] as DoubleParam).Value = ((currentTotalVentFlow - previousTotalVentFlow) / stepTime).ToString("F1"); (currentStep[166] as DoubleParam).Value = ((currentVentPushFlow - previousVentPushFlow) / stepTime).ToString("F1"); (currentStep[167] as DoubleParam).Value = ((currentVentPreExhaustPres - previousVentPreExhaustPres) / stepTime).ToString("F1"); #endregion } private void CalRecipeParameterForRunVent(RecipeStep previousStep, RecipeStep currentStep, double stepTime) { #region Temp.Setting double.TryParse((previousStep[10] as DoubleParam).Value, out double previousSusMidTemp); double.TryParse((previousStep[11] as DoubleParam).Value, out double previousSusInnerTemp); double.TryParse((previousStep[12] as DoubleParam).Value, out double previousSusOutterTemp); double.TryParse((previousStep[13] as DoubleParam).Value, out double previousWWTemp); double.TryParse((currentStep[10] as DoubleParam).Value, out double currentSusMidTemp); double.TryParse((currentStep[11] as DoubleParam).Value, out double currentSusInnerTemp); double.TryParse((currentStep[12] as DoubleParam).Value, out double currentSusOutterTemp); double.TryParse((currentStep[13] as DoubleParam).Value, out double currentWWTemp); (currentStep[14] as DoubleParam).Value = ((currentSusMidTemp - previousSusMidTemp) / stepTime).ToString("F1"); (currentStep[15] as DoubleParam).Value = ((currentSusInnerTemp - previousSusInnerTemp) / stepTime).ToString("F1"); (currentStep[16] as DoubleParam).Value = ((currentSusOutterTemp - previousSusOutterTemp) / stepTime).ToString("F1"); (currentStep[17] as DoubleParam).Value = ((currentWWTemp - previousWWTemp) / stepTime).ToString("F1"); #endregion #region Heater Output double.TryParse((previousStep[19] as DoubleParam).Value, out double previousSusMidOP); double.TryParse((previousStep[20] as DoubleParam).Value, out double previousSusInnerOP); double.TryParse((previousStep[21] as DoubleParam).Value, out double previousSusOutterOP); double.TryParse((previousStep[22] as DoubleParam).Value, out double previousSusComOP); double.TryParse((previousStep[23] as DoubleParam).Value, out double previousWWBottomOP); double.TryParse((previousStep[24] as DoubleParam).Value, out double previousWWMidOP); double.TryParse((previousStep[25] as DoubleParam).Value, out double previousWWTopOP); double.TryParse((previousStep[26] as DoubleParam).Value, out double previousWWComOP); double.TryParse((currentStep[19] as DoubleParam).Value, out double currentSusMidOP); double.TryParse((currentStep[20] as DoubleParam).Value, out double currentSusInnerOP); double.TryParse((currentStep[21] as DoubleParam).Value, out double currentSusOutterOP); double.TryParse((currentStep[22] as DoubleParam).Value, out double currentSusComOP); double.TryParse((currentStep[23] as DoubleParam).Value, out double currentWWBottomOP); double.TryParse((currentStep[24] as DoubleParam).Value, out double currentWWMidOP); double.TryParse((currentStep[25] as DoubleParam).Value, out double currentWWTopOP); double.TryParse((currentStep[26] as DoubleParam).Value, out double currentWWComOP); (currentStep[27] as DoubleParam).Value = ((currentSusMidOP - previousSusMidOP) / stepTime).ToString("F1"); (currentStep[28] as DoubleParam).Value = ((currentSusInnerOP - previousSusInnerOP) / stepTime).ToString("F1"); (currentStep[29] as DoubleParam).Value = ((currentSusOutterOP - previousSusOutterOP) / stepTime).ToString("F1"); (currentStep[30] as DoubleParam).Value = ((currentWWBottomOP - previousWWBottomOP) / stepTime).ToString("F1"); (currentStep[31] as DoubleParam).Value = ((currentWWMidOP - previousWWMidOP) / stepTime).ToString("F1"); (currentStep[32] as DoubleParam).Value = ((currentWWTopOP - previousWWTopOP) / stepTime).ToString("F1"); #endregion #region Pressure Rotation double.TryParse((previousStep[34] as DoubleParam).Value, out double previousPresSet); double.TryParse((previousStep[36] as DoubleParam).Value, out double previousRotationSet); double.TryParse((currentStep[34] as DoubleParam).Value, out double currentPresSet); double.TryParse((currentStep[36] as DoubleParam).Value, out double currentRotationSet); (currentStep[35] as DoubleParam).Value = ((currentPresSet - previousPresSet) / stepTime).ToString("F1"); (currentStep[37] as DoubleParam).Value = ((currentRotationSet - previousRotationSet) / stepTime).ToString("F1"); #endregion #region SH Total flow double.TryParse((previousStep[41] as DoubleParam).Value, out double previousSHTotalFlow); double.TryParse((currentStep[41] as DoubleParam).Value, out double currentSHTotalFlow); (currentStep[42] as DoubleParam).Value = ((currentSHTotalFlow - previousSHTotalFlow) / stepTime).ToString("F1"); string[] arrGlobalSplitRatio = (currentStep[44] as StringParam).Value.Split(':'); double[] currentGlobalSplitRatio = new double[3]; if (arrGlobalSplitRatio.Length == 3) { double.TryParse(arrGlobalSplitRatio[0], out currentGlobalSplitRatio[0]); double.TryParse(arrGlobalSplitRatio[1], out currentGlobalSplitRatio[1]); double.TryParse(arrGlobalSplitRatio[2], out currentGlobalSplitRatio[2]); } string[] arrSHTotalFlowSplitRatio = (currentStep[45] as StringParam).Value.Split(':'); double[] currentSHTotalFlowSplitRatio = new double[3]; if (arrSHTotalFlowSplitRatio.Length == 3) { double.TryParse(arrSHTotalFlowSplitRatio[0], out currentSHTotalFlowSplitRatio[0]); double.TryParse(arrSHTotalFlowSplitRatio[1], out currentSHTotalFlowSplitRatio[1]); double.TryParse(arrSHTotalFlowSplitRatio[2], out currentSHTotalFlowSplitRatio[2]); } #endregion #region Si Source double.TryParse((previousStep[47] as DoubleParam).Value, out double previousSiSourTotalFlow); double.TryParse((previousStep[51] as DoubleParam).Value, out double previousSiH4Flow); double.TryParse((previousStep[55] as DoubleParam).Value, out double previousTCSBubbLowFlow); double.TryParse((previousStep[56] as DoubleParam).Value, out double previousTCSBubbHighFlow); double.TryParse((previousStep[57] as DoubleParam).Value, out double previousTCSPushFlow); double.TryParse((previousStep[58] as DoubleParam).Value, out double previousTCSBubbPres); double.TryParse((previousStep[65] as DoubleParam).Value, out double previousHClFlow); double.TryParse((previousStep[69] as DoubleParam).Value, out double previousSiSourPushFlow); double.TryParse((previousStep[70] as DoubleParam).Value, out double previousSiSourInnerFlow); double.TryParse((previousStep[71] as DoubleParam).Value, out double previousSiSourMidFlow); double.TryParse((previousStep[72] as DoubleParam).Value, out double previousSiSourPreSplitPres); double.TryParse((currentStep[51] as DoubleParam).Value, out double currentSiH4Flow); double.TryParse((currentStep[55] as DoubleParam).Value, out double currentTCSBubbLowFlow); double.TryParse((currentStep[56] as DoubleParam).Value, out double currentTCSBubbHighFlow); double.TryParse((currentStep[57] as DoubleParam).Value, out double currentTCSPushFlow); double.TryParse((currentStep[58] as DoubleParam).Value, out double currentTCSBubbPres); double.TryParse((currentStep[65] as DoubleParam).Value, out double currentHClFlow); string[] arrSiSourSplitRatio = (currentStep[68] as StringParam).Value.Split(':'); double[] currentSiSourSplitRatio = new double[3]; if (arrSiSourSplitRatio.Length == 3) { double.TryParse(arrSiSourSplitRatio[0], out currentSiSourSplitRatio[0]); double.TryParse(arrSiSourSplitRatio[1], out currentSiSourSplitRatio[1]); double.TryParse(arrSiSourSplitRatio[2], out currentSiSourSplitRatio[2]); } double.TryParse((currentStep[69] as DoubleParam).Value, out double currentSiSourPushFlow); double.TryParse((currentStep[72] as DoubleParam).Value, out double currentSiSourPreSplitPres); (currentStep[52] as DoubleParam).Value = ((currentSiH4Flow - previousSiH4Flow) / stepTime).ToString("F1"); (currentStep[59] as DoubleParam).Value = ((currentTCSBubbLowFlow - previousTCSBubbLowFlow) / stepTime).ToString("F1"); (currentStep[60] as DoubleParam).Value = ((currentTCSBubbHighFlow - previousTCSBubbHighFlow) / stepTime).ToString("F1"); (currentStep[61] as DoubleParam).Value = ((currentTCSPushFlow - previousTCSPushFlow) / stepTime).ToString("F1"); (currentStep[62] as DoubleParam).Value = ((currentTCSBubbPres - previousTCSBubbPres) / stepTime).ToString("F1"); (currentStep[66] as DoubleParam).Value = ((currentHClFlow - previousHClFlow) / stepTime).ToString("F1"); string previousSiH4FlowMode = (previousStep[50] as ComboxParam).Value; string previousTCSFlowMode = (previousStep[54] as ComboxParam).Value; string previousHClFlowMode = (previousStep[64] as ComboxParam).Value; string currentSiH4FlowMode = (currentStep[50] as ComboxParam).Value; string currentTCSFlowMode = (currentStep[54] as ComboxParam).Value; string currentHClFlowMode = (currentStep[64] as ComboxParam).Value; bool isSiSourRunVentSwitch = false; List lstFlowMode = new List() { FlowMode.Run.ToString(), FlowMode.Vent.ToString() }; if ((previousSiH4FlowMode != currentSiH4FlowMode) && lstFlowMode.Contains(previousSiH4FlowMode) && lstFlowMode.Contains(currentSiH4FlowMode)) { isSiSourRunVentSwitch = true; } else if ((previousTCSFlowMode != currentTCSFlowMode) && lstFlowMode.Contains(previousTCSFlowMode) && lstFlowMode.Contains(currentTCSFlowMode)) { isSiSourRunVentSwitch = true; } else if ((previousHClFlowMode != currentHClFlowMode) && lstFlowMode.Contains(previousHClFlowMode) && lstFlowMode.Contains(currentHClFlowMode)) { isSiSourRunVentSwitch = true; } double TCSFlow = 0; double TCS_Eff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{SelectedChamber}.Efficiency.TCS-Eff"); if (currentTCSFlowMode == FlowMode.Run.ToString() || currentTCSFlowMode == FlowMode.Vent.ToString()) TCSFlow = (currentTCSBubbHighFlow + currentTCSBubbLowFlow) * TCS_Eff + currentTCSPushFlow; else if (currentTCSFlowMode == FlowMode.Purge.ToString()) TCSFlow = currentTCSBubbHighFlow + currentTCSBubbLowFlow + currentTCSPushFlow; if (isSiSourRunVentSwitch) { previousSiSourPushFlow = previousSiSourTotalFlow - (currentSiH4FlowMode == FlowMode.Run.ToString() ? currentSiH4Flow : 0) - (currentTCSFlowMode == FlowMode.Run.ToString() ? TCSFlow : 0) - (currentHClFlowMode == FlowMode.Run.ToString() ? currentHClFlow : 0); } double currentSiSourTotalFlow = currentSiSourPushFlow + (currentSiH4FlowMode == FlowMode.Run.ToString() ? currentSiH4Flow : 0) + (currentTCSFlowMode == FlowMode.Run.ToString() ? TCSFlow : 0) + (currentHClFlowMode == FlowMode.Run.ToString() ? currentHClFlow : 0); (currentStep[47] as DoubleParam).Value = currentSiSourTotalFlow.ToString("F1"); (currentStep[48] as DoubleParam).Value = ((currentSiSourTotalFlow - previousSiSourTotalFlow) / stepTime).ToString("F1"); double currentSiSourInnerFlow = 0; double currentSiSourMidFlow = 0; if (currentSiSourSplitRatio.Length == 3) { double rationSum = currentSiSourSplitRatio[0] + currentSiSourSplitRatio[1] + currentSiSourSplitRatio[2]; currentSiSourInnerFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[0]; currentSiSourMidFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[1]; } (currentStep[70] as DoubleParam).Value = currentSiSourInnerFlow.ToString("F1"); (currentStep[71] as DoubleParam).Value = currentSiSourMidFlow.ToString("F1"); (currentStep[73] as DoubleParam).Value = ((currentSiSourPushFlow - previousSiSourPushFlow) / stepTime).ToString("F1"); (currentStep[74] as DoubleParam).Value = ((currentSiSourInnerFlow - previousSiSourInnerFlow) / stepTime).ToString("F1"); (currentStep[75] as DoubleParam).Value = ((currentSiSourMidFlow - previousSiSourMidFlow) / stepTime).ToString("F1"); (currentStep[76] as DoubleParam).Value = ((currentSiSourPreSplitPres - previousSiSourPreSplitPres) / stepTime).ToString("F1"); #endregion #region C Source double.TryParse((previousStep[78] as DoubleParam).Value, out double previousCSourTotalFlow); double.TryParse((previousStep[82] as DoubleParam).Value, out double previousC2H4Flow); double.TryParse((previousStep[86] as DoubleParam).Value, out double previousCSourPushFlow); double.TryParse((previousStep[87] as DoubleParam).Value, out double previousCSourInnerFlow); double.TryParse((previousStep[88] as DoubleParam).Value, out double previousCSourMidFlow); double.TryParse((previousStep[88] as DoubleParam).Value, out double previousCSourPreSplitPres); double.TryParse((currentStep[82] as DoubleParam).Value, out double currentC2H4Flow); string[] arrCSourSplitRatio = (currentStep[85] as StringParam).Value.Split(':'); double[] currentCSourSplitRatio = new double[3]; if (arrCSourSplitRatio.Length == 3) { double.TryParse(arrCSourSplitRatio[0], out currentCSourSplitRatio[0]); double.TryParse(arrCSourSplitRatio[1], out currentCSourSplitRatio[1]); double.TryParse(arrCSourSplitRatio[2], out currentCSourSplitRatio[2]); } double.TryParse((currentStep[86] as DoubleParam).Value, out double currentCSourPushFlow); double.TryParse((currentStep[89] as DoubleParam).Value, out double currentCSourPreSplitPres); (currentStep[83] as DoubleParam).Value = ((currentC2H4Flow - previousC2H4Flow) / stepTime).ToString("F1"); string previousC2H4FlowMode = (previousStep[81] as ComboxParam).Value; string currentC2H4FlowMode = (currentStep[81] as ComboxParam).Value; bool isCSourRunVentSwitch = false; if ((previousC2H4FlowMode != currentC2H4FlowMode) && lstFlowMode.Contains(previousC2H4FlowMode) && lstFlowMode.Contains(currentC2H4FlowMode)) { isCSourRunVentSwitch = true; } if (isCSourRunVentSwitch) { previousCSourPushFlow = previousCSourTotalFlow - (currentC2H4FlowMode == FlowMode.Run.ToString() ? currentC2H4Flow : 0); } double currentCSourTotalFlow = currentCSourPushFlow + (currentC2H4FlowMode == FlowMode.Run.ToString() ? currentC2H4Flow : 0); (currentStep[78] as DoubleParam).Value = currentCSourTotalFlow.ToString("F1"); (currentStep[79] as DoubleParam).Value = ((currentCSourTotalFlow - previousCSourTotalFlow) / stepTime).ToString("F1"); double currentCSourInnerFlow = 0; double currentCSourMidFlow = 0; if (currentCSourSplitRatio.Length == 3) { double ratioSum = currentCSourSplitRatio[0] + currentCSourSplitRatio[1] + currentCSourSplitRatio[2]; currentCSourInnerFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[0]; currentCSourMidFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[1]; } (currentStep[87] as DoubleParam).Value = currentCSourInnerFlow.ToString("F1"); (currentStep[88] as DoubleParam).Value = currentCSourMidFlow.ToString("F1"); (currentStep[90] as DoubleParam).Value = ((currentCSourPushFlow - previousCSourPushFlow) / stepTime).ToString("F1"); (currentStep[91] as DoubleParam).Value = ((currentCSourInnerFlow - previousCSourInnerFlow) / stepTime).ToString("F1"); (currentStep[92] as DoubleParam).Value = ((currentCSourMidFlow - previousCSourMidFlow) / stepTime).ToString("F1"); (currentStep[93] as DoubleParam).Value = ((currentCSourPreSplitPres - previousCSourPreSplitPres) / stepTime).ToString("F1"); #endregion #region Dope double.TryParse((previousStep[95] as DoubleParam).Value, out double previousDopeTotalFlow); double.TryParse((previousStep[99] as DoubleParam).Value, out double previousN2LowFlow); double.TryParse((previousStep[100] as DoubleParam).Value, out double previousDiluFlowForN2); double.TryParse((previousStep[101] as DoubleParam).Value, out double previousDilutedN2Flow); double.TryParse((previousStep[102] as DoubleParam).Value, out double previousN2PostDiluPres); double.TryParse((previousStep[104] as DoubleParam).Value, out double previousN2HighFlow); double.TryParse((previousStep[112] as DoubleParam).Value, out double previousTMABubbFlow); double.TryParse((previousStep[113] as DoubleParam).Value, out double previousTMAPush); double.TryParse((previousStep[114] as DoubleParam).Value, out double previousTMABubbPres); double.TryParse((previousStep[120] as DoubleParam).Value, out double previousDopePushFlow); double.TryParse((previousStep[121] as DoubleParam).Value, out double previousDopeInnerFlow); double.TryParse((previousStep[122] as DoubleParam).Value, out double previousDopeMidFlow); double.TryParse((previousStep[123] as DoubleParam).Value, out double previousDopePreSplitPres); double.TryParse((currentStep[99] as DoubleParam).Value, out double currentN2LowFlow); double.TryParse((currentStep[100] as DoubleParam).Value, out double currentDiluFlowForN2); double.TryParse((currentStep[101] as DoubleParam).Value, out double currentDilutedN2Flow); double.TryParse((currentStep[102] as DoubleParam).Value, out double currentN2PostDiluPres); double.TryParse((currentStep[104] as DoubleParam).Value, out double currentN2HighFlow); double.TryParse((currentStep[112] as DoubleParam).Value, out double currentTMABubbFlow); double.TryParse((currentStep[113] as DoubleParam).Value, out double currentTMAPush); double.TryParse((currentStep[114] as DoubleParam).Value, out double currentTMABubbPres); string[] arrDopeSplitRatio = (currentStep[119] as StringParam).Value.Split(':'); double[] currentDopeSplitRatio = new double[3]; if (arrDopeSplitRatio.Length == 3) { double.TryParse(arrDopeSplitRatio[0], out currentDopeSplitRatio[0]); double.TryParse(arrDopeSplitRatio[1], out currentDopeSplitRatio[1]); double.TryParse(arrDopeSplitRatio[2], out currentDopeSplitRatio[2]); } double.TryParse((currentStep[120] as DoubleParam).Value, out double currentDopePushFlow); double.TryParse((currentStep[123] as DoubleParam).Value, out double currentDopePreSplitPres); (currentStep[105] as DoubleParam).Value = ((currentN2LowFlow - previousN2LowFlow) / stepTime).ToString("F1"); (currentStep[106] as DoubleParam).Value = ((currentDiluFlowForN2 - previousDiluFlowForN2) / stepTime).ToString("F1"); (currentStep[107] as DoubleParam).Value = ((currentDilutedN2Flow - previousDilutedN2Flow) / stepTime).ToString("F1"); (currentStep[108] as DoubleParam).Value = ((currentN2PostDiluPres - previousN2PostDiluPres) / stepTime).ToString("F1"); (currentStep[115] as DoubleParam).Value = ((currentTMABubbFlow - previousTMABubbFlow) / stepTime).ToString("F1"); (currentStep[116] as DoubleParam).Value = ((currentTMAPush - previousTMAPush) / stepTime).ToString("F1"); (currentStep[117] as DoubleParam).Value = ((currentTMABubbPres - previousTMABubbPres) / stepTime).ToString("F1"); string previousN2FlowMode = (previousStep[98] as ComboxParam).Value; string previousN2HighFlowMode = (previousStep[103] as ComboxParam).Value; string previousTMAFlowMode = (previousStep[111] as ComboxParam).Value; string currentN2FlowMode = (currentStep[98] as ComboxParam).Value; string currentN2HighFlowMode = (currentStep[103] as ComboxParam).Value; string currentTMAFlowMode = (currentStep[111] as ComboxParam).Value; if (previousN2HighFlowMode == "Enable" && currentN2HighFlowMode == "Enable") { (currentStep[109] as DoubleParam).Value = ((currentN2HighFlow - previousN2HighFlow) / stepTime).ToString("F1"); } else { (currentStep[109] as DoubleParam).Value = 0.ToString("F1"); } bool isDopeRunVentSwitch = false; if ((previousN2FlowMode != currentN2FlowMode) && lstFlowMode.Contains(previousN2FlowMode) && lstFlowMode.Contains(currentN2FlowMode)) { isDopeRunVentSwitch = true; } else if (previousN2HighFlowMode != currentN2HighFlowMode) { isDopeRunVentSwitch = true; } else if (previousTMAFlowMode != currentTMAFlowMode && lstFlowMode.Contains(previousTMAFlowMode) && lstFlowMode.Contains(currentTMAFlowMode)) { isDopeRunVentSwitch = true; } double TMAFlow = 0; double TMA_Eff = (double)QueryDataClient.Instance.Service.GetConfig($"PM.{SelectedChamber}.Efficiency.TMA-Eff"); if (currentTMAFlowMode == FlowMode.Run.ToString() || currentTMAFlowMode == FlowMode.Vent.ToString()) TMAFlow = currentTMABubbFlow * TMA_Eff + currentTMAPush; else if (currentTMAFlowMode == FlowMode.Purge.ToString()) TMAFlow = currentTMABubbFlow + currentTMAPush; if (isDopeRunVentSwitch) { previousDopePushFlow = previousDopeTotalFlow - (currentTMAFlowMode == FlowMode.Run.ToString() ? TMAFlow : 0) - (currentN2FlowMode == FlowMode.Run.ToString() ? currentDilutedN2Flow + (currentN2HighFlowMode == "Enable" ? currentN2HighFlow : 0) : 0); } double currentDopeTotalFlow = currentDopePushFlow + (currentN2FlowMode == FlowMode.Run.ToString() ? currentDilutedN2Flow + (currentN2HighFlowMode == "Enable" ? currentN2HighFlow : 0) : 0) + (currentTMAFlowMode == FlowMode.Run.ToString() ? TMAFlow : 0); (currentStep[95] as DoubleParam).Value = currentDopeTotalFlow.ToString("F1"); (currentStep[96] as DoubleParam).Value = ((currentDopeTotalFlow - previousDopeTotalFlow) / stepTime).ToString("F1"); double currentDopeInnerFlow = 0; double currentDopeMidFlow = 0; if (currentDopeSplitRatio.Length == 3) { double ratioSum = currentDopeSplitRatio[0] + currentDopeSplitRatio[1] + currentDopeSplitRatio[2]; currentDopeInnerFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[0]; currentDopeMidFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[1]; } (currentStep[121] as DoubleParam).Value = currentDopeInnerFlow.ToString("F1"); (currentStep[122] as DoubleParam).Value = currentDopeMidFlow.ToString("F1"); (currentStep[124] as DoubleParam).Value = ((currentDopePushFlow - previousDopePushFlow) / stepTime).ToString("F1"); (currentStep[125] as DoubleParam).Value = ((currentDopeInnerFlow - previousDopeInnerFlow) / stepTime).ToString("F1"); (currentStep[126] as DoubleParam).Value = ((currentDopeMidFlow - previousDopeMidFlow) / stepTime).ToString("F1"); (currentStep[127] as DoubleParam).Value = ((currentDopePreSplitPres - previousDopePreSplitPres) / stepTime).ToString("F1"); #endregion #region SH Supp. Flow double.TryParse((previousStep[129] as DoubleParam).Value, out double previousSHSuppTotalFlow); double.TryParse((previousStep[131] as DoubleParam).Value, out double previousSHInnerFlow); double.TryParse((previousStep[132] as DoubleParam).Value, out double previousSHMidFlow); double.TryParse((previousStep[133] as DoubleParam).Value, out double previousSHOutterFlow); double.TryParse((previousStep[137] as DoubleParam).Value, out double previousInnerSuppFlow); double.TryParse((previousStep[138] as DoubleParam).Value, out double previousMidSuppFlow); double.TryParse((previousStep[139] as DoubleParam).Value, out double previousOutterSuppFlow); double currentSHSuppTotalFlow = currentSHTotalFlow - currentSiSourTotalFlow - currentCSourTotalFlow - currentDopeTotalFlow; double sumSHTotalFlowSplitRatio = currentSHTotalFlowSplitRatio[0] + currentSHTotalFlowSplitRatio[1] + currentSHTotalFlowSplitRatio[2]; double currentSHInnerFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[0]; double currentSHMidFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[1]; double currentSHOutterFlow = currentSHTotalFlow / sumSHTotalFlowSplitRatio * currentSHTotalFlowSplitRatio[2]; double currentInnerSuppFlow = currentSHInnerFlow - currentSiSourInnerFlow - currentCSourInnerFlow - currentDopeInnerFlow; double currentMidSuppFlow = currentSHMidFlow - currentSiSourMidFlow - currentCSourMidFlow - currentDopeMidFlow; double currentOutterSuppFlow = currentSHSuppTotalFlow - currentInnerSuppFlow - currentMidSuppFlow; (currentStep[129] as DoubleParam).Value = currentSHSuppTotalFlow.ToString("F1"); (currentStep[130] as DoubleParam).Value = ((currentSHSuppTotalFlow - previousSHSuppTotalFlow) / stepTime).ToString("F1"); (currentStep[131] as DoubleParam).Value = currentSHInnerFlow.ToString("F1"); (currentStep[132] as DoubleParam).Value = currentSHMidFlow.ToString("F1"); (currentStep[133] as DoubleParam).Value = currentSHOutterFlow.ToString("F1"); (currentStep[134] as DoubleParam).Value = ((currentSHInnerFlow - previousSHInnerFlow) / stepTime).ToString("F1"); (currentStep[135] as DoubleParam).Value = ((currentSHMidFlow - previousSHMidFlow) / stepTime).ToString("F1"); (currentStep[136] as DoubleParam).Value = ((currentSHOutterFlow - previousSHOutterFlow) / stepTime).ToString("F1"); (currentStep[137] as DoubleParam).Value = currentInnerSuppFlow.ToString("F1"); (currentStep[138] as DoubleParam).Value = currentMidSuppFlow.ToString("F1"); (currentStep[139] as DoubleParam).Value = currentOutterSuppFlow.ToString("F1"); (currentStep[140] as DoubleParam).Value = ((currentInnerSuppFlow - previousInnerSuppFlow) / stepTime).ToString("F1"); (currentStep[141] as DoubleParam).Value = ((currentMidSuppFlow - previousMidSuppFlow) / stepTime).ToString("F1"); (currentStep[142] as DoubleParam).Value = ((currentOutterSuppFlow - previousOutterSuppFlow) / stepTime).ToString("F1"); #endregion #region SH Periphery Purge double.TryParse((previousStep[144] as DoubleParam).Value, out double previousSHPurgeFlow); double.TryParse((previousStep[147] as DoubleParam).Value, out double previousGRPurgeMainFlow); double.TryParse((previousStep[148] as DoubleParam).Value, out double previousGRPurgeHClFlow); double.TryParse((currentStep[144] as DoubleParam).Value, out double currentSHPurgeFlow); double.TryParse((currentStep[147] as DoubleParam).Value, out double currentGRPurgeMainFlow); double.TryParse((currentStep[148] as DoubleParam).Value, out double currentGRPurgeHClFlow); (currentStep[149] as DoubleParam).Value = ((currentSHPurgeFlow - previousSHPurgeFlow) / stepTime).ToString("F1"); (currentStep[150] as DoubleParam).Value = ((currentGRPurgeMainFlow - previousGRPurgeMainFlow) / stepTime).ToString("F1"); (currentStep[151] as DoubleParam).Value = ((currentGRPurgeHClFlow - previousGRPurgeHClFlow) / stepTime).ToString("F1"); #endregion #region Chamber Periphery Purge double.TryParse((previousStep[153] as DoubleParam).Value, out double previousHeaterUpPurgeFlow); double.TryParse((previousStep[154] as DoubleParam).Value, out double previousChamberPurgeFlow); double.TryParse((previousStep[155] as DoubleParam).Value, out double previousRotationUpPurgeFlow); double.TryParse((previousStep[156] as DoubleParam).Value, out double previousShutterPurgeFlow); double.TryParse((previousStep[157] as DoubleParam).Value, out double previousHeaterWFPurgeFlow); double.TryParse((currentStep[153] as DoubleParam).Value, out double currentHeaterUpPurgeFlow); double.TryParse((currentStep[154] as DoubleParam).Value, out double currentChamberPurgeFlow); double.TryParse((currentStep[155] as DoubleParam).Value, out double currentRotationUpPurgeFlow); double.TryParse((currentStep[156] as DoubleParam).Value, out double currentShutterPurgeFlow); double.TryParse((currentStep[157] as DoubleParam).Value, out double currentHeaterWFPurgeFlow); (currentStep[158] as DoubleParam).Value = ((currentHeaterUpPurgeFlow - previousHeaterUpPurgeFlow) / stepTime).ToString("F1"); (currentStep[159] as DoubleParam).Value = ((currentChamberPurgeFlow - previousChamberPurgeFlow) / stepTime).ToString("F1"); (currentStep[160] as DoubleParam).Value = ((currentRotationUpPurgeFlow - previousRotationUpPurgeFlow) / stepTime).ToString("F1"); (currentStep[161] as DoubleParam).Value = ((currentShutterPurgeFlow - previousShutterPurgeFlow) / stepTime).ToString("F1"); (currentStep[162] as DoubleParam).Value = ((currentHeaterWFPurgeFlow - previousHeaterWFPurgeFlow) / stepTime).ToString("F1"); #endregion #region Vent Flow double.TryParse((previousStep[164] as DoubleParam).Value, out double previousTotalVentFlow); double.TryParse((previousStep[165] as DoubleParam).Value, out double previousVentPushFlow); double.TryParse((previousStep[166] as DoubleParam).Value, out double previousVentPreExhaustPres); double.TryParse((currentStep[164] as DoubleParam).Value, out double currentTotalVentFlow); double.TryParse((currentStep[166] as DoubleParam).Value, out double currentVentPreExhaustPres); double currentSiSourTotalFlowForPurge = (currentSiH4FlowMode != FlowMode.Run.ToString() ? currentSiH4Flow : 0) + (currentTCSFlowMode != FlowMode.Run.ToString() ? TCSFlow : 0) + (currentHClFlowMode != FlowMode.Run.ToString() ? currentHClFlow : 0); double currentCSourTotalFlowForPurge = (currentC2H4FlowMode != FlowMode.Run.ToString() ? currentC2H4Flow : 0); double N2Flow = 0; if (currentN2FlowMode == FlowMode.Run.ToString()) N2Flow = currentN2LowFlow + currentDiluFlowForN2 - currentDilutedN2Flow; else if (currentN2FlowMode == FlowMode.Purge.ToString() || currentN2FlowMode == FlowMode.Vent.ToString()) N2Flow = currentN2LowFlow + currentDiluFlowForN2 + (currentN2HighFlowMode == "Enable" ? currentN2HighFlow : 0); double currentDopeTotalFlowForPurge = N2Flow + (currentTMAFlowMode != FlowMode.Run.ToString() ? TMAFlow : 0); bool isTotalVentFlowRunSwitch = false; if ((previousSiH4FlowMode != currentSiH4FlowMode) && (previousSiH4FlowMode == FlowMode.Run.ToString() || currentSiH4FlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } else if ((previousTCSFlowMode != currentTCSFlowMode) && (previousTCSFlowMode == FlowMode.Run.ToString() || currentTCSFlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } else if ((previousHClFlowMode != currentHClFlowMode) && (previousHClFlowMode == FlowMode.Run.ToString() || currentHClFlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } else if ((previousC2H4FlowMode != currentC2H4FlowMode) && (previousC2H4FlowMode == FlowMode.Run.ToString() || currentC2H4FlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } else if ((previousN2FlowMode != currentN2FlowMode) && (previousN2FlowMode == FlowMode.Run.ToString() || currentN2FlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } else if (previousN2HighFlowMode != currentN2HighFlowMode) { isTotalVentFlowRunSwitch = true; } else if (previousTMAFlowMode != currentTMAFlowMode && (previousTMAFlowMode == FlowMode.Run.ToString() || currentTMAFlowMode == FlowMode.Run.ToString())) { isTotalVentFlowRunSwitch = true; } if (isTotalVentFlowRunSwitch) { previousVentPushFlow = previousTotalVentFlow - currentSiSourTotalFlowForPurge - currentCSourTotalFlowForPurge - currentDopeTotalFlowForPurge; } double currentVentPushFlow = currentTotalVentFlow - currentSiSourTotalFlowForPurge - currentCSourTotalFlowForPurge - currentDopeTotalFlowForPurge; (currentStep[165] as DoubleParam).Value = currentVentPushFlow.ToString("F1"); (currentStep[167] as DoubleParam).Value = ((currentTotalVentFlow - previousTotalVentFlow) / stepTime).ToString("F1"); (currentStep[168] as DoubleParam).Value = ((currentVentPushFlow - previousVentPushFlow) / stepTime).ToString("F1"); (currentStep[169] as DoubleParam).Value = ((currentVentPreExhaustPres - previousVentPreExhaustPres) / stepTime).ToString("F1"); #endregion } public void TabSelectionChanged() { UpdateRecipeFormat(); OnViewLoaded(View); } public void UpdateRecipeFormat() { if (DicColunms.Keys.Contains(CurrentProcessType)) { this.Columns = DicColunms[CurrentProcessType]; } else { this.Columns = this._columnBuilder.Build($"{CurrentChamberType}\\{CurrentProcessType}"); DicColunms[CurrentProcessType] = this.Columns; } int indexOthers = this.Columns.IndexOf(this.Columns.Where(x => x.DisplayName == "Others").FirstOrDefault()); ColumnsTolerance = new ObservableCollection( this.Columns.Take(indexOthers)); this.CurrentRecipe = new RecipeData(); CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType; CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion; this.PopSettingColumns = new Dictionary(); this.PopSettingColumns.Add("Oes", _columnBuilder.OesConfig); this.PopSettingColumns.Add("Vat", _columnBuilder.VatConfig); this.PopSettingColumns.Add("FineTuning", _columnBuilder.FineTuningConfig); CurrentRecipe.PopEnable.Add("Oes", _columnBuilder.OesConfig.Count > 0); CurrentRecipe.PopEnable.Add("Vat", _columnBuilder.VatConfig.Count > 0); CurrentRecipe.PopEnable.Add("FineTuning", _columnBuilder.FineTuningConfig.Count > 0); CurrentRecipe.ToleranceEnable = Columns.FirstOrDefault(x => x.EnableTolerance) != null; this.editMode = EditMode.None; var chamber = QueryDataClient.Instance.Service.GetConfig("System.Recipe.ChamberModules"); if (chamber == null) { chamber = "PM1"; } Chambers = new ObservableCollection(((string)chamber).Split(',')); SelectedChamber = Chambers[0]; MultiChamberVisibility = Chambers.Count > 1 ? Visibility.Visible : Visibility.Collapsed; ToleranceVisibility = CurrentRecipe.ToleranceEnable ? Visibility.Visible : Visibility.Collapsed; } public void ChamberSelectionChanged() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } CurrentRecipe.ChangeChamber(Columns,_columnBuilder.Configs, SelectedChamber); } public void TreeSelectChanged(FileNode node) { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } CurrentFileNode = node; if (node != null && node.IsFile) { this.LoadData(node.PrefixPath, node.FullPath); } else { this.ClearData(); this.editMode = EditMode.None; } this.UpdateView(); //OnViewLoaded(View);//zyx debug } #region folder public void NewFolder() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name"); dialog.FileName = "new folder"; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string name = dialog.FileName.Trim(); if (string.IsNullOrEmpty(name)) { DialogBox.ShowWarning("Folder name should not be empty"); return; } string prefix = ChamberType[ChamberTypeIndexSelection] + "\\" + ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType; string processType = string.Empty; string newFolder = string.Empty; if (CurrentFileNode != null) { prefix = CurrentFileNode.PrefixPath; string folder = CurrentFileNode.FullPath; if (CurrentFileNode.IsFile) { folder = folder.Substring(0, folder.LastIndexOf("\\") + 1); if (!string.IsNullOrEmpty(folder)) newFolder = folder; } else { newFolder = folder + "\\"; } } newFolder = newFolder + name; if (IsExist(newFolder, false)) { DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder with the same name already exist."); return; } if (newFolder.Length > 200) { DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder name too long, should be less 200."); return; } _recipeProvider.CreateRecipeFolder(prefix, newFolder); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newFolder, true); } public void NewFolderRoot() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name"); dialog.FileName = "new folder"; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string name = dialog.FileName.Trim(); if (string.IsNullOrEmpty(name)) { DialogBox.ShowWarning("Folder name should not be empty"); return; } if (IsExist(name, false)) { DialogBox.ShowWarning($"Can not create folder {name}, Folder with the same name already exist."); return; } if (name.Length > 200) { DialogBox.ShowWarning($"Can not create folder {name}, Folder name too long, should be less 200."); return; } string prefix = ChamberType[ChamberTypeIndexSelection] + "\\" + ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType; _recipeProvider.CreateRecipeFolder(prefix, name); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, name, true); } public void DeleteFolder() { if (CurrentFileNode == null || CurrentFileNode.IsFile) return; if (CurrentFileNode.Files.Count > 0) { DialogBox.ShowWarning($"Can not delete non-empty folder, Remove the files or folders under \r\n{CurrentFileNode.FullPath}."); return; } var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Are you sure you want to delete \r\n {CurrentFileNode.FullPath}?"); if (selection == DialogButton.No) return; string nextFocus = CurrentFileNode.Parent.FullPath; bool isFolder = true; if (CurrentFileNode.Parent.Files.Count > 1) { for (int i = 0; i < CurrentFileNode.Parent.Files.Count; i++) { if (CurrentFileNode.Parent.Files[i] == CurrentFileNode) { if (i == 0) { nextFocus = CurrentFileNode.Parent.Files[i + 1].FullPath; isFolder = !CurrentFileNode.Parent.Files[i + 1].IsFile; } else { nextFocus = CurrentFileNode.Parent.Files[i - 1].FullPath; isFolder = !CurrentFileNode.Parent.Files[i - 1].IsFile; } } } } _recipeProvider.DeleteRecipeFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, nextFocus, isFolder); } public void RenameFolder() { if (CurrentFileNode == null || CurrentFileNode.IsFile) return; InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Folder Name"); dialog.FileName = CurrentFileNode.Name; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string name = dialog.FileName.Trim(); if (string.IsNullOrEmpty(name)) return; string newFolder = CurrentFileNode.FullPath.Substring(0, CurrentFileNode.FullPath.LastIndexOf("\\") + 1); if (!string.IsNullOrEmpty(newFolder)) newFolder = newFolder + name; else newFolder = name; if (newFolder == CurrentFileNode.FullPath) return; if (IsExist(newFolder, false)) { DialogBox.ShowWarning($"Can not rename to {newFolder}, Folder with the same name already exist."); return; } if (newFolder.Length > 200) { DialogBox.ShowWarning($"Can not create folder {newFolder}, Folder name too long, should be less 200."); return; } _recipeProvider.RenameFolder(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath, newFolder); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newFolder, true); } #endregion #region recipe public void NewRecipe() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name"); dialog.FileName = "new recipe"; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } string prefix = CurrentChamberType + "\\" + CurrentProcessType; string processType = string.Empty; if (CurrentFileNode != null) { string folder = CurrentFileNode.FullPath; if (CurrentFileNode.IsFile) { folder = folder.Substring(0, folder.LastIndexOf("\\") + 1); //if (!string.IsNullOrEmpty(folder)) // folder = folder; } else { folder = folder + "\\"; } recipeName = folder + recipeName; } if (IsExist(recipeName, true)) { DialogBox.ShowWarning($"Can not create {recipeName}, Recipe with the same name already exist."); return; } if (recipeName.Length > 200) { DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200."); return; } RecipeData recipe = new RecipeData(); recipe.Name = recipeName; recipe.PrefixPath = prefix; recipe.Creator = BaseApp.Instance.UserContext.LoginName; recipe.CreateTime = DateTime.Now; recipe.Revisor = BaseApp.Instance.UserContext.LoginName; recipe.ReviseTime = DateTime.Now; recipe.Description = string.Empty; if (!Save(recipe, true)) return; var types = prefix.Split('\\'); ReloadRecipeFileList(types[0], types[1], recipeName, false); } public void NewRecipeRoot() { if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name"); dialog.FileName = "new recipe"; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } if (IsExist(recipeName, true)) { DialogBox.ShowWarning($"Can not create {recipeName}, Recipe with the same name already exist."); return; } if (recipeName.Length > 200) { DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200."); return; } RecipeData recipe = new RecipeData(); recipe.Name = recipeName; recipe.PrefixPath = CurrentChamberType + "\\" + CurrentProcessType; recipe.Creator = BaseApp.Instance.UserContext.LoginName; recipe.CreateTime = DateTime.Now; recipe.Revisor = BaseApp.Instance.UserContext.LoginName; recipe.ReviseTime = DateTime.Now; recipe.Description = string.Empty; if (!Save(recipe, true)) return; ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false); } private void ReloadRecipeFileList(string chamberType, string processType, string selectedFile, bool selectionIsFolder) { ProcessTypeFileItem item = ProcessTypeFileList.FirstOrDefault(x => x.ProcessType == processType); if (item == null) { LOG.Write("error reload recipe file list, type = " + processType); } var prefix = $"{ChamberType[ChamberTypeIndexSelection]}\\{item.ProcessType}"; var recipes = _recipeProvider.GetXmlRecipeList(prefix); item.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, selectedFile, selectionIsFolder, recipes)[0].Files; item.InvokePropertyChanged(); } private bool IsExist(string fullPath, bool isFile) { for (int i = 0; i < ProcessTypeFileList.Count; i++) { if (ProcessTypeFileList[i].ProcessType == CurrentProcessType) { if (ProcessTypeFileList[i].FileListByProcessType.Count == 0) return false; return FindFile(fullPath, ProcessTypeFileList[i].FileListByProcessType[0].Parent, isFile); } } return true; } private bool FindFile(string path, FileNode root, bool isFile) { if (root.FullPath == path && !isFile) { return true; } foreach (var node in root.Files) { if (isFile && node.IsFile && node.FullPath == path) return true; if (!node.IsFile && FindFile(path, node, isFile)) return true; } return false; } public void SaveAsRecipe() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) return; if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name"); dialog.FileName = CurrentFileNode.Name; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } string prefix = CurrentChamberType + "\\" + CurrentProcessType; string processType = string.Empty; string folder = CurrentFileNode.FullPath; if (CurrentFileNode.IsFile) { folder = folder.Substring(0, folder.LastIndexOf("\\") + 1); } if (!string.IsNullOrEmpty(folder)) recipeName = folder + "\\" + recipeName; if (CurrentFileNode.FullPath == recipeName) return; if (IsExist(recipeName, true)) { DialogBox.ShowWarning($"Can not copy to {recipeName}, Recipe with the same name already exist."); return; } if (recipeName.Length > 200) { DialogBox.ShowWarning($"Can not create folder {recipeName}, Folder name too long, should be less 200."); return; } CurrentRecipe.Creator = BaseApp.Instance.UserContext.LoginName; CurrentRecipe.CreateTime = DateTime.Now; CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; CurrentRecipe.ReviseTime = DateTime.Now; CurrentRecipe.Description = CurrentRecipe.Description + ". Renamed from " + CurrentFileNode.Name; _recipeProvider.SaveAsRecipe(prefix, recipeName, CurrentRecipe.GetXmlString()); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false); } public void RenameRecipe() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) return; if (IsChanged) { var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No | DialogButton.Cancel, DialogType.CONFIRM, $"Recipe {CurrentRecipe.Name} is changed, do you want to save it?"); if (selection == DialogButton.Cancel) return; if (selection == DialogButton.Yes) { this.CurrentRecipe.Revisor = BaseApp.Instance.UserContext.LoginName; this.CurrentRecipe.ReviseTime = DateTime.Now; this.Save(this.CurrentRecipe, false); } } InputFileNameDialogViewModel dialog = new InputFileNameDialogViewModel("Input New Recipe Name"); dialog.FileName = CurrentFileNode.Name; WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; string recipeName = dialog.FileName.Trim(); if (string.IsNullOrEmpty(dialog.FileName)) { DialogBox.ShowWarning("Recipe file name should not be empty"); return; } string prefix = CurrentChamberType + "\\" + CurrentProcessType; string processType = string.Empty; string newName = CurrentFileNode.FullPath.Substring(0, CurrentFileNode.FullPath.LastIndexOf("\\") + 1); if (!string.IsNullOrEmpty(newName)) newName = newName + recipeName; else newName = recipeName; if (newName == CurrentFileNode.FullPath) return; if (IsExist(newName, true)) { DialogBox.ShowWarning($"Can not rename to {newName}, Recipe with the same name already exist."); return; } if (newName.Length > 200) { DialogBox.ShowWarning($"Can not create folder {newName}, Folder name too long, should be less 200."); return; } _recipeProvider.RenameRecipe(prefix, CurrentFileNode.FullPath, newName); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, newName, false); } public void DeleteRecipe() { if (CurrentFileNode == null || !CurrentFileNode.IsFile) return; var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Are you sure you want to delete \r\n {CurrentFileNode.FullPath}?"); if (selection == DialogButton.No) return; string nextFocus = CurrentFileNode.Parent.FullPath; bool isFolder = true; if (CurrentFileNode.Parent.Files.Count > 1) { for (int i = 0; i < CurrentFileNode.Parent.Files.Count; i++) { if (CurrentFileNode.Parent.Files[i] == CurrentFileNode) { if (i == 0) { nextFocus = CurrentFileNode.Parent.Files[i + 1].FullPath; isFolder = !CurrentFileNode.Parent.Files[i + 1].IsFile; } else { nextFocus = CurrentFileNode.Parent.Files[i - 1].FullPath; isFolder = !CurrentFileNode.Parent.Files[i - 1].IsFile; } } } } _recipeProvider.DeleteRecipe(CurrentFileNode.PrefixPath, CurrentFileNode.FullPath); ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, nextFocus, isFolder); } public void RefreshRecipe() { ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, "", false); } public void ReloadRecipe() { if (this.editMode == EditMode.Normal || this.editMode == EditMode.Edit) { this.LoadData(CurrentRecipe.PrefixPath, CurrentRecipe.Name); this.UpdateView(); } } public void SaveToAll() { if (!CurrentRecipe.IsCompatibleWithCurrentFormat) { DialogBox.ShowWarning($"Save failed, {CurrentRecipe.Name} is not a valid recipe file"); return; } var selection = DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No, DialogType.CONFIRM, $"Do you want to save to all? \r\n This will replace all the other chamber recipe content"); if (selection == DialogButton.No) return; CurrentRecipe.SaveTo(Chambers.ToArray()); Save(this.CurrentRecipe, false); } public void SaveTo() { if (!CurrentRecipe.IsCompatibleWithCurrentFormat) { DialogBox.ShowWarning($"Save failed, {CurrentRecipe.Name} is not a valid recipe file"); return; } SaveToDialogViewModel dialog = new SaveToDialogViewModel("Select which chamber to copy to", SelectedChamber, Chambers.ToList()); WindowManager wm = new WindowManager(); bool? dialogReturn = wm.ShowDialog(dialog); if (!dialogReturn.HasValue || !dialogReturn.Value) return; List chambers = new List(); foreach (var dialogChamber in dialog.Chambers) { if (dialogChamber.IsEnabled && dialogChamber.IsChecked) chambers.Add(dialogChamber.Name); } if (chambers.Count == 0) return; CurrentRecipe.SaveTo(chambers.ToArray()); Save(this.CurrentRecipe, false); } #endregion #region Steps public void ParamsExpanded(ExpanderColumn col) { int index = this.Columns.IndexOf(col); for (var i = index + 1; i < this.Columns.Count; i++) { if (this.Columns[i] is ExpanderColumn) break; this.Columns[i].Visibility = Visibility.Visible; } } public void ParamsCollapsed(ExpanderColumn col) { int index = this.Columns.IndexOf(col); for (var i = index + 1; i < this.Columns.Count; i++) { if (this.Columns[i] is ExpanderColumn) break; this.Columns[i].Visibility = Visibility.Collapsed; } } public void SaveRecipe() { if (this.IsChanged) { this.Save(this.CurrentRecipe, false); } } public void PopSetting(string controlName, Param paramData) { int stepNum = Convert.ToInt32(((StepParam)paramData.Parent[1]).Value); PublicPopSettingDialogViewModel dialog = new PublicPopSettingDialogViewModel(); dialog.DisplayName = paramData.DisplayName; RecipeStep Parameters = new RecipeStep(); Parameters = this.CurrentRecipe.PopSettingSteps[controlName][stepNum - 1]; RecipeStep ControlParameters = new RecipeStep(); ObservableCollection BrandParameters = new ObservableCollection(); foreach (var item in Parameters) { if (item.Name.Contains("Band")) { string name = item.Name.Replace("Wavelength", "").Replace("Bandwidth", ""); string displayName = item.DisplayName.Replace("Wavelength", "").Replace("Bandwidth", ""); if (BrandParameters.Where(x => x.Name == name).Count() == 0) { BrandParameters.Add(new BandParam() { Name = name, DisplayName = displayName }); } if (item.Name.Contains("Wavelength")) { BrandParameters.First(x => x.Name == name).WavelengthDoubleParam = item; } else if (item.Name.Contains("Bandwidth")) { BrandParameters.First(x => x.Name == name).BandwidthDoubleParam = item; } } else ControlParameters.Add(item); } dialog.Parameters = Parameters; dialog.ControlParameters = ControlParameters; dialog.BandParameters = BrandParameters; WindowManager wm = new WindowManager(); bool? bret = wm.ShowDialog(dialog); if ((bool)bret) { this.CurrentRecipe.PopSettingSteps[controlName][stepNum - 1] = dialog.Parameters; } } public bool Save(RecipeData recipe, bool createNew) { bool result = false; if (string.IsNullOrEmpty(recipe.Name)) { MessageBox.Show("Recipe name can't be empty"); return false; } recipe.Revisor = BaseApp.Instance.UserContext.LoginName; recipe.ReviseTime = DateTime.Now; result = this._recipeProvider.SaveRecipe(recipe.PrefixPath, recipe.Name, recipe.GetXmlString()); if (result) { recipe.DataSaved(); this.editMode = EditMode.Normal; this.UpdateView(); } else { MessageBox.Show("Save failed!"); } return result; } public void AddStep() { this.CurrentRecipe.Steps.Add(CurrentRecipe.CreateStep(Columns)); foreach (string key in PopSettingColumns.Keys) { if (!this.CurrentRecipe.PopSettingSteps.ContainsKey(key)) { this.CurrentRecipe.PopSettingSteps.Add(key, new RecipeStepManager()); } this.CurrentRecipe.PopSettingSteps[key].Add(this.PopSettingColumns[key]); } if (this.editMode != EditMode.New && this.editMode != EditMode.ReName) this.editMode = EditMode.Edit; int index = 1; foreach (RecipeStep parameters in this.CurrentRecipe.Steps) { (parameters[1] as StepParam).Value = index.ToString(); index++; } this.UpdateView(); } public void AppendStep() { int index = -1; bool found = false; for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++) { if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked) { index = i; found = true; break; } } if (found) { if (this.editMode != EditMode.New && this.editMode != EditMode.ReName) this.editMode = EditMode.Edit; this.CurrentRecipe.Steps.Insert(index, this.CurrentRecipe.CreateStep(this.Columns)); if (this.CurrentRecipe.PopSettingSteps.Count != 0) { foreach (string key in PopSettingColumns.Keys) { this.CurrentRecipe.PopSettingSteps[key].Insert(index, this.PopSettingColumns[key]); } } index = 1; foreach (RecipeStep parameters in this.CurrentRecipe.Steps) { (parameters[1] as StepParam).Value = index.ToString(); index++; } } } private RecipeStepManager copySteps = new RecipeStepManager(); private Dictionary> popCopySteps = new Dictionary>(); public void CopyStep() { this.copySteps.Clear(); this.popCopySteps.Clear(); for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++) { if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked) { this.copySteps.Add(this.CurrentRecipe.CloneStep(this.Columns, this.CurrentRecipe.Steps[i])); foreach (string key in PopSettingColumns.Keys) { if (!this.popCopySteps.ContainsKey(key)) { this.popCopySteps.Add(key, new RecipeStepManager()); } if (this.CurrentRecipe.PopSettingSteps.Count != 0) { this.popCopySteps[key].Add(this.CurrentRecipe.PopSettingSteps[key][i]); } } } } CurrentRecipe.ValidLoopData(); } public void PasteFrontStep() { if (this.copySteps.Count > 0) { if (this.editMode != EditMode.New && this.editMode != EditMode.ReName) this.editMode = EditMode.Edit; for (var i = 0; i < this.CurrentRecipe.Steps.Count; i++) { if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked) { for (var copyindex = 0; copyindex < this.copySteps.Count; copyindex++) { this.CurrentRecipe.Steps.Insert(i, this.CurrentRecipe.CloneStep(this.Columns, this.copySteps[copyindex])); if (this.CurrentRecipe.PopSettingSteps.Count != 0) { foreach (string key in PopSettingColumns.Keys) { this.CurrentRecipe.PopSettingSteps[key].Insert(i, this.popCopySteps[key][copyindex]); } } i++; } break; } } int index = 1; foreach (RecipeStep parameters in this.CurrentRecipe.Steps) { (parameters[1] as StepParam).Value = index.ToString(); index++; } CurrentRecipe.ValidLoopData(); this.UpdateView(); } } public void PasteBackStep() { if (this.copySteps.Count > 0) { if (this.editMode != EditMode.New && this.editMode != EditMode.ReName) this.editMode = EditMode.Edit; for (var i = this.CurrentRecipe.Steps.Count - 1; i >= 0; i--) { if (this.CurrentRecipe.Steps[i][1] is StepParam && ((StepParam)this.CurrentRecipe.Steps[i][1]).Checked) { for (var copyindex = 0; copyindex < this.copySteps.Count; copyindex++) { this.CurrentRecipe.Steps.Insert(i + 1, this.CurrentRecipe.CloneStep(this.Columns, this.copySteps[copyindex])); if (this.CurrentRecipe.PopSettingSteps.Count != 0) { foreach (string key in PopSettingColumns.Keys) { this.CurrentRecipe.PopSettingSteps[key].Insert(i + 1, this.popCopySteps[key][copyindex]); } } i++; } break; } } int index = 1; foreach (RecipeStep parameters in this.CurrentRecipe.Steps) { (parameters[1] as StepParam).Value = index.ToString(); index++; } CurrentRecipe.ValidLoopData(); this.UpdateView(); } } public void DeleteStep() { if (this.editMode != EditMode.New && this.editMode != EditMode.ReName) this.editMode = EditMode.Edit; List steps = this.CurrentRecipe.Steps.ToList(); for (var i = 0; i < steps.Count; i++) { if (steps[i][1] is StepParam && ((StepParam)steps[i][1]).Checked) { this.CurrentRecipe.Steps.Remove(steps[i]); foreach (string key in PopSettingColumns.Keys) { if (CurrentRecipe.PopSettingSteps.ContainsKey(key) && CurrentRecipe.PopSettingSteps[key].Count > i) CurrentRecipe.PopSettingSteps[key].Remove(this.CurrentRecipe.PopSettingSteps[key][i]); } } } int index = 1; foreach (RecipeStep parameters in this.CurrentRecipe.Steps) { (parameters[1] as StepParam).Value = index.ToString(); index++; } } private TreeViewItem GetParentObjectEx(DependencyObject obj) where TreeViewItem : FrameworkElement { DependencyObject parent = VisualTreeHelper.GetParent(obj); while (parent != null) { if (parent is TreeViewItem) { return (TreeViewItem)parent; } parent = VisualTreeHelper.GetParent(parent); } return null; } public void TreeRightMouseDown(MouseButtonEventArgs e) { var item = GetParentObjectEx(e.OriginalSource as DependencyObject) as TreeViewItem; if (item != null) { item.Focus(); } } #endregion private void ClearData() { this.editMode = EditMode.None; this.CurrentRecipe.Clear(); this.CurrentRecipe.Name = string.Empty; this.CurrentRecipe.Description = string.Empty; } private void LoadData(string prefixPath, string recipeName) { CurrentRecipe.Clear(); var recipeContent = _recipeProvider.LoadRecipe(prefixPath, recipeName); if (string.IsNullOrEmpty(recipeContent)) { MessageBox.Show($"{prefixPath}\\{recipeName} is empty, please confirm the file is valid."); return; } CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType; CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion; CurrentRecipe.InitData(prefixPath, recipeName, recipeContent, Columns, _columnBuilder.Configs, SelectedChamber); this.editMode = EditMode.Normal; } private void UpdateView() { bool isFileSelected = CurrentFileNode != null && CurrentFileNode.IsFile; this.EnableNew = isFileSelected; this.EnableReName = isFileSelected; this.EnableCopy = isFileSelected; this.EnableDelete = isFileSelected; this.EnableSave = isFileSelected; this.EnableStep = isFileSelected; EnableSaveTo = isFileSelected; EnableSaveToAll = isFileSelected; EnableReload = isFileSelected; if (this.editMode == EditMode.None) { this.EnableNew = true; this.EnableReName = false; this.EnableCopy = false; this.EnableDelete = false; this.EnableStep = false; this.EnableSave = false; } this.NotifyOfPropertyChange("EnableNew"); this.NotifyOfPropertyChange("EnableReName"); this.NotifyOfPropertyChange("EnableCopy"); this.NotifyOfPropertyChange("EnableDelete"); this.NotifyOfPropertyChange("EnableSave"); this.NotifyOfPropertyChange("EnableStep"); this.NotifyOfPropertyChange("EnableSaveTo"); this.NotifyOfPropertyChange("EnableSaveToAll"); this.NotifyOfPropertyChange("EnableReload"); this.NotifyOfPropertyChange("CurrentRecipe"); } }*/ }