#include "stdafx.h"
#include "OxfordControllerWrapper.h"
#include "tinyxml2.h"
#include "XMLSerialization.h"
#include "COTSUtilityDllFunExport.h"
using namespace System;
using namespace System::Windows;
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
using namespace System::Collections::Specialized;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Threading;
///
/// The oxford controller channels.
/// Always collect xray by this channels.
///
const int g_nOxfordControllerChannels = 4096; // use 2k to collect xray spectrum
const int g_nOxfordControllerProcessTime = 4;
const int g_nOxfordControllerEnergyRange = 20;
const int g_nOxfordControllerEventWaitTimerInt = 100;
const int g_nOxfordControllerEventSleepTimerInt = 100;
const long g_nMicrocopeConnectTimeOutMilliSeconds = 2000;
// Oxford single point delay time(ms)
const long g_nSinglePointCollectDelay = 3000;
const long g_nSingleFeatureCollectDelay = 5000;
const long g_nXrayControllerConnectTimeOutMilliSeconds =20000;
const long g_nImageTimeOutMilliSeconds = 40000;
const long g_nStageTimeOutMilliSeconds = 40000;
OxfordControllerWrapper::OxfordControllerWrapper(void)
: m_bIsStageUpdated(false)
, m_bBeamPositionSet(false)
{
//_dataType = ImageDataType::DataByte;
m_startControllerEvent = gcnew AutoResetEvent(false);
m_endControllerEvent = gcnew AutoResetEvent(false);
}
void OxfordControllerWrapper::CloseClient(void)
{
if (_controllerThread && _controllerThread->IsAlive)
{
}
_controllerThread->Abort();
//_controllerThread = nullptr;
_microscopeController = nullptr;
_edSpectrumController = nullptr;
_imageAcqusitionController = nullptr;
_edsChordListController = nullptr;
_SEMQuantController = nullptr;
}
OxfordControllerWrapper::~OxfordControllerWrapper(void)
{
if (_controllerThread && _controllerThread->IsAlive)
{
}
CloseClient();
}
OxfordControllerWrapper::!OxfordControllerWrapper(void)
{
if (_controllerThread && _controllerThread->IsAlive)
{
}
CloseClient();
}
bool OxfordControllerWrapper::Init()
{
if (_controllerThread != nullptr && _controllerThread->IsAlive)
{
return true;
}
_controllerThread = gcnew Thread(gcnew ThreadStart(this, &OxfordControllerWrapper::ControllerThreadFunction));
m_startControllerEvent->Reset();
m_endControllerEvent->Reset();
_controllerThread->Start();
return true;
}
void OxfordControllerWrapper::ControllerThreadFunction()
{
if (_microscopeController == nullptr)
{
auto ctrl=CreateMicroscopeController();
if (ctrl == nullptr) return;
}
if (_edSpectrumController == nullptr)
{
CreateEdsSpectrumController();
}
if (_imageAcqusitionController == nullptr)
{
CreateImageAcqusitionController();
}
if (_edsChordListController == nullptr)
{
CreateChordlistController();
}
while (true)
{
while (true)
{
if (m_startControllerEvent->WaitOne(0, true))
{
m_startControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
}
switch (_oxfordControllerData.m_nCommand)
{
case OxfordControllerCommand::COLLECT_IMAGE:
{
if (!StartImageCollecting())
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
}
}
break;
case OxfordControllerCommand::COLLECT_XRAYPOINT:
{
auto edsController = CreateEdsSpectrumController();
bool bRet = false;
if (edsController && _oxfordControllerData.m_pSpectrumData)
{
edsController->BeginMultipleAcquisition();
LogTrace(__FILE__,__LINE__,_T("BeginMultipleAcquisition...(single point)"));
if (SetBeamPosition(_oxfordControllerData.m_dBeamPositionX, _oxfordControllerData.m_dBeamPositionY))
{
bRet = StartXrayCollecting(_oxfordControllerData.m_nAcTime);
}
}
if (!bRet)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
}
}
break;
case OxfordControllerCommand::COLLECT_CURRENTXRAYPOINT:
{
auto edsController = CreateEdsSpectrumController();
bool bRet = false;
if (edsController && _oxfordControllerData.m_pSpectrumData)
{
edsController->BeginMultipleAcquisition();
if (m_bBeamPositionSet)
{
m_bBeamPositionSet = false;
bRet = true;
Point pos(_oxfordControllerData.m_dBeamPositionX * _oxfordControllerData.m_dPixelSize, _oxfordControllerData.m_dBeamPositionY * _oxfordControllerData.m_dPixelSize);
auto edsSettings = GetEdsSpectrumSettings();
edsSettings->ScanSettings->AcquisitionRegion->CreatePointRegion(pos);
}
else
{
bRet = SetCurrentBeamPosition();
}
if (bRet)
{
bRet = StartXrayCollecting(_oxfordControllerData.m_nAcTime);
}
}
if (!bRet)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
}
}
break;
case OxfordControllerCommand::COLLECT_XRAYPOINTS:
{
auto edsController = CreateEdsSpectrumController();
if (!edsController || !_oxfordControllerData.m_pXrayDataList || _oxfordControllerData.m_nXrayDataCount <= 0)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
auto edsSettings = GetEdsSpectrumSettings();
_oxfordControllerData.m_nCollectedXrayCounts = 0;
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
edsController->BeginMultipleAcquisition();
for (int i = 0; i < _oxfordControllerData.m_nXrayDataCount; ++i)
{
OxfordXrayData* pXrayData = &_oxfordControllerData.m_pXrayDataList[i];
// Accept pixel position to convert to oxford normalized beam position
Point pos(pXrayData->m_nPosX * _oxfordControllerData.m_dPixelSize, pXrayData->m_nPosY * _oxfordControllerData.m_dPixelSize);
edsSettings->EdSettings->AcquisitionMode = (EdAcquireMode)2;
edsSettings->EdSettings->AcquisitionTime = TimeSpan::FromMilliseconds(_oxfordControllerData.m_nAcTime);
edsSettings->EdSettings->ProcessTime = 5;
/*edsSettings->EdSettings->EnergyRange = 100;
edsSettings->EdSettings->NumberOfChannels = 1;*/
edsSettings->ScanSettings->AcquisitionRegion->CreatePointRegion(pos);
edsController->StartAcquisition(edsSettings);
}
}
}
break;
case OxfordControllerCommand::COLLECT_XRAYCHOILDLIST:
{
auto edsController = CreateEdsSpectrumController();
if (!edsController || !_oxfordControllerData.m_pXrayDataList || _oxfordControllerData.m_nXrayDataCount <= 0)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
auto edsSettings = GetEdsSpectrumSettings();
_oxfordControllerData.m_nCollectedXrayCounts = 0;
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
edsController->BeginMultipleAcquisition();
_oxfordControllerData.m_nCollectedXrayCounts = 0;
for (int i = 0; i < _oxfordControllerData.m_nXrayDataCount; i++)
{
List< OINA::Extender::Data::Chord^>^ chords = gcnew List();
for (int j = 0; j < _oxfordControllerData.m_pXrayDataList[i].m_nChordNum; j++)
{
int X = _oxfordControllerData.m_pXrayDataList[i].m_ChordList[j].m_nX;
int Y = _oxfordControllerData.m_pXrayDataList[i].m_ChordList[j].m_nY;
int XLength = _oxfordControllerData.m_pXrayDataList[i].m_ChordList[j].m_nLength;
OINA::Extender::Data::Chord^ chord = gcnew OINA::Extender::Data::Chord(X, Y, XLength);
chords->Add(chord);
}
OINA::Extender::Data::ChordList^ chordsList = gcnew OINA::Extender::Data::ChordList(chords, _oxfordControllerData.m_dPixelSize);//1/1024.0
edsSettings->ScanSettings->AcquisitionRegion->CreateChordListRegion(chordsList);
edsSettings->EdSettings->AcquisitionTime = TimeSpan::FromMilliseconds(_oxfordControllerData.m_nAcTime);
edsController->StartAcquisition(edsSettings);
}
}
}
break;
case OxfordControllerCommand::COLLECT_QUANTIFYSPECTRUM:
if (!StartImageCollecting())
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::WORKING;
}
break;
case OxfordControllerCommand::SET_POSITIONXY:
{
if (SetPositionXYToController(_oxfordControllerData.m_dPositionX, _oxfordControllerData.m_dPositionY))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
long nCollectedTime = 0;
while (!m_bIsStageUpdated)
{
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
nCollectedTime += g_nOxfordControllerEventSleepTimerInt;
if (nCollectedTime > g_nStageTimeOutMilliSeconds)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
break;
}
}
Thread::Sleep(500);
m_endControllerEvent->Set();
}
break;
case OxfordControllerCommand::STOP_ACQUISITION:
{
auto edsController = CreateEdsSpectrumController();
while (edsController->IsAcquiring)
{
edsController->StopAcquisition();
}
}
break;
case OxfordControllerCommand::END_MULTIPLEACQUISITION:
{
auto edsController = CreateEdsSpectrumController();
while (edsController->IsAcquiring)
{
edsController->StopAcquisition();
}
edsController->EndMultipleAcquisition();
}
break;
}
}
}
bool OxfordControllerWrapper::IsConnected()
{
if (IsMicroscopeColumnConnected()
&& IsMicroscopeStageConnected())
{
return true;
}
else
{
return false;
}
}
bool OxfordControllerWrapper::IsMicroscopeColumnConnected()
{
auto microscopeController = this->CreateMicroscopeController();
if (microscopeController != nullptr)
{
return microscopeController->ColumnConnectionStatus->IsConnected;
}
return false;
}
bool OxfordControllerWrapper::IsMicroscopeStageConnected()
{
auto microscopeController = this->CreateMicroscopeController();
if (microscopeController != nullptr)
{
return microscopeController->StageConnectionStatus->IsConnected;
}
return false;
}
IStageConditions^ OxfordControllerWrapper::GetStageConditions()
{
if (!IsMicroscopeStageConnected())
{
return nullptr;
}
return _microscopeController->StageConditions;
}
bool OxfordControllerWrapper::GetPositionXY(double& a_dPosX, double& a_dPosY)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_POSITIONXY;
double dX, dY;
if (GetPositionXYFromController(dX, dY))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
_oxfordControllerData.m_dPositionX = dX;
_oxfordControllerData.m_dPositionY = dY;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_dPosX = _oxfordControllerData.m_dPositionX;
a_dPosY = _oxfordControllerData.m_dPositionY;
return true;
}
return false;
}
///
/// Get position xy from controller
///
/// The double of position x.
/// The double of position y.
///
/// Return the position xy from controller
///
bool OxfordControllerWrapper::GetPositionXYFromController(double& a_dPosX, double& a_dPosY)
{
if (!IsMicroscopeStageConnected())
{
return false;
}
while(!_microscopeController->StageCapabilities->StageX->CanRead)
{
Sleep(100);
}
a_dPosX = _microscopeController->StageConditions->StageX * 1000.0;
while(!_microscopeController->StageCapabilities->StageY->CanRead)
{
Sleep(100);
}
a_dPosY = _microscopeController->StageConditions->StageY * 1000.0;
return true;
}
///
/// Set the position xy
///
/// The double of position x.
/// The double of position y.
/// TRUE if success, otherwise FALSE
bool OxfordControllerWrapper::SetPositionXY(const double a_dPosX, const double a_dPosY)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_POSITIONXY;
_oxfordControllerData.m_dPositionX = a_dPosX;
_oxfordControllerData.m_dPositionY = a_dPosY;
m_bIsStageUpdated = false;
m_startControllerEvent->Set();
long nCollectedTime = 0;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
else
{
return false;
}
}
bool OxfordControllerWrapper::SetPositionXYToController(const double a_dPosX, const double a_dPosY)
{
if (!IsMicroscopeStageConnected())
{
return false;
}
Dictionary^ stageDictionary = gcnew Dictionary;
stageDictionary->Add(Stage::StageX, a_dPosX / 1000.0);
stageDictionary->Add(Stage::StageY, a_dPosY / 1000.0);
_microscopeController->SetStageConditions(stageDictionary);
return true;
}
bool OxfordControllerWrapper::GetWorkingDistance(double& a_dWorkingDistance)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_WORKINGDISTANCE;
double dWD = 0;
if (GetWorkingDistanceFromController(dWD))
{
_oxfordControllerData.m_dWorkingDistance = dWD;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_dWorkingDistance = _oxfordControllerData.m_dWorkingDistance;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetWorkingDistanceFromController(double& a_dWorkingDistance)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
a_dWorkingDistance = _microscopeController->ColumnConditions->WorkingDistance;
return true;
}
bool OxfordControllerWrapper::SetWorkingDistance(double a_dWorkingDistance)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_WORKINGDISTANCE;
_oxfordControllerData.m_dWorkingDistance = a_dWorkingDistance;
if (SetWorkingDistanceToController(_oxfordControllerData.m_dWorkingDistance))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetWorkingDistanceToController(double a_dWorkingDistance)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
Dictionary^ columnDictionary = gcnew Dictionary;
columnDictionary->Add(Column::WorkingDistance, a_dWorkingDistance);
_microscopeController->SetColumnConditions(columnDictionary);
return true;
}
bool OxfordControllerWrapper::GetMagnification(double& a_dMagnification)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_MAGNIFICATION;
double dMag = 0;
if (GetMagnificationFromController(dMag))
{
_oxfordControllerData.m_dMagnification = dMag;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_dMagnification = _oxfordControllerData.m_dMagnification;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetMagnificationFromController(double& a_dMagnification)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
a_dMagnification = _microscopeController->ColumnConditions->Magnification;
return true;
}
bool OxfordControllerWrapper::SetMagnification(double a_dMagnification)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_MAGNIFICATION;
_oxfordControllerData.m_dMagnification = a_dMagnification;
if (SetMagnificationToController(_oxfordControllerData.m_dMagnification))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetMagnificationToController(double a_dMagnification)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
Dictionary^ columnDictionary = gcnew Dictionary;
columnDictionary->Add(Column::Magnification, a_dMagnification);
_microscopeController->SetColumnConditions(columnDictionary);
return true;
}
bool OxfordControllerWrapper::GetHighVoltage(double& a_dHighVoltage)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_HIGHVOTAGE;
double dValue = 0;
if (GetHighVoltageFromController(dValue))
{
_oxfordControllerData.m_dHighVotage = dValue;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_dHighVoltage = _oxfordControllerData.m_dHighVotage;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetHighVoltageFromController(double& a_dHighVoltage)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
a_dHighVoltage = _microscopeController->ColumnConditions->HighVoltage;
return true;
}
bool OxfordControllerWrapper::SetHighVoltage(double a_dHighVoltage)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_HIGHVOTAGE;
_oxfordControllerData.m_dHighVotage = a_dHighVoltage;
if (SetHighVoltageToController(_oxfordControllerData.m_dHighVotage))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetHighVoltageToController(double a_dHighVoltage)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
Dictionary^ columnDictionary = gcnew Dictionary;
columnDictionary->Add(Column::HighVoltage, a_dHighVoltage);
_microscopeController->SetColumnConditions(columnDictionary);
return true;
}
bool OxfordControllerWrapper::GetBeamOn(bool& a_bBeamOn)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_BEAMON;
//m_startControllerEvent->Set();
bool bValue;
if (GetBeamOnFromController(bValue))
{
_oxfordControllerData.m_bBeamOn = bValue;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_bBeamOn = _oxfordControllerData.m_bBeamOn;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetBeamOnFromController(bool& a_bBeamOn)
{
if (!IsMicroscopeColumnConnected())
{
return false;
}
double dValue = _microscopeController->ColumnConditions->BeamOn;
// notice: false: 0.0 and true: 1.0
a_bBeamOn = dValue > 0.1;
return true;
}
bool OxfordControllerWrapper::SetBeamOn(bool a_bBeamOn)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_BEAMON;
_oxfordControllerData.m_bBeamOn = a_bBeamOn;
if (SetBeamOnToController(_oxfordControllerData.m_bBeamOn))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetBeamOnToController(bool a_bBeamOn)
{
if (!IsConnected())
{
return false;
}
(void)a_bBeamOn;
//// notice: false: 0.0 and true: 1.0
//double dValue = a_bBeamOn? 1.0: 0.0;
//Dictionary^ columnDictionary = gcnew Dictionary;
//columnDictionary->Add(Column::BeamOn, dValue);
//_microscopeController->SetColumnConditions(columnDictionary);
return true;
}
bool OxfordControllerWrapper::GetBeamBlank(bool& a_bBeamBlank)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_BEAMBLANK;
bool bValue;
if (GetBeamBlankFromController(bValue))
{
_oxfordControllerData.m_bBeamBlank = bValue;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_bBeamBlank = _oxfordControllerData.m_bBeamBlank;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetBeamBlankFromController(bool& a_bBeamBlank)
{
if (!IsConnected())
{
return false;
}
// todo: get beam blank
a_bBeamBlank = true;
return true;
}
bool OxfordControllerWrapper::SetBeamBlank(bool a_bBeamBlank)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_BEAMBLANK;
_oxfordControllerData.m_bBeamBlank = a_bBeamBlank;
if (SetBeamBlankToController(_oxfordControllerData.m_bBeamBlank))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetBeamBlankToController(bool a_bBeamBlank)
{
if (!IsConnected())
{
return false;
}
// todo: set beam blank
(void)a_bBeamBlank;
//try
//{
// _microscopeController->ColumnConditions->BeamBlank = a_bBeamBlank;
//}
//catch(...)
//{
//}
return true;
}
bool OxfordControllerWrapper::GetExternalScan(bool& a_bExternal)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::GET_EXTERNAL;
bool bValue;
if (GetExternalScanFromController(bValue))
{
_oxfordControllerData.m_bExternal = bValue;
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
a_bExternal = _oxfordControllerData.m_bExternal;
return true;
}
return false;
}
bool OxfordControllerWrapper::GetExternalScanFromController(bool& a_bExternal)
{
if (!IsConnected())
{
return false;
}
a_bExternal = _microscopeController->IsInExternalScan;
return true;
}
bool OxfordControllerWrapper::SetExternalScan(bool a_bExternal)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::SET_EXTERNAL;
_oxfordControllerData.m_bExternal = a_bExternal;
if (SetExternalScanToController(_oxfordControllerData.m_bExternal))
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::SetExternalScanToController(bool a_bExternal)
{
if (!IsConnected())
{
return false;
}
_microscopeController->SetExternalScan(a_bExternal);
return true;
}
///
/// Set the beam position
///
/// The double of position x.
/// The double of position y.
/// Accept pixel position to convert to oxford normalized beam position
/// TRUE if success, otherwise FALSE
bool OxfordControllerWrapper::SetBeamPosition(const double a_dPosX, const double a_dPosY)
{
auto edsSettings = GetEdsSpectrumSettings();
if (!edsSettings)
{
return false;
}
m_bBeamPositionSet = true;
_oxfordControllerData.m_dBeamPositionX = a_dPosX;
_oxfordControllerData.m_dBeamPositionY = a_dPosY;
return true;
}
bool OxfordControllerWrapper::SetCurrentBeamPosition()
{
auto edsSettings = GetEdsSpectrumSettings();
if (!edsSettings)
{
return false;
}
auto ret = edsSettings->ScanSettings->AcquisitionRegion->CreateMicroscopeRegion();
return ret != nullptr;
}
bool OxfordControllerWrapper::StartXrayCollecting(const long a_nAcTimeMilliseconds)
{
auto edsController = CreateEdsSpectrumController();
if (!edsController)
{
return false;
}
auto edsSettings = GetEdsSpectrumSettings();
/*edsSettings->EdSettings->AcquisitionTime = TimeSpan::FromMilliseconds(a_nAcTimeMilliseconds);
edsSettings->EdSettings->ProcessTime = 4;*/
edsSettings->EdSettings->AcquisitionMode = (EdAcquireMode)2;
edsSettings->EdSettings->AcquisitionTime = TimeSpan::FromMilliseconds(_oxfordControllerData.m_nAcTime);
edsSettings->EdSettings->ProcessTime = 5;
auto spectrum = edsController->StartAcquisition(edsSettings);
return spectrum != nullptr;
}
bool OxfordControllerWrapper::StopXrayCollecting()
{
auto edsController = CreateEdsSpectrumController();
if (!edsController)
{
return false;
}
if (edsController->IsAcquiring)
{
edsController->StopAcquisition();
}
return !edsController->IsAcquiring;
}
void OxfordControllerWrapper::XraySpectrumProcess(OINA::Extender::Data::Ed::IEdSpectrum^ spectrum)
{
try
{
//Quantify processing
IEdSpectrumProcessing^ 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
IAutoIdSettings^ autoIdSettings = ProcessingFactory::CreateAutoIdSettings();
EdSpectrumProcessing->IdentifyElements(spectrum, autoIdSettings);
ISEMQuantSettings^ settings = ProcessingFactory::CreateSEMQuantSettings();
// While it is possible to choose other elements, Oxygen is the only supported element by stoichiometry.
settings->CombinedElement = 8;
settings->Normalised = true;
ISEMQuantStatus^ quantStatus = EdSpectrumProcessing->SEMQuantifySpectrum(spectrum, settings);//(a_nChannelData, OIHelper::SEMQuantSettings);
IEnumerable^ Results = quantStatus->Results;
if (_oxfordControllerData.m_nCommand == OxfordControllerCommand::COLLECT_XRAYPOINT
|| _oxfordControllerData.m_nCommand == OxfordControllerCommand::COLLECT_CURRENTXRAYPOINT)
{
//Get element result for single point
auto ie = Results->GetEnumerator();
String^ Quant = gcnew String("");
while (ie->MoveNext())
{
ISEMQuantResult^ result = ie->Current;
if (result->WeightPercent != 0)
{
Quant += "Quant=";
Quant += ElementProperties::GetElementSymbol(result->AtomicNumber);
Quant += ",";
Quant += result->LineType.ToString();
Quant += ",";
Quant += result->WeightPercent.ToString();
}
}
_oxfordControllerData.m_sElementResult = Quant;
ConvertSpectrumData(spectrum, _oxfordControllerData.m_pSpectrumData, _oxfordControllerData.m_nBufferSize);
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
auto edsController = CreateEdsSpectrumController();
if (edsController)
{
edsController->EndMultipleAcquisition();
m_endControllerEvent->Set();
}
}
else
{
//Get element result for single point
auto ie = Results->GetEnumerator();
String^ Quant = gcnew String("");
while (ie->MoveNext())
{
ISEMQuantResult^ result = ie->Current;
if (result->WeightPercent != 0)
{
Quant += "Quant=";
Quant += ElementProperties::GetElementSymbol(result->AtomicNumber);
Quant += ",";
Quant += result->LineType.ToString();
Quant += ",";
Quant += result->WeightPercent.ToString();
Quant += "\n";
}
}
CString msg = Quant;
unsigned char* dst = _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_strElementResult;
for (int i = 0; i < msg.GetLength(); i++)
{
dst[i] = (unsigned char)msg.GetAt(i);
}
ConvertSpectrumData(spectrum, _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_pXrayData, _oxfordControllerData.m_nBufferSize);
_oxfordControllerData.m_nCollectedXrayCounts++;
if (_oxfordControllerData.m_nCollectedXrayCounts == _oxfordControllerData.m_nXrayDataCount)
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
auto edsController = CreateEdsSpectrumController();
if (edsController)
{
edsController->EndMultipleAcquisition();
m_endControllerEvent->Set();
}
}
}
}
catch (Exception^ ex)
{
CString sMessage(_T("OnXrayAcquisitionFinished failed") + ex->ToString());
LogErrorTrace(__FILE__, __LINE__, sMessage);
}
}
void OxfordControllerWrapper::OnXrayAcquisitionFinished(Object^ sender, OINA::Extender::Acquisition::AcquisitionFinishedEventArgs^ e)
{
try
{
//Quantify processing
IEdSpectrumProcessing^ 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
IAutoIdSettings^ autoIdSettings = ProcessingFactory::CreateAutoIdSettings();
EdSpectrumProcessing->IdentifyElements(e->Value, autoIdSettings);
ISEMQuantSettings^ settings = ProcessingFactory::CreateSEMQuantSettings();
// While it is possible to choose other elements, Oxygen is the only supported element by stoichiometry.
settings->CombinedElement = 8;
settings->Normalised = true;
ISEMQuantStatus^ quantStatus = EdSpectrumProcessing->SEMQuantifySpectrum(e->Value, settings);//(a_nChannelData, OIHelper::SEMQuantSettings);
IEnumerable^ Results = quantStatus->Results;
if (_oxfordControllerData.m_nCommand == OxfordControllerCommand::COLLECT_XRAYPOINT
|| _oxfordControllerData.m_nCommand == OxfordControllerCommand::COLLECT_CURRENTXRAYPOINT)
{
//Get element result for single point
auto ie = Results->GetEnumerator();
String^ Quant = gcnew String("");
while (ie->MoveNext())
{
ISEMQuantResult^ result = ie->Current;
if (result->WeightPercent != 0)
{
Quant += "Quant=";
Quant += ElementProperties::GetElementSymbol(result->AtomicNumber);
Quant += ",";
Quant += result->LineType.ToString();
Quant += ",";
Quant += result->WeightPercent.ToString();
}
}
_oxfordControllerData.m_sElementResult = Quant;
ConvertSpectrumData(e->Value, _oxfordControllerData.m_pSpectrumData, _oxfordControllerData.m_nBufferSize);
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
auto edsController = CreateEdsSpectrumController();
if (edsController)
{
edsController->EndMultipleAcquisition();
m_endControllerEvent->Set();
}
}
else
{
//Get element result for single point
auto ie = Results->GetEnumerator();
String^ Quant = gcnew String("");
while (ie->MoveNext())
{
ISEMQuantResult^ result = ie->Current;
if (result->WeightPercent != 0)
{
Quant += "Quant=";
Quant += ElementProperties::GetElementSymbol(result->AtomicNumber);
Quant += ",";
Quant += result->LineType.ToString();
Quant += ",";
Quant += result->WeightPercent.ToString();
Quant += "\n";
}
}
CString msg = Quant;
if (_oxfordControllerData.m_pXrayDataList == NULL)
{
return;
}
unsigned char* dst = _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_strElementResult;
for (int i = 0; i < msg.GetLength(); i++)
{
dst[i] = (unsigned char)msg.GetAt(i);
}
ConvertSpectrumData(e->Value, _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_pXrayData, _oxfordControllerData.m_nBufferSize);
_oxfordControllerData.m_nCollectedXrayCounts++;
if (_oxfordControllerData.m_nCollectedXrayCounts == _oxfordControllerData.m_nXrayDataCount)
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
auto edsController = CreateEdsSpectrumController();
if (edsController)
{
edsController->EndMultipleAcquisition();
m_endControllerEvent->Set();
}
}
}
}
catch (Exception^ ex)
{
CString sMessage(_T("OnXrayAcquisitionFinished failed") + ex->ToString());
LogErrorTrace(__FILE__, __LINE__, sMessage);
}
}
void OxfordControllerWrapper::OnXrayChordlistFinished(Object^, OINA::Extender::Acquisition::AcquisitionFinishedEventArgs^ e)
{
}
bool OxfordControllerWrapper::CollectXrayPoint(const double a_dPosX, const double a_dPosY, const long a_nAcTimeMilliseconds, long* a_pSpectrumData, DWORD a_nBufferSize)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::COLLECT_XRAYPOINT;
_oxfordControllerData.m_dBeamPositionX = a_dPosX;
_oxfordControllerData.m_dBeamPositionY = a_dPosY;
_oxfordControllerData.m_nAcTime = a_nAcTimeMilliseconds;
_oxfordControllerData.m_pSpectrumData = a_pSpectrumData;
_oxfordControllerData.m_nBufferSize = a_nBufferSize;
m_startControllerEvent->Set();
Thread::Sleep(a_nAcTimeMilliseconds);
long nCollectedTime = a_nAcTimeMilliseconds;
long nCollectedTimeLimit = nCollectedTime + g_nSinglePointCollectDelay + g_nXrayControllerConnectTimeOutMilliSeconds;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
nCollectedTime += g_nOxfordControllerEventSleepTimerInt;
if (nCollectedTime > nCollectedTimeLimit)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
_oxfordControllerData.m_nCommand = OxfordControllerCommand::END_MULTIPLEACQUISITION;
m_startControllerEvent->Set();
m_endControllerEvent->Reset();
break;
}
}
_oxfordControllerData.m_pSpectrumData = nullptr;
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::CollectXrayPoint(const long a_nAcTimeMilliseconds, long* a_pSpectrumData, DWORD a_nBufferSize)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::COLLECT_CURRENTXRAYPOINT;
_oxfordControllerData.m_nAcTime = a_nAcTimeMilliseconds;
_oxfordControllerData.m_pSpectrumData = a_pSpectrumData;
_oxfordControllerData.m_nBufferSize = a_nBufferSize;
m_startControllerEvent->Set();
Thread::Sleep(a_nAcTimeMilliseconds);
long nCollectedTime = a_nAcTimeMilliseconds;
long nCollectedTimeLimit = nCollectedTime + g_nSinglePointCollectDelay + g_nXrayControllerConnectTimeOutMilliSeconds;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
nCollectedTime += g_nOxfordControllerEventSleepTimerInt;
if (nCollectedTime > nCollectedTimeLimit)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
_oxfordControllerData.m_nCommand = OxfordControllerCommand::END_MULTIPLEACQUISITION;
m_startControllerEvent->Set();
m_endControllerEvent->Reset();
break;
}
}
_oxfordControllerData.m_pSpectrumData = nullptr;
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::CollectXrayPoints(const long a_nAcTimeMilliseconds, OxfordXrayData* a_pXrayDataList, const long a_nXrayDataCount, DWORD a_nBufferSize)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::COLLECT_XRAYPOINTS;
_oxfordControllerData.m_nAcTime = a_nAcTimeMilliseconds;
_oxfordControllerData.m_pXrayDataList = a_pXrayDataList;
_oxfordControllerData.m_nXrayDataCount = a_nXrayDataCount;
_oxfordControllerData.m_nBufferSize = a_nBufferSize;
Thread::Sleep(1000);
m_startControllerEvent->Set();
long nCollectedTime = 1000;
long nCollectedTimeLimit = nCollectedTime + a_nXrayDataCount * g_nSinglePointCollectDelay + g_nXrayControllerConnectTimeOutMilliSeconds;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
nCollectedTime += g_nOxfordControllerEventSleepTimerInt;
if (nCollectedTime > nCollectedTimeLimit)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
_oxfordControllerData.m_nCommand = OxfordControllerCommand::END_MULTIPLEACQUISITION;
m_startControllerEvent->Set();
m_endControllerEvent->Reset();
break;
}
}
_oxfordControllerData.m_pXrayDataList = nullptr;
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::CollectXrayArea(const long a_nAcTimeMilliseconds, OxfordXrayData* a_pXrayDataList, const long a_nXrayDataCount, DWORD a_nBufferSize)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::COLLECT_XRAYCHOILDLIST;
_oxfordControllerData.m_nAcTime = a_nAcTimeMilliseconds;
_oxfordControllerData.m_pXrayDataList = a_pXrayDataList;
_oxfordControllerData.m_nXrayDataCount = a_nXrayDataCount;//要采集的feature个数
_oxfordControllerData.m_nCollectedXrayCounts = 0;
_oxfordControllerData.m_nChordsNum = a_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_nChordNum;
_oxfordControllerData.m_nCollectedChordsCount = 0;
_oxfordControllerData.m_nBufferSize = a_nBufferSize;
//当前采集的feature包含的像素的个数
_oxfordControllerData.m_nPixelNum = a_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_nPixelNum;
_oxfordControllerData.m_nCollectedPixelCounts = 0;
Thread::Sleep(1000);
m_startControllerEvent->Set();
//Thread::Sleep(a_nAcTimeMilliseconds * a_nXrayDataCount);
long nCollectedTime =1000;
long nCollectedTimeLimit = nCollectedTime + a_nXrayDataCount * g_nSingleFeatureCollectDelay + g_nXrayControllerConnectTimeOutMilliSeconds;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventSleepTimerInt);
nCollectedTime += g_nOxfordControllerEventSleepTimerInt;
if (nCollectedTime > nCollectedTimeLimit)
{
CString sMessage;
sMessage.Format(_T("Error: Total collected time(%d) over limit(%d)"), nCollectedTime, nCollectedTimeLimit);
LogErrorTrace(__FILE__,__LINE__,sMessage);
sMessage.Format(_T("1Total collected xray %d / %d"), _oxfordControllerData.m_nCollectedXrayCounts, _oxfordControllerData.m_nXrayDataCount);
LogErrorTrace(__FILE__, __LINE__, sMessage);
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Reset();
break;
}
}
_oxfordControllerData.m_pXrayDataList = nullptr;
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
CString sMessage;
sMessage.Format(_T("CollectXrayArea failed."));
LogErrorTrace(__FILE__, __LINE__, sMessage);
return false;
}
bool OxfordControllerWrapper::ConvertSpectrumData(IEdSpectrum^ a_spectrum, long* a_pSpectrumData, int a_nBufferSize)
{
if (!a_spectrum || !a_pSpectrumData)
{
return false;
}
memset(a_pSpectrumData, 0, sizeof(long) * a_nBufferSize);
array^ xrayData = gcnew array(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)
{
int nValue = 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
long nValueToLeftBin = (long)((double)nValue * dLeft_Percent + 0.5);
// put data into bins
a_pSpectrumData[nLeftBin] += nValueToLeftBin;
if ((nLeftBin + 1) < (long)a_nBufferSize)
{
a_pSpectrumData[nLeftBin + 1] += (nValue - nValueToLeftBin);
}
}
return true;
}
bool OxfordControllerWrapper::IsXrayCollecting()
{
if (_edSpectrumController)
{
return _edSpectrumController->IsAcquiring;
}
return false;
}
bool OxfordControllerWrapper::IsImageCollecting()
{
if (_imageAcqusitionController)
{
return _imageAcqusitionController->IsAcquiring;
}
return false;
}
bool OxfordControllerWrapper::IsQuantifySpectrumCollecting()
{
if (_edSpectrumController)
{
return _edSpectrumController->IsAcquiring;
}
return false;
}
bool OxfordControllerWrapper::SetScanSpeed(const long a_nMilliseconds)
{
auto imageAcqusitionSettings = GetImageAcqusitionSettings();
imageAcqusitionSettings->ImageSettings->DwellTimeMicroSeconds = a_nMilliseconds;
return true;
}
bool OxfordControllerWrapper::GetImageSize(long& a_nWidth, long& a_nHeight)
{
a_nWidth = _oxfordControllerData.m_nImageWidth;
a_nHeight = _oxfordControllerData.m_nImageHeight;
return true;
}
bool OxfordControllerWrapper::SetImageSize(const long a_nWidth, const long a_nHeight)
{
_oxfordControllerData.m_nImageWidth = a_nWidth;
_oxfordControllerData.m_nImageHeight = a_nHeight;
auto imageAcqusitionSettings = GetImageAcqusitionSettings();
imageAcqusitionSettings->ScanSettings->AcquisitionRegion->CreateFullFieldRegion(1.0 / a_nWidth);
return true;
}
bool OxfordControllerWrapper::CollectImage(int a)
{
return true;
}
bool OxfordControllerWrapper::QuantifySpectrum(unsigned char* cResult)
{
CString result = _oxfordControllerData.m_sElementResult;
cResult = (unsigned char*)result.GetBuffer();
return true;
}
bool OxfordControllerWrapper::CollectImage(BYTE* a_pImageBits)
{
_oxfordControllerData.m_nCommand = OxfordControllerCommand::COLLECT_IMAGE;
_oxfordControllerData.m_pImageBits = a_pImageBits;
m_startControllerEvent->Set();
long nCollectedTime = 0;
long nCollectedTimeLimit = g_nImageTimeOutMilliSeconds;
while (true)
{
if (m_endControllerEvent->WaitOne(0, true))
{
m_endControllerEvent->Reset();
break;
}
Application::DoEvents();
Thread::Sleep(g_nOxfordControllerEventWaitTimerInt);
nCollectedTime += g_nOxfordControllerEventWaitTimerInt;
if (nCollectedTime > nCollectedTimeLimit)
{
//this->CreateImageAcqusitionController();
_oxfordControllerData.m_nCommand = OxfordControllerCommand::STOP_ACQUISITION;
m_startControllerEvent->Set();
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Reset();
break;
}
}
_oxfordControllerData.m_pImageBits = nullptr;
if (_oxfordControllerData.m_nState == OxfordControllerState::SUCCEEDED)
{
return true;
}
return false;
}
bool OxfordControllerWrapper::ReadImageData(IElectronImage^ a_electronImage, BYTE* a_pImageBits)
{
if (a_electronImage == nullptr)
{
return false;
}
if (a_pImageBits == NULL)
{
return false;
}
_oxfordControllerData.m_nImageWidth = a_electronImage->Width;
_oxfordControllerData.m_nImageHeight = a_electronImage->Height;
_oxfordControllerData.m_dPixelSize = a_electronImage->PixelSize;
int nBytesPerPixel = a_electronImage->BytesPerPixel;
int nImageSize = _oxfordControllerData.m_nImageWidth * _oxfordControllerData.m_nImageHeight;
int nBufferSize = _oxfordControllerData.m_nImageWidth * _oxfordControllerData.m_nImageHeight * nBytesPerPixel;
array^ imageData = gcnew array(nBufferSize);
a_electronImage->GetData(imageData);
// 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
{
int nOffset = nBytesPerPixel - 1;
for (int i = 0; i < nImageSize; ++i)
{
#ifdef _DEBUG
byte nValue = imageData[nBytesPerPixel - 1 + i * nBytesPerPixel];
a_pImageBits[i] = nValue;
#else
a_pImageBits[i] = imageData[nOffset + i * nBytesPerPixel];
#endif
}
}
return true;
}
bool OxfordControllerWrapper::StartImageCollecting()
{
auto imageAcqusitionController = CreateImageAcqusitionController();
auto imageAcqusitionSettings = GetImageAcqusitionSettings();
if (imageAcqusitionController == nullptr)
{
return false;
}
if (imageAcqusitionSettings == nullptr)
{
return false;
}
try
{
List^ electronImageList = gcnew List();
auto images = imageAcqusitionController->StartAcquisition(imageAcqusitionSettings);
return images != nullptr;
}
catch (Exception^ /*ex*/)
{
CString sMessage(_T("StartImageCollecting: Start Acquisition failed"));
LogErrorTrace(__FILE__,__LINE__,sMessage);
}
return false;
}
void OxfordControllerWrapper::OnImageAcquisitionFinished(Object^ /*sender*/, OINA::Extender::Acquisition::AcquisitionFinishedEventArgs^ >^ e)
{
List^ electronImageList = gcnew List();
try
{
if ((bool)e->Success)
{
for each (auto eleImage in e->Value)
{
electronImageList->Add(eleImage);
}
if (electronImageList->Count == 0)
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
else if (!ReadImageData(electronImageList[0], _oxfordControllerData.m_pImageBits))
{
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
}
else
{
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
}
}
else
{
CString sMessage(_T("OnImageAcquisitionFinished failed") );
LogErrorTrace(__FILE__, __LINE__, sMessage);
}
}
catch (Exception^ ex)
{
CString sMessage(_T("OnImageAcquisitionFinished failed")+ex->ToString());
LogErrorTrace(__FILE__, __LINE__, sMessage);
}
m_endControllerEvent->Set();
}
void OxfordControllerWrapper::OnController_PixelProcessed(Object^ /*sender*/, OINA::Extender::EventArgs^ e)
{
_oxfordControllerData.m_nCollectedPixelCounts++;
//更新当前feature的元素成分
//Get element result for single point
auto ie = e->Value->QuantStatus->Results->GetEnumerator();
while (ie->MoveNext())
{
ISEMQuantResult^ result = ie->Current;
if (result->WeightPercent != 0)
{
Element^ Quant = gcnew Element();
Quant->m_nAotomaticNo = result->AtomicNumber;
Quant->m_dWeight = result->WeightPercent;
if (_oxfordControllerData.m_listElementResult == nullptr)
{
_oxfordControllerData.m_listElementResult = gcnew List();
_oxfordControllerData.m_listElementResult->Add(Quant);
}
else
{
bool bFind = false;
for (int i = 0; i < _oxfordControllerData.m_listElementResult->Count; i++)
{
Element^ result = _oxfordControllerData.m_listElementResult[i];
if (Quant->m_nAotomaticNo == result->m_nAotomaticNo)
{
result->m_dWeight += Quant->m_dWeight;
bFind = true;
}
}
if (!bFind)
{
_oxfordControllerData.m_listElementResult->Add(Quant);
}
}
}
}
//当前的chord数据中pixel没有采集完整
if (_oxfordControllerData.m_nCollectedPixelCounts == _oxfordControllerData.m_nPixelNum)
{
//形成quant数据
CString Quant = _T("");
for (int i = 0; i < _oxfordControllerData.m_listElementResult->Count; i++)
{
Element^ result = _oxfordControllerData.m_listElementResult[i];
Quant += "Quant=";
CString strAoto(ElementProperties::GetElementSymbol(result->m_nAotomaticNo));
Quant += strAoto;
Quant += ",";
Quant += _T("K-serials");
Quant += ",";
CString strWeight = (result->m_dWeight / (double)_oxfordControllerData.m_nPixelNum).ToString();
Quant += strWeight ;
Quant += "\n";
}
CString msg = Quant;
unsigned char* dst = _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_strElementResult;
for (int i = 0; i < msg.GetLength(); i++)
{
dst[i] = (unsigned char)msg.GetAt(i);
}
_oxfordControllerData.m_nCollectedXrayCounts++;
if (_oxfordControllerData.m_nCollectedXrayCounts < _oxfordControllerData.m_nXrayDataCount)
{
_oxfordControllerData.m_nPixelNum = _oxfordControllerData.m_pXrayDataList[_oxfordControllerData.m_nCollectedXrayCounts].m_nPixelNum;
_oxfordControllerData.m_nCollectedPixelCounts = 0;
_oxfordControllerData.m_listElementResult->Clear();
}
}
}
void OxfordControllerWrapper::OnController_ExperimentFinished(Object^ /*sender*/, OINA::Extender::Acquisition::AcquisitionFinishedEventArgs^ e)
{
if (_oxfordControllerData.m_nCollectedXrayCounts == _oxfordControllerData.m_nXrayDataCount)
_oxfordControllerData.m_nState = OxfordControllerState::SUCCEEDED;
else
_oxfordControllerData.m_nState = OxfordControllerState::FAILED;
m_endControllerEvent->Set();
}
bool OxfordControllerWrapper::StopImageCollecting()
{
auto imageAcqusitionController = CreateImageAcqusitionController();;
try
{
if (imageAcqusitionController->IsAcquiring)
{
imageAcqusitionController->StopAcquisition();
}
}
catch (Exception^ ex)
{
CString sMessage = ex->Message;
CString sErrorMessage;
sErrorMessage.Format(_T("StopImageCollecting: Stop Acquisition caught(%s)"), sMessage);
LogErrorTrace(__FILE__, __LINE__, sErrorMessage);
}
return !imageAcqusitionController->IsAcquiring;
}
IMicroscopeController^ OxfordControllerWrapper::CreateMicroscopeController()
{
if (_microscopeController != nullptr)
{
return _microscopeController;
}
try
{
LogTrace(__FILE__, __LINE__, _T("CreateMicroscopeControl..."));
_microscopeController = AcquireFactory::CreateMicroscopeControl();
}
catch(Exception^ ex)
{
CString sErrorMessage = ex->Message;
AfxMessageBox(_T("oxford eds cann't work,you can change work mode to offline in the sysMgrApp to run offline mode!\nerror:")+ sErrorMessage);
LogErrorTrace(__FILE__, __LINE__, sErrorMessage);
return nullptr;
}
if (_microscopeController == nullptr)
{
CString sErrorMessage ="";
AfxMessageBox(_T("oxford eds cann't work,you can change work mode to offline in the sysMgrApp to run offline mode!\nerror:") + sErrorMessage);
LogErrorTrace(__FILE__, __LINE__, sErrorMessage);
return nullptr;
}
_microscopeController->ColumnChange += gcnew EventHandler(this, &OxfordControllerWrapper::OnMicroscopeColumnUpdated);
//_microscopeController->StageChange += gcnew EventHandler(this, &OxfordControllerWrapper::OnMicroscopeStageUpdated);
_microscopeController->ChangeCompleted += gcnew EventHandler(this, &OxfordControllerWrapper::OnMicroscopeCompleted);
m_bIsStageUpdated = false;
auto nStart = GetTickCount64();
auto nEnd = nStart;
do
{
if (IsMicroscopeColumnConnected()
&& IsMicroscopeStageConnected())
{
break;
}
nEnd = GetTickCount64();
} while (nEnd >= nStart && nEnd <= (nStart + g_nMicrocopeConnectTimeOutMilliSeconds));
return _microscopeController;
}
IEdSpectrumAcquisitionController^ OxfordControllerWrapper::CreateEdsSpectrumController()
{
if (_edSpectrumController == nullptr)
{
LogTrace(__FILE__, __LINE__, _T("CreateEdSpectrumServer..."));
try
{
_edSpectrumController = AcquireFactory::CreateEdSpectrumServer();
_edSpectrumController->ExperimentFinished += gcnew EventHandler^>(this, &OxfordControllerWrapper::OnXrayAcquisitionFinished);
auto edsSpectrumSettings = GetEdsSpectrumSettings();
while (true)
{
if (_edSpectrumController->IsEdHardwareReady(edsSpectrumSettings))
{
if (edsSpectrumSettings->EdCapabilities->HasHardwareConnection)
{
break;
}
}
}
}
catch (const std::exception& e)
{
CString msg(e.what());
LogTrace(__FILE__, __LINE__,msg);
return nullptr;
}
}
return _edSpectrumController;
}
IEdSpectrumSettings^ OxfordControllerWrapper::GetEdsSpectrumSettings()
{
if (_edsSpectrumSettings == nullptr)
{
_edsSpectrumSettings = AcquireFactory::CreateEdSpectrumSettings();
if (_edsSpectrumSettings == nullptr)
{
CString sMessage(_T("Create EDS Spectrum setting failed."));
LogErrorTrace(__FILE__, __LINE__, sMessage);
ASSERT(FALSE);
}
else
{
_edsSpectrumSettings->EdSettings->AcquisitionMode = EdAcquireMode::LiveTime;
//_edsSpectrumSettings->EdSettings->AcquisitionTime = TimeSpan::FromSeconds(1);
_edsSpectrumSettings->EdSettings->NumberOfChannels = g_nOxfordControllerChannels;
_edsSpectrumSettings->EdSettings->ProcessTime = g_nOxfordControllerProcessTime;
_edsSpectrumSettings->EdSettings->EnergyRange = g_nOxfordControllerEnergyRange;
}
}
return _edsSpectrumSettings;
}
IImageAcquisitionController^ OxfordControllerWrapper::CreateImageAcqusitionController()
{
if (_imageAcqusitionController == nullptr)
{
LogTrace(__FILE__, __LINE__, _T("CreateImageAcqusitionController..."));
try
{
_imageAcqusitionController = AcquireFactory::CreateImageServer();
//_imageAcqusitionController->ExperimentStarted += gcnew EventHandler^ >^>(this, &OxfordControllerWrapper::OnImageAcquisitioStarted);
_imageAcqusitionController->ExperimentFinished += gcnew EventHandler^ >^>(this, &OxfordControllerWrapper::OnImageAcquisitionFinished);
auto imageAcqusitionSettings = GetImageAcqusitionSettings();
while (true)
{
if (_imageAcqusitionController->IsImageHardwareReady(imageAcqusitionSettings))
{
if (imageAcqusitionSettings->ImageCapabilities->HasHardwareConnection)
{
break;
}
}
}
}
catch (Exception^ ex)
{
CString sMessage = ex->Message;
LogErrorTrace(__FILE__, __LINE__, sMessage);
return nullptr;
}
}
return _imageAcqusitionController;
}
IImageAcquisitionSettings^ OxfordControllerWrapper::GetImageAcqusitionSettings()
{
if (_imageAcqusitionSettings == nullptr)
{
_imageAcqusitionSettings = AcquireFactory::CreateImageSettings();
_imageAcqusitionSettings->ScanSettings->FrameCount = 1;
IImageSettings^ imageSettings = _imageAcqusitionSettings->ImageSettings;
for each (KeyValuePair^ imputSource in imageSettings->InputSources)
{
imageSettings->EnableInputSource(imputSource->Key, false);
}
CString szXMLFileName = "./Config/ProData/HardwareConfig.xml";
tinyxml2::XMLDocument doc;
doc.LoadFile(szXMLFileName);//载入xml文件
xmls::Slo subClass;
xmls::xString sImageInputSources;
subClass.Register("ImageInputSources", &sImageInputSources);
subClass.Register("SemControllerName", &subClass);
tinyxml2::XMLElement* rootNode;
rootNode = doc.FirstChildElement(RootClassName);
subClass.Serialize(false, &doc, rootNode);
CString cImageInputSources = sImageInputSources.value().c_str();
if (cImageInputSources == "BSE")
{
imageSettings->EnableInputSource(OINA::Extender::Data::Image::ImageInputSources::Bse, true);
}
else if (cImageInputSources == "SE")
{
imageSettings->EnableInputSource(OINA::Extender::Data::Image::ImageInputSources::SE, true);
}
else
{
imageSettings->EnableInputSource(OINA::Extender::Data::Image::ImageInputSources::None, true);
}
_imageAcqusitionSettings->ImageSettings->DwellTimeMicroSeconds = 20;
_imageAcqusitionSettings->ScanSettings->AcquisitionRegion->CreateFullFieldRegion(1.0 / 1024.0);
}
return _imageAcqusitionSettings;
}
IEdChordListAcquisitionController^ OxfordControllerWrapper::CreateChordlistController()
{
if (_edsChordListController == nullptr)
{
try
{
LogTrace(__FILE__, __LINE__, _T("CreateEdChordListServer..."));
_edsChordListController = AcquireFactory::CreateEdChordListServer();
_edsChordListController->PixelProcessed += gcnew EventHandler^>(this, &OxfordControllerWrapper::OnController_PixelProcessed);
_edsChordListController->ExperimentFinished += gcnew EventHandler(this, &OxfordControllerWrapper::OnController_ExperimentFinished);
auto edsChordListSettings = GetChordlistSettings();
while (true)
{
if (_edsChordListController->IsEdHardwareReady(edsChordListSettings))
{
if (edsChordListSettings->EdCapabilities->HasHardwareConnection)
{
break;
}
}
}
}catch(Exception^ ex)
{
CString sMessage = ex->Message;
LogErrorTrace(__FILE__, __LINE__, sMessage);
return nullptr;
}
}
return _edsChordListController;
}
///
/// Get some chordlists to acquire.
///
/// The chordlists to acquire.
System::Collections::Generic::IReadOnlyList^ GetChordLists()
{
OINA::Extender::Data::Chord^ chord1 = gcnew OINA::Extender::Data::Chord(3, 0, 5);
OINA::Extender::Data::Chord^ chord2 = gcnew OINA::Extender::Data::Chord(0, 0, 3);
OINA::Extender::Data::Chord^ chord3 = gcnew OINA::Extender::Data::Chord(10, 0, 20);
OINA::Extender::Data::Chord^ chord4 = gcnew OINA::Extender::Data::Chord(550, 44, 30);
OINA::Extender::Data::Chord^ chord5 = gcnew OINA::Extender::Data::Chord(0, 270, 10);
OINA::Extender::Data::Chord^ chord6 = gcnew OINA::Extender::Data::Chord(898, 634, 15);
OINA::Extender::Data::Chord^ chord7 = gcnew OINA::Extender::Data::Chord(266, 768, 40);
List< OINA::Extender::Data::Chord^>^ chords = gcnew List();
chords->Add(chord1);
chords->Add(chord2);
chords->Add(chord3);
chords->Add(chord4);
chords->Add(chord5);
chords->Add(chord6);
chords->Add(chord7);
OINA::Extender::Data::ChordList^ chordsList = gcnew OINA::Extender::Data::ChordList(chords, 1/1024.0);
List^ ListchordsList = gcnew List();
ListchordsList->Add(chordsList);
return ListchordsList;
}
IEdChordListSettings^ OxfordControllerWrapper::GetChordlistSettings()
{
if (_edsChordListSetting == nullptr)
{
_edsChordListSetting = AcquireFactory::CreateEdChordListSettings();
if (_edsChordListSetting == nullptr)
{
CString sMessage(_T("Create EDS chordlist setting failed."));
LogErrorTrace(__FILE__, __LINE__, sMessage);
ASSERT(FALSE);
}
else
{
_edsChordListSetting->EdSettings->AcquisitionMode = EdAcquireMode::LiveTime;
//_edsChordListSetting->EdSettings->AcquisitionTime = TimeSpan::FromMilliseconds(100);// :FromSeconds(1);
_edsChordListSetting->EdSettings->NumberOfChannels =4096;
_edsChordListSetting->EdSettings->ProcessTime = g_nOxfordControllerProcessTime;
_edsChordListSetting->EdSettings->EnergyRange = g_nOxfordControllerEnergyRange;
/*_edsChordListSetting->AutoIdSettings->SetKnownElement(79, true);
_edsChordListSetting->NumberOfProcessingThreads = 1;*/
//_edsChordListSetting->ChordLists = GetChordLists();
}
}
return _edsChordListSetting;
}
void OxfordControllerWrapper::LogMessage(CString a_sMessage)
{
LogTrace(__FILE__, __LINE__, a_sMessage);
}