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
}
}