using DataEntity; using DataEntity.Share; using DataRWDAL; using DriverLib.Engine; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Xml; using XCommon; using XCommon.Log; using XCore; using XHandler.Controls.Run.Com; using XHandler.View; using XHandler.View.Liquids; using XHandler.View.MethodProperty; using XImagingXhandler.XDAL; using static HxEnum.OperationTypeEnum; namespace XHandler.Controls { public class MixingControl { string strCurrentCulture = ""; WellCalc wellCalc = new WellCalc(); LatticeBll latticeBll = new LatticeBll(); MixingBll mixingBll = new MixingBll(); public RunWnd launchView = null; LiquidAccuracyBll liquidAccuracyBll = new LiquidAccuracyBll(); public MixingControl(string strCurrentCulture) { this.strCurrentCulture = strCurrentCulture; } #region 执行混合,返回结果字符串 /// /// 执行混合,返回结果字符串 /// /// 板位节点信息 /// 装载方法属性节点对象 /// 加载枪头后多出出来的长度 /// z轴安全距离 /// 0:连接谁;1:仿真 /// public bool ExecuteMixing(XmlNode latticesNode, XmlNode methodNode, float currentLengthOfTip, float zAxisVal, bool isSimulator) { bool result = true; HxResult ret = new HxResult(); if (launchView._cancelSource.IsCancellationRequested) { result = false; return result; } #region Start Log if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strStart.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】start:"); } #endregion if (currentLengthOfTip == 0f)//枪上没有Tip不允许吸液 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.MachineRunResource.strWithTipInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: it seems without loaded tip! please check!"); } result = false; return result; } #region 数据准备 string labwareText = methodNode.SelectSingleNode("labware/text").InnerText; string strLabwareid = methodNode.SelectSingleNode("labware/value").InnerText; string channelNums = methodNode.SelectSingleNode("channels").InnerText; string armName = methodNode.SelectSingleNode("arm/text").InnerText; string armId = methodNode.SelectSingleNode("arm/value").InnerText; string latticenum = methodNode.SelectSingleNode("position/text").InnerText; string strWells = methodNode.SelectSingleNode("wellarray").InnerText; bool enableSingleWellvolume = methodNode.SelectSingleNode("enableSingleWellvolume").InnerText.ToLower() == "true" ? true : false; //每孔体积 List dropdownNames = new List(); var drops = methodNode.SelectNodes("SingleWellvolume"); if (drops != null) { foreach (XmlNode x in drops) { DropdownName d = new DropdownName(); d.dropdown_id = x.SelectSingleNode("channel").InnerText; d.dropdown_name = x.SelectSingleNode("name").InnerText; dropdownNames.Add(d); } } //double wellvolume = Convert.ToDouble(methodNode.SelectSingleNode("wellvolume").InnerText); string liquididText = methodNode.SelectSingleNode("liquidid/text").InnerText; string liquididValue = methodNode.SelectSingleNode("liquidid/value").InnerText; string liquidrangeidText = methodNode.SelectSingleNode("liquidrangeid/text").InnerText; string liquidrangeidValue = methodNode.SelectSingleNode("liquidrangeid/value").InnerText; string liquidpidText = methodNode.SelectSingleNode("liquidpid/text").InnerText; string liquidpidValue = methodNode.SelectSingleNode("liquidpid/value").InnerText; //bool enableMix = methodNode.SelectSingleNode("enableMix").InnerText.ToLower() == "true" ? true : false; double mixvolume = Convert.ToDouble(methodNode.SelectSingleNode("mixvolume").InnerText); int mixcount = Convert.ToInt32(methodNode.SelectSingleNode("mixcount").InnerText); string mixAspiratePositionText = methodNode.SelectSingleNode("mixAspiratePosition/text").InnerText; string mixAspiratePositionValue = methodNode.SelectSingleNode("mixAspiratePosition/value").InnerText; double mixAspirateDistance = Convert.ToDouble(methodNode.SelectSingleNode("mixAspirateDistance").InnerText); double mixAspirateSpeed = Convert.ToDouble(methodNode.SelectSingleNode("mixAspirateSpeed").InnerText); double beforeAirpAxisVal = 0d;//Convert.ToDouble(methodNode.SelectSingleNode("beforeAirpAxisVal").InnerText); string mixDispensePositionText = methodNode.SelectSingleNode("mixDispensePosition/text").InnerText; string mixDispensePositionValue = methodNode.SelectSingleNode("mixDispensePosition/value").InnerText; double mixDispenseDistance = Convert.ToDouble(methodNode.SelectSingleNode("mixDispenseDistance").InnerText); double mixDispenseSpeed = Convert.ToDouble(methodNode.SelectSingleNode("mixDispenseSpeed").InnerText); bool enableLiquidSensor = methodNode.SelectSingleNode("enableLiquidSensor").InnerText.ToLower() == "true" ? true : false; int liquidSensorCount = Convert.ToInt32(methodNode.SelectSingleNode("liquidSensorCount").InnerText); double liquidSensorDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorDistance").InnerText); double liquidSensorEndDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorEndDistance").InnerText); double liquidSensorSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorSpeed").InnerText); double liquidSensorRadio = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorRadio").InnerText); string liquidSensorDisIdText = methodNode.SelectSingleNode("liquidSensorDisId/text").InnerText; string liquidSensorDisIdValue = methodNode.SelectSingleNode("liquidSensorDisId/value").InnerText; bool enableLiquidFollow = methodNode.SelectSingleNode("enableLiquidFollow").InnerText.ToLower() == "true" ? true : false; int liquidFollowType = Convert.ToInt32(methodNode.SelectSingleNode("liquidFollowType/value").InnerText); string liquidFollowTypeName = methodNode.SelectSingleNode("liquidFollowType/text").InnerText; double liquidFollowSpeed = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowSpeed").InnerText); double liquidFollowDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowDistance").InnerText); double liquidFollowArea = Convert.ToDouble(methodNode.SelectSingleNode("liquidFollowArea").InnerText); bool enableSensorBlock = methodNode.SelectSingleNode("enableSensorBlock").InnerText.ToLower() == "true" ? true : false; double liquidSensorBlockDistance = Convert.ToDouble(methodNode.SelectSingleNode("liquidSensorBlockDistance").InnerText); string liquidSensorBlockDisIdText = methodNode.SelectSingleNode("liquidSensorBlockDisId/text").InnerText; string liquidSensorBlockDisIdValue = methodNode.SelectSingleNode("liquidSensorBlockDisId/value").InnerText; #endregion #region 数据验证 if (channelNums == "") { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strWithoutChannel.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Channel wasn't set, please check!"); } result = false; return result; } string[] wells = new string[] { }; string wellVariable = string.Empty; if (!string.IsNullOrEmpty(strWells)) { //判断是否包含等号,如果是包含等号的,则是变量控制孔位 if (strWells.Contains(",")) { wells = strWells.Split(','); } else if (strWells.Contains("=")) { } } string[] chs = channelNums.Split(','); if (strWells.Contains(",")) { if (chs.Length != wells.Length) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strOverWell.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Total of channel isn't same with total of wells, please check!"); } result = false; return result; } } else if (strWells.Contains("=")) { wellVariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable variable = new Variable(); //从当前变量字典中取出变量的值 for (int i = 0; i < launchView.gloadVariable.Count; i++) { Variable v = launchView.gloadVariable.Peek(); if (v.variablename == wellVariable) { variable = v; break; } } } Labware labwares = LabwareDB.GetLabware(strLabwareid); // 给孔位排序 if (strWells.Contains(',')) { string suffix = wells[0].Substring(1, wells[0].Length - 1); List sortWellName = new List(); if (Shared.ChannelCount == 1) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + suffix; if (wells.Contains(rowWellName)) { sortWellName.Add(rowWellName); } } wells = sortWellName.ToArray(); } else if (Shared.ChannelCount > 1) { #region Del //List sortWellNameSH = new List();//用来按列的孔位名称 ////上海的移液枪正常排列,A1,B1,C1,D1,E1,F1,G1,H1 //for (int j = 1; j < labwares.number_column; j++) //{ // int countWell = 0;//当前选择的孔位数量 // sortWellNameSH.Clear(); // for (int i = 0; i < labwares.number_row; i++) // { // string rowName = ComUtility.GetRowChar(i);//创建行号 // string rowWellName = rowName + j; // if (wells.Contains(rowWellName)) // { // sortWellNameSH.Add(rowWellName); // countWell++; // } // } // if (wells.Length == countWell && countWell == chs.Length) // { // wells = sortWellNameSH.ToArray(); // break; // } // else // { // if (strCurrentCulture.Equals("zh-CN")) // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strError.ToString() + Properties.RunAspirateResource.strChannelMatch.ToString()); // } // else // { // launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:Channels aren't match with these wells, please check!"); // } // result = false; // return result; // } //} #endregion } } else if (!string.IsNullOrEmpty(strWells) && !strWells.Contains(',') && !strWells.Contains("=")) { wells = new string[] { strWells }; } else if (strWells.Contains("=")) { //Variable variable = new Variable(); //string strvariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); //for (int i = 0; i < launchView.gloadVariable.Count; i++) //{ // Variable v = launchView.gloadVariable.Peek(); // if (strvariable == v.variablename) // { // variable = v; // break; // } //} Variable variable = new Variable(); string strvariable = strWells.Substring(strWells.LastIndexOf('=') + 1, (strWells.Length - strWells.LastIndexOf('=') - 1)); Variable globalVariable = null; globalVariable = ControlCom.SearchGlobalVariable(launchView, strvariable); if (!string.IsNullOrEmpty(globalVariable.variablename)) { variable = globalVariable; } if (variable.variablename.Equals(string.Empty) && strvariable.Length >= 1)//没有查找到变量名,看看是不是表达式,并求出表达式值 { //for (int i = 0; i < launchView.gloadVariable.Count; i++) //{ // Variable v = launchView.gloadVariable.Peek(); // if (strvariable.Contains(v.variablename)) // { // variable = v; // break; // } //} Stack stackTem = new Stack();//临时存储变量过得对象 int totalLoop = launchView.gloadVariable.Count; // 从当前变量字典中取出变量的值 for (int i = 0; i < totalLoop; i++) { Variable v = launchView.gloadVariable.Pop(); //取出最近的一个匹配变量 stackTem.Push(v); if (strvariable.Contains(v.variablename)) { variable = v; break; } } int totalLoopTem = stackTem.Count; for (int i = 0; i < totalLoopTem; i++) { Variable v = stackTem.Pop(); launchView.gloadVariable.Push(v); } Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); string strExpress = strvariable.Replace(variable.variablename, variable.variablecurval); variable.variablecurval = Microsoft.JScript.Eval.JScriptEvaluate(strExpress, ve).ToString(); } List sortWellName = new List(); if (chs.Length == 8) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + variable.variablecurval; sortWellName.Add(rowWellName); } wells = sortWellName.ToArray(); } else if (chs.Length > 1 && chs.Length < 8) { // 根据枪头通道计算在第几个孔位 int startNum = chs.Length * (Convert.ToInt32(variable.variablecurval) - 1); int columnCount = (int)(Math.Ceiling((double)startNum / (double)labwares.number_row)); int totalCount = (int)labwares.number_row * columnCount; // 选中列剩余多少个孔 int leftCount = totalCount - startNum; int startRowNum = (int)labwares.number_row - leftCount; if (leftCount == chs.Length) { for (int i = startRowNum; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + columnCount.ToString(); sortWellName.Add(rowWellName); } } else { for (int i = startRowNum; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + columnCount.ToString(); sortWellName.Add(rowWellName); } for (int i = 0; i < chs.Length - leftCount; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + (columnCount + 1).ToString(); sortWellName.Add(rowWellName); } } wells = sortWellName.ToArray(); } else if (chs.Length == 1) { for (int j = 1; j <= labwares.number_column; j++) { for (int i = 0; i < labwares.number_row; i++) { string rowName = ComUtility.GetRowChar(i); string rowWellName = rowName + j; sortWellName.Add(rowWellName); } } wells = new string[1]; wells[0] = sortWellName[Convert.ToInt32(variable.variablecurval)-1]; } } // 判断方法中的板位和板子是否能对应上设置的台面 Lattice lattice = new Lattice(); if (Shared.ChannelCount > 1) { TabletopTemplate tabletopTemplate = TabletopTemplateDB.GetCurrentAppTabletopTemplateCollectionFromdb(); //增加台面模板判断 if (tabletopTemplate == null) { lattice = LatticeDB.GetLatticeDataByIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number); } else { lattice = LatticeDB.GetLatticeDataByLatticeNumAndTempIdFromdb(latticenum, Convert.ToInt32(armId), Shared.SoftwareInformation.software_device_number, tabletopTemplate.tabletopid); } int xmlLatticeId = Convert.ToInt32(latticenum.Substring(1));// ControlCom.GetLatticeId(Convert.ToInt32(lattice.lattice_id), false); var latticeXn = latticesNode.SelectSingleNode("platform[lattice_id='" + xmlLatticeId.ToString() + "']"); if (latticeXn != null) { labwares.labware_sname = latticeXn.SelectNodes("labware")[0].SelectSingleNode("labware_sname").InnerText; } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunAspirateResource.strWithoutLattice.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the lattice of aspirate liquid is wrong! please check!"); } result = false; return result; } } #endregion try { string[] charray = chs; // 获取板位信息 Lattice slattice = LatticeDB.GetLatticeDataByIdFromdb(lattice.lattice_id); // 获取板位孔的坐标数据 List dtWells = ControlCom.GenerateWellCoordinate(labwares, lattice); // 液体参数 Liquid liquid = LiquidDB.GetALiquidFromdb(liquidpidValue); // 根据循环处理孔位 TipsTable tipsTable = dtWells.SingleOrDefault(t => t.lattice_id.Equals(lattice.lattice_id) && t.labware_id.Equals(strLabwareid) && t.wellname.Equals(wells[0])); if (tipsTable == null) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the well on lattice of mixing liquid is wrong! please check!"); } result = false; return result; } if (Shared.ChannelCount.Equals(96)) { if (labwares.labware_type_id.Equals("3")) { if (!wells.Contains("A1") ) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the wells on lattice of mixing liquid is wrong! please check!"); } result = false; return result; } } else { if (!wells.Contains("A1") || !wells.Length.Equals(96)) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strWithoutWellInfo.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: the wells on lattice of mixing liquid is wrong! please check!"); } result = false; return result; } } } tipsTable.lattice_num = lattice.lattice_num; #region 单通道 if (Shared.ChannelCount == 1) { #region MixMParam MixMParam mixMParam = new MixMParam(); mixMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); mixMParam.basezAxisVal = zAxisVal; mixMParam.liquidVolumeType = (int)Convert.ToInt32(liquid.liquid_volume_type); mixMParam.wellzAxisVal = (float)liquid.well_top_length; mixMParam.xAxisVal = tipsTable.axis_b_X; mixMParam.yAxisVal = tipsTable.axis_b_Y; // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); if (labwares.labware_type_id.Equals("4")) { if (labwares.labware_tubeshelf_type == 1) { ObservableCollection labwareWellInfoList = DataRWDAL.LabwareDB.GetSpecialLabwareWellInfo(labwares.labware_id); LabwareWellInfo currentWellInfo = labwareWellInfoList.FirstOrDefault(x => x.labware_well_name.Equals(tipsTable.wellname)); Labware currentWellLabware = DataRWDAL.LabwareDB.GetLabware(currentWellInfo.well_labware_id); zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]) - ((float)currentWellLabware.labware_height-(float)currentWellLabware.well_height); } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0])- ControlCom.CalculateWellBottomThickness(labwares.piled_script); } } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } } mixMParam.zAxisVal = zVal < 0 ? 0 : zVal; mixMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); mixMParam.mixAspiratePositionText = mixAspiratePositionText; if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { mixMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { mixMParam.mixAspirateDistance = (float)mixAspirateDistance; } mixMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); mixMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); mixMParam.mixDispensePositionText = mixDispensePositionText; if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { mixMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { mixMParam.mixDispenseDistance = (float)mixDispenseDistance; } mixMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); mixMParam.mixvolume = (float)mixvolume; mixMParam.mixCount = mixcount; beforeAirpAxisVal = liquid.before_aspirate_volume; mixMParam.beforeAirpAxisVal = (float)beforeAirpAxisVal; #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); launchView.SetWaitOne();//暂停 ret = mixingBll.ExecuteMix(mixMParam, isSimulator); } #endregion #region 多通道(排除96通道) else if (Shared.ChannelCount > 1&&!Shared.ChannelCount.Equals(96)) { #region MixMParamSH MixMParamSH mixMParam = new MixMParamSH(); mixMParam.armId = Convert.ToInt32(armId); mixMParam.basezAxisVal = zAxisVal; mixMParam.liquidVolumeType = (int)Convert.ToInt32((liquid.liquid_volume_type != null ? "1" : liquid.liquid_volume_type)); //mixMParam.wellzAxisVal = (float)liquid.well_top_length; if (labwares.labware_type_id.Equals("4")) { mixMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); } else { mixMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.well_height);// - (float)liquid.well_top_length) ; } mixMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); mixMParam.mixAspiratePositionText = mixAspiratePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { mixMParam.mixAspirateDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { mixMParam.mixAspirateDistance = (float)mixAspirateDistance; } } else { if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { mixMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { mixMParam.mixAspirateDistance = (float)mixAspirateDistance; } } mixMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); mixMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); mixMParam.mixDispensePositionText = mixDispensePositionText; if (labwares.labware_type_id.Equals("4")) { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { mixMParam.mixDispenseDistance = ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { mixMParam.mixDispenseDistance = (float)mixDispenseDistance; } } else { if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { mixMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { mixMParam.mixDispenseDistance = (float)mixDispenseDistance; } } mixMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); mixMParam.mixvolume = (float)mixvolume; mixMParam.mixCount = mixcount; beforeAirpAxisVal = liquid.before_aspirate_volume; mixMParam.beforeAirpAxisVal = (float)beforeAirpAxisVal; mixMParam.xAxisVal = tipsTable.axis_b_X; mixMParam.yAxisVal = tipsTable.axis_b_Y; mixMParam.isSurvey = enableLiquidSensor; if (mixMParam.isSurvey == true) { if (labwares.labware_type_id.Equals("4")) { Labware centrifugalLabware = ControlCom.GetCentrifugalLabwer(labwares.piled_script); mixMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorDistance); mixMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)liquidSensorEndDistance); mixMParam.surveySpeed = (float)liquidSensorSpeed; mixMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height); mixMParam.wellBottomzAxisVal = tipsTable.axis_b_Z - ((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).labware_height - (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_height); mixMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { mixMParam.followupType = liquidFollowType; mixMParam.followupSpeed = (float)liquidFollowSpeed; mixMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)((float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_x * (float)ControlCom.GetCentrifugalLabwer(labwares.piled_script).well_top_y); } mixMParam.sectionalArea = area; } else { } } else { mixMParam.surveyRetryCount = liquidSensorCount; mixMParam.surveyInitzVal = tipsTable.axis_b_Z - ((float)labwares.well_height - (float)liquidSensorDistance); mixMParam.surveyMaxzVal = tipsTable.axis_b_Z - ((float)labwares.well_height - (float)liquidSensorEndDistance); mixMParam.surveySpeed = (float)liquidSensorSpeed; //aspirateMParam.surveyCoefficient =; mixMParam.wellzAxisVal = tipsTable.axis_b_Z - ((float)labwares.well_height);// - (float)liquid.well_top_length); mixMParam.wellBottomzAxisVal = tipsTable.axis_b_Z; mixMParam.surveyFailHandleType = Convert.ToInt32(liquidSensorDisIdValue); if (enableLiquidFollow) { //mixMParam.followupType = liquidFollowType; mixMParam.followupSpeed = (float)liquidFollowSpeed; mixMParam.followupDistance = (float)liquidFollowDistance; float area = 0.0f; if (labwares.well_shape == (int)WellSharpe.Round) { area = (float)(Math.PI * labwares.well_mouth_radius * labwares.well_mouth_radius); } else if (labwares.well_shape == (int)WellSharpe.Rectangle) { area = (float)(labwares.well_top_x * labwares.well_top_y); } mixMParam.sectionalArea = area; } else { } } } else { } // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); if (liquid.aspirate_position_type == 0)//液面开始探测时用, { zVal = tipsTable.axis_b_Z - (float)labwares.well_height; } else if (liquid.aspirate_position_type == 1)//孔口 { zVal = mixMParam.wellzAxisVal + (float)Convert.ToDouble(liquid.aspirate_well_bottom_length); } else if (liquid.aspirate_position_type == 2)//孔底 { if (labwares.labware_type_id.Equals("4")) { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(liquid.aspirate_well_bottom_length) - ControlCom.CalculateWellBottomThickness(labwares.piled_script); } else { zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(liquid.aspirate_well_bottom_length); } } } float[] fzAxisVal = new float[charray.Length]; for (int i = 0; i < charray.Length; i++) { fzAxisVal[i] = zVal < 0 ? 0 : zVal; } mixMParam.zAxisVal = fzAxisVal; mixMParam.yChannelGapVal = (float)labwares.a1_b1_distance; #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strMixingExecute.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】> Xhandler:progress: Aspirate is executing,please wait for a moment."); } launchView.SetWaitOne();//暂停 ret = mixingBll.ExecuteMix(mixMParam, isSimulator); } #endregion #region 96通道 else if (Shared.ChannelCount.Equals(96)) { #region MixMParam MixMParam mixMParam = new MixMParam(); mixMParam.armId = Convert.ToInt32(methodNode.SelectSingleNode("arm/value").InnerText); mixMParam.basezAxisVal = zAxisVal; mixMParam.liquidVolumeType = (int)Convert.ToInt32(liquid.liquid_volume_type); mixMParam.wellzAxisVal = (float)liquid.well_top_length; mixMParam.xAxisVal = tipsTable.axis_b_X; mixMParam.yAxisVal = tipsTable.axis_b_Y; // 如果有吸液位置高度的话,则减少高度 //float zVal = tipsTable.axis_b_Z - currentLengthOfTip - (float)liquid.aspirate_well_bottom_length; float zVal = 0f; if (liquid.aspirate_well_bottom_length != "") { string[] zOffsiteArray = liquid.aspirate_well_bottom_length.Split(','); zVal = tipsTable.axis_b_Z - (float)Convert.ToDouble(zOffsiteArray[0]); } mixMParam.zAxisVal = zVal < 0 ? 0 : zVal; mixMParam.mixAspiratePositionValue = Convert.ToInt32(mixAspiratePositionValue); mixMParam.mixAspiratePositionText = mixAspiratePositionText; if (mixAspiratePositionValue == "0")//liquid { } else if (mixAspiratePositionValue == "1")//top { mixMParam.mixAspirateDistance = ((float)labwares.well_height - (float)mixAspirateDistance); } else if (mixAspiratePositionValue == "2")//bottom { mixMParam.mixAspirateDistance = (float)mixAspirateDistance; } mixMParam.mixAspirateSpeed = (float)Convert.ToDouble(mixAspirateSpeed); mixMParam.mixDispensePositionValue = Convert.ToInt32(mixDispensePositionValue); mixMParam.mixDispensePositionText = mixDispensePositionText; if (mixDispensePositionValue == "0")//liquid { } else if (mixDispensePositionValue == "1")//top { mixMParam.mixDispenseDistance = ((float)labwares.well_height - (float)mixDispenseDistance); } else if (mixDispensePositionValue == "2")//bottom { mixMParam.mixDispenseDistance = (float)mixDispenseDistance; } mixMParam.mixDispenseSpeed = (float)Convert.ToDouble(mixDispenseSpeed); mixMParam.mixvolume = (float)mixvolume; mixMParam.mixCount = mixcount; beforeAirpAxisVal = liquid.before_aspirate_volume; mixMParam.beforeAirpAxisVal = (float)beforeAirpAxisVal; #endregion launchView.UpdateLabwareWells(tipsTable, wells, 2); launchView.SetWaitOne();//暂停 ret = mixingBll.ExecuteMix(mixMParam, isSimulator); } #endregion string strWell = string.Join(",", wells); #region 错误处理 if (ret.Result != ResultType.Success) { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strMixFail.ToString() + ret.AlarmInfo + "孔 " + strWell + "板位 " + methodNode.SelectSingleNode("position / text").InnerText); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress: mixing liquid is fail from " + strWell + " well on " + methodNode.SelectSingleNode("position / text").InnerText + " lattice! error information:" + ret.AlarmInfo); //launchView.addDataIntoReport(tipsTable, labwares.labware_sname, mixvolume.ToString(), wells, "block", ""); } OperateDialog plsConfirmOper = null; if (!launchView.isRemotingOper) { System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => { plsConfirmOper = new OperateDialog(strCurrentCulture.Equals("zh-CN") ? Properties.RunMixResource.strFailWhatToDo : "mixing liquid is fail! What do you want to do?"); plsConfirmOper.ShowDialog(); })); } if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Retry) // 重试 { result = ExecuteMixing(latticesNode, methodNode, currentLengthOfTip, zAxisVal, isSimulator); return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Cancel) // 终止 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunMixResource.strLoadTipWasStopped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:mixing liquid was stopped!"); } result = false; return result; } else if (plsConfirmOper != null && plsConfirmOper.OperMark == NodeOperationTypeEnum.Continue) // 跳过 { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress + Properties.RunMixResource.strLoadTipWasSkipped); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:mixing liquid was skipped!"); } } } else { if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strProgress.ToString() + Properties.RunMixResource.strMixSuccess.ToString() + " 体积 " + mixvolume + "ul 孔 " + strWell + " 板 " + methodNode.SelectSingleNode("position / text").InnerText); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】progress:mixing " + mixvolume + "ul liquid is success from " + strWell + " well on " + methodNode.SelectSingleNode("position / text").InnerText + " lattice!"); launchView.UpdateLabwareWells(tipsTable, wells, 1); //launchView.addDataIntoReport(tipsTable, labwares.labware_sname, mixvolume.ToString(), wells, "pass", ""); } } #endregion if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strEnd.ToString()); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】complete;"); } } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); if (strCurrentCulture.Equals("zh-CN")) { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】" + Properties.MachineRunResource.strError.ToString() + " 源 " + ex.Source + " 错误信息 " + ex.Message + ";"); } else { launchView.AddLogs("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【" + methodNode.SelectSingleNode("name").InnerText + "】error:source:" + ex.Source + ";error:" + ex.Message + ";"); } result = false; } return result; } #endregion #region 根据输入的行数,取得对应的字符串名称 /// /// /// /// /// 要加上的值 /// private static string GetNextColumnChar(int col, int iaddVal) { var a = (col + 1 - 65) / 26; if (a > 0) return GetNextColumnChar(a - 1, iaddVal) + (char)(col + iaddVal); return ((char)(col + iaddVal)).ToString(); } #endregion #region 转换孔位行符号为行号 private int GetNumByWellLine(string noWell) { int num = 0; num = Convert.ToInt32(noWell) - 64; return num; } #endregion } }