CSmplMeasure.cs 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using OTSModelSharp.ServiceInterface;
  7. using static OTSDataType.otsdataconst;
  8. using OTSDataType;
  9. using System.Diagnostics;
  10. using System.Drawing;
  11. using System.Threading;
  12. using OTSModelSharp.DTLBase;
  13. using OTSCOMMONCLR;
  14. namespace OTSModelSharp
  15. {
  16. using CHoleBSEImgsList = List<CHoleBSEImg>;
  17. class CSmplMeasure
  18. {
  19. protected static NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
  20. protected bool bSaveThreadWorking;
  21. protected System.Threading.Thread m_thread_ptr;
  22. protected COTSSample m_Sample;
  23. protected CMsrThread m_pMsrThread;
  24. string m_strWorkingFolder;
  25. protected CSmplMsrResult m_pSampleRstFile;
  26. CHoleBSEImgsList m_listHoleBSEImg;
  27. //CFunExportClass loger;
  28. protected SemController m_SemHardwareMgr;
  29. protected ScanController m_ScanHardwareMgr;
  30. protected EDSController m_EDSHardwareMgr;
  31. protected Queue<COTSFieldData> fieldQueue=new Queue<COTSFieldData>();
  32. protected COTSFieldData curFldData;
  33. protected IClassifyEngine m_classifyEngine;
  34. public CSmplMeasure()
  35. {
  36. if (log == null)
  37. {
  38. log = NLog.LogManager.GetCurrentClassLogger();
  39. }
  40. m_pSampleRstFile = new CSmplMsrResult();
  41. m_SemHardwareMgr = new SemController();
  42. m_ScanHardwareMgr = new ScanController();
  43. m_EDSHardwareMgr = new EDSController();
  44. m_listHoleBSEImg = new CHoleBSEImgsList();
  45. }
  46. public CSmplMeasure( string a_strWorkingFolder, COTSSample a_pSample)
  47. {
  48. if (log == null)
  49. {
  50. log = NLog.LogManager.GetCurrentClassLogger();
  51. }
  52. m_strWorkingFolder = a_strWorkingFolder;
  53. m_pSampleRstFile = new CSmplMsrResult( a_strWorkingFolder, a_pSample);// new CSmplMsrResultFile(m_strWorkingFolder,a_pSample);
  54. m_SemHardwareMgr = new SemController();
  55. m_ScanHardwareMgr = new ScanController();
  56. m_EDSHardwareMgr = new EDSController();
  57. m_listHoleBSEImg = new CHoleBSEImgsList();
  58. m_Sample = a_pSample;
  59. }
  60. public void SetSample(COTSSample a_pSample)
  61. {
  62. m_Sample = a_pSample;
  63. m_pSampleRstFile.SetSample(a_pSample);
  64. }
  65. public void SetMsrThread(CMsrThread mt)
  66. {
  67. m_pMsrThread = mt;
  68. }
  69. bool SetSEMDataMrs()
  70. {
  71. var pSEMDataMsr = m_Sample.GetSEMDataMsr();
  72. //ASSERT(pSEMDataMsr);
  73. double dMag = pSEMDataMsr.GetMagnification();
  74. double dWorkDis = pSEMDataMsr.GetWorkingDistance();
  75. //CSemBasePtr pSEMCtrlPtr = GetSEMControl();
  76. var pSEMCtrl = m_pMsrThread.GetSEMController();
  77. // get SEM controller
  78. if (!pSEMCtrl.IsConnected())
  79. {
  80. if (!pSEMCtrl.Connect())
  81. {
  82. log.Error("SetSEMDataMrs: can't connect SEM.");
  83. return false;
  84. }
  85. }
  86. log.Info("set magnification:" + dMag.ToString());
  87. log.Info("set Working Distance:" + dWorkDis.ToString());
  88. pSEMCtrl.SetMagnification(dMag);
  89. pSEMCtrl.SetWorkingDistance(dWorkDis);
  90. return true;
  91. }
  92. bool SetSEMExteralOn()
  93. {
  94. var pSEMCtrl = m_SemHardwareMgr;
  95. // get SEM controller
  96. if (!pSEMCtrl.IsConnected())
  97. {
  98. if (!pSEMCtrl.Connect())
  99. {
  100. log.Error("SetSEMExteralOn: can't connect SEM.");
  101. return false;
  102. }
  103. }
  104. log.Warn("Set Scan Exteral on!");
  105. pSEMCtrl.SetScanExternal(true);
  106. return true;
  107. }
  108. // set SEM external off
  109. bool SetSEMExteralOff()
  110. {
  111. var pSEMCtrlPtr = m_SemHardwareMgr;
  112. // get SEM controller
  113. if (!pSEMCtrlPtr.IsConnected())
  114. {
  115. if (!pSEMCtrlPtr.Connect())
  116. {
  117. log.Error("SetSEMExteralOff: can't connect SEM.");
  118. return false;
  119. }
  120. }
  121. log.Warn("Set SEM Exteral Off!");
  122. pSEMCtrlPtr.SetScanExternal(false);
  123. return true;
  124. }
  125. bool SetBSEParam()
  126. {
  127. // get SEM controller
  128. var pSEMController = m_SemHardwareMgr;
  129. // get scan controller
  130. var pScanController = m_ScanHardwareMgr;
  131. // scan parameters
  132. var pMsrParam = m_Sample.GetMsrParams();
  133. var pImgScanParam = pMsrParam.GetImageScanParam();
  134. // get image size
  135. var nImageSizeId = pImgScanParam.GetImagePixelSize();
  136. int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
  137. Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];
  138. // get SEM controller
  139. if (!pSEMController.IsConnected())
  140. {
  141. if (!pSEMController.Connect())
  142. {
  143. log.Error("SetBSEParam: can't connect SEM.");
  144. return false;
  145. }
  146. }
  147. // get dwell time
  148. OTS_THREE_TIES_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();
  149. // convert dwell time to bruker dwell time (8, 16, 32)
  150. int nBrukerDwellTimeId=3;
  151. switch (nDwellTime)
  152. {
  153. case OTS_THREE_TIES_OPTIONS.low:
  154. nBrukerDwellTimeId = 3;
  155. break;
  156. case OTS_THREE_TIES_OPTIONS.meddium:
  157. nBrukerDwellTimeId = 4;
  158. break;
  159. case OTS_THREE_TIES_OPTIONS.high:
  160. nBrukerDwellTimeId = 5;
  161. break;
  162. default:
  163. nBrukerDwellTimeId = 3;
  164. break;
  165. }
  166. long nBrukerDwellTime = OTSDataType.otsdataconst.DWELLTIME_BRUKER_VALUES[nBrukerDwellTimeId];
  167. if (!pScanController.Init())
  168. {
  169. log.Error("SetBSEParam: failed to get scan control.");
  170. return false;
  171. }
  172. // set dwell time
  173. if (!pScanController.SetDwellTime(nBrukerDwellTime))
  174. {
  175. log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);
  176. return false;
  177. }
  178. // set image size
  179. if (!pScanController.SetImageSize(sizePixelImage.Width,sizePixelImage.Height))
  180. {
  181. // failed to set dwell time
  182. log.Error("SetBSEParam: failed to set dwell time (%d).", sizePixelImage.Height);
  183. return false;
  184. }
  185. return true;
  186. }
  187. bool SetHoleBSEParam()
  188. {
  189. // get SEM controller
  190. var pSEMController = m_SemHardwareMgr;
  191. // get scan controller
  192. var pScanController = m_ScanHardwareMgr;
  193. // scan parameters
  194. var pMsrParam = m_Sample.GetMsrParams();
  195. var pImgScanParam = pMsrParam.GetImageScanParam();
  196. // get image size
  197. var nImageSizeId = pImgScanParam.GetImagePixelSize();
  198. int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
  199. Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];
  200. // get SEM controller
  201. if (!pSEMController.IsConnected())
  202. {
  203. if (!pSEMController.Connect())
  204. {
  205. log.Error("SetBSEParam: can't connect SEM.");
  206. return false;
  207. }
  208. }
  209. // get dwell time
  210. OTS_THREE_TIES_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();
  211. // convert dwell time to bruker dwell time (6, 16, 32)
  212. long nBrukerDwellTime = DWELLTIME_BRUKER_VALUES[2];// choose the third option, so the dwell time will be 4 . there's no need to change here. it shoud be a const.
  213. if (!pScanController.Init())
  214. {
  215. log.Error("SetBSEParam: failed to get scan control.");
  216. return false;
  217. }
  218. // set dwell time
  219. if (!pScanController.SetDwellTime(nBrukerDwellTime))
  220. {
  221. log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);
  222. return false;
  223. }
  224. // set image size
  225. if (!pScanController.SetImageSize(sizePixelImage.Width/2, sizePixelImage.Height/2))
  226. {
  227. // failed to set dwell time
  228. log.Error("SetBSEParam: failed to set dwell time (%d).", sizePixelImage.Height);
  229. return false;
  230. }
  231. return true;
  232. }
  233. public void SetWorkingFolder(String a_strWorkingFolder)
  234. {
  235. // add "\\" at the string end if it is not "\\"
  236. if (a_strWorkingFolder.PadRight(1)!="\\")
  237. {
  238. a_strWorkingFolder += "\\";
  239. }
  240. m_strWorkingFolder = a_strWorkingFolder + m_Sample.GetName() + "\\";
  241. }
  242. bool CalculateUnMeasuredFieldsCenters(out List<System.Drawing.Point> a_allpieldcenter,out List<System.Drawing.Point> a_listFieldCenter)
  243. {
  244. // sample measure parameters
  245. CSampleParam pMsrParam = m_Sample.GetMsrParams();
  246. COTSImgScanPrm poImageScanParam = pMsrParam.GetImageScanParam();
  247. CSEMDataMsr poSEMDataMsr = m_Sample.GetSEMDataMsr();
  248. CMsrSampleStatus pStatus = m_Sample.GetMsrStatus();
  249. // measured field centers list
  250. List<System.Drawing.Point> listCompletedCenter = pStatus.GetCompletedFieldsCenter();
  251. // field centers list manager
  252. CFieldPositionMgr pFieldMgr = new CFieldPositionMgr();
  253. // init field centers list manager
  254. if (!pFieldMgr.Init(m_Sample.GetMsrArea(), poImageScanParam, poSEMDataMsr, listCompletedCenter))
  255. {
  256. log.Error("CalculateFieldsCenters: failed to init field centres list manager.");
  257. a_listFieldCenter = new List<System.Drawing.Point>();
  258. a_allpieldcenter = new List<Point>();
  259. return false;
  260. }
  261. // get field centers list
  262. a_listFieldCenter = pFieldMgr.GetUnmeasuredFieldCentrePoints();// GetFieldCentrePoints();
  263. a_allpieldcenter = pFieldMgr.GetFieldCentrePoints();
  264. // ok, return TRUE
  265. return true;
  266. }
  267. protected bool IsAborted()
  268. {
  269. //Debug.Assert(m_pMsrThread == null);
  270. return m_pMsrThread.IsMeasureStopped();
  271. }
  272. bool IsSampleOver(COTSImgScanPrm a_pScanParam, int a_nTotalFields)
  273. {
  274. int nStopMode = (int)a_pScanParam.GetStopMode();
  275. int nStopField = a_pScanParam.GetStopParamFields();
  276. // completed fields number
  277. CMsrSampleStatus pMsrSampleStatus = m_Sample.GetMsrStatus();
  278. int nCompeltedField = pMsrSampleStatus.GetCompletedFields();
  279. CMsrDisplayResults pMsrResults = m_Sample.GetMsrResults();
  280. List<CMsrResultItem> listMsrResult = pMsrResults.GetResultItems();
  281. int nNumParticle = 0;
  282. foreach (var pResult in listMsrResult)
  283. {
  284. if (pResult.GetTypeId() > (int)OTS_PARTCLE_TYPE.NO_ANALYSIS_X_RAY)//summarize the number of the identified particle in this condition
  285. {
  286. nNumParticle += (int)pResult.GetNumber();
  287. }
  288. }
  289. TimeSpan timeSpan = pMsrSampleStatus.GetUsedTime();
  290. int nDay = timeSpan.Days;
  291. int nHour = timeSpan.Hours;
  292. int nMin = timeSpan.Minutes;
  293. int nSec = timeSpan.Seconds;
  294. int nUsedTime = nSec + nMin * 60 + nHour * 3600 + nDay * 86400;
  295. int nParticlAim = a_pScanParam.GetStopParamParticles();
  296. int nMeasTimeAim = a_pScanParam.GetStopParamMeasTime();
  297. bool bRet = true;
  298. switch (nStopMode)
  299. {
  300. case (int)OTS_MEASURE_STOP_MODE.CoverMode:
  301. // completed fields number
  302. if (nCompeltedField < a_nTotalFields)
  303. {
  304. bRet = false;
  305. }
  306. break;
  307. case (int)OTS_MEASURE_STOP_MODE.FieldMode:
  308. if (nCompeltedField < nStopField)
  309. {
  310. bRet = false;
  311. }
  312. break;
  313. case (int)OTS_MEASURE_STOP_MODE.ParticleMode:
  314. if (nNumParticle < nParticlAim)
  315. {
  316. bRet = false;
  317. }
  318. break;
  319. case (int)OTS_MEASURE_STOP_MODE.TimeMode:
  320. if (nUsedTime < nMeasTimeAim)
  321. {
  322. bRet = false;
  323. }
  324. break;
  325. default:
  326. break;
  327. }
  328. return bRet;
  329. }
  330. // move SEM to the point
  331. bool MoveSEMToPoint(System.Drawing.Point a_poi)
  332. {
  333. // get SEM controller
  334. var pSEMController = m_SemHardwareMgr;
  335. Point a_SEMpt = new Point();
  336. CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
  337. if (!a_pCSEMStageData.ConverOTSToSEMPoint(a_poi, ref a_SEMpt))
  338. {
  339. return false;
  340. }
  341. if (!pSEMController.IsConnected())
  342. {
  343. if (!pSEMController.Connect())
  344. {
  345. log.Error("MoveSEMToPoint: can't connect SEM.");
  346. return false;
  347. }
  348. }
  349. log.Info("Begin to move SEM stage to " + a_SEMpt.X + "," + a_SEMpt.Y);
  350. Thread.Sleep(100);
  351. // move SEM to the position (rotation 0)
  352. if (!pSEMController.MoveSEMToPoint(a_SEMpt, 0))
  353. {
  354. log.Error("MoveSEMToPoint: failed to call MoveSEMToPoint method.");
  355. return false;
  356. }
  357. return true;
  358. }
  359. // Acquire a BSE image
  360. CBSEImgClr AcquireABSEImage()
  361. {
  362. // BSE image
  363. CBSEImgClr pBSEImage = null;
  364. // get scan controller
  365. var pScanController = m_ScanHardwareMgr;
  366. pBSEImage = pScanController.AcquireBSEImage(0, 0, 2);
  367. return pBSEImage;
  368. }
  369. public virtual bool FieldImageProcess(Point fldCenter, CBSEImgClr imageData)
  370. {
  371. return true;
  372. }
  373. public virtual void ClassifyFieldParticles()
  374. {
  375. return;
  376. }
  377. public virtual void ClassifyMergedParticles(List<COTSParticleClr> parts)
  378. {
  379. return;
  380. }
  381. private class AutoResetSEMControl:IDisposable
  382. {
  383. CSmplMeasure sm;
  384. public AutoResetSEMControl(CSmplMeasure s)
  385. {
  386. sm = s;
  387. }
  388. public void Dispose()
  389. {
  390. sm.SetSEMExteralOff();
  391. //sm.ResetScan();
  392. }
  393. }
  394. public void DoMeasureForOneSample()
  395. {
  396. using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this)) //when this method exit ,the SetSEMExternalOff and ResetScan will be called automatically.
  397. {
  398. // let the main thread to know that this sample measurement starts
  399. var pStatus = m_Sample.GetMsrStatus();
  400. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  401. // set current time to current time
  402. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);
  403. // let main App know that the sample begin to measure
  404. ST_MSTMsg MsgSmpStart = new ST_MSTMsg();
  405. MsgSmpStart.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  406. MsgSmpStart.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.INPROCESS;
  407. MsgSmpStart.STMSampleStu.cSampleName = m_Sample.GetName();
  408. m_pMsrThread.SendMessageToMeasureApp(MsgSmpStart);
  409. log.Info(m_Sample.GetName() + " Measurement started!");
  410. // get SEM controller to set magnification and working distance
  411. if (!SetSEMDataMrs())
  412. {
  413. log.Error("DoMeasure: fail to set SEM data.");
  414. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  415. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  416. return;
  417. }
  418. // get SEM external controll on
  419. if (!SetSEMExteralOn())
  420. {
  421. log.Error("DoMeasure: fail to set SEM external.");
  422. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  423. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  424. return;
  425. }
  426. // set the BSE scan param
  427. if (!SetBSEParam())
  428. {
  429. log.Error("DoMeasure: fail to set BSE param.");
  430. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  431. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  432. return;
  433. }
  434. var pSEMDataGnr = new CSEMDataGnr();
  435. log.Info("Get Kv, Brightness and Contrast!");
  436. m_SemHardwareMgr.GetSEMDataGnrFromHw(ref pSEMDataGnr);
  437. m_pSampleRstFile.SetSEMGnr(pSEMDataGnr);
  438. // record SEM data
  439. COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();
  440. CSEMStageData pSEMStageData = pProjMgrFile.GetSEMStageData();
  441. m_pSampleRstFile.SetSEMStageData(pSEMStageData);
  442. // record stage
  443. CStage pStage = pProjMgrFile.GetStage();
  444. m_pSampleRstFile.SetSEMStage(pStage);
  445. // calculate field centers
  446. List<System.Drawing.Point> umMeasuredlistFieldCenter;
  447. List<System.Drawing.Point> alllistFieldCenter;
  448. if (!CalculateUnMeasuredFieldsCenters(out alllistFieldCenter,out umMeasuredlistFieldCenter))
  449. {// failed to calculate field centers
  450. log.Error("DoMeasure: failed to calculate field centers.");
  451. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  452. // record end time
  453. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  454. return;
  455. }
  456. //-----save the static measure result file data into xml file and the dynamic data of every field will be saved into sqlite database
  457. log.Info("Create result file!");
  458. if (!m_pSampleRstFile.CreateResultFiles(alllistFieldCenter))
  459. {// failed to call measure result file Save method
  460. log.Error("DoMeasure: failed to call measure result file Save method.");
  461. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  462. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  463. return;
  464. }
  465. //------
  466. int nNewFieldId = 0;
  467. int numOfAllFields = pStatus.GetCompletedFields() + umMeasuredlistFieldCenter.Count;//
  468. int completedFields = pStatus.GetCompletedFields();
  469. log.Info("Unmeasured fields:" + umMeasuredlistFieldCenter.Count);
  470. for (int i = 0; i < (int)umMeasuredlistFieldCenter.Count; ++i)
  471. {// check and break if stop button is clicked
  472. if (IsAborted())
  473. {// measure stopped
  474. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
  475. // record end time
  476. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  477. //must wait for the saving data thread finished,or we'll get null pointer exception when we stop the measure process.
  478. while (fieldQueue.Count() > 0)
  479. {
  480. Thread.Sleep(100);
  481. }
  482. return;
  483. }
  484. // check if sample measurement completes
  485. COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();
  486. int nTotalFieldSize = (int)umMeasuredlistFieldCenter.Count;
  487. if (IsSampleOver(pScanParam, numOfAllFields))
  488. {
  489. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  490. break;
  491. }
  492. // get a field center
  493. System.Drawing.Point poiFieldCentre = umMeasuredlistFieldCenter[i];
  494. // update thread measure status class, let the main thread know that starts a new field
  495. ST_MSTMsg MsgFieldStart = new ST_MSTMsg();
  496. MsgFieldStart.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  497. MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET.START_MSR_FIELD;
  498. MsgFieldStart.STMSampleRetData.SMsrField.FieldPos = poiFieldCentre;
  499. m_pMsrThread.SendMessageToMeasureApp(MsgFieldStart);
  500. int fldNo = completedFields + i + 1;
  501. log.Warn("Current field:" + fldNo.ToString());
  502. // move SEM to the field center
  503. if (!MoveSEMToPoint(poiFieldCentre))
  504. {// failed to move SEM to the position
  505. log.Error("DoMeasure: failed to move SEM to the field centre point.");
  506. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  507. // record end time
  508. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  509. return;
  510. }
  511. log.Info("Begin to Acquire BSE image!");
  512. // take BSE image for the fields
  513. CBSEImgClr pBSEImg = AcquireABSEImage();
  514. // let the main thread to know that image process is completed
  515. if (pBSEImg == null)
  516. {
  517. log.Error("ImageProcess: can't get no background image.");
  518. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  519. return;
  520. }
  521. //BSEData
  522. ST_MSTMsg MsgFieldBSE = new ST_MSTMsg();
  523. MsgFieldBSE.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  524. MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET.BSE_DATA;
  525. MsgFieldBSE.STMSampleRetData.BSEData.pos.X = poiFieldCentre.X;
  526. MsgFieldBSE.STMSampleRetData.BSEData.pos.Y = poiFieldCentre.Y;
  527. MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEImg.GetHeight();
  528. MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEImg.GetWidth();
  529. byte[] pImgData = pBSEImg.GetImageDataPtr();
  530. MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;
  531. m_pMsrThread.SendMessageToMeasureApp(MsgFieldBSE);
  532. // get a new field id
  533. log.Info("Acquire BSE image success! Processing image...");
  534. // image process
  535. var rst = FieldImageProcess(poiFieldCentre, pBSEImg);
  536. if (rst == true)
  537. {
  538. // add the field into the field
  539. m_pSampleRstFile.AddAField(curFldData);
  540. }
  541. ++nNewFieldId;
  542. double measuredArea = 0; // this area should be the field area
  543. var a_pBSEImg = curFldData.GetBSEImage();
  544. double dPixelSize = m_Sample.CalculatePixelSize();
  545. measuredArea = a_pBSEImg.GetHeight() * a_pBSEImg.GetWidth()* dPixelSize * dPixelSize + 0.5; //Get measured area
  546. if (!CumulateFieldData(curFldData.ListAnalysisParticles, measuredArea))
  547. { // failed to call SaveFieldFile method
  548. log.Error("ImageProcess: call CumulateFieldData method.");
  549. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  550. return;
  551. }
  552. log.Info("Send field data to screen!");
  553. // completed fields
  554. pStatus.SetCompletedFields(pStatus.GetCompletedFields() + 1);
  555. // completed fieldCenter
  556. List<System.Drawing.Point> listCpltedCenter = pStatus.GetCompletedFieldsCenter();
  557. listCpltedCenter.Add(poiFieldCentre);
  558. //Field Data
  559. // record end time
  560. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  561. ST_MSTMsg MsgFieldEnd = new ST_MSTMsg();
  562. MsgFieldEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  563. MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET.FIELD_DATA;
  564. MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = pStatus.GetCompletedFields();
  565. MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = numOfAllFields;
  566. MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = (int)curFldData.ListAnalysisParticles.Count;
  567. MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos.X = Convert.ToInt32(poiFieldCentre.X);
  568. MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos.Y = Convert.ToInt32(poiFieldCentre.Y);
  569. m_pMsrThread.SendMessageToMeasureApp(MsgFieldEnd);
  570. }
  571. while (fieldQueue.Count > 0)//wait untill all the field data has been saved.
  572. {
  573. Thread.Sleep(100);
  574. }
  575. //merging particles
  576. log.Info("Merging big particles on the field edge!");
  577. CImageHandler imgpro = new CImageHandler();
  578. int scanfldsize = m_Sample.GetSEMDataMsr().GetScanFieldSize();
  579. List<COTSParticleClr> mergedParticles = new List<COTSParticleClr>();
  580. imgpro.MergeBigBoundaryParticles(m_pSampleRstFile.GetFieldData(), m_Sample.CalculatePixelSize(), scanfldsize, m_Sample.GetResolutionSize(), ref mergedParticles);
  581. ClassifyMergedParticles(mergedParticles);
  582. log.Warn("begin particle data db saving...");
  583. SaveMergedParticles(mergedParticles);
  584. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.COMPLT);
  585. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  586. // let main thread to know that this sample measurement completes
  587. ST_MSTMsg MsgSmplEnd = new ST_MSTMsg();
  588. MsgSmplEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  589. MsgSmplEnd.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
  590. MsgSmplEnd.STMSampleStu.cSampleName = m_Sample.GetName();
  591. m_pMsrThread.SendMessageToMeasureApp(MsgSmplEnd);
  592. }
  593. }
  594. public void DoHolePreview(int a_nHoleID)
  595. {
  596. using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this))
  597. {
  598. // let the main thread to know that this sample measurement starts
  599. CMsrSampleStatus pStatus = m_Sample.GetMsrStatus();
  600. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  601. // set current time to current time
  602. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);
  603. // let main App know that the sample begin to measure
  604. ST_MSTMsg MsgSmpStart=new ST_MSTMsg();
  605. MsgSmpStart.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  606. MsgSmpStart.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.INPROCESS;
  607. MsgSmpStart.STMSampleStu.cSampleName=m_Sample.GetName();
  608. // get SEM controller to set magnification and working distance
  609. if (!SetSEMDataMrs())
  610. {
  611. log.Error("DoHolePreview: fail to set SEM data.");
  612. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  613. // record end time
  614. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  615. return;
  616. }
  617. // get SEM external controll on
  618. if (!SetSEMExteralOn())
  619. {
  620. log.Error("DoMeasure: fail to set SEM external.");
  621. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  622. // record end time
  623. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  624. return;
  625. }
  626. // set the BSE scan param
  627. if (!SetHoleBSEParam())
  628. {
  629. log.Error("DoMeasure: fail to set BSE param.");
  630. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  631. // record end time
  632. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  633. return;
  634. }
  635. // check if measurement is aborted
  636. if (IsAborted())
  637. {// measurement aborted
  638. log.Trace("DoHolePreview: measurement aborted before get SEM condition.");
  639. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
  640. // record end time
  641. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  642. return;
  643. }
  644. // calculate field centers
  645. List<System.Drawing.Point> listFieldCenter=new List<System.Drawing.Point>();
  646. List<System.Drawing.Point> alllistFieldCenter = new List<System.Drawing.Point>();
  647. // listFieldCenter.clear();
  648. if (!CalculateUnMeasuredFieldsCenters(out alllistFieldCenter,out listFieldCenter))
  649. {// failed to calculate field centers
  650. log.Error("DoHolePreview: failed to calculate field centers.");
  651. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  652. // record end time
  653. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  654. return;
  655. }
  656. // go through each field
  657. int nNewFieldId = 0;
  658. for ( int i = 0; i < listFieldCenter.Count; ++i)
  659. {// check and break if stop button is clicked
  660. if (IsAborted())
  661. {// measure stopped
  662. log.Trace("DoHolePreview: measure thread is stopped.");
  663. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
  664. // record end time
  665. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  666. return;
  667. }
  668. // check if sample measurement completes
  669. COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();
  670. int nTotalFieldSize = listFieldCenter.Count;
  671. if (IsSampleOver(pScanParam, nTotalFieldSize))
  672. {
  673. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  674. break;
  675. }
  676. // get a field center
  677. System.Drawing.Point poiFieldCentre = listFieldCenter[i];
  678. // update thread measure status class, let the main thread know that starts a new field
  679. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  680. ST_MSTMsg MsgFieldStart=new ST_MSTMsg();
  681. //memset(&MsgFieldStart, 0, sizeof(ST_MSTMsg));
  682. MsgFieldStart.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  683. MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET.START_MSR_FIELD;
  684. MsgFieldStart.STMSampleRetData.SMsrField.FieldPos = poiFieldCentre;
  685. m_pMsrThread.SendMessageToMeasureApp(MsgFieldStart);
  686. // move SEM to the field center
  687. if (!MoveSEMToPoint(poiFieldCentre))
  688. {// failed to move SEM to the position
  689. log.Error("DoHolePreview: failed to move SEM to the field centre point.");
  690. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  691. // record end time
  692. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  693. return;
  694. }
  695. // take BSE image for the fields
  696. CBSEImgClr pBSEIamge = AcquireABSEImage();
  697. if (pBSEIamge==null)
  698. {
  699. // failed to acquire a BSE image
  700. log.Error("DoHolePreview: failed to acquire a BSE image.");
  701. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  702. // record end time
  703. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  704. return;
  705. }
  706. //BSEData
  707. ST_MSTMsg MsgFieldBSE=new ST_MSTMsg();
  708. // memset(&MsgFieldBSE, 0, sizeof(ST_MSTMsg));
  709. MsgFieldBSE.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  710. MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET.BSE_DATA;
  711. MsgFieldBSE.STMSampleRetData.BSEData.pos = poiFieldCentre;
  712. //MsgFieldBSE.STMSampleRetData.BSEData.pos.y = poiFieldCentre.y;
  713. MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEIamge.GetHeight();
  714. MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEIamge.GetWidth();
  715. byte[] pImgData = pBSEIamge.GetImageDataPtr();
  716. MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;
  717. m_pMsrThread.SendMessageToMeasureApp(MsgFieldBSE);
  718. if (pStatus.GetStatus() != OTS_MSR_SAMPLE_STATUS.INPROCESS)
  719. {
  720. // measurement failed or stopped
  721. log.Error("DoHolePreview: measurement failed or stopped.");
  722. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  723. // record end time
  724. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  725. return;
  726. }
  727. //save the result to project file
  728. CHoleBSEImg pHoleBSEImg =new CHoleBSEImg();
  729. pHoleBSEImg.SetHoleID(a_nHoleID);
  730. pHoleBSEImg.SetPosition(poiFieldCentre);
  731. Rectangle oImageRect =(Rectangle) pBSEIamge.GetImageRect();
  732. int nImageSize = pBSEIamge.GetHeight() * pBSEIamge.GetWidth();
  733. pHoleBSEImg.SetImageRect(oImageRect);
  734. pHoleBSEImg.SetImageData( pBSEIamge.GetImageDataPtr(),oImageRect.Width,oImageRect.Height);
  735. m_listHoleBSEImg.Add(pHoleBSEImg);
  736. COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();
  737. pProjMgrFile.SetHoleBESImgList(m_listHoleBSEImg,true);
  738. // prepare for the next
  739. ++nNewFieldId;
  740. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  741. ST_MSTMsg MsgFieldEnd=new ST_MSTMsg();
  742. MsgFieldEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;
  743. MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET.FIELD_DATA;
  744. MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = (i + 1);
  745. MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = listFieldCenter.Count;
  746. MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = 0;
  747. MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos = poiFieldCentre;
  748. m_pMsrThread.SendMessageToMeasureApp(MsgFieldEnd);
  749. //break;
  750. }
  751. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  752. //calculate measure time
  753. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  754. // let main thread to know that this sample measurement completes
  755. ST_MSTMsg MsgSmplEnd=new ST_MSTMsg();
  756. MsgSmplEnd.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  757. MsgSmplEnd.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.COMPLETED;
  758. m_pMsrThread.SendMessageToMeasureApp(MsgSmplEnd);
  759. }
  760. }
  761. // Cumulate field data info
  762. public virtual bool CumulateFieldData( List<COTSParticleClr> listParticles, double a_nMeasuredArea)
  763. {
  764. // get measure result items of the sample
  765. CMsrDisplayResults pMsrResults = m_Sample.GetMsrResults();
  766. // cumulate field data info
  767. //pMsrResults.CumulateMeasureResults(listResultItems);
  768. pMsrResults.CumulateMeasuredArea(a_nMeasuredArea);
  769. // cumulate ratio
  770. double dRatio = 10000 * pMsrResults.GetTotalParticleArea();
  771. dRatio = dRatio / pMsrResults.GetMeasuredArea();
  772. pMsrResults.SetRatio(dRatio);
  773. // go through the particles list
  774. foreach (COTSParticleClr pParticle in listParticles)
  775. {
  776. // create a measure result item
  777. pMsrResults.CumulateMeasureResult(pParticle);
  778. }
  779. // ok, return TRUE
  780. return true;
  781. }
  782. // hole BSE images list
  783. void SetHoleBESImgList(CHoleBSEImgsList a_listHoleBSEImg, bool a_bClear/* = TRUE*/)
  784. {// clear the hole BSE image list if necessary
  785. if (a_bClear)
  786. {
  787. m_listHoleBSEImg.Clear();
  788. }
  789. // go through the input list
  790. foreach (var pHoleBSEImg in a_listHoleBSEImg)
  791. {// add the new hole BSE image into HoleBSEImage list
  792. m_listHoleBSEImg.Add(pHoleBSEImg);
  793. }
  794. }
  795. public bool SaveMergedParticles(List<COTSParticleClr> mergedParts)
  796. {
  797. CIncAFileMgr pDBFileMgr = m_pSampleRstFile.DBFileMgr;
  798. var mergedpartdb = pDBFileMgr.GetMergedParticleDB();
  799. foreach (COTSParticleClr part in mergedParts)
  800. {
  801. mergedpartdb.SaveAParticle(part, part.GetXray(), new System.Drawing.Point(0, 0));
  802. }
  803. CPosXrayDBMgr pXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr();
  804. CElementChemistryDB xraydb = pXrayDBMgr.GetElementChemistryDB();
  805. List<CPosXrayClr> ches = new List<CPosXrayClr>();
  806. foreach (COTSParticleClr part in mergedParts)
  807. {
  808. ches.Add(part.GetXray());
  809. }
  810. xraydb.SaveElementChemistriesList(ches);
  811. return true;
  812. }
  813. }
  814. }