//时间：20200610
//作者：王琦
//功能：SmartSEM remote API控制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

using APILib;
using System.Threading;
using System.IO;
using FileManager;

namespace SmartSEMControl
{
    //可能遇到的错误提示部分？？在log加入之后添加
    class SmartSEM : ISEMControl
    {
        private NLog.Logger log;
        #region 返回错误代码枚举
        private enum ZeissErrorCode
        {
            // Failed to translate parameter into an id
            API_E_GET_TRANSLATE_FAIL = 1000,
            // Failed to get analogue value
            API_E_GET_AP_FAIL = 1001,
            // Failed to get digital value
            API_E_GET_DP_FAIL = 1002,
            // Parameter supplied is not analogue nor digital
            API_E_GET_BAD_PARAMETER = 1003,
            // Failed to translate parameter into an id
            API_E_SET_TRANSLATE_FAIL = 1004,
            // Failed to set a digital state 
            API_E_SET_STATE_FAIL = 1005,
            // Failed to set a float value
            API_E_SET_FLOAT_FAIL = 1006,
            // Value supplied is too low
            API_E_SET_FLOAT_LIMIT_LOW = 1007,
            // Value supplied is too high
            API_E_SET_FLOAT_LIMIT_HIGH = 1008,
            // Value supplied is is of wrong type
            API_E_SET_BAD_VALUE = 1009,
            // Parameter supplied is not analogue nor digital
            API_E_SET_BAD_PARAMETER = 1010,
            // Failed to translate command into an id
            API_E_EXEC_TRANSLATE_FAIL = 1011,
            // Failed to execute command=
            API_E_EXEC_CMD_FAIL = 1012,
            // Failed to execute file macro
            API_E_EXEC_MCF_FAIL = 1013,
            // Failed to execute library macro
            API_E_EXEC_MCL_FAIL = 1014,
            // Command supplied is not implemented
            API_E_EXEC_BAD_COMMAND = 1015,
            // Grab command failed
            API_E_GRAB_FAIL = 1016,
            // Get Stage position failed
            API_E_GET_STAGE_FAIL = 1017,
            // Move Stage position failed
            API_E_MOVE_STAGE_FAIL = 1018,
            // API not initialised
            API_E_NOT_INITIALISED = 1019,
            // Failed to translate parameter to an id
            API_E_NOTIFY_TRANSLATE_FAIL = 1020,
            // Set notification failed
            API_E_NOTIFY_SET_FAIL = 1021,
            // Get limits failed
            API_E_GET_LIMITS_FAIL = 1022,
            // Get multiple parameters failed
            API_E_GET_MULTI_FAIL = 1023,
            // Set multiple parameters failed
            API_E_SET_MULTI_FAIL = 1024,
            // Missing API license
            API_E_NOT_LICENSED = 1025,
            // Reserved or not implemented
            API_E_NOT_IMPLEMENTED = 1026,
            // Failed to get user name (Remoting Interface only)
            API_E_GET_USER_NAME_FAIL = 1027,
            // Failed to get user idle state (Remoting Interface only)
            API_E_GET_USER_IDLE_FAIL = 1028,
            // Failed to get the last remoting connection error string (Remoting Interface Only)
            API_E_GET_LAST_REMOTING_CONNECT_ERROR_FAIL = 1029,
            // Failed to remotely logon to the EM Server (username and password may be incorrect or EM Server is not running or User is already logged on
            API_E_EMSERVER_LOGON_FAILED = 1030,
            // Failed to start the EM Server - this may be because the Server is already running or has an internal error. 
            API_E_EMSERVER_START_FAILED = 1031,
            // The command or parameter is currently disabled (you cannot execute or set it).
            API_E_PARAMETER_IS_DISABLED = 1032,
            // Remoting incorrectly configured, use RConfigure to correct
            API_E_REMOTING_NOT_CONFIGURED = 2027,
            // Remoting did not connect to the server
            API_E_REMOTING_FAILED_TO_CONNECT = 2028,
            // Remoting could not start (unknown reason)
            API_E_REMOTING_COULD_NOT_CREATE_INTERFACE = 2029,
            // Remoting: Remote server is not running currently.
            API_E_REMOTING_EMSERVER_NOT_RUNNING = 2030,
            // Remoting: Remote server has no user logged in
            API_E_REMOTING_NO_USER_LOGGED_IN = 2031,

            // Internal Defines, although they may be useful in your own program. TRS.
            API_FIRST_REMOTING_ERROR_CODE = API_E_REMOTING_NOT_CONFIGURED,
            API_LAST_REMOTING_ERROR_CODE = API_E_REMOTING_NO_USER_LOGGED_IN,
            API_FIRST_ERROR_CODE = API_E_GET_TRANSLATE_FAIL,
            API_LAST_ERROR_CODE = API_E_REMOTING_NO_USER_LOGGED_IN
        }
        #endregion

        #region 固定参数
        //判断这个文件夹是否存在20200826
        private readonly String ELYPATH = @"C:\ProgramData\Carl Zeiss\SmartFIB\API\Drop\";
        private readonly String ELYFILENAME = "ApiLayout.ely";
        private readonly String MLFPATH = @"C:\ProgramData\Carl Zeiss\SmartSEM\User\Service\";
        private readonly String MLFFILENAME = "Opton.MLF";
        private String REMOTEELYPATH = @"";
        private String REMOTEMLFPATH = @"";
        #endregion

        #region 模拟参数
        //放大缩小
        private readonly String AP_MAG = "AP_MAG";
        //焦距
        private readonly String AP_WD = "AP_WD";
        //亮度
        private readonly String AP_BRIGHTNESS = "AP_BRIGHTNESS";
        //对比度
        private readonly String AP_CONTRAST = "AP_CONTRAST";
        //亮度目标
        private readonly String AP_AUTO_BRIGHT = "AP_AUTO_BRIGHT";
        //对比度目标
        private readonly String AP_AUTO_CONTRAST = "AP_AUTO_CONTRAST";
        //消像散X轴
        private readonly String AP_STIG_X = "AP_STIG_X";
        //消像散Y轴
        private readonly String AP_STIG_Y = "AP_STIG_Y";
        //角度补偿
        private readonly String AP_TILT_ANGLE = "AP_TILT_ANGLE";
        //SEM移动X
        private readonly String AP_BEAMSHIFT_X = "AP_BEAMSHIFT_X";
        //SEM移动Y
        private readonly String AP_BEAMSHIFT_Y = "AP_BEAMSHIFT_Y";
        //X轴移动到
        private readonly String AP_STAGE_GOTO_X = "AP_STAGE_GOTO_X";
        //Y轴移动到
        private readonly String AP_STAGE_GOTO_Y = "AP_STAGE_GOTO_Y";
        //Z轴移动到
        private readonly String AP_STAGE_GOTO_Z = "AP_STAGE_GOTO_Z";
        //T轴移动到
        private readonly String AP_STAGE_GOTO_T = "AP_STAGE_GOTO_T";
        //R轴移动到
        private readonly String AP_STAGE_GOTO_R = "AP_STAGE_GOTO_R";
        //M轴移动到
        private readonly String AP_STAGE_GOTO_M = "AP_STAGE_GOTO_M";
        //Scan Rotate角度
        private readonly String AP_SCANROTATION = "AP_SCANROTATION";
        //像素大小
        private readonly String AP_PIXEL_SIZE = "AP_PIXEL_SIZE";
        //X轴坐标
        private readonly String AP_STAGE_AT_X = "AP_STAGE_AT_X";
        //Y轴坐标
        private readonly String AP_STAGE_AT_Y = "AP_STAGE_AT_Y";
        //Z轴坐标
        private readonly String AP_STAGE_AT_Z = "AP_STAGE_AT_Z";
        //T轴坐标
        private readonly String AP_STAGE_AT_T = "AP_STAGE_AT_T";
        //R轴坐标
        private readonly String AP_STAGE_AT_R = "AP_STAGE_AT_R";
        //M轴坐标
        private readonly String AP_STAGE_AT_M = "AP_STAGE_AT_M";

        //扫描周期
        private readonly String AP_FRAME_TIME = "AP_FRAME_TIME";

        //FIB缩放
        private readonly String AP_FIB_MAGNIFICATION = "AP_FIB_MAGNIFICATION";
        //FIB焦距
        private readonly String AP_FIB_OBJECTIVE_POTENTIAL = "AP_FIB_OBJECTIVE_POTENTIAL";
        //FIB消像散X
        private readonly String AP_FIB_STIGMATOR_X = "AP_FIB_STIGMATOR_X";
        //FIB消像散Y
        private readonly String AP_FIB_STIGMATOR_Y = "AP_FIB_STIGMATOR_Y";
        //FIB光束移动X
        private readonly String AP_FIB_BEAM_SHIFT_X = "AP_FIB_BEAM_SHIFT_X";
        //FIB光束移动Y
        private readonly String AP_FIB_BEAM_SHIFT_Y = "AP_FIB_BEAM_SHIFT_Y";

        //SEM电压
        private readonly String AP_MANUALKV = "AP_MANUALKV";
        //SEM电流
        private readonly String AP_IPROBE = "AP_IPROBE";

        //拉直
        private readonly String AP_STAGE_DELTA_R = "AP_STAGE_DELTA_R";

        //光束移动位置值
        private readonly String AP_BEAM_OFFSET_X = "AP_BEAM_OFFSET_X";
        private readonly String AP_BEAM_OFFSET_Y = "AP_BEAM_OFFSET_Y";

        private readonly String AP_NR_COEF = "AP_NR_COEF";
        #endregion

        #region 数字参数
        private readonly String DP_SCANRATE = "DP_SCANRATE";
        //Scan Rotate开关
        private readonly String DP_SCAN_ROT = "DP_SCAN_ROT";
        //取消电子束校正
        private readonly String DP_TILT_CORRECTION = "DP_TILT_CORRECTION";
        //自动亮度对比度
        private readonly String DP_AUTO_VIDEO = "DP_AUTO_VIDEO";
        //图像解冻
        private readonly String DP_FROZEN = "DP_FROZEN";
        //图像类型切换
        private readonly String DP_DETECTOR_TYPE = "DP_DETECTOR_TYPE";
        //图像大小
        private readonly String DP_IMAGE_STORE = "DP_IMAGE_STORE";

        //样品台状态
        private readonly String DP_STAGE_IS = "DP_STAGE_IS";
        //自动函数状态
        private readonly String DP_AUTO_FUNCTION = "DP_AUTO_FUNCTION";

        //FIB模式
        private readonly String DP_FIB_MODE = "DP_FIB_MODE";
        //FIB_IMAGING
        private readonly String DP_FIB_IMAGING = "DP_FIB_IMAGING";

        //FIB状态
        private readonly String DP_SMARTFIB_API_STATUS = "DP_SMARTFIB_API_STATUS";

        //FIB,ELY文件确认前，需要将该变量置为2->FIB
        private readonly String DP_PATTERNING_MODE = "DP_PATTERNING_MODE";
        #endregion

        #region 命令
        //20201016 设置图像速度 CMD_SCANRATE0...CMD_SCANRATE15
        private readonly String CMD_SCANRATE3 = "CMD_SCANRATE3";
        private readonly String CMD_SCANRATE4 = "CMD_SCANRATE4";
        //add by sun 2020-12-15 拍截面图调用蔡司接口时，要保证扫描速度5以上，自动亮度对比度功能关闭
        private readonly String CMD_SCANRATE5 = "CMD_SCANRATE5";
        private readonly String CMD_SCANRATE6 = "CMD_SCANRATE6";
        //add by sun 2020-12-15 拍截面图调用蔡司接口时，要保证扫描速度5以上，自动亮度对比度功能关闭
        private readonly String CMD_SCANRATE7 = "CMD_SCANRATE7";
        private readonly String CMD_SCANRATE8 = "CMD_SCANRATE8";
        private readonly String CMD_SCANRATE9 = "CMD_SCANRATE9";
        private readonly String CMD_SCANRATE10 = "CMD_SCANRATE10";
        private readonly String CMD_LINE_AVG = "CMD_LINE_AVG";
        private readonly String CMD_PIXNR = "CMD_PIXNR";
        //开启电压
        private readonly String CMD_BEAM_ON = "CMD_BEAM_ON";
        //关闭电压
        private readonly String CMD_EHT_OFF = "CMD_EHT_OFF";
        //自动对焦1
        private readonly String CMD_AUTO_FOCUS_COARSE = "CMD_AUTO_FOCUS_COARSE";
        //自动对焦2
        private readonly String CMD_AUTO_FOCUS_FINE = "CMD_AUTO_FOCUS_FINE";
        //自动消像散
        private readonly String CMD_AUTO_STIG = "CMD_AUTO_STIG";
        //样品台急停
        private readonly String CMD_STAGE_ABORT = "CMD_STAGE_ABORT";
        //FIB模式选择
        private readonly String CMD_FIB_MODE_SEM = "CMD_FIB_MODE_SEM";
        private readonly String CMD_FIB_MODE_FIB = "CMD_FIB_MODE_FIB";
        private readonly String CMD_FIB_MODE_MILL = "CMD_FIB_MODE_MILL";
        private readonly String CMD_FIB_MODE_SEM_FIB = "CMD_FIB_MODE_SEM_FIB";
        private readonly String CMD_FIB_MODE_MILL_SEM = "CMD_FIB_MODE_MILL_SEM";
        private readonly String CMD_FIB_MODE_EXT = "CMD_FIB_MODE_EXT";
        private readonly String CMD_FIB_MODE_EXT_SEM = "CMD_FIB_MODE_EXT_SEM";
        private readonly String CMD_FIB_MODE_ARGON_SEM = "CMD_FIB_MODE_ARGON_SEM";
        private readonly String CMD_FIB_MODE_DRIFT_SEM = "CMD_FIB_MODE_DRIFT_SEM";
        private readonly String CMD_FIB_MODE_DRIFT_FIB = "CMD_FIB_MODE_DRIFT_FIB";
        private readonly String CMD_FIB_MODE_ARGON = "CMD_FIB_MODE_ARGON";

        //FIB加载.ely文件命令
        private readonly String CMD_SMARTFIB_LOAD_ELY = "CMD_SMARTFIB_LOAD_ELY";
        //FIB确认.ely文件命令
        private readonly String CMD_SMARTFIB_PREPARE_EXPOSURE = "CMD_SMARTFIB_PREPARE_EXPOSURE";
        //FIB开始.ley文件命令
        private readonly String CMD_FIB_START_MILLING = "CMD_FIB_START_MILLING";
        #endregion

        #region 宏文件命令
        private readonly String MCF_FILENAME = "MCF_";
        #endregion

        #region APILib
        private Api CZEMApi = new Api();
        private Boolean m_bInitialised = false;
        #endregion

        #region 构造函数
        public SmartSEM()
        {
            //LogManager.InitHardwareLog();
            Init();
            //判断ELY默认文件夹是否存在
            if(!Directory.Exists(ELYPATH))
            {
                Directory.CreateDirectory(ELYPATH);
            }

            if (!Directory.Exists(MLFPATH))
            {
                Directory.CreateDirectory(MLFPATH);
            }
        }
        #endregion

        #region 设备初始化
        /// <summary>
        /// 设备初始化
        /// </summary>
        /// <returns>return:true or false</returns>
        public Boolean Init()
        {
            log = NLog.LogManager.GetCurrentClassLogger();
            long lrt = 0;
            #if ROMOTE
                lrt = CZEMApi.InitialiseRemoting();
            #else
                lrt = CZEMApi.Initialise("");
            #endif
            if (lrt != 0)
            {
                log.Error("CZEMApi.Initialise Faild - " + ErrorToString(lrt), false);
                m_bInitialised = false;
                return false;
            }
            else
            {
                m_bInitialised = true;
                float testmag = GetMagnification();
                if(!float.IsNaN(testmag))
                { 
                    log.Info("CZEMApi.Initialise Success!", true);
                    return true;
                }
                else
                {
                    log.Error("CZEMApi.Initialise Faild - Disconnect", false);
                    m_bInitialised = false;
                    return false;
                }
            }
        }
        #endregion

        #region 设备远程初始化
        /// <summary>
        /// 设备远程初始化
        /// </summary>
        /// <returns>return:true or false</returns>
        public Boolean InitRemoting()
        {
            long lrt = CZEMApi.InitialiseRemoting();
            if (lrt != 0)
            {
                m_bInitialised = false;
                return false;
            }
            else
            {
                m_bInitialised = true;
                return true;
            }
        }
        #endregion

        #region 连接状态
        public Boolean ConnectStatus()
        {
            return m_bInitialised;
        }
        #endregion

        #region 关闭设备
        /// <summary>
        /// 关闭设备
        /// </summary>
        /// <returns>true or false</returns>
        public Boolean Dispose()
        {
            if (m_bInitialised)
            {
                long lrt = CZEMApi.ClosingControl();
                if (lrt != 0)
                {
                    log.Error("CZEMApi.ClosingControl Faild - " + ErrorToString(lrt), false);
                    return false;
                }
                else
                {
                    log.Info("CZEMApi.ClosingControl Success!", true);
                    m_bInitialised = false;
                    return true;
                }
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 读参数函数
        private Boolean ReadParams(String str_param, ref float value)
        {
            if (m_bInitialised)
            {
                object varfloat = new VariantWrapper((float)0.0f);
                long lrt = CZEMApi.Get(str_param, ref varfloat);
                if (lrt != 0)
                {
                    log.Error("Get " + str_param + " Faild - " + ErrorToString(lrt), false);
                    return false;
                }
                else
                {
                    value = Convert.ToSingle(varfloat);
                    return true;
                }
            }
            else
            {
                log.Error("ReadParams m_bInitialised = false", false);
                return false;
            }
        }
        #endregion

        #region 写模拟参数函数
        private Boolean WriteParams(String str_param, float value)
        {
            if (m_bInitialised)
            {
                //先取范围
                object varMin = new VariantWrapper((float)0.0f);
                object varMax = new VariantWrapper((float)0.0f);
                long lrt = CZEMApi.GetLimits(str_param, ref varMin, ref varMax);
                if (lrt != 0)
                {
                    log.Error("GetLimits " + str_param + " Faild - " + ErrorToString(lrt), false);
                    return false;
                }
                if (value <= Convert.ToSingle(varMax) && value >= Convert.ToSingle(varMin))
                {
                    object varFloat = new VariantWrapper(value);
                    lrt = CZEMApi.Set(str_param, ref varFloat);// set value
                    if (lrt != 0)
                    {
                        log.Error("Set " + str_param + " Faild - " + ErrorToString(lrt), false);
                        return false;
                    }
                    return true;
                }
                else
                {
                    log.Error("Set " + str_param + " Faild - Out to range", false);
                    return false;
                }
            }
            else
            {
                log.Error("ReadParams m_bInitialised = false", false);
                return false;
            }
        }
        #endregion

        #region 写数字参数函数
        private Boolean WriteDataParams(String str_param, float value)
        {
            if (m_bInitialised)
            {
                object varFloat = new VariantWrapper(value);
                long lrt = CZEMApi.Set(str_param, ref varFloat);// set value
                if (lrt != 0)
                {
                    log.Error("Set " + str_param + " Faild - " + ErrorToString(lrt), false);
                    return false;
                }
                return true;
            }
            else
            {
                log.Error("ReadParams m_bInitialised = false", false);
                return false;
            }
        }
        #endregion

        #region 执行命令
        private Boolean ExecuteCmd(String cmd)
        {
            if (m_bInitialised)
            {
                long lrt = CZEMApi.Execute(cmd);// execute command
                if (lrt != 0)
                {
                    log.Error("ExecuteCmd " + cmd + " Faild - " + ErrorToString(lrt), false);
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region SEM缩放
        /// <summary>
        /// 读取缩放倍数
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetMagnification()
        {
            float ret = 0;
            if(ReadParams(AP_MAG, ref ret))
            {
                log.Info("GetMagnification " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetMagnification Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置缩放倍数
        /// </summary>
        /// <param name="set">倍数</param>
        /// <returns>true or false</returns>
        public Boolean SetMagnification(float set)
        {
            Boolean ret = WriteParams(AP_MAG, set);
            log.Info("SetMagnification = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region SEM焦距
        /// <summary>
        /// 读取工作距离
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetWorkingDistance()
        {
            float ret = 0;
            if (ReadParams(AP_WD, ref ret))
            {
                log.Info("GetWorkingDistance " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetWorkingDistance Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置焦距
        /// </summary>
        /// <param name="set">焦距</param>
        /// <returns>true or false</returns>
        public Boolean SetWorkingDistance(float set)
        {
            Boolean ret = WriteParams(AP_WD, set);
            log.Info("SetWorkingDistance = " + set.ToString(), ret);
            return ret;
        }
        #endregion  

        #region 亮度
        /// <summary>
        /// 读取亮度
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetBrightness()
        {
            float ret = 0;
            if (ReadParams(AP_BRIGHTNESS, ref ret))
            {
                log.Info("GetBrightness " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetBrightness Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置亮度
        /// </summary>
        /// <param name="set">亮度</param>
        /// <returns>true or false</returns>
        public Boolean SetBrightness(float set)
        {
            Boolean ret = WriteParams(AP_BRIGHTNESS, set);
            log.Info("SetBrightness = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 对比度
        /// <summary>
        /// 读取对比度
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetContrast()
        {
            float ret = 0;
            if (ReadParams(AP_CONTRAST, ref ret))
            {
                log.Info("GetContrast " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetContrast Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置对比度
        /// </summary>
        /// <param name="set">对比度</param>
        /// <returns>true or false</returns>
        public Boolean SetContrast(float set)
        {
            Boolean ret = WriteParams(AP_CONTRAST, set);
            log.Info("SetContrast = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 自动亮度对比度
        /// <summary>
        /// 读取自动亮度对比度状态
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetAutoVideo()
        {
            float ret = 0;
            if (ReadParams(DP_AUTO_VIDEO, ref ret))
            {
                log.Info("GetAutoVideo " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetAutoVideo Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置自动亮度对比度状态
        /// </summary>
        /// <param name="set">0:off;1:B(亮度);2:C(对比度);3:BC</param>
        /// <returns>true or false</returns>
        public Boolean SetAutoVideoOff()
        {
            Boolean ret = WriteDataParams(DP_AUTO_VIDEO, (float)0);
            log.Info("SetAutoVideoOff", ret);
            return ret;
        }

        public Boolean SetAutoVideoBrightness()
        {
            Boolean ret = WriteDataParams(DP_AUTO_VIDEO, (float)1);
            log.Info("SetAutoVideoBrightness", ret);
            return ret;
        }

        public Boolean SetAutoVideoContrast()
        {
            Boolean ret = WriteDataParams(DP_AUTO_VIDEO, (float)2);
            log.Info("SetAutoVideoContrast", ret);
            return ret;
        }

        public Boolean SetAutoVideoBrightnessAndContrast()
        {
            Boolean ret = WriteDataParams(DP_AUTO_VIDEO, (float)3);
            log.Info("SetAutoVideoBrightnessAndContrast", ret);
            return ret;
        }
        #endregion

        #region 亮度目标
        /// <summary>
        /// 读取亮度目标
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetAutoBright()
        {
            float ret = 0;
            if (ReadParams(AP_AUTO_BRIGHT, ref ret))
            {
                log.Info("GetAutoBright " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Info("GetAutoBright Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置亮度目标
        /// </summary>
        /// <param name="set">亮度</param>
        /// <returns>true or false</returns>
        public Boolean SetAutoBright(float set)
        {
            Boolean ret = WriteParams(AP_AUTO_BRIGHT, set);
            log.Info("SetAutoBright = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 对比度目标
        /// <summary>
        /// 读取对比度目标
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetAutoContrast()
        {
            float ret = 0;
            if (ReadParams(AP_AUTO_CONTRAST, ref ret))
            {
                log.Info("GetAutoContrast " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetAutoContrast Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置对比度目标
        /// </summary>
        /// <param name="set">对比度目标</param>
        /// <returns>true or false</returns>
        public Boolean SetAutoContrast(float set)
        {
            Boolean ret = WriteParams(AP_AUTO_CONTRAST, set);
            log.Info("SetAutoContrast = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region SEM消像散
        /// <summary>
        /// 读取消像散X
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetAstigmatismX()
        {
            float ret = 0;
            if (ReadParams(AP_STIG_X, ref ret))
            {
                log.Info("GetAstigmatismX " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetAstigmatismX Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 读取消像散Y
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetAstigmatismY()
        {
            float ret = 0;
            if (ReadParams(AP_STIG_Y, ref ret))
            {
                log.Info("GetAstigmatismY " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetAstigmatismY Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置消像散X
        /// </summary>
        /// <param name="set">对比度</param>
        /// <returns>true or false</returns>
        public Boolean SetAstigmatismX(float set)
        {
            Boolean ret = WriteParams(AP_STIG_X, set);
            log.Info("SetAstigmatismX = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 设置消像散Y
        /// </summary>
        /// <param name="set">对比度</param>
        /// <returns>true or false</returns>
        public Boolean SetAstigmatismY(float set)
        {
            Boolean ret = WriteParams(AP_STIG_Y, set);
            log.Info("SetAstigmatismY = " +set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 角度补偿
        /// <summary>
        /// 读取角度补偿
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetTiltAngle()
        {
            float ret = 0;
            if (ReadParams(AP_TILT_ANGLE, ref ret))
            {
                log.Info("GetTiltAngle " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetTiltAngle Faild!", false);
                return float.NaN;
            }
        }
        /// <summary>
        /// 角度补偿解锁
        /// </summary>
        /// <returns></returns>
        public Boolean SetTiltAngleOn()
        {
            Boolean ret = WriteDataParams(DP_TILT_CORRECTION, 1);
            log.Info("Set DP_TILT_CORRECTION = 1.", ret);
            return ret;
        }

        /// <summary>
        /// 角度补偿锁定
        /// </summary>
        /// <returns></returns>
        public Boolean SetTiltAngleOff()
        {
            Boolean ret = WriteDataParams(DP_TILT_CORRECTION, 0);
            log.Info("Set DP_TILT_CORRECTION = 0.", ret);
            return ret;
        }

        /// <summary>
        /// 设置角度补偿
        /// </summary>
        /// <param name="set">角度补偿</param>
        /// <returns>true or false</returns>
        public Boolean SetTiltAngle(float set)
        {
            Boolean ret = false;
            //ret = WriteDataParams(DP_TILT_CORRECTION, 1);
            //log.Info("Set DP_TILT_CORRECTION = 1.", ret);
            ret = WriteParams(AP_TILT_ANGLE, set);
            log.Info("SetTiltAngle = " + set.ToString(), ret);
            //ret = WriteDataParams(DP_TILT_CORRECTION, 0);
            //log.Info("Set DP_TILT_CORRECTION = 0.", ret);
            return ret;
        }
        #endregion

        #region 图像大小
        public int[] GetImageStore()
        {
            int[] i_ret = new int[2];
            float ret = 0;
            if (ReadParams(DP_IMAGE_STORE, ref ret))
            {
                switch (ret)
                {
                    case 0:
                        i_ret[0] = 1024;
                        i_ret[1] = 768;
                        break;
                    case 1:
                        i_ret[0] = 512;
                        i_ret[1] = 384;
                        break;
                    case 2:
                        i_ret[0] = 2048;
                        i_ret[1] = 1536;
                        break;
                    case 3:
                        i_ret[0] = 3072;
                        i_ret[1] = 2304;
                        break;
                    case 4:
                        i_ret[0] = 4096;
                        i_ret[1] = 3072;
                        break;
                    case 5:
                        i_ret[0] = 5120;
                        i_ret[1] = 3840;
                        break;
                    case 6:
                        i_ret[0] = 6144;
                        i_ret[1] = 4608;
                        break;
                    case 7:
                        i_ret[0] = 8192;
                        i_ret[1] = 6144;
                        break;
                    case 8:
                        i_ret[0] = 12288;
                        i_ret[1] = 9216;
                        break;
                    case 9:
                        i_ret[0] = 16384;
                        i_ret[1] = 12288;
                        break;
                    case 10:
                        i_ret[0] = 24576;
                        i_ret[1] = 18432;
                        break;
                    case 11:
                        i_ret[0] = 32768;
                        i_ret[1] = 24576;
                        break;
                    default:
                        i_ret[0] = 0;
                        i_ret[1] = 0;
                        break;
                }
                log.Info("GetImageStore=" + i_ret[0].ToString() + "*" + i_ret[1].ToString(), true);
            }
            else
            {
                log.Error("GetImageStore Faild!", false);
                i_ret[0] = 0;
                i_ret[1] = 0;
            }
            return i_ret;
        }

        public Boolean SetImageStore(float set)
        {
            Boolean ret = WriteDataParams("DP_IMAGE_STORE", set);
            log.Info("SetImageStore = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 扫描周期
        public float GetCycleTime()
        {
            float ret = 0;
            if (ReadParams(AP_FRAME_TIME, ref ret))
            {
                

                log.Info("GetCycleTime=" + ret.ToString(), true);
            }
            else
            {
                log.Error("GetCycleTime Faild!", false);
               
            }
            return ret;
        }
        #endregion

        #region SEM电压
        /// <summary>
        /// 读取电压
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetSEMVoltage()
        {
            float ret = 0;
            if (ReadParams(AP_MANUALKV, ref ret))
            {
                log.Info("SEM_Voltage " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("SEM_Voltage Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电压
        /// </summary>
        /// <param name="set">电压</param>
        /// <returns>true or false</returns>
        public Boolean SetSEMVoltage(float set)
        {
            Boolean ret = WriteParams(AP_MANUALKV, set);
            log.Info("SetSEMVoltage = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region SEM电流
        /// <summary>
        /// 读取电流
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetSEMIPROBE()
        {
            float ret = 0;
            if (ReadParams(AP_IPROBE, ref ret))
            {
                log.Info("SEM_IPROBE " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("SEM_IPROBE Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电流
        /// </summary>
        /// <param name="set">电流</param>
        /// <returns>true or false</returns>
        public Boolean SetSEMIPROBE(float set)
        {
            Boolean ret = WriteParams(AP_IPROBE, set);
            log.Info("SetSEMIPROBE = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 抓取图像
        /// <summary>
        /// 抓取图像
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public Boolean GrabImage(String filename, short xoff,short yoff, short width,short height,short type)
        {
            if (m_bInitialised)
            {
                long lrt = CZEMApi.Grab(xoff, yoff, width, height, type, filename);
                if (lrt != 0)
                {
                    log.Error("GrabImage Faild!", false);
                    return false;
                }
                else
                {
                    log.Info("GrabImage Filename=" + filename + ",x,y,w,h,type=" + xoff.ToString() + "," + 
                        yoff.ToString() + "," + width.ToString() + "," + height.ToString() + "," + type.ToString(), true);
                    while (true)
                    {
                        Thread.Sleep(1000);
                        float sta = GetImageFrozen();
                        if (sta == 1)
                        {
                            log.Info("ImageLive", true);
                            ImageLive();
                            break;
                        }
                    }
                    return true;
                }
            }
            else
            {
                log.Error("GrabImage m_bInitialised = False!", false);
                return false;
            }
        }
        #endregion

        #region 小面积抓取图像
        /// <summary>
        /// 小面积抓取图像
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public Boolean GrabZoneImage(String filename, short xoff, short yoff, short width, short height, short type)
        {
            if (m_bInitialised)
            {
                float frametime = 0;
                ReadParams("AP_FRAME_TIME", ref frametime);
                ExecuteCmd("CMD_UNFREEZE_ZONE");
                Thread.Sleep((int)frametime + 200);
                ExecuteCmd("CMD_FREEZE_ZONE");
                Thread.Sleep((int)frametime + 200);
                CZEMApi.Grab(xoff, yoff, width, height, type, filename);
                return true;
            }
            else
            {
                log.Error("GrabImage m_bInitialised = False!", false);
                return false;
            }
        }
        #endregion

        #region 图像解冻
        public float GetImageFrozen()
        {
            float ret = 0;
            if (ReadParams(DP_FROZEN, ref ret))
            {
                log.Info("GetImageFrozen " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetImageFrozen Faild!", false);
                return float.NaN;
            }
        }
        public Boolean ImageFrozen()
        {
            Boolean ret = WriteDataParams(DP_FROZEN, (float)1);
            log.Info("ImageFrozen!", ret);
            return ret; 
        }
        public Boolean ImageLive()
        {
            Boolean ret = WriteDataParams(DP_FROZEN, (float)0);
            log.Info("ImageLive!", ret);
            return ret;
        }
        #endregion

        #region 图像类型切换
        public Boolean DetectorType(float set)
        {
            Boolean ret = WriteDataParams(DP_DETECTOR_TYPE, set);
            log.Info("DetectorType = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region SEM电子束移动接口
        /// <summary>
        /// 获取电子束移动接口X
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetBeamShiftX()
        {
            float ret = 0;
            if (ReadParams(AP_BEAMSHIFT_X, ref ret))
            {
                log.Info("GetBeamShiftX " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetBeamShiftX Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 获取电子束移动接口Y
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetBeamShiftY()
        {
            float ret = 0;
            if (ReadParams(AP_BEAMSHIFT_Y, ref ret))
            {
                log.Info("GetBeamShiftY " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetBeamShiftY Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电子束移动接口X
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetBeamShiftX(float set)
        {
            Boolean ret = WriteParams(AP_BEAMSHIFT_X, set);
            log.Info("SetBeamShiftX=" + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 设置电子束移动接口Y
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetBeamShiftY(float set)
        {
            Boolean ret = WriteParams(AP_BEAMSHIFT_Y, set);
            log.Info("SetBeamShiftY=" + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region SEM电子束移动距离接口
        /// <summary>
        /// 获取电子束移动距离接口X值
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetBeamOffsetX()
        {
            float ret = 0;
            if (ReadParams(AP_BEAM_OFFSET_X, ref ret))
            {
                log.Info("AP_BEAM_OFFSET_X " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("AP_BEAM_OFFSET_X Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 获取电子束移动距离接口Y值
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetBeamOffsetY()
        {
            float ret = 0;
            if (ReadParams(AP_BEAM_OFFSET_Y, ref ret))
            {
                log.Info("AP_BEAM_OFFSET_Y " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("AP_BEAM_OFFSET_Y Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电子束移动距离接口X值
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetBeamOffsetX(float set)
        {
            Boolean ret = WriteParams(AP_BEAM_OFFSET_X, set);
            log.Info("AP_BEAM_OFFSET_X=" + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 设置电子束移动接口Y
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetBeamOffsetY(float set)
        {
            Boolean ret = WriteParams(AP_BEAM_OFFSET_Y, set);
            log.Info("AP_BEAM_OFFSET_Y=" + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 样品台移动接口
        /// <summary>
        /// 返回样品台坐标数组
        /// </summary>
        /// <returns>Lenght=6</returns>
        public float[] GetStagePosition()
        {
            object retx = new VariantWrapper((float)0.0f);
            object rety = new VariantWrapper((float)0.0f);
            object retz = new VariantWrapper((float)0.0f);
            object rett = new VariantWrapper((float)0.0f);
            object retr = new VariantWrapper((float)0.0f);
            object retm = new VariantWrapper((float)0.0f);
            float[] ret = new float[6];
            if (m_bInitialised)
            {
                CZEMApi.GetStagePosition(ref retx, ref rety, ref retz, ref rett, ref retr, ref retm);
                ret[0] = Convert.ToSingle(retx);
                ret[1] = Convert.ToSingle(rety);
                ret[2] = Convert.ToSingle(retz);
                ret[3] = Convert.ToSingle(rett);
                ret[4] = Convert.ToSingle(retr);
                ret[5] = Convert.ToSingle(retm);
                log.Info("GetStagePosition x,y,z,t,r,m = " + retx.ToString() + "," + rety.ToString() + 
                    "," + retz.ToString() + "," + rett.ToString() + "," + retr.ToString() + "," + retm.ToString(), true);
            }
            else
            {
                ret[0] = float.NaN;
                ret[1] = float.NaN;
                ret[2] = float.NaN;
                ret[3] = float.NaN;
                ret[4] = float.NaN;
                ret[5] = float.NaN;
                log.Error("GetStagePosition Faild!", false);
            }
            return ret;
        }

        /// <summary>
        /// 设置样品台坐标数组
        /// </summary>
        /// <returns>Lenght=6</returns>
        private Boolean SetStagePosition(float[] set)
        {
            if (m_bInitialised)
            { 
                long lrt = CZEMApi.MoveStage(set[0], set[1], set[2], set[3], set[4], set[5]);
                if(lrt==0)
                {
                    log.Info("SetStagePosition x,y,z,t,r,m = " + set[0].ToString() + "," + set[1].ToString() +
                    "," + set[2].ToString() + "," + set[3].ToString() + "," + set[4].ToString() + "," + set[5].ToString(), true);
                    return true;
                }
                else
                {
                    log.Error("SetStagePosition Faild!", false);
                    return false;
                }
            }
            else
            {
                log.Error("SetStagePosition m_bInitialised = false!", false);
                return false;
            }
        }

        /// <summary>
        /// 样品台位置 X轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtX()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_X, ref ret))
            {
                log.Info("GetStageAtX Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtX Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 Y轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtY()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_Y, ref ret))
            {
                log.Info("GetStageAtY Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtY Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 Z轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtZ()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_Z, ref ret))
            {
                log.Info("GetStageAtZ Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtZ Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 T轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtT()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_T, ref ret))
            {
                log.Info("GetStageAtT Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtT Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 R轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtR()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_R, ref ret))
            {
                log.Info("GetStageAtR Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtR Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 M轴
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetStageAtM()
        {
            float ret = 0;
            if (ReadParams(AP_STAGE_AT_M, ref ret))
            {
                log.Info("GetStageAtM Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageAtM Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 样品台位置 X轴
        /// </summary>
        /// <param name="set">X轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoX(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_X, set);
            log.Info("SetStageGotoX = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 Y轴
        /// </summary>
        /// <param name="set">Y轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoY(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_Y, set);
            log.Info("SetStageGotoY = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 Z轴
        /// </summary>
        /// <param name="set">Y轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoZ(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_Z, set);
            log.Info("SetStageGotoZ = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 T轴
        /// </summary>
        /// <param name="set">Y轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoT(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_T, set);
            log.Info("SetStageGotoT = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 R轴
        /// </summary>
        /// <param name="set">Y轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoR(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_R, set);
            log.Info("SetStageGotoR = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 R轴拉直
        /// </summary>
        /// <param name="set">R轴拉直角度</param>
        /// <returns></returns>
        public Boolean SetStageDeltaR(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_DELTA_R, set);
            log.Info("AP_STAGE_DELTA_R = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 样品台位置 M轴
        /// </summary>
        /// <param name="set">M轴移动坐标</param>
        /// <returns></returns>
        public Boolean SetStageGotoM(float set)
        {
            Boolean ret = WriteParams(AP_STAGE_GOTO_M, set);
            log.Info("SetStageGotoM = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region 移动样品台XY轴
        public Boolean MoveStageXY(float x,float y)
        {
            //先取范围
            object xMin = new VariantWrapper((float)0.0f);
            object xMax = new VariantWrapper((float)0.0f);
            long lrt = CZEMApi.GetLimits(AP_STAGE_GOTO_X, ref xMin, ref xMax);
            if (lrt != 0)
            {
                log.Error("GetLimits AP_STAGE_GOTO_X Faild!", false);
                return false;
            }
            if (x > Convert.ToSingle(xMax) || x < Convert.ToSingle(xMin))
            {
                log.Error("GetLimits AP_STAGE_GOTO_X Max,Min,x = " + xMax.ToString() + "," + xMin.ToString() +
                    "," + x.ToString(), false);
                return false;
            }
            object yMin = new VariantWrapper((float)0.0f);
            object yMax = new VariantWrapper((float)0.0f);
            lrt = CZEMApi.GetLimits(AP_STAGE_GOTO_Y, ref yMin, ref yMax);
            if (lrt != 0)
            {
                log.Error("GetLimits AP_STAGE_GOTO_Y Faild!", false);
                return false;
            }
            if (y > Convert.ToSingle(yMax) || y < Convert.ToSingle(yMin))
            {
                log.Error("GetLimits AP_STAGE_GOTO_Y Max,Min,y = " + yMax.ToString() + "," + yMin.ToString() +
                    "," + y.ToString(), false);
                return false;
            }
            float[] gsp = GetStagePosition();
            gsp[0] = x;
            gsp[1] = y;
            return SetStagePosition(gsp);
        }
        #endregion

        #region 样品台急停
        public Boolean CmdStageAbort()
        {
            Boolean ret = ExecuteCmd(CMD_STAGE_ABORT);
            log.Info("CmdStageAbort!", ret);
            return ret;
        }
        #endregion

        #region Scan Rotate角度接口
        /// <summary>
        /// 获取Scan Rotate角度接口
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetScanRotation()
        {
            float ret = 0;
            if (ReadParams(AP_SCANROTATION, ref ret))
            {
                log.Info("GetScanRotation Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetScanRotation Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// ScanRotation解锁
        /// </summary>
        /// <returns></returns>
        public Boolean SetScanRotationOn()
        {
            Boolean ret = WriteDataParams(DP_SCAN_ROT, 1);
            log.Info("SetScanRotation DP_SCAN_ROT = 1", ret);
            return ret;
        }

        /// <summary>
        /// ScanRotation锁定
        /// </summary>
        /// <returns></returns>
        public Boolean SetScanRotationOff()
        {
            Boolean ret = WriteDataParams(DP_SCAN_ROT, 0);
            log.Info("SetScanRotation DP_SCAN_ROT = 0", ret);
            return ret;
        }

        /// <summary>
        /// 设置Scan Rotate角度接口
        /// </summary>
        /// <param name="set">角度补偿</param>
        /// <returns>true or false</returns>
        public Boolean SetScanRotation(float set)
        {
            Boolean ret = false;
            //ret = WriteDataParams(DP_SCAN_ROT, 1);
            //log.Info("SetScanRotation DP_SCAN_ROT = 1", ret);
            ret = WriteParams(AP_SCANROTATION, set);
            log.Info("SetScanRotation = " + set.ToString(), ret);
            //ret = WriteDataParams(DP_SCAN_ROT, 0);
            //log.Info("SetScanRotation DP_SCAN_ROT = 0", ret);
            return ret;
        }
        #endregion

        #region 像素读取PixelSize
        /// <summary>
        /// 获取Pixel Size 接口,只读
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetPixelSize()
        {
            float ret = 0;
            if (ReadParams(AP_PIXEL_SIZE, ref ret))
            {
                log.Info("GetPixelSize " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Info("GetPixelSize Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region 电子束校正设置
        /// <summary>
        /// 读取电子束校正状态
        /// </summary>
        /// <returns></returns>
        public float GetTiltCorrection()
        {
            float ret = 0;
            if (ReadParams(DP_TILT_CORRECTION, ref ret))
            {
                log.Info("GetTiltCorrection " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetTiltCorrection Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电子束校正状态
        /// </summary>
        /// <param name="set"></param>
        /// <returns></returns>
        public Boolean SetTiltCorrectionOff()
        {
            Boolean ret = WriteDataParams(DP_TILT_CORRECTION, (float)0);
            log.Info("SetTiltCorrectionOff!", ret);
            return ret;
        }
        public Boolean SetTiltCorrectionOn()
        {
            Boolean ret = WriteDataParams(DP_TILT_CORRECTION, (float)1);
            log.Info("SetTiltCorrectionOn!", ret);
            return ret;
        }
        #endregion

        #region 开启电压
        public Boolean CmdOpenVoltage()
        {
            Boolean ret = ExecuteCmd(CMD_BEAM_ON);
            log.Info("CmdOpenVoltage!", ret);
            return ret;
        }
        #endregion

        #region 关闭电压
        public Boolean CmdCloseVoltage()
        {
            Boolean ret = ExecuteCmd(CMD_EHT_OFF);
            log.Info("CmdCloseVoltage!", ret);
            return ret;
        }
        #endregion

        #region 自动对焦1
        public Boolean CmdAutoFocusCoarse()
        {
            Boolean ret = ExecuteCmd(CMD_AUTO_FOCUS_COARSE);
            log.Info("CmdAutoFocusCoarse!", ret);
            return ret;
        }
        #endregion

        #region 自动对焦2
        public Boolean CmdAutoFocusFine()
        {
            Boolean ret = ExecuteCmd(CMD_AUTO_FOCUS_FINE);
            log.Info("CmdAutoFocusFine!", ret);
            return ret;
        }
        #endregion

        #region 自动消像散
        public Boolean CmdAutoStig()
        {
            Boolean ret = ExecuteCmd(CMD_AUTO_STIG);
            log.Info("CmdAutoStig!", ret);
            return ret;
        }
        #endregion

        #region 调用宏文件命令
        public Boolean CMDMCFFilename(String _MLFFullFileName)
        {
            //String CMDMCF = MCF_FILENAME + filename;
            //Boolean ret = ExecuteCmd(CMDMCF);
            //log.Info("CMDMCFFilename = " + filename, ret);
            //return ret;

            if (File.Exists(_MLFFullFileName) && Directory.Exists(MLFPATH))
            {
                //移动文件
                if (_MLFFullFileName != (MLFPATH + MLFFILENAME))
                {
                    File.Copy(_MLFFullFileName, MLFPATH + MLFFILENAME, true);
                    log.Info("CmdFIBLoadMLF Copy FileName：" + _MLFFullFileName + " To " + MLFPATH + MLFFILENAME, true);
                    try
                    {
                        if (REMOTEMLFPATH != "")
                        {
                            File.Copy(_MLFFullFileName, REMOTEMLFPATH + MLFFILENAME, true);
                        }
                    }
                    catch { }
                }
                Boolean ret = ExecuteCmd(MCF_FILENAME + MLFFILENAME.Substring(0,MLFFILENAME.Length-4));
                log.Info("CmdFIBLoadMLF Success Execute " + _MLFFullFileName, true);
                return ret;
            }
            else
            {
                log.Error("CmdFIBLoadMLF Faild：" + _MLFFullFileName + " Is Not Exists!", false);
                return false;
            }
        }
        #endregion

        #region 读取样品台状态
        public float GetStageIs()
        {
            float ret = 0;
            if (ReadParams(DP_STAGE_IS, ref ret))
            {
                log.Info("GetStageIs " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetStageIs Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region 读取自动函数的状态
        public float GetAutoFunction()
        {
            float ret = 0;
            if (ReadParams(DP_AUTO_FUNCTION, ref ret))
            {
                log.Info("GetAutoFunction " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetAutoFunction Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region FIB缩放
        /// <summary>
        /// 读取缩放倍数
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBMagnification()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_MAGNIFICATION, ref ret))
            {
                log.Info("GetFIBMagnification " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBMagnification Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置缩放倍数
        /// </summary>
        /// <param name="set">倍数</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBMagnification(float set)
        {
            Boolean ret = WriteParams(AP_FIB_MAGNIFICATION, set);
            log.Info("GSetFIBMagnification = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region FIB焦距
        /// <summary>
        /// 读取工作距离AP_FIB_OBJECTIVE_POTENTIAL
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBObjectivePotential()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_OBJECTIVE_POTENTIAL, ref ret))
            {
                log.Info("GetFIBObjectivePotential " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBObjectivePotential Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置焦距
        /// </summary>
        /// <param name="set">焦距</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBObjectivePotential(float set)
        {
            Boolean ret = WriteParams(AP_FIB_OBJECTIVE_POTENTIAL, set);
            log.Info("SetFIBObjectivePotential = " + set.ToString(), ret);
            return ret;
        }
        #endregion  

        #region FIB消像散
        /// <summary>
        /// 读取消像散X
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBAstigmatismX()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_STIGMATOR_X, ref ret))
            {
                log.Info("GetFIBAstigmatismX " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBAstigmatismX Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 读取消像散Y
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBAstigmatismY()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_STIGMATOR_Y, ref ret))
            {
                log.Info("GetFIBAstigmatismY " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBAstigmatismY Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置消像散X
        /// </summary>
        /// <param name="set">对比度</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBAstigmatismX(float set)
        {
            Boolean ret = WriteParams(AP_FIB_STIGMATOR_X, set);
            log.Info("SetFIBAstigmatismX = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 设置消像散Y
        /// </summary>
        /// <param name="set">对比度</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBAstigmatismY(float set)
        {
            Boolean ret = WriteParams(AP_FIB_STIGMATOR_Y, set);
            log.Info("SetFIBAstigmatismY = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region FIB电子束移动接口
        /// <summary>
        /// 获取电子束移动接口X
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBBeamShiftX()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_BEAM_SHIFT_X, ref ret))
            {
                log.Info("GetFIBBeamShiftX " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBBeamShiftX Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 获取电子束移动接口Y
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBBeamShiftY()
        {
            float ret = 0;
            if (ReadParams(AP_FIB_BEAM_SHIFT_Y, ref ret))
            {
                log.Info("GetFIBBeamShiftY " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBBeamShiftY Faild!", false);
                return float.NaN;
            }
        }

        /// <summary>
        /// 设置电子束移动接口X
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBBeamShiftX(float set)
        {
            Boolean ret = WriteParams(AP_FIB_BEAM_SHIFT_X, set);
            log.Info("SetFIBBeamShiftX = " + set.ToString(), ret);
            return ret;
        }

        /// <summary>
        /// 设置电子束移动接口Y
        /// </summary>
        /// <param name="set">X坐标</param>
        /// <returns>true or false</returns>
        public Boolean SetFIBBeamShiftY(float set)
        {
            Boolean ret = WriteParams(AP_FIB_BEAM_SHIFT_Y, set);
            log.Info("SetFIBBeamShiftX = " + set.ToString(), ret);
            return ret;
        }
        #endregion

        #region FIB模式
        /// <summary>
        /// 获取FIB模式
        /// </summary>
        /// <returns>true:float or false:NaN</returns>
        public float GetFIBMode()
        {
            float ret = 0;
            if (ReadParams(DP_FIB_MODE, ref ret))
            {
                log.Info("GetFIBMode " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBMode Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region 工作模式选择
        //SEM模式
        public Boolean CmdFIBModeSEM()
        {
            Boolean ret = ExecuteCmd(CMD_FIB_MODE_SEM);
            log.Info("CmdFIBModeSEM = SEM!", ret);
            return ret;
        }

        //FIB模式
        public Boolean CmdFIBModeFIB()
        {
            Boolean ret = ExecuteCmd(CMD_FIB_MODE_FIB);
            log.Info("CmdFIBModeSEM = FIB!", ret);
            return ret;
        }

        //铣削模式
        public Boolean CmdFIBModeMILL()
        {
            Boolean ret = ExecuteCmd(CMD_FIB_MODE_MILL);
            log.Info("CmdFIBModeSEM = MILL!", ret);
            return ret;
        }

        //SEM+FIB模式
        public Boolean CmdFIBModeSEMAndFIB()
        {
            return ExecuteCmd(CMD_FIB_MODE_SEM_FIB);
        }

        //铣削+SEM模式
        public Boolean CmdFIBModeMILLAndSEM()
        {
            return ExecuteCmd(CMD_FIB_MODE_MILL_SEM);
        }

        //EXT模式
        public Boolean CmdFIBModeEXT()
        {
            return ExecuteCmd(CMD_FIB_MODE_EXT);
        }

        //EXT+SEM模式
        public Boolean CmdFIBModeEXTAndSEM()
        {
            return ExecuteCmd(CMD_FIB_MODE_EXT_SEM);
        }

        //Argon(氩)+SEM模式
        public Boolean CmdFIBModeARGONAndSEM()
        {
            return ExecuteCmd(CMD_FIB_MODE_ARGON_SEM);
        }

        //DRIFT(流)+SEM模式
        public Boolean CmdFIBModeDRIFTAndSEM()
        {
            return ExecuteCmd(CMD_FIB_MODE_DRIFT_SEM);
        }

        //DRIFT(流)+FIB模式
        public Boolean CmdFIBModeDRIFTAndFIB()
        {
            return ExecuteCmd(CMD_FIB_MODE_DRIFT_FIB);
        }

        //Argon(氩)模式
        public Boolean CmdFIBModeARGON()
        {
            return ExecuteCmd(CMD_FIB_MODE_ARGON);
        }
        #endregion

        #region 工作模式读取
        /// <summary>
        /// 工作模式读取
        /// </summary>
        /// <returns>0：SEM 1：FIB 2：MILL</returns>
        public float GetFIBIMAGING()
        {
            float ret = 0;
            if (ReadParams(DP_FIB_IMAGING, ref ret))
            {
                log.Info("GetFIBIMAGING " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBIMAGING Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region FIB工作状态
        public float GetFIBApiStatus()
        {
            float ret = 0;
            if (ReadParams(DP_SMARTFIB_API_STATUS, ref ret))
            {
                log.Info("GetFIBApiStatus " + ret.ToString() + " Success!", true);
                return ret;
            }
            else
            {
                log.Error("GetFIBApiStatus Faild!", false);
                return float.NaN;
            }
        }
        #endregion

        #region FIB加载.ely文件
        public Boolean CmdFIBLoadELY(String _ELYFullFileName)
        {
            if (File.Exists(_ELYFullFileName) && Directory.Exists(ELYPATH))
            {
                //移动文件
                if(_ELYFullFileName != ( ELYPATH + ELYFILENAME ))
                {
                    File.Copy(_ELYFullFileName, ELYPATH + ELYFILENAME, true);
                    log.Info("CmdFIBLoadELY Copy FileName：" + _ELYFullFileName + " To " + ELYPATH + ELYFILENAME, true);
                    try
                    {
                        if (REMOTEELYPATH != "")
                        {
                            File.Copy(_ELYFullFileName, REMOTEELYPATH + ELYFILENAME, true);
                        }
                    }
                    catch
                    {

                    }
                }
                Boolean ret = ExecuteCmd(CMD_SMARTFIB_LOAD_ELY);
                log.Info("CmdFIBLoadELY Success Execute " + _ELYFullFileName, true);
                return ret;
            }
            else
            {
                log.Error("CmdFIBLoadELY Faild：" + _ELYFullFileName + " Is Not Exists!", false);
                return false;
            }
        }
        #endregion

        #region FIB确认.ely文件
        public Boolean CmdFIBEXPOSUREELY()
        {
            Boolean ret = WriteDataParams(DP_PATTERNING_MODE, 2);
            log.Info("DP_PATTERNING_MODE = 2", ret);
            ret = ExecuteCmd(CMD_SMARTFIB_PREPARE_EXPOSURE);
            log.Info("CMD_SMARTFIB_PREPARE_EXPOSURE", ret);
            return ret;
        }
        #endregion

        #region FIB执行.ely文件
        public Boolean CmdFIBSTARTELY()
        {
            Boolean ret = ExecuteCmd(CMD_FIB_START_MILLING);
            log.Info("CMD_FIB_START_MILLING", ret);
            return ret;
        }
        #endregion

        #region 错误代码转义
        private String ErrorToString(long lError)
        {
            string strError;
            switch ((ZeissErrorCode)lError)
            {
                case 0:
                    strError = "OK";
                    break;
                case ZeissErrorCode.API_E_GET_TRANSLATE_FAIL:
                    strError = "Failed to translate parameter into an ID";
                    break;
                case ZeissErrorCode.API_E_GET_AP_FAIL:
                    strError = "Failed to get analogue value";
                    break;
                case ZeissErrorCode.API_E_GET_DP_FAIL:
                    strError = "Failed to get digital value";
                    break;
                case ZeissErrorCode.API_E_GET_BAD_PARAMETER:
                    strError = "Parameter supplied is neither analogue nor digital";
                    break;
                case ZeissErrorCode.API_E_SET_TRANSLATE_FAIL:
                    strError = "Failed to translate parameter into an ID";
                    break;
                case ZeissErrorCode.API_E_SET_STATE_FAIL:
                    strError = "Failed to set a digital state";
                    break;
                case ZeissErrorCode.API_E_SET_FLOAT_FAIL:
                    strError = "Failed to set a float value";
                    break;
                case ZeissErrorCode.API_E_SET_FLOAT_LIMIT_LOW:
                    strError = "Value supplied is too low";
                    break;
                case ZeissErrorCode.API_E_SET_FLOAT_LIMIT_HIGH:
                    strError = "Value supplied is too high";
                    break;
                case ZeissErrorCode.API_E_SET_BAD_VALUE:
                    strError = "Value supplied is of wrong type";
                    break;
                case ZeissErrorCode.API_E_SET_BAD_PARAMETER:
                    strError = "Parameter supplied is not analogue nor digital";
                    break;
                case ZeissErrorCode.API_E_EXEC_TRANSLATE_FAIL:
                    strError = "Failed to translate command into an ID";
                    break;
                case ZeissErrorCode.API_E_EXEC_CMD_FAIL:
                    strError = "Failed to execute command";
                    break;
                case ZeissErrorCode.API_E_EXEC_MCF_FAIL:
                    strError = "Failed to execute file macro";
                    break;
                case ZeissErrorCode.API_E_EXEC_MCL_FAIL:
                    strError = "Failed to execute library macro";
                    break;
                case ZeissErrorCode.API_E_EXEC_BAD_COMMAND:
                    strError = "Command supplied is not implemented";
                    break;
                case ZeissErrorCode.API_E_GRAB_FAIL:
                    strError = "Grab command failed";
                    break;
                case ZeissErrorCode.API_E_GET_STAGE_FAIL:
                    strError = "Get Stage position failed";
                    break;
                case ZeissErrorCode.API_E_MOVE_STAGE_FAIL:
                    strError = "Move Stage position failed";
                    break;
                case ZeissErrorCode.API_E_NOT_INITIALISED:
                    strError = "API not initialised";
                    break;
                case ZeissErrorCode.API_E_NOTIFY_TRANSLATE_FAIL: // 1020L
                    strError = "Failed to translate parameter to an ID";
                    break;
                case ZeissErrorCode.API_E_NOTIFY_SET_FAIL:
                    strError = "Set notification failed";
                    break;
                case ZeissErrorCode.API_E_GET_LIMITS_FAIL:
                    strError = "Get limits failed";
                    break;
                case ZeissErrorCode.API_E_GET_MULTI_FAIL:
                    strError = "Get multiple parameters failed";
                    break;
                case ZeissErrorCode.API_E_SET_MULTI_FAIL:
                    strError = "Set multiple parameters failed";
                    break;
                case ZeissErrorCode.API_E_NOT_LICENSED:
                    strError = "Missing API license";
                    break;
                case ZeissErrorCode.API_E_NOT_IMPLEMENTED:
                    strError = "Reserved or not implemented";
                    break;
                case ZeissErrorCode.API_E_GET_USER_NAME_FAIL:
                    strError = "Failed to get user name";
                    break;
                case ZeissErrorCode.API_E_GET_USER_IDLE_FAIL:
                    strError = "Failed to get user idle state";
                    break;
                case ZeissErrorCode.API_E_GET_LAST_REMOTING_CONNECT_ERROR_FAIL:
                    strError = "Failed to get the last remoting connection error string";
                    break;
                case ZeissErrorCode.API_E_EMSERVER_LOGON_FAILED:
                    strError = "Failed to remotely logon to the EM Server. Username and password may be incorrect or EM Server is not running or User is already logged on";
                    break;
                case ZeissErrorCode.API_E_EMSERVER_START_FAILED:
                    strError = "Failed to start the EM Server. This may be because the Server is already running or has an internal error.";
                    break;
                case ZeissErrorCode.API_E_REMOTING_NOT_CONFIGURED:
                    strError = "Remoting incorrectly configured, use RConfigure to correct";
                    break;
                case ZeissErrorCode.API_E_REMOTING_FAILED_TO_CONNECT:
                    strError = "Remoting did not connect to the server";
                    break;
                case ZeissErrorCode.API_E_REMOTING_COULD_NOT_CREATE_INTERFACE:
                    strError = "Remoting could not start (unknown reason)";
                    break;
                case ZeissErrorCode.API_E_REMOTING_EMSERVER_NOT_RUNNING:
                    strError = "EMServer is not running on the remote machine";
                    break;
                case ZeissErrorCode.API_E_REMOTING_NO_USER_LOGGED_IN:
                    strError = "No user is logged into EM Server on the remote machine";
                    break;
                default:
                    strError = string.Format("Unknown error code {0}", lError);
                    break;
            }
            return strError;
        }
        #endregion

        //20201016 扫图速度
        #region Focus rate add by sun 2020-12-15 拍截面图调用蔡司接口时，要保证扫描速度5以上，自动亮度对比度功能关闭
        public Boolean CmdFocusRate(int mFocusSpeed)
        {
            string mTempSpeed = CMD_SCANRATE4;
            switch (mFocusSpeed)
            {
                case 3:
                    mTempSpeed= CMD_SCANRATE3; break;
                case 4:
                    mTempSpeed = CMD_SCANRATE4; break;
                case 5:
                    mTempSpeed = CMD_SCANRATE5; break;
                case 6:
                    mTempSpeed = CMD_SCANRATE6; break;
                case 7:
                    mTempSpeed = CMD_SCANRATE7; break;
                case 8:
                    mTempSpeed = CMD_SCANRATE8; break;
                case 9:
                    mTempSpeed = CMD_SCANRATE9; break;
                case 10:
                    mTempSpeed = CMD_SCANRATE10; break;
                default:
                    break;
            }
            Boolean ret = ExecuteCmd(mTempSpeed); 
            log.Info("调整扫描速度为====="+ mTempSpeed + "===是否成功"+ ret, true);  //CMD_SCANRATE4!
            return ret;
        }

        public Boolean CmdFocusScanSpeed(String mFocusSpeed)  
        {
            Boolean ret = ExecuteCmd(mFocusSpeed);
            log.Info("调整扫描速度为 " + mFocusSpeed + " " +  ret.ToString(), true);
            return ret;
        }
        #endregion add by sun 2020-12-15 拍截面图调用蔡司接口时，要保证扫描速度5以上，自动亮度对比度功能关闭 end


        #region Save rate
        public Boolean CmdSaveRate()
        {
            //Boolean ret = ExecuteCmd(CMD_SCANRATE6);
            //log.Info("CMD_SCANRATE6!", ret);
            Boolean ret = ExecuteCmd(CMD_SCANRATE7);
            log.Info("CMD_SCANRATE7!", ret);
            //Boolean ret = ExecuteCmd(CMD_SCANRATE8);
            //log.Info("CMD_SCANRATE8!", ret);
            //Boolean ret = ExecuteCmd(CMD_SCANRATE9);
            //log.Info("CMD_SCANRATE9!", ret);
            return ret;
        }
        #endregion

        #region Save best rate
        public Boolean CmdSaveBestRate()
        {
            Boolean ret = ExecuteCmd(CMD_SCANRATE8);
            log.Info("CMD_SCANRATE8!", ret);
            return ret;
        }
        #endregion

        #region line scan
        public Boolean CmdLineScan()
        {
            Boolean ret = ExecuteCmd(CMD_LINE_AVG);
            log.Info("CMD_LINE_AVG!", ret);
            Thread.Sleep(200);

            CZEMApi.Set("DP_SCANRATE", new VariantWrapper((float)3));
            Thread.Sleep(200);

            CZEMApi.Set("AP_NR_COEFF", new VariantWrapper((float)30));
            Thread.Sleep(200);

            return ret;
        }
        #endregion

        #region pixel scan
        public Boolean CmdPixelScan()
        {
            Boolean ret = ExecuteCmd(CMD_PIXNR);
            log.Info("CMD_PIXNR!", ret);
            Thread.Sleep(200);

            CZEMApi.Set("DP_SCANRATE", new VariantWrapper((float)3));
            Thread.Sleep(200);

            return ret;
        }
        #endregion

        //20201102 远程服务地址
        public void SetRemoteELYPath(String path)
        {
            this.REMOTEELYPATH = path;
        }

        public void SetRemoteMLFPath(String path)
        {
            this.REMOTEMLFPATH = path;
        }

        public void SetReduced(int x, int y, int W, int H)
        {

            CZEMApi.Execute("CMD_MODE_NORMAL");

            int X = (int)Math.Floor((double)((1024 - W) / 2.0));
            int Y = (int)Math.Floor((double)((768 - H) / 2.0));
            CZEMApi.Set("AP_RED_RASTER_W", new VariantWrapper((float)W));
            CZEMApi.Set("AP_RED_RASTER_H", new VariantWrapper((float)H));
            CZEMApi.Set("AP_RED_RASTER_POSN_X", new VariantWrapper((float)X));
            CZEMApi.Set("AP_RED_RASTER_POSN_Y", new VariantWrapper((float)Y));
            Thread.Sleep(100);
            CZEMApi.Execute("CMD_MODE_REDUCED");
            Thread.Sleep(100);

        }

        public void SetReduced1(int x, int y, int W, int H)
        {

            CZEMApi.Execute("CMD_MODE_NORMAL");

            CZEMApi.Set("AP_RED_RASTER_W", new VariantWrapper((float)W));
            CZEMApi.Set("AP_RED_RASTER_H", new VariantWrapper((float)H));
            CZEMApi.Set("AP_RED_RASTER_POSN_X", new VariantWrapper((float)x));
            CZEMApi.Set("AP_RED_RASTER_POSN_Y", new VariantWrapper((float)y));
            Thread.Sleep(100);
            CZEMApi.Execute("CMD_MODE_REDUCED");
            Thread.Sleep(100);

        }

        public void CloseReduced()
        {
            CZEMApi.Execute("CMD_MODE_NORMAL");
            Thread.Sleep(200);
        }
    }
}
