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 OTSMeasureApp._0_OTSModel.Measure.ParamData; 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.SetOTSPosition(fldCenter); CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData(); Point semPos = new Point(); a_pCSEMStageData.ConverOTSToSEMPoint(fldCenter,ref semPos); curFldData.SemPos = semPos; //first step:remove background of the bse image and compound all the finded particles. log.Info("Begin to process image and get all particles!"); GetOriginalParticles(); // second step :filter the finded particles. log.Info("Begin to filter particles!"); InitFieldParticles(); COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam(); 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.GetListAnalysisParticles(); curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc. log.Info("Begin to classify particles! particle num:"+ curFldData.GetListAnalysisParticles().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. log.Warn("finished batch saving"); 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.IsBackground = true; m_thread_ptr.Start(); } } } public void InitFieldParticles() { // 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.InitParticles(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(List xrayParticles) { double dPixelSize = m_Sample.CalculatePixelSize(); CSEMStageData pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData(); foreach (var p in xrayParticles) { Point fldOtsPos = new Point(curFldData.OTSPos.X, curFldData.OTSPos.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 listXrayAnalysisparts = curFldData.GetListXrayParticles(); ////============================================= curFldData.CreateXrayList(listXrayAnalysisparts); CalculateParticlePos(listXrayAnalysisparts); var xraymode = m_Sample.GetMsrParams().GetXRayParam().GetScanMode(); // get x-ray list (analysis) by particle features uint nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime(); var nFastXrayAQTime =(uint) pXRayParam.GetFastXrayTime(); var quantifyMinSize = pXRayParam.GetFeatureModeMinSize(); var listXray = listXrayAnalysisparts.OrderByDescending(x => x.GetActualArea()).ToList(); var listXray1 = new List(); if (listXray.Count > pXRayParam.GetXrayLimit()) { for (var i = 0; i < pXRayParam.GetXrayLimit(); i++) { listXray1.Add(listXray[i]); } } else { listXray1 = listXray; } List smallparts = new List(); List bigparts = new List(); foreach (var p in listXray1) { double diameter = Math.Sqrt(p.GetActualArea() / 3.14159) * 2; if (diameter >= quantifyMinSize) { bigparts.Add(p); } else { smallparts.Add(p); } } if (xraymode == OTS_X_RAY_SCAN_MODE.FeatureMode) { if (bigparts.Count > 0) { log.Info("Begin feature mode xray collection for big particles!AQTime:" + nXRayAQTime + " xrayNum:" + bigparts.Count); m_EDSHardwareMgr.GetXRayByFeatures(bigparts, nXRayAQTime, true); } } else { if (bigparts.Count > 0) { log.Info("Begin point mode xray collection for big particles!AQTime:" + nXRayAQTime + " xrayNum:" + bigparts.Count); // get x-ray list (analysis) by points m_EDSHardwareMgr.GetXRayByPoints(bigparts, nXRayAQTime, true); } } if (smallparts.Count > 0) { log.Info("Begin point mode xray collection for small particles!AQTime:" + nFastXrayAQTime + " xrayNum:" + smallparts.Count); // get x-ray list (analysis) by points m_EDSHardwareMgr.GetXRayByPoints(smallparts, nFastXrayAQTime, true); } return ; } public override void ClassifyFieldParticles() { try { var curFld = (CFieldDataIncA)curFldData; var anylysisparts = curFld.GetListAnalysisParticles(); int nSize = anylysisparts.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { string libname = m_Sample.GetMsrParams().GetSTDName(); ClassifyIncAParticle(anylysisparts[i], libname); } } catch (Exception e) { log.Info(" classify failed. " + e.Message); } //var partlist = curFldData.GetListAnalysisParticles(); //var validPars = new List(); //foreach (var p in partlist) //{ // if (p.GetGrpId() > INVALIDPART_GROUPID) // { // validPars.Add(p); // } //} //curFldData.SetListAnalysisParticles(validPars); } 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("merged parts 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(); var specialPartsparam = pMsrParam.GetSpecialGrayRangeParam(); var pixelsize = m_Sample.CalculatePixelSize(); if (specialPartsparam.IsToRun) { List ranges = pMsrParam.GetSpecialGrayRangeParam().GetIntRanges(); foreach (var grayRange in ranges) { CIntRangeClr range = new CIntRangeClr(grayRange.range.GetStart(), grayRange.range.GetEnd()); CIntRangeClr diaRange = new CIntRangeClr(grayRange.diameterRange.GetStart(), grayRange.diameterRange.GetEnd()); curFldData.GetPartsBySpecialGray(range, diaRange,pixelsize,grayRange.ifCollectXray); } } // remove BES image background curFldData.RemoveImgBGAndGetParticles(pImgProcessParam, pixelsize); // check if this is an empty image if (curFldData.NoParticle()) { // empty fields log.Info("ImageProcess: empty field."); } 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.Error("SaveFieldFiles: save BSE file failed."); return false; } // 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.SemPos); List> fldcmds = new List>(); fldcmds.Add(fldcmd); pDBFileMgr.ExecuteNonQueryBatch(ref fldcmds); //remomove the invalid particles var cmds = pDBFileMgr.GetSavingIncADataToDBCmds(curFldData.GetListAnalysisParticles(), fldData.GetOTSPosition()); pDBFileMgr.ExecuteNonQueryBatch(ref cmds); CPosXrayDBMgr PosXrayDBMgr = pDBFileMgr.GetPosXrayDBMgr(); var listAnalysisPosXray = new List(); foreach (var p in curFldData.GetListXrayParticles()) { listAnalysisPosXray.Add(p.GetXray()); } var cmds1 = PosXrayDBMgr.GetSavingXrayCmds(listAnalysisPosXray, true); pDBFileMgr.ExecuteNonQueryBatch(ref cmds1); return true; } } }