2556 lines
123 KiB
C#
2556 lines
123 KiB
C#
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<FileNode> FileListByProcessType { get; set; }
|
|
|
|
public ProcessTypeFileItem()
|
|
{
|
|
FileListByProcessType = new ObservableCollection<FileNode>();
|
|
}
|
|
}
|
|
|
|
public class ChamberTypeItem : NotifiableItem
|
|
{
|
|
public string ChamberType { get; set; }
|
|
public ObservableCollection<ProcessTypeFileItem> FileListByChamberType { get; set; }
|
|
|
|
public ChamberTypeItem()
|
|
{
|
|
FileListByChamberType = new ObservableCollection<ProcessTypeFileItem>();
|
|
}
|
|
}
|
|
|
|
/*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<ProcessTypeFileItem> 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<EditorDataGridTemplateColumnBase> Columns { get; set; }
|
|
public Dictionary<string, RecipeStep> PopSettingColumns { get; set; }
|
|
public ObservableCollection<EditorDataGridTemplateColumnBase> ColumnsTolerance { get; set; }
|
|
|
|
public Dictionary<string, ObservableCollection<EditorDataGridTemplateColumnBase>> 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<string> 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<string> 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<string>() { "Default" };
|
|
}
|
|
else
|
|
{
|
|
ChamberType = new ObservableCollection<string>(((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<ProcessTypeFileItem>();
|
|
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<string, ObservableCollection<EditorDataGridTemplateColumnBase>>();
|
|
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<ComboxParam> previousFlowMode = new List<ComboxParam>() { previousSiH4FlowMode, previousTCSFlowMode, previousHClFlowMode,
|
|
previousC2H4FlowMode, previousN2FlowMode,previousN2FlowMode, previousN2HighFlowMode, previousTMAFlowMode};
|
|
|
|
List<ComboxParam> currentFlowMode = new List<ComboxParam>() { currentSiH4FlowMode, currentTCSFlowMode, currentHClFlowMode,
|
|
currentC2H4FlowMode, currentN2FlowMode,currentN2FlowMode, currentN2HighFlowMode, currentTMAFlowMode};
|
|
|
|
List<ComboxParam> nextFlowMode = new List<ComboxParam>() { 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<string> lstFlowMode = new List<string>() { 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<EditorDataGridTemplateColumnBase>(
|
|
this.Columns.Take(indexOthers));
|
|
|
|
this.CurrentRecipe = new RecipeData();
|
|
CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType;
|
|
CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion;
|
|
|
|
this.PopSettingColumns = new Dictionary<string, RecipeStep>();
|
|
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>(((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<string> chambers = new List<string>();
|
|
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<BandParam> BrandParameters = new ObservableCollection<BandParam>();
|
|
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<string, ObservableCollection<RecipeStep>> popCopySteps = new Dictionary<string, ObservableCollection<RecipeStep>>();
|
|
|
|
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<RecipeStep> 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<TreeViewItem>(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<TreeViewItem>(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");
|
|
}
|
|
|
|
|
|
}*/
|
|
}
|