CSmplMeasure.cs 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using OTSModelSharp.ServiceCenter;
  5. using static OTSDataType.otsdataconst;
  6. using OTSDataType;
  7. using System.Drawing;
  8. using System.Threading;
  9. using OTSCLRINTERFACE;
  10. using OTSMeasureApp._0_OTSModel.OTSDataType;
  11. using System.Windows.Forms;
  12. using System.Data;
  13. using System.IO;
  14. using OTSMeasureApp._1_OTSMeasure.Measure._3_MeasureFlow;
  15. using OpenCvSharp.Extensions;
  16. using OTSMeasureApp;
  17. using System.Diagnostics;
  18. namespace OTSModelSharp
  19. {
  20. using CHoleBSEImgsList = List<CHoleBSEImg>;
  21. public class CSmplMeasure
  22. {
  23. protected static NLog.Logger log ;
  24. protected bool bSaveThreadWorking;
  25. protected System.Threading.Thread m_thread_ptr;
  26. protected COTSSample m_Sample;
  27. protected COTSSample m_HolePreviewSample;
  28. protected CMeasure m_pMsrThread;
  29. string m_strWorkingFolder;
  30. protected CSmplMsrResult m_pSampleRstFile;
  31. CHoleBSEImgsList m_listHoleBSEImg;
  32. protected ISemController m_SemHardwareMgr;
  33. protected IScanController m_ScanHardwareMgr;
  34. protected IEDSController m_EDSController;
  35. protected Queue<COTSField> fieldQueue=new Queue<COTSField>();
  36. protected IClassifyEngine m_classifyEngine;
  37. private bool m_ifAquireClearParticleImage=false;
  38. public CSmplMeasure( string a_strWorkingFolder, COTSSample a_pSample)
  39. {
  40. m_Sample = a_pSample;
  41. log = NLog.LogManager.GetCurrentClassLogger();
  42. var expC = m_Sample.GetMsrParams().GetXRayParam().GetAnalyExpCount();
  43. var imgwidth = m_Sample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cx;
  44. var imgheight = m_Sample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cy;
  45. m_strWorkingFolder = a_strWorkingFolder;
  46. m_pSampleRstFile = new CSmplMsrResult( a_strWorkingFolder, a_pSample);
  47. m_SemHardwareMgr = SemController.GetSEMController();
  48. m_ScanHardwareMgr = ScanController.GetScanController();
  49. var ifautoid = m_Sample.GetMsrParams().GetXRayParam().IfAutoId;
  50. var knownelements = m_Sample.GetMsrParams().GetXRayParam().AnalysisElements;
  51. string deviceType = FileHelper.GetXMLInformations("EDSName");
  52. m_EDSController = EDSController.GetEDSController(deviceType, imgwidth,imgheight,expC,ifautoid,knownelements);
  53. m_listHoleBSEImg = new CHoleBSEImgsList();
  54. m_Sample = a_pSample;
  55. m_ifAquireClearParticleImage = FileHelper.GetIfAquireClearParticleImage();
  56. }
  57. public void SetSample(COTSSample a_pSample)
  58. {
  59. m_Sample = a_pSample;
  60. m_pSampleRstFile.SetSample(a_pSample);
  61. }
  62. public COTSSample GetSample() { return m_Sample; }
  63. public void SetHolePreviewSample(COTSSample a_pSample)
  64. {
  65. m_HolePreviewSample = a_pSample;
  66. }
  67. public COTSSample GetHolePreviewSample() { return m_HolePreviewSample; }
  68. public void SetMsrThread(CMeasure mt)
  69. {
  70. m_pMsrThread = mt;
  71. }
  72. bool SetSEMDataMrs(COTSSample sample)
  73. {
  74. var pSEMDataMsr = sample.GetSEMDataMsr();
  75. double dMag = pSEMDataMsr.GetMagnification();
  76. double dWorkDis = pSEMDataMsr.GetWorkingDistance();
  77. var pSEMCtrl = m_pMsrThread.GetSEMController();
  78. pSEMCtrl.SetMagnification(dMag);
  79. pSEMCtrl.SetWorkingDistance(dWorkDis);
  80. return true;
  81. }
  82. bool SetSEMExteralOn()
  83. {
  84. var pSEMCtrl = m_SemHardwareMgr;
  85. log.Warn("Set Scan Exteral on!");
  86. pSEMCtrl.SetScanExternal(true);
  87. return true;
  88. }
  89. // set SEM external off
  90. bool SetSEMExteralOff()
  91. {
  92. var pSEMCtrlPtr = m_SemHardwareMgr;
  93. log.Warn("Set SEM Exteral Off!");
  94. pSEMCtrlPtr.SetScanExternal(false);
  95. return true;
  96. }
  97. bool SetBSEParam()
  98. {
  99. // get scan controller
  100. var pScanController = m_ScanHardwareMgr;
  101. // scan parameters
  102. var pMsrParam = m_Sample.GetMsrParams();
  103. var pImgScanParam = pMsrParam.GetImageScanParam();
  104. // get image size
  105. var nImageSizeId = pImgScanParam.GetImageResulotion();
  106. int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
  107. Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];
  108. // get dwell time
  109. OTS_IMAGE_SCANSPEED_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();
  110. // convert dwell time to bruker dwell time
  111. DwellTimeLevel DwellTimeId;
  112. switch (nDwellTime)
  113. {
  114. case OTS_IMAGE_SCANSPEED_OPTIONS.low:
  115. DwellTimeId = DwellTimeLevel.Low;
  116. break;
  117. case OTS_IMAGE_SCANSPEED_OPTIONS.meddium:
  118. DwellTimeId = DwellTimeLevel.Medium;
  119. break;
  120. case OTS_IMAGE_SCANSPEED_OPTIONS.high:
  121. DwellTimeId = DwellTimeLevel.High;
  122. break;
  123. default:
  124. DwellTimeId = DwellTimeLevel.Low;
  125. break;
  126. }
  127. //long nBrukerDwellTime = OTSDataType.otsdataconst.DWELLTIME_BRUKER_VALUES[DwellTimeId];
  128. if (!pScanController.Init())
  129. {
  130. log.Error("SetBSEParam: failed to get scan control.");
  131. return false;
  132. }
  133. // set dwell time
  134. if (!pScanController.SetDwellTime(DwellTimeId))
  135. {
  136. //log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);
  137. return false;
  138. }
  139. // set image size
  140. if (!pScanController.SetImageSize(sizePixelImage.Width,sizePixelImage.Height))
  141. {
  142. // failed to set dwell time
  143. log.Error("SetBSEParam: failed to set dwell time (%d).", sizePixelImage.Height);
  144. return false;
  145. }
  146. return true;
  147. }
  148. bool SetHoleBSEParam(COTSSample sample)
  149. {
  150. // get scan controller
  151. var pScanController = m_ScanHardwareMgr;
  152. // scan parameters
  153. var pMsrParam = sample.GetMsrParams();
  154. var pImgScanParam = pMsrParam.GetImageScanParam();
  155. // get image size
  156. var nImageSizeId = pImgScanParam.GetImageResulotion();
  157. int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
  158. Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];
  159. // get dwell time
  160. OTS_IMAGE_SCANSPEED_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();
  161. // convert dwell time to bruker dwell time
  162. //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.
  163. if (!pScanController.Init())
  164. {
  165. log.Error("SetBSEParam: failed to get scan control.");
  166. return false;
  167. }
  168. // set dwell time
  169. if (!pScanController.SetDwellTime(DwellTimeLevel.Low))
  170. {
  171. //log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);
  172. return false;
  173. }
  174. // set image size
  175. if (!pScanController.SetImageSize(sizePixelImage.Width, sizePixelImage.Height))
  176. {
  177. // failed to set dwell time
  178. log.Error("SetBSEParam: failed to set ImageSize");
  179. return false;
  180. }
  181. return true;
  182. }
  183. public void SetWorkingFolder(String a_strWorkingFolder)
  184. {
  185. // add "\\" at the string end if it is not "\\"
  186. if (a_strWorkingFolder.PadRight(1)!="\\")
  187. {
  188. a_strWorkingFolder += "\\";
  189. }
  190. m_strWorkingFolder = a_strWorkingFolder + m_Sample.GetName() + "\\";
  191. }
  192. bool CalculateUnMeasuredHoleImgCenters(COTSSample sample, out List<System.Drawing.Point> a_allpieldcenter, out List<System.Drawing.Point> a_listUnMsrFieldCenter)
  193. {
  194. // sample measure parameters
  195. CSampleParam pMsrParam = sample.GetMsrParams();
  196. COTSImgScanPrm poImageScanParam = pMsrParam.GetImageScanParam();
  197. COTSImageProcParam pImgProcParam = pMsrParam.GetImageProcessParam();
  198. CSEMDataMsr poSEMDataMsr = sample.GetSEMDataMsr();
  199. CMsrSampleStatus pStatus = sample.GetMsrStatus();
  200. // measured field centers list
  201. List<System.Drawing.PointF> listCompletedCenter = pStatus.GetCompletedFieldsCenter();
  202. // field centers list manager
  203. CFieldPositionHelper pFieldMgr = new CFieldPositionHelper();
  204. // init field centers list manager
  205. if (!pFieldMgr.Init(sample.GetMsrDomain(), poImageScanParam,0, poSEMDataMsr, listCompletedCenter))
  206. {
  207. log.Error("CalculateFieldsCenters: failed to init field centres list manager.");
  208. a_listUnMsrFieldCenter = new List<System.Drawing.Point>();
  209. a_allpieldcenter = new List<Point>();
  210. return false;
  211. }
  212. // get field centers list
  213. a_listUnMsrFieldCenter = pFieldMgr.GetUnmeasuredFieldCentrePoints();// GetFieldCentrePoints();
  214. a_allpieldcenter = pFieldMgr.GetFieldCentrePoints();
  215. // ok, return TRUE
  216. return true;
  217. }
  218. protected bool IsAborted()
  219. {
  220. return m_pMsrThread.IsMeasureStopped();
  221. }
  222. protected bool IsPaused()
  223. {
  224. var statu = m_pMsrThread.GetMsrThreadStatus();
  225. if (statu.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)
  226. {
  227. return true;
  228. }
  229. else
  230. {
  231. return false;
  232. }
  233. }
  234. bool IsSampleOver(COTSImgScanPrm a_pScanParam)
  235. {
  236. string sStopMode = a_pScanParam.GetStopMode();
  237. int nStopField = a_pScanParam.GetStopParamFields();
  238. // completed fields number
  239. CMsrSampleStatus pMsrSampleStatus = m_Sample.GetMsrStatus();
  240. int nCompeltedField = pMsrSampleStatus.GetCompletedFields();
  241. CMsrResultItems pMsrResults = m_Sample.GetMsrResults();
  242. List<CMsrResultItem> listMsrResult = pMsrResults.GetResultItems();
  243. int nNumParticle = 0;
  244. foreach (var pResult in listMsrResult)
  245. {
  246. if (pResult.GetTypeId() > (int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED)//summarize the number of the identified particle in this condition
  247. {
  248. nNumParticle += (int)pResult.GetNumber();
  249. }
  250. }
  251. TimeSpan timeSpan = pMsrSampleStatus.GetUsedTime();
  252. int nDay = timeSpan.Days;
  253. int nHour = timeSpan.Hours;
  254. int nMin = timeSpan.Minutes;
  255. int nSec = timeSpan.Seconds;
  256. int nUsedTime = nSec + nMin * 60 + nHour * 3600 + nDay * 86400;
  257. int NMeasArea = (int)pMsrResults.GetMeasuredArea();
  258. int nParticlAim = a_pScanParam.GetStopParamParticles();
  259. int nMeasTimeAim = a_pScanParam.GetStopParamMeasTime();
  260. int NMeasAreaAim = a_pScanParam.GetStopParamArea()*1000000 ;
  261. bool bRet = false;
  262. string[] str = sStopMode.Replace(" ", "").Split('+');
  263. for(int i=0;i< str.Length;i++)
  264. {
  265. switch (int.Parse(str[i].Split(':')[0])-1)
  266. {
  267. case (int)OTS_MEASURE_STOP_MODE.CoverMode:
  268. // completed fields number
  269. if (nCompeltedField == m_Sample.GetFieldsData().Count)
  270. {
  271. bRet = true;
  272. }
  273. break;
  274. case (int)OTS_MEASURE_STOP_MODE.FieldMode:
  275. if (nCompeltedField >= nStopField)
  276. {
  277. bRet = true;
  278. }
  279. break;
  280. case (int)OTS_MEASURE_STOP_MODE.ParticleMode:
  281. if (nNumParticle >= nParticlAim)
  282. {
  283. bRet = true;
  284. }
  285. break;
  286. case (int)OTS_MEASURE_STOP_MODE.TimeMode:
  287. if (nUsedTime >= nMeasTimeAim)
  288. {
  289. bRet = true;
  290. }
  291. break;
  292. case (int)OTS_MEASURE_STOP_MODE.AreaMode:
  293. if (NMeasArea >= NMeasAreaAim)
  294. {
  295. bRet = true;
  296. }
  297. break;
  298. default:
  299. break;
  300. }
  301. }
  302. return bRet;
  303. }
  304. // move SEM to the point
  305. bool MoveSEMToPoint(System.Drawing.PointF a_poi)
  306. {
  307. // get SEM controller
  308. var pSEMController = m_SemHardwareMgr;
  309. PointF a_SEMpt = new Point();
  310. CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
  311. int hardWareDelay = a_pCSEMStageData.GetHardWareDelay();
  312. if (!a_pCSEMStageData.ConvertOTSToSEMCoord(a_poi, ref a_SEMpt))
  313. {
  314. return false;
  315. }
  316. log.Info("Begin to move SEM stage to OTScoord:" + a_poi.X + "," + a_poi.Y);
  317. log.Info("Begin to move SEM stage to " + a_SEMpt.X + "," + a_SEMpt.Y);
  318. // move SEM to the position (rotation 0)
  319. if (!pSEMController.MoveSEMToPoint(a_SEMpt.X, a_SEMpt.Y))
  320. {
  321. log.Error("MoveSEMToPoint: failed to call MoveSEMToPoint method.");
  322. return false;
  323. }
  324. CSampleParam pMsrParam = m_Sample.GetMsrParams();
  325. if (pMsrParam.SlopParam.IsUsingSlopParam)
  326. {
  327. double wd = pMsrParam.SlopParam.GetWD(a_SEMpt);
  328. double originWd = 0;
  329. pSEMController.GetWorkingDistance(ref originWd);
  330. if ((wd - originWd) > 2)
  331. {
  332. log.Warn("Working Distance is invalid,outof the moving scope(2cm) wd=" + wd.ToString("F2"));
  333. }
  334. else
  335. {
  336. Thread.Sleep(hardWareDelay);
  337. pSEMController.SetWorkingDistance(wd);
  338. }
  339. }
  340. if (hardWareDelay > 0)
  341. {
  342. Thread.Sleep(hardWareDelay);
  343. }
  344. return true;
  345. }
  346. // Acquire a BSE image
  347. CBSEImgClr AcquireABSEImage()
  348. {
  349. // BSE image
  350. CBSEImgClr pBSEImage = null;
  351. // get scan controller
  352. var pScanController = m_ScanHardwareMgr;
  353. pBSEImage = pScanController.AcquireBSEImage();
  354. return pBSEImage;
  355. }
  356. public bool IsLowCounts(COTSParticleClr particle)
  357. {
  358. COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();
  359. if (pXRayParam.GetUsingXray() == true)
  360. {
  361. var thecount = particle.GetXray().GetTotalCount();
  362. var expect = pXRayParam.GetAnalyExpCount();
  363. if (thecount < expect)
  364. {
  365. particle.SetType((int)OTS_PARTICLE_TYPE.LOW_COUNT);
  366. particle.SetClassifyId((int)OTS_PARTICLE_TYPE.LOW_COUNT);
  367. particle.SetTypeColor("#000000");
  368. particle.SetTypeName("LowCounts");
  369. return true;
  370. }
  371. }
  372. return false;
  373. }
  374. public virtual void ClassifyFieldParticles(COTSField curFldData)
  375. {
  376. return;
  377. }
  378. private class SEMStateObject
  379. {
  380. private PointF pos;
  381. private double workingDistance;
  382. private CSEMDataGnr semdata;
  383. private COTSSample originalSample;
  384. private double magnification;
  385. public PointF Pos { get => pos; set => pos = value; }
  386. public double WorkingDistance { get => workingDistance; set => workingDistance = value; }
  387. public CSEMDataGnr Semdata { get => semdata; set => semdata = value; }
  388. public double Magnification { get => magnification; set => magnification = value; }
  389. public COTSSample OriginalSample { get => originalSample; set => originalSample = value; }
  390. }
  391. private class AutoResetSEMControl:IDisposable
  392. {
  393. CSmplMeasure sm;
  394. private SEMStateObject semState=null;
  395. public AutoResetSEMControl(CSmplMeasure s)
  396. {
  397. sm = s;
  398. }
  399. public SEMStateObject SemState
  400. {
  401. get => semState;
  402. set => semState = value;
  403. }
  404. public void Dispose()
  405. {
  406. if (semState != null)
  407. {
  408. sm.SetBSEParam();
  409. sm.m_SemHardwareMgr.SetMagnification(semState.Magnification);
  410. Thread.Sleep(100);
  411. sm.MoveSEMToPoint(semState.Pos);
  412. Thread.Sleep(100);
  413. sm.m_SemHardwareMgr.SetWorkingDistance(semState.WorkingDistance);
  414. }
  415. sm.SetSEMExteralOff();
  416. }
  417. }
  418. private bool GetSEMDataGnrFromHw(ref CSEMDataGnr SemDataGnr)
  419. {
  420. double kv = 0, brightness = 0, contrast = 0;
  421. var hw = SemController.GetSEMController();
  422. hw.GetSemHighTension(ref kv);
  423. hw.GetSemBrightness(ref brightness);
  424. hw.GetSemContrast(ref contrast);
  425. SemDataGnr.SetValue(kv, brightness, contrast);
  426. return true;
  427. }
  428. private void AiProcess(ref CBSEImgClr pBSEImg)
  429. {
  430. var procParam = m_Sample.GetMsrParams().GetImageProcessParam();
  431. var aiserver = procParam.GetAIServer();
  432. var originalBseData = pBSEImg.GetImageDataPtr();//获取bse 图像
  433. pBSEImg.GetWidth();
  434. int m_iWidth = pBSEImg.GetWidth();
  435. int m_iHeight = pBSEImg.GetHeight();
  436. OpenCvSharp.Mat input = new OpenCvSharp.Mat();
  437. Bitmap bitmap = CImageHandler.ToGrayBitmap(originalBseData, m_iWidth, m_iHeight);
  438. input = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  439. //OpenCvSharp.Cv2.ImShow("img", input);
  440. //OpenCvSharp.Cv2.WaitKey(0);
  441. //OpenCvSharp.Cv2.DestroyAllWindows();
  442. string baseurl = "http://" + aiserver;
  443. //test server
  444. bool test = false;
  445. if (test)
  446. {
  447. if (!AI_HttpClient.AI_Test(baseurl))
  448. {
  449. log.Info("server erro!");
  450. MessageBox.Show("server erro!");
  451. input.Dispose();
  452. return;
  453. }
  454. }
  455. if (!input.Empty())
  456. {
  457. OpenCvSharp.Mat output = new OpenCvSharp.Mat();
  458. AI_HttpClient.AI_SegformerImage_cxx(baseurl, input, ref output, 1007, 1);
  459. if (output.Empty())
  460. {
  461. log.Info("aiserver out erro!");
  462. MessageBox.Show("aiserver erro!");
  463. input.Dispose();
  464. output.Dispose();
  465. return;
  466. }
  467. output = ~output; //
  468. //将二值图复制到pBSEImg
  469. var bitData = CImageHandler.BitmapToGrayByte(output.ToBitmap());
  470. pBSEImg.SetImageData(bitData, output.Width, output.Height);
  471. //OpenCvSharp.Cv2.ImShow("out", output);
  472. //OpenCvSharp.Cv2.WaitKey(0);
  473. //OpenCvSharp.Cv2.DestroyAllWindows();
  474. input.Dispose();
  475. output.Dispose();
  476. }
  477. }
  478. public void DoMeasureForOneSample()
  479. {
  480. using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this)) //when this method exit ,the SetSEMExternalOff and ResetScan will be called automatically.
  481. {
  482. // let the main thread to know that this sample measurement starts
  483. var pStatus = m_Sample.GetMsrStatus();
  484. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  485. // set current time to current time
  486. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);
  487. // let main App know that the sample begin to measure
  488. ST_MSTMsg MsgSmpStart = new ST_MSTMsg(m_Sample);
  489. MsgSmpStart.InitSampleStartMsg();
  490. m_pMsrThread.SendMessageToMeasureGUI(MsgSmpStart);
  491. log.Info(m_Sample.GetName() + " Measurement started!");
  492. // get SEM controller to set magnification and working distance
  493. if (!SetSEMDataMrs(m_Sample))
  494. {
  495. log.Error("DoMeasure: fail to set SEM data.");
  496. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  497. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  498. return;
  499. }
  500. // set the BSE scan param
  501. if (!SetBSEParam())
  502. {
  503. log.Error("DoMeasure: fail to set BSE param.");
  504. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  505. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  506. return;
  507. }
  508. var pSEMDataGnr = new CSEMDataGnr();
  509. log.Info("Get Kv, Brightness and Contrast!");
  510. GetSEMDataGnrFromHw(ref pSEMDataGnr);
  511. m_pSampleRstFile.SetSEMGnr(pSEMDataGnr);
  512. // record SEM data
  513. COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();
  514. CSEMStageData pSEMStageData = pProjMgrFile.GetSEMStageData();
  515. m_pSampleRstFile.SetSEMStageData(pSEMStageData);
  516. // record stage
  517. CStage pStage = pProjMgrFile.GetStage();
  518. m_pSampleRstFile.SetSEMStage(pStage);
  519. //-----save the static measure result file data into xml file and the dynamic data of every field will be saved into sqlite database
  520. log.Info("Create result file!");
  521. if (!m_pSampleRstFile.CreateResultFiles())
  522. {// failed to call measure result file Save method
  523. log.Error("DoMeasure: failed to call measure result file Save method.");
  524. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  525. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  526. return;
  527. }
  528. //------
  529. var FldDatas = m_Sample.GetFieldsData();
  530. for (int i = 0; i < FldDatas.Count; ++i)
  531. {// check and break if stop button is clicked
  532. var curFld = FldDatas[i];
  533. if (curFld.GetIsMeasureComplete())
  534. {
  535. continue;
  536. }
  537. if (IsPaused())
  538. {// measure stopped
  539. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.PAUSED);
  540. // record end time
  541. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  542. //must wait for the saving data thread finished,or we'll get null pointer exception when we stop the measure process.
  543. while (fieldQueue.Count() > 0)
  544. {
  545. Thread.Sleep(100);
  546. }
  547. SetSEMExteralOff();
  548. // update thread measure status class, let the main thread know that this sample measurement stopped
  549. ST_MSTMsg MsgSmpStop = new ST_MSTMsg(m_Sample);
  550. MsgSmpStop.InitSamplePausedMsg();
  551. m_pMsrThread.SendMessageToMeasureGUI(MsgSmpStop);
  552. while (IsPaused())
  553. {
  554. Thread.Sleep(300);
  555. }
  556. }
  557. if (IsAborted())
  558. {// measure stopped
  559. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
  560. // record end time
  561. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  562. //must wait for the saving data thread finished,or we'll get null pointer exception when we stop the measure process.
  563. while (fieldQueue.Count() > 0)
  564. {
  565. Thread.Sleep(100);
  566. }
  567. break;
  568. }
  569. // check if sample measurement completes
  570. COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();
  571. if (IsSampleOver(pScanParam))
  572. {
  573. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  574. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.COMPLT);
  575. break;
  576. }
  577. // get a field center
  578. System.Drawing.PointF poiFieldCentre = curFld.GetOTSPosition();
  579. // update thread measure status class, let the main thread know that starts a new field
  580. ST_MSTMsg MsgFieldStart = new ST_MSTMsg(m_Sample,curFld);
  581. MsgFieldStart.InitFieldStartMsg();
  582. m_pMsrThread.SendMessageToMeasureGUI(MsgFieldStart);
  583. int fldNo = curFld.GetId();
  584. log.Warn("Current field:" + fldNo.ToString());
  585. // move SEM to the field center
  586. if (!MoveSEMToPoint(poiFieldCentre))
  587. {// failed to move SEM to the position
  588. log.Error("DoMeasure: failed to move SEM to the field centre point.");
  589. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  590. // record end time
  591. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  592. return;
  593. }
  594. log.Info("Begin to Acquire BSE image!");
  595. // take BSE image for the fields
  596. CBSEImgClr pBSEImg = AcquireABSEImage();
  597. // let the main thread to know that image process is completed
  598. if (pBSEImg == null)
  599. {
  600. log.Error("ImageProcess: can't get BSE image.");
  601. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  602. return;
  603. }
  604. //ai 提取二值图
  605. AiProcess(ref pBSEImg);
  606. curFld.SetBSEImage(pBSEImg);
  607. //BSEData
  608. ST_MSTMsg MsgFieldBSE = new ST_MSTMsg(m_Sample,curFld);
  609. MsgFieldBSE.InitFieldBSEImageMsg();
  610. m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);
  611. log.Info("Acquire BSE image success! Processing image...");
  612. // image process
  613. FieldImageProcess(curFld);
  614. MsgFieldBSE.InitFieldBSEAnalysisPartsDataMsg();
  615. m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);
  616. if (m_ifAquireClearParticleImage)
  617. {
  618. var listAnalysisParts = curFld.GetListAnalysisParticles();
  619. foreach (var p in listAnalysisParts)
  620. {
  621. Rectangle r = (Rectangle)p.GetParticleRect();
  622. var img = m_ScanHardwareMgr.AcquireRectangleBSEImage(r);
  623. if (img != null)
  624. {
  625. curFld.particleImages.Add(img);
  626. }
  627. }
  628. }
  629. COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();
  630. if (pXRayParam.GetUsingXray() == true)
  631. {
  632. foreach (var p in curFld.GetListAnalysisParticles())
  633. {
  634. p.SetIsXrayParticle(true);
  635. }
  636. try
  637. {
  638. CollectParticlesXrayData(curFld);
  639. }
  640. catch (Exception e)
  641. {
  642. log.Error(e.Message);
  643. }
  644. }
  645. m_Sample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  646. curFld.SetIsMeasureComplete(true);
  647. log.Info("Begin to classify particles! particle num:" + curFld.GetListAnalysisParticles().Count);
  648. try
  649. {
  650. ClassifyFieldParticles(curFld);
  651. }
  652. catch(Exception e)
  653. {
  654. log.Error(e.Message);
  655. }
  656. MsgFieldBSE.InitFieldSTDColoredPartsDataMsg();
  657. m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);
  658. //start db save
  659. StartSaveFileThread(ref curFld);
  660. SendFieldParticlesInfoToGUI(curFld, m_Sample.GetMsrStatus());
  661. }
  662. while (bSaveThreadWorking)//wait untill all the field data has been saved.
  663. {
  664. Thread.Sleep(1000);
  665. log.Warn("db saving!");
  666. }
  667. TheLastWorkOfSampleMeasure();
  668. }
  669. }
  670. public void TheLastWorkOfSampleMeasure()
  671. {
  672. COTSSample theSample = m_Sample;
  673. var pStatus = theSample.GetMsrStatus();
  674. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.COMPLT);
  675. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  676. // let main thread to know that this sample measurement completes
  677. ST_MSTMsg MsgSmplEnd = new ST_MSTMsg(m_Sample);
  678. MsgSmplEnd.InitSampleCompleteMsg();
  679. m_pMsrThread.SendMessageToMeasureGUI(MsgSmplEnd);
  680. string userdB = m_Sample.GetMsrParams().GetSTDName();
  681. if(userdB.ToLower() != "nostddb" && userdB.ToLower() != "nostddb.db")
  682. {
  683. try
  684. {
  685. string userdBpath= System.Windows.Forms.Application.StartupPath + "\\Config\\SysData\\" + m_Sample.GetMsrParams().GetSTDName() + ".db";
  686. File.Copy(userdBpath, m_pSampleRstFile.GetFieldFileSubFolderStr().Remove(m_pSampleRstFile.GetFieldFileSubFolderStr().IndexOf("FIELD_FILES")) + m_Sample.GetMsrParams().GetSTDName() + ".db", true);
  687. }
  688. catch(Exception ex)
  689. {
  690. MessageBox.Show("userdB copy failed:" + ex.ToString());
  691. }
  692. }
  693. }
  694. public bool DoMEasureForReMeasure()
  695. {
  696. return true;
  697. }
  698. public virtual void FieldImageProcess(COTSField curFldData)
  699. {
  700. PointF fldCenter = curFldData.GetOTSPosition();
  701. CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
  702. PointF semPos = new Point();
  703. a_pCSEMStageData.ConvertOTSToSEMCoord(fldCenter, ref semPos);
  704. curFldData.SetSemPos(semPos);
  705. //first step:remove background of the bse image and compound all the finded particles.
  706. log.Info("Begin to process image and get all particles!");
  707. //according to the ECD scope,filter out the effective particles,remove the noise.
  708. curFldData.GetOriginalParticles(m_Sample.GetMsrParams(), m_Sample.CalculatePixelSize());
  709. log.Info("Begin to filter particles!");
  710. curFldData.FilterParticles(m_Sample.GetMsrParams().GetXRayParam());//filter according to the xraylimit
  711. log.Info("Begin to Calculate the image property of every particle!");
  712. var analysisparts = curFldData.GetListAnalysisParticles();
  713. curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc.
  714. CSampleParam pMsrParam = m_Sample.GetMsrParams();
  715. COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam();
  716. curFldData.SelectParticlesAccordingImgProp(pImgProcessParam);
  717. var overlap = pImgProcessParam.GetOverlapParam();
  718. if (overlap > 0)
  719. {
  720. try
  721. {
  722. curFldData.RemoveDuplicateOverlapParticles(overlap);
  723. }
  724. catch(Exception e)
  725. {
  726. log.Error(e.Message);
  727. }
  728. }
  729. curFldData.CalculateParticleAbsolutPos(m_pMsrThread.GetProjResultData().GetSEMStageData());
  730. curFldData.InitParticles(pImgProcessParam);
  731. return ;
  732. }
  733. public virtual void CollectParticlesXrayData(COTSField curFldData)
  734. {
  735. var allParts = curFldData.GetListXrayParticles();
  736. var smallparts = new List<COTSParticleClr>();
  737. var bigparts = new List<COTSParticleClr>();
  738. double quantifyThreshold = m_Sample.GetMsrParams().GetXRayParam().GetFeatureModeMinSize();
  739. foreach (var part in allParts)
  740. {
  741. double equalCircleDiameter = Math.Sqrt(part.GetActualArea() / 3.14159) * 2f;
  742. if (equalCircleDiameter < quantifyThreshold)
  743. {
  744. smallparts.Add(part);
  745. }
  746. else
  747. {
  748. bigparts.Add(part);
  749. }
  750. }
  751. log.Info("SmallQuantifyParts (<" + quantifyThreshold.ToString("f2") + "): " + smallparts.Count);
  752. log.Info("BigQuantifyParts (>=" + quantifyThreshold.ToString("f2") + "): " + bigparts.Count);
  753. curFldData.CreateXrayList(smallparts);
  754. curFldData.CreateXrayList(bigparts);
  755. // get x-ray parameters
  756. COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();
  757. var workmode = pXRayParam.GetScanMode();
  758. if (workmode == OTS_X_RAY_SCAN_MODE.PointMode)
  759. {
  760. uint nXRayAQTime;
  761. if (bigparts.Count > 0)
  762. {
  763. nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();
  764. log.Info("Begin to collect xraydata:" + bigparts.Count +"(" +nXRayAQTime.ToString()+") on " + workmode.ToString());
  765. m_EDSController.GetXRayByParts(bigparts, nXRayAQTime, true);
  766. }
  767. if (smallparts.Count > 0)
  768. {
  769. Thread.Sleep(500);//add delay here,or else the eds system will halt.
  770. nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();
  771. log.Info("Begin to collect xraydata:" + smallparts.Count + "(" + nXRayAQTime.ToString() + ") on " + workmode.ToString());
  772. m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);
  773. }
  774. }
  775. else if (workmode == OTS_X_RAY_SCAN_MODE.FeatureMode)
  776. {
  777. uint nXRayAQTime;
  778. if (bigparts.Count > 0)
  779. {
  780. log.Info("Begin to collect xraydata:" + bigparts.Count + " on " + OTS_X_RAY_SCAN_MODE.FeatureMode.ToString());
  781. nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();
  782. m_EDSController.GetXRayByFeatures(bigparts, nXRayAQTime, true);
  783. }
  784. if (smallparts.Count > 0)
  785. {
  786. Thread.Sleep(500);
  787. log.Info("Begin to collect xraydata:" + smallparts.Count + " on " + OTS_X_RAY_SCAN_MODE.PointMode.ToString());
  788. nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();
  789. m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);
  790. }
  791. }
  792. else if (workmode == OTS_X_RAY_SCAN_MODE.ExpandMode)
  793. {
  794. uint nXRayAQTime;
  795. if (bigparts.Count > 0)
  796. {
  797. log.Info("Begin to collect xraydata:" + bigparts.Count + " on " + OTS_X_RAY_SCAN_MODE.FeatureMode.ToString());
  798. nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();
  799. m_EDSController.GetXRayByExpandFeatures(bigparts, nXRayAQTime, true);
  800. }
  801. if (smallparts.Count > 0)
  802. {
  803. Thread.Sleep(500);
  804. log.Info("Begin to collect xraydata:" + smallparts.Count + " on " + OTS_X_RAY_SCAN_MODE.PointMode.ToString());
  805. nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();
  806. m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);
  807. }
  808. }
  809. return;
  810. }
  811. public virtual void QuantifyParticlesXrayData(COTSField curFldData)
  812. {
  813. var parts = curFldData.GetListXrayParticles();
  814. foreach (var p in parts)
  815. {
  816. m_EDSController.QuantifyXrayByPart(p);
  817. }
  818. }
  819. public void DoHolePreview()
  820. {
  821. using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this))
  822. {
  823. //----------memorize the state of sem
  824. var semstate = new SEMStateObject();
  825. double dMagnification = m_Sample.GetSEMDataMsr().GetMagnification();
  826. double wd = m_Sample.GetSEMDataMsr().GetWorkingDistance();
  827. ISemController sem = m_SemHardwareMgr;
  828. double posX=0, posY=0,posR=0;
  829. sem.GetSemPositionXY(ref posX, ref posY, ref posR);
  830. CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
  831. Point pos = new Point((int)posX, (int)posY);
  832. PointF otsPos = new Point(0, 0);
  833. if (!a_pCSEMStageData.ConvertSEMToOTSCoord(pos, ref otsPos))
  834. {
  835. return;
  836. }
  837. semstate.Pos = otsPos;
  838. semstate.Magnification = dMagnification;
  839. semstate.WorkingDistance = wd;
  840. autoReset.SemState = semstate;
  841. //-------------------------------------
  842. // let the main thread to know that this sample measurement starts
  843. CMsrSampleStatus pStatus = m_HolePreviewSample.GetMsrStatus();
  844. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  845. // set current time to current time
  846. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);
  847. // get SEM controller to set magnification and working distance
  848. if (!SetSEMDataMrs(m_HolePreviewSample))
  849. {
  850. log.Error("DoHolePreview: fail to set SEM data.");
  851. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  852. // record end time
  853. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  854. return;
  855. }
  856. // set the BSE scan param
  857. if (!SetHoleBSEParam(m_HolePreviewSample))
  858. {
  859. log.Error("DoHolePreview: fail to set BSE param.");
  860. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  861. // record end time
  862. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  863. return;
  864. }
  865. // calculate field centers
  866. List<System.Drawing.Point> listFieldCenter;
  867. List<System.Drawing.Point> alllistFieldCenter ;
  868. if (!CalculateUnMeasuredHoleImgCenters(m_HolePreviewSample, out alllistFieldCenter,out listFieldCenter))
  869. {// failed to calculate field centers
  870. log.Error("DoHolePreview: failed to calculate field centers.");
  871. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  872. // record end time
  873. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  874. return;
  875. }
  876. // go through each field
  877. //int nNewFieldId = 0;
  878. for ( int i = 0; i < listFieldCenter.Count; ++i)
  879. {// check and break if stop button is clicked
  880. if (IsAborted())
  881. {// measure stopped
  882. log.Trace("DoHolePreview: measure thread is stopped.");
  883. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
  884. // record end time
  885. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  886. return;
  887. }
  888. // check if sample measurement completes
  889. COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();
  890. int nTotalFieldSize = listFieldCenter.Count;
  891. // get a field center
  892. System.Drawing.Point poiFieldCentre = listFieldCenter[i];
  893. // move SEM to the field center
  894. if (!MoveSEMToPoint(poiFieldCentre))
  895. {// failed to move SEM to the position
  896. log.Error("DoHolePreview: failed to move SEM to the field centre point.");
  897. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  898. // record end time
  899. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  900. return;
  901. }
  902. // take BSE image for the fields
  903. CBSEImgClr pBSEIamge = AcquireABSEImage();
  904. if (pBSEIamge==null)
  905. {
  906. // failed to acquire a BSE image
  907. log.Error("DoHolePreview: failed to acquire a BSE image.");
  908. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  909. // record end time
  910. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  911. return;
  912. }
  913. //BSEData
  914. ST_MSTMsg MsgFieldBSE=new ST_MSTMsg(m_HolePreviewSample);
  915. MsgFieldBSE.InitHolePreBSEDataMsg(pBSEIamge,poiFieldCentre);
  916. m_pMsrThread.SendHolePreviewMessageToMeasureGUI(MsgFieldBSE);
  917. if (pStatus.GetStatus() != OTS_MSR_SAMPLE_STATUS.INPROCESS)
  918. {
  919. // measurement failed or stopped
  920. log.Error("DoHolePreview: measurement failed or stopped.");
  921. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
  922. // record end time
  923. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  924. return;
  925. }
  926. //save the result to project file
  927. Rectangle oImageRect = (Rectangle)pBSEIamge.GetImageRect();
  928. CHoleBSEImg pHoleBSEImg =new CHoleBSEImg(oImageRect,poiFieldCentre);
  929. pHoleBSEImg.SetImageData( pBSEIamge.GetImageDataPtr(),oImageRect.Width,oImageRect.Height);
  930. m_listHoleBSEImg.Add(pHoleBSEImg);
  931. }
  932. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  933. //calculate measure time
  934. pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
  935. // let main thread to know that this sample measurement completes
  936. ST_MSTMsg MsgSmplEnd=new ST_MSTMsg(m_HolePreviewSample);
  937. MsgSmplEnd.InitHolePreSampleEndMsg();
  938. m_pMsrThread.SendHolePreviewMessageToMeasureGUI(MsgSmplEnd);
  939. }
  940. }
  941. // Cumulate field data info
  942. public virtual bool CumulateFieldData( List<COTSParticleClr> listParticles, double a_nMeasuredArea)
  943. {
  944. // get measure result items of the sample
  945. CMsrResultItems pMsrResults = m_Sample.GetMsrResults();
  946. // go through the particles list
  947. foreach (COTSParticleClr pParticle in listParticles)
  948. {
  949. // create a measure result item
  950. pMsrResults.CumulateMeasureResult(pParticle);
  951. }
  952. pMsrResults.CumulateMeasuredArea(a_nMeasuredArea);
  953. // cumulate ratio
  954. double dRatio = pMsrResults.GetTotalParticleArea();
  955. dRatio = dRatio / pMsrResults.GetMeasuredArea();
  956. pMsrResults.SetRatio(dRatio);
  957. m_Sample.SetMsrResults(pMsrResults);
  958. return true;
  959. }
  960. public bool SaveFieldData(COTSField fldData, string filedFileFoler)
  961. {
  962. string strFieldFileFolder = filedFileFoler;
  963. CBSEImageFileMgr pBSEImgFileMgr = new CBSEImageFileMgr();
  964. pBSEImgFileMgr.SetBSEImg(fldData.GetBSEImage());
  965. int nId = fldData.GetId();
  966. string sFieldId;
  967. sFieldId = nId.ToString();
  968. string strBSEFilePathname = strFieldFileFolder + "\\" + m_pSampleRstFile.SMPL_MSR_RESULT_FIELDS_BSE + sFieldId + pBSEImgFileMgr.BMP_IMG_FILE_EXT;
  969. if (!pBSEImgFileMgr.SaveIntoBitmap(strBSEFilePathname))
  970. {
  971. log.Error("SaveFieldFiles: save BSE file failed.");
  972. return false;
  973. }
  974. if (fldData.particleImages.Count > 0)
  975. {
  976. for (int i=0;i<fldData.particleImages.Count;i++)
  977. {
  978. strBSEFilePathname= m_pSampleRstFile.GetParticleImageFolder() + "\\" + sFieldId +"_" +i.ToString()+pBSEImgFileMgr.BMP_IMG_FILE_EXT;
  979. pBSEImgFileMgr.SetBSEImg(fldData.particleImages[i]);
  980. pBSEImgFileMgr.SaveIntoBitmap(strBSEFilePathname);
  981. }
  982. }
  983. // IncA Data list
  984. CIncAFileMgr pDBFileMgr = m_pSampleRstFile.DBFileMgr;
  985. pDBFileMgr.SaveStatusDataToDB();
  986. var fldDB = pDBFileMgr.GetFieldDB();
  987. log.Warn("Start saving particle data.");
  988. var fldcmd = fldDB.GetSavingAFieldcmdObj(fldData.GetId(), fldData.GetOTSPosition(), fldData.GetSemPos());
  989. List<KeyValuePair<string, System.Data.SQLite.SQLiteParameter[]>> fldcmds = new List<KeyValuePair<string, System.Data.SQLite.SQLiteParameter[]>>();
  990. fldcmds.Add(fldcmd);
  991. pDBFileMgr.ExecuteNonQueryBatch(ref fldcmds);
  992. //remomove the invalid particles
  993. var cmds = pDBFileMgr.GetSavingParticleDataToDBCmds(fldData.GetListAnalysisParticles(), fldData.GetOTSPosition());
  994. pDBFileMgr.ExecuteNonQueryBatch(ref cmds);
  995. CPosXrayDBMgr PosXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr();
  996. var listAnalysisPosXray = new List<CPosXrayClr>();
  997. foreach (var p in fldData.GetListXrayParticles())
  998. {
  999. listAnalysisPosXray.Add(p.GetXray());
  1000. }
  1001. var cmds1 = PosXrayDBMgr.GetSavingXrayCmds(listAnalysisPosXray, true);
  1002. pDBFileMgr.ExecuteNonQueryBatch(ref cmds1);
  1003. return true;
  1004. }
  1005. protected void SaveFieldMgrData()
  1006. {
  1007. while (bSaveThreadWorking)
  1008. {
  1009. while (fieldQueue.Count() > 0)
  1010. {
  1011. COTSField f = fieldQueue.Dequeue();
  1012. //save to disk first ,then pop . if the size is 0,then we know all the saving work is done.
  1013. log.Info("Begin to save particles data! particle num:" + f.GetListAnalysisParticles().Count);
  1014. SaveFieldData(f, m_pSampleRstFile.GetFieldFileSubFolderStr());
  1015. }
  1016. if (fieldQueue.Count() == 0)
  1017. {
  1018. bSaveThreadWorking = false; //must set this flag,so the main thread can know this thread has exited.
  1019. log.Warn("finished batch saving");
  1020. return;
  1021. }
  1022. }
  1023. return;
  1024. }
  1025. private void SendFieldParticlesInfoToGUI(COTSField curFld,CMsrSampleStatus pStatus)
  1026. {
  1027. double measuredArea = 0; // this area should be the field area
  1028. var a_pBSEImg = curFld.GetBSEImage();
  1029. double dPixelSize = curFld.GetPixelSize();
  1030. measuredArea = a_pBSEImg.GetHeight() * a_pBSEImg.GetWidth() * dPixelSize * dPixelSize; //Get measured area
  1031. CumulateFieldData(curFld.GetListAnalysisParticles(), measuredArea);
  1032. log.Info("Send field data to screen!");
  1033. pStatus.AddCompletedFieldCenter(curFld.GetOTSPosition());
  1034. //Field Data
  1035. // record end time
  1036. pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
  1037. ST_MSTMsg MsgFieldEnd = new ST_MSTMsg(m_Sample,curFld);
  1038. MsgFieldEnd.InitFieldDataMsg();
  1039. m_pMsrThread.SendMessageToMeasureGUI(MsgFieldEnd);
  1040. }
  1041. protected void StartSaveFileThread(ref COTSField a_pFieldMgr)
  1042. {
  1043. fieldQueue.Enqueue(a_pFieldMgr);
  1044. if (fieldQueue.Count() > 0) //if there's data in the queue and the previous thread has finished then start a new thread.
  1045. {
  1046. if (bSaveThreadWorking == false)
  1047. {
  1048. bSaveThreadWorking = true;
  1049. m_thread_ptr = new System.Threading.Thread(this.SaveFieldMgrData);//m_thread_ptr = shared_ptr<thread>(new thread(&CSmplMeasureInc::SaveFieldMgrData, this));
  1050. m_thread_ptr.IsBackground = true;
  1051. m_thread_ptr.Start();
  1052. }
  1053. }
  1054. }
  1055. }
  1056. }