Browse Source

improve removeduplicateparticles algorithm

gsp 1 year ago
parent
commit
f8c2e568fc

+ 7 - 7
Bin/x64/Debug/Config/ReportTemplate/Inca_Template/ReportTemplateConfig.xml

@@ -33,13 +33,13 @@
     <b_ck_klcc_xsddt>False</b_ck_klcc_xsddt>
     <b_ck_klcc_dfl>True</b_ck_klcc_dfl>
     <b_ck_klcc_xfl>True</b_ck_klcc_xfl>
-    <str_cb_klcc_ljb>li3.psf</str_cb_klcc_ljb>
+    <str_cb_klcc_ljb>lj.psf</str_cb_klcc_ljb>
   </M_KLFXJG>
   <M_YSFXJG>
     <b_ck_ysfx_xsmk>True</b_ck_ysfx_xsmk>
     <index_cb_yxfx_jsfs>0</index_cb_yxfx_jsfs>
     <index_cb_ysfx_klfw>0</index_cb_ysfx_klfw>
-    <str_tb_ysfx_xsys>Al,Si,C,S,N,O,Fe,Ti,Mn,Mg,Ca,Ce,La</str_tb_ysfx_xsys>
+    <str_tb_ysfx_xsys>Al,Si,C,S,N,O,Fe,Ti,Mn,Ca,Ce,La,Mg</str_tb_ysfx_xsys>
     <list_str_tb_ysfx_xsys>
       <YS0>Al</YS0>
       <YS1>Si</YS1>
@@ -50,10 +50,10 @@
       <YS6>Fe</YS6>
       <YS7>Ti</YS7>
       <YS8>Mn</YS8>
-      <YS9>Mg</YS9>
-      <YS10>Ca</YS10>
-      <YS11>Ce</YS11>
-      <YS12>La</YS12>
+      <YS9>Ca</YS9>
+      <YS10>Ce</YS10>
+      <YS11>La</YS11>
+      <YS12>Mg</YS12>
     </list_str_tb_ysfx_xsys>
     <b_ck_yscf_xsmk>True</b_ck_yscf_xsmk>
     <index_cb_yscf_xstx>0</index_cb_yscf_xstx>
@@ -77,7 +77,7 @@
       <MBIndex0>0</MBIndex0>
       <MBIndex1>2</MBIndex1>
     </list_lbv_syxt_mblb_index>
-    <str_cb_syxt_ljb>li3.psf</str_cb_syxt_ljb>
+    <str_cb_syxt_ljb>lj.psf</str_cb_syxt_ljb>
   </M_SYXT>
   <M_KLLBXX>
     <b_ck_kllb_xsmk>True</b_ck_kllb_xsmk>

+ 1 - 1
OTSCPP/OTSData/OTSParticle.cpp

@@ -183,7 +183,7 @@ namespace OTSDATA {
 		{
 			arearatio = part->GetActualArea() / this->GetActualArea();
 		}
-		if (arearatio < 0.8)
+		if (arearatio < 0.85)
 		{
 			return 0;
 		}

+ 221 - 190
OTSIncAMeasureApp/0-OTSModel/OTSDataType/COTSField.cs

@@ -1,47 +1,40 @@
+using OTSCLRINTERFACE;
+using OTSMeasureApp._0_OTSModel.OTSDataType;
+using OTSModelSharp;
+using OTSModelSharp.ServiceCenter;
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
 using System.Drawing;
-using OTSModelSharp.ImageProcess;
-using OTSModelSharp.ServiceCenter;
-using OTSDataType;
-using OTSCLRINTERFACE;
 using System.Xml;
-using OTSMeasureApp._0_OTSModel.OTSDataType;
-using OTSModelSharp;
 
 namespace OTSDataType
 {
-   using  COTSFieldDataList = List<COTSField>;
-   public class COTSField:ISlo
+    public class COTSField : ISlo
     {
-        public COTSField leftField=null;
-        public COTSField upField=null;
-        public COTSField downField=null;
-        public COTSField rightField=null;
-        protected  NLog.Logger log ;
+        public COTSField leftField = null;
+        public COTSField upField = null;
+        public COTSField downField = null;
+        public COTSField rightField = null;
+        protected NLog.Logger log;
         // ID
         int m_nID;
 
         int measureSequence;
-       
+
         // position (from field center manager) 
-      protected  System.Drawing.PointF m_otsPos ;
+        protected System.Drawing.PointF m_otsPos;
 
-       protected CBSEImgClr m_pBSEImg;
+        protected CBSEImgClr m_pBSEImg;
 
-      protected  double m_pixelSize;
+        protected double m_pixelSize;
 
-       protected   CImageHandler m_ImagePro;
+        protected CImageHandler m_ImagePro;
 
         protected List<COTSParticleClr> m_listAllParticles = new List<COTSParticleClr>();//hold up all the particles abstracted from bse image;
 
-       protected  List<COTSParticleClr> m_listAnalysisParticles = new List<COTSParticleClr>();// according to xraylimit constraint,pick out the first big particles.
+        protected List<COTSParticleClr> m_listAnalysisParticles = new List<COTSParticleClr>();// according to xraylimit constraint,pick out the first big particles.
 
-       protected List<COTSParticleClr> m_listXrayParticles = new List<COTSParticleClr>();//hold up all the particles that needing the xray data.
+        protected List<COTSParticleClr> m_listXrayParticles = new List<COTSParticleClr>();//hold up all the particles that needing the xray data.
 
 
         private int imgheight;
@@ -71,7 +64,7 @@ namespace OTSDataType
             m_otsRect = value;
         }
 
-         public int GetMeasureSequence()
+        public int GetMeasureSequence()
         {
             return measureSequence;
         }
@@ -133,7 +126,7 @@ namespace OTSDataType
             m_listAnalysisParticles = value;
         }
 
-       
+
 
         public COTSField(PointF centerPoint, double a_dPixelSize)
         {
@@ -142,8 +135,8 @@ namespace OTSDataType
             //m_pBSEImg = a_pBSEImg;
             m_otsPos = centerPoint;
             m_pixelSize = a_dPixelSize;
-           
-           
+
+
         }
         public double GetPixelSize()
         {
@@ -153,16 +146,16 @@ namespace OTSDataType
         {
             m_pixelSize = size;
         }
-       
+
         // initialization
         void Init()
         {
             // initialization
             m_nID = -1;
-            m_otsPos =new  System.Drawing.Point(0, 0);
+            m_otsPos = new System.Drawing.Point(0, 0);
             m_listAllParticles.Clear();
         }
-       
+
 
         public COTSField(COTSField a_poSource)
         {
@@ -192,7 +185,7 @@ namespace OTSDataType
             imgheight = a_pBSEImg.GetHeight();
         }
 
-        public void RemoveImgBGAndGetParticles(COTSImageProcParam a_pImageProcessParam,double a_pixelSize,bool ifXray)
+        public void RemoveImgBGAndGetParticles(COTSImageProcParam a_pImageProcessParam, double a_pixelSize, bool ifXray)
         {
             if (m_pBSEImg == null)
                 return;
@@ -203,26 +196,29 @@ namespace OTSDataType
             {
                 p.SetIsXrayParticle(ifXray);
                 m_listAllParticles.Add(p);
-               
+
             }
-           
-            return ;
+
+            return;
         }
         public void RemoveDuplicateOverlapParticles(int overlap)
         {
             List<COTSParticleClr> finalparts = new List<COTSParticleClr>();
+            List<COTSParticleClr> duplicateparts = new List<COTSParticleClr>();
+            //find left side duplicate particles
+            var leftparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
             if (leftField != null && leftField.measureSequence < this.measureSequence)
             {
-                var leftparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
+
+                var rightsideparts = leftField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
                 log.Info("left side particles num:" + leftparts.Count.ToString());
-                foreach (var p in leftparts )
+                foreach (var p in leftparts)
                 {
                     int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
                     p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
                     COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
                     PointF pcenter = prec.GetCenterPoint();
-                    bool findsimilar = false;
-                    var rightsideparts = leftField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
+
                     foreach (var p1 in rightsideparts)
                     {
                         int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
@@ -232,39 +228,29 @@ namespace OTSDataType
                         if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
                         {
                             var sim = p.CalculateSimilarity(p1);
-                            if ( sim> 0.95)
+                            if (sim > 0.95)
                             {
                                 log.Warn("remove left side duplicate particle,similarity:" + sim.ToString("F3"));
                                 log.Warn("P1:" + p.GetImgPortraitString());
-                                log.Warn("P2:" + p1.GetImgPortraitString());
-                                findsimilar = true;
+                                log.Warn("P2:" + p1.GetImgPortraitString());                              
+                                duplicateparts.Add(p);
                                 break;
                             }
                         }
 
                     }
-                    if (findsimilar == false)
-                    {
-                        if (!finalparts.Contains(p))//particles in the four corner are processed more than one time
-                        {
-                            finalparts.Add(p);
-                        }
-                       
-                    }
+
 
 
                 }
             }
-            else 
-            {
-                foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap))
-                {
-                    finalparts.Add(p);
-                }
-            }
+
+            //find up side duplicate particles
+            var upparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
             if (upField != null && upField.measureSequence < this.measureSequence)
             {
-                var upparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
+
+                var othersideparts = upField.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
                 log.Info("up side particles num:" + upparts.Count.ToString());
                 foreach (var p in upparts)
                 {
@@ -272,8 +258,8 @@ namespace OTSDataType
                     p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
                     COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
                     PointF pcenter = prec.GetCenterPoint();
-                    bool findsimilar = false;
-                    var othersideparts = upField.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
+
+
                     foreach (var p1 in othersideparts)
                     {
                         int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
@@ -288,45 +274,35 @@ namespace OTSDataType
                                 log.Warn("remove upside duplicate particle,similarity:" + sim.ToString("F3"));
                                 log.Warn("P1:" + p.GetImgPortraitString());
                                 log.Warn("P2:" + p1.GetImgPortraitString());
-                                findsimilar = true;
+
+                                duplicateparts.Add(p);
                                 break;
                             }
                         }
 
                     }
-                    if (findsimilar == false)
-                    {
-                        if (!finalparts.Contains(p))
-                        {
-                            finalparts.Add(p);
-                        }
-                    }
+
 
 
                 }
             }
-            else
-            {
-                foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap))
-                {
-                    if (!finalparts.Contains(p))
-                    {
-                        finalparts.Add(p);
-                    }
-                }
-            }
+
+
+
+            //find right side duplicate particles
+            var rightparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
             if (rightField != null && rightField.measureSequence < this.measureSequence)
             {
-                var rightparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
+
                 log.Info("right side particles num:" + rightparts.Count.ToString());
+                var othersideparts = rightField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
                 foreach (var p in rightparts)
                 {
                     int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
                     p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
                     COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
                     PointF pcenter = prec.GetCenterPoint();
-                    bool findsimilar = false;
-                    var othersideparts = rightField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
+
                     foreach (var p1 in othersideparts)
                     {
                         int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
@@ -341,45 +317,32 @@ namespace OTSDataType
                                 log.Warn("remove right side duplicate particle,similarity:" + sim.ToString("F3"));
                                 log.Warn("P1:" + p.GetImgPortraitString());
                                 log.Warn("P2:" + p1.GetImgPortraitString());
-                                findsimilar = true;
+                                duplicateparts.Add(p);
                                 break;
                             }
                         }
 
                     }
-                    if (findsimilar == false)
-                    {
-                        if (!finalparts.Contains(p))
-                        {
-                            finalparts.Add(p);
-                        }
-                    }
-
 
                 }
             }
-            else
-            {
-                foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap))
-                {
-                    if (!finalparts.Contains(p))
-                    {
-                        finalparts.Add(p);
-                    }
-                }
-            }
+
+
+
+            //find down side duplicate particles
+            var downparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
             if (downField != null && downField.measureSequence < this.measureSequence)
             {
-                var downparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
+
                 log.Info("down side particles num:" + downparts.Count.ToString());
+                var othersideparts = downField.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
                 foreach (var p in downparts)
                 {
                     int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
                     p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
                     COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
                     PointF pcenter = prec.GetCenterPoint();
-                    bool findsimilar = false;
-                    var othersideparts = downField.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
+
                     foreach (var p1 in othersideparts)
                     {
                         int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
@@ -394,34 +357,64 @@ namespace OTSDataType
                                 log.Warn("remove down side duplicate particle,similarity:" + sim.ToString("F3"));
                                 log.Warn("P1:" + p.GetImgPortraitString());
                                 log.Warn("P2:" + p1.GetImgPortraitString());
-                                findsimilar = true;
+                                duplicateparts.Add(p);
+
                                 break;
                             }
                         }
 
                     }
-                    if (findsimilar == false)
-                    {
-                        if (!finalparts.Contains(p))
-                        {
-                            finalparts.Add(p);
-                        }
-                    }
+
+                }
+            }
 
 
+            foreach (var p in leftparts)
+            {
+                if (duplicateparts.Contains(p))
+                {
+                    continue;
+                }
+                if (!finalparts.Contains(p))
+                {
+                    finalparts.Add(p);
                 }
             }
-            else
+            foreach (var p in upparts)
             {
-                foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap))
+                if (duplicateparts.Contains(p))
                 {
-                    if (!finalparts.Contains(p))
-                    {
-                        finalparts.Add(p);
-                    }
+                    continue;
+                }
+                if (!finalparts.Contains(p))
+                {
+                    finalparts.Add(p);
+                }
+            }
+            foreach (var p in rightparts)
+            {
+                if (duplicateparts.Contains(p))
+                {
+                    continue;
+                }
+                if (!finalparts.Contains(p))
+                {
+                    finalparts.Add(p);
+                }
+            }
+            foreach (var p in downparts)
+            {
+                if (duplicateparts.Contains(p))
+                {
+                    continue;
+                }
+                if (!finalparts.Contains(p))
+                {
+                    finalparts.Add(p);
                 }
             }
 
+
             foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.CENTER, overlap))
             {
                 if (!finalparts.Contains(p))
@@ -433,24 +426,25 @@ namespace OTSDataType
             this.SetListAnalysisParticles(finalparts);
             log.Info("removing duplicate particles result:" + finalparts.Count);
         }
-        private List<COTSParticleClr> GetSideParticlesByOverlap(SORTING_DIRECTION direction,int overlap)
+        private List<COTSParticleClr> GetSideParticlesByOverlap(SORTING_DIRECTION direction, int overlap)
         {
             List<COTSParticleClr> sideparts = new List<COTSParticleClr>();
+            var borderedparts = this.GetBorderedParticles();
             if (direction == SORTING_DIRECTION.LEFT)
             {
-                var leftborderParts = this.GetLeftBorderedParticles();
+                
                 foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
 
-                    if ((right - this.GetOTSRect().GetTopLeft().X) < 2 * overlap)
+                    if (Math.Abs(right - this.GetOTSRect().GetTopLeft().X) < 2 * overlap)
                     {
-                        if (!leftborderParts.Contains(p) || Math.Abs(left-right)>2*overlap )//not on the border or it's a big particle
+                        if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or it's a big particle
                         {
                             sideparts.Add(p);
                         }
-                        
+
                     }
 
                 }
@@ -458,14 +452,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.RIGHT)
             {
-                var rightborderParts = this.GetRightBorderedParticles();
+                
                 foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
-                    if ((this.GetOTSRect().GetBottomRight().X-left) < 2 * overlap)
+                    if (Math.Abs(this.GetOTSRect().GetBottomRight().X - left) < 2 * overlap)
                     {
-                        if (!rightborderParts.Contains(p)|| Math.Abs(left - right) > 2 * overlap)//not on the border or is a big part
+                        if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or is a big part
                         {
                             sideparts.Add(p);
                         }
@@ -476,14 +470,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.UP)
             {
-                var upborderParts = this.GetTopBorderedParticles();
+               
                 foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
-                    if ((this.GetOTSRect().GetTopLeft().Y - bottom) < 2 * overlap)
+                    if (Math.Abs(this.GetOTSRect().GetTopLeft().Y - bottom) < 2 * overlap)
                     {
-                        if (!upborderParts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
+                        if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
                         {
                             sideparts.Add(p);
                         }
@@ -494,14 +488,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.DOWN)
             {
-                var downborderParts = this.GetBottomBorderedParticles();
+               
                 foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
-                    if ((top-this.GetOTSRect().GetBottomRight().Y ) < 2 * overlap)
+                    if (Math.Abs(top - this.GetOTSRect().GetBottomRight().Y) < 2 * overlap)
                     {
-                        if (!downborderParts.Contains(p)|| Math.Abs(top - bottom) > 2 * overlap)//not on the border
+                        if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
                         {
                             sideparts.Add(p);
                         }
@@ -521,7 +515,7 @@ namespace OTSDataType
                     int fldright = (int)fldrec.GetBottomRight().X;
                     int fldtop = (int)fldrec.GetTopLeft().Y;
                     int fldbottom = (int)fldrec.GetBottomRight().Y;
-                    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))
+                    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))
                     {
                         sideparts.Add(p);
                     }
@@ -532,18 +526,18 @@ namespace OTSDataType
             return sideparts;
 
         }
-        public void GetPartsBySpecialGray(CIntRangeClr grayRange, CDoubleRangeClr diameterRange,double pixelSize, bool ifXray)
+        public void GetPartsBySpecialGray(CIntRangeClr grayRange, CDoubleRangeClr diameterRange, double pixelSize, bool ifXray)
         {
             if (m_pBSEImg == null)
                 return;
             CImageHandler imghandler = new CImageHandler();
             List<COTSParticleClr> specialParts = new List<COTSParticleClr>();
-            imghandler.GetParticlesBySpecialGray(m_pBSEImg, grayRange,diameterRange,pixelSize, ref specialParts);
+            imghandler.GetParticlesBySpecialGray(m_pBSEImg, grayRange, diameterRange, pixelSize, ref specialParts);
             foreach (var p in specialParts)
             {
                 p.SetIsXrayParticle(ifXray);
                 m_listAllParticles.Add(p);
-               
+
             }
 
             return;
@@ -553,62 +547,62 @@ namespace OTSDataType
             m_ImagePro = new CImageHandler();
             foreach (COTSParticleClr part in particles)
             {
-               
-                m_ImagePro.CalParticleImageProp( part, m_pixelSize);
+
+                m_ImagePro.CalParticleImageProp(part, m_pixelSize);
             }
             return true;
         }
-     
+
         public void InitParticles(COTSImageProcParam a_pImageProcessParam)
         {
-          
+
             // get area range
             CDoubleRange oAreaRange = a_pImageProcessParam.GetIncAreaRange();
             double rMin = oAreaRange.GetStart() / 2.0;
             double rMax = oAreaRange.GetEnd() / 2.0;
 
             int nTagId = 0;
-       
+
             foreach (COTSParticleClr pParticle in m_listAnalysisParticles)//m_listAllParticles memorize all the particles .
             {
-               
+
                 pParticle.SetParticleId(nTagId);//give all the conforming particles a unified sequence no.
-              
+
                 pParticle.SetFieldId(GetId());
-              
+
                 pParticle.SetType((int)otsdataconst.OTS_PARTICLE_TYPE.NO_ANALYSIS_X_RAY);
                 pParticle.SetTypeName("Not Identified");
-              
+
                 pParticle.SetAnalysisId(nTagId); // the same as the tagId no use now.  
                 nTagId++;
-               
-               
+
+
             }
-            log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): "+ "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
-           
+            log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): " + "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
+
+
 
-     
 
         }
-       
+
         public bool CreateXrayList(List<COTSParticleClr> a_listParticles)
         {
-     
+
             foreach (COTSParticleClr pPart in a_listParticles)
             {
-             
+
                 System.Drawing.Point poi = (System.Drawing.Point)pPart.GetXRayPos();
-             
+
                 CPosXrayClr pPosXray = new CPosXrayClr();
-               
+
                 pPosXray.SetPosition(poi);
-              
+
                 pPosXray.SetPartTagId(pPart.GetParticleId());
-              
+
                 pPosXray.SetIndex(pPart.GetAnalysisId());
-                
+
                 pPosXray.SetScanFieldId(pPart.GetFieldId());
-           
+
                 pPart.SetXray(pPosXray);
             }
             return true;
@@ -640,25 +634,25 @@ namespace OTSDataType
             }
 
         }
-        public bool PositionEquals(COTSField a_oSource)         
+        public bool PositionEquals(COTSField a_oSource)
         {
 
-           
+
             if (a_oSource.m_otsPos == this.m_otsPos)
             {
                 return true;
             }
-            else 
+            else
             {
                 return false;
             }
-    
-           
-              
+
+
+
         }
 
-     
-  
+
+
         // ID
         public int GetId()
         {
@@ -671,22 +665,22 @@ namespace OTSDataType
         }
 
         // position (from field center manager) 
-       public  System.Drawing.PointF GetOTSPosition()
+        public System.Drawing.PointF GetOTSPosition()
         {
             return m_otsPos;
         }
 
-       public  void SetOTSPosition(System.Drawing.PointF a_poiPos)
+        public void SetOTSPosition(System.Drawing.PointF a_poiPos)
         {
             m_otsPos = a_poiPos;
         }
 
-        public List<COTSParticleClr>    GetTopBorderedParticles()
+        public List<COTSParticleClr> GetTopBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             foreach (var p in m_listAnalysisParticles)
             {
-               
+
                 var segs = p.GetFeature().GetSegmentsList();//COTSSegment
                 foreach (var seg in segs)
                 {
@@ -700,7 +694,7 @@ namespace OTSDataType
             return parts;
         }
 
-        public List< COTSParticleClr > GetBottomBorderedParticles()
+        public List<COTSParticleClr> GetBottomBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             foreach (var p in m_listAnalysisParticles)
@@ -718,8 +712,45 @@ namespace OTSDataType
             }
             return parts;
         }
+        public List<COTSParticleClr> GetBorderedParticles()
+        {
+            List<COTSParticleClr> parts = new List<COTSParticleClr>();
+            var leftparts = this.GetLeftBorderedParticles();
+            var rightp = this.GetRightBorderedParticles();
+            var topp = this.GetTopBorderedParticles();
+            var bottomp = this.GetBottomBorderedParticles();
+            foreach (var p in leftparts)
+            {
+                if (!parts.Contains(p))
+                {
+                    parts.Add(p);
+                }
+            }
+            foreach (var p in rightp)//
+            {
+                if (!parts.Contains(p))
+                {
+                    parts.Add(p);
+                }
+            }
+            foreach (var p in topp)
+            {
+                if (!parts.Contains(p))//there may be some particles connect to both the left and top.
+                {
+                    parts.Add(p);
+                }
+            }
+            foreach (var p in bottomp)
+            {
+                if (!parts.Contains(p))
+                {
+                    parts.Add(p);
+                }
+            }
+            return parts;
+        }
 
-        public  List<COTSParticleClr> GetLeftBorderedParticles()
+        public List<COTSParticleClr> GetLeftBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             foreach (var p in m_listAnalysisParticles)
@@ -738,7 +769,7 @@ namespace OTSDataType
             return parts;
         }
 
-        public  List <COTSParticleClr> GetRightBorderedParticles()
+        public List<COTSParticleClr> GetRightBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             foreach (var p in m_listAnalysisParticles)
@@ -758,22 +789,22 @@ namespace OTSDataType
         }
 
         // is empty
-       public  bool IsEmpty()
+        public bool IsEmpty()
         {
-            return m_listAllParticles.Count == 0; 
+            return m_listAllParticles.Count == 0;
         }
-        void Duplicate( COTSField a_oSource)
-	    {
-	
+        void Duplicate(COTSField a_oSource)
+        {
+
             m_nID = a_oSource.m_nID;
-		    m_otsPos =  a_oSource.m_otsPos;
-		
+            m_otsPos = a_oSource.m_otsPos;
+
 
-		    // copy data over
-		    foreach(var pParticle in a_oSource.m_listAllParticles)
-		    {			
-                    m_listAllParticles.Add(pParticle);
-		    }
+            // copy data over
+            foreach (var pParticle in a_oSource.m_listAllParticles)
+            {
+                m_listAllParticles.Add(pParticle);
+            }
         }
 
         public override void Serialize(bool isStoring, XmlDocument classDoc, XmlNode rootNode)
@@ -781,12 +812,12 @@ namespace OTSDataType
             xPoint xPos = new xPoint();
             Slo slo = new Slo();
             slo.Register("OTSPosition", xPos);
-      
+
 
             if (isStoring)
             {
-              
-                xPos.AssignValue(new System.Drawing.Point((int)m_otsPos.X,(int)m_otsPos.Y));
+
+                xPos.AssignValue(new System.Drawing.Point((int)m_otsPos.X, (int)m_otsPos.Y));
                 slo.Serialize(true, classDoc, rootNode);
             }
             else
@@ -797,8 +828,8 @@ namespace OTSDataType
         }
     }
 
-  
-    
+
+
 
 
 }

+ 2 - 2
OTSIncAMeasureApp/0-OTSModel/OTSDataType/COTSSample.cd

@@ -6,7 +6,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>ACAIgEIiY0AAgCAAgEiCAggAACIEBAABCIAHYEAATIg=</HashCode>
+      <HashCode>ACAIgEIiY0AAgCgAoEiCAggAACIEBAABCIAHYEAATIg=</HashCode>
       <FileName>0-OTSModel\OTSDataType\COTSSample.cs</FileName>
     </TypeIdentifier>
     <ShowAsAssociation>
@@ -50,7 +50,7 @@
   <Class Name="OTSDataType.COTSField" Collapsed="true">
     <Position X="6" Y="6.25" Width="3.5" />
     <TypeIdentifier>
-      <HashCode>MQBCAgEiEFGhLAkgAiGACADZcToQIhKDQEICDAoQUIQ=</HashCode>
+      <HashCode>cSFAAgECEEGhLAkgAiCACADYcToQIgIAQEJCDAIQQIQ=</HashCode>
       <FileName>0-OTSModel\OTSDataType\COTSField.cs</FileName>
     </TypeIdentifier>
   </Class>