COTSField.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. using OTSCLRINTERFACE;
  2. using OTSMeasureApp._0_OTSModel.OTSDataType;
  3. using OTSModelSharp;
  4. using OTSModelSharp.ServiceCenter;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Drawing;
  8. using System.Linq;
  9. using System.Xml;
  10. namespace OTSDataType
  11. {
  12. public class COTSField : ISlo
  13. {
  14. public COTSField leftField = null;
  15. public COTSField upField = null;
  16. public COTSField downField = null;
  17. public COTSField rightField = null;
  18. protected NLog.Logger log;
  19. // ID
  20. int m_nID;
  21. int measureSequence;
  22. // position (from field center manager)
  23. protected System.Drawing.PointF m_otsPos;
  24. protected CBSEImgClr m_pBSEImg;
  25. protected double m_pixelSize;
  26. protected CImageHandler m_ImagePro;
  27. protected List<COTSParticleClr> m_listAllParticles = new List<COTSParticleClr>();//hold up all the particles abstracted from bse image;
  28. protected List<COTSParticleClr> m_listAnalysisParticles = new List<COTSParticleClr>();// according to xraylimit constraint,pick out the first big particles.
  29. protected List<COTSParticleClr> m_listXrayParticles = new List<COTSParticleClr>();//hold up all the particles that needing the xray data.
  30. private int imgheight;
  31. private int imgwidth;
  32. private COTSRect m_otsRect;
  33. private COTSSample m_sample;
  34. public COTSField()
  35. {
  36. log = NLog.LogManager.GetCurrentClassLogger();
  37. Init();
  38. }//only using in xmlserialization
  39. public int ImgHeight { get => imgheight; set => imgheight = value; }
  40. public int ImgWidth { get => imgwidth; set => imgwidth = value; }
  41. public COTSSample Sample { get => m_sample; set => m_sample = value; }
  42. internal COTSRect GetOTSRect()
  43. {
  44. return m_otsRect;
  45. }
  46. internal void SetOTSRect(COTSRect value)
  47. {
  48. m_otsRect = value;
  49. }
  50. public int GetMeasureSequence()
  51. {
  52. return measureSequence;
  53. }
  54. public void SetMeasureSequence(int value)
  55. {
  56. measureSequence = value;
  57. }
  58. public List<string> strKeyName;
  59. public bool GetIsMeasureComplete()
  60. {
  61. return isMeasureComplete;
  62. }
  63. public void SetIsMeasureComplete(bool value)
  64. {
  65. isMeasureComplete = value;
  66. }
  67. private bool isMeasureComplete;
  68. public PointF GetSemPos()
  69. {
  70. return m_semPos;
  71. }
  72. public void SetSemPos(PointF value)
  73. {
  74. m_semPos = value;
  75. }
  76. private PointF m_semPos;
  77. public List<COTSParticleClr> GetAllParticles()
  78. {
  79. return m_listAllParticles;
  80. }
  81. public List<COTSParticleClr> GetListAnalysisParticles()
  82. {
  83. return m_listAnalysisParticles;
  84. }
  85. public List<COTSParticleClr> GetListXrayParticles()
  86. {
  87. m_listXrayParticles.Clear();
  88. foreach (var p in m_listAnalysisParticles)
  89. {
  90. if (p.IsXrayParticle())
  91. {
  92. m_listXrayParticles.Add(p);
  93. }
  94. }
  95. return m_listXrayParticles;
  96. }
  97. public void SetListAnalysisParticles(List<COTSParticleClr> value)
  98. {
  99. m_listAnalysisParticles = value;
  100. }
  101. public COTSField(PointF centerPoint, double a_dPixelSize)
  102. {
  103. log = NLog.LogManager.GetCurrentClassLogger();
  104. Init();
  105. //m_pBSEImg = a_pBSEImg;
  106. m_otsPos = centerPoint;
  107. m_pixelSize = a_dPixelSize;
  108. }
  109. public double GetPixelSize()
  110. {
  111. return m_pixelSize;
  112. }
  113. public void SetPixelSize(double size)
  114. {
  115. m_pixelSize = size;
  116. }
  117. // initialization
  118. void Init()
  119. {
  120. // initialization
  121. m_nID = -1;
  122. m_otsPos = new System.Drawing.Point(0, 0);
  123. m_listAllParticles.Clear();
  124. }
  125. public COTSField(COTSField a_poSource)
  126. {
  127. // can't copy itself
  128. if (a_poSource == this)
  129. {
  130. return;
  131. }
  132. Duplicate(a_poSource);
  133. }
  134. public CBSEImgClr GetBSEImage()
  135. {
  136. return m_pBSEImg;
  137. }
  138. public Bitmap GetAnalysisParticleBlackColoredImage()
  139. {
  140. CImageHandler imghandler = new CImageHandler();
  141. List<COTSParticleClr> Parts = GetAllParticles();
  142. Bitmap img = new Bitmap(this.ImgWidth, this.ImgHeight);
  143. var imgparam = m_sample.GetMsrParams().GetImageProcessParam();
  144. var pixelsize = m_sample.CalculatePixelSize();
  145. imghandler.GetImageWithBlackColoredParts(Parts,imgparam,pixelsize, ref img);
  146. return img;
  147. }
  148. public Bitmap GetAnalysisParticleSTDColoredImage()
  149. {
  150. CImageHandler imghandler = new CImageHandler();
  151. List<COTSParticleClr> Parts = GetListAnalysisParticles();
  152. Bitmap img = new Bitmap(this.ImgWidth, this.ImgHeight);
  153. var imgparam = m_sample.GetMsrParams().GetImageProcessParam();
  154. var pixelsize = m_sample.CalculatePixelSize();
  155. imghandler.GetImageWithSTDColoredParts(Parts, imgparam, pixelsize, ref img);
  156. return img;
  157. }
  158. public void SetBSEImage(CBSEImgClr a_pBSEImg)
  159. {
  160. if (a_pBSEImg == null)
  161. {
  162. // invalid BSE image.
  163. log.Error("SetBSEImage: invalid BSE image.");
  164. return;
  165. }
  166. m_pBSEImg = a_pBSEImg;
  167. imgwidth = a_pBSEImg.GetWidth();
  168. imgheight = a_pBSEImg.GetHeight();
  169. }
  170. public void GetOriginalParticles(CSampleParam pMsrParam, double pixelsize)
  171. {
  172. // get image process parameter
  173. //CSampleParam pMsrParam = m_Sample.GetMsrParams();
  174. COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam();
  175. var specialPartsparam = pMsrParam.GetSpecialGrayRangeParam();
  176. if (specialPartsparam != null && specialPartsparam.GetIsToRun())
  177. {
  178. List<CSpecialGrayRange> ranges = specialPartsparam.GetSpecialGreyRanges();
  179. foreach (var grayRange in ranges)
  180. {
  181. CIntRangeClr range = new CIntRangeClr(grayRange.range.GetStart(), grayRange.range.GetEnd());
  182. CDoubleRangeClr diaRange = new CDoubleRangeClr(grayRange.diameterRange.GetStart(), grayRange.diameterRange.GetEnd());
  183. GetPartsBySpecialGray(range, diaRange, pixelsize, grayRange.ifCollectXray);
  184. }
  185. }
  186. // remove BES image background
  187. RemoveImgBGAndGetParticles(pImgProcessParam, pixelsize);
  188. log.Info("Find all particle num:" + GetAllParticles().Count);
  189. return;
  190. }
  191. private void RemoveImgBGAndGetParticles(COTSImageProcParam a_pImageProcessParam, double a_pixelSize)
  192. {
  193. if (m_pBSEImg == null)
  194. return;
  195. CImageHandler imghandler = new CImageHandler();
  196. List<COTSParticleClr> allParts = new List<COTSParticleClr>();
  197. imghandler.RemoveBGAndGetParts(this, a_pImageProcessParam, ref allParts);
  198. m_listAllParticles = allParts;
  199. return;
  200. }
  201. class particleCompOnArea : IComparer<COTSParticleClr>
  202. {
  203. public int Compare(COTSParticleClr x, COTSParticleClr y)
  204. {
  205. return y.GetActualArea().CompareTo(x.GetActualArea());//descending sort
  206. }
  207. }
  208. public void FilterParticles(COTSXRayParam pXRayParam)
  209. {
  210. log.Info("filter particle according to xraylimit");
  211. m_listAllParticles.Sort(new particleCompOnArea());
  212. var listXray1 = new List<COTSParticleClr>();
  213. if (m_listAllParticles.Count > pXRayParam.GetXrayLimit())
  214. {
  215. for (var i = 0; i < pXRayParam.GetXrayLimit(); i++)
  216. {
  217. var part = m_listAllParticles[i];
  218. int l=0, r=0, t=0, b=0;
  219. part.GetOTSRect(ref l, ref t,ref r, ref b);
  220. COTSRect otsrec = new COTSRect(l, t, r, b);
  221. PointF p1 = otsrec.GetCenterPoint();
  222. if (m_sample.IsThisPointInMeasureArea(new Point((int)p1.X, (int)p1.Y)))
  223. {
  224. listXray1.Add(m_listAllParticles[i]);
  225. }
  226. }
  227. }
  228. else
  229. {
  230. foreach (var p in m_listAllParticles)
  231. {
  232. var part = p;
  233. int l = 0, r = 0, t = 0, b = 0;
  234. part.GetOTSRect(ref l, ref t, ref r, ref b);
  235. COTSRect otsrec = new COTSRect(l, t, r, b);
  236. PointF p1 = otsrec.GetCenterPoint();
  237. if (m_sample.IsThisPointInMeasureArea(new Point((int)p1.X, (int)p1.Y)))
  238. {
  239. listXray1.Add(p);
  240. }
  241. }
  242. }
  243. SetListAnalysisParticles(listXray1);
  244. log.Info("Xray Analysis particles:" + listXray1.Count);
  245. }
  246. public void SelectParticlesAccordingImgProp(COTSImageProcParam a_pImageProcessParam)
  247. {
  248. var selconditiondic = a_pImageProcessParam.GetParticleSelConditionDic();
  249. var listselparts = new List<COTSParticleClr>();
  250. var excludeparts = new List<COTSParticleClr>();
  251. if (selconditiondic.ContainsKey("dmax"))
  252. {
  253. log.Info("Select particles according to dmax");
  254. var rng = selconditiondic["dmax"];
  255. foreach (var p in GetListAnalysisParticles())
  256. {
  257. if (p.GetDMAX() < rng.GetStart() || p.GetDMAX() >= rng.GetEnd())
  258. {
  259. excludeparts.Add(p);
  260. }
  261. else
  262. {
  263. log.Info("dmax=" + p.GetDMAX().ToString("F2"));
  264. }
  265. }
  266. }
  267. if (selconditiondic.ContainsKey("dmin"))
  268. {
  269. log.Info("Select particles according to dmin");
  270. var rng = selconditiondic["dmin"];
  271. foreach (var p in GetListAnalysisParticles())
  272. {
  273. if (p.GetDMIN() < rng.GetStart() || p.GetDMIN() >= rng.GetEnd())
  274. {
  275. if (!excludeparts.Contains(p))
  276. {
  277. excludeparts.Add(p);
  278. }
  279. else
  280. {
  281. log.Info("dmin=" + p.GetDMIN().ToString("F2"));
  282. }
  283. }
  284. }
  285. }
  286. if (selconditiondic.ContainsKey("orientation"))
  287. {
  288. log.Info("Select particles according to orientation");
  289. var rng = selconditiondic["orientation"];
  290. foreach (var p in GetListAnalysisParticles())
  291. {
  292. if (p.GetORIENTATION() < rng.GetStart() || p.GetORIENTATION() >= rng.GetEnd())
  293. {
  294. if (!excludeparts.Contains(p))
  295. {
  296. excludeparts.Add(p);
  297. }
  298. else
  299. {
  300. log.Info("orientation=" + p.GetORIENTATION().ToString("F2"));
  301. }
  302. }
  303. }
  304. }
  305. if (selconditiondic.ContainsKey("aspect"))
  306. {
  307. log.Info("Select particles according to aspect");
  308. var rng = selconditiondic["aspect"];
  309. foreach (var p in GetListAnalysisParticles())
  310. {
  311. double aspect = p.GetDMAX() / p.GetDMIN();
  312. if (aspect < rng.GetStart() || aspect >= rng.GetEnd())
  313. {
  314. if (!excludeparts.Contains(p))
  315. {
  316. excludeparts.Add(p);
  317. }
  318. else
  319. {
  320. log.Info("aspect=" + aspect.ToString("F2"));
  321. }
  322. }
  323. }
  324. }
  325. if (selconditiondic.ContainsKey("ferret"))
  326. {
  327. log.Info("Select particles according to ferret");
  328. var rng = selconditiondic["ferret"];
  329. foreach (var p in GetListAnalysisParticles())
  330. {
  331. double dferet = p.GetFeretDiameter();
  332. if (dferet < rng.GetStart() || dferet >= rng.GetEnd())
  333. {
  334. if (!excludeparts.Contains(p))
  335. {
  336. excludeparts.Add(p);
  337. }
  338. else
  339. {
  340. log.Info("ferret=" + dferet.ToString("F2"));
  341. }
  342. }
  343. }
  344. }
  345. foreach (var p in GetListAnalysisParticles())
  346. {
  347. if (!excludeparts.Contains(p))
  348. {
  349. listselparts.Add(p);
  350. }
  351. }
  352. SetListAnalysisParticles(listselparts);
  353. log.Info("Analysis particles:" + listselparts.Count);
  354. }
  355. public void RemoveDuplicateOverlapParticles(int overlap)
  356. {
  357. List<COTSParticleClr> finalparts = new List<COTSParticleClr>();
  358. List<COTSParticleClr> duplicateparts = new List<COTSParticleClr>();
  359. //find left side duplicate particles
  360. var leftparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  361. if (leftField != null && leftField.measureSequence < this.measureSequence)
  362. {
  363. var rightsideparts = leftField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  364. if (leftField.upField != null && leftField.upField.measureSequence < this.measureSequence)//include the left up corner parts
  365. {
  366. var leftupParts = leftField.upField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  367. rightsideparts.AddRange(leftupParts);
  368. }
  369. if (leftField.downField != null && leftField.downField.measureSequence < this.measureSequence)//include the left down corner parts
  370. {
  371. var leftdownParts = leftField.downField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  372. rightsideparts.AddRange(leftdownParts);
  373. }
  374. log.Info("left side particles num:" + leftparts.Count.ToString());
  375. foreach (var p in leftparts)
  376. {
  377. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  378. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  379. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  380. PointF pcenter = prec.GetCenterPoint();
  381. foreach (var p1 in rightsideparts)
  382. {
  383. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  384. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  385. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  386. PointF p1Center = p1rec.GetCenterPoint();
  387. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  388. {
  389. var sim = p.CalculateSimilarity(p1);
  390. if (sim > 0.95)
  391. {
  392. log.Warn("remove left side duplicate particle,similarity:" + sim.ToString("F3"));
  393. log.Warn("P1:" + p.GetImgPortraitString());
  394. log.Warn("P2:" + p1.GetImgPortraitString());
  395. duplicateparts.Add(p);
  396. break;
  397. }
  398. }
  399. }
  400. }
  401. }
  402. //find up side duplicate particles
  403. var upparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
  404. if (upField != null && upField.measureSequence < this.measureSequence)
  405. {
  406. var othersideparts = upField.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
  407. log.Info("up side particles num:" + upparts.Count.ToString());
  408. foreach (var p in upparts)
  409. {
  410. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  411. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  412. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  413. PointF pcenter = prec.GetCenterPoint();
  414. foreach (var p1 in othersideparts)
  415. {
  416. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  417. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  418. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  419. PointF p1Center = p1rec.GetCenterPoint();
  420. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  421. {
  422. var sim = p.CalculateSimilarity(p1);
  423. if (sim > 0.95)
  424. {
  425. log.Warn("remove upside duplicate particle,similarity:" + sim.ToString("F3"));
  426. log.Warn("P1:" + p.GetImgPortraitString());
  427. log.Warn("P2:" + p1.GetImgPortraitString());
  428. duplicateparts.Add(p);
  429. break;
  430. }
  431. }
  432. }
  433. }
  434. }
  435. //find right side duplicate particles
  436. var rightparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  437. if (rightField != null && rightField.measureSequence < this.measureSequence)
  438. {
  439. log.Info("right side particles num:" + rightparts.Count.ToString());
  440. var othersideparts = rightField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  441. if (rightField.upField != null && rightField.upField.measureSequence < this.measureSequence)// right up corner parts
  442. {
  443. var rightupParts = rightField.upField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  444. othersideparts.AddRange(rightupParts);
  445. }
  446. if (rightField.downField != null && leftField.downField.measureSequence < this.measureSequence)// rightdown corner parts
  447. {
  448. var rightdownParts = leftField.downField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  449. othersideparts.AddRange(rightdownParts);
  450. }
  451. foreach (var p in rightparts)
  452. {
  453. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  454. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  455. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  456. PointF pcenter = prec.GetCenterPoint();
  457. foreach (var p1 in othersideparts)
  458. {
  459. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  460. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  461. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  462. PointF p1Center = p1rec.GetCenterPoint();
  463. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  464. {
  465. var sim = p.CalculateSimilarity(p1);
  466. if (sim > 0.95)
  467. {
  468. log.Warn("remove right side duplicate particle,similarity:" + sim.ToString("F3"));
  469. log.Warn("P1:" + p.GetImgPortraitString());
  470. log.Warn("P2:" + p1.GetImgPortraitString());
  471. duplicateparts.Add(p);
  472. break;
  473. }
  474. }
  475. }
  476. }
  477. }
  478. //find down side duplicate particles
  479. var downparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
  480. if (downField != null && downField.measureSequence < this.measureSequence)
  481. {
  482. log.Info("down side particles num:" + downparts.Count.ToString());
  483. var othersideparts = downField.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
  484. foreach (var p in downparts)
  485. {
  486. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  487. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  488. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  489. PointF pcenter = prec.GetCenterPoint();
  490. foreach (var p1 in othersideparts)
  491. {
  492. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  493. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  494. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  495. PointF p1Center = p1rec.GetCenterPoint();
  496. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  497. {
  498. var sim = p.CalculateSimilarity(p1);
  499. if (sim > 0.95)
  500. {
  501. log.Warn("remove down side duplicate particle,similarity:" + sim.ToString("F3"));
  502. log.Warn("P1:" + p.GetImgPortraitString());
  503. log.Warn("P2:" + p1.GetImgPortraitString());
  504. duplicateparts.Add(p);
  505. break;
  506. }
  507. }
  508. }
  509. }
  510. }
  511. foreach (var p in leftparts)
  512. {
  513. if (duplicateparts.Contains(p))
  514. {
  515. continue;
  516. }
  517. if (!finalparts.Contains(p))
  518. {
  519. finalparts.Add(p);
  520. }
  521. }
  522. foreach (var p in upparts)
  523. {
  524. if (duplicateparts.Contains(p))
  525. {
  526. continue;
  527. }
  528. if (!finalparts.Contains(p))
  529. {
  530. finalparts.Add(p);
  531. }
  532. }
  533. foreach (var p in rightparts)
  534. {
  535. if (duplicateparts.Contains(p))
  536. {
  537. continue;
  538. }
  539. if (!finalparts.Contains(p))
  540. {
  541. finalparts.Add(p);
  542. }
  543. }
  544. foreach (var p in downparts)
  545. {
  546. if (duplicateparts.Contains(p))
  547. {
  548. continue;
  549. }
  550. if (!finalparts.Contains(p))
  551. {
  552. finalparts.Add(p);
  553. }
  554. }
  555. foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.CENTER, overlap))
  556. {
  557. if (!finalparts.Contains(p))
  558. {
  559. finalparts.Add(p);
  560. }
  561. }
  562. this.SetListAnalysisParticles(finalparts);
  563. log.Info("removing duplicate particles result:" + finalparts.Count);
  564. }
  565. private List<COTSParticleClr> GetSideParticlesByOverlap(SORTING_DIRECTION direction, int overlap)
  566. {
  567. List<COTSParticleClr> sideparts = new List<COTSParticleClr>();
  568. var borderedparts = this.GetBorderedParticles();
  569. if (direction == SORTING_DIRECTION.LEFT)
  570. {
  571. foreach (var p in this.GetListAnalysisParticles())
  572. {
  573. int left = 0, top = 0, right = 0, bottom = 0;
  574. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  575. if (Math.Abs(right - this.GetOTSRect().GetTopLeft().X) < 2 * overlap)
  576. {
  577. if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or it's a big particle
  578. {
  579. sideparts.Add(p);
  580. }
  581. }
  582. }
  583. }
  584. if (direction == SORTING_DIRECTION.RIGHT)
  585. {
  586. foreach (var p in this.GetListAnalysisParticles())
  587. {
  588. int left = 0, top = 0, right = 0, bottom = 0;
  589. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  590. if (Math.Abs(this.GetOTSRect().GetBottomRight().X - left) < 2 * overlap)
  591. {
  592. if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or is a big part
  593. {
  594. sideparts.Add(p);
  595. }
  596. }
  597. }
  598. }
  599. if (direction == SORTING_DIRECTION.UP)
  600. {
  601. foreach (var p in this.GetListAnalysisParticles())
  602. {
  603. int left = 0, top = 0, right = 0, bottom = 0;
  604. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  605. if (Math.Abs(this.GetOTSRect().GetTopLeft().Y - bottom) < 2 * overlap)
  606. {
  607. if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
  608. {
  609. sideparts.Add(p);
  610. }
  611. }
  612. }
  613. }
  614. if (direction == SORTING_DIRECTION.DOWN)
  615. {
  616. foreach (var p in this.GetListAnalysisParticles())
  617. {
  618. int left = 0, top = 0, right = 0, bottom = 0;
  619. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  620. if (Math.Abs(top - this.GetOTSRect().GetBottomRight().Y) < 2 * overlap)
  621. {
  622. if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
  623. {
  624. sideparts.Add(p);
  625. }
  626. }
  627. }
  628. }
  629. if (direction == SORTING_DIRECTION.CENTER)
  630. {
  631. foreach (var p in this.GetListAnalysisParticles())
  632. {
  633. int left = 0, top = 0, right = 0, bottom = 0;
  634. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  635. var fldrec = this.GetOTSRect();
  636. int fldleft = (int)fldrec.GetTopLeft().X;
  637. int fldright = (int)fldrec.GetBottomRight().X;
  638. int fldtop = (int)fldrec.GetTopLeft().Y;
  639. int fldbottom = (int)fldrec.GetBottomRight().Y;
  640. if ((Math.Abs(top - fldtop) > 2 * overlap) && (Math.Abs(fldbottom - bottom) > 2 * overlap) && (Math.Abs(left - fldleft) > 2 * overlap) && (Math.Abs(fldright - right) > 2 * overlap))
  641. {
  642. sideparts.Add(p);
  643. }
  644. }
  645. }
  646. return sideparts;
  647. }
  648. public void GetPartsBySpecialGray(CIntRangeClr grayRange, CDoubleRangeClr diameterRange, double pixelSize, bool ifXray)
  649. {
  650. if (m_pBSEImg == null)
  651. return;
  652. CImageHandler imghandler = new CImageHandler();
  653. List<COTSParticleClr> specialParts = new List<COTSParticleClr>();
  654. imghandler.GetParticlesBySpecialGray(m_pBSEImg, grayRange, diameterRange, pixelSize, ref specialParts);
  655. foreach (var p in specialParts)
  656. {
  657. p.SetIsXrayParticle(ifXray);
  658. m_listAllParticles.Add(p);
  659. }
  660. return;
  661. }
  662. public bool CalParticleImageProp(List<COTSParticleClr> particles)
  663. {
  664. m_ImagePro = new CImageHandler();
  665. foreach (COTSParticleClr part in particles)
  666. {
  667. m_ImagePro.CalParticleImageProp(part, m_pixelSize);
  668. }
  669. return true;
  670. }
  671. public void CalculateParticleAbsolutPos(CSEMStageData pCSEMStageData)
  672. {
  673. //double dPixelSize = m_Sample.CalculatePixelSize();
  674. //CSEMStageData pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
  675. foreach (var p in GetListAnalysisParticles())
  676. {
  677. //Point fldOtsPos = new Point((curFldData.OTSPos.X, curFldData.OTSPos.Y);
  678. PointF semP = new PointF(); ;
  679. Point semPos = new Point();
  680. pCSEMStageData.ConvertOTSToSEMCoord(GetOTSPosition(), ref semP);
  681. semPos.X = (int)semP.X;
  682. semPos.Y = (int)semP.Y;
  683. p.SetSEMPos(semPos);
  684. }
  685. }
  686. public void InitParticles(COTSImageProcParam a_pImageProcessParam)
  687. {
  688. // get area range
  689. CDoubleRange oAreaRange = a_pImageProcessParam.GetIncAreaRange();
  690. double rMin = oAreaRange.GetStart() / 2.0;
  691. double rMax = oAreaRange.GetEnd() / 2.0;
  692. int nTagId = 0;
  693. foreach (COTSParticleClr pParticle in m_listAnalysisParticles)//m_listAllParticles memorize all the particles .
  694. {
  695. pParticle.SetParticleId(nTagId);//give all the conforming particles a unified sequence no.
  696. pParticle.SetFieldId(GetId());
  697. pParticle.SetType((int)otsdataconst.OTS_PARTICLE_TYPE.NO_ANALYSIS_X_RAY);
  698. pParticle.SetTypeName("Not Identified");
  699. pParticle.SetAnalysisId(nTagId); // the same as the tagId no use now.
  700. nTagId++;
  701. }
  702. log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): " + "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
  703. }
  704. public bool CreateXrayList(List<COTSParticleClr> a_listParticles)
  705. {
  706. foreach (COTSParticleClr pPart in a_listParticles)
  707. {
  708. System.Drawing.Point poi = (System.Drawing.Point)pPart.GetXRayPos();
  709. CPosXrayClr pPosXray = new CPosXrayClr();
  710. pPosXray.SetPosition(poi);
  711. pPosXray.SetPartTagId(pPart.GetParticleId());
  712. pPosXray.SetIndex(pPart.GetAnalysisId());
  713. pPosXray.SetScanFieldId(pPart.GetFieldId());
  714. pPart.SetXray(pPosXray);
  715. }
  716. return true;
  717. }
  718. public void ClearAllMeausredData()
  719. {
  720. m_listAllParticles.Clear();
  721. m_listAnalysisParticles.Clear();
  722. m_listXrayParticles.Clear();
  723. m_pBSEImg = null;
  724. }
  725. public bool PositionEquals(COTSField a_oSource)
  726. {
  727. if (a_oSource.m_otsPos == this.m_otsPos)
  728. {
  729. return true;
  730. }
  731. else
  732. {
  733. return false;
  734. }
  735. }
  736. // ID
  737. public int GetId()
  738. {
  739. return m_nID;
  740. }
  741. public void SetId(int a_nID)
  742. {
  743. m_nID = a_nID;
  744. }
  745. // position (from field center manager)
  746. public System.Drawing.PointF GetOTSPosition()
  747. {
  748. return m_otsPos;
  749. }
  750. public void SetOTSPosition(System.Drawing.PointF a_poiPos)
  751. {
  752. m_otsPos = a_poiPos;
  753. }
  754. public List<COTSParticleClr> GetTopBorderedParticles()
  755. {
  756. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  757. foreach (var p in m_listAnalysisParticles)
  758. {
  759. var segs = p.GetFeature().GetSegmentsList();//COTSSegment
  760. foreach (var seg in segs)
  761. {
  762. if (seg.GetHeight() == 0)
  763. {
  764. parts.Add(p);
  765. break;
  766. }
  767. }
  768. }
  769. return parts;
  770. }
  771. public List<COTSParticleClr> GetBottomBorderedParticles()
  772. {
  773. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  774. foreach (var p in m_listAnalysisParticles)
  775. {
  776. var segs = p.GetFeature().GetSegmentsList();
  777. foreach (var seg in segs)
  778. {
  779. if (seg.GetHeight() == this.ImgHeight - 1)//the lowest height is 767(height-1),cause starting from 0.
  780. {
  781. parts.Add(p);
  782. break;
  783. }
  784. }
  785. }
  786. return parts;
  787. }
  788. public List<COTSParticleClr> GetBorderedParticles()
  789. {
  790. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  791. var leftparts = this.GetLeftBorderedParticles();
  792. var rightp = this.GetRightBorderedParticles();
  793. var topp = this.GetTopBorderedParticles();
  794. var bottomp = this.GetBottomBorderedParticles();
  795. foreach (var p in leftparts)
  796. {
  797. if (!parts.Contains(p))
  798. {
  799. parts.Add(p);
  800. }
  801. }
  802. foreach (var p in rightp)//
  803. {
  804. if (!parts.Contains(p))
  805. {
  806. parts.Add(p);
  807. }
  808. }
  809. foreach (var p in topp)
  810. {
  811. if (!parts.Contains(p))//there may be some particles connect to both the left and top.
  812. {
  813. parts.Add(p);
  814. }
  815. }
  816. foreach (var p in bottomp)
  817. {
  818. if (!parts.Contains(p))
  819. {
  820. parts.Add(p);
  821. }
  822. }
  823. return parts;
  824. }
  825. public List<COTSParticleClr> GetLeftBorderedParticles()
  826. {
  827. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  828. foreach (var p in m_listAnalysisParticles)
  829. {
  830. var segs = p.GetFeature().GetSegmentsList();
  831. foreach (var seg in segs)
  832. {
  833. if (seg.GetStart() == 0)
  834. {
  835. parts.Add(p);
  836. break;
  837. }
  838. }
  839. }
  840. return parts;
  841. }
  842. public List<COTSParticleClr> GetRightBorderedParticles()
  843. {
  844. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  845. foreach (var p in m_listAnalysisParticles)
  846. {
  847. var segs = p.GetFeature().GetSegmentsList();
  848. foreach (var seg in segs)
  849. {
  850. if (seg.GetStart() + seg.GetLength() == this.ImgWidth)
  851. {
  852. parts.Add(p);
  853. break;
  854. }
  855. }
  856. }
  857. return parts;
  858. }
  859. // is empty
  860. public bool IsEmpty()
  861. {
  862. return m_listAllParticles.Count == 0;
  863. }
  864. void Duplicate(COTSField a_oSource)
  865. {
  866. m_nID = a_oSource.m_nID;
  867. m_otsPos = a_oSource.m_otsPos;
  868. // copy data over
  869. foreach (var pParticle in a_oSource.m_listAllParticles)
  870. {
  871. m_listAllParticles.Add(pParticle);
  872. }
  873. }
  874. public override void Serialize(bool isStoring, XmlDocument classDoc, XmlNode rootNode)
  875. {
  876. xPoint xPos = new xPoint();
  877. Slo slo = new Slo();
  878. slo.Register("OTSPosition", xPos);
  879. if (isStoring)
  880. {
  881. xPos.AssignValue(new System.Drawing.Point((int)m_otsPos.X, (int)m_otsPos.Y));
  882. slo.Serialize(true, classDoc, rootNode);
  883. }
  884. else
  885. {
  886. slo.Serialize(false, classDoc, rootNode);
  887. m_otsPos = xPos.value();
  888. }
  889. }
  890. }
  891. }