| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991 | using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using OTSModelSharp.ServiceInterface;using static OTSDataType.otsdataconst;using OTSDataType;using System.Diagnostics;using System.Drawing;using System.Threading;using OTSModelSharp.DTLBase;using OTSCOMMONCLR;namespace OTSModelSharp{    using CHoleBSEImgsList = List<CHoleBSEImg>;    class CSmplMeasure    {        protected static NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();        protected bool bSaveThreadWorking;        protected System.Threading.Thread m_thread_ptr;           protected COTSSample m_Sample;        protected CMsrThread m_pMsrThread;        string m_strWorkingFolder;       protected CSmplMsrResult m_pSampleRstFile;        CHoleBSEImgsList m_listHoleBSEImg;        //CFunExportClass loger;        protected SemController m_SemHardwareMgr;        protected ScanController m_ScanHardwareMgr;        protected EDSController m_EDSHardwareMgr;              protected Queue<COTSFieldData> fieldQueue=new Queue<COTSFieldData>();        protected COTSFieldData curFldData;        protected IClassifyEngine m_classifyEngine;        public CSmplMeasure()        {            if (log == null)            {                log = NLog.LogManager.GetCurrentClassLogger();            }            m_pSampleRstFile = new CSmplMsrResult();            m_SemHardwareMgr = new SemController();            m_ScanHardwareMgr = new ScanController();            m_EDSHardwareMgr = new EDSController();            m_listHoleBSEImg = new CHoleBSEImgsList();        }        public CSmplMeasure( string a_strWorkingFolder, COTSSample a_pSample)        {            if (log == null)            {                log = NLog.LogManager.GetCurrentClassLogger();            }            m_strWorkingFolder = a_strWorkingFolder;            m_pSampleRstFile = new CSmplMsrResult( a_strWorkingFolder,  a_pSample);// new CSmplMsrResultFile(m_strWorkingFolder,a_pSample);            m_SemHardwareMgr = new SemController();            m_ScanHardwareMgr = new ScanController();            m_EDSHardwareMgr = new EDSController();            m_listHoleBSEImg = new CHoleBSEImgsList();            m_Sample = a_pSample;                    }       public void SetSample(COTSSample a_pSample)        {                        m_Sample = a_pSample;            m_pSampleRstFile.SetSample(a_pSample);        }        public void SetMsrThread(CMsrThread mt)        {            m_pMsrThread = mt;                              }        bool SetSEMDataMrs()        {            var pSEMDataMsr = m_Sample.GetSEMDataMsr();            //ASSERT(pSEMDataMsr);            double dMag = pSEMDataMsr.GetMagnification();            double dWorkDis = pSEMDataMsr.GetWorkingDistance();            //CSemBasePtr pSEMCtrlPtr = GetSEMControl();            var pSEMCtrl = m_pMsrThread.GetSEMController();            // get SEM controller            if (!pSEMCtrl.IsConnected())            {                if (!pSEMCtrl.Connect())                {                    log.Error("SetSEMDataMrs: can't connect SEM.");                    return false;                }            }            log.Info("set magnification:" + dMag.ToString());            log.Info("set Working Distance:" + dWorkDis.ToString());            pSEMCtrl.SetMagnification(dMag);            pSEMCtrl.SetWorkingDistance(dWorkDis);            return true;        }        bool SetSEMExteralOn()        {            var pSEMCtrl = m_SemHardwareMgr;            // get SEM controller            if (!pSEMCtrl.IsConnected())            {                if (!pSEMCtrl.Connect())                {                    log.Error("SetSEMExteralOn: can't connect SEM.");                    return false;                }            }            log.Warn("Set Scan Exteral on!");            pSEMCtrl.SetScanExternal(true);            return true;        }        // set SEM external off        bool SetSEMExteralOff()        {            var pSEMCtrlPtr = m_SemHardwareMgr;            // get SEM controller            if (!pSEMCtrlPtr.IsConnected())            {                if (!pSEMCtrlPtr.Connect())                {                    log.Error("SetSEMExteralOff: can't connect SEM.");                    return false;                }            }            log.Warn("Set SEM Exteral Off!");            pSEMCtrlPtr.SetScanExternal(false);            return true;        }        bool SetBSEParam()        {            // get SEM controller             var pSEMController = m_SemHardwareMgr;            // get scan controller            var pScanController = m_ScanHardwareMgr;            // scan parameters            var pMsrParam = m_Sample.GetMsrParams();            var pImgScanParam = pMsrParam.GetImageScanParam();            // get image size            var nImageSizeId = pImgScanParam.GetImagePixelSize();            int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;            Size sizePixelImage = RESOLUTION_VALUE[nResulotionId];            // get SEM controller            if (!pSEMController.IsConnected())            {                if (!pSEMController.Connect())                {                    log.Error("SetBSEParam: can't connect SEM.");                    return false;                }            }            // get scan field size            double dScanFieldSizeX = sizePixelImage.Width;            double dScanFieldSizeY = sizePixelImage.Height;            if (!pSEMController.GetScanFieldSize(ref dScanFieldSizeX, ref dScanFieldSizeY))            {                log.Error("SetBSEParam: failed to call GetScanFieldSize method.");                return false;            }            // get dwell time             OTS_THREE_TIES_OPTIONS nDwellTime = pImgScanParam.GetScanImageSpeed();            // convert dwell time to bruker dwell time (6, 16, 32)                      const long DWELLTIME_BRUKER_ID_THREE_TIE_MIN = 3;	// 8            long nBrukerDwellTimeId = DWELLTIME_BRUKER_ID_THREE_TIE_MIN + (int)nDwellTime;            int[] DWELLTIME_BRUKER_VALUES = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };            long nBrukerDwellTime = DWELLTIME_BRUKER_VALUES[nBrukerDwellTimeId];            if (!pScanController.Init())            {                log.Error("SetBSEParam: failed to get scan control.");                               return false;            }            // set dwell time            if (!pScanController.SetDwellTime(nBrukerDwellTime))            {                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;        }       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 CalculateUnMeasuredFieldsCenters(out List<System.Drawing.Point> a_listFieldCenter)        {                   // sample measure parameters            CSampleParam pMsrParam = m_Sample.GetMsrParams();            COTSImgScanPrm  poImageScanParam = pMsrParam.GetImageScanParam();            CSEMDataMsr poSEMDataMsr = m_Sample.GetSEMDataMsr();            CMsrSampleStatus pStatus = m_Sample.GetMsrStatus();            // measured field centers list            List<System.Drawing.Point> listCompletedCenter = pStatus.GetCompletedFieldsCenter();            // field centers list manager            CFieldPositionMgr pFieldMgr = new CFieldPositionMgr();            // init field centers list manager            if (!pFieldMgr.Init(m_Sample.GetMsrArea(), poImageScanParam, poSEMDataMsr, listCompletedCenter))            {                log.Error("CalculateFieldsCenters: failed to init field centres list manager.");                a_listFieldCenter = new List<System.Drawing.Point>();                return false;            }            // get field centers list            a_listFieldCenter = pFieldMgr.GetUnmeasuredFieldCentrePoints();// GetFieldCentrePoints();            // ok, return TRUE            return true;        }        protected bool IsAborted()        {            //Debug.Assert(m_pMsrThread == null);            return m_pMsrThread.IsMeasureStopped();        }        bool IsSampleOver(COTSImgScanPrm  a_pScanParam, int a_nTotalFields)        {                      int nStopMode = (int)a_pScanParam.GetStopMode();            int nStopField = a_pScanParam.GetStopParamFields();            // completed fields number            CMsrSampleStatus pMsrSampleStatus = m_Sample.GetMsrStatus();            int nCompeltedField = pMsrSampleStatus.GetCompletedFields();            CMsrDisplayResults pMsrResults = m_Sample.GetMsrResults();            List<CMsrResultItem> listMsrResult = pMsrResults.GetResultItems();            int nNumParticle = 0;            foreach (var pResult in listMsrResult)            {                if (pResult.GetTypeId() > (int)OTS_PARTCLE_TYPE.NO_ANALYSIS_X_RAY)//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 nParticlAim = a_pScanParam.GetStopParamParticles();            int nMeasTimeAim = a_pScanParam.GetStopParamMeasTime();            bool bRet = true;            switch (nStopMode)            {                case (int)OTS_MEASURE_STOP_MODE.CoverMode:                    // completed fields number                    if (nCompeltedField < a_nTotalFields)                    {                                         bRet = false;                    }                    break;                case (int)OTS_MEASURE_STOP_MODE.FieldMode:                    if (nCompeltedField < nStopField)                    {                                             bRet = false;                    }                    break;                case (int)OTS_MEASURE_STOP_MODE.ParticleMode:                    if (nNumParticle < nParticlAim)                    {                                            bRet = false;                    }                    break;                case (int)OTS_MEASURE_STOP_MODE.TimeMode:                    if (nUsedTime < nMeasTimeAim)                    {                                              bRet = false;                    }                    break;                default:                    break;            }            return bRet;        }        // move SEM to the point        bool MoveSEMToPoint(System.Drawing.Point a_poi)        {            // get SEM controller             var pSEMController = m_SemHardwareMgr;                      Point a_SEMpt = new Point();                   CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData();                    if (!a_pCSEMStageData.ConverOTSToSEMPoint(a_poi, ref a_SEMpt))            {                return false;            }            if (!pSEMController.IsConnected())            {                if (!pSEMController.Connect())                {                    log.Error("MoveSEMToPoint: can't connect SEM.");                    return false;                }            }            log.Info("Begin to move SEM stage to " + a_SEMpt.X + "," + a_SEMpt.Y);            Thread.Sleep(100);            // move SEM to the position (rotation 0)            if (!pSEMController.MoveSEMToPoint(a_SEMpt, 0))            {                log.Error("MoveSEMToPoint: failed to call MoveSEMToPoint method.");                return false;            }            return true;        }        // Acquire a BSE image        CBSEImgClr AcquireABSEImage()        {            // BSE image            CBSEImgClr pBSEImage = null;            // get scan controller            var pScanController = m_ScanHardwareMgr;            pBSEImage = pScanController.AcquireBSEImage(0, 0, 2);                  return pBSEImage;        }        public virtual bool FieldImageProcess(Point fldCenter, CBSEImgClr imageData)        {            return true;        }        public virtual void ClassifyParticles(List<COTSParticleClr> parts)        {            return;        }        private class AutoResetSEMControl:IDisposable        {            CSmplMeasure sm;            public AutoResetSEMControl(CSmplMeasure s)            {                sm = s;            }                     public void Dispose()            {                sm.SetSEMExteralOff();                //sm.ResetScan();            }        }         public void DoMeasureForOneSample()        {            using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this)) //when this method exit ,the SetSEMExternalOff and ResetScan will be called automatically.            {                // 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();                MsgSmpStart.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;                MsgSmpStart.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.INPROCESS;                MsgSmpStart.STMSampleStu.cSampleName = m_Sample.GetName();                m_pMsrThread.SendMessageToMeasureApp(MsgSmpStart);                log.Info(m_Sample.GetName() + " Measurement started!");                // get SEM controller to set magnification and working distance                if (!SetSEMDataMrs())                {                    log.Error("DoMeasure: fail to set SEM data.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                                       pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                // get SEM external controll on                if (!SetSEMExteralOn())                {                    log.Error("DoMeasure: fail to set SEM external.");                    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 Kv, Brightness and Contrast!");                m_SemHardwareMgr.GetSEMDataGnrFromHw(ref pSEMDataGnr);                m_pSampleRstFile.SetSEMGnr(pSEMDataGnr);                // record SEM data                COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();                          CSEMStageData pSEMStageData = pProjMgrFile.GetSEMStageData();                               m_pSampleRstFile.SetSEMStageData(pSEMStageData);                // record stage                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;                }                //------                // calculate field centers                List<System.Drawing.Point> umMeasuredlistFieldCenter;                              if (!CalculateUnMeasuredFieldsCenters(out umMeasuredlistFieldCenter))                {// failed to calculate field centers                    log.Error("DoMeasure: failed to calculate field centers.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    // record end time                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                int nNewFieldId = 0;                int numOfAllFields = pStatus.GetCompletedFields() + umMeasuredlistFieldCenter.Count;//                int completedFields = pStatus.GetCompletedFields();                log.Info("Unmeasured fields:" + umMeasuredlistFieldCenter.Count);                for (int i = 0; i < (int)umMeasuredlistFieldCenter.Count; ++i)                {// check and break if stop button is clicked                    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);                        }                        return;                    }                    // check if sample measurement completes                    COTSImgScanPrm pScanParam = m_Sample.GetMsrParams().GetImageScanParam();                    int nTotalFieldSize = (int)umMeasuredlistFieldCenter.Count;                    if (IsSampleOver(pScanParam, numOfAllFields))                    {                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                        break;                    }                    // get a field center                     System.Drawing.Point poiFieldCentre = umMeasuredlistFieldCenter[i];                    // update thread measure status class, let the main thread know that starts a new field                                      ST_MSTMsg MsgFieldStart = new ST_MSTMsg();                    MsgFieldStart.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET.START_MSR_FIELD;                    MsgFieldStart.STMSampleRetData.SMsrField.FieldPos = poiFieldCentre;                    m_pMsrThread.SendMessageToMeasureApp(MsgFieldStart);                    int fldNo = completedFields + i + 1;                    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 no background image.");                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                        return;                    }                                      //BSEData                    ST_MSTMsg MsgFieldBSE = new ST_MSTMsg();                     MsgFieldBSE.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET.BSE_DATA;                    MsgFieldBSE.STMSampleRetData.BSEData.pos.X = poiFieldCentre.X;                    MsgFieldBSE.STMSampleRetData.BSEData.pos.Y = poiFieldCentre.Y;                    MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEImg.GetHeight();                    MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEImg.GetWidth();                    byte[] pImgData = pBSEImg.GetImageDataPtr();                    MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;                    m_pMsrThread.SendMessageToMeasureApp(MsgFieldBSE);                    // get a new field id                    log.Info("Acquire BSE image success! Processing image...");                    // image process                 var rst = FieldImageProcess(poiFieldCentre, pBSEImg);                    if (rst == true)                    {                                          // add the field into the field                            m_pSampleRstFile.AddAField(curFldData);                                           }                                     ++nNewFieldId;                    double measuredArea = 0; // this area should be the field area                    var a_pBSEImg = curFldData.GetBSEImage();                                        double dPixelSize = m_Sample.CalculatePixelSize();                                           measuredArea = a_pBSEImg.GetHeight() * a_pBSEImg.GetWidth()* dPixelSize * dPixelSize + 0.5; //Get measured area                    if (!CumulateFieldData(curFldData.ListAnalysisParticles, measuredArea))                    { // failed to call SaveFieldFile method                        log.Error("ImageProcess: call CumulateFieldData method.");                        pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                        return;                    }                    log.Info("Send field data to screen!");                    // completed fields                    pStatus.SetCompletedFields(pStatus.GetCompletedFields() + 1);                    // completed fieldCenter                    List<System.Drawing.Point> listCpltedCenter = pStatus.GetCompletedFieldsCenter();                    listCpltedCenter.Add(poiFieldCentre);                    //Field Data                    // record end time                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    ST_MSTMsg MsgFieldEnd = new ST_MSTMsg();                                      MsgFieldEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET.FIELD_DATA;                    MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = pStatus.GetCompletedFields();                    MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = numOfAllFields;                    MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = (int)curFldData.ListAnalysisParticles.Count;                    MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos.X = Convert.ToInt32(poiFieldCentre.X);                    MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos.Y = Convert.ToInt32(poiFieldCentre.Y);                    m_pMsrThread.SendMessageToMeasureApp(MsgFieldEnd);                                 }                while (fieldQueue.Count > 0)//wait untill all the field data has been saved.                {                    Thread.Sleep(100);                }                //merging particles                log.Info("Merging big particles on the field edge!");                CImageHandler imgpro = new CImageHandler();                int scanfldsize = m_Sample.GetSEMDataMsr().GetScanFieldSize();                List<COTSParticleClr> mergedParticles = new List<COTSParticleClr>();                imgpro.MergeBigBoundaryParticles(m_pSampleRstFile.GetFieldData(), m_Sample.CalculatePixelSize(), scanfldsize, m_Sample.GetResolutionSize(), ref mergedParticles);                                ClassifyParticles(mergedParticles);                log.Warn("begin particle data db saving...");                                         SaveMergedParticles(mergedParticles);                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();                MsgSmplEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;                MsgSmplEnd.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;                MsgSmplEnd.STMSampleStu.cSampleName = m_Sample.GetName();                m_pMsrThread.SendMessageToMeasureApp(MsgSmplEnd);            }    }              public void DoHolePreview(int a_nHoleID)        {            using (AutoResetSEMControl autoReset = new AutoResetSEMControl(this))            {                    // let the main thread to know that this sample measurement starts                    CMsrSampleStatus 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();                MsgSmpStart.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;                MsgSmpStart.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.INPROCESS;               MsgSmpStart.STMSampleStu.cSampleName=m_Sample.GetName();                // get SEM controller to set magnification and working distance                if (!SetSEMDataMrs())                {                    log.Error("DoHolePreview: fail to set SEM data.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    // record end time                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                // get SEM external controll on                if (!SetSEMExteralOn())                {                    log.Error("DoMeasure: fail to set SEM external.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.FAILED);                    // record end time                    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);                    // record end time                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                            // check if measurement is aborted                if (IsAborted())                {// measurement aborted                    log.Trace("DoHolePreview: measurement aborted before get SEM condition.");                    pStatus.SetStatus(OTS_MSR_SAMPLE_STATUS.STOPPED);                    // record end time                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    return;                }                // calculate field centers                List<System.Drawing.Point> listFieldCenter=new List<System.Drawing.Point>();               // listFieldCenter.clear();                if (!CalculateUnMeasuredFieldsCenters(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;                                    if (IsSampleOver(pScanParam, nTotalFieldSize))                    {                        pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                        break;                    }                    // get a field center                     System.Drawing.Point poiFieldCentre = listFieldCenter[i];                                 // update thread measure status class, let the main thread know that starts a new field                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    ST_MSTMsg MsgFieldStart=new ST_MSTMsg();                    //memset(&MsgFieldStart, 0, sizeof(ST_MSTMsg));                    MsgFieldStart.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldStart.STMSampleRetData.iRetDataType = MSAMPLE_RET.START_MSR_FIELD;                    MsgFieldStart.STMSampleRetData.SMsrField.FieldPos = poiFieldCentre;                    m_pMsrThread.SendMessageToMeasureApp(MsgFieldStart);                    // 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();                   // memset(&MsgFieldBSE, 0, sizeof(ST_MSTMsg));                    MsgFieldBSE.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldBSE.STMSampleRetData.iRetDataType = MSAMPLE_RET.BSE_DATA;                    MsgFieldBSE.STMSampleRetData.BSEData.pos = poiFieldCentre;                    //MsgFieldBSE.STMSampleRetData.BSEData.pos.y = poiFieldCentre.y;                    MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataHeight = pBSEIamge.GetHeight();                    MsgFieldBSE.STMSampleRetData.BSEData.iBSEDataWidth = pBSEIamge.GetWidth();                    byte[] pImgData = pBSEIamge.GetImageDataPtr();                    MsgFieldBSE.STMSampleRetData.BSEData.lpBSEData = pImgData;                    m_pMsrThread.SendMessageToMeasureApp(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                    CHoleBSEImg pHoleBSEImg =new CHoleBSEImg();                    pHoleBSEImg.SetHoleID(a_nHoleID);                    pHoleBSEImg.SetPosition(poiFieldCentre);                    Rectangle oImageRect =(Rectangle) pBSEIamge.GetImageRect();                    int nImageSize = pBSEIamge.GetHeight() * pBSEIamge.GetWidth();                    pHoleBSEImg.SetImageRect(oImageRect);                    pHoleBSEImg.SetImageData( pBSEIamge.GetImageDataPtr(),oImageRect.Width,oImageRect.Height);                    m_listHoleBSEImg.Add(pHoleBSEImg);                    COTSMsrPrjResultData pProjMgrFile = m_pMsrThread.GetProjResultData();                    pProjMgrFile.SetHoleBESImgList(m_listHoleBSEImg,true);                    // prepare for the next                    ++nNewFieldId;                    pStatus.ComputeTime(OTS_MSR_TIME_TYPE.STOPPED);                    ST_MSTMsg MsgFieldEnd=new ST_MSTMsg();                                       MsgFieldEnd.iMsgType = ENUM_MSG_TYPE.MSAMPLERESULT;                    MsgFieldEnd.STMSampleRetData.iRetDataType = MSAMPLE_RET.FIELD_DATA;                    MsgFieldEnd.STMSampleRetData.SFieldData.iCompleteFieldCount = (i + 1);                    MsgFieldEnd.STMSampleRetData.SFieldData.iMeasureFieldCount = listFieldCenter.Count;                    MsgFieldEnd.STMSampleRetData.SFieldData.iSParticleCount = 0;                    MsgFieldEnd.STMSampleRetData.SFieldData.FieldPos = poiFieldCentre;                                       m_pMsrThread.SendMessageToMeasureApp(MsgFieldEnd);                    //break;                }                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();                MsgSmplEnd.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;                MsgSmplEnd.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.COMPLETED;                              m_pMsrThread.SendMessageToMeasureApp(MsgSmplEnd);            }        }        // Cumulate field data info        public virtual bool CumulateFieldData( List<COTSParticleClr> listParticles, double a_nMeasuredArea)        {            // get measure result items of the sample            CMsrDisplayResults pMsrResults = m_Sample.GetMsrResults();            // cumulate field data info            //pMsrResults.CumulateMeasureResults(listResultItems);            pMsrResults.CumulateMeasuredArea(a_nMeasuredArea);            // cumulate ratio            double dRatio = 10000 * pMsrResults.GetTotalParticleArea();            dRatio = dRatio / pMsrResults.GetMeasuredArea();            pMsrResults.SetRatio(dRatio);                    // go through the particles list            foreach (COTSParticleClr pParticle in listParticles)            {                // create a measure result item                pMsrResults.CumulateMeasureResult(pParticle);            }            // ok, return TRUE            return true;        }        // hole BSE images list        void SetHoleBESImgList(CHoleBSEImgsList a_listHoleBSEImg, bool a_bClear/* = TRUE*/)        {// clear the hole BSE image list if necessary             if (a_bClear)            {                m_listHoleBSEImg.Clear();            }            // go through the input list            foreach (var pHoleBSEImg in a_listHoleBSEImg)            {// add the new hole BSE image into HoleBSEImage list                m_listHoleBSEImg.Add(pHoleBSEImg);            }        }        public bool SaveMergedParticles(List<COTSParticleClr> mergedParts)        {            CIncAFileMgr pDBFileMgr = m_pSampleRstFile.DBFileMgr;            var mergedpartdb = pDBFileMgr.GetMergedParticleDB();                        foreach (COTSParticleClr part in mergedParts)            {                mergedpartdb.SaveAParticle(part, part.GetXray(), new System.Drawing.Point(0, 0));            }            CPosXrayDBMgr pXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr();            CElementChemistryDB xraydb = pXrayDBMgr.GetElementChemistryDB();            List<CPosXrayClr> ches = new List<CPosXrayClr>();            foreach (COTSParticleClr part in mergedParts)            {                ches.Add(part.GetXray());            }            xraydb.SaveElementChemistriesList(ches);            return true;        }    }}
 |