| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418 | using System;using System.Collections.Generic;using System.Linq;using OTSModelSharp.ServiceCenter;using static OTSDataType.otsdataconst;using OTSDataType;using System.Drawing;using System.Threading;using OTSCLRINTERFACE;using OTSMeasureApp._0_OTSModel.OTSDataType;using System.Windows.Forms;using System.Data;using System.IO;using OTSMeasureApp._1_OTSMeasure.Measure._3_MeasureFlow;namespace OTSModelSharp{    using CHoleBSEImgsList = List<CHoleBSEImg>;      public  class CSmplMeasure {        protected static NLog.Logger log ;        protected bool bSaveThreadWorking;        protected System.Threading.Thread m_thread_ptr;           protected COTSSample m_Sample;        protected COTSSample m_HolePreviewSample;        protected CMeasure m_pMsrThread;        string m_strWorkingFolder;       protected CSmplMsrResult m_pSampleRstFile;        CHoleBSEImgsList m_listHoleBSEImg;                protected ISemController m_SemHardwareMgr;        protected IScanController m_ScanHardwareMgr;        protected IEDSController m_EDSController;              protected Queue<COTSField> fieldQueue=new Queue<COTSField>();              protected IClassifyEngine m_classifyEngine;        private bool m_ifAquireClearParticleImage=false;        public CSmplMeasure( string a_strWorkingFolder, COTSSample a_pSample)        {            m_Sample = a_pSample;            log = NLog.LogManager.GetCurrentClassLogger();            var expC = m_Sample.GetMsrParams().GetXRayParam().GetAnalyExpCount();            var imgwidth = m_Sample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cx;            var imgheight = m_Sample.GetMsrParams().GetImageScanParam().GetImageResolutionSize().cy;                      m_strWorkingFolder = a_strWorkingFolder;            m_pSampleRstFile = new CSmplMsrResult( a_strWorkingFolder,  a_pSample);            m_SemHardwareMgr = SemController.GetSEMController();            m_ScanHardwareMgr = ScanController.GetScanController();            var ifautoid = m_Sample.GetMsrParams().GetXRayParam().IfAutoId;            var knownelements = m_Sample.GetMsrParams().GetXRayParam().AnalysisElements;            m_EDSController = EDSController.GetEDSController(imgwidth,imgheight,expC,ifautoid,knownelements);            m_listHoleBSEImg = new CHoleBSEImgsList();            m_Sample = a_pSample;            m_ifAquireClearParticleImage = FileHelper.GetIfAquireClearParticleImage();        }       public void SetSample(COTSSample a_pSample)        {                        m_Sample = a_pSample;            m_pSampleRstFile.SetSample(a_pSample);        }        public COTSSample GetSample() { return m_Sample; }        public void SetHolePreviewSample(COTSSample a_pSample)        {            m_HolePreviewSample = a_pSample;                   }        public COTSSample GetHolePreviewSample() { return m_HolePreviewSample; }        public void SetMsrThread(CMeasure mt)        {            m_pMsrThread = mt;                              }        bool SetSEMDataMrs(COTSSample sample)        {            var pSEMDataMsr = sample.GetSEMDataMsr();                      double dMag = pSEMDataMsr.GetMagnification();            double dWorkDis = pSEMDataMsr.GetWorkingDistance();            double bri=pSEMDataMsr.Brightness;            double contra = pSEMDataMsr.Contrast;            try            {                var pSEMCtrl = m_pMsrThread.GetSEMController();                pSEMCtrl.SetMagnification(dMag);                pSEMCtrl.SetWorkingDistance(dWorkDis);                //pSEMCtrl.SetSemBrightness(bri);                //pSEMCtrl.SetSemContrast(contra);                log.Warn("set magnification " + dMag);                log.Warn("set wd "+ dWorkDis);                //log.Warn("set brightness "+bri);                //log.Warn("set contrast "+contra);            }            catch (Exception e)             {             log.Error(e.Message);                        }                        return true;        }              // set SEM external off        bool SetSEMExteralOff()        {            var pSEMCtrlPtr = m_SemHardwareMgr;                       log.Warn("Set SEM Exteral Off!");            pSEMCtrlPtr.SetScanExternal(false);            return true;        }        bool SetBSEParam()        {                       // get scan controller            var pScanController = m_ScanHardwareMgr;            // scan parameters            var pMsrParam = m_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];            // get dwell time             OTS_IMAGE_SCANSPEED_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();            // convert dwell time to bruker dwell time             DwellTimeLevel DwellTimeId;            switch (nDwellTime)            {                case OTS_IMAGE_SCANSPEED_OPTIONS.low:                    DwellTimeId = DwellTimeLevel.Low;                    break;                case OTS_IMAGE_SCANSPEED_OPTIONS.meddium:                    DwellTimeId = DwellTimeLevel.Medium;                    break;                case OTS_IMAGE_SCANSPEED_OPTIONS.high:                    DwellTimeId = DwellTimeLevel.High;                    break;                default:                    DwellTimeId = DwellTimeLevel.Low;                    break;            }                      if (!pScanController.Init())            {                log.Error("SetBSEParam: failed to get scan control.");                               return false;            }                       // set dwell time            if (!pScanController.SetDwellTime(DwellTimeId))            {                //log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);                return false;            }            // set image size            if (!pScanController.SetImageSize(sizePixelImage.Width,sizePixelImage.Height))            {                // failed to set dwell time                log.Error("SetBSEParam: failed to set dwell time (%d).", sizePixelImage.Height);                return false;            }            return true;        }        bool SetHoleBSEParam(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))            {                //log.Error("SetBSEParam: failed to set dwell time (%d) for bruker system.", nBrukerDwellTime);                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;        }                public  void SetWorkingFolder(String a_strWorkingFolder)        {            // add "\\" at the string end if it is not "\\"            if (a_strWorkingFolder.PadRight(1)!="\\")            {                a_strWorkingFolder += "\\";            }            m_strWorkingFolder = a_strWorkingFolder + m_Sample.GetName() + "\\";        }        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();            CSEMDataMsr 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;        }        protected bool IsAborted()        {                       return m_pMsrThread.IsMeasureStopped();        }        protected bool IsPaused()        {                        var statu = m_pMsrThread.GetMsrThreadStatus();            if (statu.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)            {                return true;            }            else             {                return false;            }                    }        bool IsSampleOver(COTSImgScanPrm  a_pScanParam)        {                      string sStopMode = a_pScanParam.GetStopMode();            int nStopField = a_pScanParam.GetStopParamFields();            // completed fields number            CMsrSampleStatus pMsrSampleStatus = m_Sample.GetMsrStatus();            int nCompeltedField = pMsrSampleStatus.GetCompletedFields();            CMsrResultItems pMsrResults = m_Sample.GetMsrResults();            List<CMsrResultItem> listMsrResult = pMsrResults.GetResultItems();            int nNumParticle = 0;            foreach (var pResult in listMsrResult)            {                if (pResult.GetTypeId() > (int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED)//summarize the number of the identified particle in this condition                {                    nNumParticle += (int)pResult.GetNumber();                }            }            TimeSpan timeSpan = pMsrSampleStatus.GetUsedTime();            int nDay = timeSpan.Days;            int nHour = timeSpan.Hours;            int nMin = timeSpan.Minutes;            int nSec = timeSpan.Seconds;            int nUsedTime = nSec + nMin * 60 + nHour * 3600 + nDay * 86400;            int NMeasArea = (int)pMsrResults.GetMeasuredArea();            int nParticlAim = a_pScanParam.GetStopParamParticles();            int nMeasTimeAim = a_pScanParam.GetStopParamMeasTime();            int NMeasAreaAim = a_pScanParam.GetStopParamArea()*1000000 ;            bool bRet = false;            string[] str = sStopMode.Replace(" ", "").Split('+');            for(int i=0;i< str.Length;i++)            {                switch (int.Parse(str[i].Split(':')[0])-1)                {                    case (int)OTS_MEASURE_STOP_MODE.CoverMode:                        // completed fields number                        if (nCompeltedField == m_Sample.GetFieldsData().Count)                        {                            bRet = true;                        }                        break;                    case (int)OTS_MEASURE_STOP_MODE.FieldMode:                        if (nCompeltedField >= nStopField)                        {                            bRet = true;                        }                        break;                    case (int)OTS_MEASURE_STOP_MODE.ParticleMode:                        if (nNumParticle >= nParticlAim)                        {                            bRet = true;                        }                        break;                    case (int)OTS_MEASURE_STOP_MODE.TimeMode:                        if (nUsedTime >= nMeasTimeAim)                        {                            bRet = true;                        }                        break;                    case (int)OTS_MEASURE_STOP_MODE.AreaMode:                        if (NMeasArea >= NMeasAreaAim)                        {                            bRet = true;                        }                        break;                    default:                        break;                }            }            return bRet;        }        // move SEM to the point        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;            }            CSampleParam pMsrParam = m_Sample.GetMsrParams();            if (pMsrParam.SlopParam.IsUsingSlopParam)            {                double wd = pMsrParam.SlopParam.GetWD(a_SEMpt);                double originWd = 0;                pSEMController.GetWorkingDistance(ref originWd);                if ((wd - originWd) > 2)                {                    log.Warn("Working Distance is invalid,outof the moving scope(2cm)  wd=" + wd.ToString("F2"));                }                else                 {                    Thread.Sleep(hardWareDelay);                    pSEMController.SetWorkingDistance(wd);                }                          }            if (hardWareDelay > 0)            {                Thread.Sleep(hardWareDelay);            }                       return true;        }        // Acquire a BSE image        CBSEImgClr AcquireABSEImage()        {            // BSE image            CBSEImgClr pBSEImage = null;            // get scan controller            var pScanController = m_ScanHardwareMgr;            pBSEImage = pScanController.AcquireBSEImage();                        return pBSEImage;        }        public bool IsLowCounts(COTSParticleClr particle)        {            COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();            if (pXRayParam.GetUsingXray() == true)            {                var thecount = particle.GetXray().GetTotalCount();                var expect = pXRayParam.GetAnalyExpCount();                if (thecount < expect)                {                    particle.SetType((int)OTS_PARTICLE_TYPE.LOW_COUNT);                    particle.SetClassifyId((int)OTS_PARTICLE_TYPE.LOW_COUNT);                    particle.SetTypeColor("#000000");                    particle.SetTypeName("LowCounts");                    return true;                }            }            return false;        }        public virtual void ClassifyFieldParticles(COTSField curFldData)        {            return;        }              private class SEMStateObject        {            private PointF pos;            private double workingDistance;            private CSEMDataGnr semdata;            private COTSSample originalSample;            private double magnification;            public PointF Pos { get => pos; set => pos = value; }            public double WorkingDistance { get => workingDistance; set => workingDistance = value; }            public CSEMDataGnr Semdata { get => semdata; set => semdata = value; }            public double Magnification { get => magnification; set => magnification = value; }            public COTSSample OriginalSample { get => originalSample; set => originalSample = value; }        }        private class AutoResetSEMControl:IDisposable        {            CSmplMeasure sm;            private SEMStateObject semState=null;            public AutoResetSEMControl(CSmplMeasure s)            {                sm = s;            }            public SEMStateObject SemState             {                 get => semState;                 set => semState = value;             }            public void Dispose()            {                if (semState != null)                {                    sm.SetBSEParam();                                       sm.m_SemHardwareMgr.SetMagnification(semState.Magnification);                    Thread.Sleep(100);                    sm.MoveSEMToPoint(semState.Pos);                    Thread.Sleep(100);                    sm.m_SemHardwareMgr.SetWorkingDistance(semState.WorkingDistance);                                   }                sm.SetSEMExteralOff();            }        }        private bool GetSEMDataGnrFromHw(ref CSEMDataGnr SemDataGnr)        {            double kv = 0, brightness = 0, contrast = 0;            var hw = SemController.GetSEMController();            hw.GetSemHighTension(ref kv);            hw.GetSemBrightness(ref brightness);            hw.GetSemContrast(ref contrast);            SemDataGnr.SetValue(kv, brightness, contrast);            return true;        }        public void DoMeasureForOneSample()        {            try            {                // let the main thread to know that this sample measurement starts                var pStatus = m_Sample.GetMsrStatus();                pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);                // set current time to current time                pStatus.ComputeTime(OTS_MSR_TIME_TYPE.START);                // let main App know that the sample begin to measure                ST_MSTMsg MsgSmpStart = new ST_MSTMsg(m_Sample);                MsgSmpStart.InitSampleStartMsg();                m_pMsrThread.SendMessageToMeasureGUI(MsgSmpStart);                log.Info(m_Sample.GetName() + " Measurement started!");                // get SEM controller to set magnification and working distance                if (!SetSEMDataMrs(m_Sample))                {                    log.Error("DoMeasure: fail to set SEM data.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                // set the BSE scan param                if (!SetBSEParam())                {                    log.Error("DoMeasure: fail to set BSE param.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                var pSEMDataGnr = new CSEMDataGnr();                log.Info("Get current Kv, Brightness and Contrast!");                GetSEMDataGnrFromHw(ref pSEMDataGnr);                m_pSampleRstFile.SetSEMDataGnr(pSEMDataGnr);                // record SEM data                COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();                CSEMStageData pSEMStageData = pProjMgrFile.GetSEMStageData();                m_pSampleRstFile.SetSEMStageData(pSEMStageData);                CStage pStage = pProjMgrFile.GetStage();                m_pSampleRstFile.SetSEMStage(pStage);                //-----save the static measure result file data into xml file and the dynamic data of every field will be saved into sqlite database                log.Info("Create result file!");                if (!m_pSampleRstFile.CreateResultFiles())                {// failed to call measure result file Save method                    log.Error("DoMeasure: failed to call measure result file Save method.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                //------                var FldDatas = m_Sample.GetFieldsData();                for (int i = 0; i < FldDatas.Count; ++i)                {// check and break if stop button is clicked                    try                    {                        var curFld = FldDatas[i];                        if (curFld.GetIsMeasureComplete())                        {                            continue;                        }                        if (curFld.Enable == false)                        {                            continue;                        }                        if (IsPaused())                        {// measure stopped			                            pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.PAUSED);                            // record end time                            pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                            //must wait for the saving data thread  finished,or we'll get null pointer exception when we stop the measure process.			                            while (fieldQueue.Count() > 0)                            {                                Thread.Sleep(100);                            }                            SetSEMExteralOff();                            // update thread measure status class, let the main thread know that this sample measurement stopped                            ST_MSTMsg MsgSmpStop = new ST_MSTMsg(m_Sample);                            MsgSmpStop.InitSamplePausedMsg();                            m_pMsrThread.SendMessageToMeasureGUI(MsgSmpStop);                            while (IsPaused())                            {                                Thread.Sleep(300);                            }                        }                        if (IsAborted())                        {// measure stopped			                            pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);                            // record end time                            pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                            //must wait for the saving data thread  finished,or we'll get null pointer exception when we stop the measure process.			                            while (fieldQueue.Count() > 0)                            {                                Thread.Sleep(100);                            }                            break;                        }                        // check if sample measurement completes                        COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();                        if (IsSampleOver(pScanParam))                        {                            pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);                            pStatus.ComputeTime(OTS_MSR_TIME_TYPE.COMPLT);                            break;                        }                        // get a field center                         System.Drawing.PointF poiFieldCentre = curFld.GetOTSPosition();                        // update thread measure status class, let the main thread know that starts a new field                        ST_MSTMsg MsgFieldStart = new ST_MSTMsg(m_Sample, curFld);                        MsgFieldStart.InitFieldStartMsg();                        m_pMsrThread.SendMessageToMeasureGUI(MsgFieldStart);                        int fldNo = curFld.GetId();                        log.Warn("Current field:" + fldNo.ToString());                        // move SEM to the field center                        if (!MoveSEMToPoint(poiFieldCentre))                        {// failed to move SEM to the position                            log.Error("DoMeasure: 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;                        }                        log.Info("Begin to Acquire BSE image!");                        // take BSE image for the fields                        CBSEImgClr pBSEImg = AcquireABSEImage();                        // let the main thread to know that image process is completed                        if (pBSEImg == null)                        {                            log.Error("ImageProcess: can't get BSE image.");                            pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                            return;                        }                        curFld.SetBSEImage(pBSEImg);                        //BSEData                        ST_MSTMsg MsgFieldBSE = new ST_MSTMsg(m_Sample, curFld);                        MsgFieldBSE.InitFieldBSEImageMsg();                        m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);                        log.Info("Acquire BSE image success! Processing image...");                        // image process                        FieldImageProcess(curFld);                        MsgFieldBSE.InitFieldBSEAnalysisPartsDataMsg();                        m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);                        if (m_ifAquireClearParticleImage)                        {                            var listAnalysisParts = curFld.GetListAnalysisParticles();                            foreach (var p in listAnalysisParts)                            {                                Rectangle r = (Rectangle)p.GetParticleRect();                                var img = m_ScanHardwareMgr.AcquireRectangleBSEImage(r);                                if (img != null)                                {                                    curFld.particleImages.Add(img);                                }                            }                        }                        COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();                        if (pXRayParam.GetUsingXray() == true)                        {                            foreach (var p in curFld.GetListAnalysisParticles())                            {                                p.SetIsXrayParticle(true);                            }                            try                            {                                CollectParticlesXrayData(curFld);                            }                            catch (Exception e)                            {                                log.Error(e.Message);                            }                        }                        m_Sample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);                        curFld.SetIsMeasureComplete(true);                        log.Info("Begin to classify particles! particle num:" + curFld.GetListAnalysisParticles().Count);                        try                        {                            ClassifyFieldParticles(curFld);                        }                        catch (Exception e)                        {                            log.Error(e.Message);                        }                        MsgFieldBSE.InitFieldSTDColoredPartsDataMsg();                        m_pMsrThread.SendMessageToMeasureGUI(MsgFieldBSE);                        //start db save                        StartSaveFileThread(ref curFld);                        // record                         pStatus.AddCompletedFieldCenter(curFld.GetOTSPosition());                                                                     pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                        SendFieldParticlesInfoToGUI(curFld, m_Sample.GetMsrStatus());                    }                    catch (Exception e)                    {                        log.Error(e.Message);                    }                }                while (bSaveThreadWorking)//wait untill all the field data has been saved.                {                    Thread.Sleep(1000);                    log.Warn("db saving!");                }                TheLastWorkOfSampleMeasure();            }            catch (Exception e)            {                log.Error(e.Message);            }            finally             {                SetSEMExteralOff();            }    }        public void TheLastWorkOfSampleMeasure()        {            COTSSample theSample = m_Sample;            var pStatus = theSample.GetMsrStatus();                       pStatus.ComputeTime(OTS_MSR_TIME_TYPE.COMPLT);            pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED);            // let main thread to know that this sample measurement completes            ST_MSTMsg MsgSmplEnd = new ST_MSTMsg(m_Sample);            MsgSmplEnd.InitSampleCompleteMsg();                      m_pMsrThread.SendMessageToMeasureGUI(MsgSmplEnd);            string userdB = m_Sample.GetMsrParams().GetSTDName();            if(userdB.ToLower() != "nostddb" && userdB.ToLower() != "nostddb.db")            {                try                {                    string userdBpath= System.Windows.Forms.Application.StartupPath + "\\Config\\SysData\\" + m_Sample.GetMsrParams().GetSTDName() + ".db";                    File.Copy(userdBpath, m_pSampleRstFile.GetFieldFileSubFolderStr().Remove(m_pSampleRstFile.GetFieldFileSubFolderStr().IndexOf("FIELD_FILES")) + m_Sample.GetMsrParams().GetSTDName() + ".db", true);                }                catch(Exception ex)                {                    MessageBox.Show("userdB copy failed:" + ex.ToString());                }            }        }        public bool DoMEasureForReMeasure()        {            return true;        }             public virtual void FieldImageProcess(COTSField curFldData)        {            PointF fldCenter = curFldData.GetOTSPosition();                                  CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();            PointF semPos = new Point();            a_pCSEMStageData.ConvertOTSToSEMCoord(fldCenter, ref semPos);            curFldData.SetSemPos(semPos);            //first step:remove background of the bse image and compound all the finded particles.            CSampleParam pMsrParam = m_Sample.GetMsrParams();            COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam();            log.Info("Begin to process image and get all particles!");            //according to the ECD scope,filter out the effective particles,remove the noise.            curFldData.GetOriginalParticles(m_Sample.GetMsrParams(), m_Sample.CalculatePixelSize());            if (curFldData.Sample.GetMsrParams().GetImageProcessParam().GetBGRemoveType() == OTS_BGREMOVE_TYPE.MATRIX)            {                curFldData.SetListAnalysisParticles(curFldData.GetAllParticles());            }            else             {                log.Info("Begin to filter particles!");                curFldData.FilterParticles(m_Sample.GetMsrParams().GetXRayParam());//filter according to the xraylimit and outermost border                log.Info("Begin to Calculate the image property of every particle!");                var analysisparts = curFldData.GetListAnalysisParticles();                curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc.                curFldData.SelectParticlesAccordingImgProp(pImgProcessParam);                var overlap = pImgProcessParam.GetOverlapParam();                if (overlap > 0)                {                    try                    {                        curFldData.RemoveDuplicateOverlapParticles(overlap);                    }                    catch (Exception e)                    {                        log.Error(e.Message);                    }                }            }                        curFldData.CalculateParticleAbsolutPos(m_pMsrThread.GetProjResultData().GetSEMStageData());                       curFldData.InitParticles(pImgProcessParam);                        return ;        }                                      public virtual void CollectParticlesXrayData(COTSField curFldData)        {                      var allParts = curFldData.GetListXrayParticles();                      var smallparts = new List<COTSParticleClr>();            var bigparts = new List<COTSParticleClr>();            double quantifyThreshold = m_Sample.GetMsrParams().GetXRayParam().GetFeatureModeMinSize();            foreach (var part in allParts)            {                double equalCircleDiameter = Math.Sqrt(part.GetActualArea() / 3.14159) * 2f;                if (equalCircleDiameter < quantifyThreshold)                {                    smallparts.Add(part);                }                else                {                    bigparts.Add(part);                }            }            log.Info("SmallQuantifyParts (<" + quantifyThreshold.ToString("f2") + "): " + smallparts.Count);            log.Info("BigQuantifyParts (>=" + quantifyThreshold.ToString("f2") + "): " + bigparts.Count);            curFldData.CreateXrayList(smallparts);            curFldData.CreateXrayList(bigparts);            // get x-ray parameters            COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();            var workmode = pXRayParam.GetScanMode();                       if (workmode == OTS_X_RAY_SCAN_MODE.PointMode)            {                uint nXRayAQTime;                if (bigparts.Count > 0)                {                    nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();                    log.Info("Begin to collect xraydata:" + bigparts.Count +"(" +nXRayAQTime.ToString()+") on " + workmode.ToString());                                        m_EDSController.GetXRayByParts(bigparts, nXRayAQTime, true);                }                if (smallparts.Count > 0)                {                    Thread.Sleep(1000);//add delay here,or else the eds system will halt.                    nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();                    log.Info("Begin to collect xraydata:" + smallparts.Count + "(" + nXRayAQTime.ToString() + ") on " + workmode.ToString());                                       m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);                }            }            else if (workmode == OTS_X_RAY_SCAN_MODE.FeatureMode)            {                              uint nXRayAQTime;                               if (bigparts.Count > 0)                {                        log.Info("Begin to collect xraydata:" + bigparts.Count + " on " + OTS_X_RAY_SCAN_MODE.FeatureMode.ToString());                        nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();                        m_EDSController.GetXRayByFeatures(bigparts, nXRayAQTime, true);                }                if (smallparts.Count > 0)                {                    Thread.Sleep(1000);                    log.Info("Begin to collect xraydata:" + smallparts.Count + " on " + OTS_X_RAY_SCAN_MODE.PointMode.ToString());                    nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();                    m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);                }            }            else if (workmode == OTS_X_RAY_SCAN_MODE.ExpandMode)            {                uint nXRayAQTime;                if (bigparts.Count > 0)                {                    log.Info("Begin to collect xraydata:" + bigparts.Count + " on " + OTS_X_RAY_SCAN_MODE.FeatureMode.ToString());                    nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime();                    m_EDSController.GetXRayByExpandFeatures(bigparts, nXRayAQTime, true);                }                if (smallparts.Count > 0)                {                    Thread.Sleep(500);                    log.Info("Begin to collect xraydata:" + smallparts.Count + " on " + OTS_X_RAY_SCAN_MODE.PointMode.ToString());                    nXRayAQTime = (uint)pXRayParam.GetSmallPartXrayTime();                    m_EDSController.GetXRayByParts(smallparts, nXRayAQTime, true);                }            }            return;        }        public virtual void QuantifyParticlesXrayData(COTSField curFldData)        {            var parts = curFldData.GetListXrayParticles();            foreach (var p in parts)            {                m_EDSController.QuantifyXrayByPart(p);            }                           }        public void DoHolePreview()        {            using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this))            {                //----------memorize the state of sem                var semstate = new SEMStateObject();                              double dMagnification = m_Sample.GetSEMDataMsr().GetMagnification();               double wd = m_Sample.GetSEMDataMsr().GetWorkingDistance();                ISemController sem = m_SemHardwareMgr;                double posX=0, posY=0,posR=0;                sem.GetSemPositionXY(ref posX, ref posY, ref posR);                CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();                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;                autoReset.SemState = semstate;                //-------------------------------------                // 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.");                    //pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    //// record end time                    //pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    //return;                }                     // set the BSE scan param                if (!SetHoleBSEParam(m_HolePreviewSample))                {                    log.Error("DoHolePreview: fail to set BSE param.");                    //pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    //// record end time                    //pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    //return;                }                            // 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                //int nNewFieldId = 0;                for ( int i = 0; i < listFieldCenter.Count; ++i)                {// check and break if stop button is clicked                    if (IsAborted())                    {// 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_Sample.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;                    }                    // take BSE image for the fields                    CBSEImgClr pBSEIamge = AcquireABSEImage();                    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);            }        }        // Cumulate field data info        public virtual bool CumulateFieldData( List<COTSParticleClr> listParticles, double a_nMeasuredArea)        {            // get measure result items of the sample            CMsrResultItems pMsrResults = m_Sample.GetMsrResults();                       // go through the particles list            foreach (COTSParticleClr pParticle in listParticles)            {                // create a measure result item                pMsrResults.CumulateMeasureResult(pParticle);            }            pMsrResults.CumulateMeasuredArea(a_nMeasuredArea);            // cumulate ratio            double dRatio = pMsrResults.GetTotalParticleArea();            dRatio = dRatio / pMsrResults.GetMeasuredArea();            pMsrResults.SetRatio(dRatio);                               m_Sample.SetMsrResults(pMsrResults);                      return true;        }                     public bool SaveFieldData(COTSField fldData, string filedFileFoler)        {                       string strFieldFileFolder = filedFileFoler;            CBSEImageFileMgr pBSEImgFileMgr = new CBSEImageFileMgr();            pBSEImgFileMgr.SetBSEImg(fldData.GetBSEImage());            int nId = fldData.GetId();            string sFieldId;            sFieldId = nId.ToString();            string strBSEFilePathname = strFieldFileFolder + "\\" + m_pSampleRstFile.SMPL_MSR_RESULT_FIELDS_BSE + sFieldId + pBSEImgFileMgr.BMP_IMG_FILE_EXT;            if (!pBSEImgFileMgr.SaveIntoBitmap(strBSEFilePathname))            {                log.Error("SaveFieldFiles: save BSE file failed.");                return false;            }            if (fldData.particleImages.Count > 0)            {                for (int i=0;i<fldData.particleImages.Count;i++)                {                    strBSEFilePathname= m_pSampleRstFile.GetParticleImageFolder() + "\\"  + sFieldId +"_" +i.ToString()+pBSEImgFileMgr.BMP_IMG_FILE_EXT;                    pBSEImgFileMgr.SetBSEImg(fldData.particleImages[i]);                    pBSEImgFileMgr.SaveIntoBitmap(strBSEFilePathname);                }                        }            // IncA Data list            CIncAFileMgr pDBFileMgr = m_pSampleRstFile.DBFileMgr;            pDBFileMgr.SaveStatusDataToDB();            var fldDB = pDBFileMgr.GetFieldDB();            log.Warn("Start saving particle data.");            var fldcmd = fldDB.GetSavingAFieldcmdObj(fldData.GetId(), fldData.GetOTSPosition(), fldData.GetSemPos());            List<KeyValuePair<string, System.Data.SQLite.SQLiteParameter[]>> fldcmds = new List<KeyValuePair<string, System.Data.SQLite.SQLiteParameter[]>>();            fldcmds.Add(fldcmd);            pDBFileMgr.ExecuteNonQueryBatch(ref fldcmds);            //remomove the invalid particles            var cmds = pDBFileMgr.GetSavingParticleDataToDBCmds(fldData.GetListAnalysisParticles(), fldData.GetOTSPosition());            pDBFileMgr.ExecuteNonQueryBatch(ref cmds);            CPosXrayDBMgr PosXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr();            var listAnalysisPosXray = new List<CPosXrayClr>();            foreach (var p in fldData.GetListXrayParticles())            {                listAnalysisPosXray.Add(p.GetXray());            }            var cmds1 = PosXrayDBMgr.GetSavingXrayCmds(listAnalysisPosXray, true);            pDBFileMgr.ExecuteNonQueryBatch(ref cmds1);            return true;        }        protected void SaveFieldMgrData()        {            while (bSaveThreadWorking)            {                while (fieldQueue.Count() > 0)                {                    COTSField f = fieldQueue.Dequeue();                                  //save to disk first ,then pop . if the size is 0,then we know all the saving work is done.                    log.Info("Begin to save particles data! particle num:" + f.GetListAnalysisParticles().Count);                    SaveFieldData(f, m_pSampleRstFile.GetFieldFileSubFolderStr());                                  }                if (fieldQueue.Count() == 0)                {                    bSaveThreadWorking = false; //must set this flag,so the main thread can know this thread has exited.                    log.Warn("finished batch saving");                    return;                }            }            return;        }        private void SendFieldParticlesInfoToGUI(COTSField curFld,CMsrSampleStatus pStatus)        {            double measuredArea = 0; // this area should be the field area            var a_pBSEImg = curFld.GetBSEImage();            double dPixelSize = curFld.GetPixelSize();            measuredArea = a_pBSEImg.GetHeight() * a_pBSEImg.GetWidth() * dPixelSize * dPixelSize; //Get measured area            CumulateFieldData(curFld.GetListAnalysisParticles(), measuredArea);            log.Info("Send field data to screen!");                       ST_MSTMsg MsgFieldEnd = new ST_MSTMsg(m_Sample,curFld);            MsgFieldEnd.InitFieldDataMsg();                       m_pMsrThread.SendMessageToMeasureGUI(MsgFieldEnd);        }        protected void StartSaveFileThread(ref COTSField a_pFieldMgr)        {            fieldQueue.Enqueue(a_pFieldMgr);            if (fieldQueue.Count() > 0) //if there's data in the queue and the previous thread has finished then start a new thread.            {                if (bSaveThreadWorking == false)                {                    bSaveThreadWorking = true;                    m_thread_ptr = new System.Threading.Thread(this.SaveFieldMgrData);//m_thread_ptr = shared_ptr<thread>(new thread(&CSmplMeasureInc::SaveFieldMgrData, this));                    m_thread_ptr.IsBackground = true;                    m_thread_ptr.Start();                }            }        }                  }}
 |