using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using OTSCLRINTERFACE; using OTSDataType; using OTSModelSharp.Measure.OTSInclution; using OTSModelSharp.ServiceCenter; using OTSModelSharp.ServiceInterface; using static OTSDataType.otsdataconst; namespace OTSModelSharp { class CSmplMeasureInclution : CSmplMeasure { public CSmplMeasureInclution(string a_strWorkingFolder, COTSSample a_pSample) : base(a_strWorkingFolder, a_pSample) { SetWorkingFolder(a_strWorkingFolder); SetSample(a_pSample); m_classifyEngine = new CClassifyEngine(); } // field image process public override bool FieldImageProcess(Point fldCenter, CBSEImgClr a_pBSEImg) { int nNewFieldId; nNewFieldId = m_pSampleRstFile.GetIdForANewField(); // create a field curFldData = new CFieldDataIncA(a_pBSEImg, m_Sample.CalculatePixelSize()); curFldData.SetId(nNewFieldId); curFldData.SetPosition(fldCenter); //first step:remove background of the bse image and compound all the finded particles. COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam(); log.Info("Begin to process image and get all particles!"); GetOriginalParticles(); // second step :filter the finded particles. log.Info("Begin to filter particles!"); FilterParticles(); CalculateParticlePos(); if (pXRayParam.GetUsingXray() == true) { Thread.Sleep(100); CollectParticlesXrayData(); Thread.Sleep(100); } log.Info("Begin to Calculate the image property of every particle!"); var analysisparts = curFldData.ListAnalysisParticles; curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc. log.Info("Begin to classify particles! particle num:"+ curFldData.ListAnalysisParticles.Count); ClassifyFieldParticles(); // save field files m_Sample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.SUCCESSED); StartSaveFileThread(curFldData); return true; ; } // save field data protected void SaveFieldMgrData() { while (bSaveThreadWorking) { while (fieldQueue.Count() > 0) { COTSFieldData f = fieldQueue.Dequeue(); //save to disk first ,then pop . if the size is 0,then we know all the saving work is done. 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. return; } } return; } protected void StartSaveFileThread(COTSFieldData 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(new thread(&CSmplMeasureInc::SaveFieldMgrData, this)); m_thread_ptr.Start();//m_thread_ptr->detach(); } } } public void FilterParticles() { // remove over sized particles, too small particles and get a analysis particles list // get pixel size double dPixelSize = m_Sample.CalculatePixelSize(); CSampleParam pMsrParam = m_Sample.GetMsrParams(); COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam(); curFldData.FilterParticles(pImgProcessParam, dPixelSize ); // make sure the particles list is not empty if (curFldData.NoAnalysisParticle()) { log.Info("There's no particles to be analysed!"); //return false; } return ; } //calculate the real sem position of the particle public void CalculateParticlePos() { double dPixelSize = m_Sample.CalculatePixelSize(); CSEMStageData pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData(); foreach (var p in curFldData.ListAnalysisParticles) { Point fldOtsPos = new Point(curFldData.PoiPos.X, curFldData.PoiPos.Y);//take the field position as the particle's position instead Point semPos = new Point(); pCSEMStageData.ConverOTSToSEMPoint(fldOtsPos, ref semPos); p.SetAbsolutPos(semPos); } } public void CollectParticlesXrayData() { // get x-ray parameters COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam(); var listAnalysisparts = curFldData.ListAnalysisParticles; var pStatus = m_Sample.GetMsrStatus(); ////============================================= curFldData.CreateXrayList(listAnalysisparts); var xraymode = m_Sample.GetMsrParams().GetXRayParam().GetScanMode(); // get x-ray list (analysis) by particle features uint nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime(); if (xraymode == OTS_X_RAY_SCAN_MODE.FeatureMode) { log.Info("Begin feature mode xray collection!AQTime:"+nXRayAQTime+" xrayNum:"+ listAnalysisparts.Count); m_EDSHardwareMgr.GetXRayByFeatures(listAnalysisparts, nXRayAQTime, true); } else { log.Info("Begin point mode xray collection!AQTime:" + nXRayAQTime + " xrayNum:" + listAnalysisparts.Count); // get x-ray list (analysis) by points m_EDSHardwareMgr.GetXRayByPoints(listAnalysisparts, nXRayAQTime, true); } return ; } public override void ClassifyFieldParticles() { try { var curFld = (CFieldDataIncA)curFldData; var quantifyparts = curFld.ListAnalysisParticles; int nSize = quantifyparts.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { string libname = m_Sample.GetMsrParams().GetSTDName(); ClassifyIncAParticle(quantifyparts[i], libname); } } catch (Exception e) { log.Info(" classify failed. " + e.Message); } } public override void ClassifyMergedParticles(List mergedParts) { try { var quantifyparts = mergedParts; int nSize = quantifyparts.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { string libname = m_Sample.GetMsrParams().GetSTDName(); ClassifyIncAParticle(quantifyparts[i], libname); } } catch (Exception e) { log.Info(" classify failed. " + e.Message); } } public bool ClassifyIncAParticle(COTSParticleClr particle, string libname)// classify particles { int steelTech = (int)m_Sample.GetMsrParams().GetSteelTechnology(); particle.SetType((int)OTS_PARTCLE_TYPE.NOT_IDENTIFIED); if (m_Sample.IfUsingSysSTD()) { if (libname != "NoSTDDB") { //var m_classifyEngine = new CClassifyEngine(); IClassifyEngine engine = m_classifyEngine.GetParticleEngine(libname); engine.Classify(particle); } if (particle.GetType() ==(int) OTS_PARTCLE_TYPE.NOT_IDENTIFIED) { IClassifyEngine engine; engine = m_classifyEngine.GetIncClassifyEngine(); engine.ClassifyIncA(particle, steelTech); } } else { if (libname != "NoSTDDB") { //var m_classifyEngine = new CClassifyEngine(); IClassifyEngine engine = m_classifyEngine.GetParticleEngine(libname); engine.Classify(particle); } } return true; } public void GetOriginalParticles() { // measure status CMsrSampleStatus pStatus = m_Sample.GetMsrStatus(); // get image process parameter CSampleParam pMsrParam = m_Sample.GetMsrParams(); COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam(); // remove BES image background curFldData.RemoveBSEImageBG(pImgProcessParam); // check if this is an empty image if (curFldData.NoParticle()) { // empty fields log.Info("ImageProcess: empty field."); //return false; } return ; } public bool SaveFieldData(COTSFieldData fldData,string filedFileFoler) { //loger.Warn("begin bitmap saving..."); 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.Info("SaveFieldFiles: save BSE file failed."); return false; } // IncA Data list CIncAFileMgr pDBFileMgr = m_pSampleRstFile.DBFileMgr; pDBFileMgr.SaveStatusDataToDB(); var fldDB = pDBFileMgr.GetFieldDB(); fldDB.SaveAField(fldData.GetId(),fldData.GetPosition()); if (!pDBFileMgr.SaveIncADataToDB(curFldData.ListAnalysisParticles, fldData.GetPosition())) { log.Info("SaveFieldFiles: save inclusion file failed."); return false; } //save the xray data and element data. CPosXrayDBMgr PosXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr(); var m_listAnalysisPosXray = new List(); foreach (var p in curFldData.ListAnalysisParticles) { m_listAnalysisPosXray.Add(p.GetXray()); } if (!PosXrayDBMgr.SaveXray(m_listAnalysisPosXray, true)) { log.Info("SaveFieldFiles: save analysis x-ray failed."); return false; } return true; } } }