IRayDMCtrl.cpp 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975
  1. #include "stdafx.h"
  2. #include "IRayDMCtrl.h"
  3. IRayCtrl* g_pIRayCtrl = nullptr;
  4. const int INIT_TIMEOUT = 10000;
  5. void SDKCallbackProxy(int nDetectorID, int nEventID, int nEventLevel, const char* pszMsg, int nParam1, int nParam2, int nPtrParamLen, void* pParam)
  6. {
  7. g_pIRayCtrl->ProcessEvent(nDetectorID, nEventID, nEventLevel, pszMsg, nParam1, nParam2, nPtrParamLen, pParam);
  8. }
  9. void FpdScanResult(DetectorProfile* pDetectorProfile)
  10. {
  11. g_pIRayCtrl->ScanResult(pDetectorProfile);
  12. }
  13. IRayCtrl::IRayCtrl()
  14. {
  15. m_hInitThread = NULL;
  16. m_hScanEventThread = NULL;
  17. m_pDPC2PanelID = new map<nsDPC::FPDDeviceIRay*, int>();
  18. m_pPanelID2DPC = new map<int, nsDPC::FPDDeviceIRay*>();
  19. //m_pImageBuffer = NULL;
  20. m_nPanelCount = 0;
  21. m_nCurrentPanelID = 0;
  22. m_strWorkPath = "";
  23. m_bOpened = false;
  24. m_eAppStatus = APP_STATUS_IDLE;
  25. m_nCurrentMode = -1;
  26. m_nImageWidth = 0;
  27. m_nImageHeight = 0;
  28. m_nRawImgWidth = 0;
  29. m_nRawImgHeight = 0;
  30. m_nWidthOffset = 0;
  31. m_nHeightOffset = 0;
  32. m_pImgBuffer = NULL;
  33. m_nImgBits = 16;
  34. m_nPixelPitch = 150;
  35. m_bPreviewEnable = false;
  36. m_nPreviewWidth = 0;
  37. m_nPreviewHeight = 0;
  38. m_bModuleConnecting = false;
  39. m_bModulePresent = false;
  40. m_bInCalibrating = false;
  41. m_pwPreviewImg = NULL;
  42. m_pwRawImageData = NULL;
  43. m_pXWindowoffThread = NULL;
  44. m_pOffsetThread = NULL;
  45. m_bInExposure = false;
  46. m_bWindowOn = false;
  47. m_nRecoverImageTimes = 0;
  48. m_hInitThread = NULL;
  49. m_hScanEventThread = NULL;
  50. for (int i = 0; i < SCAN_EVENT_NUM; ++i)
  51. {
  52. m_hArrayEvent[i] = nullptr;
  53. }
  54. m_hExitEvent = NULL;
  55. m_hRecoverImage = NULL;
  56. m_hCofirmCalib = NULL;
  57. m_hEndCalibEvent = NULL;
  58. m_hIRayModule = nullptr;
  59. m_fpGetSDKVersion = nullptr;
  60. m_fpSetUserCode = nullptr;
  61. m_fpNotifyScanResult = nullptr;
  62. m_fpRegisterScanNotify = nullptr;
  63. m_fpScanOnce = nullptr;
  64. m_fpCallback = nullptr;
  65. m_fpCreate = nullptr;
  66. m_fpDestroy = nullptr;
  67. m_fpGetAttr = nullptr;
  68. m_fpSetAttr = nullptr;
  69. m_fpInvoke = nullptr;
  70. m_fpAbort = nullptr;
  71. m_fpOpenDefectTemplateFile = nullptr;
  72. m_fpSaveDefectTemplateFile = nullptr;
  73. m_fpCloseDefectTemplateFile = nullptr;
  74. m_bOpened = false;
  75. m_bInitialing = false;
  76. m_nAppMode = 0;
  77. m_nExpMode = 0;
  78. m_nFilterMode = 0;
  79. m_nTotalFrameNum = 0;
  80. m_nCurrentFrame = 0;
  81. m_nTriggerMode = 0;
  82. m_nClinicalApplicationMode = 0;
  83. }
  84. IRayCtrl::~IRayCtrl()
  85. {
  86. ExitDetectorScanThread();
  87. if (m_pImgBuffer)
  88. {
  89. delete[] m_pImgBuffer;
  90. m_pImgBuffer = NULL;
  91. }
  92. if (m_pwPreviewImg)
  93. {
  94. delete[]m_pwPreviewImg;
  95. m_pwPreviewImg = NULL;
  96. }
  97. if (m_pwRawImageData)
  98. {
  99. delete[]m_pwRawImageData;
  100. m_pwRawImageData = NULL;
  101. }
  102. delete m_pDPC2PanelID;
  103. m_pDPC2PanelID = NULL;
  104. delete m_pPanelID2DPC;
  105. m_pPanelID2DPC = NULL;
  106. }
  107. bool IRayCtrl::ExitDetectorScanThread()
  108. {
  109. m_bOpened = false;
  110. SetEvent(m_hExitEvent);
  111. Info("Waiting iRay ScanEvent Thread End");
  112. DWORD nResult = WaitForSingleObject(m_hIRayScanEnd, 5000);
  113. if (WAIT_TIMEOUT == nResult) //m_hIRayScanEnd
  114. {
  115. Error("Detector ScanEvent Thread Quit TimeOut");
  116. ::TerminateThread(m_hScanEventThread, 0);
  117. }
  118. else
  119. {
  120. Info("Detector ScanEvent Thread Quit Success");
  121. }
  122. m_hScanEventThread = NULL;
  123. DeleteHandle();
  124. Info("Free IRay DLL");
  125. FreeIRayDLL();
  126. return true;
  127. }
  128. void IRayCtrl::DeleteHandle()
  129. {
  130. if (m_hSharedEvent)
  131. {
  132. CloseHandle(m_hSharedEvent);
  133. m_hSharedEvent = NULL;
  134. }
  135. if (m_hExitEvent)
  136. {
  137. CloseHandle(m_hExitEvent);
  138. m_hExitEvent = NULL;
  139. }
  140. if (m_hRecoverImage)
  141. {
  142. CloseHandle(m_hRecoverImage);
  143. m_hRecoverImage = NULL;
  144. }
  145. if (m_hCofirmCalib)
  146. {
  147. CloseHandle(m_hCofirmCalib);
  148. m_hCofirmCalib = NULL;
  149. }
  150. if (m_hEndCalibEvent)
  151. {
  152. CloseHandle(m_hEndCalibEvent);
  153. m_hEndCalibEvent = NULL;
  154. }
  155. if (m_hIRayScanEnd)
  156. {
  157. CloseHandle(m_hIRayScanEnd);
  158. m_hIRayScanEnd = NULL;
  159. }
  160. }
  161. bool IRayCtrl::Init(string strAppPath)
  162. {
  163. m_strWorkPath = strAppPath + "OEMDrivers\\Detector\\IRayDM\\IRay";
  164. Info("IRayCtrl::Init {$}", m_strWorkPath.c_str());
  165. bool ret = false;
  166. ret = LoadIRayDLL(m_strWorkPath);
  167. if (!ret)
  168. {
  169. Error("LoadIRayDLL failed");
  170. return false;
  171. }
  172. //同步事件锁
  173. m_hSharedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  174. //开窗控制事件
  175. m_hWindowOffEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  176. int nResult = 0;
  177. char szVersion[32] = { 0 };
  178. nResult = m_fpGetSDKVersion(szVersion);
  179. if (Err_OK != nResult)
  180. {
  181. Fatal("Get Attachment SDK Version failed!");
  182. return false;
  183. }
  184. Info("Get iRay Mammo SDK version: {$}", szVersion);
  185. /*Info("Call RegisterScanNotify");
  186. DetectorProfile* FpdScanResult = nullptr;
  187. m_fpNotifyScanResult(FpdScanResult);*/
  188. Info("Init over\n");
  189. return ret;
  190. }
  191. bool IRayCtrl::LoadIRayDLL(string strWorkPath)
  192. {
  193. Info("IRayCtrl::LoadIRayDLL");
  194. string strDllDir = strWorkPath;
  195. if (::SetDllDirectory(strDllDir.c_str()) == 0)
  196. {
  197. DWORD dwErrorCode = GetLastError();
  198. Info("SetDllDirectory error, error code ({$})", dwErrorCode);
  199. return false;
  200. }
  201. string strDllPath = strWorkPath + "\\FpdSys_MAM.dll";
  202. Info("Load {$}", strDllPath);
  203. m_hIRayModule = ::LoadLibrary(strDllPath.c_str());
  204. if (NULL == m_hIRayModule)
  205. {
  206. Fatal("Load FpdSys_MAM.dll failed!");
  207. return false;
  208. }
  209. m_fpGetSDKVersion = (FnGetSDKVersion)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_VERSION);
  210. if (NULL == m_fpGetSDKVersion)
  211. {
  212. Fatal("API GetSDKVersion failed");
  213. return false;
  214. }
  215. m_fpSetUserCode = (FnSetUserCode)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_SET_USERCODE);
  216. if (NULL == m_fpSetUserCode)
  217. {
  218. Fatal("API SetUserCode failed");
  219. return false;
  220. }
  221. m_fpNotifyScanResult = (FnNotifyScanResult)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_REGISTER_SCANNotify);
  222. if (NULL == m_fpNotifyScanResult)
  223. {
  224. Fatal("API NotifyScanResult failed");
  225. return false;
  226. }
  227. m_fpCreate = (FnCreate)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_CREATE);
  228. if (NULL == m_fpCreate)
  229. {
  230. Fatal("GetProcAddress:Create failed!");
  231. return false;
  232. }
  233. m_fpDestroy = (FnDestroy)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_DESTROY);
  234. if (NULL == m_fpDestroy)
  235. {
  236. Fatal("GetProcAddress:Destroy failed!");
  237. return false;
  238. }
  239. m_fpGetAttr = (FnGetAttr)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_GETATTR);
  240. if (NULL == m_fpGetAttr)
  241. {
  242. Fatal("GetProcAddress:GetAttr failed!");
  243. return false;
  244. }
  245. m_fpSetAttr = (FnSetAttr)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_SETATTR);
  246. if (NULL == m_fpSetAttr)
  247. {
  248. Fatal("GetProcAddress:SetAttr failed!");
  249. return false;
  250. }
  251. m_fpInvoke = (FnInvoke)GetProcAddress(m_hIRayModule, IRAY_FPD_PROC_NAME_INVOKE);
  252. if (NULL == m_fpInvoke)
  253. {
  254. Fatal("GetProcAddress:Invoke failed!");
  255. return false;
  256. }
  257. Info("LoadIRayDLL over");
  258. return true;
  259. }
  260. bool IRayCtrl::FreeIRayDLL()
  261. {
  262. if (m_hIRayModule)
  263. {
  264. FreeLibrary(m_hIRayModule);
  265. m_hIRayModule = NULL;
  266. Info("Free IRay DLL");
  267. }
  268. return true;
  269. }
  270. bool IRayCtrl::AddDPCs(nsDPC::FPDDeviceIRay* pDrvDPC, ResDataObject& Configuration, DeviceIndexStruct& DeviceStruct)
  271. {
  272. Info("IRayCtrl::AddDPCs {$}", pDrvDPC);
  273. map<nsDPC::FPDDeviceIRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  274. if (DPCsIter != m_pDPC2PanelID->end())
  275. {
  276. Info("IRayCtrl::AddDPCs This DPC already exist");
  277. return false;
  278. }
  279. //拿到当前探测器的配置
  280. m_stDeviceIndex[m_nPanelCount] = DeviceStruct;
  281. m_ObjFPDsInfo[m_nPanelCount] = Configuration;
  282. Info("AddDPCs, {$}{$} \n", m_stDeviceIndex[m_nPanelCount].strDetectorModel, m_stDeviceIndex[m_nPanelCount].strDeviceName);
  283. m_pDPC2PanelID->insert(pair<nsDPC::FPDDeviceIRay*, int>(pDrvDPC, m_nPanelCount));
  284. m_pPanelID2DPC->insert(pair<int, nsDPC::FPDDeviceIRay*>(m_nPanelCount, pDrvDPC));
  285. m_ModeConfig = m_ObjFPDsInfo[m_nCurrentPanelID];
  286. m_nPanelCount++;
  287. Info("AddDPCs over, Panel count: {$}", m_nPanelCount);
  288. return true;
  289. }
  290. bool IRayCtrl::DelDPCs(nsDPC::FPDDeviceIRay* pDrvDPC)
  291. {
  292. Info("IRayCtrl::DelDPCs {$}", pDrvDPC);
  293. map<nsDPC::FPDDeviceIRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  294. if (DPCsIter != m_pDPC2PanelID->end())
  295. {
  296. map<int, nsDPC::FPDDeviceIRay*>::iterator PanelIdIter = m_pPanelID2DPC->find(DPCsIter->second);
  297. if (PanelIdIter != m_pPanelID2DPC->end())
  298. {
  299. m_pPanelID2DPC->erase(PanelIdIter);
  300. }
  301. m_stDeviceIndex[DPCsIter->second] = {};
  302. m_ObjFPDsInfo[DPCsIter->second].clear();
  303. m_pDPC2PanelID->erase(DPCsIter);
  304. m_nPanelCount--;
  305. Info("DelDPCs over {$}\n", m_nPanelCount);
  306. }
  307. return true;
  308. }
  309. void IRayCtrl::ConfFeedback(int nEventID, int nDetectorID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  310. {
  311. if (-1 == nDetectorID)
  312. {
  313. nDetectorID = m_nCurrentPanelID;
  314. }
  315. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_CONFIGURATION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  316. }
  317. void IRayCtrl::InfoFeedback(int nEventID, int nDetectorID, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, void* pParam)
  318. {
  319. if (-1 == nDetectorID)
  320. {
  321. nDetectorID = m_nCurrentPanelID;
  322. }
  323. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_INFORMATOION, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  324. }
  325. void IRayCtrl::StatusFeedback(int nEventID, int nParam1, const char* pszMsg, int nDetectorID, float fParam2, int nPtrParamLen, void* pParam)
  326. {
  327. if (-1 == nDetectorID)
  328. {
  329. nDetectorID = m_nCurrentPanelID;
  330. }
  331. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_STATUS, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  332. }
  333. void IRayCtrl::DataFeedback(int nEventID, void* pParam, int nParam1, float fParam2, const char* pszMsg, int nPtrParamLen, int nDetectorID)
  334. {
  335. if (-1 == nDetectorID)
  336. {
  337. nDetectorID = m_nCurrentPanelID;
  338. }
  339. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_DATA, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  340. }
  341. void IRayCtrl::WarnFeedback(int nEventID, const char* pszMsg, int nParam1, float fParam2, int nPtrParamLen, void* pParam, int nDetectorID)
  342. {
  343. if (-1 == nDetectorID)
  344. {
  345. nDetectorID = m_nCurrentPanelID;
  346. }
  347. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_WARNING, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  348. }
  349. void IRayCtrl::ErrorFeedback(int nEventID, const char* pszMsg, int nDetectorID, int nParam1, float fParam2, int nPtrParamLen, void* pParam)
  350. {
  351. if (-1 == nDetectorID)
  352. {
  353. nDetectorID = m_nCurrentPanelID;
  354. }
  355. ((*m_pPanelID2DPC)[nDetectorID])->OnFPDCallback(nDetectorID, nEventID, EVT_LEVEL_ERROR, pszMsg, nParam1, fParam2, nPtrParamLen, pParam);
  356. }
  357. /***
  358. ** 说明:连接,加载SDK,初始化SDK,连接探测器等初始化操作。
  359. ** 参数:strWorkPath,初始化SDK必须的conf路径
  360. ***/
  361. bool IRayCtrl::Connect(string strAppPath, nsDPC::FPDDeviceIRay* pDrvDPC)
  362. {
  363. Info("IRayCtrl::Connect");
  364. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  365. {
  366. Warn("Not current DPC, return true");
  367. return true;
  368. }
  369. g_strAppPath = strAppPath;
  370. Info("APP Path: {$}", g_strAppPath);
  371. StartInitFPDThread();
  372. Info("=== Connect detector OK ===");
  373. return true;
  374. }
  375. /***
  376. * 说明:断连探测器
  377. * 参数:pDrvDPC: 探测器的ID。
  378. ***/
  379. bool IRayCtrl::DisConnect(nsDPC::FPDDeviceIRay* pDrvDPC)
  380. {
  381. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  382. {
  383. Warn("Not current DPC, return");
  384. return true;
  385. }
  386. Info("IRayCtrl::DisConnect");
  387. int nPanelID = m_nCurrentPanelID + 1;
  388. int nResult = IrayFnInvoke(nPanelID, Cmd_Disconnect, NULL, 0);
  389. if (TestError(m_nCurrentPanelID, nResult))
  390. {
  391. Info("Disconnect Detector {$} Failed", nPanelID);
  392. }
  393. Info("Call Destroy");
  394. nResult = m_fpDestroy(nPanelID);
  395. TestError(m_nCurrentPanelID, nResult);
  396. Info("DisConnect Over");
  397. return true;
  398. }
  399. FPDRESULT IRayCtrl::IrayFnInvoke(int nDetectorID, int nCommandID, IRayCmdParam pars[], int nParCount)
  400. {
  401. int trytimes = 0;
  402. FPDRESULT nResult = Err_OK;
  403. while (trytimes++ < 6)
  404. {
  405. nResult = m_fpInvoke(nDetectorID, nCommandID, pars, nParCount);
  406. if (Err_StateErr != nResult)
  407. return nResult;
  408. else
  409. Sleep(1000);
  410. }
  411. return nResult;
  412. }
  413. bool IRayCtrl::TestError(int nDetectorID, int nErrorStatus)
  414. {
  415. string strLog = "";
  416. switch (nErrorStatus)
  417. {
  418. case Err_OK:
  419. return false;
  420. case Err_TaskPending:
  421. {
  422. return false;
  423. }
  424. case Err_Unknown:
  425. Fatal("Err_Unknown");
  426. break;
  427. case Err_NotInitialized:
  428. Fatal("Err_NotInitialized");
  429. break;
  430. case Err_TemplateFileNotExist:
  431. case Err_TemplateFileNotMatch:
  432. break;
  433. case Err_InvalidPacketNo:
  434. case Err_InvalidPacketFormat:
  435. case Err_PacketDataCheckFailed:
  436. Fatal("25/26/27 Transfering image not finished");
  437. break;
  438. case Err_ImgChBreak:
  439. Fatal("Err_ImgChBreak");
  440. break;
  441. case Err_GeneralSocketErr:
  442. Fatal("Err_GeneralSocketErr");
  443. break;
  444. case Err_ApplyFirmwareFailed:
  445. case Err_FPD_General_Detector_Error:
  446. case Err_FPD_Busy:
  447. case Err_TaskTimeOut:
  448. case Err_DetectorRespTimeout:
  449. break;
  450. case Err_NotEnoughMemorySpace:
  451. break;
  452. case Err_ConfigFileNotExist:
  453. default:
  454. Error("Get ErrCode: {$} ", nErrorStatus);
  455. break;
  456. }
  457. return true;
  458. }
  459. //启动初始化线程
  460. void IRayCtrl::StartInitFPDThread()
  461. {
  462. Info("-----Start Init Thread------");
  463. DWORD dwThreadID;
  464. if (m_hInitThread == NULL)
  465. {
  466. m_hInitThread = CreateThread(0, 0, onInitPanel, this, 0, &dwThreadID);
  467. if (m_hInitThread == NULL)
  468. {
  469. Fatal("Start Init Thread Error");
  470. }
  471. }
  472. }
  473. //初始化
  474. DWORD IRayCtrl::onInitPanel(void* pParam)
  475. {
  476. IRayCtrl* pInstance = reinterpret_cast<IRayCtrl*>(pParam);
  477. pInstance->Action_Init();
  478. pInstance->m_hInitThread = NULL;
  479. return true;
  480. }
  481. void IRayCtrl::Action_Init()
  482. {
  483. Info("IRayCtrl::Action_Init");
  484. m_bInitialing = true;
  485. int nPanelID = 0;
  486. m_stDeviceIndex[nPanelID].strWorkDir = g_strAppPath + "\\OEMDrivers\\Detector\\IRayDM\\IRay\\work_dir\\Mammo1012F2";
  487. string strWorkDir = (m_stDeviceIndex[nPanelID].strWorkDir);
  488. Info("Call Create: {$}", strWorkDir.c_str());
  489. int nRet = m_fpCreate(strWorkDir.c_str(), SDKCallbackProxy, &nPanelID);
  490. if (TestError(nPanelID, nRet))
  491. {
  492. Error("Create Detector {$} Callback Failed", nPanelID);
  493. }
  494. Info("Create Detector {$} Callback Success", nPanelID);
  495. bool bRet = DetectorInitProcess(nPanelID);
  496. if (!bRet)
  497. {
  498. Info("Detector init process connect failed");
  499. }
  500. iRayScanEventThread();
  501. //获取探测器当前触发模式
  502. GetSyncMode(nPanelID, m_nTriggerMode);
  503. Info("Get Mammo trigger mode: {$}({$})", TriggerModeName(m_nTriggerMode), m_nTriggerMode);
  504. //if (m_nTriggerMode != Enm_TriggerMode_Prep) //如果不是Prep触发方式,那么切换到该模式
  505. if (m_nTriggerMode != Enm_TriggerMode_SyncOut)
  506. {
  507. SetSyncMode(nPanelID, Enm_TriggerMode_SyncOut);
  508. }
  509. int nOffsetType = 0;
  510. //生成HW_Offset
  511. PerformOffset(nPanelID, nOffsetType);
  512. m_bInitialing = false;
  513. Info("Action init over");
  514. }
  515. /************************************************************************************
  516. 功能:启动辅助线程,处理一些异步消息
  517. ************************************************************************************/
  518. void IRayCtrl::iRayScanEventThread()
  519. {
  520. m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  521. m_hRecoverImage = CreateEvent(NULL, FALSE, FALSE, NULL);
  522. m_hCofirmCalib = CreateEvent(NULL, FALSE, FALSE, NULL);
  523. m_hEndCalibEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  524. m_hOffsetEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  525. m_hIRayScanEnd = CreateEvent(NULL, FALSE, FALSE, NULL);
  526. m_hArrayEvent[0] = m_hExitEvent;
  527. m_hArrayEvent[1] = m_hRecoverImage;
  528. m_hArrayEvent[2] = m_hCofirmCalib;
  529. m_hArrayEvent[3] = m_hEndCalibEvent;
  530. m_hArrayEvent[4] = m_hOffsetEvent;
  531. if (m_hScanEventThread != NULL)
  532. {
  533. Info("ScanEvent Thread already run\n");
  534. return;
  535. }
  536. Info("Start ScanEvent Thread");
  537. DWORD dwThreadID;
  538. m_hScanEventThread = (HANDLE)CreateThread(NULL, 0, onScanEvent, (LPVOID)this, 0, &dwThreadID);
  539. if (m_hScanEventThread == NULL)
  540. {
  541. Fatal("Start Scan Event Error");
  542. }
  543. Info("Start ScanEvent Thread ok, ThreadID: {$}", dwThreadID);
  544. }
  545. /************************************************************************************
  546. 功能:启动线程,处理一些异步消息
  547. m_hRecoverImage 异步,恢复图像
  548. m_hCofirmCalib 异步,确认每一次校正的结果,如剂量大了/小了/
  549. m_hReconnectFD 异步,初始化探测器
  550. ************************************************************************************/
  551. DWORD IRayCtrl::onScanEvent(void* pParam)
  552. {
  553. IRayCtrl* pInstance = (IRayCtrl*)pParam;
  554. if (pInstance == NULL)
  555. {
  556. Error("onScanEvent parameter error!!!");
  557. return false;
  558. }
  559. bool bExitFlag = true;
  560. while (bExitFlag)
  561. {
  562. Info("(Waiting for Signal...)");
  563. DWORD dwResult = WaitForMultipleObjects(SCAN_EVENT_NUM, pInstance->m_hArrayEvent, FALSE, INFINITE);
  564. if (WAIT_OBJECT_0 == dwResult) //m_hExitEvent
  565. {
  566. Info("[Get Exit Event]");
  567. bExitFlag = false;
  568. }
  569. else if (WAIT_OBJECT_0 + 1 == dwResult) //m_hRecoverImage
  570. {
  571. //pInstance->CallSiemensRecoverAction(true);
  572. if (pInstance->m_nRecoverImageTimes < 2)
  573. {
  574. Info("[Get RecoverImage Event]");
  575. pInstance->m_nRecoverImageTimes++;
  576. //pInstance->RecoverLastImageAuto();
  577. }
  578. else
  579. {
  580. Info("Get RecoverImage Event already retry 2 times, omit it");
  581. }
  582. }
  583. else if (WAIT_OBJECT_0 + 2 == dwResult) //m_hCofirmCalib
  584. {
  585. Info("[Get Cofirm Calibration Event]");
  586. //pInstance->ConfirmCalibration();
  587. }
  588. else if (WAIT_OBJECT_0 + 3 == dwResult) //m_hEndCalibEvent
  589. {
  590. Info("[Get EndCalibraion Event]");
  591. //pInstance->OnEndCalibraion();
  592. }
  593. else if (WAIT_OBJECT_0 + 4 == dwResult) //m_hOffsetEvent
  594. {
  595. Info("[Get Offset Event]");
  596. pInstance->PerformOffset(pInstance->m_nCurrentPanelID + 1, 0);
  597. }
  598. }
  599. SetEvent(pInstance->m_hIRayScanEnd);
  600. Info("iRay ScanEvent Thread End");
  601. return true;
  602. }
  603. bool IRayCtrl::WaitRespond(int nTimeOut)
  604. {
  605. Info("---WaitRespond---:{$}", nTimeOut);
  606. DWORD nResult = WaitForSingleObject(m_hSharedEvent, nTimeOut);
  607. if (WAIT_TIMEOUT == nResult) //偶尔会出现EVT_HARDWARE太慢的情况
  608. {
  609. Warn("Lock TimeOut");//出现超时,肯定是有问题了
  610. ResetEvent(m_hSharedEvent);
  611. return false;
  612. }
  613. ResetEvent(m_hSharedEvent);
  614. return true;
  615. }
  616. void IRayCtrl::SendNotify()
  617. {
  618. Info("---SendNotify---");
  619. SetEvent(m_hSharedEvent);
  620. }
  621. void IRayCtrl::ResetLock()
  622. {
  623. ResetEvent(m_hSharedEvent);
  624. }
  625. void IRayCtrl::Pausetime(DWORD dwSpan)
  626. {
  627. DWORD dtstart = ::GetTickCount();
  628. while ((::GetTickCount() - dtstart) < dwSpan)
  629. {
  630. MSG msg;
  631. while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  632. {
  633. ::TranslateMessage(&msg);
  634. ::DispatchMessage(&msg);
  635. }
  636. }
  637. }
  638. bool IRayCtrl::WaitReady(int nPanelIndex, int nMs)
  639. {
  640. int nState = 0;
  641. int nWaitMs = 0;
  642. bool bResult = true;
  643. string strLog;
  644. /*do
  645. {
  646. bResult = GetDetectorStatus(nPanelIndex, nState);
  647. if (nState == Enm_State_Ready)
  648. {
  649. return true;
  650. }
  651. else
  652. {
  653. nWaitMs += 100;
  654. Pausetime(100);
  655. Info("WaitReady has waited [{$}] ms", nWaitMs);
  656. }
  657. } while (nWaitMs < nMs);*/
  658. return false;
  659. }
  660. bool IRayCtrl::DetectorInitProcess(int nDetectorID)
  661. {
  662. int nPanelIndex = nDetectorID - 1;
  663. Info("Call FnInvoke: Connect");
  664. m_stDeviceIndex[nDetectorID].bEventReturn = false;
  665. int nRet = IrayFnInvoke(nDetectorID, Cmd_Connect, NULL, 0);
  666. if (TestError(nDetectorID, nRet))
  667. {
  668. Error("Connect Detector {$} Failed", nDetectorID);
  669. return false;
  670. }
  671. bool bResult = WaitRespond(INIT_TIMEOUT);
  672. if (!m_stDeviceIndex[nDetectorID - 1].bConnectStatus)
  673. {
  674. Info("Connect Detector {$} Failed", nDetectorID);
  675. }
  676. Info("Connect Detector {$} Success", nDetectorID);
  677. m_stDeviceIndex[nPanelIndex].nPixelSpace = 139;
  678. m_stDeviceIndex[nPanelIndex].bExisted = true;
  679. m_stDeviceIndex[nPanelIndex].bInitOK = true;
  680. char pszSerialNo[64] = { 0 };
  681. nRet = GetAttr(nDetectorID, Attr_UROM_SerialNo, pszSerialNo);
  682. if (TestError(nDetectorID, nRet))
  683. {
  684. Info("Get detector serial number failed");
  685. }
  686. Info("Detector serial number: {$}", pszSerialNo);
  687. char pszMainVersion[64] = { 0 };
  688. nRet = GetAttr(nDetectorID, Attr_UROM_MainVersion, pszMainVersion);
  689. if (TestError(nDetectorID, nRet))
  690. {
  691. Info("Get detector main version failed");
  692. }
  693. Info("Detector main version: {$}", pszMainVersion);
  694. char pszSDKVersion[32] = { 0 };
  695. nRet = m_fpGetSDKVersion(pszSDKVersion);
  696. if (TestError(nDetectorID, nRet))
  697. {
  698. Info("Get SDK version failed");
  699. }
  700. Info("SDK version: {$}", pszSDKVersion);
  701. OnInitStatus(nPanelIndex, PANEL_EVENT_END_OK);
  702. return true;
  703. }
  704. bool IRayCtrl::OnInitStatus(int nPanelIndex, ENUM_PANEL_EVENT_STATE ePanelState)
  705. {
  706. int nDetectorID = 0;
  707. if (PANEL_EVENT_START == ePanelState)
  708. {
  709. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_START, "");
  710. }
  711. else if (PANEL_EVENT_END_OK == ePanelState)
  712. {
  713. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_OK, "");
  714. }
  715. else if (PANEL_EVENT_END_ERROR == ePanelState)
  716. {
  717. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END_ERROR, "");
  718. }
  719. else if (PANEL_EVENT_END == ePanelState) //未连接探测器
  720. {
  721. StatusFeedback(EVT_STATUS_INIT, PANEL_EVENT_END, "");
  722. }
  723. return true;
  724. }
  725. void IRayCtrl::ProcessEvent(int nDetectorID, int nEventID, int nEventLevel, const char* pszMsg, int nParam1, int nParam2, int nPtrParamLen, void* pParam)
  726. {
  727. string strDescrip = (pszMsg);
  728. Info("DetectorID:{$},Event:{$},Param1:{$},Param2:{$},Description:{$}", nDetectorID, nEventID, nParam1, nParam2, strDescrip.c_str());
  729. switch (nEventID)
  730. {
  731. case Evt_Exp_Prohibit:
  732. {
  733. Info("[ Event:Evt_Exp_Prohibit]");
  734. }
  735. break;
  736. case Evt_Exp_Enable:
  737. {
  738. Info("[ Event:Evt_Exp_Enable]");
  739. StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
  740. m_bWindowOn = true;
  741. StartXWindowOffThread();
  742. }
  743. break;
  744. case Evt_TaskResult_Canceled:
  745. {
  746. Info("[ Evt_TaskResult_Canceled ]");
  747. }
  748. break;
  749. case Evt_AutoTask_Started:
  750. {
  751. Info("[ Evt_AutoTask_Started ]");
  752. }
  753. break;
  754. case Evt_TaskResult_Succeed:
  755. Info( "[ Evt_TaskResult_Succeed ]");
  756. OnProcessTaskResult(nDetectorID, nParam1, nParam2, true);
  757. break;
  758. case Evt_TaskResult_Failed:
  759. Info( "[ Evt_TaskResult_Failed ]");
  760. OnProcessTaskResult(nDetectorID, nParam1, nParam2, false);
  761. break;
  762. case Evt_Retransfer_Image:
  763. Info("[ Event:Evt_Retransfer_Image], Omit it");
  764. break;
  765. case Evt_Image:
  766. {
  767. m_stDeviceIndex[nDetectorID - 1].bConnectStatus = true;
  768. Info("[ Event:Evt_Image],Image ReadOut = true");
  769. IRayImage* pstImg = (IRayImage*)pParam;
  770. if (pstImg == NULL)
  771. {
  772. Fatal("Image Data is NULL");
  773. return;
  774. }
  775. /*for (size_t i = 0; i < pstImg->propList.nItemCount; i++)
  776. {
  777. switch (pstImg->propList.pItems[i].nMapKey)
  778. {
  779. case Enm_ImageTag_AvgValue:
  780. {
  781. int nAvgValue = pstImg->propList.pItems[i].varMapVal.val.nVal;
  782. Info("Image Avg Value:{$}", nAvgValue);
  783. break;
  784. }
  785. case Enm_ImageTag_CenterValue:
  786. {
  787. int nCenterValue = pstImg->propList.pItems[i].varMapVal.val.nVal;
  788. Info("Image Center Value : {$}", nCenterValue);
  789. break;
  790. }
  791. }
  792. }*/
  793. int nRawImgHeight = pstImg->nHeight;
  794. int nRawImgWidth = pstImg->nWidth;
  795. Info("Image Height:{$},Width:{$}", nRawImgHeight, nRawImgWidth);
  796. if (m_pwRawImageData)
  797. {
  798. delete[]m_pwRawImageData;
  799. m_pwRawImageData = NULL;
  800. }
  801. m_pwRawImageData = new WORD[nRawImgHeight * nRawImgWidth];
  802. if (m_pwRawImageData == NULL)
  803. {
  804. Fatal("Allocate Raw Image Failed");
  805. return;
  806. }
  807. memcpy(m_pwRawImageData, pstImg->pData, nRawImgHeight * nRawImgWidth * sizeof(WORD));
  808. FlipX(m_pwRawImageData, nRawImgWidth, nRawImgHeight);
  809. //memcpy(m_pImgBuffer, m_pwRawImageData, m_nImageHeight * m_nImageWidth * sizeof(WORD));
  810. OnProcessImg();
  811. }
  812. break;
  813. case Evt_Prev_Image:
  814. {
  815. Info("[ Event:Evt_Prev_Image]");
  816. IRayImage* pstImg = (IRayImage*)pParam;
  817. m_stDeviceIndex[nDetectorID - 1].nImageBits = pstImg->nBytesPerPixel * 8;
  818. int nPreviewHeight = pstImg->nHeight;
  819. int nPreviewWidth = pstImg->nWidth;
  820. if (m_pwPreviewImg != NULL)
  821. {
  822. delete[] m_pwPreviewImg;
  823. m_pwPreviewImg = NULL;
  824. }
  825. if (m_pwPreviewImg == NULL)
  826. {
  827. m_pwPreviewImg = new WORD[nPreviewHeight * nPreviewWidth];
  828. if (m_pwPreviewImg == NULL)
  829. {
  830. Fatal("Allocate Preview Image Memery Failed");
  831. return;
  832. }
  833. }
  834. memcpy(m_pwPreviewImg, pstImg->pData, nPreviewHeight * nPreviewWidth * sizeof(WORD));
  835. //OnProcessPreImg();
  836. }
  837. break;
  838. case Evt_WaitImage_Timeout:
  839. {
  840. Info("[ Evt_WaitImage_Timeout ],Omit");
  841. //string strError = ERR_FPD_FATAL_ERROR; //bug 8113
  842. //OnError(nDetectorID-1, strError, "");
  843. }
  844. break;
  845. case Evt_Mammo_Flow_End:
  846. {
  847. Info("[ Evt_Mammo_Flow_End ]");
  848. ((*m_pPanelID2DPC)[m_nCurrentPanelID])->m_bStatusInAEC = false;
  849. }
  850. break;
  851. default:
  852. break;
  853. }
  854. }
  855. void IRayCtrl::OnProcessTaskResult(int nPanelID, int nParam1, int nParam2, bool bResult)
  856. {
  857. int nDetectorID = nPanelID - 1;
  858. string strTaskResult = " Task Success";
  859. if (!bResult)
  860. {
  861. strTaskResult = " Task Failed";
  862. }
  863. switch (nParam1)
  864. {
  865. case 0:
  866. {
  867. TestError(nDetectorID, nParam2);
  868. if (Err_TemplateFileNotExist == nParam2)
  869. {
  870. Info("Template file no exist");
  871. }
  872. }
  873. break;
  874. case Cmd_Disconnect:
  875. {
  876. Info("FPD {$} is Disconnected", nPanelID);
  877. SendNotify();
  878. m_stDeviceIndex[nDetectorID].bExisted = false; //QUESTION
  879. m_stDeviceIndex[nDetectorID].bInitOK = false;
  880. m_stDeviceIndex[nDetectorID].bConnectStatus = false;
  881. //m_nBatteryCapacity = 0;
  882. //SendDetectorInfo(nDetectorID); //状态栏图标更新状态
  883. }
  884. break;
  885. case Cmd_Connect:
  886. Info("[ Cmd_Connect ]");
  887. m_stDeviceIndex[nDetectorID].bEventReturn = true;
  888. if (bResult)
  889. {
  890. Info("FPD {$} is Connected", nPanelID);
  891. m_stDeviceIndex[nDetectorID].bInitOK = true;//已经连接成功过了,后面不需要在connect了,等待SDK自动connect就可以了。
  892. m_stDeviceIndex[nDetectorID].bConnectStatus = true;
  893. m_stDeviceIndex[nDetectorID].bConnectChanged = true; //连接恢复之后,都要先查询一次有没有未传输成功的图像
  894. m_nCmdConnectResult = nParam2;
  895. SendNotify();
  896. }
  897. else
  898. {
  899. m_stDeviceIndex[nDetectorID].bConnectStatus = false;
  900. Fatal("FPD {$} connect failed", nPanelID);
  901. m_nCmdConnectResult = nParam2;
  902. }
  903. break;
  904. case Cmd_SetCaliSubset:
  905. {
  906. Info("Cmd_SetCaliSubset{$}", strTaskResult);
  907. SendNotify();
  908. }
  909. break;
  910. case Cmd_ReadUserROM:
  911. Info("[ Cmd_ReadUserROM ]");
  912. break;
  913. case Cmd_WriteUserROM:
  914. {
  915. m_stDeviceIndex[nDetectorID].bWriteROM = bResult;
  916. Info("Cmd_WriteUserROM {$}", strTaskResult.c_str());
  917. //SendNotify();
  918. }
  919. break;
  920. case Cmd_OffsetGeneration:
  921. {
  922. Info("Cmd_OffsetGeneration{$}", strTaskResult.c_str());
  923. SendNotify();
  924. }
  925. break;
  926. case Cmd_GainInit:
  927. {
  928. Info("Cmd_GainInit{$}", strTaskResult.c_str());
  929. SendNotify();
  930. }
  931. break;
  932. case Cmd_DefectInit:
  933. {
  934. Info("Cmd_DefectInit{$}", strTaskResult.c_str());
  935. SendNotify();
  936. }
  937. break;
  938. case Cmd_DefectSelectCurrent:
  939. {
  940. Info("Cmd_DefectSelectCurrent{$}", strTaskResult.c_str());
  941. SendNotify();
  942. }
  943. break;
  944. case Cmd_FinishGenerationProcess:
  945. {
  946. Info("Cmd_FinishGenerationProcess{$}", strTaskResult.c_str());
  947. SendNotify();
  948. }
  949. break;
  950. case Cmd_UpdateFirmware:
  951. {
  952. Info("Cmd_UpdateFirmware{$}", strTaskResult.c_str());
  953. m_stDeviceIndex[nDetectorID].bUpdateFirmware = bResult;
  954. if (TestError(nDetectorID, nParam2))
  955. {//失败时,发notify结束超时等待
  956. SendNotify();
  957. }
  958. //else 不发,等探测器重启后,由SDK callback Cmd_connect时发notify结束
  959. }
  960. break;
  961. case Cmd_ReadTemperature:
  962. {
  963. Info("Cmd_ReadTemperature{$}", strTaskResult.c_str());
  964. m_stDeviceIndex[nDetectorID].bReadTemperature = bResult;
  965. SendNotify();
  966. }
  967. break;
  968. case Cmd_SetCorrectOption:
  969. {
  970. Info("Cmd_SetCorrectOption{$}", strTaskResult.c_str());
  971. m_stDeviceIndex[nDetectorID].bSetCorrection = bResult;
  972. SendNotify();
  973. }
  974. break;
  975. case Cmd_ReadHumidity:
  976. {
  977. Info("Cmd_ReadHumidity");
  978. }
  979. break;
  980. case Cmd_ClearAcq:
  981. {
  982. Info("Cmd_ClearAcq{$}", strTaskResult.c_str());
  983. m_bInExposure = false;
  984. m_stDeviceIndex[nDetectorID].bTaskEnd = true;
  985. }
  986. break;
  987. case Cmd_Clear:
  988. {
  989. Info("Cmd_Clear");
  990. }
  991. break;
  992. case Cmd_StartAcq:
  993. {
  994. Info("Cmd_StartAcq{$}", strTaskResult.c_str());
  995. }
  996. break;
  997. case Cmd_HwGeneratePreOffsetTemplate:
  998. {
  999. m_stDeviceIndex[nDetectorID].bEventReturn = bResult;
  1000. Info("Cmd_HwGeneratePreOffsetTemplate{$}", strTaskResult.c_str());
  1001. m_stDeviceIndex[nDetectorID].bOffsetOver = false;
  1002. SendNotify();
  1003. }
  1004. break;
  1005. case Cmd_DownloadCaliFile:
  1006. {
  1007. Info("Cmd_DownloadCaliFile{$}", strTaskResult.c_str());
  1008. SendNotify();
  1009. }
  1010. break;
  1011. case Cmd_UploadCaliFile:
  1012. {
  1013. m_stDeviceIndex[nDetectorID].bUploadCalibFile = bResult;
  1014. Info("Cmd_UploadCaliFile{$}", strTaskResult.c_str());
  1015. SendNotify();
  1016. break;
  1017. }
  1018. case Cmd_SelectCaliFile:
  1019. {
  1020. m_stDeviceIndex[nDetectorID].bUploadCalibFile = bResult;
  1021. Info("Cmd_SelectCaliFile{$}", strTaskResult.c_str());
  1022. SendNotify();
  1023. }
  1024. break;
  1025. case Cmd_SetCurAppMode:
  1026. Info("Cmd_SetCurAppMode{$}", strTaskResult.c_str());
  1027. SendNotify();
  1028. break;
  1029. default:
  1030. break;
  1031. }
  1032. }
  1033. bool IRayCtrl::ScanResult(DetectorProfile* pDetectorProfile)
  1034. {
  1035. Info("Scan Product No:{$}", pDetectorProfile->nProdNo);
  1036. string strIP = pDetectorProfile->szIP;
  1037. Info("Scan Detector IP:{$}", strIP.c_str());
  1038. string strSN = pDetectorProfile->szSN;
  1039. Info("Scan Detector SN:{$}", strSN.c_str());
  1040. if (m_nPanelCount > 0)//SDK 会自动恢复连接,不需要再调用connect,反而会影响SDK的动作
  1041. {
  1042. }
  1043. return true;
  1044. }
  1045. bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, int& nValue)
  1046. {
  1047. IRayVariant var;
  1048. var.vt = IVT_INT;
  1049. var.val.nVal = 0;
  1050. FPDRESULT nResult = m_fpGetAttr(nDetectorID, nAttrID, &var);
  1051. if (TestError(nDetectorID - 1, nResult))
  1052. {
  1053. Fatal("Get Attribute Failed");
  1054. return false;
  1055. }
  1056. nValue = var.val.nVal;
  1057. return true;
  1058. }
  1059. bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, float& fValue)
  1060. {
  1061. float ftemp = 0.0f;
  1062. IRayVariant var;
  1063. var.vt = IVT_FLT;
  1064. var.val.fVal = ftemp;
  1065. FPDRESULT nResult = m_fpGetAttr(nDetectorID, nAttrID, &var);
  1066. if (TestError(nDetectorID - 1, nResult))
  1067. {
  1068. Fatal("Get Attribute Failed");
  1069. return false;
  1070. }
  1071. fValue = var.val.fVal;
  1072. return true;
  1073. }
  1074. bool IRayCtrl::GetAttr(int nDetectorID, int nAttrID, char* pszAttr)
  1075. {
  1076. IRayVariant var;
  1077. var.vt = IVT_STR;
  1078. memset(var.val.strVal, 0, IRAY_MAX_STR_LEN);
  1079. FPDRESULT nResult = m_fpGetAttr(nDetectorID, nAttrID, &var);
  1080. if (TestError(nDetectorID - 1, nResult))
  1081. {
  1082. Fatal("Get Attribute Failed");
  1083. return false;
  1084. }
  1085. size_t len = strlen(var.val.strVal);
  1086. strcpy_s(pszAttr, len + 1, var.val.strVal);
  1087. return true;
  1088. }
  1089. bool IRayCtrl::SetAttr(int nDetectorID, int nAttrID, int nValue)
  1090. {
  1091. IRayVariant var;
  1092. var.vt = IVT_INT;
  1093. var.val.nVal = nValue;
  1094. FPDRESULT nResult = m_fpSetAttr(nDetectorID, nAttrID, &var);
  1095. if (TestError(nDetectorID - 1, nResult))
  1096. {
  1097. Fatal("Get Attribute Failed");
  1098. return false;
  1099. }
  1100. return true;
  1101. }
  1102. bool IRayCtrl::ActiveConfigurationMode(int nDetectorID, int nConfigurationID)
  1103. {
  1104. Info("Set current detector {$} configuration to {$}", nDetectorID, nConfigurationID);
  1105. string strConfigurationMode = "FfdmMainFilter1";
  1106. if (nConfigurationID == 2)
  1107. {
  1108. strConfigurationMode = "FfdmPreFilter1";
  1109. }
  1110. IRayCmdParam param[1];
  1111. param[0].pt = IPT_VARIANT;
  1112. param[0].var.vt = IVT_STR;
  1113. strncpy(param[0].var.val.strVal, strConfigurationMode.c_str(), IRAY_MAX_STR_LEN - 1);
  1114. int nResult = IrayFnInvoke(nDetectorID, Cmd_SetCaliSubset, param, 1);
  1115. if (TestError(nDetectorID, nResult))
  1116. {
  1117. Error("Cmd_SetCaliSubset to FfdmMainFilter1 failed");
  1118. return false;
  1119. }
  1120. WaitRespond(5000);
  1121. Info("({$})", strConfigurationMode);
  1122. Info("ActiveConfigurationMode over");
  1123. return true;
  1124. }
  1125. bool IRayCtrl::ActivePanel(nsDPC::FPDDeviceIRay* pDrvDPC, bool bActive)
  1126. {
  1127. Info("ActivePanel: {$}, m_nCurrentPanelID {$}", pDrvDPC, m_nCurrentPanelID);
  1128. map<nsDPC::FPDDeviceIRay*, int>::iterator DPCsIter = m_pDPC2PanelID->find(pDrvDPC);
  1129. return true;
  1130. }
  1131. /***
  1132. ** 说明:设置当前的曝光模式
  1133. ** 参数:nLogicMode,从配置文件读取,与SDK配置application mode对应
  1134. ***/
  1135. bool IRayCtrl::SelectExamMode(int nLogicMode, nsDPC::FPDDeviceIRay* pDrvDPC)
  1136. {
  1137. Info("IRayCtrl::SelectExamMode({$})", nLogicMode);
  1138. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  1139. {
  1140. Warn("Not current DPC {$}, {$} != {$}, return\n", pDrvDPC, (*m_pDPC2PanelID)[pDrvDPC], m_nCurrentPanelID);
  1141. return false;
  1142. }
  1143. if (m_stDeviceIndex[m_nCurrentPanelID].bConnectStatus == false)
  1144. {
  1145. Error("Current detector {$} is not connect, return\n", m_nCurrentPanelID);
  1146. return false;
  1147. }
  1148. m_nClinicalApplicationMode = nLogicMode;
  1149. if (m_nCurrentMode == nLogicMode) //同样appmode下没必要再次走下面的流程
  1150. {
  1151. Info("Same appmode, return true");
  1152. return true;
  1153. }
  1154. m_nCurrentMode = nLogicMode;
  1155. int nModeCount = (int)m_ModeConfig["ModeTable"].GetKeyCount("DetectorMode");
  1156. string strCoef;
  1157. for (int i = 0; i < nModeCount; i++)
  1158. {
  1159. if (nLogicMode == (int)m_ModeConfig["ModeTable"][i]["LogicMode"])
  1160. {
  1161. try
  1162. {
  1163. m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][i]["RawImgHeight"];
  1164. m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][i]["RawImgWidth"];
  1165. m_nImageWidth = (int)m_ModeConfig["ModeTable"][i]["ImageWidth"];
  1166. m_nImageHeight = (int)m_ModeConfig["ModeTable"][i]["ImageHeight"];
  1167. m_nWidthOffset = (int)m_ModeConfig["ModeTable"][i]["WidthOffset"];
  1168. m_nRightOffset = (int)m_ModeConfig["ModeTable"][i]["RightOffset"];
  1169. m_nHeightOffset = (int)m_ModeConfig["ModeTable"][i]["HeightOffset"];
  1170. m_nBottomOffset = (int)m_ModeConfig["ModeTable"][i]["BottomOffset"];
  1171. m_nImgBits = (int)m_ModeConfig["ModeTable"][i]["PhySizeInfoBit"];
  1172. m_nPixelPitch = (int)m_ModeConfig["ModeTable"][i]["PixelPitch"];
  1173. m_nSaveRaw = (int)m_ModeConfig["ModeTable"][i]["IsSaveRaw"];
  1174. strCoef = (string)m_ModeConfig["ModeTable"][i]["Sensitivity"];
  1175. if (m_pImgBuffer)
  1176. {
  1177. delete m_pImgBuffer;
  1178. m_pImgBuffer = NULL;
  1179. }
  1180. m_pImgBuffer = new WORD[m_nImageHeight * m_nImageWidth];
  1181. Info("Image size(W*H), Raw({$}*{$}), Effective({$}*{$}), Offset({$} {$} {$} {$}), Bits({$}), PixelPitch({$}), SaveRaw({$})", m_nRawImgWidth, m_nRawImgHeight, m_nImageWidth, m_nImageHeight, m_nHeightOffset, m_nBottomOffset, m_nWidthOffset, m_nRightOffset, m_nImgBits, m_nPixelPitch, m_nSaveRaw);
  1182. int nTmp = (int)m_ModeConfig["ModeTable"][i]["PreviewEnable"];
  1183. if (nTmp > 0)
  1184. {
  1185. m_bPreviewEnable = true;
  1186. }
  1187. else
  1188. {
  1189. m_bPreviewEnable = false;
  1190. }
  1191. m_nPreviewWidth = (int)m_ModeConfig["ModeTable"][i]["PreviewWidth"];
  1192. m_nPreviewHeight = (int)m_ModeConfig["ModeTable"][i]["PreviewHeight"];
  1193. Info("Preview size(W*H {$}*{$}), PreviewEnable({$})", m_nPreviewWidth, m_nPreviewHeight, m_bPreviewEnable);
  1194. Info("Sensitivity: {$}", strCoef.c_str());
  1195. break;
  1196. }
  1197. catch (ResDataObjectExption& exp)
  1198. {
  1199. Error("Get config failed: {$}", exp.what());
  1200. }
  1201. }
  1202. }
  1203. Info("SelectExamMode {$} over", m_nCurrentMode);
  1204. return true;
  1205. }
  1206. //设置应用模式模式+设置曝光模式+设置校正项
  1207. bool IRayCtrl::SelectMode(int nAppMode, int nExpMode, int nFilterMode)
  1208. {
  1209. int nPanelID = m_nCurrentPanelID + 1;
  1210. //ActiveConfigurationMode(nPanelID, nExpMode);
  1211. //获取应用模式信息
  1212. GetMammoAppMode(nPanelID);
  1213. //设置当前需要的模式到探测器
  1214. //int nFilterMode = m_stDeviceIndex[m_nCurrentPanelID].nFilterMode;
  1215. if ((m_nAppMode != nAppMode) || (m_nExpMode != nExpMode) || (m_nFilterMode != nFilterMode))
  1216. {
  1217. if (!SetMammoAppMode(nPanelID, nAppMode, nExpMode, nFilterMode))
  1218. {
  1219. Error("Set Mammo configuration parameter failed");
  1220. }
  1221. m_nAppMode = nAppMode;
  1222. m_nExpMode = nExpMode;
  1223. m_nFilterMode = nFilterMode;
  1224. }
  1225. //SetMammoAppMode(nPanelID, nAppMode, nExpMode, nFilterMode);
  1226. //设置校正参数
  1227. SetCorrectionOption(nPanelID, nExpMode);
  1228. return true;
  1229. }
  1230. bool IRayCtrl::SetSyncMode(int nDetectorID, int nSetSyncMode)
  1231. {
  1232. Info("IRayCtrl::SetSyncMode({$})", nSetSyncMode);
  1233. int nPanelID = nDetectorID + 1;
  1234. if (!WaitReady(nPanelID, 1000))
  1235. {
  1236. return false;
  1237. }
  1238. int nTriggerMode = 0;
  1239. if (GetSyncMode(nPanelID, nTriggerMode))
  1240. {
  1241. Info("Current SyncMode is {$}", TriggerModeName(nSetSyncMode));
  1242. }
  1243. else
  1244. {
  1245. Error("Get Sync Mode Failed");
  1246. return false;
  1247. }
  1248. if (nTriggerMode == nSetSyncMode)
  1249. {
  1250. Info("Same Sync Mode, return");
  1251. return true;
  1252. }
  1253. Info("Set Sync Mode:{$}", TriggerModeName(nSetSyncMode));
  1254. if (!SetAttr(nPanelID, Attr_UROM_TriggerMode_W, nSetSyncMode))
  1255. {
  1256. Error("Set Sync Mode Failed");
  1257. return false;
  1258. }
  1259. m_nTriggerMode = nSetSyncMode;
  1260. Info("Set Sync Mode Success");
  1261. Info("SetSyncMode over");
  1262. return true;
  1263. }
  1264. bool IRayCtrl::GetSyncMode(int nDetectorID, int& nTriggerMode)
  1265. {
  1266. return GetAttr(nDetectorID, Attr_UROM_TriggerMode, nTriggerMode);
  1267. }
  1268. string IRayCtrl::TriggerModeName(int nTriggerMode)
  1269. {
  1270. string strTriggerMode = "";
  1271. switch (nTriggerMode)
  1272. {
  1273. case Enm_TriggerMode_Outer:
  1274. strTriggerMode = "Enm_TriggerMode_Outer";
  1275. break;
  1276. case Enm_TriggerMode_Soft:
  1277. strTriggerMode = "Enm_TriggerMode_Soft";
  1278. break;
  1279. case Enm_TriggerMode_Prep:
  1280. strTriggerMode = "Enm_TriggerMode_Prep";
  1281. break;
  1282. case Enm_TriggerMode_AED:
  1283. strTriggerMode = "Enm_TriggerMode_AED";
  1284. break;
  1285. case Enm_TriggerMode_SyncOut:
  1286. strTriggerMode = "Enm_TriggerMode_SyncOut";
  1287. break;
  1288. default:
  1289. strTriggerMode = "Unknown";
  1290. break;
  1291. }
  1292. return strTriggerMode;
  1293. }
  1294. // pOutImg: 裁剪后图像; pInImg: 裁剪前图像; nInWidth: 裁剪前图像宽度
  1295. bool IRayCtrl::GetEffectiveImage(WORD* pOutImg, WORD* pInImg, int nInWidth)
  1296. {
  1297. if (pOutImg == NULL || pInImg == NULL || nInWidth < 0)
  1298. {
  1299. Error("Illegal parameter, can not get effective image");
  1300. return false;
  1301. }
  1302. try
  1303. {
  1304. for (int i = 0; i < m_nImageHeight; i++)
  1305. {
  1306. memcpy(pOutImg + i * m_nImageWidth, pInImg + (i + m_nHeightOffset) * nInWidth + m_nWidthOffset, m_nImageWidth * sizeof(WORD));
  1307. }
  1308. }
  1309. catch (...)
  1310. {
  1311. Error("Get effective image crashed. m_nImageWidth {$},m_nImageHeight {$},m_nWidthOffset {$},m_nHeightOffset {$},m_nBottomOffset {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset, m_nBottomOffset);
  1312. return false;
  1313. }
  1314. return true;
  1315. }
  1316. void IRayCtrl::OnProcessImg()
  1317. {
  1318. if (m_nWidthOffset != 0 || m_nHeightOffset != 0)
  1319. {
  1320. if (m_nSaveRaw)
  1321. {
  1322. }
  1323. Info("Begin get effect image, m_nRawImgWidth {$}\n", m_nRawImgWidth);
  1324. if (!GetEffectiveImage(m_pImgBuffer, m_pwRawImageData, m_nRawImgWidth))
  1325. {
  1326. Error("Get effect image failed");
  1327. return;
  1328. }
  1329. Info("Get effect image over");
  1330. }
  1331. if ((m_nClinicalApplicationMode == 2) && ((++m_nCurrentFrame) < m_nTotalFrameNum))
  1332. {
  1333. DataFeedback(EVT_DATA_AEC_PREEXP_IMAGE, m_pwRawImageData);
  1334. }
  1335. else
  1336. {
  1337. DataFeedback(EVT_DATA_RAW_IMAGE, m_pwRawImageData);
  1338. m_nCurrentFrame = 0;
  1339. }
  1340. }
  1341. bool IRayCtrl::EnterExam(APP_STATUS eStatus)
  1342. {
  1343. string strLog = "";
  1344. switch (eStatus)
  1345. {
  1346. case APP_STATUS_IDLE:
  1347. strLog = "APP_STATUS_IDLE";
  1348. break;
  1349. case APP_STATUS_WORK_BEGIN:
  1350. strLog = "APP_STATUS_WORK_BEGIN";
  1351. m_bInCalibrating = false;
  1352. break;
  1353. case APP_STATUS_WORK_END:
  1354. strLog = "APP_STATUS_WORK_END";
  1355. break;
  1356. case APP_STATUS_CAL_BEGIN:
  1357. strLog = "APP_STATUS_CAL_BEGIN";
  1358. break;
  1359. case APP_STATUS_CAL_END:
  1360. strLog = "APP_STATUS_CAL_END";
  1361. m_bInCalibrating = false;
  1362. break;
  1363. default:
  1364. break;
  1365. }
  1366. Info("Enter exam: {$}", strLog.c_str());
  1367. m_eAppStatus = eStatus;
  1368. return true;
  1369. }
  1370. RET_STATUS IRayCtrl::PrepareAcquisition(nsDPC::FPDDeviceIRay* pDrvDPC)
  1371. {
  1372. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  1373. {
  1374. Warn("Not current DPC, return");
  1375. return RET_STATUS::RET_FAILED;
  1376. }
  1377. if (m_stDeviceIndex[m_nCurrentPanelID].bConnectStatus == false)
  1378. {
  1379. Info("Current detector is not connect, return");
  1380. return RET_STATUS::RET_FAILED;
  1381. }
  1382. int nPanelID = m_nCurrentPanelID + 1;
  1383. //获取应用模式信息
  1384. GetMammoAppMode(nPanelID);
  1385. //StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START);
  1386. return RET_STATUS::RET_SUCCEED;
  1387. }
  1388. bool IRayCtrl::GetMammoAppMode(int nDetectorID)
  1389. {
  1390. string strAppMode = "Unknown";
  1391. GetAttr(nDetectorID, Attr_UROM_AppMode, m_nAppMode);
  1392. GetAttr(nDetectorID, Attr_UROM_ExpMode, m_nExpMode);
  1393. GetAttr(nDetectorID, Cfg_CurFilter, m_nFilterMode);
  1394. Info("Get detector application mode: AppMode({$}), ExpMode({$}), FilterMode({$})", m_nAppMode, m_nExpMode, m_nFilterMode);
  1395. if ((m_nAppMode == 0 && m_nExpMode == 1) || (m_nAppMode == 1 && m_nExpMode == 1)) // manual
  1396. {
  1397. m_nTotalFrameNum = 1;
  1398. strAppMode = "Normal exposure";
  1399. }
  1400. else if ((m_nAppMode == 0 && m_nExpMode == 2) || // AEC
  1401. (m_nAppMode == 1 && m_nExpMode == 2) || // AEC
  1402. (m_nAppMode == 2 && m_nExpMode == 5)) // Stereo
  1403. {
  1404. m_nTotalFrameNum = 2;
  1405. strAppMode = "AEC exposure";
  1406. }
  1407. Info("Detector Application mode: {$}, Total frame number: {$}", strAppMode, m_nTotalFrameNum);
  1408. return true;
  1409. }
  1410. bool IRayCtrl::SetMammoAppMode(int nDetectorID, int nAppMode, int nExpMode, int nFilterMode)
  1411. {
  1412. IRayCmdParam param[3];
  1413. param[0].pt = IPT_VARIANT;
  1414. param[0].var.vt = IVT_INT;
  1415. param[0].var.val.nVal = nAppMode;
  1416. param[1].pt = IPT_VARIANT;
  1417. param[1].var.vt = IVT_INT;
  1418. param[1].var.val.nVal = nExpMode;
  1419. param[2].pt = IPT_VARIANT;
  1420. param[2].var.vt = IVT_INT;
  1421. param[2].var.val.nVal = nFilterMode;
  1422. int nResult = IrayFnInvoke(nDetectorID, Cmd_SetCurAppMode, param, 3);
  1423. WaitRespond(5000);
  1424. Info("Change current application mode: AppMode({$}), ExpMode({$}), FilterMode({$})", nAppMode, nExpMode, nFilterMode);
  1425. //GetMammoAppMode(nDetectorID);
  1426. return true;
  1427. }
  1428. RET_STATUS IRayCtrl::StartAcquisition(nsDPC::FPDDeviceIRay* pDrvDPC)
  1429. {
  1430. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  1431. {
  1432. Warn("Not current DPC, return");
  1433. return RET_STATUS::RET_FAILED;
  1434. }
  1435. RET_STATUS Ret = RET_STATUS::RET_FAILED;
  1436. if (-1 == m_nCurrentMode)
  1437. {
  1438. Warn("Current mode({$}) is illegal, may not select exam mode successfully, return failed", m_nCurrentMode);
  1439. return Ret;
  1440. }
  1441. ////如果当前探测器断连,则不开始采集,直接返回失败
  1442. //if (!m_stDeviceIndex[m_nCurrentPanelID].bConnectStatus)
  1443. //{
  1444. // Warn("Detector not in connection when start acq, return failed");
  1445. // return RET_STATUS::RET_FAILED;
  1446. //}
  1447. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_START);
  1448. m_bInExposure = true;
  1449. m_bWindowOn = false;
  1450. StatusFeedback(EVT_STATUS_ACQUISITION, PANEL_EVENT_END_OK);
  1451. return RET_STATUS::RET_SUCCEED;
  1452. }
  1453. bool IRayCtrl::StartXWindowOffThread()
  1454. {
  1455. if (m_pXWindowoffThread == NULL)
  1456. {
  1457. DWORD m_NotifyThreadID;
  1458. m_pXWindowoffThread = CreateThread(0, 0, XWindowOffThread, this, 0, &m_NotifyThreadID);
  1459. if (m_pXWindowoffThread == NULL)
  1460. {
  1461. Fatal("Start Inner Exp Thread Failed");
  1462. return false;
  1463. }
  1464. }
  1465. return true;
  1466. }
  1467. DWORD IRayCtrl::XWindowOffThread(LPVOID pParam)
  1468. {
  1469. IRayCtrl* pCurPanel = (IRayCtrl*)pParam;
  1470. if (pCurPanel == NULL)
  1471. {
  1472. return false;
  1473. }
  1474. DWORD dwTimer = 500;
  1475. DWORD dwResult = WaitForSingleObject(pCurPanel->m_hWindowOffEvent, dwTimer);
  1476. Info("Simulate XWINDOW_OFF");
  1477. pCurPanel->StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_OFF);
  1478. pCurPanel->m_pXWindowoffThread = NULL;
  1479. return true;
  1480. }
  1481. RET_STATUS IRayCtrl::StopAcquisition(nsDPC::FPDDeviceIRay* pDrvDPC)
  1482. {
  1483. if ((*m_pDPC2PanelID)[pDrvDPC] != m_nCurrentPanelID)
  1484. {
  1485. Warn("Not current DPC, return");
  1486. return RET_STATUS::RET_FAILED;
  1487. }
  1488. m_bInExposure = false;
  1489. RET_STATUS Ret = RET_STATUS::RET_SUCCEED;
  1490. return Ret;
  1491. }
  1492. //Normal曝光模式才使用SW_Offset
  1493. bool IRayCtrl::PerformOffset(int nDetectorID, int nOffsetType)
  1494. {
  1495. int nPanelID = m_nCurrentPanelID + 1;
  1496. int nOffsetTimeOut = 0;
  1497. int nOffsetTotalFramesNum = 0;
  1498. int nIntervalTimeOfEachFrame = 0;
  1499. if (nOffsetType == 0) //HW_Offset
  1500. {
  1501. Info("Call Cmd_HwGeneratePreOffsetTemplate");
  1502. FPDRESULT nResult = IrayFnInvoke(nPanelID, Cmd_HwGeneratePreOffsetTemplate, NULL, 0);
  1503. if (TestError(nPanelID, nResult))
  1504. {
  1505. Error("Cmd_HwGeneratePreOffsetTemplate Cmd Failed");
  1506. StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FAILED);
  1507. return false;
  1508. }
  1509. ResetLock();
  1510. m_stDeviceIndex[m_nCurrentPanelID].bEventReturn = false;
  1511. bool bResult = WaitRespond(20000); //刷新一次20秒
  1512. if (!bResult)
  1513. {
  1514. Error("Generate HW PreOffset Template failed");
  1515. }
  1516. else
  1517. {
  1518. Info("Generate HW PreOffset Template success");
  1519. }
  1520. }
  1521. else if (nOffsetType == 1) //SW_Offset
  1522. {
  1523. GetAttr(nPanelID, Attr_OffsetTotalFrames, nOffsetTotalFramesNum);
  1524. GetAttr(nPanelID, Attr_UROM_SequenceIntervalTime, nIntervalTimeOfEachFrame);
  1525. nOffsetTimeOut = (nOffsetTotalFramesNum + 11) * nIntervalTimeOfEachFrame + 5000;
  1526. Info("Offset ToTal Frames Number: {$}, Interval Time Of EachFrame: {$}(ms), Offset TimeOut: {$}(ms)", nOffsetTotalFramesNum, nIntervalTimeOfEachFrame, nOffsetTimeOut);
  1527. Info("Call Cmd_OffsetGeneration");
  1528. FPDRESULT nResult = IrayFnInvoke(nDetectorID, Cmd_OffsetGeneration, NULL, 0);
  1529. if (TestError(nPanelID, nResult))
  1530. {
  1531. Error("Cmd_OffsetGeneration command Failed");
  1532. StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FAILED);
  1533. return false;
  1534. }
  1535. ResetLock();
  1536. m_stDeviceIndex[m_nCurrentPanelID].bEventReturn = false;
  1537. bool bResult = WaitRespond(nOffsetTimeOut); //刷新一次需要的时间
  1538. if (!bResult)
  1539. {
  1540. Error("Generate SW Offset Template failed");
  1541. return false;
  1542. }
  1543. else
  1544. {
  1545. Info("Generate SW Offset Template success");
  1546. }
  1547. }
  1548. else
  1549. {
  1550. Error("Unknown offset type");
  1551. }
  1552. /*if (m_stDeviceIndex[m_nCurrentPanelID].bEventReturn)
  1553. {
  1554. StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FINISH);
  1555. }
  1556. else
  1557. {
  1558. StatusFeedback(EVT_STATUS_PANEL, PANEL_OFFSET_FAILED);
  1559. }*/
  1560. return true;
  1561. }
  1562. bool IRayCtrl::ClearCorrectionOption(int nDetectorID)
  1563. {
  1564. Info("Clear Correction Option");
  1565. int nPanelIndex = nDetectorID - 1;
  1566. if (!WaitReady(nDetectorID, 1000))
  1567. {
  1568. return false;
  1569. }
  1570. int nOption = 0;
  1571. IRayCmdParam param[1];
  1572. param[0].var.vt = IVT_INT;
  1573. param[0].var.val.nVal = nOption;
  1574. FPDRESULT result = IrayFnInvoke(nDetectorID, Cmd_SetCorrectOption, param, 1);
  1575. //Cmd_SetCorrectOption
  1576. if (TestError(nDetectorID, result))
  1577. {
  1578. Fatal("Call SetCorrectionOption Failed");
  1579. return false;
  1580. }
  1581. bool bResult = WaitRespond(8000);
  1582. if (m_stDeviceIndex[nPanelIndex].bSetCorrection)
  1583. {
  1584. Info("Clear Correction Success");
  1585. }
  1586. else
  1587. {
  1588. Fatal("Clear Correction Failed");
  1589. return false;
  1590. }
  1591. return true;
  1592. }
  1593. bool IRayCtrl::GetCorrectionOption(int nDetectorID, int& nOption)
  1594. {
  1595. return GetAttr(nDetectorID, Attr_CurrentCorrectOption, nOption);
  1596. }
  1597. // 设置探测器端校正参数,加载校正文件
  1598. bool IRayCtrl::SetCorrectionOption(int nDetectorID, int nExpMode)
  1599. {
  1600. Info("Set Mammo Correction Option");
  1601. /*if (!WaitReady(nDetectorID, 1000))
  1602. {
  1603. return false;
  1604. }*/
  1605. int nDetectorIndex = nDetectorID - 1;
  1606. int nOffsetOption = Enm_CorrectOp_HW_PostOffset; //HW_PostOffset
  1607. //1:RAD;2:AEC;default:0;//从别的项目里找到的注释
  1608. //这里之前是Exp_Normal,但是这个枚举在哪里定义的并没有,故此处根据其他项目的曝光模式的值先修改,后续有人知道此处如何修改时再改,先能编译过,否则编译不过
  1609. if (nExpMode == 0)
  1610. {
  1611. nOffsetOption = Enm_CorrectOp_SW_PreOffset;
  1612. }
  1613. int nOption = 0;
  1614. nOption = nOption | nOffsetOption;
  1615. nOption = nOption | Enm_CorrectOp_SW_Gain;
  1616. nOption = nOption | Enm_CorrectOp_SW_Defect;
  1617. int nOldOption = 0;
  1618. GetCorrectionOption(nDetectorID, nOldOption);
  1619. if (nOption == nOldOption)
  1620. {
  1621. Info("Same Correction Option, Omit Set Correction Option");
  1622. return true;
  1623. }
  1624. if (22 == nOption)
  1625. {
  1626. Info("Set FPD {$} Correction Option: PostOffset+All", nDetectorID);
  1627. }
  1628. else
  1629. {
  1630. Info("Set FPD {$} Correction Option: {$}", nDetectorID, nOption);
  1631. }
  1632. IRayCmdParam param[1];
  1633. param[0].var.vt = IVT_INT;
  1634. param[0].var.val.nVal = nOption;
  1635. FPDRESULT result = IrayFnInvoke(nDetectorID, Cmd_SetCorrectOption, param, 1);
  1636. //Cmd_SetCorrectOption
  1637. if (TestError(nDetectorID, result))
  1638. {
  1639. Error("Call SetCorrectionOption Failed");
  1640. return false;
  1641. }
  1642. bool bResult = WaitRespond(10000); //加载校正策略
  1643. if (m_stDeviceIndex[nDetectorIndex].bSetCorrection)
  1644. {
  1645. Info("SetCorrectionOption Success");
  1646. }
  1647. else
  1648. {
  1649. Error("SetCorrectionOption Failed");
  1650. return false;
  1651. }
  1652. return true;
  1653. }
  1654. /*
  1655. * 镜像翻转
  1656. */
  1657. bool IRayCtrl::FlipX(WORD* pData, int nWidth, int nHeight)
  1658. {
  1659. int j = 0;
  1660. int i = 0;
  1661. Info("Flip Image Width:{$}, Height:{$}", nWidth, nHeight);
  1662. WORD temp;
  1663. for (i = 0; i < nHeight; i++)
  1664. {
  1665. for (j = 0; j < nWidth / 2; j++)
  1666. {
  1667. temp = pData[i * nWidth + j];
  1668. pData[i * nWidth + j] = pData[(i + 1) * nWidth - j - 1];
  1669. pData[(i + 1) * nWidth - j - 1] = temp;
  1670. }
  1671. }
  1672. Info("Flip Image Over");
  1673. return true;
  1674. }
  1675. /*
  1676. 功能:对SDK输出的图像,先旋转90度,再做镜像,做到所见即所得。
  1677. */
  1678. bool IRayCtrl::FlipXRotate90(WORD* pData, int nWidth, int nHeight)
  1679. {
  1680. Info("Rotate 270 angle");
  1681. WORD* ptempData = new WORD[nWidth * nHeight];
  1682. memcpy(ptempData, pData, nWidth * nHeight * sizeof(WORD));
  1683. for (int i = 0; i < nWidth; i++)
  1684. for (int j = 0; j < nHeight; j++)
  1685. pData[i * nWidth + j] = ptempData[j * nWidth + (nWidth - 1 - i)];
  1686. delete[]ptempData;
  1687. ptempData = NULL;
  1688. FlipX(pData, nWidth, nHeight);
  1689. return true;
  1690. }