| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- #include "stdafx.h"
- #include "SmplMeasureInc.h"
- #include "OTSFieldMgr.h"
- #include "STDXMLFileMnr.h"
- #include "OTSClassifyEng.h"
- #include<windows.h>
- #include "IClassifyEngine.h"
- namespace OTSMODEL
- {
- using namespace OTSClassifyEngine;
- CSmplMeasureInc::CSmplMeasureInc()
- {
-
- }
- CSmplMeasureInc::CSmplMeasureInc(CString a_strWorkingFolder,COTSSamplePtr a_pSample):CSmplMeasure(a_strWorkingFolder, a_pSample)
- {
- }
- CSmplMeasureInc::~CSmplMeasureInc()
- {
- bSaveThreadWorking = false;
- }
- // class methods
- // public
- // field image process
- void CSmplMeasureInc::ImageProcess(COTSFieldDataPtr a_pFieldData, CBSEImgPtr a_pBSEImg)
- {
- // measure status
- CMsrSampleStatusPtr pStatus = m_pSample->GetMsrStatus();
-
- // EDS controller
- COTSEDSBasePtr pEDSController = GetEDSControl();
- ASSERT(pEDSController);
- if (!pEDSController)
- {// failed to get EDS controller
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
- // create a field data manager
- COTSFieldMgrPtr pFieldMgr = COTSFieldMgrPtr(new COTSFieldMgr());
- pFieldMgr->SetMsrStatus(pStatus);
- if (!pFieldMgr->Init(a_pFieldData, a_pBSEImg))
- {// failed to initialize the field data manager
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
- // get image process parameter
- CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
- COTSImageProcessParamPtr pImgProcessParam = pMsrParam->GetImageProcessParam();
-
- /* remove BES image background */
- if (!pFieldMgr->RemoveBSEImageBG(pImgProcessParam))
- {// failed to call RemoveBSEImageBG method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T(" Image Process Success!"), PostLogLevel::info);
- // check if this is an empty image
- if (pFieldMgr->NoParticle())
- {// empty fields
- m_pMsrThread->SendLogMessageToMeasureApp(_T(" Image have no particles!"), PostLogLevel::warn);
- return;
- }
-
- // remove over sized particles, too small particles and get a analysis particles list
- // get pixel size
- double dPixelSize;
- if (!GetPixelSize(dPixelSize))
- {// failed to call GetPixelSize method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
-
- //Get measured area
- DWORD nMeasuredArea = 0; // this area should be the field area
- nMeasuredArea = (DWORD)(a_pBSEImg->GetHeight() * a_pBSEImg->GetWidth() * dPixelSize * dPixelSize + 0.5);
- // get x-ray parameters
- COTSXRayParamPtr pXRayParam = pMsrParam->GetXRayParam();
- // calculate search x-ray acquire time
- DWORD nXRayAQTime;
- COTSParticleList listAnalysisParticles;
- CPosXraysList listAnalysisXRay;
- ////=============================================
- //// particle x-ray analysis
- ////=============================================
- if (!pFieldMgr->ProcessParticles(pImgProcessParam, dPixelSize, listAnalysisParticles))
- {// failed to call ProcessParticles method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
-
- return;
- }
-
- // make sure if the particles list is not empty
- if (listAnalysisParticles.empty())
- {
- StartSaveFileThread(pFieldMgr);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("There is no particles to be analyzed!"), PostLogLevel::warn);
- return;
- }
- if (!pFieldMgr->CreateXrayList(listAnalysisParticles, listAnalysisXRay))
- {// failed to call CreateXrayList method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
-
- return;
- }
- if (listAnalysisParticles.size() != listAnalysisXRay.size())
- {
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
-
- return;
- }
- // let the main thread to know that particle analysis x-ray is done and number of x-ray points
- nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
-
- if (pXRayParam->GetScanMode() == OTS_X_RAY_SCAN_MODE::PointMode)
- {// get x-ray list (analysis) by points
- nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
- CString xraymsg;
- xraymsg.Format("Begin point mode xray collection,AQTime:%d XrayNum:%d", nXRayAQTime, listAnalysisParticles.size());
- m_pMsrThread->SendLogMessageToMeasureApp(xraymsg, PostLogLevel::info);
- if (!GetXRayByPoints(listAnalysisXRay, nXRayAQTime, TRUE))
- {// failed to call GetXRayByPoints method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
- m_pMsrThread->SendLogMessageToMeasureApp("Xray collection failed!", PostLogLevel::info);
- return;
- }
- }
- else
- {// get x-ray list (analysis) by particle features
- nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
- CString xraymsg;
- xraymsg.Format("Begin feature mode xray collection,AQTime:%d XrayNum:%d", nXRayAQTime, listAnalysisParticles.size());
- m_pMsrThread->SendLogMessageToMeasureApp(xraymsg, PostLogLevel::info);
- if (!GetXRayByFeatures(listAnalysisParticles, listAnalysisXRay, nXRayAQTime, TRUE))
- {
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
- m_pMsrThread->SendLogMessageToMeasureApp("Xray collection failed!", PostLogLevel::info);
- return;
- }
- }
- m_pMsrThread->SendLogMessageToMeasureApp(_T(" Xray collection finished!"), PostLogLevel::info);
- // let the main thread to know that is about to do particle analysis x-ray and number of x-ray points
- // save analysis x-ray into field data
- pFieldMgr->SetAnalysisPosXayList(listAnalysisXRay);
- CString xraymsg;
- xraymsg.Format("Begin to classify particles! num:%d", listAnalysisParticles.size());
- m_pMsrThread->SendLogMessageToMeasureApp(xraymsg , PostLogLevel::info);
- // classify Particles
- if(!ClassifyParticles(listAnalysisParticles, listAnalysisXRay))
- {
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- StartSaveFileThread(pFieldMgr);
- return;
- }
- // save field files
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to save the result to database!"), PostLogLevel::info);
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::SUCCESSED);
- StartSaveFileThread(pFieldMgr);
- m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to do the statistics and display on screen!"), PostLogLevel::info);
- // on-line classification (field)
- if (!pFieldMgr->OnLineClassification())
- {
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
- // Cumulate field data info into sample
- if (!CumulateFieldData(pFieldMgr->GetMsrResult(), nMeasuredArea))
- {// failed to call SaveFieldFile method
- pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
- return;
- }
-
- // record end time
- pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
- return;
- }
- void CSmplMeasureInc::SaveFieldMgrData()
- {
- while( bSaveThreadWorking)
- {
- while (fieldQueue.size() > 0)
- {
- COTSFieldMgrPtr f = fieldQueue.front();
- double pixelSize = 0;
- this->GetPixelSize(pixelSize);
- try
- {
- f->CalIncAParticleImageProp(pixelSize);
- f->SaveFieldFiles();
- }
- catch (const std::exception&)
- {
- LogErrorTrace(__FILE__, __LINE__, _T("ImageProcess: calcu the particle image property or save to db failed."));
- }
-
- //save to disk first ,then pop . if the size is 0,then we know all the saving work is done.
- fieldQueue.pop();
- }
- if (fieldQueue.size() == 0)
- {
- bSaveThreadWorking = false;//must set this flag,so the main thread can know this thread has exited.
- return;
- }
- }
-
-
- return;
- }
- void CSmplMeasureInc::StartSaveFileThread(COTSFieldMgrPtr a_pFieldMgr)
- {
- ASSERT(a_pFieldMgr);
- if (!a_pFieldMgr)
- {
- // invalid sample pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("StartSaveFileThread: empty field pointer."));
- return;
- }
- fieldQueue.push(a_pFieldMgr);
- if (fieldQueue.size() > 0)//if there's data in the queue and the previous thread has finished then start a new thread.
- {
- if (bSaveThreadWorking == false)
- {
- bSaveThreadWorking = true;
- m_thread_ptr = shared_ptr<thread>(new thread(&CSmplMeasureInc::SaveFieldMgrData, this));
- m_thread_ptr->detach();
- }
- }
- }
-
- // Cumulate field data info
- BOOL CSmplMeasureInc::CumulateFieldData(CMsrResultsPtr a_pFieldMsrResults, DWORD a_nMeasuredArea)
- {
- // safety check
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- // invalid sample pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("CumulateFieldData: invalid sample pointer."));
- return FALSE;
- }
- ASSERT(a_pFieldMsrResults);
- if (!a_pFieldMsrResults)
- {
- // invalid field measure result pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("CumulateFieldData: invalid field measure result pointer."));
- return FALSE;
- }
- // get measure result items
- CMsrResultItemsList& listResultItems = a_pFieldMsrResults->GetResultItems();
- // get measure result items of the sample
- CMsrResultsPtr pMsrResults = m_pSample->GetMsrResults();
- // cumulate field data info
- pMsrResults->CumulateMeasureResults(listResultItems);
- pMsrResults->CumulateMeasuredArea(a_nMeasuredArea);
- // cumulate ratio
- double dRatio = 10000 * pMsrResults->GetTotalParticleArea();
- dRatio = dRatio / pMsrResults->GetMeasuredArea();
- pMsrResults->SetRadio(dRatio);
- // ok, return TRUE
- return TRUE;
- }
- // protected
- // classify particles
- BOOL CSmplMeasureInc::ClassifyParticles(COTSParticleList& a_listAnalysisParticles, CPosXraysList& a_listAnalysisXRay)
- {
- // make sure the two lists are same size
- int nSize = (int)a_listAnalysisParticles.size();
- if ( nSize != (int)a_listAnalysisXRay.size())
- {
- // particles list size is different with x-ray size
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticles: particles list size is different with x-ray size."));
- return FALSE;
- }
- // go through all analysis particles
- for (int i = 0; i < nSize; ++i)
- {
- COTSParticlePtr pParticle = a_listAnalysisParticles[i];
- CPosXrayPtr pXray = a_listAnalysisXRay[i];
- if (!ClassifyParticle(pParticle, pXray))
- {
- // failed to call ClassifyParticle method
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticles: failed to call ClassifyParticle method."));
- return FALSE;
- }
- }
- // ok, return TRUE
- return TRUE;
- }
- BOOL CSmplMeasureInc::ClassifyParticle(COTSParticlePtr a_pParticle, CPosXrayPtr a_pXRay)
- {
- //set the particle type to NOT_IDENTIFIED
- int nInclusionID = (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED;
- // safety check
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- // invalid sample pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid sample pointer."));
- return FALSE;
- }
- ASSERT(a_pParticle);
- if (!a_pParticle)
- {
- // invalid particle pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid particle pointer."));
- return FALSE;
- }
- ASSERT(a_pXRay);
- if (!a_pXRay)
- {
- // invalid x-ray pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid x-ray pointer."));
- return FALSE;
- }
- //// 1.get elementChemistries
- CElementChemistriesList listElementChemistriesOld = a_pXRay->GetElementQuantifyData();
- //get the parameter MsrParam object
- CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
- //get the steel technology parameter
- STEEL_TECHNOLOGY steelTech = pMsrParam->GetSteelTechnology();
- //get standard database item which will be used when classify.
- CPartSTDDataPtr pPartSTDData = pMsrParam->GetPartSTDData();
- int listSize = pPartSTDData->GetSTDItemsList().size();
-
- if(!COTSClassifyEng::ClassifyXray(pPartSTDData,steelTech, listElementChemistriesOld, nInclusionID))
- {
- // invalid x-ray pointer.
- LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: can't identify the particle as any inclusion."));
- return FALSE;
- }
- if (nInclusionID<7)
- {
- nInclusionID = (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED;
- }
- if (nInclusionID == (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED)
- {
- //OTSClassifyEngine::CLEEnginePtr en = GetParticleEngine();
- //en->Classify(a_pParticle, a_pXRay);//if there is a item match the particle then the item's typeId, color and name will be put into the particle.
- }
- else
- {
- auto stdItem = pPartSTDData->GetSTDItemById(nInclusionID);
- if (stdItem != nullptr)
- {
- a_pParticle->SetType(nInclusionID);
- a_pParticle->TypeName(stdItem->GetName().GetBuffer());
- a_pParticle->TypeColor(stdItem->GetColor().GetBuffer());
- }
- }
-
- return TRUE;
- }
- // check sample STD to make sure it will not be an empty one
- BOOL CSmplMeasureInc::CheckSmplSTD()
- {
- // safety check
- ASSERT(m_pSample);
- if (!m_pSample)
- {
- // invalid sample handle
- LogErrorTrace(__FILE__, __LINE__, _T("CheckSmplSTD: invalid sample handle."));
- return FALSE;
- }
- // get sample measure parameter
- CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
- // get sample STD
- CPartSTDDataPtr pPartSTDData = pMsrParam->GetPartSTDData();
- // check if sample STD is empty
- if (*pPartSTDData.get() == CPartSTDData())
- {
- // sample STD is empty, replace it with system STD
- pPartSTDData->SetSTDItemsList(m_listSysSTDItem, TRUE);
- }
- // ok, return true
- return TRUE;
- }
- }
|