PosXrayFileMgr.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. #pragma once
  2. #include "stdafx.h"
  3. #include "PosXrayFileMgr.h"
  4. #include "OTSFileSys.h"
  5. #include "OTSHelper.h"
  6. namespace OTSMODEL {
  7. //using namespace OTSTools;
  8. // project file extension
  9. const CString POS_XRAY_FILE_EXT = _T("db");
  10. // project file filter
  11. const CString POS_XRAY_FILE_FILTER = _T("Position X-ray Files (*.db)|*.db|All Files (*.*)|*.*||");
  12. // constructor
  13. CPosXrayFileMgr::CPosXrayFileMgr(CString fileName)
  14. {
  15. // initialization
  16. m_strPathName = fileName;
  17. Init();
  18. }
  19. // destructor
  20. CPosXrayFileMgr::~CPosXrayFileMgr()
  21. {
  22. // cleanup
  23. Cleanup();
  24. //delete m_listPosXray;
  25. }
  26. // public
  27. BOOL CPosXrayFileMgr::CreateXrayFile()
  28. {
  29. // check file name
  30. m_strPathName.Trim();
  31. if (m_strPathName.IsEmpty())
  32. {
  33. // error, wrong file name
  34. LogErrorTrace(__FILE__,__LINE__,_T("Empty file path name"));
  35. ASSERT(FALSE);
  36. return FALSE;
  37. }
  38. // get database name
  39. CString sDatabaseName = GetPathName();
  40. if (COTSFileSys::Exists(sDatabaseName))
  41. {
  42. if (!Open(m_strPathName, FALSE))
  43. {
  44. LogErrorTrace(__FILE__, __LINE__, _T("Open X-ray file failed."));
  45. ASSERT(FALSE);
  46. return FALSE;
  47. }
  48. }
  49. else
  50. {
  51. if (!Create(m_strPathName))
  52. {
  53. LogErrorTrace(__FILE__, __LINE__, _T("Create X-ray file failed."));
  54. ASSERT(FALSE);
  55. return FALSE;
  56. }
  57. }
  58. return TRUE;
  59. }
  60. // Load/Save
  61. BOOL CPosXrayFileMgr::Load(int fldId,CString a_strPathName /*= _T("")*/, BOOL a_bClear /*= TRUE*/)
  62. {
  63. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  64. // clear all data if necessary
  65. if (a_bClear)
  66. {
  67. Init();
  68. }
  69. // check file pathname
  70. a_strPathName.Trim();
  71. if (a_strPathName.IsEmpty())
  72. {
  73. // file open dialog
  74. CFileDialog dlg(TRUE, POS_XRAY_FILE_EXT, NULL, OFN_FILEMUSTEXIST, POS_XRAY_FILE_FILTER);
  75. if (dlg.DoModal() != IDOK)
  76. {
  77. return FALSE;
  78. }
  79. // get file pathname
  80. a_strPathName = dlg.GetPathName();
  81. }
  82. // file pathname
  83. m_strPathName = a_strPathName;
  84. if (!GetXrayList(fldId))
  85. {
  86. //LogTrace(__FILE__, __LINE__, _T("Get X-ray list of field %d failed."), fldId);
  87. return FALSE;
  88. }
  89. // ok, return TRUE
  90. return TRUE;
  91. }
  92. BOOL CPosXrayFileMgr::Save(CString a_strPathName /*= _T("")*/)
  93. {
  94. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  95. // check file pathname
  96. a_strPathName.Trim();
  97. if (a_strPathName.IsEmpty())
  98. {
  99. // file save as dialog
  100. CFileDialog dlg(FALSE, POS_XRAY_FILE_EXT, NULL, OFN_OVERWRITEPROMPT, POS_XRAY_FILE_FILTER);
  101. if (dlg.DoModal() != IDOK)
  102. {
  103. return FALSE;
  104. }
  105. // get file pathname
  106. a_strPathName = dlg.GetPathName();
  107. }
  108. // file pathname
  109. m_strPathName = a_strPathName;
  110. if (!SaveXrayList())
  111. {
  112. LogErrorTrace(__FILE__, __LINE__, _T("Get X-ray list failed."));
  113. return FALSE;
  114. }
  115. // ok, return TRUE
  116. return TRUE;
  117. }
  118. // check if a xray containing any element of the elements list
  119. BOOL CPosXrayFileMgr::IsXrayContainElements(CPosXrayPtr a_pXray, CElementsList& a_listElements, BOOL& a_bResult)
  120. {
  121. // safety check
  122. ASSERT(a_pXray);
  123. if (!a_pXray)
  124. {
  125. // invalid x-ray pointer
  126. LogErrorTrace(__FILE__, __LINE__, _T("IsXrayContainElements: invalid x-ray pointer."));
  127. return FALSE;
  128. }
  129. // get peak list of the x-ray
  130. COTSPeakList a_listPeaks;
  131. if (!CPosXrayFileMgr::GetPeaksList(a_pXray, a_listPeaks))
  132. {
  133. // failed to get peaks list of x-ray
  134. LogErrorTrace(__FILE__, __LINE__, _T("IsXrayContainElements: failed to call GetPeaksList method."));
  135. return FALSE;
  136. }
  137. // x-ray has no peaks
  138. if (a_listPeaks.empty())
  139. {
  140. // x-ray has no peaks means that this x-ray data is empty, result set to FALSE.
  141. a_bResult = FALSE;
  142. }
  143. else if (a_listElements.empty())
  144. {
  145. // result set to TRUE if element list is empty
  146. a_bResult = TRUE;
  147. }
  148. else
  149. {
  150. for (auto pElement : a_listElements)
  151. {
  152. // check if the peaks list contains peaks of the element
  153. a_bResult = TRUE;
  154. }
  155. }
  156. // ok, return TRUE
  157. return TRUE;
  158. }
  159. // CPosXrayFileMgr::get peaks list of a x-ray
  160. BOOL CPosXrayFileMgr::GetPeaksList(CPosXrayPtr a_pXray, COTSPeakList& a_listPeaks)
  161. {
  162. // safety check
  163. ASSERT(a_pXray);
  164. if (!a_pXray)
  165. {
  166. // invalid x-ray pointer
  167. LogErrorTrace(__FILE__, __LINE__, _T("GetPeaksList: invalid x-ray pointer."));
  168. return FALSE;
  169. }
  170. // clear list
  171. a_listPeaks.clear();
  172. DWORD* nXrayData;
  173. DWORD* nXrayDataOld;
  174. nXrayData = new DWORD[GENERALXRAYCHANNELS];
  175. nXrayDataOld = new DWORD[GENERALXRAYCHANNELS];
  176. DWORD* nXrayDataSrc = a_pXray->GetXrayData();
  177. // copy data
  178. memcpy(nXrayData, nXrayDataSrc, sizeof(DWORD)*GENERALXRAYCHANNELS);
  179. memcpy(nXrayDataOld, nXrayDataSrc, sizeof(DWORD)*GENERALXRAYCHANNELS);
  180. // find max value
  181. DWORD nMax = nXrayData[0];
  182. for (unsigned int i = 0; i < GENERALXRAYCHANNELS; i++)
  183. {
  184. if (nXrayData[i] > nMax)
  185. nMax = nXrayData[i];
  186. }
  187. // set threshold
  188. DWORD nThreshold = (DWORD)(nMax * 0.1 + 0.5);
  189. for (unsigned int i = 0; i < GENERALXRAYCHANNELS; i++)
  190. {
  191. if (nXrayData[i] > nThreshold)
  192. {
  193. nXrayData[i] = nMax;
  194. }
  195. else
  196. {
  197. nXrayData[i] = 0;
  198. }
  199. }
  200. // find range
  201. std::vector<DWORD> listUp;
  202. std::vector<DWORD> listDown;
  203. listUp.clear();
  204. for(int i = 0; i < GENERALXRAYCHANNELS - 1; i++)
  205. {
  206. if (nXrayData[i] == 0 && nXrayData[i + 1] == nMax)
  207. listUp.push_back(i);
  208. }
  209. listDown.clear();
  210. for (int i = 1; i < GENERALXRAYCHANNELS; i++)
  211. {
  212. if (nXrayData[i] == nMax && nXrayData[i + 1] == 0)
  213. listDown.push_back(i);
  214. }
  215. // find peak
  216. if (listUp.size() == listDown.size())
  217. {
  218. if (listUp[0] > listDown[0])
  219. {
  220. listUp.erase(listUp.begin());
  221. listDown.erase(listDown.end());
  222. }
  223. }
  224. else if ((int)listUp.size() == ((int)listDown.size() + 1))
  225. {
  226. listUp.erase(listUp.end());
  227. }
  228. else if ((int)listDown.size() == ((int)listUp.size() + 1))
  229. {
  230. listDown.erase(listDown.begin());
  231. }
  232. if (listUp.size() != listDown.size())
  233. {
  234. LogErrorTrace(__FILE__, __LINE__, _T("Can't fix the range."));
  235. return FALSE;
  236. }
  237. int nLength = (int)listUp.size();
  238. for (unsigned int i = 0; i < nLength; i++)
  239. {
  240. COTSPeakPtr pPeak = COTSPeakPtr(new COTSPeak());
  241. CIntRange oIntRang;
  242. oIntRang.SetEnd(listDown[i]);
  243. oIntRang.SetStart(listUp[i]);
  244. pPeak->SetRange(oIntRang);
  245. // record the last max position
  246. DWORD nMaxTemp = *(nXrayDataOld + listUp[i]);
  247. int nPos;
  248. for (int p = (int)listUp[i]; p < (int)listDown[i]; p++)
  249. {
  250. if (nXrayDataOld[p] > nMaxTemp)
  251. {
  252. nMaxTemp = nXrayDataOld[p];
  253. nPos = p;
  254. }
  255. }
  256. pPeak->SetHeight(nMaxTemp);
  257. pPeak->SetPosition(nPos);
  258. a_listPeaks.push_back(pPeak);
  259. }
  260. delete[]nXrayData;
  261. delete[]nXrayDataOld;
  262. // ok, return TRUE
  263. return TRUE;
  264. }
  265. void CPosXrayFileMgr::SetPosXrayList(CPosXraysList& a_listPosXray, BOOL a_bClear)
  266. {
  267. // clear holes list if necessary
  268. if (a_bClear)
  269. {
  270. m_listPosXray.clear();
  271. }
  272. // copy the list
  273. for (auto pPosXray : a_listPosXray)
  274. {
  275. m_listPosXray.push_back(pPosXray);
  276. }
  277. }
  278. BOOL CPosXrayFileMgr::GetXrayList(int fldId)
  279. {
  280. //get x-ray info list
  281. CPosXrayInfoList listInfo;
  282. listInfo.clear();
  283. if (!GetXrayInfoList(listInfo,fldId))
  284. {
  285. LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray info failed."));
  286. return FALSE;
  287. }
  288. if (listInfo.empty())
  289. {
  290. return FALSE;
  291. }
  292. for (auto pInfo : listInfo)
  293. {
  294. //get x-ray data
  295. CPosXrayPtr pXray = CPosXrayPtr(new CPosXray());
  296. pXray->SetIndex(pInfo->GetIndex());
  297. pXray->SetPartTagId(pInfo->GetPartTagId());
  298. pXray->SetPosition(pInfo->GetPosition());
  299. pXray->SetScanFieldId(pInfo->GetScanFieldId());
  300. pXray->SetFeatureId(pInfo->GetFeatureId());
  301. const long a_nXrayId = pInfo->GetIndex();
  302. const long a_nFieldId = pInfo->GetScanFieldId();
  303. if (!GetXrayData(a_nXrayId, a_nFieldId, pXray))
  304. {
  305. LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray data failed."));
  306. return FALSE;
  307. }
  308. //get element list
  309. if (m_bHasElement)
  310. {
  311. long nElementSize = pInfo->GetElementNum();
  312. if (nElementSize == 0)
  313. {
  314. m_listPosXray.push_back(pXray);
  315. continue;
  316. }
  317. CElementChemistriesList listElementChemistry;
  318. if (!GetElementChemistry(a_nXrayId, a_nFieldId, nElementSize, listElementChemistry))
  319. {
  320. LogErrorTrace(__FILE__, __LINE__, _T("GetXrayList: get x-ray data failed."));
  321. return FALSE;
  322. }
  323. pXray->SetElementQuantifyData(listElementChemistry);
  324. }
  325. m_listPosXray.push_back(pXray);
  326. }
  327. return TRUE;
  328. }
  329. BOOL CPosXrayFileMgr::SaveXrayList()
  330. {
  331. if (!m_listPosXray.empty())
  332. {
  333. auto XrayDataDB = GetXrayDataDB();
  334. if (!XrayDataDB)
  335. {
  336. LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table"));
  337. ASSERT(FALSE);
  338. return FALSE;
  339. }
  340. auto XElementChemistryDB = GetElementChemistryDB();
  341. if (!XElementChemistryDB)
  342. {
  343. LogErrorTrace(__FILE__, __LINE__, _T("Failed to open element chemistry table"));
  344. ASSERT(FALSE);
  345. return FALSE;
  346. }
  347. XrayDataDB->GetDatastore()->CloseSynchronous();
  348. XrayDataDB->GetDatastore()->BeginTransaction();
  349. //save info list
  350. SaveXrayInfoList();
  351. for (auto pPosXray : m_listPosXray)
  352. {
  353. if (!XrayDataDB->SavePosXrayPtr(pPosXray))
  354. {
  355. LogErrorTrace(__FILE__, __LINE__, _T("Failed to save x-ray data."));
  356. return FALSE;
  357. }
  358. //save element
  359. if (m_bHasElement)
  360. {
  361. if (!XElementChemistryDB->SaveElementChemistriesList(pPosXray))
  362. {
  363. LogErrorTrace(__FILE__, __LINE__, _T("Failed to save element chemistry list data."));
  364. return FALSE;
  365. }
  366. }
  367. }
  368. XrayDataDB->GetDatastore()->CommitTransaction();
  369. }
  370. return TRUE;
  371. }
  372. BOOL CPosXrayFileMgr::SaveXrayInfoList()
  373. {
  374. auto XrayInfoDB = GetXrayInfoDB();
  375. if (!XrayInfoDB)
  376. {
  377. LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table"));
  378. ASSERT(FALSE);
  379. return FALSE;
  380. }
  381. if (m_listPosXray.empty())
  382. {
  383. LogErrorTrace(__FILE__, __LINE__, _T("current xray info is empty."));
  384. return FALSE;
  385. }
  386. if (!XrayInfoDB->SaveXrayInfoList(m_listPosXray))
  387. {
  388. LogErrorTrace(__FILE__, __LINE__, _T("Failed to save xray info list."));
  389. return FALSE;
  390. }
  391. return TRUE;
  392. }
  393. //Get XrayInfoList
  394. BOOL CPosXrayFileMgr::GetXrayInfoList(CPosXrayInfoList& a_listXray,int fldId)
  395. {
  396. auto XrayInfoDB = GetXrayInfoDB();
  397. if (!XrayInfoDB)
  398. {
  399. LogErrorTrace(__FILE__,__LINE__,_T("Failed to open result setting table"));
  400. ASSERT(FALSE);
  401. return FALSE;
  402. }
  403. a_listXray = XrayInfoDB->GetXrayInfoListByFieldId(fldId);
  404. return TRUE;
  405. }
  406. BOOL CPosXrayFileMgr::GetXrayData(const long a_nXrayId, const long a_nFieldId, CPosXrayPtr a_pPosXray)
  407. {
  408. ASSERT(a_pPosXray);
  409. if (!a_pPosXray)
  410. {
  411. LogErrorTrace(__FILE__, __LINE__, _T("Invalid x-ray point."));
  412. return FALSE;
  413. }
  414. auto XrayDataDB = GetXrayDataDB();
  415. if (!XrayDataDB)
  416. {
  417. LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table"));
  418. ASSERT(FALSE);
  419. return FALSE;
  420. }
  421. CPosXrayPtr pPosXray = XrayDataDB->GetXRayDataById(a_nXrayId, a_nFieldId);
  422. a_pPosXray->SetXrayData(pPosXray->GetXrayData());
  423. return TRUE;
  424. }
  425. BOOL CPosXrayFileMgr::GetElementChemistry(const long a_nXrayId, const long a_nFieldId, const long a_nElementSize, CElementChemistriesList& a_listElementChemistry)
  426. {
  427. auto XElementChemistryDB = GetElementChemistryDB();
  428. if (!XElementChemistryDB)
  429. {
  430. LogErrorTrace(__FILE__, __LINE__, _T("Failed to open result setting table"));
  431. ASSERT(FALSE);
  432. return FALSE;
  433. }
  434. a_listElementChemistry.clear();
  435. a_listElementChemistry = XElementChemistryDB->GetElementChemistryListById(a_nXrayId, a_nFieldId, a_nElementSize);
  436. return TRUE;
  437. }
  438. CXRayDataDBPtr CPosXrayFileMgr::GetXrayDataDB()
  439. {
  440. if (!m_pXrayDataDB)
  441. {
  442. auto datastorePtr = GetDatastore();
  443. if (datastorePtr)
  444. {
  445. m_pXrayDataDB = std::make_shared<CXRayDataDB>(datastorePtr);
  446. }
  447. }
  448. ASSERT(m_pXrayDataDB);
  449. return m_pXrayDataDB;
  450. }
  451. CElementChemistryDBPtr CPosXrayFileMgr::GetElementChemistryDB()
  452. {
  453. if (!m_pElementChemistryDB)
  454. {
  455. auto datastorePtr = GetDatastore();
  456. if (datastorePtr)
  457. {
  458. m_pElementChemistryDB = std::make_shared<CElementChemistryDB>(datastorePtr);
  459. }
  460. }
  461. ASSERT(m_pElementChemistryDB);
  462. return m_pElementChemistryDB;
  463. }
  464. CPosXrayInfoDBPtr CPosXrayFileMgr::GetXrayInfoDB()
  465. {
  466. if (!m_pXrayInfoDB)
  467. {
  468. auto datastorePtr = GetDatastore();
  469. if (datastorePtr)
  470. {
  471. m_pXrayInfoDB = std::make_shared<CPosXrayInfoDB>(datastorePtr);
  472. }
  473. }
  474. ASSERT(m_pXrayInfoDB);
  475. return m_pXrayInfoDB;
  476. }
  477. // cleanup
  478. void CPosXrayFileMgr::Cleanup()
  479. {
  480. // need to do nothing at the moment
  481. m_listPosXray.clear();
  482. }
  483. // initialization
  484. void CPosXrayFileMgr::Init()
  485. {
  486. // initialization
  487. m_listPosXray.clear();
  488. if (!CreateXrayFile())
  489. {
  490. ASSERT(false);
  491. }
  492. }
  493. // duplication
  494. void CPosXrayFileMgr::Duplicate(const CPosXrayFileMgr& a_oSource)
  495. {
  496. // initialization
  497. m_listPosXray.clear();
  498. // copy data over
  499. for (auto pPosXray : a_oSource.m_listPosXray)
  500. {
  501. CPosXrayPtr pPosXrayNew = CPosXrayPtr(new CPosXray(*pPosXray.get()));
  502. m_listPosXray.push_back(pPosXrayNew);
  503. }
  504. }
  505. }