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.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 ImageAquistionParam() { this.ImageData = new byte[width * height]; } //in public int width; public int height; 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; private bool m_bXrayDone = false; //电压 private double m_dHighVoltage; //放大倍数 private double m_dMagnification; //工作距离 private double m_dWorkingDistance; //亮度 private double m_dBirghtness; //对比度 private double m_dContrast; //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; //构造函数 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.DwellTime, p.sourceType, p.width); 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) { //if ((m_dStageX - x < 0.001) && (m_dStageY - y < 0.001)) //{ // return true; //} 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) { 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) { 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(); foreach (Segment seg in prm.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); 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(); } public float GetMagnification() { ReadMicroscopeColumn(); return (float)m_dMagnification; } public Boolean SetMagnification(float set) { 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; } //焦距 public float GetWorkingDistance() { ReadMicroscopeColumn(); return (float)m_dWorkingDistance; } public Boolean SetWorkingDistance(float set) { 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; } //亮度 public float GetBrightness() { ReadMicroscopeColumn(); return (float)m_dBirghtness; } public Boolean SetBrightness(float set) { 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; } //对比度 public float GetContrast() { ReadMicroscopeColumn(); return (float)m_dContrast; } public Boolean SetContrast(float set) { 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(); 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, 1024, 2048, 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 //a_dImageScanSize : 图像分辨率,图像的高 public bool SetImageAcquistionSetting(double a_dDwellTime, ImageInputSourceType a_nImageType, double a_dImageScanSize) { IImageSettings imageSettings = imageAcquisitionSettings.ImageSettings; IImageCapabilities imageCapabilities = imageAcquisitionSettings.ImageCapabilities; IImageScanSettings scanSettings = imageAcquisitionSettings.ScanSettings; if (a_dDwellTime > imageCapabilities.MaximumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MaximumImageDwellMicroseconds; } if (a_dDwellTime < imageCapabilities.MinimumImageDwellMicroseconds) { imageSettings.DwellTimeMicroSeconds = imageCapabilities.MinimumImageDwellMicroseconds; } else { imageSettings.DwellTimeMicroSeconds = a_dDwellTime; } imageSettings.InputSources.ToList().ForEach(i => imageSettings.EnableInputSource(i.Key, false)); imageSettings.EnableInputSource((ImageInputSources)a_nImageType, true); if (!ImageScanSize.Contains(a_dImageScanSize)) { NLog.LogManager.GetCurrentClassLogger().Error("图像尺寸输入无效"); return false; } var pixelSize = 1d / a_dImageScanSize; scanSettings.AcquisitionRegion.CreateFullFieldRegion(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; } /// /// 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) { 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 void StopXrayAquisition() { EdSpectrumAcquisitionController.StopAcquisition(); } #endregion } }