| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482 |
- #pragma once
- #include "stdafx.h"
- #include <stdlib.h>
- #include <crtdbg.h>
- #include "SmplMeasure.h"
- #include "SmplMsrResultFileMgr.h"
- #include "FieldMgr.h"
- #include "StageFile.h"
- namespace OTSMODEL
- {
- using namespace OTSDATA;
- using namespace std;
- CSmplMeasure::CSmplMeasure()
- {
-
- Init();
- }
- CSmplMeasure::CSmplMeasure(CString a_strWorkingFolder, COTSSamplePtr a_pSample)
- {
- m_pMsrThread = nullptr;
- SetSample(a_pSample);
- SetWorkingFolder(a_strWorkingFolder);
- m_pSmplMsrResultFileMgr = CSmplMsrResultFileMgrPtr(new CSmplMsrResultFileMgr(m_strWorkingFolder));
-
- if (!m_pSmplMsrResultFileMgr->Init(m_pSample))
- {// failed to initialize measure result file
- LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: initialize measure result file."));
- return;
- }
-
- }
-
- CSmplMeasure::~CSmplMeasure()
- {
- }
- void CSmplMeasure::SetSample(COTSSamplePtr a_pSample)
- {
- ASSERT(a_pSample);
- if (!a_pSample)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSample: invalid Sample."));
- return;
- }
- m_pSample = a_pSample;
-
- }
- // measure thread
- void CSmplMeasure::SetMsrThread(CMsrThread* a_pMsrThread)
- {
- ASSERT(a_pMsrThread);
- if (!a_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetMsrThread: invalid thread."));
- return;
- }
- m_pMsrThread = a_pMsrThread;
- }
- void CSmplMeasure::SetWorkingFolder(CString a_strWorkingFolder)
- {
- // add "\\" at the string end if it is not "\\"
- if (a_strWorkingFolder.Right(1) != _T('\\'))
- {
- a_strWorkingFolder += _T("\\");
- }
- m_strWorkingFolder = a_strWorkingFolder + m_pSample->GetName() + _T("\\");
- }
- // measurement
- void CSmplMeasure::DoMeasureOneSample()
- {
- ASSERT(m_pSample);
- // let the main thread to know that this sample measurement starts
- CMsrSampleStatusPtr pStatus = m_pSample->GetMsrStatus();
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::INPROCESS);
- // set current time to current time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::START);
- // let main App know that the sample begin to measure
- ST_MSTMsg MsgSmpStart;
- memset(&MsgSmpStart, 0, sizeof(ST_MSTMsg));
- MsgSmpStart.iMsgType = ENUM_MSG_TYPE::MSAMPLESTATUS;
- MsgSmpStart.STMSampleStu.iMeasureSampleStatus = (int)OTS_MSR_SAMPLE_STATUS::INPROCESS;
- memset(MsgSmpStart.STMSampleStu.cSampleName, 0, sizeof(MsgSmpStart.STMSampleStu.cSampleName));
- strcpy(MsgSmpStart.STMSampleStu.cSampleName, m_pSample->GetName());
- m_pMsrThread->SendMessageToMeasureApp(MsgSmpStart);
- m_pMsrThread->SendLogMessageToMeasureApp(_T(m_pSample->GetName() + " Measurement started!"), PostLogLevel::info);
- // get SEM controller to set magnification and working distance
- if (!SetSEMDataMrs())
- {
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: fail to set SEM data."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // get SEM external controll on
- if (!SetSEMExteralOn())
- {
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: fail to set SEM external."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T(" Set External On!"), PostLogLevel::info);
- // set the BSE scan param
- if (!SetBSEParam())
- {
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: fail to set BSE param."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // will be called before quit this method
- ON_SCOPE_EXIT([&]()
- {// disconnect hardware
- SetSEMExteralOff();
- ResetScan();
- }
- );
-
- // record SEM working condition
- CSEMDataGnrPtr pSEMDataGnr = m_pMsrThread->GetSEMDataGnr();
- ASSERT(pSEMDataGnr);
- if (!pSEMDataGnr)
- {
- // failed to call RecordSEMCondition method
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to call RecordSEMCondition method."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- m_pSmplMsrResultFileMgr->SetSEMGnr(pSEMDataGnr);
- // record SEM data
- COTSProjMgrFilePtr pProjMgrFile = m_pMsrThread->GetProjMgrFile();
- ASSERT(pProjMgrFile);
- if (!pProjMgrFile)
- {
- // failed to call RecordSEMCondition method
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to get project file."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- CSEMStageDataPtr pSEMStageData = pProjMgrFile->GetSEMStageData();
- ASSERT(pSEMStageData);
- if (!pSEMStageData)
- {
- // failed to call RecordSEMCondition method
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to get SEM data."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- m_pSmplMsrResultFileMgr->SetSEMStageData(pSEMStageData);
- // record stage
- CStagePtr pStage = pProjMgrFile->GetStage();
- ASSERT(pStage);
- if (!pStage)
- {// failed to call RecordSEMCondition method
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to get stage."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- m_pSmplMsrResultFileMgr->SetSEMStage(pStage);
- // check if sample measurement completes
- COTSImageScanParamPtr pScanParam = m_pSample->GetMsrParams()->GetImageScanParam();
- //int nTotalFieldSize = (int)umMeasuredlistFieldCenter.size();
- ASSERT(pScanParam);
- if (!pScanParam)
- {
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure:invalid Scan param."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // calculate field centers
- std::vector<CPoint> umMeasuredlistFieldCenter;
- //umMeasuredlistFieldCenter.clear();
- if (!CalculateUnMeasuredFieldsCenters(umMeasuredlistFieldCenter))
- {// failed to calculate field centers
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to calculate field centers."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- //-----save the static measure result file data into xml file and the dynamic data of every field will be saved into sqlite database
- CString strPathName = m_pSmplMsrResultFileMgr->GetPathName();
- if (!m_pSmplMsrResultFileMgr->Save(strPathName))
- {// failed to call measure result file Save method
- //LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: failed to call measure result file Save method."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Created Result File!"), PostLogLevel::info);
- //------
- int nNewFieldId = 0;
- int numOfAllFields = pStatus->GetCompletedFields() + umMeasuredlistFieldCenter.size();//
- int completedFields = pStatus->GetCompletedFields();
- CString s;
- s.Format("%d", umMeasuredlistFieldCenter.size());
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Unmeasured fields:") + s, PostLogLevel::info);
- for (int i = 0; i < (int)umMeasuredlistFieldCenter.size(); ++i)
- {// check and break if stop button is clicked
- if (IsAborted())
- {// measure stopped
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::STOPPED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- //must wait for the saving data thread finished,or we'll get null pointer exception when we stop the measure process.
- while (fieldQueue.size() > 0)
- {
- Sleep(100);
- }
- return;
- }
-
- if (IsSampleOver(pScanParam, numOfAllFields))
- {
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- break;
- }
- // get a field center
- CPoint poiFieldCentre = umMeasuredlistFieldCenter[i];
- // update thread measure status class, let the main thread know that starts a new field
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- ST_MSTMsg MsgFieldStart;
- memset(&MsgFieldStart, 0, sizeof(ST_MSTMsg));
- MsgFieldStart.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET::START_MSR_FIELD;
- MsgFieldStart.STMSampleRetData.SMsrField.Fieldpos = poiFieldCentre;
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldStart);
- CString str;
- str.Format("%d", i+ completedFields+1);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Current field:") + str, PostLogLevel::warn);
- str.Empty();
- str.Format("(%d,%d)", poiFieldCentre.x, poiFieldCentre.y);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to move SEM to ") + str, PostLogLevel::info);
- // move SEM to the field center
- if (!MoveSEMToPoint(poiFieldCentre))
- {// failed to move SEM to the position
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- continue;
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to Acquire BSEImage"), PostLogLevel::info);
- // take BSE image for the fields
- CBSEImgPtr pBSEIamge = AcquireABSEImage();
- if (pBSEIamge==nullptr)
- {// failed to acquire a BSE image
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Failed to Acquire BSEImage"), PostLogLevel::info);
- continue;
- }
- //BSEData
- ST_MSTMsg MsgFieldBSE;
- memset(&MsgFieldBSE, 0, sizeof(ST_MSTMsg));
- MsgFieldBSE.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET::BSE_DATA;
- MsgFieldBSE.STMSampleRetData.BSEData.pos.x = poiFieldCentre.x;
- MsgFieldBSE.STMSampleRetData.BSEData.pos.y = poiFieldCentre.y;
- MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEIamge->GetHeight();
- MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEIamge->GetWidth();
- BYTE* pImgData = pBSEIamge->GetImageDataPointer();
- MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldBSE);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Acquire BSE image success! Processing Image....."), PostLogLevel::info);
- // get a new field id
- nNewFieldId = m_pSmplMsrResultFileMgr->GetIdForANewField(nNewFieldId);
- // create a field
- COTSFieldDataPtr pNewFieldData = COTSFieldDataPtr(new COTSFieldData());
- pNewFieldData->SetId(nNewFieldId);
- pNewFieldData->SetPosition(poiFieldCentre);
- pNewFieldData->SetFieldFileFolder(m_pSmplMsrResultFileMgr->GetFieldFileSubFolderStr());
- // image process
- try
- {
- ImageProcess(pNewFieldData, pBSEIamge);
- }
- catch (...)
- {// catch an exception when call AcquireBSEImage method
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Image process failed."), PostLogLevel::warn);
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- continue;
- }
- // is the field data empty
- if (!pNewFieldData->IsEmpty())
- {
- // add the field into the field
- m_pSmplMsrResultFileMgr->AddAField(pNewFieldData);
- }
-
- // prepare for the next
- ++nNewFieldId;
- // completed fields
- pStatus->SetCompletedFields(pStatus->GetCompletedFields() + 1);
- // completed fieldCenter
- std::vector<CPoint>& listCpltedCenter = pStatus->GetCompletedFieldsCenter();
- listCpltedCenter.push_back(poiFieldCentre);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Send result to the screen!"), PostLogLevel::info);
- //Field Data
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- ST_MSTMsg MsgFieldEnd;
- memset(&MsgFieldEnd, 0, sizeof(ST_MSTMsg));
- MsgFieldEnd.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET::FIELD_DATA;
- MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = pStatus->GetCompletedFields();
- MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = numOfAllFields;
- MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = (int)pNewFieldData->GetParticleList().size();
- MsgFieldEnd.STMSampleRetData.SFieldData.Fieldpos.x = poiFieldCentre.x;
- MsgFieldEnd.STMSampleRetData.SFieldData.Fieldpos.y = poiFieldCentre.y;
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldEnd);
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- }
- while (fieldQueue.size() > 0)//wait untill all the field data has been saved.
- {
- Sleep(100);
- }
- //calculate measure time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::SUCCESSED);
- // let main thread to know that this sample measurement completes
- ST_MSTMsg MsgSmplEnd;
- memset(&MsgSmplEnd, 0, sizeof(ST_MSTMsg));
- MsgSmplEnd.iMsgType = ENUM_MSG_TYPE::MSAMPLESTATUS;
- MsgSmplEnd.STMSampleStu.iMeasureSampleStatus = (int)OTS_MSR_SAMPLE_STATUS::SUCCESSED;
- memcpy(MsgSmplEnd.STMSampleStu.cSampleName, m_pSample->GetName(), sizeof(m_pSample->GetName()));
- m_pMsrThread->SendMessageToMeasureApp(MsgSmplEnd);
- return;
- }
-
- // hole preview
- void CSmplMeasure::DoHolePreviewOneSample(int a_nHoleID)
- {// safety check
- ASSERT(m_pSample);
-
- // let the main thread to know that this sample measurement starts
- CMsrSampleStatusPtr pStatus = m_pSample->GetMsrStatus();
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::INPROCESS);
- // set current time to current time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::START);
- // let main App know that the sample begin to measure
- ST_MSTMsg MsgSmpStart;
- memset(&MsgSmpStart, 0, sizeof(ST_MSTMsg));
- MsgSmpStart.iMsgType = ENUM_MSG_TYPE::MSAMPLESTATUS;
- MsgSmpStart.STMSampleStu.iMeasureSampleStatus = (int)OTS_MSR_SAMPLE_STATUS::INPROCESS;
- memset(MsgSmpStart.STMSampleStu.cSampleName, 0, sizeof(MsgSmpStart.STMSampleStu.cSampleName));
- strcpy(MsgSmpStart.STMSampleStu.cSampleName, m_pSample->GetName());
-
- // get SEM controller to set magnification and working distance
- if (!SetSEMDataMrs())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview: fail to set SEM data."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // get SEM external controll on
- if (!SetSEMExteralOn())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: fail to set SEM external."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // set the BSE scan param
- if (!SetBSEParam())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("DoMeasure: fail to set BSE param."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // will be called before quit this method
- ON_SCOPE_EXIT([&]()
- {// disconnect hardware
- SetSEMExteralOff();
- ResetScan();
- }
- );
- // check if measurement is aborted
- if (IsAborted())
- {// measurement aborted
- LogTrace(__FILE__, __LINE__, _T("DoHolePreview: measurement aborted before get SEM condition."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::STOPPED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // calculate field centers
- std::vector<CPoint> listFieldCenter;
- listFieldCenter.clear();
- if (!CalculateUnMeasuredFieldsCenters(listFieldCenter))
- {// failed to calculate field centers
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview: failed to calculate field centers."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // go through each field
- int nNewFieldId = 0;
- for (int i = 0; i < (int)listFieldCenter.size(); ++i)
- {// check and break if stop button is clicked
- if (IsAborted())
- {// measure stopped
- LogTrace(__FILE__, __LINE__, _T("DoHolePreview: measure thread is stopped."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::STOPPED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- // check if sample measurement completes
- COTSImageScanParamPtr pScanParam = m_pSample->GetMsrParams()->GetImageScanParam();
- int nTotalFieldSize = (int)listFieldCenter.size();
- ASSERT(pScanParam);
- if (!pScanParam)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview:invalid Scan param."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
-
- return;
- }
- if (IsSampleOver(pScanParam, nTotalFieldSize))
- {
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
-
- break;
- }
- // get a field center
- CPoint poiFieldCentre = listFieldCenter[i];
- LogErrorTrace(__FILE__, __LINE__, _T("C++ Position Message 1: field %d begin."), i);
- // update thread measure status class, let the main thread know that starts a new field
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
-
- ST_MSTMsg MsgFieldStart;
- memset(&MsgFieldStart, 0, sizeof(ST_MSTMsg));
- MsgFieldStart.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET::START_MSR_FIELD;
- MsgFieldStart.STMSampleRetData.SMsrField.Fieldpos = poiFieldCentre;
- LogInfoTrace(__FILE__, __LINE__, _T("Message :DoHolePreview: field %d measure begin. message type is %d"), i, MsgFieldStart.iMsgType);
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldStart);
- // move SEM to the field center
- if (!MoveSEMToPoint(poiFieldCentre))
- {// failed to move SEM to the position
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview: failed to move SEM to the field centre point."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
-
- return;
- }
- // take BSE image for the fields
- CBSEImgPtr pBSEIamge = AcquireABSEImage();
- if (!pBSEIamge)
- {
- // failed to acquire a BSE image
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview: failed to acquire a BSE image."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- //BSEData
- ST_MSTMsg MsgFieldBSE;
- memset(&MsgFieldBSE, 0, sizeof(ST_MSTMsg));
- MsgFieldBSE.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET::BSE_DATA;
- MsgFieldBSE.STMSampleRetData.BSEData.pos.x = poiFieldCentre.x;
- MsgFieldBSE.STMSampleRetData.BSEData.pos.y = poiFieldCentre.y;
- MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEIamge->GetHeight();
- MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEIamge->GetWidth();
- BYTE* pImgData = pBSEIamge->GetImageDataPointer();
- MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;
- //MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = new BYTE[MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight*MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth];
-
- //memcpy(MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData, pImgData, sizeof(BYTE)*MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight*MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth);
- LogErrorTrace(__FILE__, __LINE__, _T("C++ Position Message 4: OTS position x is %d, y is %d is sent in the message."), poiFieldCentre.x, poiFieldCentre.y);
- LogInfoTrace(__FILE__, __LINE__, _T("Message : ImageProcess: send BSE data. message type is %d"), MsgFieldBSE.iMsgType);
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldBSE);
- if (pStatus->GetStatus() != OTS_MSR_SAMPLE_STATUS::INPROCESS)
- {
- // measurement failed or stopped
- LogErrorTrace(__FILE__, __LINE__, _T("DoHolePreview: measurement failed or stopped."));
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- //save the result to project file
- CHoleBSEImgPtr pHoleBSEImg = CHoleBSEImgPtr(new CHoleBSEImg());
- pHoleBSEImg->SetHoleID(a_nHoleID);
- pHoleBSEImg->SetPosition(poiFieldCentre);
- CRect oImageRect = pBSEIamge->GetImageRect();
- long nImageSize = pBSEIamge->GetHeight() * pBSEIamge->GetWidth();
- pHoleBSEImg->SetImageRect(oImageRect);
- memcpy(pHoleBSEImg->GetImageDataPointer(), pBSEIamge->GetImageDataPointer(), sizeof(BYTE)*nImageSize);
-
- m_listHoleBSEImg.push_back(pHoleBSEImg);
- COTSProjMgrFilePtr pProjMgrFile = m_pMsrThread->GetProjMgrFile();
- pProjMgrFile->SetHoleBESImgList(m_listHoleBSEImg);
- // prepare for the next
- ++nNewFieldId;
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- ST_MSTMsg MsgFieldEnd;
- memset(&MsgFieldEnd, 0, sizeof(ST_MSTMsg));
- MsgFieldEnd.iMsgType = ENUM_MSG_TYPE::MSAMPLERESULT;
- MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET::FIELD_DATA;
- MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = (i + 1);
- MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = (int)listFieldCenter.size();
- MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = 0;
- MsgFieldEnd.STMSampleRetData.SFieldData.Fieldpos.x = poiFieldCentre.x;
- MsgFieldEnd.STMSampleRetData.SFieldData.Fieldpos.y = poiFieldCentre.y;
- LogInfoTrace(__FILE__, __LINE__, _T("Message: DoHolePreview: field %d measure end. message type is %d"), i, MsgFieldEnd.iMsgType);
- m_pMsrThread->SendMessageToMeasureApp(MsgFieldEnd);
- }
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- //calculate measure time
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::SUCCESSED);
- // let main thread to know that this sample measurement completes
- ST_MSTMsg MsgSmplEnd;
- memset(&MsgSmplEnd, 0, sizeof(ST_MSTMsg));
- MsgSmplEnd.iMsgType = ENUM_MSG_TYPE::MSAMPLESTATUS;
- MsgSmplEnd.STMSampleStu.iMeasureSampleStatus = (int)OTS_MSR_SAMPLE_STATUS::SUCCESSED;
- memcpy(MsgSmplEnd.STMSampleStu.cSampleName, m_pSample->GetName(), sizeof(m_pSample->GetName()));
-
- LogInfoTrace(__FILE__, __LINE__, _T("Message : DoHolePreview: sample %s end. message type is %d"), m_pSample->GetName(), MsgSmplEnd.iMsgType);
- m_pMsrThread->SendMessageToMeasureApp(MsgSmplEnd);
- }
- // hole BSE images list
- void CSmplMeasure::SetHoleBESImgList(CHoleBSEImgsList& a_listHoleBSEImg, BOOL a_bClear/* = TRUE*/)
- {// clear the hole BSE image list if necessary
- if (a_bClear)
- {
- m_listHoleBSEImg.clear();
- }
- // go through the input list
- for (auto pHoleBSEImg : a_listHoleBSEImg)
- {// add the new hole BSE image into HoleBSEImage list
- m_listHoleBSEImg.push_back(pHoleBSEImg);
- }
-
- }
- // samples list
- bool CSmplMeasure::SetSysSTDItem(CSTDItemsList& a_listSysSTDItem, BOOL a_bClear/* = TRUE*/)
- {// clear samples list if necessary
- if (a_bClear)
- {
- m_listSysSTDItem.clear();
- }
-
- // go through the sample list of the source
- for (auto pItem : a_listSysSTDItem)
- { // create a sample copy
- // add the new sample into sample list
- m_listSysSTDItem.push_back(pItem);
- }
- return true;
- }
- BOOL CSmplMeasure::IsSampleOver(COTSImageScanParamPtr a_pScanParam, int a_nTotalFields)
- {
- ASSERT(a_pScanParam);
- if (!a_pScanParam)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("IsSampleOver: invalid sample scan param."));
- return FALSE;
- }
- int nStopMode = (int)a_pScanParam->GetStopMode();
- int nStopField = a_pScanParam->GetStopParamFields();
- // completed fields number
- CMsrSampleStatusPtr pMsrSampleStatus = m_pSample->GetMsrStatus();
- int nCompeltedField = pMsrSampleStatus->GetCompletedFields();
- CMsrResultsPtr pMsrResults = m_pSample->GetMsrResults();
- CMsrResultItemsList listMsrResult = pMsrResults->GetResultItems();
- int nNumParticle = 0;
- for (auto pResult : listMsrResult)
- {
- if (pResult->GetTypeId() >(int) OTS_PARTCLE_TYPE::NO_ANALYSIS_X_RAY)//summarize the number of the identified particle in this condition
- {
- nNumParticle += pResult->GetNumber();
- }
- }
- COleDateTimeSpan timeSpan = pMsrSampleStatus->GetUsedTime();
- int nDay = timeSpan.GetDays();
- int nHour = timeSpan.GetHours();
- int nMin = timeSpan.GetMinutes();
- int nSec = timeSpan.GetSeconds();
- int nUsedTime = nSec + nMin * 60 + nHour * 3600 + nDay * 86400;
-
- int nParticlAim = a_pScanParam->GetStopParamParticles();
- int nMeasTimeAim = a_pScanParam->GetStopParamMeasTime();
- BOOL bRet = TRUE;
- switch(nStopMode)
- {
- case (int)OTS_MEASURE_STOP_MODE::CoverMode:
- // completed fields number
- if (nCompeltedField < a_nTotalFields )
- {
- LogInfoTrace(__FILE__, __LINE__, _T("IsSampleOver: sample measure has not finished."));
- bRet = FALSE;
- }
- break;
- case (int)OTS_MEASURE_STOP_MODE::FieldMode:
- if (nCompeltedField < nStopField)
- {
- LogInfoTrace(__FILE__, __LINE__, _T("IsSampleOver: sample measure has not finished."));
- bRet = FALSE;
- }
- break;
- case (int)OTS_MEASURE_STOP_MODE::ParticleMode:
-
- if (nNumParticle < nParticlAim)
- {
- LogInfoTrace(__FILE__, __LINE__, _T("IsSampleOver: sample measure has not finished."));
- bRet = FALSE;
- }
- break;
- case (int)OTS_MEASURE_STOP_MODE::TimeMode:
-
- if (nUsedTime < nMeasTimeAim)
- {
- LogInfoTrace(__FILE__, __LINE__, _T("IsSampleOver: sample measure has not finished."));
- bRet = FALSE;
- }
- break;
- default:
- break;
- }
- return bRet;
- }
-
- BOOL CSmplMeasure::SetPrjFileSave()
- {
- ASSERT(m_pMsrThread);
- if (!m_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetPrjFileSave: thread is null."));
- return FALSE;
- }
- COTSProjMgrFilePtr pProjMgr = m_pMsrThread->GetProjMgrFile();
- ASSERT(pProjMgr);
- if (!pProjMgr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetPrjFileSave: thread is null."));
- return FALSE;
- }
- pProjMgr->SetModify(TRUE);
- return TRUE;
-
- }
- BOOL CSmplMeasure::SetSEMDataMrs()
- {
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMDataMrs: prject sample is empty."));
- return FALSE;
- }
- CSEMDataMsrPtr pSEMDataMsr = m_pSample->GetSEMDataMsr();
- ASSERT(pSEMDataMsr);
- if (!pSEMDataMsr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMDataMrs: failed to get SEM measure data."));
- return FALSE;
- }
- if (*pSEMDataMsr.get() == CSEMDataMsr())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMDataMrs: SEM measure data is empty."));
- return FALSE;
- }
- double dMag = pSEMDataMsr->GetMagnification();
- double dWorkDis = pSEMDataMsr->GetWorkingDistance();
- CSemBasePtr pSEMCtrlPtr = GetSEMControl();
- ASSERT(pSEMCtrlPtr);
- if (!pSEMCtrlPtr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMDataMrs: failed to get SEM controller."));
- return FALSE;
- }
- // get SEM controller
- if (!pSEMCtrlPtr->IsConnected())
- {
- if (!pSEMCtrlPtr->Connect())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMDataMrs: can't connect SEM."));
- return FALSE;
- }
- }
- //LogInfoTrace(__FILE__, __LINE__, _T("SetSEMDataMrs:set mag and dis"));
- m_pMsrThread->SendLogMessageToMeasureApp("Set mag and dis", PostLogLevel::info);
- pSEMCtrlPtr->SetMagnification(dMag);
- pSEMCtrlPtr->SetWorkingDistance(dWorkDis);
- //LogInfoTrace(__FILE__, __LINE__, _T("SetSEMDataMrs:set mag and dis is over"));
- return TRUE;
- }
- // set SEM external on
- BOOL CSmplMeasure::SetSEMExteralOn()
- {
- CSemBasePtr pSEMCtrlPtr = m_pMsrThread->GetSEMController();
- ASSERT(pSEMCtrlPtr);
- if (!pSEMCtrlPtr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMExteralOn: failed to get SEM controller."));
- return FALSE;
- }
- // get SEM controller
- if (!pSEMCtrlPtr->IsConnected())
- {
- if (!pSEMCtrlPtr->Connect())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMExteralOn: can't connect SEM."));
- return FALSE;
- }
- }
- pSEMCtrlPtr->SetScanExternal(TRUE);
-
- return TRUE;
- }
- // set SEM external off
- BOOL CSmplMeasure::SetSEMExteralOff()
- {
- CSemBasePtr pSEMCtrlPtr = m_pMsrThread->GetSEMController();
- ASSERT(pSEMCtrlPtr);
- if (!pSEMCtrlPtr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMExteralOff: failed to get SEM controller."));
- return FALSE;
- }
- // get SEM controller
- if (!pSEMCtrlPtr->IsConnected())
- {
- if (!pSEMCtrlPtr->Connect())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetSEMExteralOff: can't connect SEM."));
- return FALSE;
- }
- }
- pSEMCtrlPtr->SetScanExternal(FALSE);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Set External Off!"), PostLogLevel::info);
- return TRUE;
- }
- // set BSE param
- BOOL CSmplMeasure::SetBSEParam()
- {
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: prject sample is empty."));
- return FALSE;
- }
- // get SEM controller
- CSemBasePtr pSEMController = GetSEMControl();
- if (!pSEMController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to get SEM control."));
- return FALSE;
- }
- // get scan controller
- COTSScanBasePtr pScanController = GetScanControl();
- if (!pScanController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to get scan control."));
- return FALSE;
- }
- // scan parameters
- CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
- COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam();
- // get image size
- OTS_FIVE_TIES_OPTIONS nImageSizeId = pImgScanParam->GetImagePixelSize();
- int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
- CSize sizePixelImage = RESOLUTION_VALUE[nResulotionId];
- // get SEM controller
- if (!pSEMController->IsConnected())
- {
- if (!pSEMController->Connect())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: can't connect SEM."));
- return FALSE;
- }
- }
- // get scan field size
- double dScanFieldSizeX = sizePixelImage.cx;
- double dScanFieldSizeY = sizePixelImage.cy;
- if (!pSEMController->GetScanFieldSize(dScanFieldSizeX, dScanFieldSizeY))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to call GetScanFieldSize method."));
- return FALSE;
- }
- // get dwell time
- OTS_THREE_TIES_OPTIONS nDwellTime = pImgScanParam->GetScanImageSpeed();
- // convert dwell time to bruker dwell time (6, 16, 32)
- long nBrukerDwellTimeId = DWELLTIME_BRUKER_ID_THREE_TIE_MIN + (int)nDwellTime;
- long nBrukerDwellTime = DWELLTIME_BRUKER_VALUES[nBrukerDwellTimeId];
- if (!pScanController->Init())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to get scan control."));
- return FALSE;
- }
- // set dwell time
- if (!pScanController->SetDwellTime(nBrukerDwellTime))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to set dwell time (%d) for bruker system."), nBrukerDwellTime);
- return FALSE;
- }
- // set image size
- if (!pScanController->SetImageSize(sizePixelImage.cx))
- {
- // failed to set dwell time
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to set dwell time (%d)."), sizePixelImage.cx);
- return FALSE;
- }
- return TRUE;
- }
- // reset Scan
- BOOL CSmplMeasure::ResetScan()
- {
- // get scan controller
- COTSScanBasePtr pScanController = GetScanControl();
- if (!pScanController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("SetBSEParam: failed to get scan control."));
- return FALSE;
- }
- // reset Scanner
- if (!pScanController->SetAndStartScan())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("AcquireABSEImage: failed to call SetAndStartScan method."));
- return FALSE;
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Reset Scan!"), PostLogLevel::info);
- return true;
- }
- // initialization
- void CSmplMeasure::Init()
- {
- m_pMsrThread = nullptr;
- m_strWorkingFolder = _T("");
-
- }
- // check if measurement is aborted
- BOOL CSmplMeasure::IsAborted()
- {
- ASSERT(m_pMsrThread);
- return m_pMsrThread->IsMeasureStopped();
- }
- // hardware control
- CSemBasePtr CSmplMeasure::GetSEMControl()
- {
- // SEM controller
- CSemBasePtr pSEMController = nullptr;
- // safety check
- ASSERT(m_pMsrThread);
- if (!m_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetSEMControl: invalid measure thread pointer."));
- return pSEMController;
- }
- // get SEM controller
- pSEMController = m_pMsrThread->GetSEMController();
- // return SEM controller
- return pSEMController;
- }
- COTSScanBasePtr CSmplMeasure::GetScanControl()
- {
- // scan controller
- COTSScanBasePtr pScanController = nullptr;
- // safety check
- ASSERT(m_pMsrThread);
- if (!m_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetScanControl: invalid measure thread pointer."));
- return pScanController;
- }
- // get scan controller
- pScanController = m_pMsrThread->GetScanController();
- // return scan controller
- return pScanController;
- }
- COTSEDSBasePtr CSmplMeasure::GetEDSControl()
- {
- // EDS controller
- COTSEDSBasePtr pEDSController = nullptr;
- // safety check
- ASSERT(m_pMsrThread);
- if (!m_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetEDSControl: invalid measure thread pointer."));
- return pEDSController;
- }
- // get EDS controller
- pEDSController = m_pMsrThread->GetEDSController();
- // return EDS controller
- return pEDSController;
- }
- // get SEM condition (general)
- BOOL CSmplMeasure::RecordSEMCondition(CSEMDataGnrPtr a_pSEMDataGnr)
- {
- // safety check
- ASSERT(a_pSEMDataGnr);
- if (!a_pSEMDataGnr)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("RecordSEMCondition: invalid input pointer."));
- return FALSE;
- }
- // get SEM controller
- CSemBasePtr pSEMCotroller = GetSEMControl();
- ASSERT(pSEMCotroller);
- if (!pSEMCotroller)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("RecordSEMCondition: failed to get SEM controller."));
- return FALSE;
- }
- // get SEM condition (general)
- if (!pSEMCotroller->GetSEMDataGnr(a_pSEMDataGnr))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("RecordSEMCondition: failed to call GetSEMDataGnr method."));
- return FALSE;
- }
- // ok, return TRUE
- return TRUE;
- }
- // calculate field centers
- BOOL CSmplMeasure::CalculateUnMeasuredFieldsCenters(std::vector<CPoint>& a_listFieldCenter)
- {
- // safety check
- ASSERT(m_pSample);
- // sample measure parameters
- CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
- COTSImageScanParamPtr poImageScanParam = pMsrParam->GetImageScanParam();
- CSEMDataMsrPtr poSEMDataMsr = m_pSample->GetSEMDataMsr();
- CMsrSampleStatusPtr pMsrStatus = m_pSample->GetMsrStatus();
- // measured field centers list
- std::vector<CPoint>& listCompletedCenter = pMsrStatus->GetCompletedFieldsCenter();
- // field centers list manager
- CFieldMgrPtr pFieldMgr = CFieldMgrPtr(new CFieldMgr());
- // init field centers list manager
- if (!pFieldMgr->Init(m_pSample->GetMsrArea(), poImageScanParam, poSEMDataMsr, listCompletedCenter))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("CalculateFieldsCenters: failed to init field centres list manager."));
- return FALSE;
- }
- // get field centers list
- a_listFieldCenter = pFieldMgr->GetUnmeasuredFieldCentrePoints();// GetFieldCentrePoints();
-
- // ok, return TRUE
- return TRUE;
- }
- // move SEM to the point
- BOOL CSmplMeasure::MoveSEMToPoint(CPoint a_poi)
- {
- /*Sleep(500);*/
- // get SEM controller
- CSemBasePtr pSEMController = GetSEMControl();
- ASSERT(pSEMController);
- if (!pSEMController)
- {
- // failed to get SEM control
- LogErrorTrace(__FILE__, __LINE__, _T("MoveSEMToPoint: failed to get SEM control."));
- return FALSE;
- }
- CPoint a_SEMpt;
- CStageFilePtr pStageFile = CStageFilePtr(new CStageFile());
- CSEMStageDataPtr a_pCSEMStageData = m_pMsrThread->GetProjMgrFile()->GetSEMStageData();
- pStageFile->SetStageData(a_pCSEMStageData);
- //LogErrorTrace(__FILE__, __LINE__, _T("C++ Position Message 2: OTS position x is %d, y is %d."), a_poi.x, a_poi.y);
- if (!pStageFile->ConverOTSToSEMPoint(a_poi, a_SEMpt))
- {
- return FALSE;
- }
- //LogErrorTrace(__FILE__, __LINE__, _T("C++ Position Message 3: SEM position x is %d, y is %d."), a_SEMpt.x, a_SEMpt.y);
- if (!pSEMController->IsConnected())
- {
- if (!pSEMController->Connect())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("MoveSEMToPoint: can't connect SEM."));
- return FALSE;
- }
- }
- // move SEM to the position (rotation 0)
- if (!pSEMController->MoveSEMToPoint(a_SEMpt, 0))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("MoveSEMToPoint: failed to call MoveSEMToPoint method."));
- return FALSE;
- }
- //Sleep(500);
- return TRUE;
- }
- // Acquire a BSE image
- CBSEImgPtr CSmplMeasure::AcquireABSEImage()
- {
- // BSE image
- CBSEImgPtr pBSEImage = nullptr;
- // safety check
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("AcquireABSEImage: invalid sample pointer."));
- return FALSE;
- }
- // get scan controller
- COTSScanBasePtr pScanController = GetScanControl();
- if (!pScanController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("AcquireABSEImage: failed to get scan control."));
- return pBSEImage;
- }
- try
- {
- pBSEImage = pScanController->AcquireBSEImage(0, 0, 2);
- if (pBSEImage==nullptr)
- {
- return nullptr;
- //LogErrorTrace(__FILE__, __LINE__, _T("AcquireABSEImage: the BSE image is invalid."));
- }
- }
- catch (...)
- {
- //LogErrorTrace(__FILE__, __LINE__, _T("AcquireABSEImage: catch an exception when call AcquireBSEImage method."));
- return nullptr;
- }
-
- return pBSEImage;
- }
- // get x-ray acquire time
- BOOL CSmplMeasure::GetXRayAcquireTime(XRAY_TYPE a_nXrayType, OTS_THREE_TIES_OPTIONS a_nXraySpeed, DWORD& a_nXRayAQTime)
- {
- // safety check
- ASSERT(m_pMsrThread);
- if (!m_pMsrThread)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayAcquireTime: invalid thread pointer."));
- return FALSE;
- }
- // get project manager file
- COTSProjMgrFilePtr pOTSProjMgrFile = m_pMsrThread->GetProjMgrFile();
- ASSERT(pOTSProjMgrFile);
- if (!pOTSProjMgrFile)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayAcquireTime: failed to get project manager file."));
- return FALSE;
- }
- // x-ray parameters
- COTSXRayParamPtr pXRayParam = pOTSProjMgrFile->GetXRayParam();
- ASSERT(pXRayParam);
- if (!pXRayParam)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayAcquireTime: failed to get x-ray parameters."));
- return FALSE;
- }
- a_nXRayAQTime = (DWORD)pXRayParam->GetMidAnalyAQTime();
-
- // ok, return TRUE
- return TRUE;
- }
- // get x-rays
- BOOL CSmplMeasure::GetXRayByPoints(CPosXraysList& a_listPosXRay, DWORD a_nXRayAQTime, BOOL a_bElementInfo /*= FALSE*/)
- {
- // get EDS controller
- COTSEDSBasePtr pEDSController = GetEDSControl();
- ASSERT(pEDSController);
- if (!pEDSController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByPoints: failed to get EDS controller."));
- return FALSE;
- }
- // init EDS controller
- if (!pEDSController->Init())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByPoints: failed to inti EDS (%s)."), pEDSController->GetName());
- return FALSE;
- }
- //// set get quantify info flag, firstly only get x-ray data
- if (!a_bElementInfo)
- {
- pEDSController->SetQuantification(FALSE);
- }
- else
- {
- // get element, because only the first point can get element
- pEDSController->SetQuantification(TRUE);
- }
- int nSize = (int)a_listPosXRay.size();
- if (nSize > 1024)
- {
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Too many point Xray! Divide into multi times!"), PostLogLevel::error);
- int nTimes = nSize / 1024;
- CPosXraysList listPosXRayTemp;
- for (int i = 0; i < nTimes; i++)
- {
- listPosXRayTemp.clear();
- for (int m = 0; m < 1024; m++)
- {
- listPosXRayTemp.push_back(a_listPosXRay[i * 1024 + m]);
- }
- if (!pEDSController->GetXRayByPoints(listPosXRayTemp, a_nXRayAQTime))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByPoints: failed to get element."));
- return FALSE;
- }
- }
- int nLast = nSize % 1024;
- if (nLast != 0)
- {
- listPosXRayTemp.clear();
- for (int m = 0; m < nLast; m++)
- {
- listPosXRayTemp.push_back(a_listPosXRay[nTimes * 1024 + m]);
- }
- if (!pEDSController->GetXRayByPoints(listPosXRayTemp, a_nXRayAQTime))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByPoints: failed to get element."));
- return FALSE;
- }
- }
- }
- else
- {
- if (!pEDSController->GetXRayByPoints(a_listPosXRay, a_nXRayAQTime))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByPoints: failed to get element."));
- return FALSE;
- }
- }
- // ok, return TRUE
- return TRUE;
- }
- BOOL CSmplMeasure::GetXRayByFeatures(COTSParticleList& a_listParticles, CPosXraysList& a_listPosXRay, DWORD a_nXRayAQTime, BOOL a_bElementInfo /*= FALSE*/)
- {
-
- // get EDS controller
- COTSEDSBasePtr pEDSController = GetEDSControl();
- ASSERT(pEDSController);
- if (!pEDSController)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByFeatures: failed to get EDS controller."));
- return FALSE;
- }
- // get out if particles list is empty
- if (a_listParticles.size() == 0)
- {
- return TRUE;
- }
- // init EDS controller
- if (!pEDSController->Init())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByFeatures: failed to inti EDS (%s)."), pEDSController->GetName());
- return FALSE;
- }
- // set get quantify info flag
- pEDSController->SetQuantification(a_bElementInfo);
- int nSize = (int)a_listParticles.size();
- if (nSize > 512)
- {
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Too many feature Xray! Divide into multi times!"), PostLogLevel::error);
- }
- int nTimes = nSize / 512;
- int nLast = nSize % 512;
- if (nLast != 0)
- {
- nTimes += 1;
- }
- COTSParticleList listPartTemp;
- CPosXraysList listPosXRayTemp;
- for (int i = 0; i < nTimes; i++)
- {
- listPartTemp.clear();
- listPosXRayTemp.clear();
- for (int m = 0; m < 512; m++)
- {
- if (i * 512 + m < nSize)
- {
- listPartTemp.push_back(a_listParticles[i * 512 + m]);
- listPosXRayTemp.push_back(a_listPosXRay[i * 512 + m]);
- }
- else
- {
- break;
- }
- }
- // get the features list of the particles
- std::vector<std::vector<BrukerSegment>> listBrukerFeatures;//covert these particles into brukerfeatures.
- for (auto pPart : listPartTemp)
- {
- auto pFeature = pPart->GetFeature();
- COTSSegmentsList listSegment = pFeature->GetSegmentsList();
- std::vector<BrukerSegment> listBrukSegment;
- for (auto Segment : listSegment)
- {
- BrukerSegment BrukSeg;
- BrukSeg.XCount = Segment->GetLength();
- BrukSeg.Y = Segment->GetHeight();
- BrukSeg.XStart = Segment->GetStart();
- listBrukSegment.push_back(BrukSeg);
- }
- listBrukerFeatures.push_back(listBrukSegment);
- }
- if (listPosXRayTemp.size() > 0)
- {
- if (!pEDSController->GetXRayByFeatures(listPosXRayTemp, listBrukerFeatures, a_nXRayAQTime))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetXRayByFeatures: failed to get xray by features."));
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- // get pixel size
- BOOL CSmplMeasure::GetPixelSize(double& a_dPixelSize)
- {
- // safety check
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("GetPixelSize: invalid sample pointer."));
- return FALSE;
- }
- a_dPixelSize = m_pSample->CalculatePixelSize();
- return TRUE;
- }
- // save a field
- BOOL CSmplMeasure::SaveSampleFile()
- {
- // save the file
- CString strPathName = m_pSmplMsrResultFileMgr->GetPathName();
- if (!m_pSmplMsrResultFileMgr->Save(strPathName))
- {
- // failed to save the file
- LogErrorTrace(__FILE__, __LINE__, _T("SaveAField: failed to save the file."));
- return FALSE;
- }
- // ok, return TRUE
- return TRUE;
- }
- }
|