#pragma once #include "stdafx.h" #include "PosXrayFileMgr.h" #include "OTSFileSys.h" #include "OTSHelper.h" namespace OTSMODEL { using namespace OTSTools; // project file extension const CString POS_XRAY_FILE_EXT = _T("db"); // project file filter const CString POS_XRAY_FILE_FILTER = _T("Position X-ray Files (*.db)|*.db|All Files (*.*)|*.*||"); // constructor CPosXrayFileMgr::CPosXrayFileMgr(CString fileName) { // initialization m_strPathName = fileName; Init();/*because this database has been merged into Inclution.db,so there's no need to create again.*/ } // destructor CPosXrayFileMgr::~CPosXrayFileMgr() { // cleanup Cleanup(); //delete m_listPosXray; } // public BOOL CPosXrayFileMgr::CreateXrayFile() { // check file name m_strPathName.Trim(); if (m_strPathName.IsEmpty()) { // error, wrong file name LogErrorTrace(__FILE__,__LINE__,_T("Empty file path name")); ASSERT(FALSE); return FALSE; } // get database name CString sDatabaseName = GetPathName(); if (COTSFileSys::Exists(sDatabaseName)) { if (!Open(m_strPathName, FALSE)) { LogErrorTrace(__FILE__, __LINE__, _T("Open X-ray file failed.")); ASSERT(FALSE); return FALSE; } } else { if (!Create(m_strPathName)) { LogErrorTrace(__FILE__, __LINE__, _T("Create X-ray file failed.")); ASSERT(FALSE); return FALSE; } } return TRUE; } // Load/Save BOOL CPosXrayFileMgr::Load(int fldId,CString a_strPathName /*= _T("")*/, BOOL a_bClear /*= TRUE*/) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // clear all data if necessary if (a_bClear) { Init(); } // check file pathname a_strPathName.Trim(); if (a_strPathName.IsEmpty()) { // file open dialog CFileDialog dlg(TRUE, POS_XRAY_FILE_EXT, NULL, OFN_FILEMUSTEXIST, POS_XRAY_FILE_FILTER); if (dlg.DoModal() != IDOK) { return FALSE; } // get file pathname a_strPathName = dlg.GetPathName(); } // file pathname m_strPathName = a_strPathName; if (!GetXrayList(fldId)) { //LogTrace(__FILE__, __LINE__, _T("Get X-ray list of field %d failed."), fldId); return FALSE; } // ok, return TRUE return TRUE; } BOOL CPosXrayFileMgr::Save() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString a_strPathName = m_strPathName; // check file pathname a_strPathName.Trim(); if (a_strPathName.IsEmpty()) { // file save as dialog CFileDialog dlg(FALSE, POS_XRAY_FILE_EXT, NULL, OFN_OVERWRITEPROMPT, POS_XRAY_FILE_FILTER); if (dlg.DoModal() != IDOK) { return FALSE; } // get file pathname a_strPathName = dlg.GetPathName(); } // file pathname m_strPathName = a_strPathName; if (!SaveXrayList()) { LogErrorTrace(__FILE__, __LINE__, _T("Get X-ray list failed.")); return FALSE; } // ok, return TRUE return TRUE; } // check if a xray containing any element of the elements list BOOL CPosXrayFileMgr::IsXrayContainElements(CPosXrayPtr a_pXray, CElementsList& a_listElements, BOOL& a_bResult) { // safety check ASSERT(a_pXray); if (!a_pXray) { // invalid x-ray pointer LogErrorTrace(__FILE__, __LINE__, _T("IsXrayContainElements: invalid x-ray pointer.")); return FALSE; } // get peak list of the x-ray COTSPeakList a_listPeaks; if (!CPosXrayFileMgr::GetPeaksList(a_pXray, a_listPeaks)) { // failed to get peaks list of x-ray LogErrorTrace(__FILE__, __LINE__, _T("IsXrayContainElements: failed to call GetPeaksList method.")); return FALSE; } // x-ray has no peaks if (a_listPeaks.empty()) { // x-ray has no peaks means that this x-ray data is empty, result set to FALSE. a_bResult = FALSE; } else if (a_listElements.empty()) { // result set to TRUE if element list is empty a_bResult = TRUE; } else { for (auto pElement : a_listElements) { // check if the peaks list contains peaks of the element a_bResult = TRUE; } } // ok, return TRUE return TRUE; } // CPosXrayFileMgr::get peaks list of a x-ray BOOL CPosXrayFileMgr::GetPeaksList(CPosXrayPtr a_pXray, COTSPeakList& a_listPeaks) { // safety check ASSERT(a_pXray); if (!a_pXray) { // invalid x-ray pointer LogErrorTrace(__FILE__, __LINE__, _T("GetPeaksList: invalid x-ray pointer.")); return FALSE; } // clear list a_listPeaks.clear(); DWORD* nXrayData; DWORD* nXrayDataOld; nXrayData = new DWORD[GENERALXRAYCHANNELS]; nXrayDataOld = new DWORD[GENERALXRAYCHANNELS]; DWORD* nXrayDataSrc = a_pXray->GetXrayData(); // copy data memcpy(nXrayData, nXrayDataSrc, sizeof(DWORD)*GENERALXRAYCHANNELS); memcpy(nXrayDataOld, nXrayDataSrc, sizeof(DWORD)*GENERALXRAYCHANNELS); // find max value DWORD nMax = nXrayData[0]; for (unsigned int i = 0; i < GENERALXRAYCHANNELS; i++) { if (nXrayData[i] > nMax) nMax = nXrayData[i]; } // set threshold DWORD nThreshold = (DWORD)(nMax * 0.1 + 0.5); for (unsigned int i = 0; i < GENERALXRAYCHANNELS; i++) { if (nXrayData[i] > nThreshold) { nXrayData[i] = nMax; } else { nXrayData[i] = 0; } } // find range std::vector listUp; std::vector listDown; listUp.clear(); for(int i = 0; i < GENERALXRAYCHANNELS - 1; i++) { if (nXrayData[i] == 0 && nXrayData[i + 1] == nMax) listUp.push_back(i); } listDown.clear(); for (int i = 1; i < GENERALXRAYCHANNELS; i++) { if (nXrayData[i] == nMax && nXrayData[i + 1] == 0) listDown.push_back(i); } // find peak if (listUp.size() == listDown.size()) { if (listUp[0] > listDown[0]) { listUp.erase(listUp.begin()); listDown.erase(listDown.end()); } } else if ((int)listUp.size() == ((int)listDown.size() + 1)) { listUp.erase(listUp.end()); } else if ((int)listDown.size() == ((int)listUp.size() + 1)) { listDown.erase(listDown.begin()); } if (listUp.size() != listDown.size()) { LogErrorTrace(__FILE__, __LINE__, _T("Can't fix the range.")); return FALSE; } int nLength = (int)listUp.size(); for (unsigned int i = 0; i < nLength; i++) { COTSPeakPtr pPeak = COTSPeakPtr(new COTSPeak()); CIntRange oIntRang; oIntRang.SetEnd(listDown[i]); oIntRang.SetStart(listUp[i]); pPeak->SetRange(oIntRang); // record the last max position DWORD nMaxTemp = *(nXrayDataOld + listUp[i]); int nPos; for (int p = (int)listUp[i]; p < (int)listDown[i]; p++) { if (nXrayDataOld[p] > nMaxTemp) { nMaxTemp = nXrayDataOld[p]; nPos = p; } } pPeak->SetHeight(nMaxTemp); pPeak->SetPosition(nPos); a_listPeaks.push_back(pPeak); } delete[]nXrayData; delete[]nXrayDataOld; // ok, return TRUE return TRUE; } void CPosXrayFileMgr::SetPosXrayList(CPosXrayList& a_listPosXray, BOOL a_bClear) { // clear holes list if necessary if (a_bClear) { m_listPosXray.clear(); } // copy the list for (auto pPosXray : a_listPosXray) { m_listPosXray.push_back(pPosXray); } } BOOL CPosXrayFileMgr::GetXrayList(int fldId) { //get x-ray info list CPosXrayList listInfo; listInfo.clear(); if (!GetXrayInfoList(listInfo,fldId)) { LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray info failed.")); return FALSE; } if (listInfo.empty()) { return FALSE; } for (auto pInfo : listInfo) { //get x-ray data CPosXrayPtr pXray = CPosXrayPtr(new CPosXray()); pXray->SetIndex(pInfo->GetIndex()); pXray->SetPartTagId(pInfo->GetPartTagId()); pXray->SetPosition(pInfo->GetPosition()); pXray->SetScanFieldId(pInfo->GetScanFieldId()); pXray->SetFeatureId(pInfo->GetFeatureId()); const long a_nXrayId = pInfo->GetIndex(); const long a_nFieldId = pInfo->GetScanFieldId(); if (!GetXrayData(a_nXrayId, a_nFieldId, pXray)) { LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray data failed.")); return FALSE; } //get element list if (m_bHasElement) { long nElementSize = pInfo->GetElementNum(); if (nElementSize == 0) { m_listPosXray.push_back(pXray); continue; } CElementChemistriesList listElementChemistry; if (!GetElementChemistry(a_nXrayId, a_nFieldId, nElementSize, listElementChemistry)) { LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray data failed.")); return FALSE; } pXray->SetElementQuantifyData(listElementChemistry); } m_listPosXray.push_back(pXray); } return TRUE; } BOOL CPosXrayFileMgr::SaveXrayList() { if (!m_listPosXray.empty()) { auto XrayDataDB = GetXrayDataDB(); if (!XrayDataDB) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table")); ASSERT(FALSE); return FALSE; } auto XElementChemistryDB = GetElementChemistryDB(); if (!XElementChemistryDB) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to open element chemistry table")); ASSERT(FALSE); return FALSE; } XrayDataDB->GetDatastore()->CloseSynchronous(); XrayDataDB->GetDatastore()->BeginTransaction(); //save info list SaveXrayInfoList(); for (auto pPosXray : m_listPosXray) { if (!XrayDataDB->SavePosXrayPtr(pPosXray)) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to save x-ray data.")); return FALSE; } //save element if (m_bHasElement) { if (!XElementChemistryDB->SaveElementChemistriesList(pPosXray)) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to save element chemistry list data.")); return FALSE; } } } XrayDataDB->GetDatastore()->CommitTransaction(); } return TRUE; } BOOL CPosXrayFileMgr::SaveXrayInfoList() { auto XrayInfoDB = GetXrayInfoDB(); if (!XrayInfoDB) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table")); ASSERT(FALSE); return FALSE; } if (m_listPosXray.empty()) { LogErrorTrace(__FILE__, __LINE__, _T("current xray info is empty.")); return FALSE; } if (!XrayInfoDB->SaveXrayInfoList(m_listPosXray)) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to save xray info list.")); return FALSE; } return TRUE; } //Get XrayInfoList BOOL CPosXrayFileMgr::GetXrayInfoList(CPosXrayList& a_listXray,int fldId) { auto XrayInfoDB = GetXrayInfoDB(); if (!XrayInfoDB) { LogErrorTrace(__FILE__,__LINE__,_T("Failed to open result setting table")); ASSERT(FALSE); return FALSE; } a_listXray = XrayInfoDB->GetXrayInfoListByFieldId(fldId); return TRUE; } BOOL CPosXrayFileMgr::GetXrayData(const long a_nXrayId, const long a_nFieldId, CPosXrayPtr a_pPosXray) { ASSERT(a_pPosXray); if (!a_pPosXray) { LogErrorTrace(__FILE__, __LINE__, _T("Invalid x-ray point.")); return FALSE; } auto XrayDataDB = GetXrayDataDB(); if (!XrayDataDB) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table")); ASSERT(FALSE); return FALSE; } CPosXrayPtr pPosXray = XrayDataDB->GetXRayDataById(a_nXrayId, a_nFieldId); a_pPosXray->SetXrayData(pPosXray->GetXrayData()); return TRUE; } BOOL CPosXrayFileMgr::GetElementChemistry(const long a_nXrayId, const long a_nFieldId, const long a_nElementSize, CElementChemistriesList& a_listElementChemistry) { auto XElementChemistryDB = GetElementChemistryDB(); if (!XElementChemistryDB) { LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table")); ASSERT(FALSE); return FALSE; } a_listElementChemistry.clear(); a_listElementChemistry = XElementChemistryDB->GetElementChemistryListById(a_nXrayId, a_nFieldId, a_nElementSize); return TRUE; } CXRayDataDBPtr CPosXrayFileMgr::GetXrayDataDB() { if (!m_pXrayDataDB) { auto datastorePtr = GetDatastore(); if (datastorePtr) { m_pXrayDataDB = std::make_shared(datastorePtr); } } ASSERT(m_pXrayDataDB); return m_pXrayDataDB; } CElementChemistryDBPtr CPosXrayFileMgr::GetElementChemistryDB() { if (!m_pElementChemistryDB) { auto datastorePtr = GetDatastore(); if (datastorePtr) { m_pElementChemistryDB = std::make_shared(datastorePtr); } } ASSERT(m_pElementChemistryDB); return m_pElementChemistryDB; } CPosXrayInfoDBPtr CPosXrayFileMgr::GetXrayInfoDB() { if (!m_pXrayInfoDB) { auto datastorePtr = GetDatastore(); if (datastorePtr) { m_pXrayInfoDB = std::make_shared(datastorePtr); } } ASSERT(m_pXrayInfoDB); return m_pXrayInfoDB; } // cleanup void CPosXrayFileMgr::Cleanup() { // need to do nothing at the moment m_listPosXray.clear(); } // initialization void CPosXrayFileMgr::Init() { // initialization m_listPosXray.clear(); if (!CreateXrayFile()) { ASSERT(false); } } // duplication void CPosXrayFileMgr::Duplicate(const CPosXrayFileMgr& a_oSource) { // initialization m_listPosXray.clear(); // copy data over for (auto pPosXray : a_oSource.m_listPosXray) { CPosXrayPtr pPosXrayNew = CPosXrayPtr(new CPosXray(*pPosXray.get())); m_listPosXray.push_back(pPosXrayNew); } } }