using OINA.Extender; using OINA.Extender.Acquisition; using OINA.Extender.Acquisition.Ed; using OINA.Extender.Acquisition.Image; using OINA.Extender.Data; using OINA.Extender.Data.Ed; using OINA.Extender.Data.Image; using OINA.Extender.MicroscopeControl; using OINA.Extender.Processing; using OINA.Extender.Processing.Ed; using OINA.Extender.Processing.Quant; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Windows; using System.Windows.Forms; using static OxfordExtenderWrapper.ExtenderIpcUI; namespace OxfordExtenderWrapper { enum OxfordControllerState { READY = 0, WORKING = 1, SUCCEEDED = 2, FAILED = 3, ABORT = 4 }; [Serializable] public class Segment { private int m_nX; private int m_nY; private int m_nLength; public int X { get { return m_nX; } set { if (value > 0) { m_nX = value; } } } public int Y { get { return m_nY; } set { if (value > 0) { m_nY = value; } } } public int Length { get { return m_nLength; } set { if (value > 0) { m_nLength = value; } } } }; /// /// Enum EDSConst definition. /// enum EDSConst { MAX_XRAY_BATCH = 1024, XANA_CHANNELS = 2000, XANA_CHANNELS_MAX = 4192, MAX_AMPTIME_CONSTANTS = 10, MAX_EV_PER_CHANNELS = 5, MAX_ANALYZERS = 5, MAX_LEN_ANALYZER_NAME = 16 }; [Serializable] struct OxfordChord { public long m_nX; public long m_nY; public long m_nLength; }; enum OxfordCommandType { GetMagnification = 0, SetMagnification = 1, GetWorkingDistance = 2, SetWorkingDistance = 3, GetBrightness = 4, SetBrightness = 5, GetContrast = 6, SetContrast = 7, GetSEMVoltage = 8, SetSEMVoltage = 9, //样品台 GetStagePosition = 10, SetStagePosition = 11, GetStageAtX = 12, GetStageAtY = 13, GetStageAtZ = 14, GetStageAtT = 15, GetStageAtR = 16, SetStageGotoX = 17, SetStageGotoY = 18, SetStageGotoZ = 19, SetStageGotoT = 20, SetStageGotoR = 21, MoveStageXY = 22, //拍图 ImageAquisition = 23, //采集参数设置 SetImageAcquistionSetting = 24, //获取分辨率 GetImageResolution = 25, //设置分辨率 SetImageResolution = 26, //获取bitmap GetBitmap = 27, //X-ray //点采集 XrayPointCollection = 29, COLLECT_XRAYPOINTS = 30, //面采集 XrayAreaCollection = 31, COLLECT_XRAYFEATURES = 32, Exit = 100, } [Serializable] public class ImageAquistionParam { public enum ImageRegionType { FullField = 0, Rectangle = 1 } public ImageAquistionParam() { this.ImageData = new byte[width * height]; regionType = ImageRegionType.FullField; } //in public ImageRegionType regionType; public int width; public int height; public Rect ImgRectRegion; public double DwellTime; public ImageInputSourceType sourceType; //out public byte[] ImageData; } [Serializable] public class PointXrayParam { public PointXrayParam() { this.XrayData = new uint[2000]; this.listElement = new Dictionary(); } public double dMilliSecondsTime; public double x; public double y; //out public uint[] XrayData; public Dictionary listElement; public bool b_quant; } [Serializable] public class AreaXrayParam { public AreaXrayParam() { this.XrayData = new uint[2000]; this.listElement = new Dictionary(); } public double dMilliSecondsTime; public List a_listChord = new List(); public uint[] XrayData; public Dictionary listElement; public bool b_quant; } [Serializable] public struct MoveStageParam { public float x; public float y; } struct oxfordCommandData { public OxfordCommandType commandType; public bool returnType; public MoveStageParam moveStagePrm; public ImageAquistionParam grabImgParam; public PointXrayParam pointXrayPrm; public AreaXrayParam areaXrayPrm; public List XrayPrmForPoints; public int PointXrayDataReceived; public List XrayPrmForFeatures; public int AreaXrayDataReceived; } public class ExtenderWrapper : MarshalByRefObject { NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); private oxfordCommandData currentCommand; //控制电镜 private IMicroscopeController microscopeController = null; /// /// IImageAcquisitionController object /// private IImageAcquisitionController imageAcquisitionController = null; /// /// IImageSettings object /// private IImageAcquisitionSettings imageAcquisitionSettings = null; //控制器 private IEdSpectrumAcquisitionController EdSpectrumAcquisitionController = null; private IEdSpectrumSettings EdSpectrumSettings = null; private IEdSpectrumProcessing EdSpectrumProcessing = null; // Use the autoIdSettings to define elements that are known or elements that you want to exclude. They also list elements that cannot be identified private IAutoIdSettings autoIdSettings = null; private ISEMQuantSettings quantSettings = null; //private IEdChordListAcquisitionController _edsChordListController = null; private IEdChordListSettings _edsChordListSetting; private int XRayChannelLength = 2000; private int EDSColletionTimeOut = 10000; const int g_nOxfordControllerProcessTime = 4; const int g_nOxfordControllerEnergyRange = 20; const int XrayQuantityLimitPerTime = 256; private bool m_bXrayDone = false; //电压 private double m_dHighVoltage=0; //放大倍数 private double m_dMagnification=0; //工作距离 private double m_dWorkingDistance=0; //亮度 private double m_dBirghtness=0; //对比度 private double m_dContrast = 0; //BeamOn private bool m_bBeamOn; //FilamentOn private bool m_bFilamentOn; //样品台位置 private double m_dStageX; private double m_dStageY; private double m_dStageZ; private double m_dStageR; private double m_dStageT; private byte[] m_ImageBit = null; private long m_nImageWidth = 0; private long m_nImageHeight = 0; private double m_dImagePixelsize = 0;//it will be initialized when we get an image from the EDS. bool m_bAcquistionDone = false; private bool m_StageUpdated; private bool m_CollumnUpdated; private bool m_ExternalScanUpdated; const String theElementNameList = ("H,He") + (",Li,Be,B,C,N,O,F,Ne") + (",Na,Mg,Al,Si,P,S,Cl,Ar") + (",K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr") + (",Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe") + (",Cs,Ba,La") + (",Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu") + (",Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn") + (",Fr,Ra,Ac") + (",Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Lr"); private bool m_ifautoid = true; private string m_knownelements; //构造函数 public ExtenderWrapper() { //ConnectToEDSHardware(); } public bool ConnectToEDSHardware() { try { InitMicroscopeController(); InitImageAcquisition(); InitXrayAcquistion(); return true; } catch (Exception e) { log.Error(e.Message); return false; } } //结束 public void CloseExtender() { CloseMicroscopeController(); CloseImageAcquisition(); CloseXrayAcquistion(); } public bool AquisitionImage(ref ImageAquistionParam p) { currentCommand.grabImgParam = p; currentCommand.commandType = OxfordCommandType.ImageAquisition; SetImageAcquistionSetting(p); try { int lastingTime = 0; m_bAcquistionDone = false; imageAcquisitionController.BeginMultipleAcquisition(); IEnumerable images = imageAcquisitionController.StartAcquisition(imageAcquisitionSettings); int time1 = Environment.TickCount; while (true) { if (m_bAcquistionDone) { p.ImageData = m_ImageBit; currentCommand.returnType = true; break; } Application.DoEvents(); int time2; time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * 6) { currentCommand.returnType = false; break; } } } catch (InvalidSettingsException settingsException) { var sb = new StringBuilder(@"Invalid settings have been supplied: "); sb.AppendLine(); settingsException.ValidationResults.ValidationErrors.ToList().ForEach(ve => sb.AppendFormat("{0}{1}", Environment.NewLine, ve)); NLog.LogManager.GetCurrentClassLogger().Error(sb.ToString()); } catch (AcquisitionStartException startException) { string msg = string.Format(@"AcquisitionStartException: {0}", startException.Message); NLog.LogManager.GetCurrentClassLogger().Error(msg); } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool MoveStageXY(float x, float y) { currentCommand.moveStagePrm = new MoveStageParam(); currentCommand.moveStagePrm.x = x; currentCommand.moveStagePrm.y = y; currentCommand.commandType = OxfordCommandType.MoveStageXY; var stageDictionary = new Dictionary { { Stage.StageX, (double)x/1000.0 }, { Stage.StageY, (double)y /1000.0} }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); currentCommand.returnType = true; int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 60000) { currentCommand.returnType = false; break; } } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool XrayAreaCollecting(ref AreaXrayParam p) { currentCommand.areaXrayPrm = p; currentCommand.commandType = OxfordCommandType.XrayAreaCollection; m_bXrayDone = false; SetXrayAcquisitionParam(p.dMilliSecondsTime); List Chords = new List(); foreach (Segment seg in p.a_listChord) { Chord chord = new Chord(seg.X, seg.Y, seg.Length); Chords.Add(chord); } var chordsList = new ChordList(Chords, m_dImagePixelsize); EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreateChordListRegion(chordsList); EdSpectrumAcquisitionController.BeginMultipleAcquisition(); try { IEdSpectrum edSpectrum = EdSpectrumAcquisitionController.StartAcquisition(EdSpectrumSettings); var time1 = Environment.TickCount; while (true) { if (m_bXrayDone) { currentCommand.returnType = true; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * 6) { currentCommand.returnType = false; break; } } } catch (InvalidSettingsException invalidSettingsException) { string msg = string.Format(@"Invalid Settings Exception:{0}, {1}", invalidSettingsException.Message, invalidSettingsException.ValidationResults.ValidationErrors); log.Error(msg); } catch (AcquisitionStartException acquisitionStartException) { string msg = string.Format(@"Acquisition Start Exception:{0}", acquisitionStartException.Message); log.Error(msg); } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool XrayPointCollecting(ref PointXrayParam p) { currentCommand.pointXrayPrm = p; currentCommand.commandType = OxfordCommandType.XrayPointCollection; m_bXrayDone = false; p.XrayData = new uint[XRayChannelLength]; p.listElement = new Dictionary(); SetXrayAcquisitionParam(p.dMilliSecondsTime); EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreatePointRegion(new System.Windows.Point(p.x * m_dImagePixelsize, p.y * m_dImagePixelsize)); EdSpectrumAcquisitionController.BeginMultipleAcquisition(); try { m_bXrayDone = false; IEdSpectrum edSpectrum = EdSpectrumAcquisitionController.StartAcquisition(EdSpectrumSettings); var time1 = Environment.TickCount; while (true) { if (m_bXrayDone) { currentCommand.returnType = true; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * 6) { EdSpectrumAcquisitionController.EndMultipleAcquisition(); log.Warn("XrayStartAcquisition 超时!"); currentCommand.returnType = false; } } } catch (InvalidSettingsException invalidSettingsException) { string msg = string.Format(@"Invalid Settings Exception:{0}, {1}", invalidSettingsException.Message, invalidSettingsException.ValidationResults.ValidationErrors); log.Error(msg); } catch (AcquisitionStartException acquisitionStartException) { string msg = string.Format(@"Acquisition Start Exception:{0}", acquisitionStartException.Message); log.Error(msg); } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool CollectXrayByPoints(ref List a_listPoints, uint a_nXRayAQTime, bool a_bElementInfo) { int nSize = a_listPoints.Count; List singleGroup = new List(); int nTimes = nSize / XrayQuantityLimitPerTime; for (int i = 0; i < nTimes; i++) { singleGroup.Clear(); for (int m = 0; m < XrayQuantityLimitPerTime; m++) { singleGroup.Add(a_listPoints[i * XrayQuantityLimitPerTime + m]); } if (!CollectXrayByPointsOnHardwareLimit(ref singleGroup, a_nXRayAQTime, a_bElementInfo)) { return false; } } int nLast = nSize % XrayQuantityLimitPerTime; if (nLast != 0) { singleGroup.Clear(); for (int m = 0; m < nLast; m++) { singleGroup.Add(a_listPoints[m]); } if (!CollectXrayByPointsOnHardwareLimit(ref singleGroup, a_nXRayAQTime, a_bElementInfo)) { return false; } } return true; } public bool CollectXrayByPointsOnHardwareLimit(ref List a_listPoints, uint a_nXRayAQTime, bool a_bElementInfo) { if (a_listPoints.Count > XrayQuantityLimitPerTime) { return false; } currentCommand.XrayPrmForPoints = a_listPoints; currentCommand.commandType = OxfordCommandType.COLLECT_XRAYPOINTS; //log.Info("线程:开始采集多点xray"); var PointXrayDatas = currentCommand.XrayPrmForPoints; currentCommand.PointXrayDataReceived = 0; m_bXrayDone = false; var dMilliSecondsTime = PointXrayDatas[0].dMilliSecondsTime; SetXrayAcquisitionParam(dMilliSecondsTime); EdSpectrumAcquisitionController.BeginMultipleAcquisition(); foreach (var prm in PointXrayDatas) { prm.b_quant = a_bElementInfo; EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreatePointRegion(new System.Windows.Point(prm.x * m_dImagePixelsize, prm.y * m_dImagePixelsize)); try { m_bXrayDone = false; IEdSpectrum edSpectrum = EdSpectrumAcquisitionController.StartAcquisition(EdSpectrumSettings); } catch (InvalidSettingsException invalidSettingsException) { string msg = string.Format(@"Invalid Settings Exception:{0}, {1}", invalidSettingsException.Message, invalidSettingsException.ValidationResults.ValidationErrors); log.Error(msg); } catch (AcquisitionStartException acquisitionStartException) { string msg = string.Format(@"Acquisition Start Exception:{0}", acquisitionStartException.Message); log.Error(msg); } } var time1 = Environment.TickCount; while (true) { if (m_bXrayDone) { currentCommand.returnType = true; EdSpectrumAcquisitionController.EndMultipleAcquisition(); break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * PointXrayDatas.Count) { EdSpectrumAcquisitionController.EndMultipleAcquisition(); currentCommand.returnType = false; } } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool CollectXrayByFeatures(ref List a_listFeatures, double a_nXRayAQTime, bool a_bElementInfo) { int nSize = a_listFeatures.Count; List singleGroup = new List(); int nTimes = nSize / XrayQuantityLimitPerTime; for (int i = 0; i < nTimes; i++) { singleGroup.Clear(); for (int m = 0; m < XrayQuantityLimitPerTime; m++) { singleGroup.Add(a_listFeatures[i * XrayQuantityLimitPerTime + m]); } if (!CollectXrayByFeaturesOnHardwareLimit(ref singleGroup, a_nXRayAQTime, a_bElementInfo)) { return false; } } int nLast = nSize % XrayQuantityLimitPerTime; if (nLast != 0) { singleGroup.Clear(); for (int m = 0; m < nLast; m++) { singleGroup.Add(a_listFeatures[m]); } if (!CollectXrayByFeaturesOnHardwareLimit(ref singleGroup, a_nXRayAQTime, a_bElementInfo)) { return false; } } return true; } public bool CollectXrayByFeaturesOnHardwareLimit(ref List a_listFeatures, double a_nXRayAQTime, bool a_bElementInfo) { if (a_listFeatures.Count > XrayQuantityLimitPerTime) { return false; } currentCommand.XrayPrmForFeatures = a_listFeatures; currentCommand.commandType = OxfordCommandType.COLLECT_XRAYFEATURES; var p = currentCommand.XrayPrmForFeatures; currentCommand.AreaXrayDataReceived = 0; m_bXrayDone = false; var dMilliSecondsTime = p[0].dMilliSecondsTime; SetXrayAcquisitionParam(p[0].dMilliSecondsTime); EdSpectrumAcquisitionController.BeginMultipleAcquisition(); foreach (var prm in p) { prm.b_quant = a_bElementInfo; List Chords = new List(); Chord chord; foreach (Segment seg in prm.a_listChord) { if (seg.Length >= 3) { chord = new Chord(seg.X + 1, seg.Y, seg.Length - 2);//get the middle part } else { chord = new Chord(seg.X, seg.Y, seg.Length); } Chords.Add(chord); } var chordsList = new ChordList(Chords, m_dImagePixelsize); EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreateChordListRegion(chordsList); try { m_bXrayDone = false; IEdSpectrum edSpectrum = EdSpectrumAcquisitionController.StartAcquisition(EdSpectrumSettings); } catch (InvalidSettingsException invalidSettingsException) { string msg = string.Format(@"Invalid Settings Exception:{0}, {1}", invalidSettingsException.Message, invalidSettingsException.ValidationResults.ValidationErrors); log.Error(msg); } catch (AcquisitionStartException acquisitionStartException) { string msg = string.Format(@"Acquisition Start Exception:{0}", acquisitionStartException.Message); log.Error(msg); } } var time1 = Environment.TickCount; while (true) { if (m_bXrayDone) { currentCommand.returnType = true; EdSpectrumAcquisitionController.EndMultipleAcquisition(); break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * p.Count) { EdSpectrumAcquisitionController.EndMultipleAcquisition(); currentCommand.returnType = false; break; } } if (currentCommand.returnType == true) { a_listFeatures = currentCommand.XrayPrmForFeatures; return true; } else { return false; } } //控制电镜初始化 void InitMicroscopeController() { this.microscopeController = AcquireFactory.CreateMicroscopeControl(); this.microscopeController.ColumnChange += this.OnMicroscopeColumnChange; this.microscopeController.StageChange += this.OnMicroscopeStageChange; this.microscopeController.ColumnConnected += this.OnMicroscopeColumnConnected; this.microscopeController.StageConnected += this.OnMicroscopeStageConnected; this.microscopeController.ChangeCompleted += this.OnMicroscopeChangeCompleted; //ReadMicroscopeColumn(); //ReadStage(); } //控制电镜释放 void CloseMicroscopeController() { if (microscopeController != null) { this.microscopeController.ColumnChange -= this.OnMicroscopeColumnChange; this.microscopeController.StageChange -= this.OnMicroscopeStageChange; this.microscopeController.ColumnConnected -= this.OnMicroscopeColumnConnected; this.microscopeController.StageConnected -= this.OnMicroscopeStageConnected; this.microscopeController.ChangeCompleted -= this.OnMicroscopeChangeCompleted; microscopeController = null; } } //读取当前的电镜控制值 private void ReadMicroscopeColumn() { var columnCapabilities = this.microscopeController.ColumnCapabilities; var columnConditions = this.microscopeController.ColumnConditions; if (columnCapabilities.Magnification.CanRead) { m_dMagnification = columnConditions.Magnification; } if (columnCapabilities.WorkingDistance.CanRead) { m_dWorkingDistance = columnConditions.WorkingDistance; } if (columnCapabilities.HighVoltage.CanRead) { m_dHighVoltage = columnConditions.HighVoltage; } if (columnCapabilities.Brightness.CanRead) { m_dBirghtness = columnConditions.Brightness; } if (columnCapabilities.Contrast.CanRead) { m_dContrast = columnConditions.Contrast; } if (columnCapabilities.BeamOn.CanRead) { m_bBeamOn = Convert.ToBoolean(columnConditions.BeamOn); } if (columnCapabilities.FilamentOn.CanRead) { m_bFilamentOn = Convert.ToBoolean(columnConditions.FilamentOn); } } //读取样品台位置 private void ReadStage() { var stageCapabilities = this.microscopeController.StageCapabilities; var stageConditions = this.microscopeController.StageConditions; while (!stageCapabilities.StageX.CanRead) { Thread.Sleep(100); } if (stageCapabilities.StageX.CanRead) { this.m_dStageX = stageConditions.StageX * 1000.0; } if (stageCapabilities.StageY.CanRead) { this.m_dStageY = stageConditions.StageY * 1000.0; } if (stageCapabilities.StageZ.CanRead) { this.m_dStageZ = stageConditions.StageZ; } if (stageCapabilities.StageT.CanRead) { this.m_dStageT = stageConditions.StageT; } if (stageCapabilities.StageR.CanRead) { this.m_dStageR = stageConditions.StageR; } } //电镜控制改变事件 private void OnMicroscopeColumnChange(object sender, EventArgs e) { ReadMicroscopeColumn(); } //样品台控制改变事件 private void OnMicroscopeStageChange(object sender, EventArgs e) { ReadStage(); } //镜筒控制连接或断开时的事件 private void OnMicroscopeColumnConnected(object sender, EventArgs e) { ReadMicroscopeColumn(); } //样品台控制连接或断开时的事件 private void OnMicroscopeStageConnected(object sender, EventArgs e) { ReadStage(); } //样品台控制、电镜控制、外围控制的事件改变完成 private void OnMicroscopeChangeCompleted(object sender, CompletedEventArgs e) { if (e.Control == MicroscopeControlType.Stage) { if (e.Success) { m_StageUpdated = true; } } else if (e.Control == MicroscopeControlType.Column) { if (e.Success) { m_CollumnUpdated = true; } } else if (e.Control == MicroscopeControlType.ExternalScan) { if (e.Success) { m_ExternalScanUpdated = true; } } ReadMicroscopeColumn(); ReadStage(); } bool ifMagRead=false; public float GetMagnification() { ReadMicroscopeColumn(); if (m_dMagnification != 0) { ifMagRead=true; } return (float)m_dMagnification; } public Boolean SetMagnification(float set) { if (!ifMagRead) { return false; } Dictionary columnDictionary = new Dictionary { { Column.Magnification, (double)set } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 10000) { currentCommand.returnType = false; return false; } } return true; } bool ifwdread = false; //焦距 public float GetWorkingDistance() { ReadMicroscopeColumn(); if (m_dWorkingDistance != 0) { bool ifwdread = true; } return (float)m_dWorkingDistance; } public Boolean SetWorkingDistance(float set) { if (!ifwdread) { return false; } Dictionary columnDictionary = new Dictionary { { Column.WorkingDistance, (double)set } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 10000) { currentCommand.returnType = false; return false; } } return true; } bool ifBrightnessRead = false; //亮度 public float GetBrightness() { ReadMicroscopeColumn(); if (m_dBirghtness != 0) { ifBrightnessRead = true; } return (float)m_dBirghtness; } public Boolean SetBrightness(float set) { if (!ifBrightnessRead) { return false; } Dictionary columnDictionary = new Dictionary { { Column.Brightness, (double)set } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 2000) { currentCommand.returnType = false; return false; } } return true; } bool ifContrastRead = false; //对比度 public float GetContrast() { ReadMicroscopeColumn(); if (m_dContrast != 0) { ifContrastRead = true; } return (float)m_dContrast; } public Boolean SetContrast(float set) { if (!ifContrastRead) { return false; } Dictionary columnDictionary = new Dictionary { { Column.Contrast, (double)set } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 2000) { currentCommand.returnType = false; return false; //break; } } return true; } //SEM电压 public float GetSEMVoltage() { ReadMicroscopeColumn(); log.Warn(m_dHighVoltage); return (float)m_dHighVoltage; } public Boolean SetSEMVoltage(float set) { Dictionary columnDictionary = new Dictionary { { Column.HighVoltage, (double)set } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 10000) { currentCommand.returnType = false; return false; //break; } } return true; } public bool SetSemScanExternal(bool b) { m_ExternalScanUpdated = false; if (!b) { EndMultipleAquisition(); } this.microscopeController.SetExternalScan(b); int time1 = Environment.TickCount; int time2; while (!m_ExternalScanUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 2000) { currentCommand.returnType = false; return false; //break; } } return true; } //样品台 public float[] GetStagePosition() { ReadStage(); float[] ret = new float[5]; ret[0] = (float)m_dStageX; ret[1] = (float)m_dStageY; ret[2] = (float)m_dStageZ; ret[3] = (float)m_dStageT; ret[4] = (float)m_dStageR; return ret; } public Boolean SetStagePosition(float[] set) { double stageX = (double)set[0]; double stageY = (double)set[1]; double stageZ = (double)set[2]; double stageT = (double)set[3]; double stageR = (double)set[4]; var stageDictionary = new Dictionary { { Stage.StageX, (double)stageX/1000.0 }, { Stage.StageY, (double)stageY/1000.0 }, { Stage.StageZ, (double)stageZ }, { Stage.StageT, (double)stageT }, { Stage.StageR, (double)stageR } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; //break; } } return true; } public float GetStageAtX() { ReadStage(); return (float)m_dStageX; } public float GetStageAtY() { ReadStage(); return (float)m_dStageY; } public float GetStageAtZ() { ReadStage(); return (float)m_dStageZ; } public float GetStageAtT() { ReadStage(); return (float)m_dStageT; } public float GetStageAtR() { ReadStage(); return (float)m_dStageR; } public Boolean SetStageGotoX(float set) { double stageX = (double)set; var stageDictionary = new Dictionary { { Stage.StageX, (double)stageX/1000.0 } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; //break; } } return true; } public Boolean SetStageGotoY(float set) { double stageY = (double)set; var stageDictionary = new Dictionary { { Stage.StageY, (double)stageY/1000.0 } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; //break; } } return true; } public Boolean SetStageGotoZ(float set) { double stageZ = (double)set; var stageDictionary = new Dictionary { { Stage.StageZ, (double)stageZ } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; //break; } } return true; } public Boolean SetStageGotoT(float set) { double stageT = (double)set; var stageDictionary = new Dictionary { { Stage.StageT, (double)stageT } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; } } return true; } public Boolean SetStageGotoR(float set) { double stageR = (double)set; var stageDictionary = new Dictionary { { Stage.StageR, (double)stageR } }; m_StageUpdated = false; this.microscopeController.SetStageConditions(stageDictionary); int time1 = Environment.TickCount; int time2; while (!m_StageUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 20000) { currentCommand.returnType = false; return false; //break; } } return true; } #region 拍图 //图像扫描尺寸 public double[] ImageScanSize = { 32, 64, 128, 256, 512, 704, 768, 1408, 1024, 1536, 2048, 3072, 4096, 8192 }; public double GetDImagePixelsize() { return m_dImagePixelsize; } public void SetDImagePixelsize(double value) { m_dImagePixelsize = value; } void InitImageAcquisition() { imageAcquisitionController = AcquireFactory.CreateImageServer(); imageAcquisitionSettings = AcquireFactory.CreateImageSettings(); imageAcquisitionController.ExperimentStarted += this.OnImageExperimentStarted; imageAcquisitionController.ExperimentFinished += this.OnImageExperimentFinished; } void InitXrayAcquistion() { EdSpectrumSettings = AcquireFactory.CreateEdSpectrumSettings(); EdSpectrumAcquisitionController = AcquireFactory.CreateEdSpectrumServer(); EdSpectrumProcessing = ProcessingFactory.CreateSpectrumProcessing(); // Use the autoIdSettings to define elements that are known or elements that you want to exclude. They also list elements that cannot be identified autoIdSettings = ProcessingFactory.CreateAutoIdSettings(); quantSettings = ProcessingFactory.CreateSEMQuantSettings(); EdSpectrumAcquisitionController.ExperimentFinished += this.OnEdSpectrumExperimentFinished; //EdSpectrumAcquisitionController.ExperimentStarted += this.OnEdSpectrumExperimentStarted; } //控制电镜释放 void CloseImageAcquisition() { if (imageAcquisitionController != null) { imageAcquisitionController.ExperimentStarted -= this.OnImageExperimentStarted; imageAcquisitionController.ExperimentFinished -= this.OnImageExperimentFinished; imageAcquisitionController = null; } } void CloseXrayAcquistion() { if (EdSpectrumAcquisitionController != null) { EdSpectrumAcquisitionController.ExperimentFinished -= this.OnEdSpectrumExperimentFinished; //EdSpectrumAcquisitionController.ExperimentStarted -= this.OnEdSpectrumExperimentStarted; EdSpectrumAcquisitionController = null; } } /// /// OnImageExperimentStarted /// private void OnImageExperimentStarted(object sender, AcquisitionStartedEventArgs e) { NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); log.Info("拍图开始事件!"); } //int m_nState; /// /// OnImageExperimentFinished /// private void OnImageExperimentFinished(object sender, AcquisitionFinishedEventArgs e) { IElectronImage electronImage = e.Value[0]; if (!ReadImageData(electronImage, out m_ImageBit, out m_nImageWidth, out m_nImageHeight, out m_dImagePixelsize)) { NLog.LogManager.GetCurrentClassLogger().Error("图像采集完成,获取图像像素失败!"); } if (m_ImageBit != null && m_ImageBit.Length == m_nImageWidth * m_nImageHeight) { m_bAcquistionDone = true; } } bool ReadImageData(IElectronImage a_electronImage, out Byte[] a_pImageBits, out long a_nImageHeight, out long a_nImageWidth, out double a_nPixelSize) { a_nImageHeight = 0; a_nImageWidth = 0; a_nPixelSize = 0; a_pImageBits = null; if (a_electronImage == null) { return false; } a_nImageHeight = a_electronImage.Height; a_nImageWidth = a_electronImage.Width; a_nPixelSize = a_electronImage.PixelSize; int nBytesPerPixel = a_electronImage.BytesPerPixel; long nImageSize = a_nImageHeight * a_nImageWidth; long nBufferSize = nImageSize * nBytesPerPixel; Byte[] imageData = new Byte[nBufferSize]; a_electronImage.GetData(imageData); a_pImageBits = new Byte[nImageSize]; // default, oxford will return short image, we need to convert to byte if (nBytesPerPixel == 2) { int nBSEValue = 0; for (int i = 0; i < nImageSize; ++i) { nBSEValue = imageData[0 + i * nBytesPerPixel] + imageData[1 + i * nBytesPerPixel] * 255; a_pImageBits[i] = (Byte)(nBSEValue / 128.0 + 0.5); } } else { string msg = string.Format("image byte per pixel other than 2({0}), image convert may wrong", nBytesPerPixel); NLog.LogManager.GetCurrentClassLogger().Error(msg); int nOffset = nBytesPerPixel - 1; for (int i = 0; i < nImageSize; ++i) { a_pImageBits[i] = imageData[nOffset + i * nBytesPerPixel]; } } return true; } //a_dDwellTime : 1~100000之间的数 //a_sImageType : 1: SE, 2: Bse public bool SetImageAcquistionSetting(ImageAquistionParam p) { IImageSettings imageSettings = imageAcquisitionSettings.ImageSettings; IImageCapabilities imageCapabilities = imageAcquisitionSettings.ImageCapabilities; IImageScanSettings scanSettings = imageAcquisitionSettings.ScanSettings; if (p.DwellTime > imageCapabilities.MaximumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MaximumImageDwellMicroseconds; } if (p.DwellTime < imageCapabilities.MinimumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MinimumImageDwellMicroseconds; } else { imageSettings.DwellTimeMicroSeconds = p.DwellTime; } imageSettings.InputSources.ToList().ForEach(i => imageSettings.EnableInputSource(i.Key, false)); imageSettings.EnableInputSource((ImageInputSources)p.sourceType, true); if (!ImageScanSize.Contains(p.width)) { NLog.LogManager.GetCurrentClassLogger().Error("图像尺寸输入无效"); return false; } var pixelSize = 1d / p.width; if (p.regionType == ImageAquistionParam.ImageRegionType.FullField) { scanSettings.AcquisitionRegion.CreateFullFieldRegion(pixelSize); } else { scanSettings.AcquisitionRegion.CreateRectangleRegion(p.ImgRectRegion, pixelSize); } return true; } #endregion #region X-ray void SetXrayAcquisitionParam(double a_dMilliSecondsTime) { EdSpectrumSettings.EdSettings.AcquisitionMode = EdAcquireMode.LiveTime; // RealTime or LiveTime EdSpectrumSettings.EdSettings.AcquisitionTime = TimeSpan.FromMilliseconds(a_dMilliSecondsTime); EdSpectrumSettings.EdSettings.ProcessTime = 4; EdSpectrumSettings.EdSettings.EnergyRange = 20; EdSpectrumSettings.EdSettings.NumberOfChannels = 4096; } private bool GetAtomicNumberByEleName(string name, out int atomicNum) { var allelenames = theElementNameList.Split(','); for (int i = 0; i < allelenames.Length; i++) { if (allelenames[i] == name) { atomicNum = i + 1; return true; } } atomicNum = 0; return false; } /// /// Called when IEdSpectrumAcquisitionController Experiment Finished /// /// sender object /// The instance containing the event data. private void OnEdSpectrumExperimentFinished(object sender, AcquisitionFinishedEventArgs e) { IEdSpectrumAcquisitionController edSpectrumAcquisitionController = sender as IEdSpectrumAcquisitionController; uint[] m_XrayData; NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); IEdSpectrum edSpectrum = e.Value; if (!ReadXrayData(edSpectrum, out m_XrayData, XRayChannelLength)) { NLog.LogManager.GetCurrentClassLogger().Error("Xray采集完成,获取xray失败!"); } long nXraycount = 0; for (int i = 0; i < 2000; i++) { nXraycount += m_XrayData[i]; } //Quantify processing bool bquant = false; if (currentCommand.commandType == OxfordCommandType.XrayPointCollection) { bquant = currentCommand.pointXrayPrm.b_quant; } else if (currentCommand.commandType == OxfordCommandType.XrayAreaCollection) { bquant = currentCommand.areaXrayPrm.b_quant; } else if (currentCommand.commandType == OxfordCommandType.COLLECT_XRAYPOINTS) { var curXrayData = currentCommand.XrayPrmForPoints[currentCommand.PointXrayDataReceived]; bquant = curXrayData.b_quant; } else if (currentCommand.commandType == OxfordCommandType.COLLECT_XRAYFEATURES) { var curXrayData = currentCommand.XrayPrmForFeatures[currentCommand.AreaXrayDataReceived]; bquant = curXrayData.b_quant; } var m_listElement = new Dictionary(); if (bquant) { if (m_ifautoid == false) { log.Warn(autoIdSettings.KnownElements); autoIdSettings.ClearKnownElements(); //m_knownelements = "K,Ca,Sc,Ti,V,Mn,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr"; var knownelenames = m_knownelements.Split(','); foreach (var ele in knownelenames) { int atomicnum; if (GetAtomicNumberByEleName(ele, out atomicnum)) { autoIdSettings.SetKnownElement(atomicnum, true); } } log.Warn(autoIdSettings.KnownElements); } else { } EdSpectrumProcessing.IdentifyElements(e.Value, autoIdSettings); // While it is possible to choose other elements, Oxygen is the only supported element by stoichiometry. quantSettings.CombinedElement = 8; quantSettings.Normalised = true; ISEMQuantStatus quantStatus = EdSpectrumProcessing.SEMQuantifySpectrum(e.Value, quantSettings);//(a_nChannelData, OIHelper::SEMQuantSettings); IEnumerable Results = quantStatus.Results; var ie = Results.GetEnumerator(); while (ie.MoveNext()) { ISEMQuantResult result = ie.Current; if (result.WeightPercent != 0) { m_listElement.Add(ElementProperties.GetElementSymbol(result.AtomicNumber), result.WeightPercent); } } } //------------------------ if (m_XrayData != null && m_XrayData.Length == XRayChannelLength) { if (currentCommand.commandType == OxfordCommandType.XrayPointCollection) { currentCommand.pointXrayPrm.XrayData = m_XrayData; currentCommand.pointXrayPrm.listElement = m_listElement; m_bXrayDone = true; } else if (currentCommand.commandType == OxfordCommandType.XrayAreaCollection) { currentCommand.areaXrayPrm.XrayData = m_XrayData; currentCommand.areaXrayPrm.listElement = m_listElement; m_bXrayDone = true; } else if (currentCommand.commandType == OxfordCommandType.COLLECT_XRAYPOINTS) { var curXrayData = currentCommand.XrayPrmForPoints[currentCommand.PointXrayDataReceived]; curXrayData.XrayData = m_XrayData; curXrayData.listElement = m_listElement; currentCommand.PointXrayDataReceived += 1; if (currentCommand.PointXrayDataReceived == currentCommand.XrayPrmForPoints.Count) { m_bXrayDone = true; } } else if (currentCommand.commandType == OxfordCommandType.COLLECT_XRAYFEATURES) { var curXrayData = currentCommand.XrayPrmForFeatures[currentCommand.AreaXrayDataReceived]; curXrayData.XrayData = m_XrayData; curXrayData.listElement = m_listElement; currentCommand.AreaXrayDataReceived += 1; if (currentCommand.AreaXrayDataReceived == currentCommand.XrayPrmForFeatures.Count) { m_bXrayDone = true; } } } } bool ReadXrayData(IEdSpectrum a_spectrum, out uint[] a_pSpectrumData, int a_nBufferSize) { a_pSpectrumData = new uint[a_nBufferSize]; int[] xrayData = new int[a_spectrum.NumberOfChannels]; a_spectrum.GetChannelData(xrayData); double dZeroChannelValue = a_spectrum.ZeroChannelValue; int nChannelStart = 0; if (dZeroChannelValue < 0) // zero channel value should less than zero { nChannelStart = (int)(-dZeroChannelValue / a_spectrum.ChannelWidth + 0.5); } int nDataLength = (int)(a_spectrum.EnergyRange * 1000 / a_spectrum.ChannelWidth + 0.5); double dStep1 = 1.0 / nDataLength; double dStep2 = 1.0 / a_nBufferSize; for (int i = 0; i < nDataLength; ++i) { uint nValue = (uint)(xrayData[i + nChannelStart] > 0 ? xrayData[i + nChannelStart] : 0); double dBinPos = i * dStep1; long nLeftBin = (long)(dBinPos / dStep2); // calculate % into left bin double dLeft_Percent = (double)(nLeftBin + 1) - dBinPos / dStep2; // ((nLeftBin + 1)*dStep2 - dBinPos)/dStep2 // calculate data into the left bin uint nValueToLeftBin = (uint)((double)nValue * dLeft_Percent + 0.5); // put data into bins a_pSpectrumData[nLeftBin] += nValueToLeftBin; if ((nLeftBin + 1) < a_nBufferSize) { a_pSpectrumData[nLeftBin + 1] += (nValue - nValueToLeftBin); } } return true; } public bool IsAcquiringSpectrum() { return EdSpectrumAcquisitionController.IsAcquiring; } public void BeginMultipleAquisition() { EdSpectrumAcquisitionController.BeginMultipleAcquisition(); } public void EndMultipleAquisition() { EdSpectrumAcquisitionController.EndMultipleAcquisition(); } public bool GetSemBeamOn() { var beamon = microscopeController.ColumnConditions.BeamOn; if (beamon == 1) { return true; } else { return false; } } public bool SetSemBeamOnOrOff(bool val) { double beamon; if (val) { beamon = 1; } else { beamon = 0; } Dictionary columnDictionary = new Dictionary { { Column.BeamOn, (double)beamon } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 10000) { currentCommand.returnType = false; return false; } } return true; } public bool SetSemFilamentOnOrOff(bool val) { double beamon; if (val) { beamon = 1; } else { beamon = 0; } Dictionary columnDictionary = new Dictionary { { Column.FilamentOn, (double)beamon } }; m_CollumnUpdated = false; this.microscopeController.SetColumnConditions(columnDictionary); int time1 = Environment.TickCount; int time2; while (!m_CollumnUpdated) { Application.DoEvents(); time2 = Environment.TickCount; if (time2 - time1 > 10000) { currentCommand.returnType = false; return false; } } return true; } public void StopXrayAquisition() { EdSpectrumAcquisitionController.StopAcquisition(); } public void SetQuantifiCationParam(bool IfAutoId, string knownElements) { m_ifautoid = IfAutoId; m_knownelements = knownElements; } #endregion } }