COTSField.cs 37 KB

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