#pragma once #define _CRTDBG_MAP_ALLOC #include #include #include "stdafx.h" #include "SmplMsrResultFileMgr.h" #include "PosXrayFileMgr.h" #include "BSEImgFileMgr.h" #include "IncAFileMgr.h" #include "OTSHelper.h" #include "OTSFileSys.h" namespace OTSMODEL { using namespace OTSDATA; // constructor CSmplMsrResultFileMgr::CSmplMsrResultFileMgr(CString workingFolder) { m_strWorkingFolder = workingFolder; m_listAnalysisXray.clear(); } // destructor CSmplMsrResultFileMgr::~CSmplMsrResultFileMgr() { } // class methods // public // initialization // this method needs to be called before measurement BOOL CSmplMsrResultFileMgr::Init(COTSSamplePtr a_pSample) { // sample check ASSERT(a_pSample); if (!a_pSample) { // invalid sample pointer LogErrorTrace(__FILE__, __LINE__, _T("Init: failed to create the working directory.")); return FALSE; } // sample name CString strSmplName = a_pSample->GetName(); strSmplName.Trim(); if (strSmplName.IsEmpty()) { // the sample name string can't be an empty string LogErrorTrace(__FILE__, __LINE__, _T("Init: the sample name string is an empty string.")); return FALSE; } // the working directory string can't be an empty string if (m_strWorkingFolder.IsEmpty()) { // the working directory is empty LogTrace(__FILE__, __LINE__, _T("Init: the woring folder directory string is an empty string.")); return FALSE; } // check if the working directory is there if (!COTSFileSys::Exists(m_strWorkingFolder)) { // the working directory is not exit, create it if (!COTSFileSys::CreateFolder(m_strWorkingFolder)) { // failed to create the working directory LogTrace(__FILE__, __LINE__, _T("Init: failed to create the working directory.")); return FALSE; } } // sample measure file pathname CString strPathname = m_strWorkingFolder + strSmplName + SMPL_MSR_RESULT_FILE_EXT; // file not exists, creates it if (!CreateFileMgr(strPathname)) { // failed to create the file LogErrorTrace(__FILE__, __LINE__, _T("Init: can't create file manager(%s). error: %s"), strPathname); return FALSE; } // get field files directory string CString strFieldFileSubFolder = GetFieldFileSubFolderStr(); // check if the field files directory exists if (!COTSFileSys::Exists(strFieldFileSubFolder)) { // field files directory exists not exists, creates it if (!COTSFileSys::CreateFolder(strFieldFileSubFolder)) { // failed to create the field files directory LogErrorTrace(__FILE__, __LINE__, _T("Init: failed to create field files directory (%s). error: %s"), strFieldFileSubFolder); return FALSE; } } // ok, return TRUE SetSample(a_pSample); return TRUE; } // Load BOOL CSmplMsrResultFileMgr::Load(CString a_strPathname /*= _T("")*/) { /* int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpFlag);*/ //_CrtSetBreakAlloc(7415416); //AFX_MANAGE_STATE(AfxGetStaticModuleState()); // check the pathname string a_strPathname.Trim(); if (a_strPathname.IsEmpty()) { // open CFileDialog dlg(TRUE, SMPL_MSR_RESULT_FILE_EXT, NULL, OFN_FILEMUSTEXIST, SMPL_MSR_RESULT_FILE_FILTER); if (dlg.DoModal() != IDOK) { // user canceled loading LogTrace(__FILE__, __LINE__, _T("Load: user canceled loading.")); return FALSE; } a_strPathname = dlg.GetPathName(); } // get path of the pathname CString strFilePath = COTSHelper::GetFolderName(a_strPathname); if (strFilePath.IsEmpty()) { // file path string is an empty string LogErrorTrace(__FILE__, __LINE__, _T("Load: file path string is an empty string.")); return FALSE; } // field file sub folder string CString strFieldFileSubFolder = strFilePath + _T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER + _T("\\"); // check if the field file sub folder exists if (!COTSFileSys::Exists(strFieldFileSubFolder)) { // field files folder doesn't exist LogErrorTrace(__FILE__, __LINE__, _T("Load: field files folder doesn't exist (%s)."), strFieldFileSubFolder); return FALSE; } SetWorkingFolderStr(strFieldFileSubFolder); // create sample measure result file CSmplMsrResultFilePtr pSmplMsrResultFile = CSmplMsrResultFilePtr(new CSmplMsrResultFile()); tinyxml2::XMLDocument doc; doc.LoadFile(a_strPathname);//载入xml文件 tinyxml2::XMLElement *rootNode; rootNode = doc.FirstChildElement(RootClassName); pSmplMsrResultFile->Serialize(false, &doc, rootNode); // file version CString strFileVersion = pSmplMsrResultFile->GetFileVersion(); DWORD nFileVersion = COTSHelper::GetVersionFromString(strFileVersion); if (nFileVersion == 0) {// invalid file LogErrorTrace(__FILE__, __LINE__, _T("Load: invalid sample measure result file %s"), a_strPathname); return FALSE; } // sample measure result file m_pSmplMsrResultFile = pSmplMsrResultFile; SetPathName(a_strPathname); this->LoadFieldDataFromDB(m_strPathname); // ok, return TRUE return TRUE; } // Load BOOL CSmplMsrResultFileMgr::LoadFieldDataFromDB(CString a_strPathname /*= _T("")*/) { // check the pathname string a_strPathname.Trim(); if (a_strPathname.IsEmpty()) { // open CFileDialog dlg(TRUE, SMPL_MSR_RESULT_FILE_EXT, NULL, OFN_FILEMUSTEXIST, SMPL_MSR_RESULT_FILE_FILTER); if (dlg.DoModal() != IDOK) { // user canceled loading LogTrace(__FILE__, __LINE__, _T("Load: user canceled loading.")); return FALSE; } a_strPathname = dlg.GetPathName(); } // get path of the pathname CString strFilePath = COTSHelper::GetFolderName(a_strPathname); if (strFilePath.IsEmpty()) { // file path string is an empty string LogErrorTrace(__FILE__, __LINE__, _T("Load: file path string is an empty string.")); return FALSE; } // field file sub folder string CString strFieldFileSubFolder = strFilePath + _T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER + _T("\\"); // check if the field file sub folder exists if (!COTSFileSys::Exists(strFieldFileSubFolder)) {// field files folder doesn't exist LogErrorTrace(__FILE__, __LINE__, _T("Load: field files folder doesn't exist (%s)."), strFieldFileSubFolder); return FALSE; } CString strIncAFilename = strFieldFileSubFolder + _T("\\") + SMPL_MSR_RESULT_INCLUSION_FILE; CIncAFileMgrPtr pIncAFileMgr = CIncAFileMgrPtr(new CIncAFileMgr(strIncAFilename)); COTSFieldDataList allFlds; CMsrSampleStatusPtr poMsrStatus= m_pSmplMsrResultFile->GetSample()->GetMsrStatus(); CMsrResultsPtr poMsrResults= m_pSmplMsrResultFile->GetSample()->GetMsrResults(); double aFldArea = m_pSmplMsrResultFile->GetSample()->CalculateAFieldArea(); if (pIncAFileMgr->GetAllFieldsFromDB(allFlds, poMsrStatus, poMsrResults, aFldArea)) { m_pSmplMsrResultFile->SetFieldData(allFlds); COTSFieldDataList& listFieldData = m_pSmplMsrResultFile->GetFieldData(); for (auto pFieldData : listFieldData) { //pFieldData->SetFieldFileFolder(strFieldFileSubFolder); } return TRUE; } else { return FALSE; } } // Save BOOL CSmplMsrResultFileMgr::Save(CString a_strPathname /*= _T("")*/) { // safety check ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { // invalid sample measure result file pointer LogErrorTrace(__FILE__, __LINE__, _T("Save: invalid sample measure result file pointer.")); return FALSE; } // check the pathname string a_strPathname.Trim(); if (a_strPathname.IsEmpty()) { // file save as dialog CFileDialog dlg(FALSE, SMPL_MSR_RESULT_FILE_EXT, NULL, OFN_OVERWRITEPROMPT, SMPL_MSR_RESULT_FILE_FILTER); if (dlg.DoModal() != IDOK) { // user canceled loading LogTrace(__FILE__, __LINE__, _T("Save: user canceled save.")); return FALSE; } // get file pathname a_strPathname = dlg.GetPathName(); } // get path of the pathname CString strFilePath = COTSHelper::GetFolderName(a_strPathname); if (strFilePath.IsEmpty()) { // file path string is an empty string LogErrorTrace(__FILE__, __LINE__, _T("Save: file path string is an empty string.")); return FALSE; } // check if the path exists if (!COTSFileSys::Exists(strFilePath)) { // file path doesn't exist create it if (!COTSFileSys::CreateFolder(strFilePath)) { // failed to create file path LogErrorTrace(__FILE__, __LINE__, _T("Save: failed to create file path (%s)."), strFilePath); return FALSE; } } tinyxml2::XMLDocument doc; if (COTSFileSys::Exists(a_strPathname)) { doc.LoadFile(a_strPathname);//载入xml文件 } doc.Clear(); tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();//添加xml文件头申明 doc.InsertFirstChild(declaration); tinyxml2::XMLElement *rootNode; rootNode = doc.NewElement(RootClassName); doc.InsertEndChild(rootNode); m_pSmplMsrResultFile->Serialize(true, &doc, rootNode); int result = doc.SaveFile(a_strPathname); // ok, return TRUE return TRUE; } // field file sub folder string CString CSmplMsrResultFileMgr::GetFieldFileSubFolderStr() { // return empty string if working folder if (m_strWorkingFolder.IsEmpty()) { return _T(""); } // add "\\" at the string end if it is not "\\" if (m_strWorkingFolder.Right(1) != _T('\\')) { m_strWorkingFolder += _T("\\"); } // field file sub folder string CString strFieldFileSubFolder = m_strWorkingFolder; CString strFIELDS_FILE_SUBFOLDER = _T("FIELD_FILES"); if (strFieldFileSubFolder.Find(_T(strFIELDS_FILE_SUBFOLDER)) <= 0) { strFieldFileSubFolder = m_strWorkingFolder + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER + _T("\\"); } else { strFieldFileSubFolder = m_strWorkingFolder; } // return field file sub folder string return strFieldFileSubFolder; } // save a x-ray file for a field BOOL CSmplMsrResultFileMgr::SaveXRayFileForAField(COTSFieldMgrPtr a_pField) { // check input ASSERT(a_pField); if (!a_pField) { LogErrorTrace(__FILE__, __LINE__, _T("SaveXRayFileForAField: invalid field data pointer.")); return FALSE; } // get field x-ray file pathname CString strXRayFilePathname = m_strWorkingFolder + _T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER + _T("\\"); CString strXRaySearchFilename = strXRayFilePathname + SMPL_MSR_RESULT_SEARCH_X_RAY_FILE; CString strXRayAnalysisFilename = strXRayFilePathname + SMPL_MSR_RESULT_ANALYSIS_X_RAY_FILE; // save x-ray file for the field CPosXrayFileMgrPtr pPosXrayFileMgr = CPosXrayFileMgrPtr(new CPosXrayFileMgr(strXRayAnalysisFilename)); CPosXrayList listSearchXray = a_pField->GetSearchPosXrayList(); pPosXrayFileMgr->SetPosXrayList(listSearchXray,TRUE); pPosXrayFileMgr->SetHasElement(FALSE); if (!pPosXrayFileMgr->Save()) { LogErrorTrace(__FILE__, __LINE__, _T("SaveXRayFileForAField: save search x-ray failed.")); return FALSE; } CPosXrayList listAnalysisXray = a_pField->GetAnalysisPosXrayList(); pPosXrayFileMgr->SetPosXrayList(listAnalysisXray, TRUE); pPosXrayFileMgr->SetHasElement(TRUE); if (!pPosXrayFileMgr->Save()) { LogErrorTrace(__FILE__, __LINE__, _T("SaveXRayFileForAField: save analysis x-ray failed.")); return FALSE; } // ok, return TRUE return TRUE; } // fields COTSFieldDataPtr CSmplMsrResultFileMgr::GetFieldById(int a_nID) { COTSFieldDataList listFieldData = m_pSmplMsrResultFile->GetFieldData(); if (a_nID <0 || a_nID >(int)listFieldData.size()) { return nullptr; } COTSFieldDataPtr pFieldData = listFieldData[a_nID]; return pFieldData; } BOOL CSmplMsrResultFileMgr::AddAField(COTSFieldDataPtr a_pFieldData) { ASSERT(a_pFieldData); if (!a_pFieldData) { // empty field data pointer LogErrorTrace(__FILE__, __LINE__, _T("AddAField: empty field data pointer.")); return FALSE; } COTSFieldDataList& listFieldData = m_pSmplMsrResultFile->GetFieldData(); listFieldData.push_back(a_pFieldData); return TRUE; } BOOL CSmplMsrResultFileMgr::DeleteAFieldById(int a_nID) { COTSFieldDataList& listFieldData = m_pSmplMsrResultFile->GetFieldData(); if (a_nID <0 || a_nID > (int)listFieldData.size()) { return FALSE; } listFieldData.erase(listFieldData.begin()+a_nID); return TRUE; } void CSmplMsrResultFileMgr::SetSample(COTSSamplePtr a_pSample) { ASSERT(a_pSample); if (!a_pSample) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid sample.")); return; } ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid sample result file manager.")); return; } m_pSmplMsrResultFile->SetSample(a_pSample); } void CSmplMsrResultFileMgr::SetSEMGnr(CSEMDataGnrPtr a_pSEMGnr) { ASSERT(a_pSEMGnr); if (!a_pSEMGnr) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid SEM general data pointer.")); return; } ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid sample result file manager.")); return; } m_pSmplMsrResultFile->SetSEMStage(a_pSEMGnr); } // get id for a new field int CSmplMsrResultFileMgr::GetIdForANewField(int a_nLastFieldId) { // new field id int nNewFieldId = a_nLastFieldId;// +this->m_pSmplMsrResultFile->GetSample()->GetMsrStatus()->GetCompletedFields(); // safety check ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { // shouldn't be here, invalid sample measure result file LogErrorTrace(__FILE__, __LINE__, _T("GetIdForANewField: invalid sample measure result file.")); return nNewFieldId; } // make the new field id is unit COTSFieldDataList& listFieldData = m_pSmplMsrResultFile->GetFieldData(); BOOL bUnit = FALSE; do { auto itr = std::find_if(listFieldData.begin(), listFieldData.end(), [nNewFieldId](COTSFieldDataPtr p) { return p->GetId() == nNewFieldId; }); bUnit = (itr == listFieldData.end()); if (!bUnit) { ++nNewFieldId; } } while (!bUnit); // return new field id return nNewFieldId; } // set SEMStageData void CSmplMsrResultFileMgr::SetSEMStageData(CSEMStageDataPtr a_pSEMStageData) { ASSERT(a_pSEMStageData); if (!a_pSEMStageData) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid SEM stage data pointer.")); return; } ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid sample result file manager.")); return; } m_pSmplMsrResultFile->SetSEMStageData(a_pSEMStageData); } // set SEMStage void CSmplMsrResultFileMgr::SetSEMStage(CStagePtr a_pStage) { ASSERT(a_pStage); if (!a_pStage) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid stage pointer.")); return; } ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("input a invalid sample result file manager.")); return; } m_pSmplMsrResultFile->SetStage(a_pStage); } //COTSFieldMgrList CSmplMsrResultFileMgr::GetOTSFldMgrListAndAnalysisXrayList() //{ // // if (m_listFieldMgr.size() > 0)//if the list is not empty ,prove that we've already load all the dada.so there's no need to load again. // { // return m_listFieldMgr; // } // m_listFieldMgr.clear(); // ASSERT(m_pSmplMsrResultFile); // if (!m_pSmplMsrResultFile) // { // LogErrorTrace(__FILE__, __LINE__, _T("GetOTSFieldMgrList: invalid sample measure result file pointer.")); // return m_listFieldMgr; // } // //Get FieldDataList // COTSFieldDataList listFieldData = m_pSmplMsrResultFile->GetFieldData(); // int nFieldNum = (int)listFieldData.size(); // m_listAnalysisXray.clear(); // // get field number // for (auto pFieldData : listFieldData) // { // COTSFieldMgrPtr pFieldMgr = COTSFieldMgrPtr(new COTSFieldMgr()); // // get FieldData // pFieldMgr->SetOTSFieldData(pFieldData); // // COTSParticleList& listParticle = pFieldData->GetParticleList(); // if (listParticle.empty()) // { // LogInfoTrace(__FILE__, __LINE__, _T("GetOTSFieldMgrList: there is no particle in this field.")); // continue; // } // // get BSE // CString strFieldFileFolder = pFieldData->GetFieldFileFolder(); // int nId = pFieldData->GetId(); // CString sFieldId; // sFieldId.Format(_T("%d"), nId); // CString strBSEFilePathname = strFieldFileFolder + SMPL_MSR_RESULT_FIELDS_BSE + sFieldId + BMP_IMG_FILE_EXT; // CBSEImgFileMgrPtr pBSEImgFile = CBSEImgFileMgrPtr(new CBSEImgFileMgr()); // if (!pBSEImgFile->LoadFromBitmap(strBSEFilePathname)) // { // LogErrorTrace(__FILE__, __LINE__, _T("GetOTSFieldMgrList: can't load BSE File.")); // CMsrResultsPtr pMsrResults = CMsrResultsPtr(new CMsrResults()); // pFieldMgr->SetMsrResult(pMsrResults); // m_listFieldMgr.push_back(pFieldMgr); // continue; // } // CBSEImgPtr pBSEImg = pBSEImgFile->GetBSEImg(); // //pFieldMgr->SetBSEImage(CBSEImgPtr(new CBSEImg(*pBSEImg.get()))); // pFieldMgr->SetBSEImage(pBSEImg); // // get analysis X-ray list // CString strXRayAnalysisFilename = strFieldFileFolder + _T("\\") + SMPL_MSR_RESULT_ANALYSIS_X_RAY_FILE; // CPosXrayFileMgrPtr pPosAnalysisXrayFileMgr = CPosXrayFileMgrPtr(new CPosXrayFileMgr(strXRayAnalysisFilename)); // pPosAnalysisXrayFileMgr->SetHasElement(TRUE); // if (!pPosAnalysisXrayFileMgr->Load(pFieldData->GetId(),strXRayAnalysisFilename)) // { // LogTrace(__FILE__, __LINE__, _T("GetOTSFieldMgrList: load analysis x-ray of field %d failed."), pFieldData->GetId()); // CMsrResultsPtr pMsrResults = CMsrResultsPtr(new CMsrResults()); // pFieldMgr->SetMsrResult(pMsrResults); // m_listFieldMgr.push_back(pFieldMgr); // continue; // } // CPosXraysList listAnalysisXray = pPosAnalysisXrayFileMgr->GetPosXrayList(); // pFieldMgr->SetAnalysisPosXayList(listAnalysisXray); // SetAnalysisXrayToList(listAnalysisXray); // //Mrs result need compute // CMsrResultsPtr pMsrResults = CMsrResultsPtr(new CMsrResults()); // pFieldMgr->SetMsrResult(pMsrResults); // m_listFieldMgr.push_back(pFieldMgr); // } // return m_listFieldMgr; //} void CSmplMsrResultFileMgr::SetParticleList(COTSParticleList& a_listParticle) { m_listParticle.clear(); for (auto pParticle : a_listParticle) { //COTSParticlePtr pParticleNew = COTSParticlePtr(new COTSParticle(*pParticle.get())); //COTSParticlePtr pParticleNew = pParticle; m_listParticle.push_back(pParticle); } } BOOL CSmplMsrResultFileMgr::ComputeParticleList() { ASSERT(m_pSmplMsrResultFile); if (!m_pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("GetParticleList: invalid sample measure result file pointer.")); return FALSE; } m_listParticle.clear(); //Get FieldDataList COTSFieldDataList& listFieldData = m_pSmplMsrResultFile->GetFieldData(); for (auto pFieldData : listFieldData) { COTSParticleList listParticle = pFieldData->GetParticleList(); for (auto pParticle : listParticle) { //COTSParticlePtr pParticleNew = COTSParticlePtr(new COTSParticle(*pParticle.get())); //COTSParticlePtr pParticleNew =pParticle; m_listParticle.push_back(pParticle); } } return TRUE; } BOOL CSmplMsrResultFileMgr::SetAnalysisXrayToList(CPosXrayList a_listAnalysisXray) { //m_listAnalysisXray.clear(); for (auto pXray: a_listAnalysisXray) { //CPosXrayPtr pXrayNew = pXray; m_listAnalysisXray.push_back(pXray); } return TRUE; } // protected // create a new file BOOL CSmplMsrResultFileMgr::CreateFileMgr(CString a_strPathname) { // check the file pathname a_strPathname.Trim(); if (a_strPathname.IsEmpty()) { // file pathname is an empty string LogTrace(__FILE__, __LINE__, _T("Init: file pathname string is an empty string.")); return FALSE; } // create sample measure result file m_pSmplMsrResultFile = CSmplMsrResultFilePtr(new CSmplMsrResultFile()); SetPathName(a_strPathname); // ok, return TRUE return TRUE; } }