PZMedical2121ZCtrl.cpp 108 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196
  1. /* -------------------------------------------------------------------------
  2. // 文件名 : PZMedical2121ZCtrl.cpp
  3. // 创建者 : wangyuedong
  4. // 创建时间 : 2022-08-08
  5. // 功能描述 : PZMedical2121Z动态探测器功能实现
  6. // -----------------------------------------------------------------------*/
  7. #include "StdAfx.h"
  8. #include "ModeAbstract.h"
  9. #include "EComRFMessage_i.h"
  10. #include "PZMedical2121ZCtrl.h"
  11. #include "CShareMemManager.h"
  12. extern CString strAppPath;
  13. extern CAppSettings *g_pAcqParam;
  14. extern CString g_strConfFilePath;
  15. extern CString g_strHWConfFilePath;
  16. #define BUFFER_NUM 10
  17. #define IMAGEWIDTH 2880
  18. PZMedical2121ZCtrl* PZMedical2121ZCtrl::g_pPZMedicalInstance = NULL;
  19. PZMedical2121ZCtrl::PZMedical2121ZCtrl(void)
  20. {
  21. m_bFPDConnected = false;
  22. g_pPZMedicalInstance = this;
  23. m_nModeSize = 1;
  24. m_RadMode.nLogicMode = 1;
  25. m_RadMode.nOffIndex = 0;
  26. m_FluMode.nLogicMode = 3;
  27. m_FluMode.nOffIndex = 0;
  28. m_CINEMode.nLogicMode = 3;
  29. m_CINEMode.nOffIndex = 0;
  30. m_ActiveMode.nLogicMode = -1;
  31. m_ActiveMode.nOffIndex = -1;
  32. m_CalSynParam.frenquency = 1;
  33. m_CalSynParam.xWindow = 500;
  34. m_PreSynParam.frenquency = 1;
  35. m_PreSynParam.xWindow = 500;
  36. m_CurSynParam.frenquency = 1;
  37. m_CurSynParam.xWindow = 500;
  38. m_bOffsetDone = false;
  39. m_bCalStart = false;
  40. m_hWnd = NULL;
  41. m_pWnd = NULL;
  42. m_eStatus = NotInit;
  43. m_eSubStatus = SubStatus_Unknown;
  44. m_bIsWorkingMode = false;
  45. m_bAbortOffset = false;
  46. m_bOffsetAll = true;
  47. m_nRADSpeed = 0; //0时默认为单帧点片
  48. m_nFLUSpeed = 15; //透视模式默认为15帧
  49. m_nCINSpeed = 0;
  50. m_bExit = false;
  51. m_EnableProcessChain = false;
  52. m_EnableDrvLog = false;
  53. m_pDataBuffer = new CShareMem(_T("ImageBuffer"));
  54. m_pDataBuffer->CreateShareMem(IMAGEWIDTH*(IMAGEWIDTH + 1)*BUFFER_NUM*sizeof(WORD));
  55. m_nCurrentFrame = -1;
  56. m_nTotalFrameGrab = 0;
  57. m_bWaitLastImg = false; //默认不需要等最后一张图
  58. m_nXrayOnNum = 0;
  59. m_pImgBufferSize = 1024 * 1024; //linshi
  60. m_ImgInfo.pwData = new WORD[m_pImgBufferSize];
  61. m_nRawWidth = 1024;
  62. m_nTotalGainGroup = 3;
  63. g_bTestTrue = false;
  64. g_TestSavingImage = NULL;
  65. //初始化为NULL值
  66. API_COM_Init = NULL;
  67. API_COM_Open = NULL;
  68. API_COM_SetCfgFilePath = NULL;
  69. API_COM_HstAcq = NULL;
  70. API_COM_Trigger = NULL;
  71. API_COM_Dacq = NULL;
  72. API_COM_Cbct = NULL;
  73. API_COM_Stop = NULL;
  74. API_COM_GetImage = NULL;
  75. API_COM_GetImageMode = NULL;
  76. API_COM_SetFPConf = NULL;
  77. API_COM_GetFPConf = NULL;
  78. API_COM_GetFPsn = NULL;
  79. API_COM_GetFPsnEx = NULL;
  80. API_COM_GetFPCompatibleVer = NULL;
  81. API_COM_GetDllVer = NULL;
  82. API_COM_GetBinningMode = NULL;
  83. API_COM_SetBinningMode = NULL;
  84. API_COM_GetPreCalibMode = NULL;
  85. API_COM_SetPreCalibMode = NULL;
  86. API_COM_GetCalibMode = NULL;
  87. API_COM_SetCalibMode = NULL;
  88. API_COM_GenOffsetTpl = NULL;
  89. API_COM_GenGainTpl = NULL;
  90. API_COM_GenDefectTpl = NULL;
  91. API_COM_UploadFPZMTpl = NULL;
  92. API_COM_RegisterEvCallBack = NULL;
  93. API_COM_Dst = NULL;
  94. API_COM_Prep = NULL;
  95. API_COM_SetDynamicPara = NULL;
  96. API_COM_Dexit = NULL;
  97. API_COM_GetFPCurStatus = NULL;
  98. API_COM_GetFPStatus = NULL;
  99. m_pScanThreadProc = NULL;
  100. m_hInitEvent = NULL;
  101. m_hExitEvent = NULL;
  102. m_hGenTplEvent = NULL;
  103. for (int i = 0; i < PZ_EVENT_COUNT; i++)
  104. m_hEventArray[i] = NULL;
  105. m_hCallbackEvent = NULL;
  106. m_nTriggerMode = 2;
  107. m_nImgID = 1;
  108. m_nOffsetImgID = 1; //SDK逻辑是从1开始的
  109. m_nGainImgID = 1; //SDK逻辑是从1开始的
  110. m_cEventNum = -1;
  111. m_cImgBuff = NULL;
  112. m_ucState = -1;
  113. m_ucPerCent = -1;
  114. m_bGetImage = false;
  115. m_bSendRadImage = false;
  116. m_bExiChecked = false;
  117. m_bTimeChecked = false;
  118. m_nExiStdWork = 1000;
  119. m_nExiStdCali = 30000;
  120. m_cFPDCalibMode = 5; //初始时,设置成一个不存在的校正模式
  121. strCalMode = "-1";
  122. m_bSaveRaw = false;
  123. m_cCalibMode = PZ_OFFSET_GAIN_DEFECT;
  124. m_bTriggered = true; //默认为true,使初始化时可以stop一次
  125. m_nBinningMode = -1;
  126. m_nWinTime = -1;
  127. m_nStartLine = 0;
  128. m_nEndLine = 0;
  129. m_nStartColumn = 0;
  130. m_nEndColumn = 0;
  131. m_dwBeginT = 0;
  132. m_dwEndT = 0;
  133. m_nDelayT = 0;
  134. m_nPixelSpacing = 140;
  135. m_bTimerSwitch = true;
  136. m_dwGetImageT = 0;
  137. m_dwLastT = 0;
  138. m_nSaturation = 50000;
  139. m_nStandbyRate = 2;
  140. m_nRadImgCount = 3;
  141. m_vecCycleTime.clear();
  142. m_vecDelayTime.clear();
  143. //addend
  144. }
  145. PZMedical2121ZCtrl::~PZMedical2121ZCtrl(void)
  146. {
  147. map<int, ZSKK_ROI_PARAM*>::iterator iter1 = m_ROImap.begin();
  148. while (iter1 != m_ROImap.end())
  149. {
  150. delete iter1->second;
  151. ++iter1;
  152. }
  153. if (m_ImgInfo.pwData != NULL)
  154. {
  155. delete[] m_ImgInfo.pwData;
  156. }
  157. m_ROImap.clear();
  158. }
  159. BEGIN_MESSAGE_MAP(PZMedical2121ZCtrl, CAcqCtrl)
  160. END_MESSAGE_MAP()
  161. bool PZMedical2121ZCtrl::InitDETECTOR(HWND hWnd, bool bState)
  162. {
  163. //如果探测器未连接则直接返回
  164. if (CAcqCtrl::InitDETECTOR(hWnd, bState)) return true;
  165. LogInfo("===== Init PZMedical2121Z system =====");
  166. m_bState = bState;
  167. m_hWnd = hWnd;
  168. m_bFPDConnected = false;
  169. m_eStatus = Init;
  170. CString strLog = "";
  171. // 读取模式配置文件
  172. // 1.获取RFModeConf.xml路径 (RFOC\conf\hw\PZMedical2121Z\RFModeConf.xml)
  173. LogInfo(g_strHWConfFilePath);
  174. CAppSettings appDetectorSet;
  175. if (appDetectorSet.Load(g_strHWConfFilePath + _T("\\Detector.xml")))
  176. {
  177. LogInfo("Load Detector.xml OK");
  178. }
  179. else
  180. {
  181. LogError("Load Detector.xml failed");
  182. return false;
  183. }
  184. m_SubConfigPath = appDetectorSet.GetValueByKey(_T("DetectorType")); //m_SubConfigPath 为 PZMedical2121Z
  185. CString strRFConfPath;
  186. strRFConfPath.Format("%s\\%s\\RFModeConf.xml", g_strHWConfFilePath, m_SubConfigPath);
  187. //LogInfo(strRFConfPath);
  188. //CalibrationType 配置项。0: RAW; 1: OFFSET; 7: OFFSET_GAIN_DEFECT
  189. strCalMode = appDetectorSet.GetValueByKey(_T("CalibrationType"));
  190. if (strCalMode == "0")
  191. m_cCalibMode = PZ_RAW;
  192. else if (strCalMode == "1")
  193. m_cCalibMode = PZ_OFFSET;
  194. else if (strCalMode == "7")
  195. m_cCalibMode = PZ_OFFSET_GAIN_DEFECT;
  196. CString strSaveRaw = appDetectorSet.GetValueByKey(_T("SaveRawDataMode"));
  197. if (strSaveRaw == "0")
  198. {
  199. m_bSaveRaw = false;
  200. LogInfo("Not save Raw");
  201. }
  202. else if (strSaveRaw == "1")
  203. {
  204. m_bSaveRaw = true;
  205. LogInfo("Save Raw");
  206. }
  207. else
  208. {
  209. strLog.Format("Unknown save raw mode: %s. Not save", strSaveRaw);
  210. m_bSaveRaw = false;
  211. }
  212. // 2.加载 RFModeConf.xml 配置
  213. if (RFModeConf.Load(strRFConfPath))
  214. {
  215. LogInfo("Load mode configuration file OK");
  216. }
  217. else
  218. {
  219. LogError("Load mode configuration file Failed");
  220. return false;
  221. }
  222. m_nModeSize = (int)RFModeConf.DetectorMode.m_nodes.size();
  223. // 3.上层应用模式和RFMode对应的模式映射表 (RFOC\conf\hw\PZMedical2121Z\RealModeMatch.xml)
  224. CString strRealModeConfFile;
  225. strRealModeConfFile.Format("%s\\%s\\RealModeMatch.xml", g_strHWConfFilePath, m_SubConfigPath);
  226. //LogInfo(strRealModeConfFile);
  227. if (m_appRealModeConf.Load(strRealModeConfFile))
  228. {
  229. LogInfo("Load RealModeMatch.xml OK");
  230. }
  231. else
  232. {
  233. LogError("Load file failed: " + strRealModeConfFile);
  234. return false;
  235. }
  236. m_appRealModeConf.GetAllDataToVector();
  237. // 4.写入AbstractModeConfig.xml (RFOC\conf\AbstractModeConfig.xml)
  238. AbstractModeConfig AbstractModes;
  239. CString strAbstractModeFile;
  240. strAbstractModeFile.Format("%s\\AbstractModeConfig.xml", g_strConfFilePath);
  241. //LogInfo(strAbstractModeFile);
  242. if (AbstractModes.Load(strAbstractModeFile))
  243. {
  244. AbstractModes.DetectorMode.Clear();
  245. }
  246. else
  247. {
  248. CStdioFile file;
  249. if (file.Open(strAbstractModeFile, CFile::modeCreate | CFile::modeReadWrite))
  250. {
  251. file.WriteString(_T("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"));
  252. file.WriteString(_T("<AbstractMode>\n"));
  253. file.WriteString(_T("</AbstractMode>\n"));
  254. file.Close();
  255. }
  256. AbstractModes.Load(strAbstractModeFile);
  257. }
  258. for (int i = 0; i < m_nModeSize; ++i)
  259. {
  260. ModeNode modeNode;
  261. modeNode.LogicMode = RFModeConf.DetectorMode.m_nodes[i].LogicMode;
  262. modeNode.PUMode = RFModeConf.DetectorMode.m_nodes[i].PUMode;
  263. int nCount = (int)RFModeConf.DetectorMode.m_nodes[i].OffsetMode.m_nodes.size();
  264. modeNode.ModeDescription = RFModeConf.DetectorMode.m_nodes[i].OffsetMode.m_nodes[nCount - 1].Description;
  265. modeNode.Frequency = RFModeConf.DetectorMode.m_nodes[i].OffsetMode.m_nodes[nCount - 1].Frequency;
  266. if (modeNode.Frequency < 1.0)
  267. {
  268. m_nTOMOMode = modeNode.LogicMode;
  269. }
  270. modeNode.ExamType = RFModeConf.DetectorMode.m_nodes[i].ExamType;
  271. modeNode.AutoOffset = RFModeConf.DetectorMode.m_nodes[i].OffsetMode.m_nodes[nCount - 1].AutoOff;
  272. modeNode.XWindow = RFModeConf.DetectorMode.m_nodes[i].OffsetMode.m_nodes[nCount - 1].Xwindow;
  273. modeNode.OffsetMode = nCount - 1;
  274. modeNode.PF2CF = RFModeConf.DetectorMode.m_nodes[i].PolyGainEnable;
  275. CString strtemp;
  276. strtemp.Format("%d", modeNode.LogicMode);
  277. for (DWORD j = 0; j < m_appRealModeConf.vecData.size(); ++j)
  278. {
  279. if (m_appRealModeConf.vecData[j].value == strtemp)
  280. {
  281. strtemp = m_appRealModeConf.vecData[j].key;
  282. break;
  283. }
  284. }
  285. modeNode.MatchCode = strtemp;
  286. AbstractModes.DetectorMode.Add(modeNode);
  287. }
  288. AbstractModes.Save(strAbstractModeFile);
  289. if (!m_bState)
  290. {
  291. LogInfo("===== INIT SYSTEM OVER, IN DEMO =====");
  292. return true;
  293. }
  294. ///////////////////////
  295. // 5.对品臻模式配置文件的读取 (RFOC\conf\hw\PZMedical2121Z\PZAppModeConf.xml)
  296. CString strModeConfPath;
  297. strModeConfPath.Format("%s\\%s\\PZAppModeConf.xml", g_strHWConfFilePath, m_SubConfigPath);
  298. //LogInfo(strModeConfPath);
  299. if (PZModeConf.Load(strModeConfPath))
  300. {
  301. LogInfo("Load PZAppModeConf.xml file OK");
  302. }
  303. else
  304. {
  305. LogError("Load PZAppModeConf.xml file Failed");
  306. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  307. return false;
  308. }
  309. // 6.读取品臻探测器的配置文件 (RFOC\conf\hw\PZMedical2121Z\PZParamSetConf.xml)
  310. CString pzConfPath;
  311. pzConfPath.Format("%s\\%s\\PZParamSetConf.xml", g_strHWConfFilePath, m_SubConfigPath);
  312. //LogInfo(pzConfPath);
  313. CAppSettings pzConf;
  314. if (pzConf.Load(pzConfPath))
  315. {
  316. LogInfo("Load PZParamSetConf.xml OK");
  317. }
  318. else
  319. {
  320. LogError("Load PZParamSetConf.xml failed");
  321. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  322. return false;
  323. }
  324. m_strFPSN = pzConf.GetValueByKey("FPSN").GetBuffer();
  325. m_nExiStdWork = atoi(pzConf.GetValueByKey("EXIstdWork").GetBuffer());
  326. m_nExiStdCali = atoi(pzConf.GetValueByKey("EXIstdCal").GetBuffer());
  327. m_bTimerSwitch = atoi(pzConf.GetValueByKey("TimerSwitch").GetBuffer());
  328. m_nSaturation = atoi(pzConf.GetValueByKey("Saturation").GetBuffer());
  329. m_nStandbyRate = atoi(pzConf.GetValueByKey("StandbyRate").GetBuffer());
  330. m_nRadImgCount = atoi(pzConf.GetValueByKey("RadImgCount").GetBuffer());
  331. m_nBinningMode = atoi(pzConf.GetValueByKey("BinningModeParam").GetBuffer());
  332. m_nTriggerMode = atoi(pzConf.GetValueByKey("TriggerMode").GetBuffer());
  333. if (m_nSaturation < 10000)
  334. {
  335. strLog.Format("Some Saturation(%d) not in reason at %s, use 50000 as default", m_nSaturation, pzConfPath);
  336. m_nSaturation = 50000;
  337. }
  338. strLog.Format("CalibMode(%d), EXIstdWork(%d), EXIstdCal(%d), TimerSwitch(%d), Saturation(%d), StandbyRate(%d), RadImgCount(%d)",
  339. m_cCalibMode, m_nExiStdWork, m_nExiStdCali, m_bTimerSwitch, m_nSaturation, m_nStandbyRate, m_nRadImgCount);
  340. LogInfo(strLog);
  341. CString strConfTemp, strTemp;
  342. int nPos = 0;
  343. vector<int>::iterator iter;
  344. vector<int>::iterator begin;
  345. vector<int>::iterator end;
  346. m_vecCycleTime.clear();
  347. m_vecDelayTime.clear();
  348. strConfTemp = pzConf.GetValueByKey("CycleTime");
  349. strTemp = strConfTemp.Tokenize(",", nPos);
  350. while (strTemp != "")
  351. {
  352. m_vecCycleTime.push_back(atoi(strTemp));
  353. strTemp = strConfTemp.Tokenize(",", nPos);
  354. }
  355. begin = m_vecCycleTime.begin();
  356. end = m_vecCycleTime.end();
  357. strLog = "CycleTime: ";
  358. for (iter = begin; iter != end; iter++)
  359. {
  360. strTemp.Format("%d,", *iter);
  361. strLog += strTemp;
  362. }
  363. LogInfo(strLog);
  364. nPos = 0;
  365. strConfTemp = pzConf.GetValueByKey("DelayTime");
  366. strTemp = strConfTemp.Tokenize(",", nPos);
  367. while (strTemp != "")
  368. {
  369. m_vecDelayTime.push_back(atoi(strTemp));
  370. strTemp = strConfTemp.Tokenize(",", nPos);
  371. }
  372. begin = m_vecDelayTime.begin();
  373. end = m_vecDelayTime.end();
  374. strLog = "DelayTime: ";
  375. for (iter = begin; iter != end; iter++)
  376. {
  377. strTemp.Format("%d,", *iter);
  378. strLog += strTemp;
  379. }
  380. LogInfo(strLog);
  381. if (m_vecCycleTime.empty() || m_vecDelayTime.empty())
  382. {
  383. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  384. return false;
  385. }
  386. //LoadROIParams(); //品臻动态不用RFModeConf.xml中的ROI配置
  387. if (!LoadPZMedicalDLL())
  388. {
  389. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  390. return false;
  391. }
  392. if (!StartScanThread())
  393. {
  394. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  395. return false;
  396. }
  397. //SetEvent(m_hInitEvent);
  398. if (!InitHW(m_hWnd))
  399. {
  400. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  401. return false;
  402. }
  403. LogInfo("===== INIT SYSTEM OVER =====");
  404. return true;
  405. }
  406. // 判断SDK接口返回值
  407. bool PZMedical2121ZCtrl::TestError(int nErrorStatus)
  408. {
  409. CString strLog = "";
  410. switch (nErrorStatus)
  411. {
  412. case TRUE:
  413. {
  414. LogInfo("return ok");
  415. return true;
  416. }
  417. break;
  418. case FALSE:
  419. {
  420. LogError("return error");
  421. }
  422. break;
  423. default:
  424. {
  425. strLog.Format("Error: %d", nErrorStatus);
  426. LogError(strLog);
  427. }
  428. break;
  429. }
  430. return false;
  431. }
  432. // 加载PZMedical的SDK
  433. bool PZMedical2121ZCtrl::LoadPZMedicalDLL()
  434. {
  435. LogInfo("## LoadPZMedicalDLL ##");
  436. ::SetDllDirectory(strAppPath + "\\PZMedical\\");
  437. CString strLog = "";
  438. strLog.Format("Path: %s\\PZMedical\\", strAppPath);
  439. LogInfo(strLog);
  440. m_hModule = ::LoadLibrary(strAppPath + "\\PZMedical\\ComApi.dll");
  441. if (m_hModule != NULL)
  442. {
  443. API_COM_Init = (PZ_COM_Init)GetProcAddress(m_hModule, "COM_Init");
  444. if (API_COM_Init == NULL)
  445. {
  446. LogError("Load COM_Init failed");
  447. return false;
  448. }
  449. API_COM_List = (PZ_COM_List)GetProcAddress(m_hModule, "COM_List");
  450. if (API_COM_List == NULL)
  451. {
  452. LogError("Load COM_List failed");
  453. return false;
  454. }
  455. API_COM_Open = (PZ_COM_Open)GetProcAddress(m_hModule, "COM_Open");
  456. if (API_COM_Open == NULL)
  457. {
  458. LogError("Load COM_Open failed");
  459. return false;
  460. }
  461. API_COM_Close = (PZ_COM_Close)GetProcAddress(m_hModule, "COM_Close");
  462. if (API_COM_Close == NULL)
  463. {
  464. LogError("Load COM_Close failed");
  465. return false;
  466. }
  467. API_COM_SetCfgFilePath = (PZ_COM_SetCfgFilePath)GetProcAddress(m_hModule, "COM_SetCfgFilePath");
  468. if (API_COM_SetCfgFilePath == NULL)
  469. {
  470. LogError("Load COM_SetCfgFilePath failed");
  471. return false;
  472. }
  473. API_COM_LogPathGet = (PZ_COM_LogPathGet)GetProcAddress(m_hModule, "COM_LogPathGet");
  474. if (API_COM_LogPathGet == NULL)
  475. {
  476. LogError("Load COM_LogPathGet failed");
  477. return false;
  478. }
  479. API_COM_LogPathSet = (PZ_COM_LogPathSet)GetProcAddress(m_hModule, "COM_LogPathSet");
  480. if (API_COM_LogPathSet == NULL)
  481. {
  482. LogError("Load COM_LogPathSet failed");
  483. return false;
  484. }
  485. API_COM_HstAcq = (PZ_COM_HstAcq)GetProcAddress(m_hModule, "COM_HstAcq");
  486. if (API_COM_HstAcq == NULL)
  487. {
  488. LogError("Load COM_HstAcq failed");
  489. return false;
  490. }
  491. API_COM_Trigger = (PZ_COM_Trigger)GetProcAddress(m_hModule, "COM_Trigger");
  492. if (API_COM_Trigger == NULL)
  493. {
  494. LogError("Load COM_Trigger failed");
  495. return false;
  496. }
  497. API_COM_Dacq = (PZ_COM_Dacq)GetProcAddress(m_hModule, "COM_Dacq");
  498. if (API_COM_Dacq == NULL)
  499. {
  500. LogError("Load COM_Dacq failed");
  501. return false;
  502. }
  503. API_COM_Cbct = (PZ_COM_Cbct)GetProcAddress(m_hModule, "COM_Cbct");
  504. if (API_COM_Cbct == NULL)
  505. {
  506. LogError("Load COM_Cbct failed");
  507. return false;
  508. }
  509. API_COM_Stop = (PZ_COM_Stop)GetProcAddress(m_hModule, "COM_Stop");
  510. if (API_COM_Stop == NULL)
  511. {
  512. LogError("Load COM_Stop failed");
  513. return false;
  514. }
  515. API_COM_GetImage = (PZ_COM_GetImage)GetProcAddress(m_hModule, "COM_GetImage");
  516. if (API_COM_GetImage == NULL)
  517. {
  518. LogError("Load COM_GetImage failed");
  519. return false;
  520. }
  521. API_COM_GetImageMode = (PZ_COM_GetImageMode)GetProcAddress(m_hModule, "COM_GetImageMode");
  522. if (API_COM_GetImageMode == NULL)
  523. {
  524. LogError("Load COM_GetImageMode failed");
  525. return false;
  526. }
  527. API_COM_SetFPConf = (PZ_COM_SetFPConf)GetProcAddress(m_hModule, "COM_SetFPConf");
  528. if (API_COM_SetFPConf == NULL)
  529. {
  530. LogError("Load COM_SetFPConf failed");
  531. return false;
  532. }
  533. API_COM_GetFPConf = (PZ_COM_GetFPConf)GetProcAddress(m_hModule, "COM_GetFPConf");
  534. if (API_COM_GetFPConf == NULL)
  535. {
  536. LogError("Load COM_GetFPConf failed");
  537. return false;
  538. }
  539. API_COM_GetFPsn = (PZ_COM_GetFPsn)GetProcAddress(m_hModule, "COM_GetFPsn");
  540. if (API_COM_GetFPsn == NULL)
  541. {
  542. LogError("Load COM_GetFPsn failed");
  543. return false;
  544. }
  545. API_COM_GetFPsnEx = (PZ_COM_GetFPsnEx)GetProcAddress(m_hModule, "COM_GetFPsnEx");
  546. if (API_COM_GetFPsnEx == NULL)
  547. {
  548. LogError("Load COM_GetFPsn failed");
  549. return false;
  550. }
  551. API_COM_GetFPCompatibleVer = (PZ_COM_GetFPCompatibleVer)GetProcAddress(m_hModule, "COM_GetFPCompatibleVer");
  552. if (API_COM_GetFPCompatibleVer == NULL)
  553. {
  554. LogError("Load COM_GetFPCompatibleVer failed");
  555. return false;
  556. }
  557. API_COM_GetDllVer = (PZ_COM_GetDllVer)GetProcAddress(m_hModule, "COM_GetDllVer");
  558. if (API_COM_GetDllVer == NULL)
  559. {
  560. LogError("Load COM_GetDllVer failed");
  561. return false;
  562. }
  563. API_COM_GetBinningMode = (PZ_COM_GetBinningMode)GetProcAddress(m_hModule, "COM_GetBinningMode");
  564. if (API_COM_GetBinningMode == NULL)
  565. {
  566. LogError("Load COM_GetBinningMode failed");
  567. return false;
  568. }
  569. API_COM_SetBinningMode = (PZ_COM_SetBinningMode)GetProcAddress(m_hModule, "COM_SetBinningMode");
  570. if (API_COM_SetBinningMode == NULL)
  571. {
  572. LogError("Load COM_SetBinningMode failed");
  573. return false;
  574. }
  575. API_COM_GetPreCalibMode = (PZ_COM_GetPreCalibMode)GetProcAddress(m_hModule, "COM_GetPreCalibMode");
  576. if (API_COM_GetPreCalibMode == NULL)
  577. {
  578. LogError("Load COM_GetPreCalibMode failed");
  579. return false;
  580. }
  581. API_COM_SetPreCalibMode = (PZ_COM_SetPreCalibMode)GetProcAddress(m_hModule, "COM_SetPreCalibMode");
  582. if (API_COM_SetPreCalibMode == NULL)
  583. {
  584. LogError("Load COM_SetPreCalibMode failed");
  585. return false;
  586. }
  587. API_COM_GetCalibMode = (PZ_COM_GetCalibMode)GetProcAddress(m_hModule, "COM_GetCalibMode");
  588. if (API_COM_GetCalibMode == NULL)
  589. {
  590. LogError("Load COM_GetCalibMode failed");
  591. return false;
  592. }
  593. API_COM_SetCalibMode = (PZ_COM_SetCalibMode)GetProcAddress(m_hModule, "COM_SetCalibMode");
  594. if (API_COM_SetCalibMode == NULL)
  595. {
  596. LogError("Load COM_SetCalibMode failed");
  597. return false;
  598. }
  599. API_COM_GenOffsetTpl = (PZ_COM_GenOffsetTpl)GetProcAddress(m_hModule, "COM_GenOffsetTpl");
  600. if (API_COM_GenOffsetTpl == NULL)
  601. {
  602. LogError("Load COM_GenOffsetTpl failed");
  603. return false;
  604. }
  605. API_COM_GenGainTpl = (PZ_COM_GenGainTpl)GetProcAddress(m_hModule, "COM_GenGainTpl");
  606. if (API_COM_GenGainTpl == NULL)
  607. {
  608. LogError("Load COM_GenGainTpl failed");
  609. return false;
  610. }
  611. API_COM_GenDefectTpl = (PZ_COM_GenDefectTpl)GetProcAddress(m_hModule, "COM_GenDefectTpl");
  612. if (API_COM_GenDefectTpl == NULL)
  613. {
  614. LogError("Load COM_GenDefectTpl failed");
  615. return false;
  616. }
  617. API_COM_RegisterEvCallBack = (PZ_COM_RegisterEvCallBack)GetProcAddress(m_hModule, "COM_RegisterEvCallBack");
  618. if (API_COM_RegisterEvCallBack == NULL)
  619. {
  620. LogError("Load COM_RegisterEvCallBack failed");
  621. return false;
  622. }
  623. API_COM_UploadFPZMTpl = (PZ_COM_UploadFPZMTpl)GetProcAddress(m_hModule, "COM_UploadFPZMTpl");
  624. if (API_COM_UploadFPZMTpl == NULL)
  625. {
  626. LogError("Load COM_UploadFPZMTpl failed");
  627. return false;
  628. }
  629. API_COM_Dst = (PZ_COM_Dst)GetProcAddress(m_hModule, "COM_Dst");
  630. if (API_COM_Dst == NULL)
  631. {
  632. LogError("Load COM_Dst failed");
  633. return false;
  634. }
  635. API_COM_Prep = (PZ_COM_Prep)GetProcAddress(m_hModule, "COM_Prep");
  636. if (API_COM_Prep == NULL)
  637. {
  638. LogError("Load COM_Prep failed");
  639. return false;
  640. }
  641. API_COM_SetDynamicPara = (PZ_COM_SetDynamicPara)GetProcAddress(m_hModule, "COM_SetDynamicPara");
  642. if (API_COM_SetDynamicPara == NULL)
  643. {
  644. LogError("Load COM_SetDynamicPara failed");
  645. return false;
  646. }
  647. API_COM_Dexit = (PZ_COM_Dexit)GetProcAddress(m_hModule, "COM_Dexit");
  648. if (API_COM_Dexit == NULL)
  649. {
  650. LogError("Load COM_Dexit failed");
  651. return false;
  652. }
  653. API_COM_GetFPCurStatus = (PZ_COM_GetFPCurStatus)GetProcAddress(m_hModule, "COM_GetFPCurStatus");
  654. if (API_COM_GetFPCurStatus == NULL)
  655. {
  656. LogError("Load COM_GetFPCurStatus failed");
  657. return false;
  658. }
  659. API_COM_GetFPStatus = (PZ_COM_GetFPStatus)GetProcAddress(m_hModule, "COM_GetFPStatus");
  660. if (API_COM_GetFPStatus == NULL)
  661. {
  662. LogError("Load COM_GetFPStatus failed");
  663. return false;
  664. }
  665. }
  666. else
  667. {
  668. DWORD dw = GetLastError();
  669. strLog.Format("Load dll failed: %d", dw);
  670. LogError(strLog);
  671. return false;
  672. }
  673. LogInfo("LoadPZMedicalDLL OVER");
  674. return true;
  675. }
  676. // 卸载PZMedical的SDK
  677. void PZMedical2121ZCtrl::FreePZMedicalDLL()
  678. {
  679. LogInfo("## FreePZMedicalDLL ##");
  680. if (m_hModule)
  681. {
  682. FreeLibrary(m_hModule);
  683. m_hModule = NULL;
  684. LogInfo("FreePZMedicalDLL OVER");
  685. }
  686. else
  687. LogWarn("FreePZMedicalDLL failed");
  688. }
  689. // 调用SDK接口初始化探测器
  690. bool PZMedical2121ZCtrl::InitHW(HWND hWnd)
  691. {
  692. LogInfo("## InitHW ##");
  693. BOOL nRet;
  694. CHAR cRet;
  695. CString strLog;
  696. LogInfo("Call COM_RegisterEventCallBack: EVENT_LINKUPEX");
  697. nRet = API_COM_RegisterEvCallBack(EVENT_LINKUPEX, FuncLinkEXCallBack);
  698. if (!TestError(nRet))
  699. {
  700. LogError("Call COM_RegisterEventCallBack: EVENT_LINKUPEX failed");
  701. return false;
  702. }
  703. LogInfo("Call COM_RegisterEventCallBack: EVENT_LINKUP");
  704. nRet = API_COM_RegisterEvCallBack(EVENT_LINKUP, FuncLinkCallBack);
  705. if (!TestError(nRet))
  706. {
  707. LogError("Call COM_RegisterEventCallBack: EVENT_LINKUP failed");
  708. return false;
  709. }
  710. LogInfo("Call RegisterImageCallBack: EVENT_LINKDOWN");
  711. nRet = API_COM_RegisterEvCallBack(EVENT_LINKDOWN, FuncBreakCallBack);
  712. if (!TestError(nRet))
  713. {
  714. LogError("Call RegisterImageCallBack: EVENT_LINKDOWN failed");
  715. return false;
  716. }
  717. LogInfo("Call RegisterEventCallBack: EVENT_IMAGEVALID");
  718. nRet = API_COM_RegisterEvCallBack(EVENT_IMAGEVALID, FuncImageCallBack);
  719. if (!TestError(nRet))
  720. {
  721. LogError("Call RegisterEventCallBack: EVENT_IMAGEVALID failed");
  722. return false;
  723. }
  724. LogInfo("Call RegisterEventCallBack: EVENT_HEARTBEAT");
  725. nRet = API_COM_RegisterEvCallBack(EVENT_HEARTBEAT, FuncHeartBeatCallBack);
  726. if (!TestError(nRet))
  727. {
  728. LogError("Call RegisterEventCallBack: EVENT_HEARTBEAT failed");
  729. return false;
  730. }
  731. LogInfo("Call RegisterEventCallBack: EVENT_OFFSETDONE");
  732. nRet = API_COM_RegisterEvCallBack(EVENT_OFFSETDONE, FuncOffsetDoneCallBack);
  733. if (!TestError(nRet))
  734. {
  735. LogError("Call RegisterEventCallBack: EVENT_OFFSETDONE failed");
  736. return false;
  737. }
  738. LogInfo("Call RegisterEventCallBack: EVENT_READY");
  739. nRet = API_COM_RegisterEvCallBack(EVENT_READY, FuncReadyCallBack);
  740. if (!TestError(nRet))
  741. {
  742. LogError("Call RegisterEventCallBack: EVENT_READY failed");
  743. return false;
  744. }
  745. LogInfo("Call RegisterEventCallBack: EVENT_EXPOSE");
  746. nRet = API_COM_RegisterEvCallBack(EVENT_EXPOSE, FuncExposeCallBack);
  747. if (!TestError(nRet))
  748. {
  749. LogError("Call RegisterEventCallBack: EVENT_EXPOSE failed");
  750. return false;
  751. }
  752. LogInfo("Call RegisterEventCallBack: EVENT_IMAGESTART");
  753. nRet = API_COM_RegisterEvCallBack(EVENT_IMAGESTART, FuncImageStartCallBack);
  754. if (!TestError(nRet))
  755. {
  756. LogError("Call RegisterEventCallBack: EVENT_IMAGESTART failed");
  757. return false;
  758. }
  759. LogInfo("Call RegisterEventCallBack: EVENT_IMAGEEND");
  760. nRet = API_COM_RegisterEvCallBack(EVENT_IMAGEEND, FuncImageEndCallBack);
  761. if (!TestError(nRet))
  762. {
  763. LogError("Call RegisterEventCallBack: EVENT_IMAGEEND failed");
  764. return false;
  765. }
  766. //设置PCConfig.ini配置文件路径, 一般的情况下PCConfig.ini与ComApi.dll保持平行
  767. LogInfo("Call SetCfgFilePath");
  768. CString strCfgFilePath = strAppPath + _T("\\PZMedical");
  769. nRet = API_COM_SetCfgFilePath(strCfgFilePath.GetBuffer());
  770. if (!TestError(nRet))
  771. {
  772. LogWarn("Set SetCfgFilePath failed");
  773. }
  774. strCfgFilePath.ReleaseBuffer();
  775. //设置SDK日志保存路径
  776. LogInfo("Call SdkLog");
  777. CString strSDKFilePath = strAppPath + _T("\\PZMedical\\log");
  778. nRet = API_COM_LogPathSet(strSDKFilePath.GetBuffer());
  779. if (!TestError(nRet))
  780. {
  781. LogWarn("Set SdkLog failed");
  782. }
  783. strSDKFilePath.ReleaseBuffer();
  784. LogInfo("Call Init");
  785. nRet = API_COM_Init();
  786. if (!TestError(nRet))
  787. {
  788. strLog.Format("===== InitHW failed: COM_Init return(%d) =====", nRet);
  789. LogError(strLog);
  790. return false;
  791. }
  792. //因为不能确认连接到RFOC前探测器的状态,所以默认close一次
  793. if (!CloseDetector()) return false;
  794. //连接平板, 此处会触发平板的两个事件: EVENT_LINKUP, EVENT_HEARTBEAT
  795. //CString cFpSN = "AGA1BT309461";
  796. strLog.Format("Call Open, SN: %s", m_strFPSN);
  797. LogInfo(strLog);
  798. nRet = API_COM_Open(m_strFPSN.GetBuffer());
  799. if (!TestError(nRet))
  800. {
  801. LogWarn("Open FPD failed");
  802. return false;
  803. }
  804. bool bRet = WaitRespond(8000); //8秒钟之内回调,否则视为超时
  805. if (bRet)
  806. {
  807. //连接之后获取探测器基本信息
  808. if (!GetFPInfo())
  809. {
  810. LogWarn("GetFPInfo failed");
  811. }
  812. //连接之后设置校正模式
  813. if (!GetSetCalibMode(m_cCalibMode))
  814. {
  815. LogWarn("GetSetCalibMode failed");
  816. }
  817. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_CONNECTED, 0);
  818. }
  819. else
  820. {
  821. LogError("===== InitHW failed: Timeout =====");
  822. return false;
  823. }
  824. m_eStatus = Standby;
  825. m_eSubStatus = SubStatus_IDLE;
  826. LogInfo("InitHW OVER");
  827. return true;
  828. }
  829. //PZ2121Z先stop接口后close接口
  830. bool PZMedical2121ZCtrl::StopDetector()
  831. {
  832. LogInfo("## StopDtector ##");
  833. LogInfo("Call Stop");
  834. BOOL nRet = API_COM_Stop();
  835. if (!TestError(nRet))
  836. {
  837. LogError("COM_Stop failed");
  838. return false;
  839. }
  840. LogInfo("StopDtector OVER");
  841. return true;
  842. }
  843. //PZ2121Z的close接口一般要在stop接口之后探测器处于idle状态时才调用,探测器非idle状态时不要直接调用
  844. bool PZMedical2121ZCtrl::CloseDetector()
  845. {
  846. LogInfo("## CloseDetector ##");
  847. if (m_eStatus != Standby)
  848. {
  849. StopDetector();
  850. }
  851. LogInfo("Call Close");
  852. BOOL nRet = API_COM_Close();
  853. if (!TestError(nRet))
  854. {
  855. LogError("COM_Close failed");
  856. return false;
  857. }
  858. LogInfo("CloseDetector OVER");
  859. return true;
  860. }
  861. //PZ2121Z连接之前回调函数,COM_Open()接口之前触发
  862. BOOL CALLBACK PZMedical2121ZCtrl::FuncLinkEXCallBack(CHAR cEvent)
  863. {
  864. g_pPZMedicalInstance->LogInfo("[FuncLinkEXCallBack]");
  865. //这里列出所有与该电脑建立连接的探测器
  866. g_pPZMedicalInstance->LogInfo("Call List");
  867. BOOL nRet;
  868. CString strLog;
  869. TComFpList tFPList;
  870. nRet = g_pPZMedicalInstance->API_COM_List(&tFPList);
  871. if (!g_pPZMedicalInstance->TestError(nRet))
  872. {
  873. g_pPZMedicalInstance->LogWarn("List FPD failed");
  874. return false;
  875. }
  876. strLog.Format("List FP number: %d, SN: %s", tFPList.ncount, tFPList.tFpNode[0].FPPsn);
  877. g_pPZMedicalInstance->LogInfo(strLog);
  878. return TRUE;
  879. }
  880. //PZ2121Z连接成功回调函数,COM_Open()接口触发
  881. BOOL CALLBACK PZMedical2121ZCtrl::FuncLinkCallBack(CHAR cEvent)
  882. {
  883. CString strLog = "";
  884. strLog.Format("[EVENT_LINKUP] EventNum(%d): Detector connected.", cEvent);
  885. g_pPZMedicalInstance->LogInfo(strLog);
  886. g_pPZMedicalInstance->m_cEventNum = cEvent;
  887. g_pPZMedicalInstance->m_bFPDConnected = true;
  888. SetEvent(g_pPZMedicalInstance->m_hCallbackEvent);
  889. return TRUE;
  890. }
  891. //PZ2121Z连接失败回调函数, 断开连接触发
  892. BOOL CALLBACK PZMedical2121ZCtrl::FuncBreakCallBack(CHAR cEvent)
  893. {
  894. if (g_pPZMedicalInstance->m_cEventNum == cEvent) //当断线的时候,SDK会一直给EVENT_LINKDOWN回调,这个判断避免记录日志过多
  895. return FALSE;
  896. g_pPZMedicalInstance->m_cEventNum = cEvent;
  897. CString strLog = "";
  898. strLog.Format("[EVENT_LINKDOWN] EventNum(%d): Detector disconnected!", cEvent);
  899. g_pPZMedicalInstance->LogInfo(strLog);
  900. g_pPZMedicalInstance->m_bFPDConnected = false;
  901. return TRUE;
  902. }
  903. //PZ2121Z探测器心跳回调函数,COM_Open()接口触发
  904. BOOL CALLBACK PZMedical2121ZCtrl::FuncHeartBeatCallBack(CHAR cEvent)
  905. {
  906. CString strLog = "";
  907. strLog.Format("[EVENT_HEARTBEAT] EventNum(%d): Detector activate", cEvent);
  908. g_pPZMedicalInstance->LogInfo(strLog);
  909. if (!g_pPZMedicalInstance->GetFPCurStatus())
  910. {
  911. g_pPZMedicalInstance->LogError("GetFPCurStatus Error");
  912. }
  913. if (!g_pPZMedicalInstance->GetFPWifiTempBat())
  914. {
  915. g_pPZMedicalInstance->LogError("GetFPWifiTempBat Error");
  916. }
  917. return TRUE;
  918. }
  919. //PZ2121Z图像采集准备好的回调函数,之后可调用COM_GetImage()接口
  920. BOOL CALLBACK PZMedical2121ZCtrl::FuncImageCallBack(CHAR cEvent)
  921. {
  922. CString strLog;
  923. if (g_pPZMedicalInstance->m_bTimerSwitch)
  924. {
  925. g_pPZMedicalInstance->m_dwGetImageT = GetTickCount();
  926. DWORD dwTemp = g_pPZMedicalInstance->m_dwGetImageT - g_pPZMedicalInstance->m_dwLastT;
  927. g_pPZMedicalInstance->m_dwLastT = g_pPZMedicalInstance->m_dwGetImageT;
  928. strLog.Format("[EVENT_IMAGEVALID] EventNum(%d): No.(%d), Interval(%d)", cEvent, g_pPZMedicalInstance->m_nImgID, dwTemp);
  929. }
  930. else
  931. strLog.Format("[EVENT_IMAGEVALID] EventNum(%d): No.(%d)", cEvent, g_pPZMedicalInstance->m_nImgID);
  932. g_pPZMedicalInstance->LogInfo(strLog);
  933. g_pPZMedicalInstance->OnImageEvt();
  934. return TRUE;
  935. }
  936. //PZ2121Z探测器offset刷新完成回调函数, COM_Prep()接口触发
  937. BOOL CALLBACK PZMedical2121ZCtrl::FuncOffsetDoneCallBack(CHAR cEvent)
  938. {
  939. CString strLog = "";
  940. strLog.Format("[EVENT_OFFSETDONE] EventNum(%d): Detector offset done.", cEvent);
  941. g_pPZMedicalInstance->LogInfo(strLog);
  942. g_pPZMedicalInstance->m_bOffsetDone = true;
  943. SetEvent(g_pPZMedicalInstance->m_hCallbackEvent);
  944. return TRUE;
  945. }
  946. //PZ2121Z探测器
  947. BOOL CALLBACK PZMedical2121ZCtrl::FuncReadyCallBack(CHAR cEvent)
  948. {
  949. g_pPZMedicalInstance->LogInfo("[FuncReadyCallBack]");
  950. return TRUE;
  951. }
  952. //PZ2121Z探测器检测到X-ray时触发
  953. BOOL CALLBACK PZMedical2121ZCtrl::FuncExposeCallBack(CHAR cEvent)
  954. {
  955. g_pPZMedicalInstance->LogInfo("[FuncExposeCallBack]");
  956. return TRUE;
  957. }
  958. //开始传输图像
  959. BOOL CALLBACK PZMedical2121ZCtrl::FuncImageStartCallBack(CHAR cEvent)
  960. {
  961. g_pPZMedicalInstance->LogInfo("[FuncImageStartCallBack]");
  962. return TRUE;
  963. }
  964. //传输图像完成
  965. BOOL CALLBACK PZMedical2121ZCtrl::FuncImageEndCallBack(CHAR cEvent)
  966. {
  967. g_pPZMedicalInstance->LogInfo("[FuncImageEndCallBack]");
  968. return TRUE;
  969. }
  970. //PZ2121Z在获取到EVENT_LINKUP事件之后,获取平板的基本信息
  971. bool PZMedical2121ZCtrl::GetFPInfo()
  972. {
  973. BOOL nRet;
  974. CHAR cRet;
  975. CString strLog;
  976. #if 0
  977. //获取探测器型号以及SDK版本信息
  978. LogInfo("Call GetFPType");
  979. cRet = API_COM_GetFPType();
  980. switch (cRet)
  981. {
  982. case FP_TYPE_3543:
  983. LogInfo("FP_TYPE_3543");
  984. break;
  985. case FP_TYPE_4343:
  986. LogInfo("FP_TYPE_4343");
  987. break;
  988. case FP_TYPE_2121:
  989. LogInfo("FP_TYPE_2121");
  990. break;
  991. default:
  992. LogInfo("Unknow Type");
  993. break;
  994. }
  995. #endif
  996. //获取序列号和SDK版本
  997. CHAR cFpSN[32] = { '\0' };
  998. CHAR cSDKVer[32] = { '\0' };
  999. LogInfo("Call GetFPsn");
  1000. nRet = API_COM_GetFPsn(cFpSN);
  1001. //nRet = API_COM_GetFPsnEx(0, cFpSN);
  1002. if (!TestError(nRet))
  1003. {
  1004. LogWarn("GetFPsn failed");
  1005. }
  1006. LogInfo("Call GetDllVer");
  1007. nRet = API_COM_GetDllVer(cSDKVer);
  1008. if (!TestError(nRet))
  1009. {
  1010. LogWarn("GetDllVer failed");
  1011. }
  1012. strLog.Format("FPD SN(%s), SDK Ver(%s)", cFpSN, cSDKVer);
  1013. LogInfo(strLog);
  1014. //获取Binning模式, 如果当前探测器内部的Binnin模式和配置文件中的Binning模式不同, 则重新设置
  1015. LogInfo("Call GetBinningMode");
  1016. CHAR cBinningMode = 0;
  1017. nRet = API_COM_GetBinningMode(&cBinningMode);
  1018. if (!TestError(nRet))
  1019. {
  1020. LogWarn("GetBinningMode failed");
  1021. //return false;
  1022. }
  1023. else
  1024. {
  1025. if (cBinningMode == PZ_ONExONE)
  1026. strLog = "BinningMode is 1x1";
  1027. else if (cBinningMode == PZ_TWOxTWO)
  1028. strLog = "BinningMode is 2x2";
  1029. else if (cBinningMode == PZ_THRxTHR)
  1030. strLog = "BinningMode is 3x3";
  1031. else if (cBinningMode == PZ_FOURxFOUR)
  1032. strLog = "BingingMode is 4x4";
  1033. else if (cBinningMode == PZ_SIXxSIX)
  1034. strLog = "BingingMode is 6x6";
  1035. else
  1036. strLog.Format("No support BinningMode: %d", cBinningMode);
  1037. LogInfo(strLog);
  1038. }
  1039. if (m_nBinningMode != cBinningMode)
  1040. {
  1041. //设置探测器的 BinningMode 为 m_nBinningMode 值
  1042. LogInfo("Call SetBinningMode");
  1043. nRet = API_COM_SetBinningMode(m_nBinningMode);
  1044. if (!TestError(nRet))
  1045. {
  1046. LogError("SetBinningMode failed");
  1047. //return false;
  1048. }
  1049. strLog.Format("Change BinningMode to %d", m_nBinningMode);
  1050. LogInfo(strLog);
  1051. }
  1052. return true;
  1053. }
  1054. bool PZMedical2121ZCtrl::GetFPCurStatus()
  1055. {
  1056. LogInfo("Call GetFPCurStatus");
  1057. m_nFPCurStatus = API_COM_GetFPCurStatus();
  1058. switch (m_nFPCurStatus)
  1059. {
  1060. case STATUS_IDLE:
  1061. LogInfo("FP current status: IDLE");
  1062. break;
  1063. case STATUS_HST:
  1064. LogInfo("FP current status: HST");
  1065. break;
  1066. case STATUS_AED1:
  1067. LogInfo("FP current status: AED1");
  1068. break;
  1069. case STATUS_AED2:
  1070. LogInfo("FP current status: AED2");
  1071. break;
  1072. case STATUS_RECOVER:
  1073. LogInfo("FP current status: RECOVER");
  1074. break;
  1075. case STATUS_DST:
  1076. LogInfo("FP current status: DST");
  1077. break;
  1078. default:
  1079. LogError("FP current status: ERROR");
  1080. break;
  1081. }
  1082. return true;
  1083. }
  1084. bool PZMedical2121ZCtrl::GetFPWifiTempBat()
  1085. {
  1086. CString strLog = "";
  1087. BOOL nRet;
  1088. TFPStat tFPStat = { 0 };
  1089. nRet = API_COM_GetFPStatus(&tFPStat);
  1090. strLog.Format(_T("Wifi signal: %d"), tFPStat.tWifiStatus.ucSignal_level);
  1091. LogInfo(strLog);
  1092. strLog.Format(_T("Temperature: %.1f, Humidity:%.1f"), (double(tFPStat.tFpTempHum.Temp)) / 10, (double(tFPStat.tFpTempHum.Hum)) / 10);
  1093. LogInfo(strLog);
  1094. if (0 != (tFPStat.tBatInfo1.full + tFPStat.tBatInfo2.full))
  1095. strLog.Format(_T("Battery: %.2f"), (double(tFPStat.tBatInfo1.Remain + tFPStat.tBatInfo2.Remain) / (tFPStat.tBatInfo1.full + tFPStat.tBatInfo2.full)));
  1096. else
  1097. strLog = "Battery: NULL";
  1098. LogInfo(strLog);
  1099. return true;
  1100. }
  1101. bool PZMedical2121ZCtrl::GetImageInfo()
  1102. {
  1103. BOOL nRet;
  1104. CString strLog;
  1105. TImageMode* ptImageMode = NULL;
  1106. LogInfo("Call GetImageMode");
  1107. nRet = API_COM_GetImageMode(ptImageMode);
  1108. if (!TestError(nRet))
  1109. {
  1110. LogWarn("Get image mode failed");
  1111. return false;
  1112. }
  1113. UINT16 u16ImageRow = ptImageMode->usRow;
  1114. UINT16 u16ImageCol = ptImageMode->usCol;
  1115. UINT16 u16ImagePixel = ptImageMode->usPix;
  1116. strLog.Format("ImageRow(%d), ImageCol(%d), ImagePixel(%d)", u16ImageRow, u16ImageCol, u16ImagePixel);
  1117. LogInfo(strLog);
  1118. return true;
  1119. }
  1120. bool PZMedical2121ZCtrl::ExpEnable() //父类AcqCtrl有,暂时没用
  1121. {
  1122. CAcqCtrl::ExpEnable();
  1123. return true;
  1124. }
  1125. bool PZMedical2121ZCtrl::ExpDisable() //父类AcqCtrl有,暂时没用
  1126. {
  1127. CAcqCtrl::ExpDisable();
  1128. return true;
  1129. }
  1130. bool PZMedical2121ZCtrl::FluEnable() //父类AcqCtrl有,暂时没用
  1131. {
  1132. CAcqCtrl::FluEnable();
  1133. return true;
  1134. }
  1135. bool PZMedical2121ZCtrl::FluDisable() //父类AcqCtrl有,暂时没用
  1136. {
  1137. CAcqCtrl::FluDisable();
  1138. return true;
  1139. }
  1140. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1141. ////////////////////////////////////////////////////////// Functions //////////////////////////////////
  1142. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1143. // 获取当前校正文件状态
  1144. bool PZMedical2121ZCtrl::GetCalibrationStatus(int nLogicMode, int nOffsetIndex, ZSKK_CAL_STATUS& modeStatus)
  1145. {
  1146. return true;
  1147. }
  1148. // 激活当前模式
  1149. bool PZMedical2121ZCtrl::ActiveLogicMode(int nmode, int nOffRef)
  1150. {
  1151. LogInfo("## ActiveLogicMode ##");
  1152. if (!m_bFPDConnected)
  1153. {
  1154. LogError("No connect, return false");
  1155. return false;
  1156. }
  1157. if ((m_eStatus == Offset) || (m_eStatus == XrayCalibration))
  1158. {
  1159. LogError("Detector is in calibration state, ignore Active Mode");
  1160. return false;
  1161. }
  1162. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, 0); // Notify Prepare
  1163. m_PreSynParam.xWindow = m_CurSynParam.xWindow;
  1164. m_PreSynParam.frenquency = m_CurSynParam.frenquency;
  1165. DetectorMode tempDetectMode;
  1166. OffsetMode tempOffsetMode;
  1167. CString strLog = "";
  1168. int ntempOffsetNum = 0;
  1169. int nXSize, nYSize;
  1170. // 根据激活模式状态,切换改采集卡配置,切换同步方式
  1171. size_t nsize = RFModeConf.DetectorMode.m_nodes.size();
  1172. for (int i = 0; i < nsize; i++)
  1173. {
  1174. tempDetectMode = RFModeConf.DetectorMode.m_nodes[i];
  1175. ntempOffsetNum = tempDetectMode.OffsetMode.m_nodes.size();
  1176. if (tempDetectMode.LogicMode == nmode)
  1177. {
  1178. if (nmode != m_ActiveMode.nLogicMode)
  1179. {
  1180. LogInfo("Change ApplicationMode");
  1181. }
  1182. else
  1183. {
  1184. LogInfo("No Change just return");
  1185. //return true;
  1186. break; //改为break,可以执行下面的修改配置操作
  1187. }
  1188. if (nOffRef < tempDetectMode.OffsetMode.m_nodes.size())
  1189. {
  1190. tempOffsetMode = tempDetectMode.OffsetMode.m_nodes[nOffRef];
  1191. m_CurSynParam.frenquency = tempOffsetMode.Frequency;
  1192. m_CurSynParam.xWindow = tempOffsetMode.Xwindow;
  1193. strLog.Format("Frenquency(%f), Xwindow(%f)", m_CurSynParam.frenquency, m_CurSynParam.xWindow);
  1194. LogInfo(strLog);
  1195. COPYDATASTRUCT copyData;
  1196. copyData.lpData = &m_CurSynParam;
  1197. copyData.cbData = sizeof(ZSKK_CAL_SYN_PARAM);
  1198. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALDETECTOR_FPSXWIN, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1199. }
  1200. //使用PZAppModeConf.xml中的起始行列计算图像大小,避免在使用自定义开窗模式时需要修改PZAppModeConf.xml和RFModeConf.xml两个文件
  1201. APPMode objPZMode;
  1202. bool bGetMode = false;
  1203. for (int n = 0; n < PZModeConf.APPMode.m_nodes.size(); n++)
  1204. {
  1205. if (PZModeConf.APPMode.m_nodes[n].AppModeKey == nmode)
  1206. {
  1207. objPZMode = PZModeConf.APPMode.m_nodes[nmode];
  1208. bGetMode = true;
  1209. break;
  1210. }
  1211. }
  1212. if (!bGetMode)
  1213. {
  1214. strLog.Format("Not found the mode: %d", nmode);
  1215. LogError(strLog);
  1216. return false;
  1217. }
  1218. nXSize = (objPZMode.EndColum - objPZMode.StartColum + 1) / (objPZMode.BinningMode + 1);
  1219. nYSize = (objPZMode.EndLine - objPZMode.StartLine + 1) / (objPZMode.BinningMode + 1);
  1220. ChangeActiveMode(tempDetectMode.ExamType, tempDetectMode.PUMode
  1221. , /*tempDetectMode.ImageSizeX*/nXSize,
  1222. /*tempDetectMode.ImageSizeY*/nYSize
  1223. , tempDetectMode.DeadLineLeft, tempDetectMode.DeadLineTop
  1224. , tempDetectMode.DeadLineRight, tempDetectMode.DeadLineBottom);
  1225. break;
  1226. }
  1227. }
  1228. m_ActiveMode.nLogicMode = nmode;
  1229. m_ActiveMode.nOffIndex = nOffRef;
  1230. strLog.Format("Active mode(%d) successfully", m_ActiveMode.nLogicMode);
  1231. LogInfo(strLog);
  1232. ZSKK_CAL_STATUS CalStatus;
  1233. if (GetCalibrationStatus(nmode, nOffRef, CalStatus))
  1234. {
  1235. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_CURMODE_ACTIVE, m_ActiveMode.nLogicMode * 10 + m_ActiveMode.nOffIndex, 0);
  1236. COPYDATASTRUCT copyData;
  1237. copyData.lpData = &CalStatus;
  1238. copyData.cbData = sizeof(ZSKK_CAL_STATUS);
  1239. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALIBRATIONSTATUS, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1240. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_CURMODE_CALSTATUS, ZSKK_DETECTOR_LPARAM_CALSTATUS_REFRESH, 0);
  1241. }
  1242. //调用SDK接口,进入采集状态
  1243. if (!StartAcquisition(nmode))
  1244. {
  1245. return false;
  1246. }
  1247. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVESUCCESS, 0);
  1248. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_READYACQ, 0);
  1249. LogInfo("------ActiveLogicMode Send message: ACQ_READY------");
  1250. return true;
  1251. }
  1252. bool PZMedical2121ZCtrl::ChangeActiveMode(CString ExamType, int nPUMode, int nSizeX, int nSizeY, int nCropLeft, int nCropTop, int nCropRight, int nCropBottom)
  1253. {
  1254. LogInfo(" ## ChangeActiveMode ## ");
  1255. CString strLog = "";
  1256. DWORD ImgSize = nSizeX * nSizeY;
  1257. m_nRawWidth = nSizeX;
  1258. m_nRawHeight = nSizeY;
  1259. if (m_ImgInfo.pwData == NULL)
  1260. {
  1261. m_pImgBufferSize = ImgSize;
  1262. m_ImgInfo.pwData = new WORD[m_pImgBufferSize];
  1263. }
  1264. else
  1265. {
  1266. if (ImgSize > m_pImgBufferSize)
  1267. {
  1268. delete[]m_ImgInfo.pwData;
  1269. m_pImgBufferSize = ImgSize;
  1270. m_ImgInfo.pwData = new WORD[m_pImgBufferSize];
  1271. }
  1272. }
  1273. strLog.Format("Change active mode: SizeX = %d, SizeY = %d", m_nRawWidth, m_nRawHeight);
  1274. LogInfo(strLog);
  1275. if (m_cImgBuff != NULL)
  1276. {
  1277. delete m_cImgBuff;
  1278. m_cImgBuff = NULL;
  1279. }
  1280. m_cImgBuff = new CHAR[nSizeX * nSizeY * 2];
  1281. m_nCropLeft = nCropLeft;
  1282. m_nCropTop = nCropTop;
  1283. m_nCropRight = nCropRight;
  1284. m_nCropBottom = nCropBottom;
  1285. m_ImgInfo.nWidth = nSizeX - m_nCropLeft - m_nCropRight;
  1286. m_ImgInfo.nHeight = nSizeY - m_nCropTop - m_nCropBottom;
  1287. m_ImgInfo.nBits = 16;
  1288. m_ACQInfo.nColumn = m_ImgInfo.nWidth;
  1289. m_ACQInfo.nRow = m_ImgInfo.nHeight;
  1290. m_ACQInfo.nBits = 16;
  1291. m_ACQInfo.fACQElementSpacing = (float)(m_nPixelSpacing*0.001);
  1292. CWnd *pWndTest = NULL;
  1293. if (ExamType == _T("RAD") || ExamType == _T("TOMO"))
  1294. {
  1295. strLog.Format("Send RAD image information: SizeX = %d, SizeY = %d, PixelSpacing = %.3f", m_ACQInfo.nColumn, m_ACQInfo.nRow, m_ACQInfo.fACQElementSpacing);
  1296. LogInfo(strLog);
  1297. COPYDATASTRUCT copyData;
  1298. copyData.lpData = &m_ACQInfo;
  1299. copyData.cbData = sizeof(ZSKK_ACQ_INFO);
  1300. MSGControl(pWndTest, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_RAD_IMAGESIZEBIT, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1301. }
  1302. else
  1303. {
  1304. strLog.Format("Send Flu Image information: SizeX = %d, SizeY = %d, PixelSpacing = %.3f,", m_ACQInfo.nColumn, m_ACQInfo.nRow, m_ACQInfo.fACQElementSpacing);
  1305. LogInfo(strLog);
  1306. COPYDATASTRUCT copyData;
  1307. copyData.lpData = &m_ACQInfo;
  1308. copyData.cbData = sizeof(ZSKK_ACQ_INFO);
  1309. MSGControl(pWndTest, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_FLU_IMAGESIZEBIT, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1310. }
  1311. LogInfo("CHANGE OVER");
  1312. return true;
  1313. }
  1314. void PZMedical2121ZCtrl::setNextStepEvent()
  1315. {
  1316. LogInfo(" ## setNextStepEvent ## ");
  1317. }
  1318. bool PZMedical2121ZCtrl::DownloadCorrectionFile2Device()
  1319. {
  1320. LogInfo(" ## DownloadCorrectionFile2Device ## ");
  1321. return true;
  1322. }
  1323. // For detector x-ray calibration
  1324. bool PZMedical2121ZCtrl::OnXrayGenStart()
  1325. {
  1326. LogInfo("Calibration request to start Xray");
  1327. //Send message to upper layer
  1328. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_STARTXRAY, NULL, ZSKK_MSG_TYPE_SYNC_NO);
  1329. return true;
  1330. }
  1331. // For detector x-ray calibration
  1332. bool PZMedical2121ZCtrl::OnXrayGenStop()
  1333. {
  1334. LogInfo("Calibration request to stop Xray");
  1335. //Send message to upper layer
  1336. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_STOPXRAY, NULL, ZSKK_MSG_TYPE_SYNC_YES);
  1337. return true;
  1338. }
  1339. // For detector x-ray calibration
  1340. bool PZMedical2121ZCtrl::OnXrayGenSetDose()
  1341. {
  1342. LogInfo(" ## OnXrayGenSetDose ## ");
  1343. return true;
  1344. }
  1345. // For detector x-ray calibration
  1346. bool PZMedical2121ZCtrl::OnXrayCalSuccess()
  1347. {
  1348. LogInfo("------Calibration success---");
  1349. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALSUCCESS, 0);
  1350. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_READYACQ, 0);
  1351. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_ALARM_CODE, 0, 0); //clear alarm error
  1352. LogInfo("------OnXrayCalSuccess Send message: ACQ_READY---");
  1353. return true;
  1354. }
  1355. // For detector x-ray calibration
  1356. bool PZMedical2121ZCtrl::OnXrayCalFail()
  1357. {
  1358. //Send message to upper layer
  1359. m_strCalWarning = "ERR_CALIBRATION_COMPUTATION";
  1360. LogInfo("Calibration failed: ERR_CALIBRATION_COMPUTATION");
  1361. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALFAILED, 0);
  1362. return true;
  1363. }
  1364. bool PZMedical2121ZCtrl::OnSYNC()
  1365. {
  1366. //Send message to upper layer
  1367. CString strdose;
  1368. strdose.Format("Get syn message,Xwindow = %d, Frequency = %f", m_CalSynParam.xWindow, m_CalSynParam.frenquency);
  1369. LogInfo(strdose);
  1370. //修改该信号,回调函数通知外部给信号
  1371. COPYDATASTRUCT copyData;
  1372. copyData.lpData = &m_CalSynParam;
  1373. copyData.cbData = sizeof(ZSKK_CAL_SYN_PARAM);
  1374. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALDETECTOR_FPSXWIN, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1375. return true;
  1376. }
  1377. bool PZMedical2121ZCtrl::OnWarning()
  1378. {
  1379. LogInfo(" ## OnWarning ## ");
  1380. return true;
  1381. }
  1382. bool PZMedical2121ZCtrl::OnStatus()
  1383. {
  1384. LogInfo(" ## OnStatus ## ");
  1385. return true;
  1386. }
  1387. bool PZMedical2121ZCtrl::OnModeActive()
  1388. {
  1389. LogInfo(" ## OnModeActive ## ");
  1390. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVESUCCESS, 0);
  1391. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_READYACQ, 0);
  1392. return true;
  1393. }
  1394. bool PZMedical2121ZCtrl::OnTimeOut()
  1395. {
  1396. if (m_bState)return false;
  1397. return true;
  1398. }
  1399. //获取LogicMode列表,4343D不太依赖这个配置,所以用不到
  1400. bool PZMedical2121ZCtrl::GetLogicModeList(vector <ZSKK_DETECTOR_MODE_INFO> &vecDetectorMode)
  1401. {
  1402. //if (CAcqCtrl::GetLogicModeList(vecDetectorMode)) return true;
  1403. LogInfo(" ## GetLogicModeList ## ");
  1404. DetectorMode tempDetectMode;
  1405. OffsetMode tempOffsetMode;
  1406. ZSKK_DETECTOR_MODE_INFO tempDetectorModeInfo;
  1407. vector <ZSKK_DETECTOR_MODE_INFO> &tempvecDetectorMode = vecDetectorMode;
  1408. tempvecDetectorMode.clear();
  1409. int ntempOffsetNum = 0;
  1410. int nsize = RFModeConf.DetectorMode.m_nodes.size();
  1411. for (int i = 0; i < nsize; i++)
  1412. {
  1413. tempDetectMode = RFModeConf.DetectorMode.m_nodes[i];
  1414. tempDetectorModeInfo.nLogicMode = tempDetectMode.LogicMode;
  1415. tempDetectorModeInfo.nPUMode = tempDetectMode.PUMode;
  1416. tempDetectorModeInfo.strExpType = tempDetectMode.ExamType;
  1417. tempDetectorModeInfo.strConfFile = tempDetectMode.ConfigurationFile;
  1418. //tempDetectorModeInfo.strBinMode = tempDetectMode
  1419. tempDetectorModeInfo.nGainValue = tempDetectMode.GainValue;
  1420. tempDetectorModeInfo.nModeEnable = tempDetectMode.ModeEnable;
  1421. tempDetectorModeInfo.nColumn = tempDetectMode.ImageSizeX;
  1422. tempDetectorModeInfo.nRow = tempDetectMode.ImageSizeY;
  1423. //offset info
  1424. ntempOffsetNum = tempDetectMode.OffsetMode.m_nodes.size();
  1425. for (int j = 0; j < ntempOffsetNum; j++)
  1426. {
  1427. tempOffsetMode = tempDetectMode.OffsetMode.m_nodes[j];
  1428. tempDetectorModeInfo.nOffsetIndex = tempOffsetMode.OffsetIndex;
  1429. tempDetectorModeInfo.nXwindow = tempOffsetMode.Xwindow;
  1430. tempDetectorModeInfo.fFrequency = tempOffsetMode.Frequency;
  1431. tempDetectorModeInfo.strDescription = tempOffsetMode.Description;
  1432. tempvecDetectorMode.push_back(tempDetectorModeInfo);
  1433. }
  1434. }
  1435. //vecDetectorMode = tempvecDetectorMode;
  1436. LogInfo("End to get logicModelist");
  1437. return true;
  1438. }
  1439. bool PZMedical2121ZCtrl::CalibrateAllModes()
  1440. {
  1441. LogInfo(" ## CalibrateAllModes ## ");
  1442. return true;
  1443. }
  1444. // 从RFModeConf.xml中获取OffsetMode,4343D闲时自己刷offset,用不到这个函数
  1445. int PZMedical2121ZCtrl::GetOffsetMode(int nLogicMode, int nOffsetIndex, int nSpeed)
  1446. {
  1447. LogInfo("## GetOffsetMode ##");
  1448. CString strlog;
  1449. int res = nOffsetIndex;
  1450. DetectorMode tempDetectMode;
  1451. OffsetMode tempOffsetMode;
  1452. int ntempOffsetNum = 0;
  1453. int nsize = RFModeConf.DetectorMode.m_nodes.size();
  1454. for (int i = 0; i < nsize; i++)
  1455. {
  1456. tempDetectMode = RFModeConf.DetectorMode.m_nodes[i];
  1457. if (tempDetectMode.LogicMode == nLogicMode)
  1458. {
  1459. ntempOffsetNum = tempDetectMode.OffsetMode.m_nodes.size();
  1460. for (int j = 0; j < ntempOffsetNum; j++)
  1461. {
  1462. tempOffsetMode = tempDetectMode.OffsetMode.m_nodes[j];
  1463. if (nSpeed == (int)(tempOffsetMode.Frequency))
  1464. {
  1465. res = j;
  1466. strlog.Format("current logic mode is %d speed is %0.2f, offset mode is %d", nLogicMode, tempOffsetMode.Frequency, res);
  1467. LogInfo(strlog);
  1468. return res;
  1469. }
  1470. }
  1471. }
  1472. }
  1473. return res;
  1474. }
  1475. // [xxxDlg.cpp]OnMSGPARAMETER() -> [xxxCtrl.cpp]OnMSGPARAMETER_Process(WPARAM, LPARAM)
  1476. // WPARAM 0: ZSKK_DETECTOR_PA_SET_RADMODE 设置点片模式
  1477. bool PZMedical2121ZCtrl::SelectRADMode(int nLogicMode, int nOffsetIndex)
  1478. {
  1479. LogInfo("## SelectRADMode ##");
  1480. if (CAcqCtrl::SelectRADMode(nLogicMode, nOffsetIndex)) return true;
  1481. if (!m_bFPDConnected)
  1482. {
  1483. LogError("No connect, return false");
  1484. return false;
  1485. }
  1486. CString strLog = "";
  1487. //从上层传过来的模式为ZSKK模式,301或302一类的code值,需要通过文件RealModeMatch.xml转换成当前平板的真实逻辑模式。
  1488. CString strMode;
  1489. strMode.Format("%04d", nLogicMode);
  1490. m_RadMode.nLogicMode = atoi(m_appRealModeConf.GetValueByKey(strMode));
  1491. m_RadMode.nOffIndex = nOffsetIndex;
  1492. strLog.Format("Select RAD Mode(%d), Offset index(%d)", m_RadMode.nLogicMode, m_RadMode.nOffIndex);
  1493. LogInfo(strLog);
  1494. LogInfo("SelectRADMode OVER");
  1495. return true;
  1496. }
  1497. // WPARAM 1: ZSKK_DETECTOR_PA_SET_FLUMODE 设置透视模式
  1498. bool PZMedical2121ZCtrl::SelectFLUMode(int nLogicMode, int nOffsetIndex)
  1499. {
  1500. LogInfo(" ## SelectFLUMode ## ");
  1501. if (CAcqCtrl::SelectFLUMode(nLogicMode, nOffsetIndex))return true;
  1502. if (!m_bFPDConnected)
  1503. {
  1504. LogWarn("Not connected");
  1505. }
  1506. CString strLog = "";
  1507. //从上层传过来的模式为ZSKK模式,101或202一类的code值,需要通过文件RealModeMatch.xml转换成当前平板的真实逻辑模式。
  1508. CString strMode;
  1509. strMode.Format("%04d", nLogicMode);
  1510. m_FluMode.nLogicMode = atoi(m_appRealModeConf.GetValueByKey(strMode));
  1511. m_FluMode.nOffIndex = nOffsetIndex;
  1512. strLog.Format("SELECT OVER, FLU MODE(%d), OFFSET INDEX(%d)", m_FluMode.nLogicMode, nOffsetIndex);
  1513. LogInfo(strLog);
  1514. //LogInfo("->CBCTStart");
  1515. //int nRet = COM_MFPCBCTSTART(); //调用CBCT接口,提前终止SDK的Idle状态,避免在出射线的时候还在刷新offset文件
  1516. //if (!TestError(nRet))
  1517. //{
  1518. // LogError("CBCTStart failed");
  1519. // return false;
  1520. //}
  1521. return true;
  1522. }
  1523. // WPARAM 2: ZSKK_DETECTOR_PA_SET_CINEMODE 没有这个模式,用不到
  1524. bool PZMedical2121ZCtrl::SelectCINEMode(int nLogicMode, int nOffsetIndex) //选择CINE模式
  1525. {
  1526. LogInfo(" ## SelectCINEMode ## ");
  1527. if (CAcqCtrl::SelectCINEMode(nLogicMode, nOffsetIndex))return true;
  1528. if (!m_bFPDConnected)
  1529. {
  1530. LogError("No connect, return false");
  1531. return false;
  1532. }
  1533. CString strLog = "";
  1534. strLog.Format("-----Select CINE mode: %d, Offset index: %d----", nLogicMode, nOffsetIndex);
  1535. LogInfo(strLog);
  1536. return true; //4343D没有这个模式
  1537. //从上层传过来的模式为ZSKK模式,101或202一类的code值,需要通过文件RealModeMatch.xml转换成当前平板的真实逻辑模式。
  1538. //CString strMode;
  1539. //strMode.Format("%04d", nLogicMode);
  1540. //LogInfo(strMode);
  1541. //m_CINEMode.nLogicMode = atoi(m_appRealModeConf.GetValueByKey(strMode));
  1542. //strMode.Format("nLogicMode %04d", m_CINEMode.nLogicMode);
  1543. //LogInfo(strMode);
  1544. m_CINEMode.nLogicMode = nLogicMode;
  1545. m_CINEMode.nOffIndex = nOffsetIndex;
  1546. return true;
  1547. }
  1548. // WPARAM 3: ZSKK_DETECTOR_PA_SET_RADSPEED 设置点片帧频
  1549. // 每种曝光模式只有一个帧频,接口中只记录日志,返回true
  1550. bool PZMedical2121ZCtrl::SetRadOffsetMode(int nLogicMode, int nOffsetIndex, int nSpeed)
  1551. {
  1552. LogInfo("## SetRadOffsetMode ##");
  1553. if (!m_bFPDConnected)
  1554. {
  1555. LogError("No connect, return false");
  1556. return false;
  1557. }
  1558. CString strlog = "";
  1559. //int ApplicationMode = GetOffsetMode(nLogicMode, nOffsetIndex, nSpeed);
  1560. strlog.Format("Set RAD speed to: %d", nSpeed);
  1561. LogInfo(strlog);
  1562. return true; //不支持获取校正状态(校正文件有效期等)
  1563. ZSKK_CAL_STATUS CalStatus;
  1564. if (GetCalibrationStatus(m_RadMode.nLogicMode, m_RadMode.nOffIndex, CalStatus))
  1565. {
  1566. COPYDATASTRUCT copyData;
  1567. copyData.lpData = &CalStatus;
  1568. copyData.cbData = sizeof(ZSKK_CAL_STATUS);
  1569. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALIBRATIONSTATUS, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1570. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_RADMODE_CALSTATUS, ZSKK_DETECTOR_LPARAM_CALSTATUS_REFRESH, 0);
  1571. }
  1572. return true;
  1573. }
  1574. // WPARAM 4: ZSKK_DETECTOR_PA_SET_FLUSPEED 设置透视帧频
  1575. // 目前4343D每种曝光模式只有一个帧频,接口中只记录日志,返回true
  1576. bool PZMedical2121ZCtrl::SetFluOffsetMode(int nLogicMode, int nOffsetIndex, float fSpeed)
  1577. {
  1578. LogInfo(" ## SetFluOffsetMode ## ");
  1579. if (!m_bFPDConnected)
  1580. {
  1581. LogError("No connect, return false");
  1582. return false;
  1583. }
  1584. CString strlog = "";
  1585. //int ApplicationMode = GetOffsetMode(nLogicMode, nOffsetIndex, fSpeed);
  1586. strlog.Format("Set FLU speed to: %0.2f", fSpeed/*, ApplicationMode*/);
  1587. LogInfo(strlog);
  1588. return true; //不支持获取校正状态(校正文件有效期等)
  1589. ZSKK_CAL_STATUS CalStatus;
  1590. if (GetCalibrationStatus(m_FluMode.nLogicMode, m_FluMode.nOffIndex, CalStatus))
  1591. {
  1592. COPYDATASTRUCT copyData;
  1593. copyData.lpData = &CalStatus;
  1594. copyData.cbData = sizeof(ZSKK_CAL_STATUS);
  1595. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALIBRATIONSTATUS, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1596. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_RADMODE_CALSTATUS, ZSKK_DETECTOR_LPARAM_CALSTATUS_REFRESH, 0);
  1597. }
  1598. return true;
  1599. }
  1600. // WPARAM 5: ZSKK_DETECTOR_PA_SET_FLUSPEED 没有这个模式,用不到
  1601. bool PZMedical2121ZCtrl::SetCinOffsetMode(int nLogicMode, int nOffsetIndex, float fSpeed)
  1602. {
  1603. LogInfo(" ## SetCinOffsetMode ## ");
  1604. int ApplicationMode = GetOffsetMode(nLogicMode, nOffsetIndex, fSpeed);
  1605. CString strlog;
  1606. strlog.Format("current CIN speed is %0.2f, OffseMode is %d", fSpeed, ApplicationMode);
  1607. LogInfo(strlog);
  1608. if (!m_bFPDConnected)
  1609. {
  1610. LogError("No connect, return false");
  1611. return false;
  1612. }
  1613. return true; //4343D没有这个模式
  1614. ZSKK_CAL_STATUS CalStatus;
  1615. if (GetCalibrationStatus(m_CINEMode.nLogicMode, m_CINEMode.nOffIndex, CalStatus))
  1616. {
  1617. COPYDATASTRUCT copyData;
  1618. copyData.lpData = &CalStatus;
  1619. copyData.cbData = sizeof(ZSKK_CAL_STATUS);
  1620. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALIBRATIONSTATUS, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  1621. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_RADMODE_CALSTATUS, ZSKK_DETECTOR_LPARAM_CALSTATUS_REFRESH, 0);
  1622. }
  1623. return false;
  1624. }
  1625. // WPARAM 6: ZSKK_DETECTOR_PA_ACTIVE_RADMODE 激活点片模式
  1626. // 只是设置上传帧频、窗口、图像大小等参数
  1627. bool PZMedical2121ZCtrl::ActiveRADMode()
  1628. {
  1629. LogInfo("## ActiveRADMode ##");
  1630. if (CAcqCtrl::ActiveRADMode()) return true;
  1631. if (!m_bFPDConnected)
  1632. {
  1633. LogError("No connect, return false");
  1634. return false;
  1635. }
  1636. if (m_eStatus == Acquire)
  1637. {
  1638. LogWarn("Already in acquiring image, return true");
  1639. return true;
  1640. }
  1641. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, 0);
  1642. LogInfo("------ActiveRADMode Send message: PREPARE---");
  1643. if (!ActiveHSTMode())
  1644. {
  1645. LogError("Set FPD in HST failed");
  1646. }
  1647. //check if the mode is active already
  1648. bool bActive = false;
  1649. m_bSendRadImage = false;
  1650. m_nPixelSpacing = 140; //图像的Pixel Spacing
  1651. CString strtemp;
  1652. strtemp.Format("RAD Mode: %d, Target offset Index: %d", m_RadMode.nLogicMode, m_RadMode.nOffIndex);
  1653. LogInfo(strtemp);
  1654. if (ActiveLogicMode(m_RadMode.nLogicMode, m_RadMode.nOffIndex))
  1655. {
  1656. bActive = true;
  1657. }
  1658. else
  1659. {
  1660. bActive = false;
  1661. }
  1662. if (bActive)
  1663. {
  1664. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVESUCCESS, 0);
  1665. LogInfo("Success, Current RAD mode active success");
  1666. return true;
  1667. }
  1668. else
  1669. {
  1670. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVEFAILED, 0);
  1671. LogInfo("Failed, Current RAD mode active failed.");
  1672. return false;
  1673. }
  1674. }
  1675. // WPARAM 7: ZSKK_DETECTOR_PA_ACTIVE_FLUMODE 激活透视模式
  1676. // 只是设置上传帧频、窗口、图像大小等参数
  1677. bool PZMedical2121ZCtrl::ActiveFLUMode()
  1678. {
  1679. LogInfo("## ActiveFLUMode ##");
  1680. if (CAcqCtrl::ActiveFLUMode()) return true;
  1681. if (!m_bFPDConnected)
  1682. {
  1683. LogError("No connect, return false");
  1684. return false;
  1685. }
  1686. if (m_eStatus == Acquire)
  1687. {
  1688. LogInfo("Acquiring image,return true");
  1689. return true;
  1690. }
  1691. //::PostMessage(this->m_hWnd,MSG_ACQ_STATUS,ACQ_PREPARE,NULL);
  1692. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, 0);
  1693. LogInfo("------ActiveFLUMode Send message: ACQ_PREPARE---");
  1694. if (!ActiveDSTMode())
  1695. {
  1696. LogError("Set FPD in DST failed");
  1697. }
  1698. //check if the mode is active already
  1699. bool bActive = false;
  1700. //通过配置文件获取binning模式,用来计算PixelSpacing
  1701. CString strLog = "";
  1702. APPMode objPZMode;
  1703. bool bGetMode = false;
  1704. for (int n = 0; n < PZModeConf.APPMode.m_nodes.size(); n++)
  1705. {
  1706. if (PZModeConf.APPMode.m_nodes[n].AppModeKey == m_FluMode.nLogicMode)
  1707. {
  1708. objPZMode = PZModeConf.APPMode.m_nodes[m_FluMode.nLogicMode];
  1709. bGetMode = true;
  1710. break;
  1711. }
  1712. }
  1713. if (!bGetMode)
  1714. {
  1715. strLog.Format("Not found the mode: %d", m_FluMode.nLogicMode);
  1716. LogError(strLog);
  1717. return false;
  1718. }
  1719. m_nPixelSpacing = (objPZMode.BinningMode + 1) * 140;//图像的PixelSpacing根据binning模式自动扩大相应倍数
  1720. CString strtemp;
  1721. strtemp.Format("Flu Mode: %d, Target offset Index: %d", m_FluMode.nLogicMode, m_FluMode.nOffIndex);
  1722. LogInfo(strtemp);
  1723. if (ActiveLogicMode(m_FluMode.nLogicMode, m_FluMode.nOffIndex))
  1724. {
  1725. bActive = true;
  1726. }
  1727. else
  1728. {
  1729. bActive = false;
  1730. }
  1731. if (bActive)
  1732. {
  1733. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVESUCCESS, 0);
  1734. LogInfo("# ActiveFLUMode # successfully");
  1735. return true;
  1736. }
  1737. else
  1738. {
  1739. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVEFAILED, 0);
  1740. LogError("# ActiveFLUMode # failed");
  1741. return false;
  1742. }
  1743. }
  1744. // WPARAM 8: ZSKK_DETECTOR_PA_ACTIVE_CINEMODE 没有这个模式,用不到
  1745. bool PZMedical2121ZCtrl::ActiveCINEMode()
  1746. {
  1747. LogInfo("## ActiveCINEMode ##");
  1748. if (CAcqCtrl::ActiveCINEMode())return true;
  1749. if (!m_bFPDConnected)
  1750. {
  1751. LogError("No connect, return false");
  1752. return false;
  1753. }
  1754. if (m_eStatus == Acquire)
  1755. {
  1756. LogInfo("Acquiring image,return true");
  1757. return true;
  1758. }
  1759. return true; //2121Z没有这个模式
  1760. //::PostMessage(this->m_hWnd,MSG_ACQ_STATUS,ACQ_PREPARE,NULL);
  1761. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, 0);
  1762. LogInfo("------ActiveFLUMode Send message: ACQ_PREPARE---");
  1763. if (!ActiveDSTMode())
  1764. {
  1765. LogError("Set FPD in DST failed");
  1766. }
  1767. //check if the mode is active already
  1768. bool bActive = false;
  1769. CString strtemp;
  1770. strtemp.Format("CINE Mode: %d, Target offset Index, %d", m_CINEMode.nLogicMode, m_CINEMode.nOffIndex);
  1771. LogInfo(strtemp);
  1772. if (ActiveLogicMode(m_CINEMode.nLogicMode, m_CINEMode.nOffIndex))
  1773. {
  1774. bActive = true;
  1775. }
  1776. else
  1777. {
  1778. bActive = false;
  1779. }
  1780. if (bActive)
  1781. {
  1782. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVESUCCESS, 0);
  1783. LogInfo("Success, Current CINE mode active success");
  1784. return true;
  1785. }
  1786. else
  1787. {
  1788. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_MODEACTIVEFAILED, 0);
  1789. LogError("Failed, Current CINE mode active failed.");
  1790. return false;
  1791. }
  1792. }
  1793. //对于PZ2121Z探测器,调用SDK的 COM_HstAcq() 接口,激活HST模式
  1794. bool PZMedical2121ZCtrl::ActiveHSTMode()
  1795. {
  1796. BOOL nRet;
  1797. LogInfo("## ActiveHSTMode ##");
  1798. if (!m_bFPDConnected)
  1799. {
  1800. LogError("No connect, return false");
  1801. return false;
  1802. }
  1803. LogInfo("Set FPD in HST mode");
  1804. nRet = API_COM_HstAcq();
  1805. if (!TestError(nRet))
  1806. {
  1807. LogError("COM_hstAcq failed");
  1808. return false;
  1809. }
  1810. m_eSubStatus = SubStatus_HST;
  1811. return true;
  1812. }
  1813. //对于PZ2121Z探测器,调用SDK的 COM_Dst() 接口,激活DST模式
  1814. bool PZMedical2121ZCtrl::ActiveDSTMode()
  1815. {
  1816. BOOL nRet;
  1817. LogInfo("## ActiveDSTMode ##");
  1818. if (!m_bFPDConnected)
  1819. {
  1820. LogError("No connect, return false");
  1821. return false;
  1822. }
  1823. LogInfo("Set FPD in DST mode");
  1824. nRet = API_COM_Dst();
  1825. if (!TestError(nRet))
  1826. {
  1827. LogError("COM_Dst failed");
  1828. return false;
  1829. }
  1830. m_eSubStatus = SubStatus_DST;
  1831. return true;
  1832. }
  1833. bool PZMedical2121ZCtrl::SetSpotFrameRate(float fps)
  1834. {
  1835. LogInfo("## SetSpotFrameRate ##");
  1836. if (CAcqCtrl::SetSpotFrameRate(fps))return true;
  1837. return true;
  1838. }
  1839. bool PZMedical2121ZCtrl::SetFLUFrameRate(float fps)
  1840. {
  1841. LogInfo("## SetFLUFrameRate ##");
  1842. if (CAcqCtrl::SetFLUFrameRate(fps))return true;
  1843. return true;
  1844. }
  1845. bool PZMedical2121ZCtrl::SetCINEFrameRate(float fps)
  1846. {
  1847. LogInfo("## SetCINEFrameRate ##");
  1848. if (CAcqCtrl::SetCINEFrameRate(fps))return true;
  1849. return true;
  1850. }
  1851. bool PZMedical2121ZCtrl::GetActiveMode(int &nLogicMode, int &nOffsetIndex)
  1852. {
  1853. LogInfo(" ## GetActiveMode ## ");
  1854. nLogicMode = m_ActiveMode.nLogicMode;
  1855. nOffsetIndex = m_ActiveMode.nOffIndex;
  1856. return true;
  1857. }
  1858. bool PZMedical2121ZCtrl::GetOffsetInfo(int nLogicMode, vector <ZSKK_PROTOCOL_OFFSET_INFO> &vecOffsetInfo)
  1859. {
  1860. LogInfo(" ## GetOffsetInfo ## ");
  1861. if (CAcqCtrl::GetOffsetInfo(nLogicMode, vecOffsetInfo))return true;
  1862. return true;
  1863. }
  1864. // [xxxDlg.cpp]OnMSGWORKFLOW() -> [xxxCtrl.cpp]OnMSGWORKFLOW_Process(WPARAM, LPARAM)
  1865. // WRARAM 2: ZSKK_DETECTOR_WF_EXIT 退出
  1866. bool PZMedical2121ZCtrl::ExitDETECTOR()
  1867. {
  1868. if (CAcqCtrl::ExitDETECTOR()) return true;
  1869. //if (m_eStatus==Offset||m_eStatus==XrayCalibration)
  1870. //{
  1871. // AbortCalibration();
  1872. //}
  1873. if (m_eStatus == Acquire)
  1874. {
  1875. StopGrab(1);
  1876. }
  1877. if (!CloseDetector()) return false;
  1878. if (m_cImgBuff != NULL)
  1879. {
  1880. delete m_cImgBuff;
  1881. m_cImgBuff = NULL;
  1882. }
  1883. StopScanThread();
  1884. FreePZMedicalDLL();
  1885. LogInfo("================================Exit PZMedical system===========================\n\n\n");
  1886. return true;
  1887. }
  1888. // WRARAM 3: ZSKK_DETECTOR_WF_REINIT 暂时不支持
  1889. bool PZMedical2121ZCtrl::ResetConnection()
  1890. {
  1891. LogInfo("ResetConnection()");
  1892. if (CAcqCtrl::ResetConnection()) return true;
  1893. return true;
  1894. }
  1895. // WRARAM 7: ZSKK_DETECTOR_WF_BEGINWORK 进入检查状态
  1896. bool PZMedical2121ZCtrl::BeginWorkMode(void)
  1897. {
  1898. LogInfo("## BeginWorkMode ##");
  1899. if (CAcqCtrl::BeginWorkMode()) return true;
  1900. if (!m_bFPDConnected)
  1901. {
  1902. LogError("FPD no connected, return false");
  1903. return false;
  1904. }
  1905. m_bIsWorkingMode = true;
  1906. LogInfo("BeginWorkMode OVER");
  1907. return true;
  1908. }
  1909. // WRARAM 8: ZSKK_DETECTOR_WF_ENDWORK 退出检查状态
  1910. bool PZMedical2121ZCtrl::EndWorkMode(void)
  1911. {
  1912. LogInfo("## EndWorkMode ##");
  1913. if (CAcqCtrl::EndWorkMode()) return true;
  1914. if (!m_bFPDConnected)
  1915. {
  1916. LogError("FPD no connected, return false");
  1917. return false;
  1918. }
  1919. m_bIsWorkingMode = false;
  1920. m_ActiveMode.nLogicMode = -1;
  1921. m_ActiveMode.nOffIndex = -1;
  1922. if (!StopDetector()) return false;
  1923. LogInfo("EndWorkMode OVER");
  1924. return true;
  1925. }
  1926. // WRARAM 9: ZSKK_DETECTOR_WF_SETGRABMODE 设置采集模式
  1927. bool PZMedical2121ZCtrl::SetGrabMode(int nMode)
  1928. {
  1929. LogInfo("## SetGrabMode ##");
  1930. CString strLog = "";
  1931. if (!m_bFPDConnected)
  1932. {
  1933. LogError("No connect, return false");
  1934. return false;
  1935. }
  1936. m_nGrabMode = nMode;
  1937. switch (nMode)
  1938. {
  1939. case ZSKK_HARDWARE_SEQUENCE_SINGLERAD:
  1940. strLog = "single rad";
  1941. break;
  1942. case ZSKK_HARDWARE_SEQUENCE_SEQUENCERAD:
  1943. strLog = "sequence rad";
  1944. break;
  1945. case ZSKK_HARDWARE_SEQUENCE_PULSEFLU:
  1946. strLog = "pulse flu";
  1947. break;
  1948. case ZSKK_HARDWARE_SEQUENCE_CONTINOUSFLU:
  1949. strLog = "continous flu";
  1950. break;
  1951. default:
  1952. strLog.Format("unknown mode, %d", nMode);
  1953. break;
  1954. }
  1955. LogInfo("Set current grab mode: " + strLog);
  1956. LogInfo("SetGrabMode OVER");
  1957. return true;
  1958. }
  1959. // WRARAM 10: ZSKK_DETECTOR_WF_BEGINGRAB
  1960. // 同步模式:通过触发调用这个接口;连续透视模式:这个接口之后才将图像传给上层
  1961. bool PZMedical2121ZCtrl::StartGrab()
  1962. {
  1963. LogInfo("## StartGrab ##");
  1964. if (!m_bFPDConnected)
  1965. {
  1966. LogError("No connect, return false");
  1967. return false;
  1968. }
  1969. if (m_eStatus == Acquire)
  1970. {
  1971. LogWarn("Acquiring image, return true");
  1972. return true;
  1973. }
  1974. CString strLog = "";
  1975. m_nImgID = 1;
  1976. m_eStatus = Acquire;
  1977. if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SINGLERAD || m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SEQUENCERAD)
  1978. {
  1979. m_dwBeginT = GetTickCount();
  1980. strLog.Format("exposure at %d", m_dwBeginT);
  1981. LogInfo(strLog);
  1982. }
  1983. LogInfo("StartGrab OVER");
  1984. return true;
  1985. }
  1986. // WRARAM 11: ZSKK_DETECTOR_WF_ENDGRAB 结束采集
  1987. bool PZMedical2121ZCtrl::StopGrab(int nXRayOnNum)
  1988. {
  1989. LogInfo("## StopGrab ##");
  1990. if (!m_bFPDConnected)
  1991. {
  1992. LogError("No connect, return false");
  1993. return false;
  1994. }
  1995. CString strLog = "";
  1996. if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SINGLERAD)
  1997. return true;
  1998. else if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SEQUENCERAD)
  1999. {
  2000. m_nXrayOnNum = nXRayOnNum;
  2001. if (nXRayOnNum > m_nTotalFrameGrab)
  2002. {
  2003. //序列点片,有可能会在最后一张图到来之前,停止采集,如果这样,就等一个采集周期的时间;
  2004. int nTimeout = (nXRayOnNum - m_nTotalFrameGrab)*m_nWinTime;
  2005. strLog.Format("XrayOnNum(%d), FrameNum(%d), wait %d ms", nXRayOnNum, m_nTotalFrameGrab, nTimeout);
  2006. LogWarn(strLog);
  2007. m_bWaitLastImg = true; //将此标志位置为true,
  2008. if (!WaitRespond(nTimeout))
  2009. LogWarn("Can not get the images");
  2010. m_bWaitLastImg = false; //无论超时与否,结束后将标志位置为false
  2011. }
  2012. m_nImgID = 1;
  2013. m_eStatus = Standby;
  2014. m_bExiChecked = false; //结束采集后将标志位置回false
  2015. if (!StopAcquisition())
  2016. return false;
  2017. }
  2018. else
  2019. {
  2020. m_nImgID = 1;
  2021. m_eStatus = Standby;
  2022. m_bExiChecked = false; //结束采集后将标志位置回false
  2023. if (!StopAcquisition())
  2024. return false;
  2025. }
  2026. LogInfo("StopGrab OVER");
  2027. return true;
  2028. }
  2029. // 调用SDK接口,进入采集状态,nMode是RFModeConf.xml中的LogicMode
  2030. bool PZMedical2121ZCtrl::StartAcquisition(int nMode)
  2031. {
  2032. CString strLog = "";
  2033. m_nCurrentFrame = -1; //每次采集前将其恢复初值,使每个采集序列写共享内存时从0开始
  2034. m_bExiChecked = false; //采集前,将标志位置为false,认为EXI检查不通过
  2035. m_bTimeChecked = false; //采集前,将标志位置为false,任务时间检查不通过
  2036. BOOL nRet;
  2037. if (m_bTriggered) //设置参数前,需要确保处于stop状态
  2038. {
  2039. if (!StopAcquisition(1))
  2040. return false;
  2041. }
  2042. m_nImgID = 1;
  2043. APPMode objPZMode;
  2044. bool bGetMode = false;
  2045. for (int n = 0; n < PZModeConf.APPMode.m_nodes.size(); n++)
  2046. {
  2047. if (PZModeConf.APPMode.m_nodes[n].AppModeKey == nMode)
  2048. {
  2049. objPZMode = PZModeConf.APPMode.m_nodes[nMode];
  2050. bGetMode = true;
  2051. break;
  2052. }
  2053. }
  2054. if (!bGetMode)
  2055. {
  2056. strLog.Format("Not found the mode: %d", nMode);
  2057. LogError(strLog);
  2058. return false;
  2059. }
  2060. strLog.Format("Key(%d) Name(%s) Binning(%d) FrameRate(%d) DelayT1(%d) DelayT2(%d) DelayT3(%d) StartendLine(%d %d), StartendColumn(%d %d)",
  2061. objPZMode.AppModeKey, objPZMode.APPModeName, objPZMode.BinningMode, objPZMode.FrameRate, objPZMode.DelayT1, objPZMode.DelayT2,
  2062. objPZMode.DelayT3, objPZMode.StartLine, objPZMode.EndLine, objPZMode.StartColum, objPZMode.EndColum);
  2063. LogInfo(strLog);
  2064. if (objPZMode.APPModeName.Find("RAD") >= 0)
  2065. {
  2066. m_dwBeginT = 0;
  2067. m_dwEndT = 0;
  2068. m_nTotalFrameGrab = 0;
  2069. m_nXrayOnNum = 0;
  2070. m_bWaitLastImg = false;
  2071. #if 0
  2072. if (m_nRADSpeed == 0) //单帧点片和序列点片采用一套配置,只有上层传下来的m_nRADSpeed值不同,该值为0时为单帧点片
  2073. {
  2074. int nRepeatNum = 1;
  2075. if (!SetAcquisitionParam(objPZMode.FrameRate, nRepeatNum, objPZMode.BinningMode))
  2076. return false;
  2077. }
  2078. else //序列点片//
  2079. {
  2080. if (!SetAcquisitionParam(objPZMode.FrameRate, m_nRADSpeed, objPZMode.BinningMode))
  2081. return false;
  2082. }
  2083. #endif // 0
  2084. //if (!RefreshOffset()) return false;
  2085. //if (m_bOffsetDone == true)
  2086. {
  2087. LogInfo("Call Trigger");
  2088. nRet = API_COM_Trigger();
  2089. if (!TestError(nRet))
  2090. {
  2091. LogError("Trigger failed");
  2092. return false;
  2093. }
  2094. m_bTriggered = true;
  2095. }
  2096. }
  2097. else if (objPZMode.APPModeName.Find("PF") >= 0) //脉冲透视
  2098. {
  2099. /*//设置ROI
  2100. if (objPZMode.OpenROI != 0)
  2101. {
  2102. if (!SetROIMode(objPZMode.StartLine, objPZMode.EndLine, objPZMode.StartColum, objPZMode.EndColum))
  2103. return false;
  2104. }
  2105. */
  2106. int nRepeatNum = 0;
  2107. if (!SetAcquisitionParam(objPZMode.FrameRate, nRepeatNum, objPZMode.BinningMode))
  2108. {
  2109. return false;
  2110. }
  2111. if (!RefreshOffset()) return false;
  2112. if ((m_bOffsetDone == true) && (m_nTriggerMode == 0)) //内部触发方式
  2113. {
  2114. LogInfo("Using internal trigger");
  2115. nRet = API_COM_Dacq();
  2116. if (!TestError(nRet))
  2117. {
  2118. LogError("Internal Trigger failed");
  2119. return false;
  2120. }
  2121. }
  2122. else if ((m_bOffsetDone == true) && (m_nTriggerMode == 1)) //外部触发方式
  2123. {
  2124. LogInfo("Using external trigger");
  2125. nRet = API_COM_Cbct();
  2126. if (!TestError(nRet))
  2127. {
  2128. LogError("External Trigger failed");
  2129. return false;
  2130. }
  2131. }
  2132. else if ((m_bOffsetDone == true) && (m_nTriggerMode == 2)) //自动选择触发方式
  2133. {
  2134. LogInfo("Using external trigger");
  2135. nRet = API_COM_Cbct();
  2136. if (!TestError(nRet))
  2137. {
  2138. LogError("External Trigger failed");
  2139. return false;
  2140. }
  2141. }
  2142. else
  2143. {
  2144. LogError("Unknowned trigger mode, return false");
  2145. }
  2146. m_bTriggered = true;
  2147. }
  2148. else if (objPZMode.APPModeName.Find("CF") >= 0) //连续透视
  2149. {
  2150. int nRepeatNum = 0;
  2151. if (!SetAcquisitionParam(objPZMode.FrameRate, nRepeatNum, objPZMode.BinningMode))
  2152. return false;
  2153. if (!RefreshOffset()) return false;
  2154. if ((m_bOffsetDone == true) && (m_nTriggerMode == 0)) //内部触发方式
  2155. {
  2156. LogInfo("Using internal trigger");
  2157. nRet = API_COM_Dacq();
  2158. if (!TestError(nRet))
  2159. {
  2160. LogError("Internal Trigger failed");
  2161. return false;
  2162. }
  2163. }
  2164. else if ((m_bOffsetDone == true) && (m_nTriggerMode == 1)) //外部触发方式
  2165. {
  2166. LogInfo("Using external trigger");
  2167. nRet = API_COM_Cbct();
  2168. if (!TestError(nRet))
  2169. {
  2170. LogError("External Trigger failed");
  2171. return false;
  2172. }
  2173. }
  2174. else if ((m_bOffsetDone == true) && (m_nTriggerMode == 2)) //自动选择触发方式
  2175. {
  2176. LogInfo("Using internal trigger");
  2177. nRet = API_COM_Dacq();
  2178. if (!TestError(nRet))
  2179. {
  2180. LogError("Internal Trigger failed");
  2181. return false;
  2182. }
  2183. }
  2184. else
  2185. {
  2186. LogError("Unknowned trigger mode, return false");
  2187. }
  2188. m_bTriggered = true;
  2189. }
  2190. else
  2191. {
  2192. LogError("Unknowned mode");
  2193. return false;
  2194. }
  2195. return true;
  2196. }
  2197. /************************
  2198. * 结束采集,主要用于调用SDK的COM_Stop()接口或者COM_Dexit()接口。
  2199. * 厂商建议:探测器在IDLE状态下刷binning 1X1的offset,在设置binning2X2刷另一种offset
  2200. * 因为前者的耗时比较久,所以结束采集后要置为binning 1X1模式来刷这个模式下的offset
  2201. * nMode = 0, 设置回binning 1X1, XWinTime 500模式
  2202. ************************/
  2203. bool PZMedical2121ZCtrl::StopAcquisition(int nMode)
  2204. {
  2205. if (m_bTriggered)
  2206. {
  2207. LogInfo("Call Stop");
  2208. BOOL nRet = API_COM_Stop();
  2209. //BOOL nRet = API_COM_Dexit();
  2210. if (!TestError(nRet))
  2211. {
  2212. LogError("COM_Stop failed");
  2213. return false;
  2214. }
  2215. m_bTriggered = false;
  2216. }
  2217. m_eSubStatus = SubStatus_IDLE;
  2218. return true;
  2219. }
  2220. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2221. ////////////////////////////////////////////////////////// MSG Process //////////////////////////
  2222. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2223. bool PZMedical2121ZCtrl::OnCOPYDATA_MSG_Process(WPARAM wParam, LPARAM lParam)
  2224. {
  2225. COPYDATASTRUCT* tempCopyDataStruct;
  2226. switch (wParam)
  2227. {
  2228. case ZSKK_DETECTOR_PA_SETIMGPROC:
  2229. {
  2230. tempCopyDataStruct = (COPYDATASTRUCT*)lParam;
  2231. CString mode = (char*)(tempCopyDataStruct->lpData);
  2232. CString strlog;
  2233. strlog.Format("ApplyProcessChainMode: %s", mode);
  2234. LogInfo(strlog);
  2235. LogInfo("do not support now");
  2236. //ApplyProcessChainMode(mode);
  2237. break;
  2238. }
  2239. default:
  2240. break;
  2241. }
  2242. return true;
  2243. }
  2244. bool PZMedical2121ZCtrl::OnMSGWORKFLOW_Process(WPARAM wParam, LPARAM lParam)
  2245. {
  2246. switch (wParam)
  2247. {
  2248. case ZSKK_DETECTOR_WF_HANDLE:
  2249. break;
  2250. case ZSKK_DETECTOR_WF_INIT:
  2251. break;
  2252. case ZSKK_DETECTOR_WF_REINIT:
  2253. ResetConnection();
  2254. break;
  2255. case ZSKK_DETECTOR_WF_EXIT:
  2256. ExitDETECTOR();
  2257. break;
  2258. case ZSKK_DETECTOR_WF_TURNOFF:
  2259. break;
  2260. case ZSKK_DETECTOR_WF_QUERY_STATUS:
  2261. break;
  2262. case ZSKK_DETECTOR_WF_ALARM_CODE:
  2263. break;
  2264. case ZSKK_DETECTOR_WF_BEGINWORK:
  2265. LogInfo("MSG: Begin Work");
  2266. BeginWorkMode();
  2267. break;
  2268. case ZSKK_DETECTOR_WF_ENDWORK:
  2269. LogInfo("MSG: End Work");
  2270. EndWorkMode();
  2271. break;
  2272. case ZSKK_DETECTOR_WF_SETGRABMODE:
  2273. LogInfo("MSG: Set Grab Mode");
  2274. SetGrabMode((int)lParam);
  2275. break;
  2276. case ZSKK_DETECTOR_WF_BEGINGRAB:
  2277. LogInfo("MSG: Begin Grab Image");
  2278. StartGrab();
  2279. break;
  2280. case ZSKK_DETECTOR_WF_ENDGRAB:
  2281. LogInfo("MSG: End Grab Image");
  2282. StopGrab((int)lParam);
  2283. break;
  2284. case ZSKK_DETECTOR_WF_APPREADY:
  2285. break;
  2286. case ZSKK_DETECTOR_WF_RELOADCONFIG:
  2287. break;
  2288. case ZSKK_DETECTOR_WF_RELOADABS:
  2289. break;
  2290. default:
  2291. break;
  2292. }
  2293. return true;
  2294. }
  2295. bool PZMedical2121ZCtrl::OnMSGCALIBRATION_Process(WPARAM wParam, LPARAM lParam)
  2296. {
  2297. CString strLog = "";
  2298. strLog.Format("OnMsgCali wParam(%d) lParam(%d)", (int)wParam, (int)lParam);
  2299. //LogInfo(strLog); //调用频率高,日志过大
  2300. switch (wParam)
  2301. {
  2302. case ZSKK_DETECTOR_CALIBRATION_START_TYPE:
  2303. if ((m_ActiveMode.nLogicMode == -1) && (m_ActiveMode.nOffIndex == -1))
  2304. {
  2305. return false;
  2306. }
  2307. switch (lParam)
  2308. {
  2309. case ZSKK_DETECTOR_LPARAM_CALIBRATION_OFFSET_REQUEST:
  2310. BeginCalibration(m_ActiveMode.nLogicMode, m_ActiveMode.nOffIndex, 4);
  2311. break;
  2312. case ZSKK_DETECTOR_LPARAM_CALIBRATION_LINEARGAIN_REQUEST:
  2313. BeginCalibration(m_ActiveMode.nLogicMode, m_ActiveMode.nOffIndex, 2);
  2314. break;
  2315. case ZSKK_DETECTOR_LPARAM_CALIBRATION_POLYGAIN_REQUEST:
  2316. BeginCalibration(m_ActiveMode.nLogicMode, m_ActiveMode.nOffIndex, 8);
  2317. break;
  2318. case ZSKK_DETECTOR_LPARAM_CALIBRATION_DEFECT_REQUEST:
  2319. BeginCalibration(m_ActiveMode.nLogicMode, m_ActiveMode.nOffIndex, 1);
  2320. break;
  2321. case ZSKK_DETECTOR_LPARAM_CALIBRATION_BLINKING_REQUEST:
  2322. BeginCalibration(m_ActiveMode.nLogicMode, m_ActiveMode.nOffIndex, 16);
  2323. break;
  2324. default:
  2325. break;
  2326. }
  2327. break;
  2328. case ZSKK_DETECTOR_CALIBRATION_STOP:
  2329. ExitCalibration();
  2330. break;
  2331. case ZSKK_DETECTOR_CALIBRATION_ABORT:
  2332. AbortCalibration();
  2333. break;
  2334. case ZSKK_DETECTOR_CALIBRATION_REFRESH_OFFSET:
  2335. break;
  2336. case ZSKK_DETECTOR_CALIBRATION_SETDOSE:
  2337. break;
  2338. case ZSKK_DETECTOR_CALIBRATION_STARTXRAY:
  2339. break;
  2340. case ZSKK_DETECTOR_CALIBRATION_STOPXRAY:
  2341. break;
  2342. case ZSKK_DETECTOR_CALIBRATION_CALRESULT:
  2343. break;
  2344. case ZSKK_DETECTOR_CALIBRATION_CALMANUAL:
  2345. LogInfo("MSG: calibration manual");
  2346. OffsetByUser((int)lParam);
  2347. break;
  2348. case ZSKK_MSG_RFHW_CAL_OFFSETABORT:
  2349. break;
  2350. case ZSKK_DETECTOR_CALIBRATION_NEXTSTEP:
  2351. CalibNextStep();
  2352. break;
  2353. default:
  2354. break;
  2355. }
  2356. return true;
  2357. }
  2358. bool PZMedical2121ZCtrl::OnMSGPARAMETER_Process(WPARAM wParam, LPARAM lParam)
  2359. {
  2360. CString strLog;
  2361. switch (wParam)
  2362. {
  2363. case ZSKK_DETECTOR_PA_SET_RADMODE:
  2364. SelectRADMode((int)lParam / 10, (int)lParam % 10);
  2365. break;
  2366. case ZSKK_DETECTOR_PA_SET_FLUMODE:
  2367. SelectFLUMode((int)lParam / 10, (int)lParam % 10);
  2368. break;
  2369. case ZSKK_DETECTOR_PA_SET_CINEMODE:
  2370. SelectCINEMode((int)lParam / 10, (int)lParam % 10);
  2371. break;
  2372. case ZSKK_DETECTOR_PA_SET_RADSPEED:
  2373. strLog.Format("Get set rad speed message, receive rad speed: %d", int(lParam));
  2374. LogInfo(strLog);
  2375. m_nRADSpeed = (int)lParam / 100;
  2376. SetRadOffsetMode(m_RadMode.nLogicMode, m_RadMode.nOffIndex, m_nRADSpeed);
  2377. break;
  2378. case ZSKK_DETECTOR_PA_SET_FLUSPEED:
  2379. strLog.Format("Get set flu speed message, receive flu speed %d", int(lParam));
  2380. LogInfo(strLog);
  2381. m_nFLUSpeed = (int)lParam;
  2382. SetFluOffsetMode(m_FluMode.nLogicMode, m_FluMode.nOffIndex, int(lParam));
  2383. break;
  2384. case ZSKK_DETECTOR_PA_SET_FLUSPEED_EX:
  2385. m_nFLUSpeed = (int)lParam / 100;
  2386. strLog.Format("receive flu speedEx %d, %d", int(lParam), m_nFLUSpeed);
  2387. LogInfo(strLog);
  2388. SetFluOffsetMode(m_FluMode.nLogicMode, m_FluMode.nOffIndex, int(lParam));
  2389. break;
  2390. case ZSKK_DETECTOR_PA_SET_CINESPEED:
  2391. LogInfo("Get set cin speed message");
  2392. strLog.Format("receive cin speed %d", int(lParam));
  2393. LogInfo(strLog);
  2394. m_nCINSpeed = (int)lParam;
  2395. SetCinOffsetMode(m_FluMode.nLogicMode, m_FluMode.nOffIndex, int(lParam));
  2396. break;
  2397. case ZSKK_DETECTOR_PA_SET_CINESPEED_EX:
  2398. m_nCINSpeed = (int)lParam / 100;
  2399. strLog.Format("receive cin speedEx %d, %d", int(lParam), m_nCINSpeed);
  2400. LogInfo(strLog);
  2401. SetCinOffsetMode(m_nGrabMode, m_FluMode.nOffIndex, int(lParam));
  2402. break;
  2403. case ZSKK_DETECTOR_PA_ACTIVE_RADMODE:
  2404. ActiveRADMode();
  2405. break;
  2406. case ZSKK_DETECTOR_PA_ACTIVE_FLUMODE:
  2407. ActiveFLUMode();
  2408. break;
  2409. case ZSKK_DETECTOR_PA_ACTIVE_CINEMODE:
  2410. ActiveCINEMode();
  2411. break;
  2412. case ZSKK_DETECTOR_PA_SETGRABSTART:
  2413. if (ZSKK_DETECTOR_LPARAM_STARTTYPE_FLU == lParam)
  2414. {
  2415. MSGControl(NULL, ZSKK_MSG_RFHW_WFOUT, ZSKK_MSG_RFHW_WF_XRAYON, NULL, ZSKK_MSG_TYPE_SYNC_NO);
  2416. StartGrab();
  2417. }
  2418. else
  2419. StopGrab(100);
  2420. break;
  2421. default:
  2422. strLog.Format("Unknow parameter: %d", wParam);
  2423. LogWarn(strLog);
  2424. break;
  2425. }
  2426. return true;
  2427. }
  2428. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2429. ////////////////////////////////////////////////////////// Calibration //////////////////////////
  2430. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2431. bool PZMedical2121ZCtrl::EnterCalibration()
  2432. {
  2433. if (CAcqCtrl::EnterCalibration()) return true;
  2434. return true;
  2435. }
  2436. // [xxxDlg.cpp]OnMSGCALIBRATION() -> [xxxCtrl.cpp]OnMSGCALIBRATION_Process(WPARAM, LPARAM)
  2437. // WRARAM 0: ZSKK_DETECTOR_CALIBRATION_START_TYPE 设置校正类型
  2438. // CAL Mode: 1 defect, 2: Linear Gain, 4: Offset 8: Polynomial gain, 16: Blinking
  2439. // 2121Z进行offset校正(4)和gain校正(2)
  2440. bool PZMedical2121ZCtrl::BeginCalibration(int nLogicMode, int nOffsetIndex, int nCalMode)
  2441. {
  2442. CString strLog = "";
  2443. strLog.Format("## BeginCalibration ## nLogicMode(%d), nOffsetIndex(%d), nCalMode(%d)", nLogicMode, nOffsetIndex, nCalMode);
  2444. LogInfo(strLog);
  2445. if (CAcqCtrl::BeginCalibration(nLogicMode, nOffsetIndex, nCalMode)) return true;
  2446. if (!m_bFPDConnected)
  2447. {
  2448. LogError("No connect, return false");
  2449. return false;
  2450. }
  2451. m_nOffsetImgID = 1; //modify20210331 SDK逻辑是从1开始的
  2452. m_nGainImgID = 1; //modify20210331 SDK逻辑是从1开始的
  2453. m_bGetImage = false; //当发生器出线时才获取gain图像,所以先置为false
  2454. //在找剂量点的时候,会调用StopGrab,停止采集,这时候应该再开始采集
  2455. if (!m_bTriggered)
  2456. {
  2457. //调用SDK接口,进入采集状态
  2458. if (!StartAcquisition(m_ActiveMode.nLogicMode))
  2459. {
  2460. return false;
  2461. }
  2462. }
  2463. if (nCalMode == 4) //offset
  2464. {
  2465. if (m_eStatus == Offset)
  2466. {
  2467. LogInfo("At offset state, return true");
  2468. return true;
  2469. }
  2470. LogInfo("Start current offset calibration send message: START");
  2471. //MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALMANUAL, ZSKK_DETECTOR_LPARAM_CALMANUAL_START, ZSKK_MSG_TYPE_SYNC_NO);
  2472. //del20210331 此消息需要成对发送,没有发结束的地方,此处也就先不发开始了
  2473. StartOffsetCalibration(m_ActiveMode.nLogicMode);
  2474. ZSKK_CAL_STATUS CalStatus;
  2475. if (GetCalibrationStatus(nLogicMode, nOffsetIndex, CalStatus))
  2476. {
  2477. COPYDATASTRUCT copyData;
  2478. copyData.lpData = &CalStatus;
  2479. copyData.cbData = sizeof(ZSKK_CAL_STATUS);
  2480. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALIBRATIONSTATUS, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  2481. MSGControl(m_pWnd, ZSKK_MSG_RFDT_PARAMOUT, ZSKK_DETECTOR_PA_CURMODE_CALSTATUS, ZSKK_DETECTOR_LPARAM_CALSTATUS_REFRESH, 0);
  2482. }
  2483. }
  2484. else if (nCalMode == 2) //gain
  2485. {
  2486. if (m_eStatus == XrayCalibration)
  2487. {
  2488. LogInfo("At xray calibration, return true");
  2489. return true;
  2490. }
  2491. m_eStatus = XrayCalibration;
  2492. StartGainCalibration(nLogicMode, nOffsetIndex, nCalMode);
  2493. }
  2494. else
  2495. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALSUCCESS, ZSKK_MSG_TYPE_SYNC_NO);
  2496. return true;
  2497. }
  2498. // WRARAM 1: ZSKK_DETECTOR_CALIBRATION_STOP
  2499. bool PZMedical2121ZCtrl::ExitCalibration()
  2500. {
  2501. LogInfo(" ## ExitCalibration ## ");
  2502. if (CAcqCtrl::ExitCalibration())return true;
  2503. if (!m_bFPDConnected)
  2504. {
  2505. LogError("No connect, return false");
  2506. return false;
  2507. }
  2508. //还原active模式,重新加载模式
  2509. if (m_bCalStart)
  2510. {
  2511. LogInfo("Calibration already started.. Need reload all modes");
  2512. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, 0);
  2513. XMODE tmpMode;
  2514. tmpMode.nLogicMode = m_ActiveMode.nLogicMode;
  2515. tmpMode.nOffIndex = m_ActiveMode.nOffIndex;
  2516. //校正结束后模式被清空,需要重新装载模式
  2517. ActiveLogicMode(tmpMode.nLogicMode, tmpMode.nOffIndex);
  2518. }
  2519. if (m_bTriggered)
  2520. {
  2521. if (!StopAcquisition())
  2522. return false;
  2523. }
  2524. m_eStatus = Standby;
  2525. m_bCalStart = false;
  2526. m_bGetImage = false;
  2527. m_bExiChecked = false; //结束校正后,将标志位置回false
  2528. return true;
  2529. }
  2530. // WRARAM 2: ZSKK_DETECTOR_CALIBRATION_ABORT 终止校正
  2531. bool PZMedical2121ZCtrl::AbortCalibration()
  2532. {
  2533. LogInfo(" ## AbortCalibration ## ");
  2534. if (CAcqCtrl::AbortCalibration())return true;
  2535. if (!m_bFPDConnected)
  2536. {
  2537. LogError("No connect, return false");
  2538. return false;
  2539. }
  2540. if (m_bTriggered)
  2541. {
  2542. if (!StopAcquisition())
  2543. return false;
  2544. }
  2545. if (m_eStatus == Offset)
  2546. {
  2547. m_bAbortOffset = true;
  2548. }
  2549. OnXrayGenStop();
  2550. m_eStatus = Standby;
  2551. m_bCalStart = false;
  2552. m_bGetImage = false;
  2553. m_bExiChecked = false; //终止校正后,将标志位置回false
  2554. return true;
  2555. }
  2556. // WRARAM 8: ZSKK_DETECTOR_CALIBRATION_CALMANUAL 开始offset校正
  2557. // 4343D非work状态下自动刷offset,所以不做手动处理
  2558. bool PZMedical2121ZCtrl::OffsetByUser(int nOffsetType)
  2559. {
  2560. if (CAcqCtrl::OffsetByUser()) return true;
  2561. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALMANUAL, ZSKK_DETECTOR_LPARAM_CALMANUAL_START, ZSKK_MSG_TYPE_SYNC_NO);
  2562. Sleep(50);
  2563. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALMANUAL, ZSKK_DETECTOR_LPARAM_CALMANUAL_END, ZSKK_MSG_TYPE_SYNC_NO);
  2564. return true;
  2565. }
  2566. //刷新offset模板,调用 COM_Prep()接口后等待回调EVENT_OFFSETDONE到来, 表示模板刷新完成
  2567. bool PZMedical2121ZCtrl::RefreshOffset()
  2568. {
  2569. BOOL nRet;
  2570. bool bRet;
  2571. LogInfo("## RefreshOffset ##");
  2572. LogInfo("Call Prep");
  2573. nRet = API_COM_Prep();
  2574. if (!TestError(nRet))
  2575. {
  2576. LogError("COM_Prep failed");
  2577. return false;
  2578. }
  2579. bRet = WaitRespond(5000); //等待EVENT_OFFSETDONE回调5秒,否则视为超时
  2580. if (bRet)
  2581. {
  2582. LogInfo("RefreshOffset Done");
  2583. }
  2584. else
  2585. {
  2586. LogInfo("Waiting FPD Offset TimeOut");
  2587. return false;
  2588. }
  2589. return true;
  2590. }
  2591. // 开始offset,向上层发送消息
  2592. bool PZMedical2121ZCtrl::StartOffsetCalibration(int nMode)
  2593. {
  2594. LogInfo("## StartOffsetCalibration ##");
  2595. if (CAcqCtrl::StartOffsetCalibration()) return true;
  2596. CString strLog = "";
  2597. if (!m_bFPDConnected)
  2598. {
  2599. LogError("No connect, return false");
  2600. return false;
  2601. }
  2602. LogInfo("Start current offset calibration send message: ACQ_PREPARE");
  2603. MSGControl(m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_PREPARE, ZSKK_MSG_TYPE_SYNC_NO);
  2604. m_eStatus = Offset;
  2605. COPYDATASTRUCT copyData;
  2606. copyData.lpData = &m_CurSynParam;
  2607. copyData.cbData = sizeof(ZSKK_CAL_SYN_PARAM);
  2608. MSGControl(m_pWnd, ZSKK_MSG_RFDATA_OUT, ZSKK_DETECTOR_DATA_CALDETECTOR_FPSXWIN, (LPARAM)&copyData, ZSKK_MSG_TYPE_SYNC_YES);
  2609. strLog.Format("Mode(%d) is doing offset now frenquency %d fps xWindow %d ", nMode, m_CurSynParam.frenquency, m_CurSynParam.xWindow);
  2610. LogInfo(strLog);
  2611. return true;
  2612. }
  2613. // 开始gain校正,向上层发送消息
  2614. bool PZMedical2121ZCtrl::StartGainCalibration(int nLogicmode, int nRefNum, int CalMode)
  2615. {
  2616. LogInfo(" ## StartGainCalibration ## ");
  2617. CString strLog = "";
  2618. m_bExiChecked = false; //校正图像同样需要EXI检查,所以开始之前将标志位置为false
  2619. LogInfo("Calibration Set Dose");
  2620. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_SETDOSE, 30000, ZSKK_MSG_TYPE_SYNC_YES);
  2621. OnXrayGenStart();
  2622. return true;
  2623. }
  2624. // 一级手闸按下或发生器出线时调用,品臻动态探测器在出线时调用这个接口
  2625. // 在BeginCalibration中调用Trigger,在此接口中将取图标志位置m_bGetImage为true
  2626. bool PZMedical2121ZCtrl::CalibNextStep()
  2627. {
  2628. LogInfo("Begin get gain image");
  2629. m_bGetImage = true;
  2630. return true;
  2631. }
  2632. // 生成校正文件并上传
  2633. bool PZMedical2121ZCtrl::GenTpl()
  2634. {
  2635. LogInfo(" ## GenTpl ## ");
  2636. BOOL nRet, nRet2, nRet3;
  2637. CString strLog = "";
  2638. UCHAR ucTplName[20] = "gain_defect.tpl"; //上传时只上传这个校正文件
  2639. CString strTplPath = strAppPath + "\\reference\\gain_defect.tpl";
  2640. LogInfo(strTplPath);
  2641. CHAR* cTplPath = (CHAR*)strTplPath.GetBuffer();
  2642. LogInfo("->Tplgen");
  2643. nRet = API_COM_GenOffsetTpl();
  2644. nRet2 = API_COM_GenGainTpl();
  2645. nRet3 = API_COM_GenDefectTpl();
  2646. if (!TestError(nRet && nRet2 && nRet3))
  2647. {
  2648. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALFAILED, ZSKK_MSG_TYPE_SYNC_NO);
  2649. LogError("Tplgen failed");
  2650. return false;
  2651. }
  2652. //上传到探测器内部才能生效
  2653. m_ucState = -1;
  2654. m_ucPerCent = -1; //上传之前,将相关状态置为初始值
  2655. if (m_nBinningMode == PZ_ONExONE)
  2656. {
  2657. LogInfo("->Uploadtpl-1x1");
  2658. }
  2659. else if (m_nBinningMode == PZ_TWOxTWO)
  2660. {
  2661. LogInfo("->Uploadtpl-2x2");
  2662. }
  2663. else if (m_nBinningMode == PZ_THRxTHR)
  2664. {
  2665. LogInfo("->Uploadtpl-3x3");
  2666. }
  2667. else
  2668. {
  2669. strLog.Format("->Uploadtpl-%d", m_nBinningMode);
  2670. LogInfo(strLog);
  2671. }
  2672. nRet = API_COM_UploadFPZMTpl(m_nBinningMode + 1, cTplPath);
  2673. if (!TestError(nRet))
  2674. {
  2675. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALFAILED, ZSKK_MSG_TYPE_SYNC_NO);
  2676. LogError("Uploadtpl failed");
  2677. return false;
  2678. }
  2679. strTplPath.ReleaseBuffer();
  2680. return true;
  2681. }
  2682. // 加载RFModeConf.xml中的ROI配置,4343D用不到
  2683. void PZMedical2121ZCtrl::LoadROIParams()
  2684. {
  2685. DetectorMode tempDetectMode;
  2686. ROIMode tempROIMode;
  2687. int ntempROINum = 0;
  2688. int nsize = RFModeConf.DetectorMode.m_nodes.size();
  2689. int nPUMode = 0;
  2690. for (int i = 0; i < nsize; i++)
  2691. {
  2692. tempDetectMode = RFModeConf.DetectorMode.m_nodes[i];
  2693. ntempROINum = tempDetectMode.ROIMode.m_nodes.size();
  2694. nPUMode = tempDetectMode.PUMode;
  2695. for (int j = 0; j < ntempROINum; j++)
  2696. {
  2697. tempROIMode = tempDetectMode.ROIMode.m_nodes[j];
  2698. if (tempROIMode.Active == 1)
  2699. {
  2700. ZSKK_ROI_PARAM *pPram = new ZSKK_ROI_PARAM;
  2701. pPram->CenterColumnAdress = tempROIMode.CenterColumnAddress;
  2702. pPram->CenterRowAdress = tempROIMode.CenterRowAddress;
  2703. pPram->Height = tempROIMode.Height;
  2704. pPram->Width = tempROIMode.Width;
  2705. pPram->ROIIndex = tempROIMode.ROIIndex;
  2706. pPram->Shape = tempROIMode.Shape;
  2707. pPram->Active = true;
  2708. m_ROImap[nPUMode] = pPram;
  2709. }
  2710. }
  2711. }
  2712. }
  2713. // 裁剪图像,4343D用不到
  2714. int PZMedical2121ZCtrl::CropImageMargin(LPVOID pDstData, int& nDstWidth, int& nDstHeight,
  2715. LPVOID pScrData, int nSrcWidth, int nSrcHeight, int nBits,
  2716. int nLeftMargin, int nTopMargin, int nRightMargin, int nBottomMargin)
  2717. {
  2718. LogInfo("CropImageMargin()");
  2719. if (nLeftMargin == 0 && nTopMargin == 0 && nRightMargin == 0 && nBottomMargin == 0) return -1;
  2720. if ((pDstData == NULL) || (pScrData == NULL) || (nSrcWidth <= 0) || (nSrcHeight <= 0) || (nBits <= 0))
  2721. return -1;
  2722. if ((nLeftMargin >= nSrcWidth) || (nTopMargin >= nSrcHeight))
  2723. return -1;
  2724. int nBitsToBYTE = (int)((nBits + 7)*0.125);
  2725. if (nBitsToBYTE < 1)
  2726. return -1;
  2727. int nXL, nXR, nYL, nYR;
  2728. nXL = nLeftMargin;
  2729. nYL = nTopMargin;
  2730. if (nSrcWidth - nRightMargin < 0)
  2731. return -1;
  2732. nXR = nSrcWidth - nRightMargin - 1;
  2733. if (nXR < nXL)
  2734. return -1;
  2735. if (nSrcHeight - nBottomMargin < 0)
  2736. return -1;
  2737. nYR = nSrcHeight - nBottomMargin - 1;
  2738. if (nYR < nYL)
  2739. return -1;
  2740. nDstWidth = nXR - nXL + 1;
  2741. nDstHeight = nYR - nYL + 1;
  2742. int i;
  2743. #pragma omp parallel private(i)
  2744. {
  2745. #pragma omp for
  2746. for (i = nYL; i <= nYR; i++)
  2747. ::memcpy((WORD*)pDstData + (i - nYL) * nDstWidth, (WORD*)pScrData + (i * nSrcWidth + nXL), nDstWidth * nBitsToBYTE);
  2748. }
  2749. return 0;
  2750. }
  2751. // 获取图像并储存
  2752. void PZMedical2121ZCtrl::OnImageEvt(/*UINT32 uiImageNo, VOID* uiImgBuffAddr, UINT32 uiImgValidSize*/)
  2753. {
  2754. BOOL nRet;
  2755. CString strLog = "";
  2756. bool bPass = true; //图像是否符合标准
  2757. if (m_eStatus != Acquire && m_eStatus != Offset && m_eStatus != XrayCalibration)
  2758. {
  2759. LogWarn("Omit Image, error status");
  2760. return;
  2761. }
  2762. if (m_eStatus == Acquire) //曝光出图流程
  2763. {
  2764. LogInfo("Call GetImage");
  2765. nRet = API_COM_GetImage(m_cImgBuff);
  2766. if (!TestError(nRet))
  2767. {
  2768. LogError("GetImage failed");
  2769. return;
  2770. }
  2771. if (m_cImgBuff == NULL)
  2772. {
  2773. LogError("Image buffer is NULL");
  2774. return;
  2775. }
  2776. int res = CropImageMargin(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight,
  2777. m_cImgBuff, m_nRawWidth, m_nRawHeight, m_ImgInfo.nBits,
  2778. m_nCropLeft, m_nCropTop, m_nCropRight, m_nCropBottom);
  2779. if (res != 0)
  2780. {
  2781. memcpy(m_ImgInfo.pwData, m_cImgBuff, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2);
  2782. }
  2783. //memcpy(m_ImgInfo.pwData, m_cImgBuff, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2);
  2784. if (m_bSaveRaw)
  2785. SaveImage(m_ImgInfo.pwData, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2); //检查EXI、时间间隔之前把图存一下,便于用其它工具查看
  2786. m_nImgID++; //从SaveImage函数里改到外面自增,避免不存图导致这个变量不自增
  2787. //标准1,EXI检查。正常的曝光图像剂量会在100~150以上
  2788. if (!m_bExiChecked)
  2789. {
  2790. if (!CheckImageExi(m_nExiStdWork))
  2791. {
  2792. bPass = false;
  2793. }
  2794. else
  2795. m_bExiChecked = true; //检查通过,将标志位置为true
  2796. }
  2797. //if (m_ActiveMode.nLogicMode == PZ_MODE_RAD4343H || m_ActiveMode.nLogicMode == PZ_MODE_RAD4343M ) //modifybyys20190515 改为用m_nGrabMode来判断当前的模式
  2798. if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SINGLERAD || m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SEQUENCERAD)
  2799. {
  2800. //标准2,出线(StartGrab)到出图回调时间间隔检查。
  2801. //发生器出线到探测器返回图像基本上需要将近一个采图周期的时间,如果少于这个时间,则是出线前的图像
  2802. if (!m_bTimeChecked && m_bExiChecked)
  2803. {
  2804. m_dwEndT = GetTickCount();
  2805. if (m_dwEndT - m_dwBeginT < m_nDelayT)
  2806. {
  2807. strLog.Format("Omit Image, the time interval(%d) is too short: %d", m_dwEndT - m_dwBeginT, m_nDelayT);
  2808. LogWarn(strLog);
  2809. bPass = false;
  2810. }
  2811. else
  2812. m_bTimeChecked = true;
  2813. }
  2814. //应用饱和值处理,避免图像剂量过大,对后处理模块有影响
  2815. if (bPass)
  2816. ApplyImgSaturation(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight, m_nSaturation);
  2817. if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_SINGLERAD)
  2818. {
  2819. if (m_bSendRadImage)
  2820. {
  2821. LogWarn("Omit Image, already send to upper");
  2822. return;
  2823. }
  2824. if (bPass)
  2825. {
  2826. WriteFrame(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight);
  2827. MSGControl(m_pWnd, ZSKK_MSG_RFHW_WFOUT, ZSKK_MSG_RFHW_WF_DATAINFOSINGLE, m_nCurrentFrame, ZSKK_MSG_TYPE_SYNC_NO);
  2828. }
  2829. //已经得到符合标准的图像,或不合标准的图像超过了一定张数,就停止采集
  2830. if (bPass || m_nImgID > m_nRadImgCount)
  2831. {
  2832. m_bSendRadImage = true;
  2833. m_nImgID = 1;
  2834. m_eStatus = Standby;
  2835. if (!StopAcquisition())
  2836. return;
  2837. m_bExiChecked = false; //结束采集后将标志位置回false
  2838. }
  2839. }
  2840. else // 序列点片 //
  2841. {
  2842. if (bPass)
  2843. {
  2844. m_nTotalFrameGrab++;
  2845. WriteFrame(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight);
  2846. MSGControl(m_pWnd, ZSKK_MSG_RFHW_WFOUT, ZSKK_MSG_RFHW_WF_DATAINFOSEQUENCE, m_nCurrentFrame, ZSKK_MSG_TYPE_SYNC_NO);
  2847. //StopGrab的时候会等待最后一张图像,图像拿齐了,setEvent停止等待,避免时间过长
  2848. if (m_bWaitLastImg && m_nTotalFrameGrab == m_nXrayOnNum)
  2849. SetEvent(m_hCallbackEvent);
  2850. }
  2851. }
  2852. }
  2853. else if (m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_PULSEFLU || m_nGrabMode == ZSKK_HARDWARE_SEQUENCE_CONTINOUSFLU)
  2854. {
  2855. if (bPass)
  2856. {
  2857. WriteFrame(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight);
  2858. MSGControl(m_pWnd, ZSKK_MSG_RFHW_WFOUT, ZSKK_MSG_RFHW_WF_DATAINFOFLU, m_nCurrentFrame, ZSKK_MSG_TYPE_SYNC_NO);
  2859. }
  2860. }
  2861. else
  2862. {
  2863. strLog.Format("Omit Image, error work mode: %d", m_ActiveMode.nLogicMode);
  2864. LogWarn(strLog);
  2865. return;
  2866. }
  2867. }
  2868. else if (m_eStatus == Offset) //暗场校正出图流程
  2869. {
  2870. LogInfo("GetImage at offset state");
  2871. nRet = API_COM_GetImage(m_cImgBuff);
  2872. if (!TestError(nRet))
  2873. {
  2874. LogError("GetImage failed");
  2875. return;
  2876. }
  2877. if (m_cImgBuff == NULL)
  2878. {
  2879. LogError("Image buffer is NULL");
  2880. return;
  2881. }
  2882. memcpy(m_ImgInfo.pwData, m_cImgBuff, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2);
  2883. strLog.Format("dark\\%d", m_nOffsetImgID); //modify20210331 探测器工具校正时命名不带flood,此处也不带此关键字,这样校正时可以直接覆盖上一次的图像
  2884. if (SaveImage(strLog, m_ImgInfo.pwData, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2))
  2885. m_nOffsetImgID++;
  2886. else
  2887. {
  2888. m_nImgID = 1;
  2889. m_eStatus = Standby;
  2890. if (!StopAcquisition())
  2891. return;
  2892. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALFAILED, ZSKK_MSG_TYPE_SYNC_NO);
  2893. return;
  2894. }
  2895. if (m_nOffsetImgID == PZ_OFFSET_COUNT + 1)
  2896. {
  2897. m_nImgID = 1;
  2898. m_eStatus = Standby;
  2899. //MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALSUCCESS, ZSKK_MSG_TYPE_SYNC_NO);
  2900. OnXrayCalSuccess();
  2901. }
  2902. }
  2903. else if (m_eStatus == XrayCalibration) //增益校正出图流程
  2904. {
  2905. // 要根据标志位m_bGetImage来决定是否取gain图像
  2906. if (!m_bGetImage)
  2907. {
  2908. LogWarn("Omit Gain Image, error status");
  2909. return;
  2910. }
  2911. LogInfo("->GetImage at gain state");
  2912. nRet = API_COM_GetImage(m_cImgBuff);
  2913. if (!TestError(nRet))
  2914. {
  2915. LogError("GetImage failed");
  2916. return;
  2917. }
  2918. if (m_cImgBuff == NULL)
  2919. {
  2920. LogError("Image buffer is NULL");
  2921. return;
  2922. }
  2923. memcpy(m_ImgInfo.pwData, m_cImgBuff, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2);
  2924. if (!m_bExiChecked) //如果EXI检查没通过,就进行EXI检查
  2925. {
  2926. if (!CheckImageExi(m_nExiStdCali))
  2927. return;
  2928. m_bExiChecked = true; //检查通过,将标志位置为true
  2929. }
  2930. strLog.Format("flood\\%d", m_nGainImgID); //modify20210331 探测器工具校正时命名不带flood,此处也不带此关键字,这样校正时可以直接覆盖上一次的图像
  2931. if (SaveImage(strLog, m_ImgInfo.pwData, m_ImgInfo.nWidth*m_ImgInfo.nHeight * 2))
  2932. m_nGainImgID++;
  2933. else
  2934. {
  2935. m_nImgID = 1;
  2936. m_eStatus = Standby;
  2937. if (!StopAcquisition())
  2938. return;
  2939. MSGControl(m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALFAILED, ZSKK_MSG_TYPE_SYNC_NO);
  2940. return;//shibai
  2941. }
  2942. if (m_nGainImgID == PZ_GAIN_COUNT + 1)
  2943. {
  2944. m_nImgID = 1;
  2945. m_eStatus = Standby;
  2946. if (!StopAcquisition(1)) //只停止采集,不修改binning mode,避免上传到错误的校正文件路径
  2947. return;
  2948. OnXrayGenStop();
  2949. SetEvent(m_hGenTplEvent);
  2950. }
  2951. }
  2952. else
  2953. {
  2954. strLog.Format("Omit Image, error status: %d", m_eStatus);
  2955. LogError(strLog);
  2956. return;
  2957. }
  2958. }
  2959. // 调用WriteShareMemEx()向共享内存中写入图像
  2960. bool PZMedical2121ZCtrl::WriteFrame(WORD* pImgData, int nWidth, int nHeight)
  2961. {
  2962. if (pImgData == NULL)
  2963. {
  2964. LogError("ImgData is NULL");
  2965. return false;
  2966. }
  2967. if ((nWidth <= 0) || (nHeight <= 0))
  2968. {
  2969. LogError("Width or Height error");
  2970. return false;
  2971. }
  2972. DWORD nTotalMem = m_pDataBuffer->GetShareMemSize();
  2973. int ntotal = nTotalMem / (nWidth*nHeight*sizeof(WORD));
  2974. if (ntotal == 0)
  2975. {
  2976. LogError("GetShareMemSize failed, shared memory size is 0");
  2977. return false;
  2978. }
  2979. m_nCurrentFrame = (m_nCurrentFrame + 1) % ntotal;
  2980. m_pDataBuffer->WriteShareMemEx(m_nCurrentFrame*nWidth*nHeight*sizeof(WORD), (LPVOID)pImgData, nWidth*nHeight*sizeof(WORD));
  2981. if (g_bTestTrue) //如果g_bTestTrue=true, 那么测试保存图片
  2982. {
  2983. LogInfo("Test Saving Image");
  2984. g_TestSavingImage->Write(pImgData, nWidth*nHeight*sizeof(WORD));
  2985. g_TestSavingImage->Close();
  2986. }
  2987. return true;
  2988. }
  2989. bool PZMedical2121ZCtrl::LogInfo(LPCSTR strLog)
  2990. {
  2991. if (logfile == NULL)
  2992. {
  2993. return false;
  2994. }
  2995. else
  2996. {
  2997. logfile->WriteLog(strLog, LOG_INFORMATION, LOG_RELEASE, true);
  2998. return true;
  2999. }
  3000. }
  3001. bool PZMedical2121ZCtrl::LogError(LPCSTR strLog)
  3002. {
  3003. if (logfile == NULL)
  3004. {
  3005. return false;
  3006. }
  3007. else
  3008. {
  3009. logfile->WriteLog(strLog, LOG_ERROR, LOG_RELEASE, true);
  3010. return true;
  3011. }
  3012. }
  3013. bool PZMedical2121ZCtrl::LogWarn(LPCSTR strLog)
  3014. {
  3015. if (logfile == NULL)
  3016. {
  3017. return false;
  3018. }
  3019. else
  3020. {
  3021. logfile->WriteLog(strLog, LOG_WARNING, LOG_RELEASE, true);
  3022. return true;
  3023. }
  3024. }
  3025. // 辅助线程
  3026. UINT PZMedical2121ZCtrl::ScanThread(LPVOID pParam)
  3027. {
  3028. PZMedical2121ZCtrl* pMain = (PZMedical2121ZCtrl*)pParam;
  3029. if (pMain == NULL)
  3030. {
  3031. return false;
  3032. }
  3033. CString strLog = "";
  3034. BOOL bExit = false;
  3035. DWORD dwTimeOut = 5000;
  3036. pMain->LogInfo("ScanThread...");
  3037. while (!bExit)
  3038. {
  3039. DWORD dwResult = WaitForMultipleObjects(PZ_EVENT_COUNT, pMain->m_hEventArray, FALSE, INFINITE);
  3040. switch (dwResult)
  3041. {
  3042. case WAIT_OBJECT_0: //m_hInitEvent
  3043. {
  3044. pMain->LogInfo("Get Init Event");
  3045. if (!pMain->InitHW(pMain->m_hWnd))
  3046. {
  3047. pMain->MSGControl(pMain->m_pWnd, ZSKK_MSG_RFDT_WFOUT, ZSKK_DETECTOR_WF_QUERY_STATUS, ZSKK_DETECTOR_LPARAM_STATUS_UNCONNECTED, 0);
  3048. }
  3049. }
  3050. break;
  3051. case WAIT_OBJECT_0 + 1: //m_hExitEvent
  3052. {
  3053. pMain->LogInfo("Get Exit Event");
  3054. bExit = true;
  3055. }
  3056. break;
  3057. case WAIT_OBJECT_0 + 2: //m_hGenTplEvent
  3058. {
  3059. pMain->LogInfo("Get GenTpl Event");
  3060. pMain->GenTpl();
  3061. }
  3062. break;
  3063. case WAIT_OBJECT_0 + 3: //m_hImgEvent
  3064. {
  3065. pMain->OnImageEvt();
  3066. }
  3067. break;
  3068. default:
  3069. {
  3070. DWORD nErrorCode;
  3071. nErrorCode = GetLastError();
  3072. strLog.Format("Unknown scan event! result: %d, error code: %d", dwResult, nErrorCode);
  3073. pMain->LogError(strLog);
  3074. bExit = true;
  3075. }
  3076. break;
  3077. }
  3078. }
  3079. SetEvent(pMain->m_hScanThreadEnd);
  3080. pMain->LogInfo("ScanThread End");
  3081. return 0;
  3082. }
  3083. // 开启辅助线程
  3084. bool PZMedical2121ZCtrl::StartScanThread()
  3085. {
  3086. LogInfo("## StartScanThread ##");
  3087. if (m_hInitEvent)
  3088. {
  3089. CloseHandle(m_hInitEvent);
  3090. m_hInitEvent = NULL;
  3091. }
  3092. m_hInitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3093. if (m_hExitEvent)
  3094. {
  3095. CloseHandle(m_hExitEvent);
  3096. m_hExitEvent = NULL;
  3097. }
  3098. m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3099. if (m_hScanThreadEnd)
  3100. {
  3101. CloseHandle(m_hScanThreadEnd);
  3102. m_hScanThreadEnd = NULL;
  3103. }
  3104. m_hScanThreadEnd = CreateEvent(NULL, FALSE, FALSE, NULL);
  3105. if (m_hGenTplEvent)
  3106. {
  3107. CloseHandle(m_hGenTplEvent);
  3108. m_hGenTplEvent = NULL;
  3109. }
  3110. m_hGenTplEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3111. if (m_hImgEvent)
  3112. {
  3113. CloseHandle(m_hImgEvent);
  3114. m_hImgEvent = NULL;
  3115. }
  3116. m_hImgEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3117. m_hEventArray[0] = m_hInitEvent;
  3118. m_hEventArray[1] = m_hExitEvent;
  3119. m_hEventArray[2] = m_hGenTplEvent;
  3120. m_hEventArray[3] = m_hImgEvent;
  3121. if (m_hCallbackEvent)
  3122. {
  3123. CloseHandle(m_hCallbackEvent);
  3124. m_hCallbackEvent = NULL;
  3125. }
  3126. m_hCallbackEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  3127. if (m_pScanThreadProc == NULL)
  3128. m_pScanThreadProc = ::AfxBeginThread(ScanThread, this);
  3129. if (NULL == m_pScanThreadProc)
  3130. {
  3131. LogError("Start scan thread failed");
  3132. return false;
  3133. }
  3134. LogInfo("StartScanThread OVER");
  3135. return true;
  3136. }
  3137. bool PZMedical2121ZCtrl::StopScanThread()
  3138. {
  3139. LogInfo("## StopScanThread ##");
  3140. SetEvent(m_hExitEvent);
  3141. DWORD dwRet = WaitForSingleObject(m_hScanThreadEnd, 60000); //upload 1x1校正文件会比较耗时
  3142. if (dwRet == WAIT_OBJECT_0)
  3143. LogInfo("Stop scan thread over");
  3144. else if (dwRet == WAIT_TIMEOUT)
  3145. {
  3146. TerminateThread(m_pScanThreadProc, 0);
  3147. LogInfo("Terminate scan thread");
  3148. }
  3149. else
  3150. {
  3151. CString strLog = "";
  3152. strLog.Format("Unknow event: %u", dwRet);
  3153. LogWarn(strLog);
  3154. }
  3155. if (m_hInitEvent)
  3156. {
  3157. CloseHandle(m_hInitEvent);
  3158. m_hInitEvent = NULL;
  3159. }
  3160. if (m_hExitEvent)
  3161. {
  3162. CloseHandle(m_hExitEvent);
  3163. m_hExitEvent = NULL;
  3164. }
  3165. if (m_hGenTplEvent)
  3166. {
  3167. CloseHandle(m_hGenTplEvent);
  3168. m_hGenTplEvent = NULL;
  3169. }
  3170. if (m_hImgEvent)
  3171. {
  3172. CloseHandle(m_hImgEvent);
  3173. m_hImgEvent = NULL;
  3174. }
  3175. if (m_hCallbackEvent)
  3176. {
  3177. CloseHandle(m_hCallbackEvent);
  3178. m_hCallbackEvent = NULL;
  3179. }
  3180. if (m_hScanThreadEnd)
  3181. {
  3182. CloseHandle(m_hScanThreadEnd);
  3183. m_hScanThreadEnd = NULL;
  3184. }
  3185. LogInfo("StopScanThread OVER");
  3186. return true;
  3187. }
  3188. /*
  3189. // 4343D图像上传回调
  3190. BOOL __stdcall PZMedical2121ZCtrl::FuncMFpDataUploadProcessCallback(UCHAR ucFileType, UCHAR ucState, UCHAR ucPerCent)
  3191. {
  3192. CString strLog = "";
  3193. if (g_pPZMedicalInstance->m_ucState == ucState && ucState != STATE_DATA) //每毫秒都有多次相同状体的回调,所以在这做一下拦截,避免日志文件太大
  3194. return 1;
  3195. g_pPZMedicalInstance->m_ucState = ucState;
  3196. if (ucState == STATE_ERASE)
  3197. {
  3198. g_pPZMedicalInstance->LogInfo("[DataUploadProcessCallback] State: ERASE");
  3199. }
  3200. else if (ucState == STATE_DATA)
  3201. {
  3202. if (g_pPZMedicalInstance->m_ucPerCent == ucPerCent) //STATE_DATA状态下,相同百分比只记录一次,避免日志太大
  3203. return 1;
  3204. g_pPZMedicalInstance->m_ucPerCent = ucPerCent;
  3205. strLog.Format("[DataUploadProcessCallback] DATA PerCent(%d)", ucPerCent);
  3206. g_pPZMedicalInstance->LogInfo(strLog);
  3207. }
  3208. else if (ucState == STATE_DONE)
  3209. {
  3210. g_pPZMedicalInstance->LogInfo("[DataUploadProcessCallback] State: UPLOAD DONE");
  3211. g_pPZMedicalInstance->StopAcquisition(); //再次停止,切回binning1x1
  3212. //g_pPZMedicalInstance->MSGControl(g_pPZMedicalInstance->m_pWnd, ZSKK_MSG_RFDT_CALOUT, ZSKK_DETECTOR_CALIBRATION_CALRESULT, ZSKK_DETECTOR_LPARAM_CALIBRATION_CALSUCCESS, ZSKK_MSG_TYPE_SYNC_NO);
  3213. g_pPZMedicalInstance->OnXrayCalSuccess();
  3214. }
  3215. else
  3216. {
  3217. strLog.Format("[DataUploadProcessCallback] Unknown State(%d)", ucState);
  3218. g_pPZMedicalInstance->LogWarn(strLog);
  3219. }
  3220. return 1;
  3221. }
  3222. */
  3223. // 用于辅助线程中,等待SDK回调时的延时操作
  3224. // 等到回调,返回true; 等不到回调返回false,即为超时
  3225. bool PZMedical2121ZCtrl::WaitRespond(int nTimeOut)
  3226. {
  3227. CString strLog;
  3228. strLog.Format("-----WaitRespond: %d ms-----", nTimeOut);
  3229. LogInfo(strLog);
  3230. DWORD dwRet = WaitForSingleObject(g_pPZMedicalInstance->m_hCallbackEvent, nTimeOut);
  3231. if (dwRet == WAIT_TIMEOUT)
  3232. {
  3233. LogWarn("Time out in wait respond");
  3234. ResetEvent(m_hCallbackEvent);
  3235. return false;
  3236. }
  3237. else if (dwRet == WAIT_FAILED)
  3238. {
  3239. DWORD dwSignal = GetLastError();
  3240. strLog.Format("Failed: %x", dwSignal);
  3241. LogError(strLog);
  3242. return false;
  3243. }
  3244. else if (dwRet == WAIT_OBJECT_0)
  3245. {
  3246. LogInfo("-----WaitRespond got Signal-----");
  3247. }
  3248. else
  3249. {
  3250. strLog.Format("Unknow Signal: %d", dwRet);
  3251. LogWarn(strLog);
  3252. }
  3253. return true;
  3254. }
  3255. // 存储曝光过程图像,用于查看图像质量
  3256. bool PZMedical2121ZCtrl::SaveImage(WORD* pImage, int nImgSize)
  3257. {
  3258. if (m_nImgID == IMG_COUNT + 1)
  3259. m_nImgID = 1;
  3260. CString strTemp;
  3261. strTemp.Format("%s\\rawdata\\Image_%d.raw", strAppPath, m_nImgID);
  3262. CFile fileImage;
  3263. if (!fileImage.Open(strTemp.GetBuffer(), CFile::modeCreate | CFile::modeWrite))
  3264. {
  3265. LogInfo("Save image failed");
  3266. return false;
  3267. }
  3268. else
  3269. {
  3270. fileImage.Write(pImage, nImgSize);
  3271. LogInfo(strTemp);
  3272. //m_nImgID++; //如果不存图,这个变量将不自增。而这个变量的用途又不止存图时的id,所以不在此处自增了
  3273. }
  3274. fileImage.Close();
  3275. strTemp.ReleaseBuffer();
  3276. return true;
  3277. }
  3278. // 存储校正过程图像,用于生成校正文件
  3279. bool PZMedical2121ZCtrl::SaveImage(const char* szFileName, WORD* pImage, int nImgSize)
  3280. {
  3281. CString strTemp = "";
  3282. strTemp.Format("%s\\reference\\%s.raw", strAppPath, szFileName);
  3283. CFile fileImage;
  3284. if (!fileImage.Open(strTemp.GetBuffer(), CFile::modeCreate | CFile::modeWrite))
  3285. {
  3286. LogInfo("Save image failed");
  3287. return false;
  3288. }
  3289. else
  3290. {
  3291. fileImage.Write(pImage, nImgSize);
  3292. LogInfo(strTemp);
  3293. }
  3294. fileImage.Close();
  3295. strTemp.ReleaseBuffer();
  3296. return true;
  3297. }
  3298. // 检查图像的EXI值
  3299. bool PZMedical2121ZCtrl::CheckImageExi(WORD dwExiThrethold)
  3300. {
  3301. LogInfo(" ## Check EXI ## ");
  3302. //bool bResult = CalculateEXI(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight, 16, dwExiThrethold);
  3303. //if (bResult)
  3304. int nRet = AEDCalcu(m_ImgInfo.pwData, m_ImgInfo.nWidth, m_ImgInfo.nHeight, 16, dwExiThrethold, 0.05f);
  3305. if (nRet == 0)
  3306. {
  3307. return true;
  3308. }
  3309. LogWarn("Omit Image, Not meet the EXI requirements!!");
  3310. return false;
  3311. }
  3312. // 计算图像EXI值,目前用不到了,替换为AEDCalcu
  3313. bool PZMedical2121ZCtrl::CalculateEXI(WORD* pImgData, int nImgWidth, int nImgHeight, int nImageBit, int nThreshold)
  3314. {
  3315. int nROIXL = static_cast<int>(0.3 * nImgWidth);
  3316. int nROIXR = static_cast<int>(0.7 * nImgWidth);
  3317. int nROIYL = static_cast<int>(0.3 * nImgHeight);
  3318. int nROIYR = static_cast<int>(0.7 * nImgHeight);
  3319. WORD* pSrc = NULL;
  3320. long nCount = 0;
  3321. DWORD64 nSum = 0;
  3322. int nEXI = 0;
  3323. CString strLog = "";
  3324. try
  3325. {
  3326. for (int i = nROIYL; i < nROIYR; i++)
  3327. {
  3328. pSrc = pImgData + nImgWidth;
  3329. for (int j = nROIXL; j < nROIXR; j++)
  3330. {
  3331. nSum += *(pSrc + j);
  3332. nCount++;
  3333. }
  3334. }
  3335. nEXI = (int)(nSum / nCount);
  3336. }
  3337. catch (...)
  3338. {
  3339. return false;
  3340. }
  3341. strLog.Format("Image EXI Mean: %d, Threshold: %d", nEXI, nThreshold);
  3342. LogInfo(strLog);
  3343. if (nEXI >= nThreshold)
  3344. {
  3345. LogInfo("Exi Check Xray On the Image");
  3346. return true;//有x射线
  3347. }
  3348. return false;
  3349. }
  3350. int PZMedical2121ZCtrl::AEDCalcu(WORD* pImage, int nWidth, int nHeight, int nImageBit, int nThreshold, float fArea)
  3351. {
  3352. CString str;
  3353. //str.Format("Width(%d),hight(%d),bit(%d),threshold(%d),area(%0.2f)", nWidth, nHeight, nImageBit, nThreshold, fArea);
  3354. //LogInfo(str); //日志太多了
  3355. if (!pImage)
  3356. {
  3357. LogError("Buffer is null");
  3358. return 2;//图像读入失败。
  3359. }
  3360. int N = 65536;
  3361. int *Histogram = NULL;
  3362. Histogram = new int[N];
  3363. if (Histogram == NULL)
  3364. {
  3365. LogError("Alloc buffer failed");
  3366. return 4;//内存分配失败。
  3367. }
  3368. memset(Histogram, 0, sizeof(int)* N);
  3369. unsigned long int nCount = 0;
  3370. unsigned long int temp = 0;
  3371. int nIdxI = 0;
  3372. int nIdxJ = 0;
  3373. for (nIdxJ = 30; nIdxJ < nHeight - 30; nIdxJ = nIdxJ + 4)
  3374. {
  3375. for (nIdxI = 30; nIdxI < nWidth - 30; nIdxI = nIdxI + 4)
  3376. {
  3377. //temp=int(( pImage[ nIdxI * nWidth + nIdxJ ]+pImage[ nIdxI * nWidth + nIdxJ + 1]
  3378. //+pImage[ nIdxI * nWidth + nIdxJ + 2]+pImage[ nIdxI * nWidth + nIdxJ + 3])/4);
  3379. // or Algorithm N.2
  3380. temp = int(pImage[nIdxJ * nWidth + nIdxI]);
  3381. Histogram[temp]++;
  3382. nCount++;
  3383. }
  3384. }
  3385. float fCoe = 0.01f;
  3386. int nCoeCount = int(fCoe * nCount);
  3387. int nAreaCount = int((1 - fCoe) * nCount * fArea);
  3388. unsigned long int nIdx = 0;
  3389. unsigned long int nSum = 0;
  3390. for (nIdx = N - 1; nIdx >= 0; nIdx--)
  3391. {
  3392. nSum += Histogram[nIdx];
  3393. if (nSum >= nCoeCount)
  3394. break;
  3395. }
  3396. unsigned long int fMean = 0;
  3397. unsigned long int nflag = 0;
  3398. for (int i = nIdx; i >= 0; i--)
  3399. {
  3400. if (Histogram[nIdx] == 0)
  3401. {
  3402. continue;
  3403. }
  3404. fMean += nIdx*Histogram[nIdx];
  3405. nflag += Histogram[nIdx];
  3406. if (nflag >= nAreaCount)
  3407. {
  3408. break;
  3409. }
  3410. }
  3411. if (Histogram)
  3412. {
  3413. delete Histogram;
  3414. Histogram = NULL;
  3415. }
  3416. if (nflag == 0)
  3417. {
  3418. LogInfo("Not have Xray image");
  3419. return 1;//无x射线
  3420. }
  3421. fMean = unsigned long int(fMean / nflag);
  3422. str.Format("Mean count(%d)", fMean);
  3423. LogInfo(str);
  3424. if (fMean >= nThreshold)
  3425. {
  3426. //LogInfo("Xray image");
  3427. return 0;
  3428. }
  3429. else
  3430. {
  3431. //LogInfo("Not have Xray image");
  3432. return 1;
  3433. }
  3434. }
  3435. /*************************
  3436. * 设置探测器的采图周期以及一次trigger的采图张图
  3437. * 只有初始化的时候需要获取一次参数信息,确保是符合binning1X1模式的采集周期
  3438. * nFrameRate:帧频; nRepeatNum:采集张数,默认为0,表示持续上图; cBinningMode:设置Binning模式
  3439. //***********************/
  3440. bool PZMedical2121ZCtrl::SetAcquisitionParam(int nFrameRate, int nRepeatNum, char cBinningMode)
  3441. {
  3442. CString strLog;
  3443. BOOL nRet;
  3444. UINT32 nXwinTime = 0;
  3445. UINT32 nDelayTime = 0;
  3446. LogInfo("## SetAcquisitionParam ##");
  3447. //参数检查
  3448. if (nFrameRate < 0)
  3449. {
  3450. strLog.Format("nFrameRate(%d) is not reasonable", nFrameRate);
  3451. LogError(strLog);
  3452. return false;
  3453. }
  3454. nXwinTime = m_vecCycleTime.at(nFrameRate);
  3455. nDelayTime = m_vecDelayTime.at(nFrameRate);
  3456. strLog.Format("FrameRate: %d, RepeatNum: %d, BinningMode: %d, XwinTime: %d, DelayTime: %d", nFrameRate, nRepeatNum, cBinningMode, nXwinTime, nDelayTime);
  3457. LogInfo(strLog);
  3458. LogInfo("Call SetDynamicPara");
  3459. nRet = API_COM_SetDynamicPara(nXwinTime, (UINT16)nRepeatNum, cBinningMode);
  3460. if (!TestError(nRet))
  3461. {
  3462. LogError("SetDynamicPara failed");
  3463. return false;
  3464. }
  3465. m_nWinTime = nXwinTime;
  3466. m_nDelayT = nDelayTime;
  3467. LogInfo("SetAcquisitionParam OVER");
  3468. return true;
  3469. }
  3470. /******************************
  3471. * nMode,要设置的binning模式
  3472. * 进行了判重处理,避免重复调用参数相同的SDK接口
  3473. //****************************/
  3474. bool PZMedical2121ZCtrl::SetBinningMode(int nMode)
  3475. {
  3476. CString strLog = "";
  3477. if (m_nBinningMode == nMode) //判重处理
  3478. {
  3479. //根据和品臻方面讨论,闲时默认将采集周期设置为500,刷binning1x1模式的暗场图
  3480. //if (nMode == PZ_ONExONE && m_nWinTime != 500)
  3481. //{
  3482. // if (!SetSDKCfg(2))
  3483. // return false;
  3484. //} //当前不一定是停止采集了,所以没必要设置500周期的工作,由setbinning的地方去判断、设置周期
  3485. if (nMode == PZ_ONExONE)
  3486. strLog = "Already in Binning 1X1 mode";
  3487. else if (nMode == PZ_TWOxTWO)
  3488. strLog = "Already in Binning 2X2 mode";
  3489. else if (nMode == PZ_THRxTHR)
  3490. strLog = "Already in Binning 3X3 mode";
  3491. else
  3492. strLog.Format("Already in unknown Binning mode: %d", nMode);
  3493. LogInfo(strLog);
  3494. return true;
  3495. }
  3496. BOOL nRet;
  3497. if (nMode == PZ_ONExONE)
  3498. {
  3499. LogInfo("SetBinning to 1x1");
  3500. }
  3501. else if (nMode == PZ_TWOxTWO)
  3502. {
  3503. LogInfo("SetBinning to 2x2");
  3504. }
  3505. else if (nMode == PZ_THRxTHR)
  3506. {
  3507. LogInfo("SetBinning to 3x3");
  3508. }
  3509. else
  3510. {
  3511. strLog.Format("SetBinning to %d", nMode);
  3512. LogInfo(strLog);
  3513. }
  3514. nRet = API_COM_SetBinningMode(nMode);
  3515. if (!TestError(nRet))
  3516. {
  3517. LogError("SetBinning failed");
  3518. return false;
  3519. }
  3520. m_nBinningMode = nMode;
  3521. return true;
  3522. }
  3523. /******************************
  3524. * 获取、设置校正模式。
  3525. * 首先从探测器和SDK那里获取之前设置的校正模式,与当前用户配置的校正模式相对比,不同则修改为用户的矫正模式
  3526. * nMode = 0,获取校正模式
  3527. //****************************/
  3528. bool PZMedical2121ZCtrl::GetSetCalibMode(CHAR cCalibMode, int nMode)
  3529. {
  3530. CString strLog = "";
  3531. BOOL nRet;
  3532. if (nMode)
  3533. {
  3534. LogInfo("Call GetPreCalibMode");
  3535. CHAR cFPDCalibMode = API_COM_GetPreCalibMode();
  3536. switch (cFPDCalibMode)
  3537. {
  3538. case IMG_CALIB_RAW:
  3539. LogInfo("FPD calibration mode is raw");
  3540. break;
  3541. case IMG_CALIB_OFFSET:
  3542. LogInfo("FPD calibration mode is offset");
  3543. break;
  3544. case IMG_CALIB_GAIN:
  3545. LogInfo("FPD calibration mode is gain");
  3546. break;
  3547. case IMG_CALIB_DEFECT:
  3548. LogInfo("FPD calibration mode is defect");
  3549. break;
  3550. case (IMG_CALIB_OFFSET | IMG_CALIB_GAIN):
  3551. LogInfo("FPD calibration mode is offset+gain");
  3552. break;
  3553. case(IMG_CALIB_OFFSET | IMG_CALIB_GAIN | IMG_CALIB_DEFECT):
  3554. LogInfo("FPD calibration mode is offset+gain+defect");
  3555. break;
  3556. default:
  3557. LogInfo("FPD calibration mode is unknown");
  3558. break;
  3559. }
  3560. LogInfo("Call GetCalibMode");
  3561. CHAR cSDKCalibMode = API_COM_GetCalibMode();
  3562. switch (cSDKCalibMode)
  3563. {
  3564. case IMG_CALIB_RAW:
  3565. LogInfo("SDK calibration mode is raw");
  3566. break;
  3567. case IMG_CALIB_OFFSET:
  3568. LogInfo("SDK calibration mode is offset");
  3569. break;
  3570. case IMG_CALIB_GAIN:
  3571. LogInfo("SDK calibration mode is gain");
  3572. break;
  3573. case IMG_CALIB_DEFECT:
  3574. LogInfo("SDK calibration mode is defect");
  3575. break;
  3576. case (IMG_CALIB_OFFSET | IMG_CALIB_GAIN) :
  3577. LogInfo("SDK calibration mode is offset+gain");
  3578. break;
  3579. case(IMG_CALIB_OFFSET | IMG_CALIB_GAIN | IMG_CALIB_DEFECT) :
  3580. LogInfo("SDK calibration mode is offset+gain+defect");
  3581. break;
  3582. default:
  3583. LogInfo("SDK calibration mode is unknown");
  3584. break;
  3585. }
  3586. if (cCalibMode != cFPDCalibMode) //设置FPD校正模式
  3587. {
  3588. strLog.Format("Call SetPreCalibMode, User CalibMode(%d)", cCalibMode);
  3589. LogInfo(strLog);
  3590. nRet = API_COM_SetPreCalibMode(cCalibMode);
  3591. if (!TestError(nRet))
  3592. {
  3593. LogError("SetPreCalibMode failed");
  3594. return false;
  3595. }
  3596. }
  3597. else
  3598. {
  3599. LogInfo("FPD same as User CalibMode");
  3600. }
  3601. if (cCalibMode != cSDKCalibMode) //设置SDK校正模式
  3602. {
  3603. strLog.Format("Call SetCalibMode, User CalibMode(%d)", cCalibMode);
  3604. LogInfo(strLog);
  3605. nRet = API_COM_SetCalibMode(cCalibMode);
  3606. if (!TestError(nRet))
  3607. {
  3608. LogError("SetCalibMode failed");
  3609. return false;
  3610. }
  3611. return true;
  3612. }
  3613. else
  3614. {
  3615. LogInfo("SDK same as User CalibMode");
  3616. }
  3617. }
  3618. return true;
  3619. }
  3620. // 对图像应用过饱和值处理
  3621. bool PZMedical2121ZCtrl::ApplyImgSaturation(WORD* pImgData, int nWidth, int nHeight, int nSaturation)
  3622. {
  3623. LogInfo(" ## ApplyImgSaturation ## ");
  3624. WORD wSaturation = (WORD)nSaturation;
  3625. for (int i = 0; i < nWidth; i++)
  3626. {
  3627. for (int j = 0; j < nHeight; j++)
  3628. {
  3629. if (pImgData[i * nHeight + j] > wSaturation)
  3630. {
  3631. pImgData[i * nHeight + j] = wSaturation;
  3632. }
  3633. }
  3634. }
  3635. LogInfo("APPLY OVER");
  3636. return true;
  3637. }
  3638. /******************************
  3639. * 设置开窗模式。
  3640. * nStartLine, nStartColumn, 起始行、列
  3641. * nEndLine, nEndColumn, 终止行、列
  3642. //****************************/
  3643. bool PZMedical2121ZCtrl::SetROIMode(int nStartLine, int nEndLine, int nStartColumn, int nEndColumn)
  3644. {
  3645. CString strLog = "";
  3646. //判重
  3647. if (nStartLine == m_nStartLine && nEndLine == m_nEndLine &&
  3648. nStartColumn == m_nStartColumn && nEndColumn == m_nEndColumn)
  3649. {
  3650. strLog.Format("The startendline is already(%d %d); the stratendcolumn is already(%d %d)",
  3651. nStartLine, nEndLine, nStartColumn, nEndColumn);
  3652. LogInfo(strLog);
  3653. return true;
  3654. }
  3655. m_nStartLine = nStartLine;
  3656. m_nEndLine = nEndLine;
  3657. m_nStartColumn = nStartColumn;
  3658. m_nEndColumn = nEndColumn;
  3659. /*
  3660. strLog.Format("->SetStartEndLine(%d %d)", nStartLine, nEndLine);
  3661. LogInfo(strLog);
  3662. nRet = COM_SETSTARTENDLINE(nStartLine, nEndLine);
  3663. if (!TestError(nRet))
  3664. return false;
  3665. strLog.Format("->SetStartEndColum(%d %d)", nStartColumn, nEndColumn);
  3666. LogInfo(strLog);
  3667. nRet = COM_SETSTARTENDCOLUM(nStartColumn, nEndColumn);
  3668. if (!TestError(nRet))
  3669. return false;
  3670. */
  3671. //测试输出,看是否成功设置了起始行列
  3672. //LogInfo("->GetStartEndLine");
  3673. //nRet = COM_GETSTARTENDLINE(&m_nStartLine, &m_nEndLine);
  3674. //if (!TestError(nRet))
  3675. // return false;
  3676. //LogInfo("->GetStartEndColum");
  3677. //nRet = COM_GETSTARTENDCOLUM(&m_nStartColumn, &m_nEndColumn);
  3678. //if (!TestError(nRet))
  3679. // return false;
  3680. //strLog.Format("StartEndLine(%d %d) StartEndColumn(%d %d)", m_nStartLine, m_nEndLine, m_nStartColumn, m_nEndColumn);
  3681. //LogInfo(strLog);
  3682. return true;
  3683. }