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.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; namespace OxfordExtenderWrapper { public class ExtenderWrapper1:MarshalByRefObject { NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); private Thread controlThread; AutoResetEvent startEvent = new AutoResetEvent(false); AutoResetEvent endEvent = new AutoResetEvent(false); private oxfordCommandData currentCommand; #region 电镜控制、样品台 //控制电镜 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 OxfordControllerState m_nState; 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; //构造函数 public ExtenderWrapper1() { } public bool ConnectToEDSHardware() { try { InitMicroscopeController(); InitImageAcquisition(); InitXrayAcquistion(); controlThread = new Thread(this.ControlerThread); controlThread.Start(); return true; } catch (Exception e) { log.Error(e.Message); return false; } } //结束 public void CloseExtender() { CloseMicroscopeController(); CloseImageAcquisition(); CloaseXrayAcquistion(); currentCommand.commandType = OxfordCommandType.Exit; if (controlThread != null) { startEvent.Set(); controlThread.Join(); } controlThread = null; } private void ControlerThread() { while (true) { while (true) { if (startEvent.WaitOne(0, true)) { break; } Application.DoEvents(); } switch (currentCommand.commandType) { case OxfordCommandType.MoveStageXY: { MoveStageParam p = currentCommand.moveStagePrm; var stageDictionary = new Dictionary { { Stage.StageX, (double)p.x/1000.0 }, { Stage.StageY, (double)p.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 > 20000) { currentCommand.returnType = false; break; } } endEvent.Set(); } break; case OxfordCommandType.ImageAquisition: { ImageAquistionParam p = currentCommand.grabImgParam; SetImageAcquistionSetting(p.DwellTime, p.sourceType, p.width); try { int lastingTime = 0; m_bAcquistionDone = false; imageAcquisitionController.BeginMultipleAcquisition(); IEnumerable images = imageAcquisitionController.StartAcquisition(imageAcquisitionSettings); var time1 = Environment.TickCount; while (true) { if (m_bAcquistionDone) { p.ImageData = m_ImageBit; currentCommand.returnType = true; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * 6) { currentCommand.returnType = false; } } } 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); } endEvent.Set(); } break; case OxfordCommandType.XrayPointCollection: { PointXrayParam p = currentCommand.pointXrayPrm; 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)); NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); try { m_bXrayDone = false; var time1 = Environment.TickCount; IEdSpectrum edSpectrum = EdSpectrumAcquisitionController.StartAcquisition(EdSpectrumSettings); while (true) { if (m_bXrayDone) { currentCommand.returnType = true; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > EDSColletionTimeOut * 2) { 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); } endEvent.Set(); } break; case OxfordCommandType.COLLECT_XRAYPOINTS: { var p = currentCommand.XrayPrmForPoints; var PointXrayDatas = currentCommand.XrayPrmForPoints; currentCommand.PointXrayDataReceived = 0; m_bXrayDone = false; var dMilliSecondsTime = PointXrayDatas[0].dMilliSecondsTime; SetXrayAcquisitionParam(dMilliSecondsTime); foreach (var prm in PointXrayDatas) { EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreatePointRegion(new System.Windows.Point(prm.x * m_dImagePixelsize, prm.y * m_dImagePixelsize)); //log.Info("开始XrayStartAcquisition:t=" + dMilliSecondsTime.ToString() + "pos=" + "(" + prm.x.ToString() + "," + prm.y.ToString() + ")"); 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; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > PointXrayDatas[0].dMilliSecondsTime * 5* PointXrayDatas.Count) { EdSpectrumAcquisitionController.EndMultipleAcquisition(); log.Warn("XrayStartAcquisition 超时!"); currentCommand.returnType = false; } } endEvent.Set(); } break; case OxfordCommandType.XrayAreaCollection: { AreaXrayParam p = currentCommand.areaXrayPrm; 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); } SetAreaAcquistionRegion(Chords); try { int lastingTime = 0; 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 > p.dMilliSecondsTime * 10) { 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); } endEvent.Set(); } break; case OxfordCommandType.COLLECT_XRAYFEATURES: { var p = currentCommand.XrayPrmForFeatures; currentCommand.AreaXrayDataReceived = 0; m_bXrayDone = false; int lastingTime = 0; var dMilliSecondsTime = p[0].dMilliSecondsTime; SetXrayAcquisitionParam(p[0].dMilliSecondsTime); foreach (var prm in p) { List Chords = new List(); foreach (Segment seg in prm.a_listChord) { Chord chord = new Chord(seg.X, seg.Y, seg.Length); Chords.Add(chord); } SetAreaAcquistionRegion(Chords); 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; break; } Application.DoEvents(); var time2 = Environment.TickCount; if (time2 - time1 > p[0].dMilliSecondsTime * 5* p.Count) { EdSpectrumAcquisitionController.EndMultipleAcquisition(); log.Warn("XrayStartAcquisition 超时!"); //return false; currentCommand.returnType = false; } } endEvent.Set(); } break; case OxfordCommandType.Exit: { endEvent.Set(); log.Info("receive exit command"); } break; } if (currentCommand.commandType == OxfordCommandType.Exit) { log.Info("exiting the thread"); break; } } } 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); var time1 = Environment.TickCount; while (true) { if (m_bAcquistionDone) { p.ImageData = m_ImageBit; currentCommand.returnType = true; break; } Application.DoEvents(); //Thread.Sleep(100); var 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); } imageAcquisitionController.EndMultipleAcquisition(); 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; startEvent.Set(); while (true) { if (endEvent.WaitOne(0, false)) { break; } } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool XrayAreaCollecting(ref AreaXrayParam p) { currentCommand.areaXrayPrm = p; currentCommand.commandType = OxfordCommandType.XrayAreaCollection; startEvent.Set(); while (true) { if (endEvent.WaitOne(0, false)) { break; } } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool XrayPointCollecting(ref PointXrayParam p) { currentCommand.pointXrayPrm = p; currentCommand.commandType = OxfordCommandType.XrayPointCollection; startEvent.Set(); while (true) { if (endEvent.WaitOne(0, false)) { break; } Application.DoEvents(); } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool CollectXrayByPoints(ref List a_listPoints, uint a_nXRayAQTime, bool a_bElementInfo) { foreach (var prm in a_listPoints) { prm.b_quant = a_bElementInfo; prm.dMilliSecondsTime = a_nXRayAQTime; } currentCommand.XrayPrmForPoints = a_listPoints; currentCommand.commandType = OxfordCommandType.COLLECT_XRAYPOINTS; startEvent.Set(); while (true) { if (endEvent.WaitOne(0, false)) { break; } Application.DoEvents(); } if (currentCommand.returnType == true) { return true; } else { return false; } } public bool CollectXrayByFeatures(ref List a_listFeatures, double a_nXRayAQTime, bool a_bElementInfo) { foreach (var prm in a_listFeatures) { prm.b_quant = a_bElementInfo; prm.dMilliSecondsTime = a_nXRayAQTime; } currentCommand.XrayPrmForFeatures = a_listFeatures; currentCommand.commandType = OxfordCommandType.COLLECT_XRAYFEATURES; startEvent.Set(); while (true) { if (endEvent.WaitOne(0, false)) { break; } } if (currentCommand.returnType == true) { a_listFeatures = currentCommand.XrayPrmForFeatures; return true; } else { return false; } } internal oxfordCommandData GetCurrentCommand() { return currentCommand; } internal void SetCurrentCommand(oxfordCommandData value) { currentCommand = value; } //控制电镜初始化 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; 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() { return (float)m_dMagnification; } public Boolean SetMagnification(float set) { Dictionary columnDictionary = new Dictionary { { Column.Magnification, (double)set } }; this.microscopeController.SetColumnConditions(columnDictionary); return true; } //焦距 public float GetWorkingDistance() { return (float)m_dWorkingDistance; } public Boolean SetWorkingDistance(float set) { Dictionary columnDictionary = new Dictionary { { Column.WorkingDistance, (double)set } }; this.microscopeController.SetColumnConditions(columnDictionary); return true; } //亮度 public float GetBrightness() { return (float)m_dBirghtness; } public Boolean SetBrightness(float set) { Dictionary columnDictionary = new Dictionary { { Column.Brightness, (double)set } }; this.microscopeController.SetColumnConditions(columnDictionary); return true; } //对比度 public float GetContrast() { return (float)m_dContrast; } public Boolean SetContrast(float set) { Dictionary columnDictionary = new Dictionary { { Column.Contrast, (double)set } }; this.microscopeController.SetColumnConditions(columnDictionary); return true; } //SEM电压 public float GetSEMVoltage() { return (float)m_dHighVoltage; } public Boolean SetSEMVoltage(float set) { Dictionary columnDictionary = new Dictionary { { Column.HighVoltage, (double)set } }; this.microscopeController.SetColumnConditions(columnDictionary); return true; } public bool SetSemScanExternal(bool b) { this.microscopeController.SetExternalScan(b); return true; } //样品台 public float[] GetStagePosition() { 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 } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } public float GetStageAtX() { return (float)m_dStageX; } public float GetStageAtY() { return (float)m_dStageY; } public float GetStageAtZ() { return (float)m_dStageZ; } public float GetStageAtT() { return (float)m_dStageT; } public float GetStageAtR() { return (float)m_dStageR; } public Boolean SetStageGotoX(float set) { double stageX = (double)set; var stageDictionary = new Dictionary { { Stage.StageX, (double)stageX/1000.0 } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } public Boolean SetStageGotoY(float set) { double stageY = (double)set; var stageDictionary = new Dictionary { { Stage.StageY, (double)stageY/1000.0 } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } public Boolean SetStageGotoZ(float set) { double stageZ = (double)set; var stageDictionary = new Dictionary { { Stage.StageZ, (double)stageZ } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } public Boolean SetStageGotoT(float set) { double stageT = (double)set; var stageDictionary = new Dictionary { { Stage.StageT, (double)stageT } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } public Boolean SetStageGotoR(float set) { double stageR = (double)set; var stageDictionary = new Dictionary { { Stage.StageR, (double)stageR } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } private Boolean MoveStage(float x, float y) { double stageX = (double)x; double stageY = (double)y; var stageDictionary = new Dictionary { { Stage.StageX, (double)stageX }, { Stage.StageY, (double)stageY } }; this.microscopeController.SetStageConditions(stageDictionary); return true; } #endregion #region 拍图 //图像扫描尺寸 public double[] ImageScanSize = { 32, 64, 128, 256, 512, 704, 768, 1024, 4096, 8192 }; 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; private double dImagePixelsize; public double GetDImagePixelsize() { return m_dImagePixelsize; } internal void SetDImagePixelsize(double value) { m_dImagePixelsize = value; } //private Bitmap m_Bitmap = null; void InitImageAcquisition() { imageAcquisitionController = AcquireFactory.CreateImageServer(); imageAcquisitionSettings = AcquireFactory.CreateImageSettings(); //imageAcquisitionSettings. //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 CloaseXrayAcquistion() { 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, ImageInputSources 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; // EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreateFullFieldRegion(1.0 / 1024.0); } void SetAreaAcquistionRegion(List a_nChords) { ChordList chordsList = null; chordsList = new ChordList(a_nChords, m_dImagePixelsize); EdSpectrumSettings.ScanSettings.AcquisitionRegion.CreateChordListRegion(chordsList); } /// /// Called when IEdSpectrumAcquisitionController Experiment Starting. /// /// The sender. /// The instance containing the event data. private void OnEdSpectrumExperimentStarting(object sender, AcquisitionStartingEventArgs e) { } /// /// Called when IEdSpectrumAcquisitionController Experiment Started. /// /// The sender. /// The instance containing the event data. private void OnEdSpectrumExperimentStarted(object sender, AcquisitionStartedEventArgs e) { } private IEdChordListSettings GetChordlistSettings() { if (_edsChordListSetting == null) { _edsChordListSetting = AcquireFactory.CreateEdChordListSettings(); if (_edsChordListSetting != null) { _edsChordListSetting.EdSettings.AcquisitionMode = EdAcquireMode.LiveTime; _edsChordListSetting.EdSettings.NumberOfChannels = 1024; _edsChordListSetting.EdSettings.ProcessTime = g_nOxfordControllerProcessTime; _edsChordListSetting.EdSettings.EnergyRange = g_nOxfordControllerEnergyRange; _edsChordListSetting.AutoIdSettings.SetKnownElement(79, true); _edsChordListSetting.NumberOfProcessingThreads = 1; } else { NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); log.Error("Create EDS chordlist setting failed."); } } return _edsChordListSetting; } struct Element { public int m_nAotomaticNo; public double m_dWeight; } /// /// /// /// /// /// /// 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; } /// /// Called when IEdSpectrum DataChanged /// /// Event source /// Event arguments private void OnDataChanged(object sender, EventArgs e) { } public bool IsAcquiringSpectrum() { return EdSpectrumAcquisitionController.IsAcquiring; } public void BeginMultipleAquisition() { EdSpectrumAcquisitionController.BeginMultipleAcquisition(); } public void EndMultipleAquisition() { EdSpectrumAcquisitionController.EndMultipleAcquisition(); } //public void BeginAreaModeMultipleAquisition() //{ // var controller = CreateChordlistController(); // controller.BeginMultipleAcquisition(); //} //public void EndAreaModeMultipleAquisition() //{ // var controller = CreateChordlistController(); // controller.EndMultipleAcquisition(); //} public bool GetSemBeamOn() { var beamon = microscopeController.ColumnConditions.BeamOn; if (beamon == 1) { return true; } else { return false; } } public void StopXrayAquisition() { EdSpectrumAcquisitionController.StopAcquisition(); } #endregion } }