using System; using System.Collections.Generic; using System.Data.SQLite; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using OTSCLRINTERFACE; using OTSDataType; using OTSModelSharp.Measure.OTSCleanliness; using OTSModelSharp.ServiceCenter; using OTSModelSharp.ServiceInterface; using static OTSDataType.otsdataconst; namespace OTSModelSharp { class CSmplMeasureCleanliness : CSmplMeasure { public CSmplMeasureCleanliness(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_BSEImg) { int nNewFieldId; nNewFieldId = m_pSampleRstFile.GetIdForANewField(); //first step:remove background of the bse image and compound all the finded particles. curFldData = new CFieldDataClean( a_BSEImg,m_Sample.CalculatePixelSize()); CFieldDataClean curFldDataCln =( CFieldDataClean) curFldData; curFldData.SetId(nNewFieldId); curFldData.SetOTSPosition(fldCenter); Point semPos = new Point(); CSEMStageData a_pCSEMStageData = m_pMsrThread.GetProjResultData().GetSEMStageData(); a_pCSEMStageData.ConverOTSToSEMPoint(fldCenter, ref semPos); curFldData.SemPos = semPos; GetOriginalParticles(); // second step :filter the finded particles. FilterParticles((CFieldDataClean)curFldData); CalculateParticleAbsolutPos(); log.Info("Begin to Calculate the image property of every particle!"); var analysisparts = curFldDataCln.ListBigParticles; curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam(); //collect xray data. if (pXRayParam.GetUsingXray() == true) { Thread.Sleep(100); CollectParticlesXrayData((CFieldDataClean)curFldData); Thread.Sleep(100); } 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) // { // CFieldDataClean f = (CFieldDataClean) fieldQueue.Dequeue(); // //double pixelSize = m_Sample.CalculatePixelSize(); // //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(CFieldDataClean fld) { // 1)remove over sized particles, too small particles and get a analysis particles list double dPixelSize = m_Sample.CalculatePixelSize(); CSampleParam pMsrParam = m_Sample.GetMsrParams(); COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam(); curFldData.InitParticles(pImgProcessParam, dPixelSize); if (curFldData.NoAnalysisParticle()) { log.Warn("There's no analysis particles!"); } var listXray = curFldData.GetListAnalysisParticles().OrderByDescending(x => x.GetActualArea()).ToList(); var listXray1 = new List(); var pXRayParam = pMsrParam.GetXRayParam(); if (listXray.Count > pXRayParam.GetXrayLimit()) { for (var i = 0; i < pXRayParam.GetXrayLimit(); i++) { listXray1.Add(listXray[i]); } } else { listXray1 = listXray; } //2) according to the quantify threshold size value saperate the analysis particles into two group :the bigparticles and the smallparticles. double quantifyThreshold = m_Sample.GetMsrParams().GetXRayParam().GetFeatureModeMinSize(); var smallparts = fld.ListSmallParticles; var bigparts = fld.ListBigParticles; foreach (var part in listXray1) { double equalCircleDiameter = Math.Sqrt(part.GetActualArea() / 3.14159) * 2f; if (equalCircleDiameter < quantifyThreshold) { smallparts.Add(part); } else { bigparts.Add(part); } } fld.ListSmallParticles = smallparts; fld.ListBigParticles = bigparts; //fld.SmallParticlePercentage=percentage; log.Info("SmallQuantifyParts (<" + quantifyThreshold.ToString("f2") + "): " + smallparts.Count); log.Info("BigQuantifyParts (>=" + quantifyThreshold.ToString("f2")+ "): " + bigparts.Count); return ; } public void CollectParticlesXrayData(CFieldDataClean fld) { // get x-ray parameters COTSXRayParam pXRayParam = m_Sample.GetMsrParams ().GetXRayParam(); // calculate search x-ray acquire time uint nXRayAQTime; var smallparts = fld.ListSmallParticles; var bigparts = fld.ListBigParticles; var pStatus = m_Sample.GetMsrStatus(); curFldData.CreateXrayList(bigparts); // big particle using the full xray strategy. curFldData.CreateXrayList(smallparts); //small particle using the fast xray strategy if (bigparts.Count > 0) { var workmode = pXRayParam.GetScanMode(); // get x-ray list (analysis) by particle features if (workmode == OTS_X_RAY_SCAN_MODE.FeatureMode) { nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime(); m_EDSHardwareMgr.GetXRayByFeatures(bigparts, nXRayAQTime, true); } else { nXRayAQTime = (uint)pXRayParam.GetMidAnalyAQTime(); m_EDSHardwareMgr.GetXRayByPoints(bigparts, nXRayAQTime, true); } } if (smallparts.Count > 0) { nXRayAQTime = (uint)pXRayParam.GetFastXrayTime(); // get x-ray list (analysis) by points m_EDSHardwareMgr.GetXRayByPoints(smallparts, nXRayAQTime, true); } return ; } public override void ClassifyFieldParticles() { try { CFieldDataClean curFldDataCln = (CFieldDataClean)curFldData; string libname = m_Sample.GetMsrParams().GetSTDName(); if (libname != "NoSTDDB") { log.Info("Begin to classify big particles!Using " + libname); var bigparts = curFldDataCln.ListBigParticles; ClassifyQuantifyParticles(bigparts,libname); var smallParts = curFldDataCln.ListSmallParticles; ClassifyQuantifyParticles(smallParts, libname); } } catch (Exception e) { log.Info("calcu the particle image property or classify failed. "+e.Message); } } public override void ClassifyMergedParticles(List mergedParts) { try { string libname = m_Sample.GetMsrParams().GetSTDName(); if (libname != "NoSTDDB") { log.Info("Begin to classify big particles!Using " + libname); var bigparts = mergedParts; ClassifyQuantifyParticles(bigparts, libname); } } catch (Exception e) { log.Info("calcu the particle image property or classify failed. " + e.Message); } } public void GetOriginalParticles() { // measure status CMsrSampleStatus pStatus = m_Sample.GetMsrStatus(); // get image process parameter CSampleParam pMsrParam = m_Sample.GetMsrParams(); COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam(); var dPixelsize = m_Sample.CalculatePixelSize(); // remove BES image background curFldData.RemoveImgBGAndGetParticles(pImgProcessParam, dPixelsize); // check if this is an empty image if (curFldData.NoParticle()) { // empty fields log.Info("ImageProcess: empty field."); //return false; } return ; } public bool ClassifyQuantifyParticles(List a_listAnalysisParticles, string libname)// classify particles { int nSize = (int)a_listAnalysisParticles.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { COTSParticleClr pParticle = a_listAnalysisParticles[i]; IClassifyEngine engine = m_classifyEngine.GetParticleEngine(libname); if (!engine.Classify(pParticle)) { // invalid x-ray pointer. log.Info("ClassifyParticle: can't identify the particle as any classified id."); return false; } } return true; } public bool ClassifySmallParticles(List smallparts, string libname) { List a_listAnalysisParticles = smallparts; int nSize = (int)a_listAnalysisParticles.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { COTSParticleClr pParticle = a_listAnalysisParticles[i]; IClassifyEngine engine = m_classifyEngine.GetCurveCompareEngine(libname); if (!engine.Classify(pParticle)) { log.Info("ClassifyParticle: can't identify the particle as any inclusion."); return false; } } return true; } //public bool SaveFieldFiles(CFieldDataClean 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.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.GetOTSPosition(),fldData.SemPos); // var analysisParts = fldData.GetListAnalysisParticles(); // if (!pDBFileMgr.SaveIncADataToDB(analysisParts, fldData.GetOTSPosition())) // { // 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 analysisParts) // { // m_listAnalysisPosXray.Add(p.GetXray()); // } // if (!PosXrayDBMgr.SaveXray(m_listAnalysisPosXray, true)) // { // log.Info("SaveFieldFiles: save analysis x-ray failed."); // return false; // } // //save the small particle info // //CSmallParticleInfoDB smallPartDB = pDBFileMgr.GetSmallParticleInfoDB(); // //Dictionary> mapSmallParts = new Dictionary>(); // //foreach (COTSParticleClr smallP in fldData.ListSmallParticles) // //{ // // if (mapSmallParts.ContainsKey((int)smallP.GetType())) // // { // // mapSmallParts[(int)smallP.GetType()].Add(smallP); // // } // // else // // { // // var plist = new List(); // // plist.Add(smallP); // // mapSmallParts.Add((int)smallP.GetType(), plist); // // } // //} // //List smallparts = new List(); // //foreach (KeyValuePair> particles in mapSmallParts) // //{ // // CSmallParticleInfo partInfo = new CSmallParticleInfo(); // // partInfo.FieldId = particles.Value[0].GetFieldId(); // // partInfo.AveGray = particles.Value[0].GetAveGray(); // // partInfo.Quantity = (int)(particles.Value.Count / fldData.SmallParticlePercentage); // // partInfo.TypeId = particles.Key; // // partInfo.TypeColor = particles.Value[0].GetTypeColor(); // // partInfo.TypeName = particles.Value[0].GetTypeName(); // // double area = 0; // // foreach (var p in particles.Value) // // { // // area += p.GetActualArea(); // // } // // //partInfo.Area = Convert.ToInt32(area / f.SmallParticlePercentage); // // partInfo.Area =(int) area ; // // smallparts.Add(partInfo); // //} // //List> cmds = new List>(); // //foreach (CSmallParticleInfo smallp in smallparts) // //{ // // var cmd= smallPartDB.SaveAKindOfSmallParticle(smallp, new CPosXrayClr(), new System.Drawing.Point(0, 0)); // // cmds.Add(cmd); // //} // //pDBFileMgr.ExecuteNonQueryBatch(ref cmds); // return true; //} } }