OTSBrukerImpl.cpp 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277
  1. #include "stdafx.h"
  2. #include "OTSBrukerImpl.h"
  3. #include "3Parties\dibapi.h"
  4. #include "BrukerSPXFileMgr.h"
  5. #include "ControllerHelper.h"
  6. namespace OTSController {
  7. unsigned int DEFAULT_MAX_WAIT_TIME_COLLECT_COUNTS = 5000;
  8. const CString DllXMLFileName = "./Config/ProData/BrukerDllVersion.xml";
  9. // constructor
  10. COTSBrukerImpl::COTSBrukerImpl()
  11. : m_bInit(false)
  12. , m_psServerName()
  13. , m_bSEMInst(false)
  14. , m_bScannerInst(false)
  15. , m_bXRAyControllerInst(false)
  16. , m_psRTSpectrumBuffer()
  17. , m_nClientID(0)
  18. , m_bSEMExternal(false)
  19. , m_nSPU(FIRST_DETECTOR_ID)
  20. , m_bCloseClient(true)
  21. , m_pSpectrumHead(NULL)
  22. , m_pBrukerDllHandle()
  23. , m_bDoQuantification(false)
  24. , m_bShowQuantificationSpectrum(false)
  25. {
  26. LogTrace(__FILE__,__LINE__,_T("Bruker Implement Controller created"));
  27. }
  28. // destructor
  29. COTSBrukerImpl::~COTSBrukerImpl()
  30. {
  31. // close client if necessary
  32. if (m_bCloseClient)
  33. {
  34. CloseClient();
  35. }
  36. // memory clean
  37. m_pBrukerDllHandle.reset();
  38. m_psServerName.reset();
  39. m_psRTSpectrumBuffer.reset();
  40. LogTrace(__FILE__, __LINE__, _T("Bruker Implement Controller released."));
  41. }
  42. // COTSBrukerImpl methods
  43. // public
  44. // initialization
  45. BOOL COTSBrukerImpl::Init(CONTROL_TYPE a_nControlType, BOOL a_b32Bite /*=TRUE*/)
  46. {
  47. // method return value
  48. BOOL bRet = FALSE;
  49. // is initialized before?
  50. if (!m_bInit)
  51. {
  52. // calculate Bruker client dll name
  53. CString strBruckerDllName = "";
  54. if (this->GetLoadDllName(strBruckerDllName))
  55. {
  56. // load Bruker client dll name succeed
  57. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Init: bruker client dll name: %s"), strBruckerDllName);
  58. }
  59. else
  60. {
  61. // load Bruker client dll name failed, use default Bruker client dll name Bruker.API.Esprit2.2.dll
  62. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Init: failed to call GetLoadDllName method, use default Bruker client dll name Bruker.API.Esprit2.1.dll"));
  63. strBruckerDllName = _T("Bruker.API.Esprit2.2.dll");
  64. }
  65. // is dll opened?
  66. if (!m_pBrukerDllHandle)
  67. {
  68. // make sure Bruker dll handle clean
  69. m_pBrukerDllHandle.reset(new OTSBrukerClientDll);
  70. // load Bruker client dll
  71. m_bInit = m_pBrukerDllHandle->LoadDll(strBruckerDllName);
  72. }
  73. // load Bruker client dll OK?
  74. if (!m_bInit)
  75. {
  76. // failed to load bruker client dll
  77. AfxMessageBox(_T("当前Bruker能谱配置不能正常工作,请检查!"));
  78. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Init: failed to load Bruker Client Dll , Dll Name: %s"), strBruckerDllName);
  79. exit(0);
  80. //return bRet;
  81. }
  82. // return false if failed to call QueryServers or OpenClient methods
  83. if (!QueryServers() || !OpenClient())
  84. {
  85. return bRet;
  86. }
  87. // prepare spectra buffer
  88. if (!m_psRTSpectrumBuffer)
  89. {
  90. m_psRTSpectrumBuffer.reset(new char[(int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE]);
  91. }
  92. memset(m_psRTSpectrumBuffer.get(), 0, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE);
  93. }
  94. // initialized?
  95. if (m_bInit)
  96. {
  97. // ok, return true
  98. bRet = TRUE;
  99. // control type?
  100. switch (a_nControlType)
  101. {
  102. // SEM
  103. case CONTROL_TYPE::BRUKER_SEM:
  104. {
  105. m_bSEMInst = TRUE;
  106. }
  107. break;
  108. // scanner
  109. case CONTROL_TYPE::BRUKER_SCAN:
  110. {
  111. m_bScannerInst = TRUE;
  112. }
  113. break;
  114. // x-ray control
  115. case CONTROL_TYPE::BRUKER_XRAY:
  116. {
  117. // check detector states and set m_nSPU
  118. if (!SetSPU())
  119. {
  120. return FALSE;
  121. }
  122. m_bXRAyControllerInst = TRUE;
  123. }
  124. break;
  125. default:
  126. {
  127. // invalid control type, something wrong
  128. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Init: invalid control type."));
  129. return FALSE;
  130. }
  131. break;
  132. }
  133. }
  134. // return method return flag
  135. return bRet;
  136. }
  137. // check connection
  138. BOOL COTSBrukerImpl::CheckConnection(BOOL& a_bConnected)
  139. {
  140. // safety check
  141. ASSERT(m_pBrukerDllHandle);
  142. if (!m_pBrukerDllHandle)
  143. {
  144. // error, invalid m_pBrukerDllHandle
  145. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CheckConnection: invalid m_pBrukerDllHandle."));
  146. return FALSE;
  147. }
  148. // check connection
  149. if (m_pBrukerDllHandle->CheckConnection(m_nClientID))
  150. {
  151. // connected
  152. a_bConnected = TRUE;
  153. // ok, return true
  154. return TRUE;
  155. }
  156. else
  157. {
  158. // connection failed
  159. a_bConnected = FALSE;
  160. // get error code
  161. int nError = m_pBrukerDllHandle->GetLastReturn();
  162. // return TRUE if error code is no connection
  163. if (nError == (int)EBrukerErrorCode::ERROR_NO_CONNECTION)
  164. {
  165. // error, no hardware connected
  166. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CheckConnection: no hardware connected."));
  167. }
  168. else
  169. {
  170. // error, other connect error
  171. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CheckConnection: failed to call CheckConnection method."));
  172. }
  173. // connection has something wrong, return false
  174. return FALSE;
  175. }
  176. }
  177. // SEM functions
  178. // SEM Data (mag, KV and working distance)
  179. BOOL COTSBrukerImpl::GetSEMData(double& a_dMagnification, double& a_dHighVoltage, double& a_dWorkingDistance)
  180. {
  181. // safety check
  182. ASSERT(m_pBrukerDllHandle);
  183. if (!m_pBrukerDllHandle)
  184. {
  185. // error, invalid m_pBrukerDllHandle
  186. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetContrast: invalid m_pBrukerDllHandle."));
  187. return FALSE;
  188. }
  189. // get SEM data (mag, KV and working distance)
  190. double dMagnification, dHighVoltage, dWorkingDistance;
  191. if (!m_pBrukerDllHandle->GetSEMData(m_nClientID, &dMagnification, &dHighVoltage, &dWorkingDistance))
  192. {
  193. // failed to call get SEM data method (mag, KV and working distance)
  194. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSEMData: failed to call GetSEMBCData client id is %d"), m_nClientID);
  195. return FALSE;
  196. }
  197. a_dMagnification = dMagnification;
  198. a_dHighVoltage = dHighVoltage;
  199. a_dWorkingDistance = dWorkingDistance;
  200. // ok, return TRUE
  201. return TRUE;
  202. }
  203. BOOL COTSBrukerImpl::SetSEMData(double a_dMagnification, double a_dHighVoltage, double a_dWorkingDistance)
  204. {
  205. // bruker dll handle check
  206. ASSERT(m_pBrukerDllHandle);
  207. if (!m_pBrukerDllHandle)
  208. {
  209. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetContrast: invalid m_pBrukerDllHandle."));
  210. return FALSE;
  211. }
  212. // set SEM data (mag, KV and working distance)
  213. if (!m_pBrukerDllHandle->SetSEMData(m_nClientID, a_dMagnification, a_dHighVoltage, a_dWorkingDistance))
  214. {
  215. // failed to call set SEM data method (mag, KV and working distance)
  216. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSEMData: failed to call GetSEMBCData client id = %d"), m_nClientID);
  217. return FALSE;
  218. }
  219. // ok, return TRUE
  220. return TRUE;
  221. }
  222. // SEM BC Data (brightness and contrast)
  223. BOOL COTSBrukerImpl::GetSEMBCData(double& a_dBrightness, double& a_dContrast)
  224. {
  225. // bruker dll handle check
  226. ASSERT(m_pBrukerDllHandle);
  227. if (!m_pBrukerDllHandle)
  228. {
  229. // error, invalid m_pBrukerDllHandle
  230. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetBrightness: invalid m_pBrukerDllHandle."));
  231. return FALSE;
  232. }
  233. // get SEM data
  234. double dBrightness = 0, dContrast = 0;
  235. if (!m_pBrukerDllHandle->GetSEMBCData(m_nClientID, &dBrightness, &dContrast))
  236. {
  237. // failed to call get SEM data method
  238. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetBrightness: failed to call GetSEMBCData client id is %d"), m_nClientID);
  239. return FALSE;
  240. }
  241. a_dBrightness = dBrightness;
  242. a_dContrast = dContrast;
  243. // ok, return TRUE
  244. return TRUE;
  245. }
  246. BOOL COTSBrukerImpl::SetSEMBCData(double a_dBrightness, double a_dContrast)
  247. {
  248. // bruker dll handle check
  249. ASSERT(m_pBrukerDllHandle);
  250. if (!m_pBrukerDllHandle)
  251. {
  252. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetBrightness: invalid m_pBrukerDllHandle."));
  253. return FALSE;
  254. }
  255. // set SEM data
  256. if (!m_pBrukerDllHandle->SetSEMBCData(m_nClientID, a_dBrightness, a_dContrast))
  257. {
  258. // failed to call set SEM data method
  259. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetBrightness: failed to call SetSEMBCData client id is %d"), m_nClientID);
  260. return FALSE;
  261. }
  262. // ok, return TRUE
  263. return TRUE;
  264. }
  265. // get Probe Current
  266. BOOL COTSBrukerImpl::GetProbeCurrent(double& a_dKV)
  267. {
  268. // safety check
  269. ASSERT(m_pBrukerDllHandle);
  270. if (!m_pBrukerDllHandle)
  271. {
  272. // error, invalid m_pBrukerDllHandle
  273. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetProbeCurrent: invalid m_pBrukerDllHandle"));
  274. return FALSE;
  275. }
  276. // get Probe Current
  277. if (!m_pBrukerDllHandle->GetSEMProbeCurrent(m_nClientID, &a_dKV))
  278. {
  279. // failed to call GetSEMSpotSize method
  280. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::GetProbeCurrent: failed to call GetSEMProbeCurrent method, client id = %d", m_nClientID);
  281. return FALSE;
  282. }
  283. // ok, return TRUE
  284. return TRUE;
  285. }
  286. BOOL COTSBrukerImpl::SetProbeCurrent(double a_dKV)
  287. {
  288. // safety check
  289. ASSERT(m_pBrukerDllHandle);
  290. if (!m_pBrukerDllHandle)
  291. {
  292. // safety check
  293. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetProbeCurrent: invalid m_pBrukerDllHandle."));
  294. return FALSE;
  295. }
  296. // set Probe Current
  297. if (!m_pBrukerDllHandle->SetSEMProbeCurrent(m_nClientID, a_dKV))
  298. {
  299. // failed to call GetSEMSpotSize method
  300. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetProbeCurrent: failed to call SetSEMProbeCurrent method, client id = %d", m_nClientID);
  301. return FALSE;
  302. }
  303. // ok, return TRUE
  304. return TRUE;
  305. }
  306. // spot size
  307. BOOL COTSBrukerImpl::GetSEMSpotSize(double& a_dSpotSize)
  308. {
  309. // safety check
  310. ASSERT(m_pBrukerDllHandle);
  311. if (!m_pBrukerDllHandle)
  312. {
  313. // error, invalid m_pBrukerDllHandle
  314. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSEMSpotSize: invalid m_pBrukerDllHandle."));
  315. return FALSE;
  316. }
  317. // get spot size
  318. if (!m_pBrukerDllHandle->GetSEMSpotSize(m_nClientID, &a_dSpotSize))
  319. {
  320. // failed to call GetSEMSpotSize method
  321. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::GetSpotSize: failed to call GetSEMSpotSize method, client id = %d", m_nClientID);
  322. return FALSE;
  323. }
  324. // ok, return TRUE
  325. return TRUE;
  326. }
  327. BOOL COTSBrukerImpl::SetSEMSpotSize(double a_dSpotSize)
  328. {
  329. // safety check
  330. ASSERT(m_pBrukerDllHandle);
  331. if (!m_pBrukerDllHandle)
  332. {
  333. // error, invalid m_pBrukerDllHandle
  334. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSEMSpotSize: invalid m_pBrukerDllHandle."));
  335. return FALSE;
  336. }
  337. // set spot size
  338. if (!m_pBrukerDllHandle->SetSEMSpotSize(m_nClientID, a_dSpotSize))
  339. {
  340. // failed to call SetSEMSpotSize method
  341. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetSEMSpotSize: failed to call SetSEMSpotSize method, client id = %d", m_nClientID);
  342. return FALSE;
  343. }
  344. // ok, return TRUE
  345. return TRUE;
  346. }
  347. // stage data
  348. BOOL COTSBrukerImpl::GetSEMStageData(
  349. double& a_dPositionX,
  350. double& a_dPositionY,
  351. double& a_dPositionZ,
  352. double& a_dTilt,
  353. double& a_dRotation)
  354. {
  355. // safety check
  356. ASSERT(m_pBrukerDllHandle);
  357. if (!m_pBrukerDllHandle)
  358. {
  359. // error, invalid m_pBrukerDllHandle
  360. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSEMStageData: invalid m_pBrukerDllHandle."));
  361. return FALSE;
  362. }
  363. // get stage data
  364. double dPositionX, dPositionY, dPositionZ, dTilt, dRotation;
  365. if (!m_pBrukerDllHandle->GetSEMStageData(m_nClientID, &dPositionX, &dPositionY, &dPositionZ, &dTilt, &dRotation))
  366. {
  367. // failed to call GetSEMStageData method
  368. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::GetSEMStageData: failed to call GetSEMStageData method, client id = %d", m_nClientID);
  369. return FALSE;
  370. }
  371. a_dPositionX = dPositionX;
  372. a_dPositionY = dPositionY;
  373. a_dPositionZ = dPositionZ;
  374. a_dTilt = dTilt;
  375. a_dRotation = dRotation;
  376. // ok return TRUE
  377. return true;
  378. }
  379. BOOL COTSBrukerImpl::SetSEMStageData(
  380. double a_dPositionX,
  381. double a_dPositionY,
  382. double a_dPositionZ,
  383. double a_dTilt,
  384. double a_dRotation)
  385. {
  386. // safety check
  387. ASSERT(m_pBrukerDllHandle);
  388. if (!m_pBrukerDllHandle)
  389. {
  390. // error, invalid m_pBrukerDllHandle
  391. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSEMStageData: invalid m_pBrukerDllHandle."));
  392. return FALSE;
  393. }
  394. // set stage data
  395. if (!m_pBrukerDllHandle->SetSEMStageData(m_nClientID, a_dPositionX, a_dPositionY, a_dPositionZ, a_dTilt, a_dRotation))
  396. {
  397. // failed to call SetSEMStageData method
  398. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::GetSEMStageData: failed to call SetSEMStageData method, client id = %d", m_nClientID);
  399. return FALSE;
  400. }
  401. // ok, return TRUE
  402. return TRUE;
  403. }
  404. // external on/off
  405. BOOL COTSBrukerImpl::SetSEMExternalOn(void)
  406. {
  407. // safety check
  408. ASSERT(m_pBrukerDllHandle);
  409. if (!m_pBrukerDllHandle)
  410. {
  411. // error, invalid m_pBrukerDllHandle
  412. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSEMExternalOn: invalid m_pBrukerDllHandle."));
  413. return FALSE;
  414. }
  415. // set external on
  416. if (m_pBrukerDllHandle->SetSEMExternalOn(m_nClientID))
  417. {
  418. m_bSEMExternal = true;
  419. }
  420. else
  421. {
  422. // failed to call SetSEMExternalOn method
  423. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetSEMExternalOn: failed to call SetSEMExternalOn method, client id = %d", m_nClientID);
  424. return FALSE;
  425. }
  426. // ok, return TRUE
  427. return TRUE;
  428. }
  429. // set SEM external off
  430. // return true if success
  431. BOOL COTSBrukerImpl::SetSEMExternalOff(void)
  432. {
  433. // safety check
  434. ASSERT(m_pBrukerDllHandle);
  435. if (!m_pBrukerDllHandle)
  436. {
  437. // error, invalid m_pBrukerDllHandle
  438. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSEMExternalOff: invalid m_pBrukerDllHandle."));
  439. return FALSE;
  440. }
  441. // set external off
  442. if (m_pBrukerDllHandle->SetSEMExternalOff(m_nClientID))
  443. {
  444. m_bSEMExternal = false;
  445. }
  446. else
  447. {
  448. // failed to call SetSEMExternalOn method
  449. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetSEMExternalOff: failed to call SetSEMExternalOff method, client id = %d", m_nClientID);
  450. return FALSE;
  451. }
  452. // ok, return TRUE
  453. return TRUE;
  454. }
  455. // get scan Mode
  456. BOOL COTSBrukerImpl::GetScanMode(long& a_nScanMode)
  457. {
  458. a_nScanMode = (m_bSEMExternal) ? BRUKER_SCAN_MODE_EXTERNAL_ON : BRUKER_SCAN_MODE_EXTERNAL_OFF;
  459. return TRUE;
  460. }
  461. // set scan mode
  462. BOOL COTSBrukerImpl::SetScanMode(long a_nScanMode)
  463. {
  464. // method return flag
  465. BOOL bRet = FALSE;
  466. if (a_nScanMode == BRUKER_SCAN_MODE_EXTERNAL_OFF)
  467. {
  468. bRet = SetSEMExternalOff();
  469. }
  470. else if (!m_bSEMExternal)
  471. {
  472. bRet = SetSEMExternalOn();
  473. }
  474. // return method return flag
  475. return bRet;
  476. }
  477. // set SEM off
  478. BOOL COTSBrukerImpl::SwitchSEMOff(BOOL a_bHTValue, BOOL a_bBeamCurrent, BOOL a_bBeamBlank)
  479. {
  480. // safety check
  481. ASSERT(m_pBrukerDllHandle);
  482. if (!m_pBrukerDllHandle)
  483. {
  484. // error, invalid m_pBrukerDllHandle
  485. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SwitchSEMOff: invalid m_pBrukerDllHandle."));
  486. return FALSE;
  487. }
  488. // turn high tension off
  489. if (!a_bHTValue)
  490. {
  491. if (!m_pBrukerDllHandle->SwitchSEMOff(m_nClientID, true, false, false))
  492. {
  493. // failed to call sSwitchSEMOff method
  494. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetHTOnOff: failed to call sSwitchSEMOff (HV) method, client id = %d", m_nClientID );
  495. return FALSE;
  496. }
  497. }
  498. else if(a_bBeamCurrent)
  499. {
  500. if (!m_pBrukerDllHandle->SwitchSEMOff(m_nClientID, false, true, false))
  501. {
  502. // failed to call sSwitchSEMOff method
  503. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetHTOnOff: failed to call sSwitchSEMOff (Beam Current) method, client id = %d", m_nClientID );
  504. return FALSE;
  505. }
  506. }
  507. else if(a_bBeamBlank)
  508. {
  509. if (!m_pBrukerDllHandle->SwitchSEMOff(m_nClientID, false, false, true))
  510. {
  511. // failed to call sSwitchSEMOff method
  512. LogErrorTrace(__FILE__, __LINE__, "COTSBrukerImpl::SetHTOnOff: failed to call sSwitchSEMOff (Beam Blank) method, client id = %d", m_nClientID );
  513. return FALSE;
  514. }
  515. }
  516. // ok, return TRUE
  517. return TRUE;
  518. }
  519. // image configuration
  520. BOOL COTSBrukerImpl::ImageGetConfiguration(
  521. DWORD& a_nWidth,
  522. DWORD& a_nHeight,
  523. DWORD& a_nAverage,
  524. BYTE& a_bCh1,
  525. BYTE& a_bCh2)
  526. {
  527. // bruker dll handle check
  528. ASSERT(m_pBrukerDllHandle);
  529. if (!m_pBrukerDllHandle)
  530. {
  531. // error, invalid m_pBrukerDllHandle
  532. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ImageGetConfiguration: invalid m_pBrukerDllHandle."));
  533. return FALSE;
  534. }
  535. // get image configuration
  536. DWORD nWidth;
  537. DWORD nHeight;
  538. DWORD nAverage;
  539. BYTE bCh1;
  540. BYTE bCh2;
  541. if (!m_pBrukerDllHandle->ImageGetConfiguration(m_nClientID, &nWidth, &nHeight, &nAverage, &bCh1, &bCh2))
  542. {
  543. // failed to call ImageGetConfiguration method
  544. LogErrorTrace(__FILE__, __LINE__, "ImageGetConfiguration::ImageGetConfiguration: failed to call ImageGetConfiguration method, client id = %d", m_nClientID);
  545. return FALSE;
  546. }
  547. a_nWidth = nWidth;
  548. a_nHeight = nHeight;
  549. a_nAverage = nAverage;
  550. a_bCh1 = bCh1;
  551. a_bCh2 = bCh2;
  552. // ok, return TRUE
  553. return TRUE;
  554. }
  555. BOOL COTSBrukerImpl::ImageSetConfiguration(
  556. DWORD a_nWidth,
  557. DWORD a_nHeight,
  558. DWORD a_nAverage,
  559. BYTE a_bCh1,
  560. BYTE a_bCh2)
  561. {
  562. // safety check
  563. ASSERT(m_pBrukerDllHandle);
  564. if (!m_pBrukerDllHandle)
  565. {
  566. // error, invalid m_pBrukerDllHandle
  567. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ImageSetConfiguration: invalid m_pBrukerDllHandle."));
  568. return FALSE;
  569. }
  570. // set image configuration
  571. if (!m_pBrukerDllHandle->ImageSetConfiguration(m_nClientID, a_nWidth, a_nHeight, a_nAverage, a_bCh1, a_bCh2))
  572. {
  573. // failed to call ImageSetConfiguration method
  574. LogErrorTrace(__FILE__, __LINE__, "ImageGetConfiguration::ImageSetConfiguration: failed to call ImageSetConfiguration method, client id = %d", m_nClientID);
  575. return FALSE;
  576. }
  577. // ok, return TRUE
  578. return TRUE;
  579. }
  580. // Acquire Image
  581. CBSEImgPtr COTSBrukerImpl::AcquireImage()
  582. {
  583. try
  584. {
  585. // safety check
  586. ASSERT(m_pBrukerDllHandle);
  587. if (!m_pBrukerDllHandle)
  588. {
  589. // error invalid m_pBrukerDllHandle
  590. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage: invalid m_pBrukerDllHandle."));
  591. // return empty BES image point
  592. return CBSEImgPtr();
  593. }
  594. // set external on
  595. if (!SetSEMExternalOn())
  596. {
  597. // failed to call SetSEMExternalOn method
  598. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage: failed to call SetSEMExternalOn method."));
  599. return CBSEImgPtr();
  600. }
  601. // Get the image config so we can allocate enough memory
  602. DWORD nWidth = 0;
  603. DWORD nHeight = 0;
  604. DWORD nAverage;
  605. BYTE bCh1;
  606. BYTE bCh2;
  607. if (!ImageGetConfiguration(nWidth, nHeight, nAverage, bCh1, bCh2))
  608. {
  609. // failed to call ImageGetConfiguration method
  610. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage: failed to call ImageGetConfiguration method."));
  611. return CBSEImgPtr();
  612. }
  613. // SEM info
  614. RTImageInfoEx oImageInfo;
  615. // the buffer returned is a bitmap stream, i.e. it contains the header information as well
  616. long nImageSize = nWidth * nHeight + 20000;
  617. std::vector<BYTE> vecImage(nImageSize, 0);
  618. BYTE showProgress = false;
  619. if (!m_pBrukerDllHandle->ImageAquireImage(m_nClientID, 1, showProgress, &vecImage[0], &nImageSize, &oImageInfo))
  620. {
  621. // failed to call ImageAquireImage method
  622. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage: failed to call ImageAquireImage, client id is %d"), m_nClientID);
  623. return CBSEImgPtr();
  624. }
  625. LPBITMAPFILEHEADER pHeader = (LPBITMAPFILEHEADER)&vecImage[0];
  626. LPBITMAPINFOHEADER pInfoHeader = (LPBITMAPINFOHEADER)(pHeader + 1);
  627. LPBYTE lpb = FindDIBBits(pInfoHeader);
  628. // Bruker acquires an upside-down image. Flip the image here.
  629. CBSEImgPtr poBseImage(new CBSEImg());
  630. CRect imageRect(0, 0, nWidth, nHeight);
  631. poBseImage->SetImageRect(imageRect);
  632. poBseImage->InitImageData(nWidth, nHeight);
  633. BYTE* pImageData = poBseImage->GetImageDataPointer();
  634. // turn bInverseImage to FALSE if don't need to do flip
  635. BOOL bInverseImage = TRUE;
  636. if (bInverseImage)
  637. {
  638. // copy image upside down
  639. for (DWORD i = 0; i < nHeight; ++i)
  640. {
  641. LPBYTE pTarget = pImageData + i * nWidth;
  642. LPBYTE pSource = lpb + (nHeight - 1 - i) * nWidth;
  643. memcpy(pTarget, pSource, nWidth);
  644. }
  645. }
  646. else
  647. {
  648. long nActImageSize = nWidth * nHeight;
  649. memcpy(pImageData, lpb, nActImageSize);
  650. }
  651. // return BSE image
  652. return poBseImage;
  653. }
  654. catch (const std::exception&)
  655. {
  656. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage exception"));
  657. }
  658. finally{
  659. // turn SEM to external off
  660. if (!SetSEMExternalOff())
  661. {
  662. // failed to call SetSEMExternalOn method
  663. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::AcquireImage: failed to call SetSEMExternalOff method."));
  664. }
  665. }
  666. // error, return nullptr
  667. return nullptr;
  668. }
  669. // set image point (move beam to position)
  670. // CPoint& a_oPoint offside the image top left point (pixel)
  671. BOOL COTSBrukerImpl::ImageSetPoint(const CPoint& a_oPoint)
  672. {
  673. // safety check
  674. ASSERT(m_pBrukerDllHandle);
  675. if (!m_pBrukerDllHandle)
  676. {
  677. // error invalid m_pBrukerDllHandle
  678. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ImageSetPoint: invalid m_pBrukerDllHandle."));
  679. return FALSE;
  680. }
  681. // image set point
  682. if (!m_pBrukerDllHandle->ImageSetPoint(m_nClientID, (DWORD)a_oPoint.x, (DWORD)a_oPoint.y))
  683. {
  684. // failed to call ImageSetPoint method
  685. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ImageSetPoint: failed to call ImageSetPoint, client id is %d"), m_nClientID);
  686. return FALSE;
  687. }
  688. // ok, return TRUE
  689. return TRUE;
  690. }
  691. // x-ray functions
  692. /// get live time
  693. float COTSBrukerImpl::GetLiveTime()
  694. {
  695. // safety check
  696. ASSERT(m_pSpectrumHead);
  697. if (!m_pSpectrumHead)
  698. {
  699. // error, invalid m_pBrukerDllHandle
  700. LogErrorTrace(__FILE__, __LINE__, _T("GetLiveRealTime::ImageSetPoint: invalid m_pSpectrumHead."));
  701. return 0.0;
  702. }
  703. // NOTE: m_pSpectrumHead will set when spectra are collected and needs to be set to NULL
  704. // after live time is collected
  705. float fRet = (float)m_pSpectrumHead->LifeTime / (float)1000.0; // ms to second
  706. m_pSpectrumHead = NULL;
  707. return fRet;
  708. }
  709. BOOL COTSBrukerImpl::GetLiveRealTime(float& a_dLiveTime, float& a_dRealTime)
  710. {
  711. // safety check
  712. ASSERT(m_pSpectrumHead);
  713. if (!m_pSpectrumHead)
  714. {
  715. // error, invalid m_pSpectrumHead.
  716. LogErrorTrace(__FILE__, __LINE__, _T("GetLiveRealTime::ImageSetPoint: invalid m_pSpectrumHead."));
  717. return FALSE;
  718. }
  719. // NOTE: m_pSpectrumHead will set when spectra are collected and needs to be set to NULL
  720. // after live time is collected
  721. a_dLiveTime = (float)m_pSpectrumHead->LifeTime / (float)1000.0; // ms to second
  722. a_dRealTime = (float)m_pSpectrumHead->RealTime / (float)1000.0; // ms to second
  723. m_pSpectrumHead = NULL;
  724. // ok, return TRUE
  725. return TRUE;
  726. }
  727. // collect spectrum data
  728. // this method needs to be called after beam has been set to right position by ImageSetPoint method
  729. BOOL COTSBrukerImpl::CollectSpectrum( DWORD a_nMilliseconds, long* a_pXRayData, DWORD a_nBufferSize)
  730. {
  731. // safety check
  732. ASSERT(m_pBrukerDllHandle);
  733. if (!m_pBrukerDllHandle)
  734. {
  735. // error, invalid m_pSpectrumHead.
  736. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: invalid m_pBrukerDllHandle."));
  737. return FALSE;
  738. }
  739. // input check
  740. ASSERT(a_pXRayData);
  741. if (!(a_pXRayData))
  742. {
  743. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: invalid a_pXRayData."));
  744. return FALSE;
  745. }
  746. // set buffer to 0
  747. memset(a_pXRayData, 0, sizeof(long) * a_nBufferSize);
  748. // start x ray measurement
  749. if (!SpectrumRealTimeMeasurement(a_nMilliseconds))
  750. {
  751. // failed to call SpectrumRealTimeMeasurement method
  752. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: failed to call SpectrumRealTimeMeasurement method."));
  753. return FALSE;
  754. }
  755. if (m_bDoQuantification)
  756. {
  757. // quantify the spectrum
  758. LogInfoTrace(__FILE__,__LINE__,_T("QuantifySpectrum"));
  759. char* pcMethod = "Default";//"Default";// "Automatic";
  760. char* pcParams = "ResultType=quantification";
  761. char cResult[(int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE];
  762. memset(cResult, 0, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE);
  763. if (!QuantifySpectrum(pcMethod, pcParams, cResult, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  764. {
  765. LogErrorTrace(__FILE__,__LINE__,_T("failed to call QuantifySpectrum method"));
  766. return FALSE;
  767. }
  768. LogTrace(__FILE__,__LINE__,_T("Result: %s"), CControllerHelper::CharToString(cResult));
  769. // convert the result char to string
  770. CString strResult = CControllerHelper::CharToString(cResult);
  771. LogTrace(__FILE__, __LINE__, _T("Result: %s"), strResult);
  772. }
  773. // read spectrum
  774. if (!ReadSpectrum())
  775. {
  776. // failed to call ReadSpectrum method
  777. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: failed to call ReadSpectrum method."));
  778. return FALSE;
  779. }
  780. // copy spectrum
  781. if (!CopySpectrum(a_pXRayData, a_nBufferSize))
  782. {
  783. // failed to call CopySpectrum
  784. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: failed to call CopySpectrum method."));
  785. return FALSE;
  786. }
  787. // ok. return TRUE
  788. return TRUE;
  789. }
  790. BOOL COTSBrukerImpl::QuantifySpectrumOut(DWORD a_nMilliseconds, long* a_pXRayData, DWORD a_nBufferSize, CElementChemistriesList& a_listElementChemistries)
  791. {
  792. // safety check
  793. ASSERT(m_pBrukerDllHandle);
  794. if (!m_pBrukerDllHandle)
  795. {
  796. // error, invalid m_pBrukerDllHandle
  797. LogErrorTrace(__FILE__, __LINE__, _T("QuantifySpectrum::CollectSpectrum: invalid m_pBrukerDllHandle."));
  798. return FALSE;
  799. }
  800. // input check
  801. ASSERT(a_pXRayData);
  802. if (!(a_pXRayData))
  803. {
  804. LogErrorTrace(__FILE__, __LINE__, _T("QuantifySpectrum::CollectSpectrum: invalid a_pXRayData."));
  805. return FALSE;
  806. }
  807. // set buffer to 0
  808. memset(a_pXRayData, 0, sizeof(long) * a_nBufferSize);
  809. // start x ray measurement
  810. if (!SpectrumRealTimeMeasurement(a_nMilliseconds))
  811. {
  812. // failed to call SpectrumRealTimeMeasurement method
  813. LogErrorTrace(__FILE__, __LINE__, _T("QuantifySpectrum::CollectSpectrum: failed to call SpectrumRealTimeMeasurement method."));
  814. return FALSE;
  815. }
  816. // quantify the spectrum
  817. LogInfoTrace(__FILE__, __LINE__, _T("QuantifySpectrum"));
  818. char* pcMethod = "Default";// "Automatic";
  819. char* pcParams = "ResultType=quantification";
  820. char cResult[(int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE];
  821. memset(cResult, 0, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE);
  822. if (!QuantifySpectrum(pcMethod, pcParams, cResult, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  823. {
  824. LogErrorTrace(__FILE__, __LINE__, _T("failed to call QuantifySpectrum method"));
  825. return FALSE;
  826. }
  827. LogTrace(__FILE__, __LINE__, _T("Result: %s"), CControllerHelper::CharToString(cResult));
  828. // convert the result char to string
  829. CString strResult = CControllerHelper::CharToString(cResult);
  830. LogTrace(__FILE__, __LINE__, _T("Result: %s"), strResult);
  831. // separate the result string to element chemistry string
  832. std::vector<CString> listStrElementChemistries = CControllerHelper::SplitString(strResult, _T("\n"));
  833. for (auto strElementChemistry : listStrElementChemistries)
  834. {
  835. CElementChemistryPtr oElementChemistryData;
  836. if (GetElementChemistryData(*oElementChemistryData.get(), strElementChemistry))
  837. {
  838. a_listElementChemistries.push_back(oElementChemistryData);
  839. }
  840. }
  841. // read spectrum
  842. if (!ReadSpectrum())
  843. {
  844. // failed to call ReadSpectrum method
  845. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: failed to call ReadSpectrum method."));
  846. return FALSE;
  847. }
  848. // copy spectrum
  849. if (!CopySpectrum(a_pXRayData, a_nBufferSize))
  850. {
  851. // failed to call CopySpectrum
  852. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectSpectrum: failed to call CopySpectrum method."));
  853. return FALSE;
  854. }
  855. // ok. return TRUE
  856. return TRUE;
  857. }
  858. // quantify the spectrum in buffer
  859. BOOL COTSBrukerImpl::QuantifySpectrum(char* a_pcMethod, char* a_pcParams, char* a_pcResultBuffer, long a_nBufferSize)
  860. {
  861. // safety check
  862. ASSERT(m_pBrukerDllHandle);
  863. if (!m_pBrukerDllHandle)
  864. {
  865. // error, invalid m_pBrukerDllHandle
  866. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrum: invalid m_pBrukerDllHandle."));
  867. return FALSE;
  868. }
  869. // input check
  870. ASSERT(a_pcMethod);
  871. if (!a_pcParams)
  872. {
  873. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrum: invalid a_pcMethod."));
  874. return FALSE;
  875. }
  876. ASSERT(a_pcParams);
  877. if (!a_pcParams)
  878. {
  879. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrum: invalid a_pcParams."));
  880. return FALSE;
  881. }
  882. ASSERT(a_pcResultBuffer);
  883. if (!a_pcResultBuffer)
  884. {
  885. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrum: invalid a_pcResultBuffer."));
  886. return FALSE;
  887. }
  888. // quantify the spectrum in buffer
  889. if (!m_pBrukerDllHandle->QuantifySpectrum(m_nClientID, 1, a_pcMethod, a_pcParams, a_pcResultBuffer, a_nBufferSize))
  890. {
  891. // failed to call QuantifySpectrum method
  892. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrum:Call QuantifySpectrum failed: client id is %d."), m_nClientID);
  893. return false;
  894. }
  895. // ok. return TRUE
  896. return TRUE;
  897. }
  898. // collect x ray points (point scan)
  899. BOOL COTSBrukerImpl::CollectXRayPoints(std::vector<CPosXray*>& a_vXPoints, DWORD a_nACTimeMS)
  900. {
  901. // safety check
  902. ASSERT(m_pBrukerDllHandle);
  903. if (!m_pBrukerDllHandle)
  904. {
  905. // error, invalid m_pBrukerDllHandle
  906. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: invalid m_pBrukerDllHandle."));
  907. return FALSE;
  908. }
  909. // do nothing if points list is empty
  910. if (a_vXPoints.empty())
  911. {
  912. // points list is empty
  913. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: poits list is empty."));
  914. return TRUE;
  915. }
  916. // turn SEM to external
  917. if (!SetSEMExternalOn())
  918. {
  919. // failed to call SetSEMExternalOn method
  920. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call SetSEMExternalOn method."));
  921. return FALSE;
  922. }
  923. // create array of BrukerSegment
  924. long nCollectCount = (long)a_vXPoints.size();
  925. //boost::scoped_array<BrukerSegment> segmentArray(new BrukerSegment[nCollectCount]);
  926. BrukerSegment* segmentArray(new BrukerSegment[nCollectCount]);
  927. for (int i = 0; i < nCollectCount; ++i)
  928. {
  929. CPoint poi = a_vXPoints[i]->GetPosition();
  930. segmentArray[i].Y = poi.y;
  931. segmentArray[i].XStart = poi.x;
  932. }
  933. // ask bruker to collect a set of x ray data
  934. if (!StartPointListMeasurement(nCollectCount, segmentArray, a_nACTimeMS))
  935. {
  936. // failed to call StartPointListMeasurement method
  937. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call StartPointListMeasurement method."));
  938. return FALSE;
  939. }
  940. // get the specs for a_vXPoints
  941. if (!ReadXRayPoints(a_vXPoints, a_nACTimeMS))
  942. {
  943. // failed to call ReadXRayPoints method
  944. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call ReadXRayPoints method."));
  945. return FALSE;
  946. }
  947. delete segmentArray;
  948. // ok return TRUE
  949. return TRUE;
  950. }
  951. BOOL COTSBrukerImpl::CollectXRayPoints(CPosXraysList& a_listXrayPois, DWORD a_nACTimeMS)
  952. {
  953. // bruker dll handle check
  954. ASSERT(m_pBrukerDllHandle);
  955. if (!m_pBrukerDllHandle)
  956. {
  957. // error, invalid m_pBrukerDllHandle
  958. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: invalid m_pBrukerDllHandle."));
  959. return FALSE;
  960. }
  961. // do nothing if points list is empty
  962. if (a_listXrayPois.empty())
  963. {
  964. // points list is empty
  965. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: poits list is empty."));
  966. return TRUE;
  967. }
  968. // turn SEM to external
  969. if (!SetSEMExternalOn())
  970. {
  971. // failed to call SetSEMExternalOn method
  972. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call SetSEMExternalOn method."));
  973. return FALSE;
  974. }
  975. // create array of BrukerSegment
  976. long nCollectCount = (long)a_listXrayPois.size();
  977. //boost::scoped_array<BrukerSegment> segmentArray(new BrukerSegment[nCollectCount]);
  978. BrukerSegment* segmentArray(new BrukerSegment[nCollectCount]);
  979. for (int i = 0; i < nCollectCount; ++i)
  980. {
  981. CPoint poi = a_listXrayPois[i]->GetPosition();
  982. segmentArray[i].Y = poi.y;
  983. segmentArray[i].XStart = poi.x;
  984. }
  985. // ask bruker to collect a set of x ray data
  986. if (!StartPointListMeasurement(nCollectCount, segmentArray, a_nACTimeMS))
  987. {
  988. // failed to call StartPointListMeasurement method
  989. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call StartPointListMeasurement method."));
  990. return FALSE;
  991. }
  992. // get the specs for a_listXrayPois
  993. if (!ReadXRayPoints(a_listXrayPois, a_nACTimeMS))
  994. {
  995. // failed to call ReadXRayPoints method
  996. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call ReadXRayPoints method."));
  997. return FALSE;
  998. }
  999. delete segmentArray;
  1000. // ok return TRUE
  1001. return TRUE;
  1002. }
  1003. // collect x ray points (area scan)
  1004. BOOL COTSBrukerImpl::CollectXRayPointsByFeatures(std::vector<CPosXray*>& a_vXPoints, std::vector<std::vector<BrukerSegment>>& a_vFeatures, DWORD a_nACTimeMS)
  1005. {
  1006. // safety check
  1007. ASSERT(m_pBrukerDllHandle);
  1008. if (!m_pBrukerDllHandle)
  1009. {
  1010. // error, invalid m_pBrukerDllHandle
  1011. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: invalid m_pBrukerDllHandle."));
  1012. return FALSE;
  1013. }
  1014. // do nothing if points list is empty
  1015. if (a_vXPoints.empty())
  1016. {
  1017. // points list is empty
  1018. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: poits list is empty."));
  1019. return TRUE;
  1020. }
  1021. // lists size check
  1022. if (a_vXPoints.size() != a_vFeatures.size())
  1023. {
  1024. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures:Feature size(%d) doesn't match xray point size(%d)"), a_vFeatures.size(), a_vXPoints.size());
  1025. return FALSE;
  1026. }
  1027. // set SEM to external
  1028. if (!SetSEMExternalOn())
  1029. {
  1030. // failed to call SetSEMExternalOn method
  1031. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call SetSEMExternalOn method."));
  1032. return FALSE;
  1033. }
  1034. // create array of BrukerSegment
  1035. long nCollectCount = (long)a_vXPoints.size();
  1036. long nTotalPixelCount = 0;
  1037. // add by Jieshi 23/08/2017
  1038. /*boost::scoped_array<WORD> pixelTimes(new WORD[nCollectCount]);
  1039. boost::scoped_array<BrukerFeature> features(new BrukerFeature[nCollectCount]);*/
  1040. WORD* pixelTimes(new WORD[nCollectCount]);
  1041. BrukerFeature* features(new BrukerFeature[nCollectCount]);
  1042. std::vector<BrukerSegment> extraSegments;
  1043. for (size_t i = 0; i < a_vXPoints.size(); i++)
  1044. {
  1045. features[i].SegmentCount = (long)a_vFeatures[i].size();
  1046. if (features[i].SegmentCount > 0)
  1047. {
  1048. features[i].pSegment = &a_vFeatures[i][0];
  1049. // calculate pixel time
  1050. int nPixelCount = 0;
  1051. for (int j = 0; j < features[i].SegmentCount; j++)
  1052. {
  1053. nPixelCount += features[i].pSegment[j].XCount;
  1054. }
  1055. pixelTimes[i] = (WORD)(a_nACTimeMS * 1000 / nPixelCount);
  1056. nTotalPixelCount += nPixelCount;
  1057. }
  1058. else
  1059. {
  1060. // will generate according to the x-ray position
  1061. // this shouldn't happen
  1062. extraSegments.push_back(BrukerSegment());
  1063. extraSegments[extraSegments.size() - 1].XStart = a_vXPoints[i]->GetPosition().x;
  1064. extraSegments[extraSegments.size() - 1].Y = a_vXPoints[i]->GetPosition().y;
  1065. features[i].SegmentCount = 1;
  1066. features[i].pSegment = &extraSegments[extraSegments.size() - 1];
  1067. pixelTimes[i] = (WORD)(a_nACTimeMS * 1000);
  1068. }
  1069. }
  1070. // ask bruker to collect a set of x-ray data
  1071. if (!StartFeatureListMeasurement(nCollectCount, features, pixelTimes))
  1072. {
  1073. // failed to call StartFeatureListMeasurement method
  1074. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call StartFeatureListMeasurement method."));
  1075. return FALSE;
  1076. }
  1077. // get the specs for a_vXPoints
  1078. if (!ReadXRayPointsByFeature(a_vXPoints, a_nACTimeMS))
  1079. {
  1080. // failed to call ReadXRayPointsByFeature method
  1081. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call ReadXRayPointsByFeature method."));
  1082. return FALSE;
  1083. }
  1084. delete pixelTimes;
  1085. delete features;
  1086. // ok, return TRUE
  1087. return TRUE;
  1088. }
  1089. BOOL COTSBrukerImpl::ReadXRayPoints(std::vector<CPosXray*>& a_vXPoints, const DWORD a_nACTimeMS)
  1090. {
  1091. // Fail a_vXPoints is empty
  1092. if (a_vXPoints.empty())
  1093. {
  1094. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints Empty point list given in argument a_oPointList"));
  1095. return TRUE;
  1096. }
  1097. long nCollectCount = (long)a_vXPoints.size();
  1098. // get the specs for a_vXPoints
  1099. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  1100. for (int i = 0; i < nCollectCount; ++i)
  1101. {
  1102. // cleanup data storage
  1103. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1104. if (m_bDoQuantification)
  1105. {
  1106. // quantify the spectrum
  1107. char* pcMethod = "Default";//"Default";// "Automatic";
  1108. char* pcParams = "ResultType=quantification";
  1109. char cResult[10000];
  1110. memset(cResult, 0, 10000);
  1111. if (!m_pBrukerDllHandle->QuantifyPointListSpectrum(m_nClientID, i, pcMethod, pcParams, cResult, 10000, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  1112. {
  1113. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints failed to call QuantifyPointListSpectrum method, error code %d"), m_pBrukerDllHandle->GetLastReturn());
  1114. }
  1115. CElementChemistriesList vElement = CElement::ExtractElementChemistrys(CControllerHelper::CharToString(cResult));
  1116. }
  1117. // get spectrum data of a point
  1118. bool success = GetPointListSpectrum(i, (long*)nChannelData);
  1119. if (!success)
  1120. {
  1121. // error
  1122. CPoint poi = a_vXPoints[i]->GetPosition();
  1123. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Call GetPointListSpectrum failed : index = %d(x : %d, y : %d)"),
  1124. i,
  1125. poi.x,
  1126. poi.y);
  1127. return FALSE;
  1128. }
  1129. // set spectrum data for the x-ray point
  1130. a_vXPoints[i]->SetXrayData(nChannelData);
  1131. }
  1132. // We have seen rare instances where StartPointListMeasurement returns some unexpected empty
  1133. // spectra. (We can expect spectra to be empty if we measure in a hole due to charging in the
  1134. // BSE image, but on some occasions we see some empty spectra within areas of a measurement
  1135. // that otherwise look ok. We have no explanation for this and can't replicate it.)
  1136. // In these scenarios we want to fall back to a single point measurement to see if it will
  1137. // collect something valid.
  1138. // Only if we haven't had an actual bruker error
  1139. for (int i = 0; i < nCollectCount; ++i)
  1140. {
  1141. // check spectrum
  1142. DWORD nTatolXrayCount = a_vXPoints[i]->GetTotalCount();
  1143. if (nTatolXrayCount < 20)
  1144. {
  1145. // captured an empty spectrum
  1146. CPoint poi = a_vXPoints[i]->GetPosition();
  1147. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Collected low count spectrum(%d counts), index = %d(x:%d, y : %d) This could be caused by charging."),
  1148. nTatolXrayCount, i, poi.x, poi.y);
  1149. // try to redo x-ray collection at the position
  1150. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1151. if (!CollectOneXRayPoint(poi, a_nACTimeMS, (long*)nChannelData, (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS))
  1152. {
  1153. // error
  1154. //LogError(_T("Call CollectOneXRayPoint failed: index = %d(x:%d, y:%d)"),
  1155. // i, poi.x, poi.y);
  1156. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints: Call CollectOneXRayPoint failed: index = %d(x:%d, y:%d)"),
  1157. i, poi.x, poi.y);
  1158. return FALSE;
  1159. }
  1160. // set spectrum with new spectrum
  1161. a_vXPoints[i]->SetXrayData(nChannelData);
  1162. nTatolXrayCount = a_vXPoints[i]->GetTotalCount();
  1163. if (nTatolXrayCount < 20)
  1164. {
  1165. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum still low count (%d counts), index = %d(x:%d, y:%d.) This could be caused by charging."),
  1166. nTatolXrayCount, i, poi.x, poi.y);
  1167. }
  1168. else
  1169. {
  1170. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum collected successfully (%d counts), index = %d(x:%d, y:%d.)"),
  1171. nTatolXrayCount, i, poi.x, poi.y);
  1172. }
  1173. }
  1174. }
  1175. LogInfoTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints end"));
  1176. return TRUE;
  1177. }
  1178. BOOL COTSBrukerImpl::ReadXRayPoints(CPosXraysList& a_listXrayPois, const DWORD a_nACTimeMS)
  1179. {
  1180. // point list is empty?
  1181. if (a_listXrayPois.empty())
  1182. {
  1183. // doing nothing if point list is empty
  1184. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints: point list (a_listXrayPois) is empty"));
  1185. return TRUE;
  1186. }
  1187. long nCollectCount = (long)a_listXrayPois.size();
  1188. // get the specs for a_vXPoints
  1189. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  1190. for (int i = 0; i < nCollectCount; ++i)
  1191. {
  1192. // cleanup data storage
  1193. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1194. if (m_bDoQuantification)
  1195. {
  1196. // quantify the spectrum
  1197. char* pcMethod = "Default";//"Default";// "Automatic";
  1198. char* pcParams = "ResultType=quantification";
  1199. char cResult[10000];
  1200. memset(cResult, 0, 10000);
  1201. if (!m_pBrukerDllHandle->QuantifyPointListSpectrum(m_nClientID, i, pcMethod, pcParams, cResult, 10000, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  1202. {
  1203. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints failed to call QuantifyPointListSpectrum method, error code %d"), m_pBrukerDllHandle->GetLastReturn());
  1204. }
  1205. CElementChemistriesList vElement = CElement::ExtractElementChemistrys(CControllerHelper::CharToString(cResult));
  1206. }
  1207. // get spectrum data of a point
  1208. bool success = GetPointListSpectrum(i, (long*)nChannelData);
  1209. if (!success)
  1210. {
  1211. // error
  1212. CPoint poi = a_listXrayPois[i]->GetPosition();
  1213. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Call GetPointListSpectrum failed : index = %d(x : %d, y : %d)"),
  1214. i,
  1215. poi.x,
  1216. poi.y);
  1217. return FALSE;
  1218. }
  1219. // set spectrum data for the x-ray point
  1220. a_listXrayPois[i]->SetXrayData(nChannelData);
  1221. }
  1222. // We have seen rare instances where StartPointListMeasurement returns some unexpected empty
  1223. // spectra. (We can expect spectra to be empty if we measure in a hole due to charging in the
  1224. // BSE image, but on some occasions we see some empty spectra within areas of a measurement
  1225. // that otherwise look ok. We have no explanation for this and can't replicate it.)
  1226. // In these scenarios we want to fall back to a single point measurement to see if it will
  1227. // collect something valid.
  1228. // Only if we haven't had an actual bruker error
  1229. for (int i = 0; i < nCollectCount; ++i)
  1230. {
  1231. // check spectrum
  1232. DWORD nTatolXrayCount = a_listXrayPois[i]->GetTotalCount();
  1233. if (nTatolXrayCount < 20)
  1234. {
  1235. // captured an empty spectrum
  1236. CPoint poi = a_listXrayPois[i]->GetPosition();
  1237. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Collected low count spectrum(%d counts), index = %d(x:%d, y : %d) This could be caused by charging."),
  1238. nTatolXrayCount, i, poi.x, poi.y);
  1239. // try to redo x-ray collection at the position
  1240. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1241. if (!CollectOneXRayPoint(poi, a_nACTimeMS, (long*)nChannelData, (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS))
  1242. {
  1243. // error
  1244. //LogError(_T("Call CollectOneXRayPoint failed: index = %d(x:%d, y:%d)"),
  1245. // i, poi.x, poi.y);
  1246. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints: Call CollectOneXRayPoint failed: index = %d(x:%d, y:%d)"),
  1247. i, poi.x, poi.y);
  1248. return FALSE;
  1249. }
  1250. // set spectrum with new spectrum
  1251. a_listXrayPois[i]->SetXrayData(nChannelData);
  1252. nTatolXrayCount = a_listXrayPois[i]->GetTotalCount();
  1253. if (nTatolXrayCount < 20)
  1254. {
  1255. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum still low count (%d counts), index = %d(x:%d, y:%d.) This could be caused by charging."),
  1256. nTatolXrayCount, i, poi.x, poi.y);
  1257. }
  1258. else
  1259. {
  1260. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum collected successfully (%d counts), index = %d(x:%d, y:%d.)"),
  1261. nTatolXrayCount, i, poi.x, poi.y);
  1262. }
  1263. }
  1264. }
  1265. // ok, return true
  1266. return TRUE;
  1267. }
  1268. BOOL COTSBrukerImpl::ReadXRayPointsByFeature(std::vector<CPosXray*>& a_vXPoints, const DWORD /*a_nACTimeMS*/)
  1269. {
  1270. // point list is empty?
  1271. if (a_vXPoints.empty())
  1272. {
  1273. // doing nothing if point list is empty
  1274. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature: point list is empty"));
  1275. // ok, return true
  1276. return TRUE;
  1277. }
  1278. long nCollectCount = (long)a_vXPoints.size();
  1279. // get the specs for a_vXPoints
  1280. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  1281. for (int i = 0; i < nCollectCount; ++i)
  1282. {
  1283. // cleanup data storage
  1284. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1285. // get spectrum data of a point
  1286. bool success = GetFeatureListSpectrum(i, (long*)nChannelData);
  1287. if (!success)
  1288. {
  1289. // error
  1290. CPoint poi = a_vXPoints[i]->GetPosition();
  1291. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature:Call GetFeatureListSpectrum failed: index = %d(x:%d, y:%d)"),
  1292. i,
  1293. poi.x,
  1294. poi.y);
  1295. return FALSE;
  1296. }
  1297. // set spectrum data for the x-ray point
  1298. a_vXPoints[i]->SetXrayData(nChannelData);
  1299. }
  1300. //ok, return true
  1301. return TRUE;
  1302. }
  1303. BOOL COTSBrukerImpl::ReadXRayPointsByFeature(CPosXraysList& a_vXPoints, const DWORD a_nACTimeMS)
  1304. {
  1305. // point list is empty?
  1306. if (a_vXPoints.empty())
  1307. {
  1308. // point list is empty
  1309. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature: point list is empty"));
  1310. // ok, return true
  1311. return TRUE;
  1312. }
  1313. long nCollectCount = (long)a_vXPoints.size();
  1314. // get the specs for a_vXPoints
  1315. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  1316. for (int i = 0; i < nCollectCount; ++i)
  1317. {
  1318. // cleanup data storage
  1319. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  1320. // get spectrum data of a point
  1321. bool success = GetFeatureListSpectrum(i, (long*)nChannelData);
  1322. if (!success)
  1323. {
  1324. // error
  1325. CPoint poi = a_vXPoints[i]->GetPosition();
  1326. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature:Call GetFeatureListSpectrum failed: index = %d(x:%d, y:%d)"),
  1327. i,
  1328. poi.x,
  1329. poi.y);
  1330. return FALSE;
  1331. }
  1332. // set spectrum data for the x-ray point
  1333. a_vXPoints[i]->SetXrayData(nChannelData);
  1334. }
  1335. // ok, return true
  1336. return TRUE;
  1337. }
  1338. // protected
  1339. // query servers
  1340. BOOL COTSBrukerImpl::QueryServers(void)
  1341. {
  1342. // safety check
  1343. ASSERT(m_pBrukerDllHandle);
  1344. if (!m_pBrukerDllHandle)
  1345. {
  1346. // error, invalid m_pBrukerDllHandle
  1347. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QueryServers: invalid m_pBrukerDllHandle."));
  1348. return FALSE;
  1349. }
  1350. // query servers
  1351. long nBufferSize = (long)BRUKER_PARAM::BUF_LENGTH;
  1352. m_psServerName.reset(new char[(int)BRUKER_PARAM::BUF_LENGTH]);
  1353. memset(m_psServerName.get(), 0, nBufferSize);
  1354. if (!m_pBrukerDllHandle->QueryServers(m_psServerName.get(), nBufferSize))
  1355. {
  1356. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QueryServers: failed to call QueryServers method."));
  1357. return FALSE;
  1358. }
  1359. // ok, return TRUE
  1360. return TRUE;
  1361. }
  1362. // Open Client
  1363. // return true if success
  1364. BOOL COTSBrukerImpl::OpenClient(void)
  1365. {
  1366. // bruker dll handle check
  1367. ASSERT(m_pBrukerDllHandle);
  1368. if (!m_pBrukerDllHandle)
  1369. {
  1370. // error, invalid m_pBrukerDllHandle
  1371. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: invalid m_pBrukerDllHandle."));
  1372. return FALSE;
  1373. }
  1374. // first attempt to open client
  1375. BOOL bStartNew = FALSE;
  1376. BOOL bGUI = FALSE;
  1377. BOOL bRet = OpenClient(m_psServerName.get(), "edx", "edx", static_cast<BYTE>(bStartNew), static_cast<BYTE>(bGUI), &m_nClientID);
  1378. if (!bRet)
  1379. {
  1380. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: call OpenClient failed at the first attempt."));
  1381. }
  1382. // double check the connection if client id is zero
  1383. if (m_nClientID == 0)
  1384. {
  1385. // check if connection is OK
  1386. BOOL bConnected = FALSE;
  1387. if (!CheckConnection(bConnected))
  1388. {
  1389. // failed to check connection
  1390. return FALSE;
  1391. }
  1392. // try to open client again if there is no connection
  1393. if (!bConnected)
  1394. {
  1395. // second attempt to open client
  1396. bRet = OpenClient(m_psServerName.get(), "edx", "edx", static_cast<BYTE>(bStartNew), static_cast<BYTE>(bGUI), &m_nClientID);
  1397. if (!bRet)
  1398. {
  1399. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: call OpenClient failed at the second attempt."));
  1400. }
  1401. }
  1402. }
  1403. // return method return flag
  1404. return bRet;
  1405. }
  1406. BOOL COTSBrukerImpl::OpenClient(char* a_sServerName, char* a_sUserName, char* a_sPassword, BYTE a_nStartNew, BYTE a_bGUI, DWORD* a_nClientID)
  1407. {
  1408. // bruker dll handle check
  1409. ASSERT(m_pBrukerDllHandle);
  1410. if (!m_pBrukerDllHandle)
  1411. {
  1412. // error, invalid m_pBrukerDllHandle
  1413. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: invalid m_pBrukerDllHandle."));
  1414. return FALSE;
  1415. }
  1416. // open client
  1417. BOOL bRet = m_pBrukerDllHandle->OpenClient(a_sServerName, a_sUserName, a_sPassword, a_nStartNew, a_bGUI, a_nClientID);
  1418. if (!bRet)
  1419. {
  1420. // failed to open the client
  1421. // get error code
  1422. long nRet = m_pBrukerDllHandle->GetLastReturn();
  1423. if (nRet == -201)
  1424. {
  1425. // -201 -- there is an opened instance.
  1426. bRet = TRUE;
  1427. m_bCloseClient = FALSE; // FALSE, do not close the interface when the controller is deleted
  1428. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: client dll is in used."));
  1429. }
  1430. else
  1431. {
  1432. bRet = FALSE;
  1433. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::OpenClient: failed to open client dll."));
  1434. }
  1435. }
  1436. return bRet;
  1437. }
  1438. // check detector states and set m_nSPU // Bruker四个有一个盒子,盒子共接4个探头
  1439. BOOL COTSBrukerImpl::SetSPU(void)
  1440. {
  1441. // bruker dll handle check
  1442. ASSERT(m_pBrukerDllHandle);
  1443. if (!m_pBrukerDllHandle)
  1444. {
  1445. // error, invalid m_pBrukerDllHandle
  1446. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: invalid m_pBrukerDllHandle."));
  1447. return FALSE;
  1448. }
  1449. // combine value
  1450. long nCombineValue = 0;
  1451. BOOL bCombine = FALSE;
  1452. // check if the first detector is OK
  1453. BOOL bFirst = FALSE;
  1454. long nMaxEnergy1;
  1455. if (!CheckDetectorState(FIRST_DETECTOR_ID, bFirst, nMaxEnergy1))
  1456. {
  1457. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: failed to call CheckDetectorState method (first)."));
  1458. return FALSE;
  1459. }
  1460. if (bFirst)
  1461. {
  1462. nCombineValue = m_nSPU = FIRST_DETECTOR_COM;
  1463. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: find first."));
  1464. }
  1465. // check if the second detector is OK
  1466. BOOL bSecond = FALSE;
  1467. long nMaxEnergy2;
  1468. if (!CheckDetectorState(SECOND_DETECTOR_ID, bSecond, nMaxEnergy2))
  1469. {
  1470. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: failed to call CheckDetectorState method (second)."));
  1471. return FALSE;
  1472. }
  1473. if (bSecond)
  1474. {
  1475. m_nSPU = SECOND_DETECTOR_ID;
  1476. if (nCombineValue != 0)
  1477. {
  1478. bCombine = TRUE;
  1479. m_nSPU = FIRST_DETECTOR_ID;
  1480. }
  1481. nCombineValue += SECOND_DETECTOR_COM;
  1482. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: find second."));
  1483. }
  1484. // the third detector is OK
  1485. BOOL bThird = FALSE;
  1486. long nMaxEnergy3;
  1487. if (!CheckDetectorState(THIRD_DETECTOR_ID, bThird, nMaxEnergy3))
  1488. {
  1489. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: failed to call CheckDetectorState method (third)."));
  1490. return FALSE;
  1491. }
  1492. if (bThird)
  1493. {
  1494. m_nSPU = THIRD_DETECTOR_ID;
  1495. if (nCombineValue != 0)
  1496. {
  1497. bCombine = TRUE;
  1498. m_nSPU = FIRST_DETECTOR_ID;
  1499. }
  1500. nCombineValue += THIRD_DETECTOR_COM;
  1501. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: find third."));
  1502. }
  1503. // the fourth detector is OK
  1504. BOOL bFourth = FALSE;
  1505. long nMaxEnergy4;
  1506. if (!CheckDetectorState(FOURTH_DETECTOR_ID, bFourth, nMaxEnergy4))
  1507. {
  1508. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: failed to call CheckDetectorState method (fourth)."));
  1509. return FALSE;
  1510. }
  1511. if (bFourth)
  1512. {
  1513. m_nSPU = FOURTH_DETECTOR_ID;
  1514. if (nCombineValue != 0)
  1515. {
  1516. bCombine = TRUE;
  1517. m_nSPU = FIRST_DETECTOR_ID;
  1518. }
  1519. nCombineValue += FOURTH_DETECTOR_COM;
  1520. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: find fourth."));
  1521. }
  1522. // combine the two detectors if more than one active detectors.
  1523. BOOL bRet = FALSE;
  1524. if (bCombine)
  1525. {
  1526. bRet = m_pBrukerDllHandle->CombineSpectrometer(m_nClientID, nCombineValue);
  1527. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: find combined."));
  1528. }
  1529. else
  1530. {
  1531. bRet = (nCombineValue != 0);
  1532. if (!bRet)
  1533. {
  1534. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: no detactor."));
  1535. }
  1536. }
  1537. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetSPU: result is %d."), bRet);
  1538. // method return flag
  1539. return bRet;
  1540. }
  1541. // check detector State
  1542. BOOL COTSBrukerImpl::CheckDetectorState(long a_nDetectorId, BOOL& a_bState, long& a_nMaxEnergy)
  1543. {
  1544. // bruker dll handle check
  1545. ASSERT(m_pBrukerDllHandle);
  1546. if (!m_pBrukerDllHandle)
  1547. {
  1548. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CheckDetectorState: invalid m_pBrukerDllHandle."));
  1549. return FALSE;
  1550. }
  1551. // get spectrum configuration
  1552. DWORD nPulseThroughput;
  1553. a_bState = m_pBrukerDllHandle->GetSpectrometerConfiguration(m_nClientID, a_nDetectorId, a_nMaxEnergy, &nPulseThroughput);
  1554. // ok, return TRUE
  1555. return TRUE;
  1556. }
  1557. // Close Client
  1558. // return true if success
  1559. BOOL COTSBrukerImpl::CloseClient(void)
  1560. {
  1561. // safety check
  1562. ASSERT(m_pBrukerDllHandle);
  1563. if (!m_pBrukerDllHandle)
  1564. {
  1565. // error, invalid m_pBrukerDllHandle
  1566. LogErrorTrace(__FILE__, __LINE__, " COTSBrukerImpl::CloseClient: invalid m_pBrukerDllHandle");
  1567. return FALSE;
  1568. }
  1569. if (!m_pBrukerDllHandle->CloseClient(m_nClientID))
  1570. {
  1571. LogErrorTrace(__FILE__, __LINE__, " COTSBrukerImpl::CloseClient failed ");
  1572. return FALSE;
  1573. }
  1574. // ok, return true
  1575. return TRUE;
  1576. }
  1577. /// collect a x ray point
  1578. /// input: CPoint a_oPoi,
  1579. // DWORD a_nLifeTimeMilliSeconds,
  1580. // long* a_pXRayData,
  1581. // DWORD a_nBufferSize,
  1582. // CollectOneXRayPoint
  1583. /// return true if success
  1584. BOOL COTSBrukerImpl::CollectOneXRayPoint(
  1585. const CPoint& a_oPoi,
  1586. DWORD a_nLifeTimeMilliSeconds,
  1587. long* a_pXRayData,
  1588. DWORD a_nBufferSize,
  1589. bool a_bSetHeadStruc)
  1590. {
  1591. // move beam to the point
  1592. if (!ImageSetPoint(a_oPoi))
  1593. {
  1594. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectOneXRayPoint:Call ImageSetPoint failed: at position [%d, %d]"), a_oPoi.x, a_oPoi.y);
  1595. return FALSE;
  1596. }
  1597. // collect a x-ray
  1598. if (!CollectSpectrum(a_nLifeTimeMilliSeconds, a_pXRayData, a_nBufferSize))
  1599. {
  1600. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectOneXRayPoint:Call CollectSpectrum failed : at position[%d, %d]"), a_oPoi.x, a_oPoi.y);
  1601. return FALSE;
  1602. }
  1603. // ok, return true
  1604. return TRUE;
  1605. }
  1606. BOOL COTSBrukerImpl::StartSpectrumMeasurement()
  1607. {
  1608. // safety check
  1609. ASSERT(m_pBrukerDllHandle);
  1610. if (!m_pBrukerDllHandle)
  1611. {
  1612. // error, invalid m_pBrukerDllHandle
  1613. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartSpectrumMeasurement: invalid m_pBrukerDllHandle"));
  1614. return FALSE;
  1615. }
  1616. DWORD nRealTime = 0;
  1617. // Success?
  1618. if (!m_pBrukerDllHandle->StartSpectrumMeasurement(m_nClientID, m_nSPU, nRealTime))
  1619. {
  1620. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::::StartSpectrumMeasurement:Call StartSpectrumMeasurement failed: client id is %d"), m_nClientID);
  1621. return FALSE;
  1622. }
  1623. // ok, return true
  1624. return TRUE;
  1625. }
  1626. // call IsSpectrumMeterRunning
  1627. // return true if success
  1628. BOOL COTSBrukerImpl::IsSpectrumMeterRunning(BOOL& a_bRunning)
  1629. {
  1630. // safety check
  1631. ASSERT(m_pBrukerDllHandle);
  1632. if (!m_pBrukerDllHandle)
  1633. {
  1634. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::IsSpectrumMeterRunning:m_pBrukerDllHandle failed, return"));
  1635. return FALSE;
  1636. }
  1637. double nState;
  1638. double nPulseRate;
  1639. bool bRunning;
  1640. if (!m_pBrukerDllHandle->GetSpectrumMeasureState(m_nClientID, 1, &bRunning, &nState, &nPulseRate))
  1641. {
  1642. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::IsSpectrumMeterRunning:Call GetSpectrumMeasureState failed: client id is %d"), m_nClientID);
  1643. return FALSE;
  1644. }
  1645. a_bRunning = (BOOL)bRunning;
  1646. // ok, return true
  1647. return TRUE;
  1648. }
  1649. // call StopSpectrumMeter
  1650. // return true if success
  1651. BOOL COTSBrukerImpl::StopSpectrumMeter(void)
  1652. {
  1653. // safety check
  1654. ASSERT(m_pBrukerDllHandle);
  1655. if (!m_pBrukerDllHandle)
  1656. {
  1657. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StopSpectrumMeter:m_pBrukerDllHandle failed, return"));
  1658. return FALSE;
  1659. }
  1660. if (!m_pBrukerDllHandle->StopSpectrumMeasurement(m_nClientID, 1))
  1661. {
  1662. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StopSpectrumMeter:Call StopSpectrumMeasurement failed: client id is %d"), m_nClientID);
  1663. return FALSE;
  1664. }
  1665. // ok, return true
  1666. return TRUE;
  1667. }
  1668. BOOL COTSBrukerImpl::ReadSpectrum(long* a_pXRayData, DWORD a_nBufferSize)
  1669. {
  1670. // read spectrum
  1671. if (!ReadSpectrum())
  1672. {
  1673. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Read Spectrum failed."));
  1674. return FALSE;
  1675. }
  1676. // copy spectrum
  1677. if (!CopySpectrum(a_pXRayData, a_nBufferSize))
  1678. {
  1679. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadSpectrum:Copy Spectrum failed."));
  1680. return FALSE;
  1681. }
  1682. // ok, return true
  1683. return TRUE;
  1684. }
  1685. // get quantification method name strings (automatic only)
  1686. BOOL COTSBrukerImpl::GetQuantificationMethods(std::vector<CString>& a_vMethods)
  1687. {
  1688. // safety check
  1689. ASSERT(m_pBrukerDllHandle);
  1690. if (!m_pBrukerDllHandle)
  1691. {
  1692. // error, invalid m_pBrukerDllHandle
  1693. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetQuantificationMethods: invalid m_pBrukerDllHandle"));
  1694. return FALSE;
  1695. }
  1696. // automatic methods only
  1697. bool AUTOMATIC_ONLY = true;
  1698. // char buffer size
  1699. const long CHAR_BUFFER_SIZE = 4096 * 100;
  1700. // char buffer
  1701. char cBuffer[CHAR_BUFFER_SIZE];
  1702. long nBufferSize = CHAR_BUFFER_SIZE;
  1703. // get quantification method name strings
  1704. if (!m_pBrukerDllHandle->GetQuantificationMethods(m_nClientID, AUTOMATIC_ONLY, cBuffer, &nBufferSize))
  1705. {
  1706. LogErrorTrace(__FILE__, __LINE__, _T("Call GetQuantificationMethods failed: client id is %d"), m_nClientID);
  1707. return FALSE;
  1708. }
  1709. // get the quantification method name strings
  1710. CString strMethodsNames = CControllerHelper::CharToString(cBuffer);
  1711. LogTrace(__FILE__, __LINE__, _T("Result: %s"), strMethodsNames);
  1712. // clear the method strings list
  1713. a_vMethods.clear();
  1714. // separate the method strings
  1715. a_vMethods = CControllerHelper::SplitString(strMethodsNames, _T("\n"));
  1716. // ok, return true
  1717. return TRUE;
  1718. }
  1719. BOOL COTSBrukerImpl::QuantifyXrayPoint(CPosXray* a_pXRayPoint, CString a_strMethodName)
  1720. {
  1721. // safety check
  1722. ASSERT(m_pBrukerDllHandle);
  1723. if (!m_pBrukerDllHandle)
  1724. {
  1725. // error, invalid m_pBrukerDllHandle
  1726. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifyXrayPoint: invalid m_pBrukerDllHandle"));
  1727. return FALSE;
  1728. }
  1729. ASSERT(a_pXRayPoint);
  1730. if (!a_pXRayPoint)
  1731. {
  1732. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifyXrayPoint:x-ray point is empty, return"));
  1733. return FALSE;
  1734. }
  1735. // method name validation
  1736. a_strMethodName.Trim();
  1737. ASSERT(!a_strMethodName.IsEmpty());
  1738. if (a_strMethodName.IsEmpty())
  1739. {
  1740. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifyXrayPoint:method name is empty, return"));
  1741. return FALSE;
  1742. }
  1743. CString sFilePathName = GetQuantificationSpectrumPathName();
  1744. // export
  1745. CBrukerSPXFileMgr spxFileHelpers;
  1746. if (!spxFileHelpers.ExportXrayPoint(sFilePathName, _T("Quantification"), a_pXRayPoint))
  1747. {
  1748. LogErrorTrace(__FILE__,__LINE__,_T("Save quantification file(%s) failed."), sFilePathName);
  1749. return FALSE;
  1750. }
  1751. CElementChemistriesList vElementChemistry;
  1752. if (!QuantifySpectrumFile(sFilePathName, a_strMethodName, vElementChemistry))
  1753. {
  1754. LogErrorTrace(__FILE__,__LINE__,_T("Quantify spectrum by method %s from file(%s) failed."), a_strMethodName, sFilePathName);
  1755. return FALSE;
  1756. }
  1757. a_pXRayPoint->SetElementQuantifyData(vElementChemistry);
  1758. // ok, return true
  1759. return true;
  1760. }
  1761. BOOL COTSBrukerImpl::QuantifySpectrumFile(LPCTSTR a_sFilePathName, CString a_strMethodName, CElementChemistriesList& a_vElementChemistry)
  1762. {
  1763. // safety check
  1764. ASSERT(m_pBrukerDllHandle);
  1765. if (!m_pBrukerDllHandle)
  1766. {
  1767. // error, invalid m_pBrukerDllHandle
  1768. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifyXrayPoint: invalid m_pBrukerDllHandle"));
  1769. return FALSE;
  1770. }
  1771. ASSERT(a_sFilePathName);
  1772. if (!a_sFilePathName)
  1773. {
  1774. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::QuantifySpectrumFile:file path name is not correct, return"));
  1775. return FALSE;
  1776. }
  1777. char sPathName[MAX_PATH];
  1778. CControllerHelper::WCharToChar((const wchar_t *)a_sFilePathName, sPathName);
  1779. if (!LoadSpectrum(sPathName))
  1780. {
  1781. LogErrorTrace(__FILE__,__LINE__,_T("LoadSpectrum from file(%s) failed"), a_sFilePathName);
  1782. return FALSE;
  1783. }
  1784. LogTrace(__FILE__,__LINE__,_T("Loaded spectrum to Bruker from file %s"), a_sFilePathName);
  1785. if (m_bShowQuantificationSpectrum)
  1786. {
  1787. ShowSpectrum(0, "Quantification");
  1788. }
  1789. char cMethod[(int)BRUKER_PARAM::BUF_LENGTH];
  1790. CControllerHelper::WCharToChar((const wchar_t *)&a_strMethodName, cMethod);
  1791. char* pcParams = "ResultType=quantification";
  1792. char cResult[(int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE];
  1793. memset(cResult, 0, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE);
  1794. LogTrace(__FILE__,__LINE__,_T("To QuantifySpectrum"));
  1795. if (!m_pBrukerDllHandle->QuantifySpectrum(m_nClientID, 0, cMethod, pcParams, cResult, (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  1796. {
  1797. LogErrorTrace(__FILE__,__LINE__,_T("Call QuantifySpectrum failed: client id is %d."), m_nClientID);
  1798. return FALSE;
  1799. }
  1800. // convert the result char to string
  1801. CString strResult = CControllerHelper::CharToString(cResult);
  1802. LogTrace(__FILE__,__LINE__,_T("Result: %s"), strResult);
  1803. // separate the result string to element chemistry string
  1804. std::vector<CString> vElementChemistryStrings = CControllerHelper::SplitString(strResult, _T("\n"));
  1805. for (auto& strElementChemistry : vElementChemistryStrings)
  1806. {
  1807. CElementChemistryPtr oElementChemistryData;
  1808. if (GetElementChemistryData(*oElementChemistryData.get(), strElementChemistry))
  1809. {
  1810. a_vElementChemistry.push_back(oElementChemistryData);
  1811. }
  1812. }
  1813. // ok, return true
  1814. return TRUE;
  1815. }
  1816. RTSpectrumHeaderRec* COTSBrukerImpl::GetSectrumHeader()
  1817. {
  1818. // safety check
  1819. ASSERT(m_psRTSpectrumBuffer);
  1820. if (!m_psRTSpectrumBuffer)
  1821. {
  1822. // error, invalid m_psRTSpectrumBuffer
  1823. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSectrumHeader: invalid m_psRTSpectrumBuffer"));
  1824. // return nullptr
  1825. return nullptr;
  1826. }
  1827. return (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get();
  1828. }
  1829. // call GetSpectrum
  1830. // return true if success
  1831. BOOL COTSBrukerImpl::GetSpectrum(long a_nBufferIndex, RTSpectrumHeaderRec*a_poSpcHR, long a_nBufferSize)
  1832. {
  1833. // safety check
  1834. ASSERT(m_pBrukerDllHandle);
  1835. if (!m_pBrukerDllHandle)
  1836. {
  1837. // error, invalid m_pBrukerDllHandle
  1838. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSpectrum: invalid m_pBrukerDllHandle"));
  1839. return FALSE;
  1840. }
  1841. if (!m_pBrukerDllHandle->GetSpectrum(m_nClientID, a_nBufferIndex, a_poSpcHR, a_nBufferSize))
  1842. {
  1843. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSpectrum:Call GetSpectrum failed: client id is %d, error code is %d."), m_nClientID);
  1844. return FALSE;
  1845. }
  1846. // ok, return true
  1847. return TRUE;
  1848. }
  1849. BOOL COTSBrukerImpl::LoadSpectrum(char* a_sFilePathName)
  1850. {
  1851. // safety check
  1852. ASSERT(a_sFilePathName);
  1853. if (!a_sFilePathName)
  1854. {
  1855. // invalid a_sFilePathName
  1856. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::LoadSpectrum: invalid a_sFilePathName"));
  1857. return FALSE;
  1858. }
  1859. ASSERT(m_pBrukerDllHandle);
  1860. if (!m_pBrukerDllHandle)
  1861. {
  1862. // invalid m_pBrukerDllHandle
  1863. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::LoadSpectrum: invalid m_pBrukerDllHandle"));
  1864. return FALSE;
  1865. }
  1866. if (!m_pBrukerDllHandle->LoadSpectrum(m_nClientID, a_sFilePathName))
  1867. {
  1868. // error, failed to call LoadSpectrum method
  1869. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::LoadSpectrum: failed to call LoadSpectrum method. client id is %d."), m_nClientID);
  1870. return FALSE;
  1871. }
  1872. // ok, return true
  1873. return TRUE;
  1874. }
  1875. // call ReadSpectrum
  1876. // return true if success
  1877. BOOL COTSBrukerImpl::ReadSpectrum(void)
  1878. {
  1879. // safety check
  1880. ASSERT(m_pBrukerDllHandle);
  1881. if (!m_pBrukerDllHandle)
  1882. {
  1883. // error, invalid m_pBrukerDllHandle
  1884. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadSpectrum: invalid m_pBrukerDllHandle"));
  1885. return FALSE;
  1886. }
  1887. if (!m_pBrukerDllHandle->ReadSpectrum(m_nClientID, 1))
  1888. {
  1889. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadSpectrum:Call ReadSpectrum failed: client id is %d"), m_nClientID);
  1890. return FALSE;
  1891. }
  1892. // ok, return true
  1893. return TRUE;
  1894. }
  1895. // put spectrum into Bruker system
  1896. BOOL COTSBrukerImpl::PutSpectrum(char* a_pBuffer, long a_nBufferSize)
  1897. {
  1898. // safety check
  1899. ASSERT(m_pBrukerDllHandle);
  1900. if (!m_pBrukerDllHandle)
  1901. {
  1902. // error, invalid m_pBrukerDllHandle
  1903. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::PutSpectrum: invalid m_pBrukerDllHandle"));
  1904. return FALSE;
  1905. }
  1906. if (!m_pBrukerDllHandle->PutSpectrum(m_nClientID, a_pBuffer, a_nBufferSize))
  1907. {
  1908. // error, fail to call PutSpectrum method
  1909. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::PutSpectrum: failed to call PutSpectrum."), m_nClientID);
  1910. return FALSE;
  1911. }
  1912. // ok, return true
  1913. return TRUE;
  1914. }
  1915. BOOL COTSBrukerImpl::CreateSpectrum(char* m_pParamBuffer, RTSpectrumHeaderRec* a_poSpcHR, char* m_pResultBuffer, long& a_nBufferSize)
  1916. {
  1917. // safety check
  1918. ASSERT(m_pParamBuffer);
  1919. if (!m_pParamBuffer)
  1920. {
  1921. // error, invalid m_pParamBuffer
  1922. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CreateSpectrum: invalid m_pParamBuffer"));
  1923. return FALSE;
  1924. }
  1925. ASSERT(a_poSpcHR);
  1926. if (!a_poSpcHR)
  1927. {
  1928. // invalid a_poSpcHR
  1929. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CreateSpectrum: invalid a_poSpcHR"));
  1930. return FALSE;
  1931. }
  1932. ASSERT(m_pResultBuffer);
  1933. if (!m_pResultBuffer)
  1934. {
  1935. // error, invalid m_pResultBuffer
  1936. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CreateSpectrum: invalid m_pResultBuffer"));
  1937. return FALSE;
  1938. }
  1939. ASSERT(m_pBrukerDllHandle);
  1940. if (!m_pBrukerDllHandle)
  1941. {
  1942. // error, invalid m_pBrukerDllHandle
  1943. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CreateSpectrum: invalid m_pBrukerDllHandle"));
  1944. return FALSE;
  1945. }
  1946. if (!m_pBrukerDllHandle->CreateSpectrum(m_pParamBuffer, a_poSpcHR, m_pResultBuffer, &a_nBufferSize))
  1947. {
  1948. // error, failed to call CreateSpectrum method
  1949. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CreateSpectrum: failed to call CreateSpectrum method. client id is %d."), m_nClientID);
  1950. return FALSE;
  1951. }
  1952. // ok, return true
  1953. return TRUE;
  1954. }
  1955. BOOL COTSBrukerImpl::ShowSpectrum(long a_nBufferIndex, char* a_pSpectumName)
  1956. {
  1957. // safety check
  1958. ASSERT(m_pBrukerDllHandle);
  1959. if (!m_pBrukerDllHandle)
  1960. {
  1961. // error, invalid m_pBrukerDllHandle
  1962. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ShowSpectrum: invalid m_pBrukerDllHandle"));
  1963. return FALSE;
  1964. }
  1965. ASSERT(a_pSpectumName);
  1966. if (!a_pSpectumName)
  1967. {
  1968. // error, invalid a_pSpectumName
  1969. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ShowSpectrum: invalid a_pSpectumName"));
  1970. return FALSE;
  1971. }
  1972. if (!m_pBrukerDllHandle->ShowSpectrum(m_nClientID, a_nBufferIndex, a_pSpectumName))
  1973. {
  1974. // error, failed to call ShowSpectrum method
  1975. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ShowSpectrum: failed to call ShowSpectrum method. client id is %d."), m_nClientID);
  1976. return FALSE;
  1977. }
  1978. // ok, return true
  1979. return TRUE;
  1980. }
  1981. BOOL COTSBrukerImpl::GetSpectrometerParams(long a_nBufferIndex, char* a_pBuffer, long& a_nBufferSize)
  1982. {
  1983. // safety check
  1984. ASSERT(m_pBrukerDllHandle);
  1985. if (!m_pBrukerDllHandle)
  1986. {
  1987. // error, invalid m_pBrukerDllHandle
  1988. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSpectrometerParams: invalid m_pBrukerDllHandle"));
  1989. return FALSE;
  1990. }
  1991. if (!m_pBrukerDllHandle->GetSpectrometerParams(m_nClientID, a_nBufferIndex, a_pBuffer, &a_nBufferSize))
  1992. {
  1993. // error, failed to call GetSpectrometerParams method
  1994. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetSpectrometerParams: failed to call GetSpectrometerParams method. client id is %d."), m_nClientID);
  1995. return FALSE;
  1996. }
  1997. // ok, return true
  1998. return TRUE;
  1999. }
  2000. BOOL COTSBrukerImpl::GetElementChemistryData(CElementChemistry& a_oElementChemistryData, CString a_strElementChemistry)
  2001. {
  2002. // split element chemistry string
  2003. std::vector<CString> vString = CControllerHelper::SplitString(a_strElementChemistry, _T(","));
  2004. // the strings list should has at least three strings
  2005. long MIN_STRINGs_COUNT = 3;
  2006. if (MIN_STRINGs_COUNT > (long)vString.size())
  2007. {
  2008. return FALSE;
  2009. }
  2010. // name
  2011. CString strName = vString[0];
  2012. strName.Trim();
  2013. if (strName.IsEmpty())
  2014. {
  2015. return FALSE;
  2016. }
  2017. auto nPos = strName.Find(_T("="));
  2018. CString strTempName;
  2019. if (nPos > 0)
  2020. {
  2021. strTempName = strName.Right(strName.GetLength() - nPos - 1);
  2022. }
  2023. else
  2024. {
  2025. LogErrorTrace(__FILE__,__LINE__,_T("Wrong element name string(%s)"), strName);
  2026. strTempName = strName.Right(1);
  2027. }
  2028. a_oElementChemistryData.SetName(strTempName);
  2029. // percentage
  2030. CString strPercentage = vString[2];
  2031. strPercentage.Trim();
  2032. if (strPercentage.IsEmpty())
  2033. {
  2034. return FALSE;
  2035. }
  2036. double dPercentage;
  2037. if (!CControllerHelper::StringToDouble(strPercentage, dPercentage))
  2038. {
  2039. return FALSE;
  2040. }
  2041. a_oElementChemistryData.SetPercentage(dPercentage);
  2042. // OK return true
  2043. return TRUE;
  2044. }
  2045. // call CopySpectrum
  2046. // return true if success
  2047. BOOL COTSBrukerImpl::CopySpectrum(long* a_pXRayData, DWORD a_nBufferSize)
  2048. {
  2049. // start x ray measurement
  2050. if (!GetSpectrum(1, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  2051. {
  2052. // error, failed to call GetSpectrum method
  2053. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl:: failed to call GetSpectrum method."));
  2054. return FALSE;
  2055. }
  2056. // convert spectrum
  2057. if (!ConvertSpectrum((RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), a_pXRayData, a_nBufferSize))
  2058. {
  2059. // error failed to call ConvertSpectrum method
  2060. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::Call ConvertSpectrum failed."));
  2061. return FALSE;
  2062. }
  2063. // set head struck
  2064. // always get a spectrum header for exporting quantify header
  2065. m_pSpectrumHead = (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get();
  2066. // ok, return true
  2067. return TRUE;
  2068. }
  2069. // start spectrum life time measurement
  2070. BOOL COTSBrukerImpl::StartSpectrumLifeTimeMeasurement(DWORD a_nLifeTime)
  2071. {
  2072. // safety check
  2073. ASSERT(m_pBrukerDllHandle);
  2074. if (!m_pBrukerDllHandle)
  2075. {
  2076. // error, invalid m_pBrukerDllHandle
  2077. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartSpectrumLifeTimeMeasurement: invalid m_pBrukerDllHandle"));
  2078. return FALSE;
  2079. }
  2080. if (!m_pBrukerDllHandle->StartSpectrumLifeTimeMeasurement(m_nClientID, m_nSPU, a_nLifeTime))
  2081. {
  2082. // error, failed to call StartSpectrumLifeTimeMeasurement method
  2083. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartSpectrumLifeTimeMeasurement: failed to call StartSpectrumLifeTimeMeasurement method. client id is %d"), m_nClientID);
  2084. return FALSE;
  2085. }
  2086. // ok, return true
  2087. return TRUE;
  2088. }
  2089. // call StartSpectrumLifeTimeMeasurement
  2090. // return true if success
  2091. BOOL COTSBrukerImpl::SpectrumLifeTimeMeasurement(DWORD a_nLifeTime)
  2092. {
  2093. if (!StartSpectrumLifeTimeMeasurement(a_nLifeTime))
  2094. {
  2095. // error failed to call StartSpectrumLifeTimeMeasurement method
  2096. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumLifeTimeMeasurement: failed to call StartSpectrumLifeTimeMeasurement method."));
  2097. return FALSE;
  2098. }
  2099. // check to see if the system has finished the action
  2100. #pragma warning(suppress: 28159)
  2101. DWORD nStart = GetTickCount();
  2102. DWORD nEnd = nStart;
  2103. BOOL bRunning = TRUE;
  2104. do
  2105. {
  2106. #pragma warning(suppress: 28159)
  2107. nEnd = GetTickCount();
  2108. if (!IsSpectrumMeterRunning(bRunning))
  2109. {
  2110. // error, failed to call IsSpectrumMeterRunning method
  2111. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumLifeTimeMeasurement: failed to call IsSpectrumMeterRunning method."));
  2112. return FALSE;
  2113. }
  2114. } while (nEnd >= nStart && nEnd <= (nStart + a_nLifeTime + 1) && bRunning);
  2115. // force to stop if system still busy
  2116. if (bRunning && !StopSpectrumMeter())
  2117. {
  2118. // error, failed to call stop StopSpectrumMeter method
  2119. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumLifeTimeMeasurement: failed to call StopSpectrumMeter method."));
  2120. return FALSE;
  2121. }
  2122. // ok, return true
  2123. return TRUE;
  2124. }
  2125. // Start Spectrum Real Time Measurement
  2126. BOOL COTSBrukerImpl::StartSpectrumRealTimeMeasurement(DWORD a_nRealTime)
  2127. {
  2128. // safety check
  2129. ASSERT(m_pBrukerDllHandle);
  2130. if (!m_pBrukerDllHandle)
  2131. {
  2132. // error, invalid m_pBrukerDllHandle
  2133. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartSpectrumRealTimeMeasurement: invalid m_pBrukerDllHandle"));
  2134. return FALSE;
  2135. }
  2136. if (!m_pBrukerDllHandle->StartSpectrumMeasurement(m_nClientID, m_nSPU, a_nRealTime))
  2137. {
  2138. // error, failed to call StartSpectrumMeasurement method
  2139. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartSpectrumRealTimeMeasurement: failed to call StartSpectrumMeasurement method. client id is %d."), m_nClientID);
  2140. return FALSE;
  2141. }
  2142. // ok, return true
  2143. return TRUE;
  2144. }
  2145. // call StartSpectrumRealTimeMeasurement
  2146. // return true if success
  2147. BOOL COTSBrukerImpl::SpectrumRealTimeMeasurement(DWORD a_nRealTime)
  2148. {
  2149. if (!StartSpectrumRealTimeMeasurement(a_nRealTime))
  2150. {
  2151. // error, failed to call StartSpectrumRealTimeMeasurement method
  2152. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumRealTimeMeasurement: failed to call StartSpectrumRealTimeMeasurement method."));
  2153. return FALSE;
  2154. }
  2155. // check to see if the system has finished the action
  2156. #pragma warning(suppress: 28159)
  2157. DWORD nStart = GetTickCount();
  2158. DWORD nEnd = nStart;
  2159. BOOL bRunning = TRUE;
  2160. do
  2161. {
  2162. #pragma warning(suppress: 28159)
  2163. nEnd = GetTickCount();
  2164. if (!IsSpectrumMeterRunning(bRunning))
  2165. {
  2166. // error, failed to call IsSpectrumMeterRunning method
  2167. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumRealTimeMeasurement: failed to call IsSpectrumMeterRunning method."));
  2168. return FALSE;
  2169. }
  2170. } while (nEnd >= nStart && nEnd <= (nStart + a_nRealTime + 1) && bRunning);
  2171. // force to stop if system still busy
  2172. if (bRunning && !StopSpectrumMeter())
  2173. {
  2174. // error failed to call StopSpectrumMeter method
  2175. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumRealTimeMeasurementCall: failed to call StopSpectrumMeter method."));
  2176. return FALSE;
  2177. }
  2178. // ok, return true
  2179. return TRUE;
  2180. }
  2181. BOOL COTSBrukerImpl::SpectrumCountsMeasurement(DWORD a_nTotalCounts, int a_nTimeLimit /*= -1*/)
  2182. {
  2183. if (a_nTimeLimit <= 0)
  2184. {
  2185. a_nTimeLimit = DEFAULT_MAX_WAIT_TIME_COLLECT_COUNTS;
  2186. }
  2187. if (!StartSpectrumMeasurement())
  2188. {
  2189. // error, failed to call StartSpectrumMeasurement method
  2190. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: failed to call StartSpectrumMeasurement method."));
  2191. return FALSE;
  2192. }
  2193. // check to see if the system has finished the action
  2194. #pragma warning(suppress: 28159)
  2195. DWORD nStartTime = GetTickCount();
  2196. DWORD nEndTime = nStartTime;
  2197. BOOL bRunning = TRUE;
  2198. do
  2199. {
  2200. if (!IsSpectrumMeterRunning(bRunning))
  2201. {
  2202. // error, failed to call IsSpectrumMeterRunning method
  2203. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: failed to call IsSpectrumMeterRunning method."));
  2204. return FALSE;
  2205. }
  2206. if (!bRunning)
  2207. {
  2208. // get out if bruker stopped
  2209. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: Bruker stopped."));
  2210. break;
  2211. }
  2212. // read spectrum
  2213. if (!ReadSpectrum())
  2214. {
  2215. // error, failed to call ReadSpectrum method
  2216. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: failed to call ReadSpectrum method."));
  2217. return FALSE;
  2218. }
  2219. // get a x ray
  2220. if (!GetSpectrum(1, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  2221. {
  2222. // error, failed to call GetSpectrum method
  2223. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: failed to call GetSpectrum(1) method."));
  2224. return FALSE;
  2225. }
  2226. // quick to check total counts
  2227. // pcharTemp point to start of whole spectrum
  2228. char* pcharTemp = (char*)m_psRTSpectrumBuffer.get();
  2229. // jump over spectrum head, pcharTemp points to the data block
  2230. pcharTemp += sizeof(RTSpectrumHeaderRec);
  2231. // pLongChannels point to the data block
  2232. long* pLongChannels = (long*)pcharTemp;
  2233. RTSpectrumHeaderRec* pSpectrumHead = (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get();
  2234. int nTotalChannel = pSpectrumHead->ChannelCount;
  2235. DWORD nTotalPoints = 0;
  2236. for (int i = 0; i < nTotalChannel; ++i)
  2237. {
  2238. nTotalPoints += pLongChannels[i];
  2239. }
  2240. #pragma warning(suppress: 28159)
  2241. nEndTime = GetTickCount();
  2242. if (nTotalPoints >= a_nTotalCounts)
  2243. {
  2244. // get out, get enough points
  2245. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: Stop collection: Got enough points"));
  2246. break;
  2247. }
  2248. // stop collection if it take too long
  2249. if (nEndTime > (nStartTime + a_nTimeLimit + 1))
  2250. {
  2251. // get out, took too long
  2252. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: Stop collection, took too long."));
  2253. break;
  2254. }
  2255. } while (bRunning);
  2256. // force to stop if system still busy
  2257. if (bRunning && !StopSpectrumMeter())
  2258. {
  2259. // error, failed to call StopSpectrumMeter method
  2260. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SpectrumCountsMeasurement: failed to call StopSpectrumMeter method."));
  2261. return FALSE;
  2262. }
  2263. // ok, return true
  2264. return TRUE;
  2265. }
  2266. BOOL COTSBrukerImpl::ConvertSpectrum(RTSpectrumHeaderRec* a_poSpcHR, long* a_pXRayData, DWORD a_nBufferSize)
  2267. {
  2268. // safety check
  2269. ASSERT(a_poSpcHR);
  2270. if (!a_poSpcHR)
  2271. {
  2272. // error, invalid a_poSpcHR
  2273. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ConvertSpectrum: invalid a_poSpcHR."));
  2274. return FALSE;
  2275. }
  2276. if (!(a_nBufferSize > 0))
  2277. {
  2278. // error, invalid buffer size
  2279. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ConvertSpectrum: invalid buffer size."));
  2280. return FALSE;
  2281. }
  2282. a_poSpcHR->ChannelCount = 4096;
  2283. ASSERT(a_pXRayData);
  2284. if (!a_pXRayData)
  2285. {
  2286. // error, invalid a_pXRayData
  2287. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ConvertSpectrum: invalid a_pXRayData."));
  2288. return FALSE;
  2289. }
  2290. // calculate zero peak channel
  2291. long nZeroPeakChannel = 0;
  2292. const double MIN_CALIBRATION_LIN = 0.000001;
  2293. if (fabs(a_poSpcHR->CalibrationLin) > MIN_CALIBRATION_LIN)
  2294. {
  2295. nZeroPeakChannel = (long)fabs(a_poSpcHR->CalibrationAbs / a_poSpcHR->CalibrationLin);
  2296. }
  2297. // check if there are valid data channels
  2298. if (a_poSpcHR->ChannelCount / 2 <= nZeroPeakChannel)
  2299. {
  2300. // error, no channel data;
  2301. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ConvertSpectrum: no channel data (nZeroPeakChannel: %i)."), nZeroPeakChannel);
  2302. return FALSE;
  2303. }
  2304. // pcharTemp point to start of whole spectrum
  2305. char* pcharTemp = (char*)a_poSpcHR;
  2306. // jump over spectrum head, pcharTemp points to the data block
  2307. pcharTemp += sizeof(RTSpectrumHeaderRec);
  2308. // pLongChannels point to the data block
  2309. long* pLongChannels = (long*)pcharTemp;
  2310. // calculate zero peak ending channel
  2311. long nZeroPeakEndingChannel = nZeroPeakChannel;
  2312. // check if there are valid data channels
  2313. if (a_poSpcHR->ChannelCount <= nZeroPeakEndingChannel)
  2314. {
  2315. // no channel data
  2316. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ConvertSpectrum: no channel data nZeroPeakEndingChannel: %i)."), nZeroPeakEndingChannel);
  2317. return FALSE;
  2318. }
  2319. // find the end of the zero peak channel
  2320. long nPrevCount = pLongChannels[nZeroPeakEndingChannel];
  2321. for (long i = 0;
  2322. i < nZeroPeakChannel && // zero peak ending channel will be less than nZeroPeakChannel * 2
  2323. nPrevCount > 0;
  2324. ++i)
  2325. {
  2326. ++nZeroPeakEndingChannel;
  2327. long nCurrentCount = pLongChannels[nZeroPeakEndingChannel];
  2328. long nNextCount = pLongChannels[nZeroPeakEndingChannel + 1];
  2329. long nNextNextCountNext = pLongChannels[nZeroPeakEndingChannel + 2];
  2330. // if current count == 0 && nNextCount == 0 && nNextNextCountNext == 0
  2331. // or current > previous count && nNextCount > nCurrentCount && nNextNextCountNext > nNextCount, then this is
  2332. if ((nCurrentCount == 0 && nNextCount == 0 && nNextNextCountNext == 0) ||
  2333. (nCurrentCount > nPrevCount && nNextCount > nCurrentCount && nNextNextCountNext > nNextCount))
  2334. {
  2335. // find the zero peak ending channel, get out
  2336. break;
  2337. }
  2338. // the current count will be the
  2339. nPrevCount = nCurrentCount;
  2340. }
  2341. // calculate valid data channel number
  2342. long nDataChannelNO = a_poSpcHR->ChannelCount - nZeroPeakChannel;
  2343. // clean zero peak data
  2344. if (a_poSpcHR->ChannelCount > (nZeroPeakEndingChannel + 1))
  2345. {
  2346. memset(pLongChannels, 0, (nZeroPeakEndingChannel + 1) * sizeof(long));
  2347. }
  2348. // jump over zero peak channels
  2349. pLongChannels += nZeroPeakChannel;
  2350. // clean data buffer
  2351. memset(a_pXRayData, 0, a_nBufferSize * sizeof(long));
  2352. // copy data from bruker data buffer to data buffer [blend]
  2353. double dStep1 = 1.0 / (double)nDataChannelNO; // step size of bruker bin
  2354. double dStep2 = 1.0 / (double)a_nBufferSize; // step size of bin
  2355. // blend bruker data
  2356. for (long i = 0; i < nDataChannelNO; ++i)
  2357. {
  2358. // get the bruker bin data
  2359. long nValue = (pLongChannels[i] > 0) ? pLongChannels[i] : 0;
  2360. // calculate the bruker bin position
  2361. double dBinPos = (double)i * dStep1;
  2362. // calculate bin number on the left side of the position
  2363. long nLeftBin = (long)(dBinPos / dStep2);
  2364. // calculate % into left bin
  2365. double dLeft_Percent = double(nLeftBin + 1) - dBinPos / dStep2; // ((nLeftBin + 1)*dStep2 - dBinPos)/dStep2
  2366. // calculate data into the left bin
  2367. long nValueToLeftBin = (long)((double)nValue * dLeft_Percent + 0.5);
  2368. // put data into bins
  2369. a_pXRayData[nLeftBin] += nValueToLeftBin;
  2370. if ((nLeftBin + 1) < (long)a_nBufferSize)
  2371. {
  2372. a_pXRayData[nLeftBin + 1] += (nValue - nValueToLeftBin);
  2373. }
  2374. }
  2375. // ok, return true
  2376. return TRUE;
  2377. }
  2378. // call GetPointListSpectrum
  2379. // return true if success
  2380. BOOL COTSBrukerImpl::GetPointListSpectrum(long a_nIndex, long* a_pnSpec)
  2381. {
  2382. // safety check
  2383. ASSERT(m_pBrukerDllHandle);
  2384. if (!m_pBrukerDllHandle)
  2385. {
  2386. // error, invalid m_pBrukerDllHandle
  2387. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetPointListSpectrum: invalid m_pBrukerDllHandle."));
  2388. return FALSE;
  2389. }
  2390. ASSERT(a_pnSpec);
  2391. if (!a_pnSpec)
  2392. {
  2393. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetPointListSpectrum: invalid a_pnSpec."));
  2394. return FALSE;
  2395. }
  2396. // Success?
  2397. if (m_pBrukerDllHandle->GetPointListSpectrum(m_nClientID, a_nIndex, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (long)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  2398. {
  2399. if (!ConvertSpectrum((RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), a_pnSpec, (DWORD)BRUKER_PARAM::RT_SPECTRUM_CHANNELS))
  2400. {
  2401. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetPointListSpectrum:Call ConvertSpectrum failed."));
  2402. return FALSE;
  2403. }
  2404. }
  2405. else
  2406. {
  2407. long hr = m_pBrukerDllHandle->GetLastReturn();
  2408. if (hr == (long)EBrukerErrorCode::ERROR_INVALID_RESULT_DATA) // ERROR_INVALID_RESULT_DATA (-106) usually occurs during an out of memory situation
  2409. {
  2410. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetPointListSpectrum:Call GetPointListSpectrum failed: invalid data."));
  2411. }
  2412. else
  2413. {
  2414. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetPointListSpectrum:Call GetPointListSpectrum failed: error code is %d."), hr);
  2415. }
  2416. return FALSE;
  2417. }
  2418. return TRUE;
  2419. }
  2420. // call GetFeatureListSpectrum
  2421. // return true if success
  2422. BOOL COTSBrukerImpl::GetFeatureListSpectrum(long a_nIndex, long* a_pnSpec)
  2423. {
  2424. if (!m_pBrukerDllHandle)
  2425. {
  2426. // error, invalid m_pBrukerDllHandle
  2427. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetFeatureListSpectrum:m_pBrukerDllHandle failed, return"));
  2428. return FALSE;
  2429. }
  2430. if (!a_pnSpec)
  2431. {
  2432. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetFeatureListSpectrum:a_pnSpec failed, return"));
  2433. return FALSE;
  2434. }
  2435. // Success?
  2436. if (!(m_pBrukerDllHandle->GetFeatureListSpectrum(m_nClientID, a_nIndex, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE)))
  2437. {
  2438. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetFeatureListSpectrum:failed, return"));
  2439. return FALSE;
  2440. }
  2441. // return method return flag
  2442. if (!ConvertSpectrum((RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), a_pnSpec, (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS))
  2443. {
  2444. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetFeatureListSpectrum: convert spectrum failed, return"));
  2445. return FALSE;
  2446. }
  2447. return TRUE;
  2448. }
  2449. // call StartPointListMeasurement
  2450. // return true if success
  2451. BOOL COTSBrukerImpl::StartPointListMeasurement(
  2452. DWORD a_nSegmentCount,
  2453. BrukerSegment* a_poSegment,
  2454. DWORD m_nMilliseconds)
  2455. {
  2456. ASSERT(m_pBrukerDllHandle);
  2457. if (!m_pBrukerDllHandle)
  2458. {
  2459. // error, invalid m_pBrukerDllHandle
  2460. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartPointListMeasurement:m_pBrukerDllHandle failed, return"));
  2461. return FALSE;
  2462. }
  2463. ASSERT(a_poSegment);
  2464. if (!a_poSegment)
  2465. {
  2466. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartPointListMeasurement:a_poSegment failed, return"));
  2467. return FALSE;
  2468. }
  2469. if (!m_pBrukerDllHandle->StartPointListMeasurement(m_nClientID, m_nSPU, a_nSegmentCount, a_poSegment, m_nMilliseconds))
  2470. {
  2471. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartPointListMeasurement:Call StartPointListMeasurement failed: client id is %d(%d, %d, %d)"), m_nClientID, m_nSPU, a_nSegmentCount, m_nMilliseconds);
  2472. return FALSE;
  2473. }
  2474. return TRUE;
  2475. }
  2476. // call StartFeatureListMeasurement
  2477. // return true if success
  2478. BOOL COTSBrukerImpl::StartFeatureListMeasurement(
  2479. DWORD a_nFeatureCount,
  2480. BrukerFeature* a_poFeature,
  2481. WORD* a_pwdPixelTimes)
  2482. {
  2483. ASSERT(m_pBrukerDllHandle);
  2484. if (!m_pBrukerDllHandle)
  2485. {
  2486. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartFeatureListMeasurement:m_pBrukerDllHandle failed, return"));
  2487. return FALSE;
  2488. }
  2489. ASSERT(a_poFeature);
  2490. if (!a_poFeature)
  2491. {
  2492. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartFeatureListMeasurement:a_poFeature failed, return"));
  2493. return FALSE;
  2494. }
  2495. if (!a_pwdPixelTimes)
  2496. {
  2497. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartFeatureListMeasurement:a_pwdPixelTimes failed, return"));
  2498. return FALSE;
  2499. }
  2500. if (!m_pBrukerDllHandle->StartFeatureListMeasurement(m_nClientID, m_nSPU, a_nFeatureCount, a_poFeature, a_pwdPixelTimes))
  2501. {
  2502. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::StartFeatureListMeasurement:Call StartFeatureListMeasurement failed: client id is %d"), m_nClientID);
  2503. return FALSE;
  2504. }
  2505. return TRUE;
  2506. }
  2507. // instance termination
  2508. //void COTSBrukerImpl::FinishedInstance(void) { ; }
  2509. //
  2510. CString COTSBrukerImpl::GetQuantificationSpectrumPathName()
  2511. {
  2512. CString sFilePathName = _T("\\QuantificationSpectrum.spx");
  2513. return sFilePathName;
  2514. }
  2515. BOOL COTSBrukerImpl::GetXRayByPoints(CPosXraysList& a_listXrayPois, DWORD a_nACTimeMS)
  2516. {
  2517. try
  2518. {
  2519. // bruker dll handle check
  2520. ASSERT(m_pBrukerDllHandle);
  2521. if (!m_pBrukerDllHandle)
  2522. {
  2523. // error, invalid m_pBrukerDllHandle
  2524. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetXRayByPoints: invalid m_pBrukerDllHandle."));
  2525. return FALSE;
  2526. }
  2527. // do nothing if points list is empty
  2528. if (a_listXrayPois.empty())
  2529. {
  2530. // points list is empty
  2531. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetXRayByPoints: poits list is empty."));
  2532. return TRUE;
  2533. }
  2534. //// turn SEM to external
  2535. //if (!SetSEMExternalOn())
  2536. //{
  2537. // // failed to call SetSEMExternalOn method
  2538. // LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetXRayByPoints: failed to call SetSEMExternalOn method."));
  2539. // return FALSE;
  2540. //}
  2541. // create array of BrukerSegment
  2542. long nCollectCount = (long)a_listXrayPois.size();
  2543. BrukerSegment* segmentArray(new BrukerSegment[nCollectCount]);
  2544. for (int i = 0; i < nCollectCount; ++i)
  2545. {
  2546. CPoint poi = a_listXrayPois[i]->GetPosition();
  2547. segmentArray[i].Y = poi.y;
  2548. segmentArray[i].XStart = poi.x;
  2549. }
  2550. // ask Bruker to collect a set of x ray data
  2551. if (!StartPointListMeasurement(nCollectCount, segmentArray, a_nACTimeMS))
  2552. {
  2553. // failed to call StartPointListMeasurement method
  2554. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call StartPointListMeasurement method."));
  2555. return FALSE;
  2556. }
  2557. // get the specs for a_listXrayPois
  2558. if (!SetXRayPoints(a_listXrayPois, a_nACTimeMS))
  2559. {
  2560. // failed to call ReadXRayPoints method
  2561. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPoints: failed to call ReadXRayPoints method."));
  2562. return FALSE;
  2563. }
  2564. delete[] segmentArray;
  2565. // ok return TRUE
  2566. return TRUE;
  2567. }
  2568. catch (const std::exception&)
  2569. {
  2570. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetXRayByPoints: exception."));
  2571. }
  2572. //finally
  2573. //{
  2574. // // turn SEM to external OFF
  2575. // if (!SetSEMExternalOff())
  2576. // {
  2577. // // failed to call SetSEMExternalOn method
  2578. // LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::GetXRayByPoints: failed to call SetSEMExternalOff method."));
  2579. //
  2580. // }
  2581. //}
  2582. // error, return false
  2583. return FALSE;
  2584. }
  2585. BOOL COTSBrukerImpl::SetXRayPoints(CPosXraysList& a_listXrayPois, const DWORD a_nACTimeMS)
  2586. {
  2587. // Fail a_vXPoints is empty
  2588. if (a_listXrayPois.empty())
  2589. {
  2590. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints Empty point list given in argument a_oPointList"));
  2591. return TRUE;
  2592. }
  2593. long nCollectCount = (long)a_listXrayPois.size();
  2594. // get the specs for a_vXPoints
  2595. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  2596. for (int i = 0; i < nCollectCount; ++i)
  2597. {
  2598. // cleanup data storage
  2599. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  2600. if (m_bDoQuantification)
  2601. {
  2602. // quantify the spectrum
  2603. char* pcMethod = "Default";//"Default";//"Automatic";
  2604. char* pcParams = "ResultType=quantification";
  2605. char cResult[10000];
  2606. memset(cResult, 0, 10000);
  2607. if (!m_pBrukerDllHandle->QuantifyPointListSpectrum(m_nClientID, i, pcMethod, pcParams, cResult, 10000, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  2608. {
  2609. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints failed to call QuantifyPointListSpectrum method at index %d, error code %d"), i, m_pBrukerDllHandle->GetLastReturn());
  2610. //return FALSE;
  2611. }
  2612. CElementChemistriesList listElement = CElement::ExtractElementChemistrys(CControllerHelper::CharToString(cResult));
  2613. a_listXrayPois[i]->SetElementQuantifyData(listElement);
  2614. }
  2615. // get spectrum data of a point
  2616. bool success = GetPointListSpectrum(i, (long*)nChannelData);
  2617. if (!success)
  2618. {
  2619. // error
  2620. CPoint poi = a_listXrayPois[i]->GetPosition();
  2621. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints:Call GetPointListSpectrum failed : index = %d(x : %d, y : %d)"),
  2622. i,
  2623. poi.x,
  2624. poi.y);
  2625. return FALSE;
  2626. }
  2627. // set spectrum data for the x-ray point
  2628. a_listXrayPois[i]->SetXrayData(nChannelData);
  2629. }
  2630. // We have seen rare instances where StartPointListMeasurement returns some unexpected empty
  2631. // spectra. (We can expect spectra to be empty if we measure in a hole due to charging in the
  2632. // BSE image, but on some occasions we see some empty spectra within areas of a measurement
  2633. // that otherwise look ok. We have no explanation for this and can't replicate it.)
  2634. // In these scenarios we want to fall back to a single point measurement to see if it will
  2635. // collect something valid.
  2636. // Only if we haven't had an actual bruker error
  2637. for (int i = 0; i < nCollectCount; ++i)
  2638. {
  2639. // check spectrum
  2640. DWORD nTatolXrayCount = a_listXrayPois[i]->GetTotalCount();
  2641. if (nTatolXrayCount < 20)
  2642. {
  2643. // captured an empty spectrum
  2644. CPoint poi = a_listXrayPois[i]->GetPosition();
  2645. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints:Collected low count spectrum(%d counts), index = %d(x:%d, y : %d) This could be caused by charging."),
  2646. nTatolXrayCount, i, poi.x, poi.y);
  2647. // try to redo x-ray collection at the position
  2648. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  2649. if (!CollectOneXRayPoint(poi, a_nACTimeMS, (long*)nChannelData, (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS))
  2650. {
  2651. // error, call CollectOneXRayPoint failed
  2652. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints: Call CollectOneXRayPoint failed: index = %d(x:%d, y:%d)"),
  2653. i, poi.x, poi.y);
  2654. return FALSE;
  2655. }
  2656. // set spectrum with new spectrum
  2657. a_listXrayPois[i]->SetXrayData(nChannelData);
  2658. nTatolXrayCount = a_listXrayPois[i]->GetTotalCount();
  2659. if (nTatolXrayCount < 20)
  2660. {
  2661. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum still low count (%d counts), index = %d(x:%d, y:%d.) This could be caused by charging."),
  2662. nTatolXrayCount, i, poi.x, poi.y);
  2663. //return FALSE;
  2664. }
  2665. else
  2666. {
  2667. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPoints:Single point spectrum collected successfully (%d counts), index = %d(x:%d, y:%d.)"),
  2668. nTatolXrayCount, i, poi.x, poi.y);
  2669. }
  2670. }
  2671. }
  2672. // ok, return true
  2673. return TRUE;
  2674. }
  2675. BOOL COTSBrukerImpl::GetXRayByFeatures(CPosXraysList& a_vXPoints, std::vector<std::vector<BrukerSegment>>& a_vFeatures, DWORD a_nACTimeMS)
  2676. {
  2677. // bruker dll handle check
  2678. ASSERT(m_pBrukerDllHandle);
  2679. if (!m_pBrukerDllHandle)
  2680. {
  2681. // error, invalid m_pBrukerDllHandle
  2682. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: invalid m_pBrukerDllHandle."));
  2683. return FALSE;
  2684. }
  2685. // do nothing if points list is empty
  2686. if (a_vXPoints.empty())
  2687. {
  2688. // points list is empty
  2689. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: poits list is empty."));
  2690. return TRUE;
  2691. }
  2692. // lists size check
  2693. if (a_vXPoints.size() != a_vFeatures.size())
  2694. {
  2695. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures:Feature size(%d) doesn't match xray point size(%d)"), a_vFeatures.size(), a_vXPoints.size());
  2696. return FALSE;
  2697. }
  2698. // set SEM to external
  2699. if (!SetSEMExternalOn())
  2700. {
  2701. // failed to call SetSEMExternalOn method
  2702. LogTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call SetSEMExternalOn method."));
  2703. return FALSE;
  2704. }
  2705. // create array of BrukerSegment
  2706. long nCollectCount = (long)a_vXPoints.size();
  2707. long nTotalPixelCount = 0;
  2708. // added by Jieshi 23/08/2017
  2709. WORD* pixelTimes(new WORD[nCollectCount]);
  2710. BrukerFeature* features(new BrukerFeature[nCollectCount]);
  2711. std::vector<BrukerSegment> extraSegments;
  2712. for (size_t i = 0; i < a_vXPoints.size(); i++)
  2713. {
  2714. features[i].SegmentCount = (long)a_vFeatures[i].size();
  2715. if (features[i].SegmentCount > 0)
  2716. {
  2717. features[i].pSegment = &a_vFeatures[i][0];
  2718. // calculate pixel time
  2719. int nPixelCount = 0;
  2720. /* for (int j = 0; j < features[i].SegmentCount; j++)
  2721. {
  2722. nPixelCount += features[i].pSegment[j].XCount;
  2723. }
  2724. pixelTimes[i] = (WORD)(a_nACTimeMS * 1000 / nPixelCount);*///旧方法有错误 added by zty. because not using ceil function ,the result may be 0.
  2725. /*for (size_t j = 0; j < a_vFeatures[i].size(); j++)
  2726. {
  2727. nPixelCount += a_vFeatures[i][j].XCount;
  2728. }*/
  2729. for (int j = 0; j < features[i].SegmentCount; j++)
  2730. {
  2731. nPixelCount += features[i].pSegment[j].XCount;
  2732. }
  2733. pixelTimes[i] = (WORD)(ceil((double)a_nACTimeMS * 1000.0 / (double)nPixelCount));
  2734. nTotalPixelCount += nPixelCount;
  2735. }
  2736. else
  2737. {
  2738. // will generate according to the x-ray position
  2739. // this shouldn't happen
  2740. extraSegments.push_back(BrukerSegment());
  2741. extraSegments[extraSegments.size() - 1].XStart = a_vXPoints[i]->GetPosition().x;
  2742. extraSegments[extraSegments.size() - 1].Y = a_vXPoints[i]->GetPosition().y;
  2743. features[i].SegmentCount = 1;
  2744. features[i].pSegment = &extraSegments[extraSegments.size() - 1];
  2745. pixelTimes[i] = (WORD)(a_nACTimeMS * 1000);
  2746. }
  2747. }
  2748. // ask bruker to collect a set of x-ray data
  2749. if (!StartFeatureListMeasurement(nCollectCount, features, pixelTimes))
  2750. {
  2751. // failed to call StartFeatureListMeasurement method
  2752. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call StartFeatureListMeasurement method."));
  2753. return FALSE;
  2754. }
  2755. // get the specs for a_vXPoints
  2756. if (!SetXRayPointsByFeature(a_vXPoints, a_nACTimeMS))
  2757. {
  2758. // failed to call ReadXRayPointsByFeature method
  2759. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::CollectXRayPointsByFeatures: failed to call ReadXRayPointsByFeature method."));
  2760. return FALSE;
  2761. }
  2762. delete[] pixelTimes;
  2763. delete[] features;
  2764. // ok, return TRUE
  2765. return TRUE;
  2766. }
  2767. BOOL COTSBrukerImpl::SetXRayPointsByFeature(CPosXraysList& a_vXPoints, const DWORD a_nACTimeMS)
  2768. {
  2769. // Fail a_vXPoints is empty
  2770. if (a_vXPoints.empty())
  2771. {
  2772. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature:Empty point list given in argument a_oPointList"));
  2773. return TRUE;
  2774. }
  2775. long nCollectCount = (long)a_vXPoints.size();
  2776. // get the specs for a_vXPoints
  2777. static DWORD nChannelData[(int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS];
  2778. for (int i = 0; i < nCollectCount; ++i)
  2779. {
  2780. // cleanup data storage
  2781. memset(nChannelData, 0, sizeof(DWORD) * (int)BRUKER_PARAM::RT_SPECTRUM_CHANNELS);
  2782. if (m_bDoQuantification)
  2783. {
  2784. // quantify the spectrum
  2785. char* pcMethod = "Default";//"Default";// "Automatic";
  2786. char* pcParams = "ResultType=quantification";
  2787. char cResult[10000];
  2788. memset(cResult, 0, 10000);
  2789. if (!m_pBrukerDllHandle->QuantifyFeatureListSpectrum(m_nClientID, i, pcMethod, pcParams, cResult, 10000, (RTSpectrumHeaderRec*)m_psRTSpectrumBuffer.get(), (int)BRUKER_PARAM::RT_SPECTRUM_BUFFER_SIZE))
  2790. {
  2791. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::SetXRayPoints failed to call QuantifyPointListSpectrum method, error code %d"), m_pBrukerDllHandle->GetLastReturn());
  2792. //return FALSE;
  2793. }
  2794. CElementChemistriesList listElement = CElement::ExtractElementChemistrys(CControllerHelper::CharToString(cResult));
  2795. a_vXPoints[i]->SetElementQuantifyData(listElement);
  2796. }
  2797. // get spectrum data of a point
  2798. bool success = GetFeatureListSpectrum(i, (long*)nChannelData);
  2799. if (!success)
  2800. {
  2801. // error
  2802. CPoint poi = a_vXPoints[i]->GetPosition();
  2803. LogErrorTrace(__FILE__, __LINE__, _T("COTSBrukerImpl::ReadXRayPointsByFeature:Call GetFeatureListSpectrum failed: index = %d(x:%d, y:%d)"),
  2804. i,
  2805. poi.x,
  2806. poi.y);
  2807. return FALSE;
  2808. }
  2809. // set spectrum data for the x-ray point
  2810. a_vXPoints[i]->SetXrayData(nChannelData);
  2811. }
  2812. return TRUE;
  2813. }
  2814. BOOL COTSBrukerImpl::GetLoadDllName(CString& csDllName)
  2815. {
  2816. /*COTSXmlFileDllExportPtr lpXMLDllExport = COTSXmlFileDllExportPtr(new COTSXmlFileDllExport);
  2817. return lpXMLDllExport->GetBrukerDLLVersion(DllXMLFileName,csDllName);*/
  2818. tinyxml2::XMLDocument doc;
  2819. doc.LoadFile(DllXMLFileName);//载入xml文件
  2820. xmls::Slo subClass;
  2821. xmls::xString szS;
  2822. subClass.Register("Version", &szS);
  2823. subClass.Register("BrukerDllVersion", &subClass);
  2824. tinyxml2::XMLElement *rootNode;
  2825. rootNode = doc.FirstChildElement(RootClassName);
  2826. subClass.Serialize(false, &doc, rootNode);
  2827. csDllName = szS.value().c_str();
  2828. return true;
  2829. }
  2830. }