SmplMeasureInc.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #include "stdafx.h"
  2. #include "SmplMeasureInc.h"
  3. #include "OTSFieldMgr.h"
  4. #include "STDXMLFileMnr.h"
  5. #include "OTSClassifyEng.h"
  6. #include<windows.h>
  7. #include "IClassifyEngine.h"
  8. namespace OTSMODEL
  9. {
  10. using namespace OTSClassifyEngine;
  11. CSmplMeasureInc::CSmplMeasureInc()
  12. {
  13. }
  14. CSmplMeasureInc::CSmplMeasureInc(CString a_strWorkingFolder,COTSSamplePtr a_pSample):CSmplMeasure(a_strWorkingFolder, a_pSample)
  15. {
  16. }
  17. CSmplMeasureInc::~CSmplMeasureInc()
  18. {
  19. bSaveThreadWorking = false;
  20. }
  21. // class methods
  22. // public
  23. // field image process
  24. void CSmplMeasureInc::ImageProcess(COTSFieldDataPtr a_pFieldData, CBSEImgPtr a_pBSEImg)
  25. {
  26. // measure status
  27. CMsrSampleStatusPtr pStatus = m_pSample->GetMsrStatus();
  28. // EDS controller
  29. COTSEDSBasePtr pEDSController = GetEDSControl();
  30. ASSERT(pEDSController);
  31. if (!pEDSController)
  32. {// failed to get EDS controller
  33. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  34. return;
  35. }
  36. // create a field data manager
  37. COTSFieldMgrPtr pFieldMgr = COTSFieldMgrPtr(new COTSFieldMgr());
  38. pFieldMgr->SetMsrStatus(pStatus);
  39. if (!pFieldMgr->Init(a_pFieldData, a_pBSEImg))
  40. {// failed to initialize the field data manager
  41. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  42. return;
  43. }
  44. // get image process parameter
  45. CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
  46. COTSImageProcessParamPtr pImgProcessParam = pMsrParam->GetImageProcessParam();
  47. /* remove BES image background */
  48. if (!pFieldMgr->RemoveBSEImageBG(pImgProcessParam))
  49. {// failed to call RemoveBSEImageBG method
  50. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  51. return;
  52. }
  53. m_pMsrThread->SendLogMessageToMeasureApp(_T(" Image Process Success!"), PostLogLevel::info);
  54. // check if this is an empty image
  55. if (pFieldMgr->NoParticle())
  56. {// empty fields
  57. m_pMsrThread->SendLogMessageToMeasureApp(_T(" Image have no particles!"), PostLogLevel::warn);
  58. return;
  59. }
  60. // remove over sized particles, too small particles and get a analysis particles list
  61. // get pixel size
  62. double dPixelSize;
  63. if (!GetPixelSize(dPixelSize))
  64. {// failed to call GetPixelSize method
  65. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  66. return;
  67. }
  68. //Get measured area
  69. DWORD nMeasuredArea = 0; // this area should be the field area
  70. nMeasuredArea = (DWORD)(a_pBSEImg->GetHeight() * a_pBSEImg->GetWidth() * dPixelSize * dPixelSize + 0.5);
  71. // get x-ray parameters
  72. COTSXRayParamPtr pXRayParam = pMsrParam->GetXRayParam();
  73. // calculate search x-ray acquire time
  74. DWORD nXRayAQTime;
  75. COTSParticleList listAnalysisParticles;
  76. CPosXraysList listAnalysisXRay;
  77. ////=============================================
  78. //// particle x-ray analysis
  79. ////=============================================
  80. if (!pFieldMgr->ProcessParticles(pImgProcessParam, dPixelSize, listAnalysisParticles))
  81. {// failed to call ProcessParticles method
  82. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  83. StartSaveFileThread(pFieldMgr);
  84. return;
  85. }
  86. // make sure if the particles list is not empty
  87. if (listAnalysisParticles.empty())
  88. {
  89. StartSaveFileThread(pFieldMgr);
  90. m_pMsrThread->SendLogMessageToMeasureApp(_T("There is no particles to be analyzed!"), PostLogLevel::warn);
  91. return;
  92. }
  93. if (!pFieldMgr->CreateXrayList(listAnalysisParticles, listAnalysisXRay))
  94. {// failed to call CreateXrayList method
  95. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  96. StartSaveFileThread(pFieldMgr);
  97. return;
  98. }
  99. if (listAnalysisParticles.size() != listAnalysisXRay.size())
  100. {
  101. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  102. StartSaveFileThread(pFieldMgr);
  103. return;
  104. }
  105. // let the main thread to know that particle analysis x-ray is done and number of x-ray points
  106. nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
  107. if (pXRayParam->GetScanMode() == OTS_X_RAY_SCAN_MODE::PointMode)
  108. {// get x-ray list (analysis) by points
  109. nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
  110. CString xraymsg;
  111. xraymsg.Format("Begin point mode xray collection,AQTime:%d XrayNum:%d", nXRayAQTime, listAnalysisParticles.size());
  112. m_pMsrThread->SendLogMessageToMeasureApp(xraymsg, PostLogLevel::info);
  113. if (!GetXRayByPoints(listAnalysisXRay, nXRayAQTime, TRUE))
  114. {// failed to call GetXRayByPoints method
  115. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  116. StartSaveFileThread(pFieldMgr);
  117. m_pMsrThread->SendLogMessageToMeasureApp("Xray collection failed!", PostLogLevel::info);
  118. return;
  119. }
  120. }
  121. else
  122. {// get x-ray list (analysis) by particle features
  123. nXRayAQTime = pXRayParam->GetMidAnalyAQTime();
  124. CString xraymsg;
  125. xraymsg.Format("Begin feature mode xray collection,AQTime:%d XrayNum:%d", nXRayAQTime, listAnalysisParticles.size());
  126. m_pMsrThread->SendLogMessageToMeasureApp(xraymsg, PostLogLevel::info);
  127. if (!GetXRayByFeatures(listAnalysisParticles, listAnalysisXRay, nXRayAQTime, TRUE))
  128. {
  129. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  130. StartSaveFileThread(pFieldMgr);
  131. m_pMsrThread->SendLogMessageToMeasureApp("Xray collection failed!", PostLogLevel::info);
  132. return;
  133. }
  134. }
  135. m_pMsrThread->SendLogMessageToMeasureApp(_T(" Xray collection finished!"), PostLogLevel::info);
  136. // let the main thread to know that is about to do particle analysis x-ray and number of x-ray points
  137. // save analysis x-ray into field data
  138. pFieldMgr->SetAnalysisPosXayList(listAnalysisXRay);
  139. CString xraymsg;
  140. xraymsg.Format("Begin to classify particles! num:%d", listAnalysisParticles.size());
  141. m_pMsrThread->SendLogMessageToMeasureApp(xraymsg , PostLogLevel::info);
  142. // classify Particles
  143. if(!ClassifyParticles(listAnalysisParticles, listAnalysisXRay))
  144. {
  145. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  146. StartSaveFileThread(pFieldMgr);
  147. return;
  148. }
  149. // save field files
  150. m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to save the result to database!"), PostLogLevel::info);
  151. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::SUCCESSED);
  152. StartSaveFileThread(pFieldMgr);
  153. m_pMsrThread->SendLogMessageToMeasureApp(_T("Begin to do the statistics and display on screen!"), PostLogLevel::info);
  154. // on-line classification (field)
  155. if (!pFieldMgr->OnLineClassification())
  156. {
  157. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  158. return;
  159. }
  160. // Cumulate field data info into sample
  161. if (!CumulateFieldData(pFieldMgr->GetMsrResult(), nMeasuredArea))
  162. {// failed to call SaveFieldFile method
  163. pStatus->SetStatus(OTS_MSR_SAMPLE_STATUS::FAILED);
  164. return;
  165. }
  166. // record end time
  167. pStatus->ComputeTime(OTS_MSR_TIME_TYPE::STOPPED);
  168. return;
  169. }
  170. void CSmplMeasureInc::SaveFieldMgrData()
  171. {
  172. while( bSaveThreadWorking)
  173. {
  174. while (fieldQueue.size() > 0)
  175. {
  176. COTSFieldMgrPtr f = fieldQueue.front();
  177. double pixelSize = 0;
  178. this->GetPixelSize(pixelSize);
  179. try
  180. {
  181. f->CalIncAParticleImageProp(pixelSize);
  182. f->SaveFieldFiles();
  183. }
  184. catch (const std::exception&)
  185. {
  186. LogErrorTrace(__FILE__, __LINE__, _T("ImageProcess: calcu the particle image property or save to db failed."));
  187. }
  188. //save to disk first ,then pop . if the size is 0,then we know all the saving work is done.
  189. fieldQueue.pop();
  190. }
  191. if (fieldQueue.size() == 0)
  192. {
  193. bSaveThreadWorking = false;//must set this flag,so the main thread can know this thread has exited.
  194. return;
  195. }
  196. }
  197. return;
  198. }
  199. void CSmplMeasureInc::StartSaveFileThread(COTSFieldMgrPtr a_pFieldMgr)
  200. {
  201. ASSERT(a_pFieldMgr);
  202. if (!a_pFieldMgr)
  203. {
  204. // invalid sample pointer.
  205. LogErrorTrace(__FILE__, __LINE__, _T("StartSaveFileThread: empty field pointer."));
  206. return;
  207. }
  208. fieldQueue.push(a_pFieldMgr);
  209. if (fieldQueue.size() > 0)//if there's data in the queue and the previous thread has finished then start a new thread.
  210. {
  211. if (bSaveThreadWorking == false)
  212. {
  213. bSaveThreadWorking = true;
  214. m_thread_ptr = shared_ptr<thread>(new thread(&CSmplMeasureInc::SaveFieldMgrData, this));
  215. m_thread_ptr->detach();
  216. }
  217. }
  218. }
  219. // Cumulate field data info
  220. BOOL CSmplMeasureInc::CumulateFieldData(CMsrResultsPtr a_pFieldMsrResults, DWORD a_nMeasuredArea)
  221. {
  222. // safety check
  223. ASSERT(m_pSample);
  224. if (!m_pSample)
  225. {
  226. // invalid sample pointer.
  227. LogErrorTrace(__FILE__, __LINE__, _T("CumulateFieldData: invalid sample pointer."));
  228. return FALSE;
  229. }
  230. ASSERT(a_pFieldMsrResults);
  231. if (!a_pFieldMsrResults)
  232. {
  233. // invalid field measure result pointer.
  234. LogErrorTrace(__FILE__, __LINE__, _T("CumulateFieldData: invalid field measure result pointer."));
  235. return FALSE;
  236. }
  237. // get measure result items
  238. CMsrResultItemsList& listResultItems = a_pFieldMsrResults->GetResultItems();
  239. // get measure result items of the sample
  240. CMsrResultsPtr pMsrResults = m_pSample->GetMsrResults();
  241. // cumulate field data info
  242. pMsrResults->CumulateMeasureResults(listResultItems);
  243. pMsrResults->CumulateMeasuredArea(a_nMeasuredArea);
  244. // cumulate ratio
  245. double dRatio = 10000 * pMsrResults->GetTotalParticleArea();
  246. dRatio = dRatio / pMsrResults->GetMeasuredArea();
  247. pMsrResults->SetRadio(dRatio);
  248. // ok, return TRUE
  249. return TRUE;
  250. }
  251. // protected
  252. // classify particles
  253. BOOL CSmplMeasureInc::ClassifyParticles(COTSParticleList& a_listAnalysisParticles, CPosXraysList& a_listAnalysisXRay)
  254. {
  255. // make sure the two lists are same size
  256. int nSize = (int)a_listAnalysisParticles.size();
  257. if ( nSize != (int)a_listAnalysisXRay.size())
  258. {
  259. // particles list size is different with x-ray size
  260. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticles: particles list size is different with x-ray size."));
  261. return FALSE;
  262. }
  263. // go through all analysis particles
  264. for (int i = 0; i < nSize; ++i)
  265. {
  266. COTSParticlePtr pParticle = a_listAnalysisParticles[i];
  267. CPosXrayPtr pXray = a_listAnalysisXRay[i];
  268. if (!ClassifyParticle(pParticle, pXray))
  269. {
  270. // failed to call ClassifyParticle method
  271. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticles: failed to call ClassifyParticle method."));
  272. return FALSE;
  273. }
  274. }
  275. // ok, return TRUE
  276. return TRUE;
  277. }
  278. BOOL CSmplMeasureInc::ClassifyParticle(COTSParticlePtr a_pParticle, CPosXrayPtr a_pXRay)
  279. {
  280. //set the particle type to NOT_IDENTIFIED
  281. int nInclusionID = (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED;
  282. // safety check
  283. ASSERT(m_pSample);
  284. if (!m_pSample)
  285. {
  286. // invalid sample pointer.
  287. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid sample pointer."));
  288. return FALSE;
  289. }
  290. ASSERT(a_pParticle);
  291. if (!a_pParticle)
  292. {
  293. // invalid particle pointer.
  294. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid particle pointer."));
  295. return FALSE;
  296. }
  297. ASSERT(a_pXRay);
  298. if (!a_pXRay)
  299. {
  300. // invalid x-ray pointer.
  301. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: invalid x-ray pointer."));
  302. return FALSE;
  303. }
  304. //// 1.get elementChemistries
  305. CElementChemistriesList listElementChemistriesOld = a_pXRay->GetElementQuantifyData();
  306. //get the parameter MsrParam object
  307. CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
  308. //get the steel technology parameter
  309. STEEL_TECHNOLOGY steelTech = pMsrParam->GetSteelTechnology();
  310. //get standard database item which will be used when classify.
  311. CPartSTDDataPtr pPartSTDData = pMsrParam->GetPartSTDData();
  312. int listSize = pPartSTDData->GetSTDItemsList().size();
  313. if(!COTSClassifyEng::ClassifyXray(pPartSTDData,steelTech, listElementChemistriesOld, nInclusionID))
  314. {
  315. // invalid x-ray pointer.
  316. LogErrorTrace(__FILE__, __LINE__, _T("ClassifyParticle: can't identify the particle as any inclusion."));
  317. return FALSE;
  318. }
  319. if (nInclusionID<7)
  320. {
  321. nInclusionID = (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED;
  322. }
  323. if (nInclusionID == (int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED)
  324. {
  325. //OTSClassifyEngine::CLEEnginePtr en = GetParticleEngine();
  326. //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.
  327. }
  328. else
  329. {
  330. auto stdItem = pPartSTDData->GetSTDItemById(nInclusionID);
  331. if (stdItem != nullptr)
  332. {
  333. a_pParticle->SetType(nInclusionID);
  334. a_pParticle->TypeName(stdItem->GetName().GetBuffer());
  335. a_pParticle->TypeColor(stdItem->GetColor().GetBuffer());
  336. }
  337. }
  338. return TRUE;
  339. }
  340. // check sample STD to make sure it will not be an empty one
  341. BOOL CSmplMeasureInc::CheckSmplSTD()
  342. {
  343. // safety check
  344. ASSERT(m_pSample);
  345. if (!m_pSample)
  346. {
  347. // invalid sample handle
  348. LogErrorTrace(__FILE__, __LINE__, _T("CheckSmplSTD: invalid sample handle."));
  349. return FALSE;
  350. }
  351. // get sample measure parameter
  352. CMsrParamsPtr pMsrParam = m_pSample->GetMsrParams();
  353. // get sample STD
  354. CPartSTDDataPtr pPartSTDData = pMsrParam->GetPartSTDData();
  355. // check if sample STD is empty
  356. if (*pPartSTDData.get() == CPartSTDData())
  357. {
  358. // sample STD is empty, replace it with system STD
  359. pPartSTDData->SetSTDItemsList(m_listSysSTDItem, TRUE);
  360. }
  361. // ok, return true
  362. return TRUE;
  363. }
  364. }