Bläddra i källkod

add missing files

gsp 1 månad sedan
förälder
incheckning
1a15b9a172

+ 1 - 9
OTSCommon/Language.cs

@@ -74,15 +74,7 @@ namespace OTSCommon
                 for (int i = 0; i < fieldInfo.Length; i++)
                 {
                    
-                    //if (fieldInfo[i].FieldType.Name == "ContextMenuStrip")
-                    //{
-                    //    ContextMenuStrip contextMenuStrip = (ContextMenuStrip)fieldInfo[i].GetValue(form);
-                    //    for (int j = 0; j < contextMenuStrip.Items.Count; j++)
-                    //    {
-                    //        if (table.Contains(contextMenuStrip.Items[j].Name.ToLower()))
-                    //            contextMenuStrip.Items[j].Text = (string)table[contextMenuStrip.Items[j].Name.ToLower()];
-                    //    }
-                    //}
+                    
                     if(fieldInfo[i].FieldType.Name == "ToolStripMenuItem")
                     {
                         ToolStripMenuItem toolStripMenuItem=(ToolStripMenuItem)fieldInfo[i].GetValue(form);

+ 403 - 0
OTSIncAMeasureApp/1-OTSMeasure/Measure/3-MeasureFlow/CBrightnessContrastAdjust.cs

@@ -0,0 +1,403 @@
+
+using OTSCLRINTERFACE;
+using OTSCommon.DBOperate.Model;
+using OTSDataType;
+using OTSMeasureApp._0_OTSModel.OTSDataType;
+using OTSModelSharp;
+using OTSModelSharp.ServiceCenter;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using static OTSDataType.otsdataconst;
+
+namespace OTSMeasureApp._1_OTSMeasure.Measure._3_MeasureFlow
+{
+    internal class CBrightnessContrastAdjust
+    {
+       
+        protected static NLog.Logger log;
+
+    
+        protected CMeasure m_pMsrThread;
+
+         double curbrightness = 0, curcontrast = 0;
+
+        protected ISemController m_SemHardwareMgr;
+        protected IScanController m_ScanHardwareMgr;
+        CBrightnessContrastRegulateParam m_BrightnessContrastRegulateParam = new CBrightnessContrastRegulateParam();
+        int imgwidth = 0;
+        int imgheight = 0;
+        internal CBrightnessContrastRegulateParam BrightnessContrastRegulationParam { get => m_BrightnessContrastRegulateParam; set => m_BrightnessContrastRegulateParam = value; }
+        private DateTime periodStart = DateTime.Now;
+        public void SetPeriodStart(DateTime a_periodStart)
+        {
+            periodStart = a_periodStart;
+        }
+        public DateTime GetPeriodStart()
+        {
+            return periodStart;
+        }
+        public bool checkPeriodTime()
+        {
+            if(!m_BrightnessContrastRegulateParam.toRun)
+            {
+                return false;
+            }
+            if (m_BrightnessContrastRegulateParam.autoRegulateType == AutoRegulateType.EveryPeriod)
+            {
+                if ((DateTime.Now - periodStart).TotalMinutes > m_BrightnessContrastRegulateParam.period)
+                {
+                    periodStart = DateTime.Now;
+                    return true;
+                }
+            }
+            else if (m_BrightnessContrastRegulateParam.autoRegulateType == AutoRegulateType.EverySample)
+            {
+                return false;
+            }
+            return false;
+        }
+        public bool CheckIsSampleAutoRegulate()
+        {
+            if (!m_BrightnessContrastRegulateParam.toRun)
+            {
+                return false;
+            }
+            if (m_BrightnessContrastRegulateParam.autoRegulateType == AutoRegulateType.EverySample)
+            {
+                return true;
+            }
+            else
+            { 
+            return false;   
+            }
+        }
+        public CBrightnessContrastAdjust(CMeasure a_msrThread)
+        {
+            m_pMsrThread = a_msrThread;
+           
+            log = NLog.LogManager.GetCurrentClassLogger();
+
+             imgwidth = m_pMsrThread.m_pMeasureParam.GetDefaultParam().GetImageScanParam().GetImageResolutionSize().cx/2;
+             imgheight = m_pMsrThread.m_pMeasureParam.GetDefaultParam().GetImageScanParam().GetImageResolutionSize().cy/2;
+
+            m_BrightnessContrastRegulateParam = a_msrThread.m_pMeasureParam.GetDefaultParam().BrightnessContrastRegulationParam;
+
+            m_SemHardwareMgr = SemController.GetSEMController();
+            m_ScanHardwareMgr = ScanController.GetScanController();
+
+
+
+        }
+        private class SEMStateObject
+        {
+            private PointF pos;
+            private double workingDistance;
+          
+            private double magnification;
+            public PointF Pos { get => pos; set => pos = value; }
+            public double WorkingDistance { get => workingDistance; set => workingDistance = value; }
+       
+            public double Magnification { get => magnification; set => magnification = value; }
+            public double brightness { get; set; } 
+            public double contrast { get; set; }
+            public Size ScanImagesize { get; set; }
+
+        }
+        private class AutoResetSEMControl : IDisposable
+        {
+            CBrightnessContrastAdjust sm;
+            private SEMStateObject semState = null;
+            public AutoResetSEMControl(CBrightnessContrastAdjust s)
+            {
+                sm = s;
+            }
+
+            public SEMStateObject SemState
+            {
+                get => semState;
+                set => semState = value;
+            }
+
+            public void Dispose()
+            {
+                if (semState != null)
+                {
+                   
+
+                    sm.m_SemHardwareMgr.SetMagnification(semState.Magnification);
+                    Thread.Sleep(100);
+                    sm.MoveSEMToPoint(semState.Pos);
+                    Thread.Sleep(100);
+                    sm.m_SemHardwareMgr.SetWorkingDistance(semState.WorkingDistance);
+
+                    sm.m_ScanHardwareMgr.SetImageSize(semState.ScanImagesize.Width,semState.ScanImagesize.Height);
+                }
+                log.Warn("Set SEM Exteral Off!");
+                sm.m_SemHardwareMgr.SetScanExternal(false);
+            }
+        }
+
+       
+       public bool MoveSEMToPoint(System.Drawing.PointF a_poi)
+        {
+            // get SEM controller 
+            var pSEMController = m_SemHardwareMgr;
+
+
+
+            PointF a_SEMpt = new Point();
+
+            CSEMStageData a_pCSEMStageData = m_pMsrThread.m_pMeasureParam.GetDefaultParam().GetStageDataParam();
+            int hardWareDelay = a_pCSEMStageData.GetHardWareDelay();
+
+
+            if (!a_pCSEMStageData.ConvertOTSToSEMCoord(a_poi, ref a_SEMpt))
+            {
+                return false;
+            }
+
+            //log.Info("Begin to move SEM stage to OTScoord:" + a_poi.X + "," + a_poi.Y);
+
+            log.Info("Begin to move SEM stage to " + a_SEMpt.X + "," + a_SEMpt.Y);
+
+            // move SEM to the position (rotation 0)
+            if (!pSEMController.MoveSEMToPoint(a_SEMpt.X, a_SEMpt.Y))
+            {
+                log.Error("MoveSEMToPoint: failed to call MoveSEMToPoint method.");
+                return false;
+            }
+
+            if (hardWareDelay > 0)
+            {
+                Thread.Sleep(hardWareDelay);
+            }
+
+            return true;
+        }
+        public void DoBrightnessContrastAdjust()
+        {
+            using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this))
+            {
+                log.Warn("begin to do auto brightness and contrast adjust.");
+                //----------memorize the state of sem
+                var semstate = new SEMStateObject();
+
+                double dMagnification = 0;
+                    m_SemHardwareMgr.GetMagnification(ref dMagnification);
+                double wd = 0;
+                m_SemHardwareMgr.GetWorkingDistance(ref wd);
+                ISemController sem = m_SemHardwareMgr;
+                double posX = 0, posY = 0, posR = 0;
+                sem.GetSemPositionXY(ref posX, ref posY, ref posR);
+
+                CSEMStageData a_pCSEMStageData = m_pMsrThread.m_pMeasureParam.GetDefaultParam().GetStageDataParam();
+
+                Point pos = new Point((int)posX, (int)posY);
+                PointF otsPos = new Point(0, 0);
+
+                if (!a_pCSEMStageData.ConvertSEMToOTSCoord(pos, ref otsPos))
+                {
+                    return;
+                }
+                semstate.Pos = otsPos;
+                semstate.Magnification = dMagnification;
+                semstate.WorkingDistance = wd;
+                CSize size = m_pMsrThread.m_pMeasureParam.GetDefaultParam().GetImageScanParam().GetImageResolutionSize();
+                semstate.ScanImagesize =new Size(size.cx, size.cy );
+
+                autoReset.SemState =semstate;
+
+
+                //-------------------------------------
+                
+
+               
+
+                double dMag = m_BrightnessContrastRegulateParam.mag;
+                // get SEM controller to set magnification and working distance
+                if (!m_SemHardwareMgr.SetMagnification(dMag))
+                {
+                    log.Error("fail to set magnification.");
+
+                }
+                InitAcquireBSEParam();
+                // move sem to std position
+                if (!MoveSEMToPoint(m_BrightnessContrastRegulateParam.stdMaterialOTSPos))
+                {
+                    log.Error(" failed to move SEM to the field centre point.");
+                  
+                    return;
+                }
+           
+                m_SemHardwareMgr.SetSemContrast(m_BrightnessContrastRegulateParam.initialContrast);
+                m_SemHardwareMgr.SetSemBrightness(m_BrightnessContrastRegulateParam.initialBrightness);
+                CBSEImgClr pBSEIamge = m_ScanHardwareMgr.AcquireBSEImage();
+                if (pBSEIamge == null)
+                {
+
+                    log.Error("failed to acquire a BSE image.");
+
+                    return;
+                }
+                int bright = 0, dark = 0;
+                ProcessBSEImageToGetTheTwoGrayValue(pBSEIamge, ref bright, ref dark);
+                var starttime = DateTime.Now;
+
+                var desiredark = m_BrightnessContrastRegulateParam.darkphaseGrayvalue;
+                var desirebright = m_BrightnessContrastRegulateParam.brightphaseGrayvalue;
+                
+                SortedDictionary<double, SEMStateObject> BCstatedic =new SortedDictionary<double, SEMStateObject>();
+
+                while (Math.Abs( dark-desiredark)>3 || Math.Abs(bright-desirebright)>3)
+                {
+                   
+                    if (m_pMsrThread.IsMeasureStopped())
+                    {// measure stopped
+                        log.Trace("measure thread is stopped.");
+                        
+                        return;
+                    }
+                    double curbrightness = 0, curcontrast = 0; 
+                   
+                  
+
+                    var error1 = desirebright - bright;
+                    var error2 = desiredark - dark;
+                    var varerror = Math.Pow(error1, 2) + Math.Pow(error2, 2);
+                    SEMStateObject BcsemState = new SEMStateObject();
+                    m_SemHardwareMgr.GetSemBrightness(ref curbrightness);
+                    m_SemHardwareMgr.GetSemContrast(ref curcontrast);
+                    BcsemState.brightness = curbrightness;
+                    BcsemState.contrast = curcontrast;  
+                    if(!BCstatedic.ContainsKey(varerror))
+                    {
+                        BCstatedic.Add(varerror, BcsemState);                       
+                    }   
+                    if((DateTime.Now-starttime).TotalSeconds>20)
+                    {
+                        log.Warn("Auto BC time out, stop the auto BC!");
+
+                        if (BCstatedic.Count > 0)
+                        {
+                            var minerror = BCstatedic.Keys.Min();
+                            var minstate = BCstatedic[minerror];
+                            m_SemHardwareMgr.SetSemBrightness(minstate.brightness);
+                            m_SemHardwareMgr.SetSemContrast(minstate.contrast);
+                            log.Warn("Auto BC set brightness and contrast to:" + minstate.brightness + " " + minstate.contrast);
+                        }   
+                        break;
+                    }
+                    RegulateBrightnessAndContrast(bright, desirebright, dark, desiredark,curbrightness,curcontrast);
+
+                    log.Info("two gray:" + bright.ToString() +" "+ dark.ToString());
+                    Thread.Sleep(500);
+
+                    // take BSE image for the fields
+                     pBSEIamge = m_ScanHardwareMgr.AcquireBSEImage();
+
+                    if (pBSEIamge == null)
+                    {
+                        log.Error(" failed to acquire a BSE image.");
+                        return;
+                    }
+                    ProcessBSEImageToGetTheTwoGrayValue(pBSEIamge, ref bright, ref dark);
+
+                }
+                m_SemHardwareMgr.GetSemContrast(ref m_BrightnessContrastRegulateParam.initialContrast);
+                m_SemHardwareMgr.GetSemBrightness(ref m_BrightnessContrastRegulateParam.initialBrightness);
+                log.Warn("Auto BC done!");
+
+
+            }
+        }
+
+        private void ProcessBSEImageToGetTheTwoGrayValue(CBSEImgClr pBSEIamge, ref int bright, ref int dark)
+        {
+            CImageHandler imageHandler = new CImageHandler();
+            imageHandler.CalculateBrightnessDarkGrayByOtsu(pBSEIamge, ref bright, ref dark);
+        }
+        public void GetCurrentTwoProminentGray(ref int dark, ref int bright)
+        {
+            InitAcquireBSEParam();
+           var pBSEIamge = m_ScanHardwareMgr.AcquireBSEImage();
+            CImageHandler imageHandler = new CImageHandler();
+            imageHandler.CalculateBrightnessDarkGrayByOtsu(pBSEIamge, ref bright, ref dark);
+
+        }
+        public void GetCurrentBrightnessAndContrast(ref double bright, ref double contrast)
+        {
+
+            m_SemHardwareMgr.GetSemBrightness(ref bright);
+            m_SemHardwareMgr.GetSemContrast(ref contrast);
+        }
+        public void WriteBrightnessAndContrast(ref double bright, ref double contrast)
+        {
+
+            m_SemHardwareMgr.SetSemContrast(contrast);
+            m_SemHardwareMgr.SetSemBrightness(bright);
+        }
+        void RegulateBrightnessAndContrast(double bri, double desirebri, double dark, double desiredark,double curbrightness,double curcontrast)
+        {
+           
+          
+            var amplifierScope =6;//the scope that sem brightness and contrast can be adjusted
+
+            var error1 = desirebri - bri;
+            var error2 = desiredark - dark;
+          
+            var error = error1 + error2;
+            double brightness = curbrightness + (error/255)* amplifierScope;
+            if (bri - dark > 10)
+            {
+                double expectcontrast = (desirebri - desiredark) / desirebri;
+                double currentcontrast = (bri - dark) / bri;
+                double gain= (expectcontrast-currentcontrast)/expectcontrast* amplifierScope;
+                double contrast = curcontrast +gain;
+                m_SemHardwareMgr.SetSemContrast(contrast);
+
+            }
+                
+            
+            m_SemHardwareMgr.SetSemBrightness(brightness);
+        }
+
+        bool InitAcquireBSEParam()
+        {
+
+            // get scan controller
+            var pScanController = m_ScanHardwareMgr;
+
+
+            if (!pScanController.Init())
+            {
+                log.Error(" failed to get scan control.");
+
+                return false;
+            }
+
+            // set dwell time
+            if (!pScanController.SetDwellTime(DwellTimeLevel.Low))
+            {
+                //log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);
+                return false;
+            }
+
+            // set image size
+            if (!pScanController.SetImageSize(imgwidth, imgheight))
+            {
+                // failed to set dwell time
+                log.Error(" failed to set ImageSize");
+                return false;
+            }
+
+            return true;
+        }
+    }
+}
+

+ 382 - 0
OTSIncAMeasureApp/1-OTSMeasure/Measure/3-MeasureFlow/CSmplPreviewMeasure.cs

@@ -0,0 +1,382 @@
+
+using OTSCLRINTERFACE;
+using OTSDataType;
+using OTSModelSharp;
+using OTSModelSharp.ServiceCenter;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using static OTSDataType.otsdataconst;
+using CHoleBSEImgsList = System.Collections.Generic.List<OTSDataType.CHoleBSEImg>;
+namespace OTSMeasureApp._1_OTSMeasure.Measure._3_MeasureFlow
+{
+    internal class CSmplPreviewMeasure
+    {
+        protected static NLog.Logger log;
+      
+        protected COTSSample m_HolePreviewSample;
+        protected CMeasure m_pMsrThread;
+     
+        CHoleBSEImgsList m_listHoleBSEImg;
+
+        protected ISemController m_SemHardwareMgr;
+        protected IScanController m_ScanHardwareMgr;
+       
+
+      
+
+      
+
+     
+        public CSmplPreviewMeasure(CMeasure a_msrThread, COTSSample a_pSample)
+        {
+            m_pMsrThread = a_msrThread;
+            m_HolePreviewSample = a_pSample;
+            log = NLog.LogManager.GetCurrentClassLogger();
+          
+            var imgwidth = m_HolePreviewSample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cx;
+            var imgheight = m_HolePreviewSample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cy;
+
+          
+           
+            m_SemHardwareMgr = SemController.GetSEMController();
+            m_ScanHardwareMgr = ScanController.GetScanController();
+          
+          
+         
+            m_listHoleBSEImg = new CHoleBSEImgsList();
+           
+         
+
+
+        }
+        private class SEMStateObject
+        {
+            private PointF pos;
+            private double workingDistance;
+          
+         
+            private double magnification;
+            public PointF Pos { get => pos; set => pos = value; }
+            public double WorkingDistance { get => workingDistance; set => workingDistance = value; }
+         
+            public double Magnification { get => magnification; set => magnification = value; }
+
+        }
+        private class AutoResetSEMControl : IDisposable
+        {
+            CSmplPreviewMeasure sem;
+            private SEMStateObject semState = null;
+            public AutoResetSEMControl(SEMStateObject s, CSmplPreviewMeasure a_sem)
+            {
+                semState = s;
+                sem=a_sem;
+            }
+
+            public SEMStateObject SemState
+            {
+                get => semState;
+                set => semState = value;
+            }
+
+            public void Dispose()
+            {
+                if (semState != null)
+                {
+                  
+
+                    sem.m_SemHardwareMgr.SetMagnification(semState.Magnification);
+                    Thread.Sleep(100);
+                    sem.MoveSEMToPoint(semState.Pos);
+                    Thread.Sleep(100);
+                    sem.m_SemHardwareMgr.SetWorkingDistance(semState.WorkingDistance);
+
+
+                }
+                log.Warn("Set SEM Exteral Off!");
+                sem.m_SemHardwareMgr.SetScanExternal(false);
+            }
+        }
+       
+      
+        bool MoveSEMToPoint(System.Drawing.PointF a_poi)
+        {
+            // get SEM controller 
+            var pSEMController = m_SemHardwareMgr;
+
+
+
+            PointF a_SEMpt = new Point();
+
+            CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
+            int hardWareDelay = a_pCSEMStageData.GetHardWareDelay();
+
+
+            if (!a_pCSEMStageData.ConvertOTSToSEMCoord(a_poi, ref a_SEMpt))
+            {
+                return false;
+            }
+
+            log.Info("Begin to move SEM stage to OTScoord:" + a_poi.X + "," + a_poi.Y);
+
+            log.Info("Begin to move SEM stage to " + a_SEMpt.X + "," + a_SEMpt.Y);
+
+            // move SEM to the position (rotation 0)
+            if (!pSEMController.MoveSEMToPoint(a_SEMpt.X, a_SEMpt.Y))
+            {
+                log.Error("MoveSEMToPoint: failed to call MoveSEMToPoint method.");
+                return false;
+            }
+ 
+            if (hardWareDelay > 0)
+            {
+                Thread.Sleep(hardWareDelay);
+            }
+
+            return true;
+        }
+        public void DoHolePreview()
+        {
+            SEMStateObject originalStateObj= new SEMStateObject();
+
+            //----------memorize the state of sem
+            double posX = 0, posY = 0, posR = 0;
+            m_SemHardwareMgr.GetSemPositionXY(ref posX, ref posY, ref posR);
+            Point pos = new Point((int)posX, (int)posY);
+            PointF otsPos = new Point(0, 0);
+            CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();
+            if (!a_pCSEMStageData.ConvertSEMToOTSCoord(pos, ref otsPos))
+            {
+                return;
+            }
+            originalStateObj.Pos = otsPos;
+            double originalWd = 0;
+            double originalMag = 0;
+            m_SemHardwareMgr.GetWorkingDistance(ref originalWd);
+            m_SemHardwareMgr.GetMagnification(ref originalMag );
+            originalStateObj.WorkingDistance = originalWd;
+            originalMag = Math.Max(originalMag, 1.0); // ensure magnification is not zero
+
+            using (AutoResetSEMControl autoReset = new AutoResetSEMControl(originalStateObj,this))
+            {
+              
+                // let the main thread to know that this sample measurement starts
+                CMsrSampleStatus pStatus = m_HolePreviewSample.GetMsrStatus();
+                pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
+
+                // set current time to current time
+                pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);
+
+                var pSEMCtrl = m_pMsrThread.GetSEMController();
+                var pSEMDataMsr = m_HolePreviewSample.GetSEMDataMsr();
+
+                double dMinMag = pSEMDataMsr.GetMagnification();
+                // get SEM controller to set magnification and working distance
+                if (!pSEMCtrl.SetMagnification(dMinMag))
+                {
+                    log.Error("DoHolePreview: fail to set magnification.");
+                   
+                }
+
+
+               
+
+
+
+
+                // calculate field centers
+                List<System.Drawing.Point> listFieldCenter;
+                List<System.Drawing.Point> alllistFieldCenter;
+
+                if (!CalculateUnMeasuredHoleImgCenters(m_HolePreviewSample, out alllistFieldCenter, out listFieldCenter))
+                {// failed to calculate field centers
+                    log.Error("DoHolePreview: failed to calculate field centers.");
+                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
+                    // record end time
+                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+                    return;
+                }
+
+                // go through each field
+             
+                for (int i = 0; i < listFieldCenter.Count; ++i)
+                {// check and break if stop button is clicked
+                    if (m_pMsrThread.IsMeasureStopped())
+                    {// measure stopped
+                        log.Trace("DoHolePreview: measure thread is stopped.");
+                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);
+                        // record end time
+                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+                        return;
+                    }
+
+                    // check if sample measurement completes
+                    COTSImgScanPrm pScanParam = m_HolePreviewSample.GetMsrParams().GetImageScanParam();
+                    int nTotalFieldSize = listFieldCenter.Count;
+
+
+
+                    // get a field center 
+                    System.Drawing.Point poiFieldCentre = listFieldCenter[i];
+
+
+
+
+                    // move SEM to the field center
+                    if (!MoveSEMToPoint(poiFieldCentre))
+                    {// failed to move SEM to the position
+                        log.Error("DoHolePreview: failed to move SEM to the field centre point.");
+                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
+                        // record end time
+                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+
+                        return;
+                    }
+                    // set the BSE scan param
+                    if (!InitHoleBSEParam(m_HolePreviewSample))
+                    {
+                        log.Error("DoHolePreview: fail to set BSE param.");
+
+                    }
+                    // take BSE image for the fields
+                    CBSEImgClr pBSEIamge = m_ScanHardwareMgr.AcquireBSEImage();
+                 
+                    if (pBSEIamge == null)
+                    {
+                        // failed to acquire a BSE image
+                        log.Error("DoHolePreview: failed to acquire a BSE image.");
+                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
+                        // record end time
+                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+
+                        return;
+                    }
+
+
+                    //BSEData
+                    ST_MSTMsg MsgFieldBSE = new ST_MSTMsg(m_HolePreviewSample);
+
+                    MsgFieldBSE.InitHolePreBSEDataMsg(pBSEIamge, poiFieldCentre);
+
+
+
+                    m_pMsrThread.SendHolePreviewMessageToMeasureGUI(MsgFieldBSE);
+
+                    if (pStatus.GetStatus() != OTS_MSR_SAMPLE_STATUS.INPROCESS)
+                    {
+                        // measurement failed or stopped
+                        log.Error("DoHolePreview: measurement failed or stopped.");
+                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);
+                        // record end time
+                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+
+                        return;
+                    }
+
+                    //save the result to project file
+                    Rectangle oImageRect = (Rectangle)pBSEIamge.GetImageRect();
+                    CHoleBSEImg pHoleBSEImg = new CHoleBSEImg(oImageRect, poiFieldCentre);
+
+                    pHoleBSEImg.SetImageData(pBSEIamge.GetImageDataPtr(), oImageRect.Width, oImageRect.Height);
+
+                    m_listHoleBSEImg.Add(pHoleBSEImg);
+
+                }
+
+                pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);
+                //calculate measure time
+                pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);
+
+                // let main thread to know that this sample measurement completes
+                ST_MSTMsg MsgSmplEnd = new ST_MSTMsg(m_HolePreviewSample);
+
+                MsgSmplEnd.InitHolePreSampleEndMsg();
+
+
+                m_pMsrThread.SendHolePreviewMessageToMeasureGUI(MsgSmplEnd);
+
+            }
+        }
+        bool CalculateUnMeasuredHoleImgCenters(COTSSample sample, out List<System.Drawing.Point> a_allpieldcenter, out List<System.Drawing.Point> a_listUnMsrFieldCenter)
+        {
+
+            // sample measure parameters
+            CSampleParam pMsrParam = sample.GetMsrParams();
+            COTSImgScanPrm poImageScanParam = pMsrParam.GetImageScanParam();
+            COTSImageProcParam pImgProcParam = pMsrParam.GetImageProcessParam();
+            CSEMFieldData poSEMDataMsr = sample.GetSEMDataMsr();
+            CMsrSampleStatus pStatus = sample.GetMsrStatus();
+
+
+            // measured field centers list
+            List<System.Drawing.PointF> listCompletedCenter = pStatus.GetCompletedFieldsCenter();
+
+            // field centers list manager
+            CFieldPositionHelper pFieldMgr = new CFieldPositionHelper();
+
+            // init field centers list manager
+            if (!pFieldMgr.Init(sample.GetMsrDomain(), poImageScanParam, 0, poSEMDataMsr, listCompletedCenter))
+            {
+                log.Error("CalculateFieldsCenters: failed to init field centres list manager.");
+                a_listUnMsrFieldCenter = new List<System.Drawing.Point>();
+                a_allpieldcenter = new List<Point>();
+                return false;
+            }
+
+            // get field centers list
+            a_listUnMsrFieldCenter = pFieldMgr.GetUnmeasuredFieldCentrePoints();// GetFieldCentrePoints();
+
+            a_allpieldcenter = pFieldMgr.GetFieldCentrePoints();
+
+            // ok, return TRUE
+            return true;
+
+        }
+        bool InitHoleBSEParam(COTSSample sample)
+        {
+
+            // get scan controller
+            var pScanController = m_ScanHardwareMgr;
+
+
+            // scan parameters
+            var pMsrParam = sample.GetMsrParams();
+            var pImgScanParam = pMsrParam.GetImageScanParam();
+
+            // get image size
+            var nImageSizeId = pImgScanParam.GetImageResulotion();
+            int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;
+            Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];
+
+
+
+            if (!pScanController.Init())
+            {
+                log.Error("SetBSEParam: failed to get scan control.");
+
+                return false;
+            }
+
+            // set dwell time
+            if (!pScanController.SetDwellTime(DwellTimeLevel.Low))
+            {
+               
+                return false;
+            }
+
+            // set image size
+            if (!pScanController.SetImageSize(sizePixelImage.Width / 2, sizePixelImage.Height / 2))
+            {
+                // failed to set dwell time
+                log.Error("SetBSEParam: failed to set ImageSize");
+                return false;
+            }
+
+            return true;
+        }
+    }
+}