![]() |
CASToR
1.0
Tomographic Reconstruction (PET/SPECT)
|
00001 00002 /* 00003 Implementation of class oDeformationManager 00004 00005 - separators: X 00006 - doxygen: X 00007 - default initialization: X 00008 - CASTOR_DEBUG: X 00009 - CASTOR_VERBOSE: X 00010 */ 00011 00018 #include "oDeformationManager.hh" 00019 #include "sAddonManager.hh" 00020 00021 00022 00023 // ===================================================================== 00024 // --------------------------------------------------------------------- 00025 // --------------------------------------------------------------------- 00026 // ===================================================================== 00027 /* 00028 \fn oDeformationManager 00029 \brief Constructor of oDeformationManager. Simply set all data members to default values. 00030 */ 00031 oDeformationManager::oDeformationManager() 00032 { 00033 // Image dimensions 00034 mp_ID = NULL; 00035 // Options for each deformation type 00036 m_optionsResp = ""; 00037 m_optionsCard = ""; 00038 m_optionsInv = ""; 00039 // Deformation objects and associated bool 00040 mp_DeformationResp = NULL; 00041 mp_DeformationCard = NULL; 00042 mp_DeformationInv = NULL; 00043 m_UseDeformationResp = false; 00044 m_UseDeformationCard = false; 00045 m_UseDeformationInv = false; 00046 // Variable indicating the current gate for the different types of motion 00047 m_currentRespGate = 0; 00048 m_currentCardGate = 0; 00049 m_currentPMotionIndex = 0; 00050 // Number of gates for cyclic motion 00051 m_nbRespGates = -1; 00052 m_nbCardGates = -1; 00053 // Verbosity 00054 m_verbose = -1; 00055 // Data mode 00056 m_dataMode = -1; 00057 // Not checked yet 00058 m_checked = false; 00059 // Not initialized yet 00060 m_initialized = false; 00061 } 00062 00063 // ===================================================================== 00064 // --------------------------------------------------------------------- 00065 // --------------------------------------------------------------------- 00066 // ===================================================================== 00067 /* 00068 \fn ~oDeformationManager 00069 \brief Destructor of oDeformationManager. Free memory from all allocated tabs. 00070 */ 00071 oDeformationManager::~oDeformationManager() 00072 { 00073 // Delete deformation objects 00074 if (m_initialized) 00075 { 00076 if (mp_DeformationResp != NULL) delete mp_DeformationResp; 00077 if (mp_DeformationCard != NULL) delete mp_DeformationCard; 00078 if (mp_DeformationInv != NULL) delete mp_DeformationInv; 00079 } 00080 } 00081 00082 // ===================================================================== 00083 // --------------------------------------------------------------------- 00084 // --------------------------------------------------------------------- 00085 // ===================================================================== 00086 /* 00087 \fn InstantiateImageForDeformation 00088 \param oImageSpace* ap_Image : required to call oImageSpace instanciation functions 00089 \brief If deformation is enabled, ask the Image Space to Instantiate the temporary backward image for deformation 00090 If reconstruction is in histogram mode, the temporal sensitivity image is instanciated as well 00091 */ 00092 void oDeformationManager::InstantiateImageForDeformation(oImageSpace* ap_Image) 00093 { 00094 if ( m_UseDeformationResp || m_UseDeformationCard || m_UseDeformationInv ) 00095 { 00096 // Verbose 00097 if(m_verbose>=2) Cout("oDeformationManager::InstantiateImageForDeformation() -> Instantiate buffer images"<< endl); 00098 // Instantiate buffer image for backward deformation 00099 ap_Image->InstantiateBwdImageForDeformation(); 00100 // In histogram mode, need another buffer image for sensitivity deformation 00101 if (m_dataMode == MODE_HISTOGRAM) ap_Image->InstantiateSensImageForDeformation(); 00102 } 00103 } 00104 00105 // ===================================================================== 00106 // --------------------------------------------------------------------- 00107 // --------------------------------------------------------------------- 00108 // ===================================================================== 00109 /* 00110 \fn DeallocateImageForDeformation 00111 \param oImageSpace* ap_Image : required to call oImageSpace deallocation functions 00112 \brief If deformation is enabled, ask the Image Space to free memory of the temporary backward image for deformation 00113 If reconstruction is in histogram mode, the temporal sensitivity image is deallocated as well 00114 */ 00115 void oDeformationManager::DeallocateImageForDeformation(oImageSpace* ap_Image) 00116 { 00117 if ( m_UseDeformationResp || m_UseDeformationCard || m_UseDeformationInv ) 00118 { 00119 // Verbose 00120 if(m_verbose>=2) Cout("oDeformationManager::DeallocateImageForDeformation() -> Deallocate buffer images"<< endl); 00121 // Deallocate backward buffer image 00122 ap_Image->DeallocateBwdImageForDeformation(); 00123 // In histogram mode, deallocate sensitivity buffer image 00124 if (m_dataMode == MODE_HISTOGRAM) ap_Image->DeallocateSensImageForDeformation(); 00125 } 00126 } 00127 00128 // ===================================================================== 00129 // --------------------------------------------------------------------- 00130 // --------------------------------------------------------------------- 00131 // ===================================================================== 00132 /* 00133 \fn InitImageForDeformation 00134 \param oImageSpace* ap_Image : required to call oImageSpace initialization functions 00135 \brief If deformation is enabled, ask the Image Space to initialize the temporary backward image for deformation 00136 If reconstruction is in histogram mode, the temporal sensitivity image is initialized as well 00137 */ 00138 void oDeformationManager::InitImageForDeformation(oImageSpace* ap_Image) 00139 { 00140 if ( m_UseDeformationResp || m_UseDeformationCard || m_UseDeformationInv ) 00141 { 00142 if(m_verbose>=2) Cout("oDeformationManager::InitImageForDeformation() -> Initialize buffer images"<< endl); 00143 ap_Image->InitBwdImageForDeformation(); 00144 if (m_dataMode == MODE_HISTOGRAM) ap_Image->InitSensImageForDeformation(); 00145 } 00146 } 00147 00148 // ===================================================================== 00149 // --------------------------------------------------------------------- 00150 // --------------------------------------------------------------------- 00151 // ===================================================================== 00152 /* 00153 \fn CheckParameters 00154 \brief This function is used to check parameters after the latter 00155 have been all set using Set functions. 00156 \return 0 if success, positive value otherwise. 00157 */ 00158 int oDeformationManager::CheckParameters() 00159 { 00160 // Verbose 00161 if (m_verbose>=4) Cout("oDeformationManager::CheckParameters() -> Check parameters before initialization"<< endl); 00162 // Check image dimensions 00163 if (mp_ID==NULL) 00164 { 00165 Cerr("***** oDeformationManager::CheckParameters() -> No image dimensions provided !" << endl); 00166 return 1; 00167 } 00168 // Check resp gates 00169 if (m_nbRespGates<0) 00170 { 00171 Cerr("***** oDeformationManager::CheckParameters() -> Wrong number of respiratory gates !" << endl); 00172 return 1; 00173 } 00174 // Check card gates 00175 if (m_nbCardGates<0) 00176 { 00177 Cerr("***** oDeformationManager::CheckParameters() -> Wrong number of respiratory gates !" << endl); 00178 return 1; 00179 } 00180 // Check verbosity 00181 if (m_verbose<0) 00182 { 00183 Cerr("***** oDeformationManager::CheckParameters() -> Wrong verbosity level provided !" << endl); 00184 return 1; 00185 } 00186 // Check data mode 00187 if (m_dataMode<0) 00188 { 00189 Cerr("***** oDeformationManager::CheckParameters() -> Wrong data mode provided ! (should be =0 (list-mode) or =1 (histogram)" << endl); 00190 return 1; 00191 } 00192 // Normal end 00193 m_checked = true; 00194 return 0; 00195 } 00196 00197 // ===================================================================== 00198 // --------------------------------------------------------------------- 00199 // --------------------------------------------------------------------- 00200 // ===================================================================== 00201 /* 00202 \fn Initialize 00203 \brief Set the flags for the different motion types and instanciate/initialize deformation objects 00204 through the ParseOptionsAndInitializeDeformations() private function. 00205 \return 0 if success, positive value otherwise. 00206 */ 00207 int oDeformationManager::Initialize() 00208 { 00209 // Forbid initialization without check 00210 if (!m_checked) 00211 { 00212 Cerr("***** oDeformationManager::Initialize() -> Must call CheckParameters() before Initialize() !" << endl); 00213 return 1; 00214 } 00215 00216 // Check resp options 00217 if (m_optionsResp=="") m_UseDeformationResp = false; 00218 else m_UseDeformationResp = true; 00219 // Check card options 00220 if (m_optionsCard=="") m_UseDeformationCard = false; 00221 else m_UseDeformationCard = true; 00222 // Check inv options 00223 if (m_optionsInv=="") m_UseDeformationInv = false; 00224 else m_UseDeformationInv = true; 00225 00226 // Initialize current gates and involuntary motion indices 00227 m_currentRespGate = 0; 00228 m_currentCardGate = 0; 00229 m_currentPMotionIndex = 0; 00230 00231 // Return if no deformation 00232 if (!m_UseDeformationCard && !m_UseDeformationInv && !m_UseDeformationResp) 00233 { 00234 m_initialized = true; 00235 return 0; 00236 } 00237 00238 // Verbose 00239 if (m_verbose>=1) Cout("oDeformationManager::Initialize() -> Initialize deformations" << endl); 00240 00241 // Parse deformation options and initialize them 00242 if (ParseOptionsAndInitializeDeformations()) 00243 { 00244 Cerr("***** oDeformationManager::Initialize() -> A problem occured while parsing deformation options and initializing them !" << endl); 00245 return 1; 00246 } 00247 00248 // Normal end 00249 m_initialized = true; 00250 return 0; 00251 } 00252 00253 // ===================================================================== 00254 // --------------------------------------------------------------------- 00255 // --------------------------------------------------------------------- 00256 // ===================================================================== 00257 /* 00258 \fn ParseOptionsAndInitializeProjectors 00259 \brief Parse respiratory/cardiac/involuntary patient motion options contained in the previously provided 00260 strings. This function is called inside the Initialize() function. 00261 \details Manage the options reading and initialize specific vDeformation 00262 Options are a string containing first the name of the deformation, 00263 then either a ':' and a configuration file specific to the deformation 00264 - or - as many ',' as needed parameters for this deformation. 00265 Specific pure virtual functions of the vDeformation are used to read parameters and initialize them. 00266 \todo Some cleaning if we merge respiratory and cardiac motion objects 00267 \return 0 if success, positive value otherwise 00268 */ 00269 int oDeformationManager::ParseOptionsAndInitializeDeformations() 00270 { 00271 if (m_verbose>=2) Cout("oDeformationManager::ParseOptionsAndInitializeDeformations ..."<< endl); 00272 00273 string deformation = ""; 00274 string list_options = ""; 00275 string file_options = ""; 00276 00277 // This is for the automatic initialization of the deformations 00278 typedef vDeformation *(*maker_deformation) (); 00279 00280 // Get deformation's list from addon manager 00281 std::map <string,maker_deformation> list = sAddonManager::GetInstance()->mp_listOfDeformations; 00282 00283 size_t colon, comma; 00284 00285 // --------------------------------------------------------------------------------------------------- 00286 // Manage deformation for respiratory motion 00287 // --------------------------------------------------------------------------------------------------- 00288 if (m_UseDeformationResp) 00289 { 00290 // ______________________________________________________________________________ 00291 // Get the deformation name in the options and isolate the real deformation's options 00292 00293 // Search for a colon ":", this indicates that a configuration file is provided after the deformation name 00294 colon = m_optionsResp.find_first_of(":"); 00295 comma = m_optionsResp.find_first_of(","); 00296 00297 // Case 1: we have a colon 00298 if (colon!=string::npos) 00299 { 00300 // Get the deformation name before the colon 00301 deformation = m_optionsResp.substr(0,colon); 00302 // Get the configuration file after the colon 00303 file_options = m_optionsResp.substr(colon+1); 00304 // List of options is empty 00305 list_options = ""; 00306 } 00307 // Case 2: we have a comma 00308 else if (comma!=string::npos) 00309 { 00310 // Get the deformation name before the first comma 00311 deformation = m_optionsResp.substr(0,comma); 00312 // Get the list of options after the first comma 00313 list_options = m_optionsResp.substr(comma+1); 00314 // Configuration file is empty 00315 file_options = ""; 00316 } 00317 // Case 3: no colon and no comma (a single deformation name) 00318 else 00319 { 00320 // Get the deformation name 00321 deformation = m_optionsResp; 00322 // Configuration file is empty 00323 file_options = ""; 00324 // List of options is empty 00325 list_options = ""; 00326 } 00327 00328 // Create the deformation 00329 if (list[deformation]) mp_DeformationResp = list[deformation](); 00330 else 00331 { 00332 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> Deformation '" << deformation << "' does not exist !" << endl); 00333 sAddonManager::GetInstance()->ShowHelpDeformation(); 00334 return 1; 00335 } 00336 // Set parameters 00337 mp_DeformationResp->SetImageDimensionsAndQuantification(mp_ID); 00338 mp_DeformationResp->SetVerbose(m_verbose); 00339 mp_DeformationResp->SetNbTransformations(m_nbRespGates); 00340 00341 00342 // Provide configuration file if any 00343 if (file_options!="" && mp_DeformationResp->ReadAndCheckConfigurationFile(file_options)) 00344 { 00345 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while reading and checking respiratory deformation's configuration file !" << endl); 00346 return 1; 00347 } 00348 // Provide options if any 00349 if (list_options!="" && mp_DeformationResp->ReadAndCheckOptionsList(list_options)) 00350 { 00351 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while parsing and reading respiratory deformation's options !" << endl); 00352 return 1; 00353 } 00354 00355 // Check parameters 00356 if (mp_DeformationResp->CheckParameters()) 00357 { 00358 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while checking respiratory deformation parameters !" << endl); 00359 return 1; 00360 } 00361 // Initialize the deformation 00362 if (mp_DeformationResp->Initialize()) 00363 { 00364 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while initializing respiratory deformation !" << endl); 00365 return 1; 00366 } 00367 00368 // Tell the DynamicDataManager that respiratory motion is enabled 00369 mp_ID->SetRespMotionFlagOn(); // Probably useless since the DynamicDataManager already knows that normally ? 00370 } 00371 00372 // --------------------------------------------------------------------------------------------------- 00373 // Manage deformation for cardiac motion 00374 // --------------------------------------------------------------------------------------------------- 00375 if (m_UseDeformationCard) 00376 { 00377 // ______________________________________________________________________________ 00378 // Get the deformation name in the options and isolate the real deformation's options 00379 00380 // Search for a colon ":", this indicates that a configuration file is provided after the deformation name 00381 colon = m_optionsCard.find_first_of(":"); 00382 comma = m_optionsCard.find_first_of(","); 00383 00384 // Case 1: we have a colon 00385 if (colon!=string::npos) 00386 { 00387 // Get the deformation name before the colon 00388 deformation = m_optionsCard.substr(0,colon); 00389 // Get the configuration file after the colon 00390 file_options = m_optionsCard.substr(colon+1); 00391 // List of options is empty 00392 list_options = ""; 00393 } 00394 // Case 2: we have a comma 00395 else if (comma!=string::npos) 00396 { 00397 // Get the deformation name before the first comma 00398 deformation = m_optionsCard.substr(0,comma); 00399 // Get the list of options after the first comma 00400 list_options = m_optionsCard.substr(comma+1); 00401 // Configuration file is empty 00402 file_options = ""; 00403 } 00404 // Case 3: no colon and no comma (a single deformation name) 00405 else 00406 { 00407 // Get the deformation name 00408 deformation = m_optionsCard; 00409 // Configuration file is empty 00410 file_options = ""; 00411 // List of options is empty 00412 list_options = ""; 00413 } 00414 00415 // Create the deformation 00416 if (list[deformation]) mp_DeformationCard = list[deformation](); 00417 else 00418 { 00419 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> Deformation '" << deformation << "' does not exist !" << endl); 00420 return 1; 00421 } 00422 // Set parameters 00423 mp_DeformationCard->SetImageDimensionsAndQuantification(mp_ID); 00424 mp_DeformationCard->SetVerbose(m_verbose); 00425 mp_DeformationCard->SetNbTransformations(m_nbCardGates); 00426 // Provide configuration file if any 00427 if (file_options!="" && mp_DeformationCard->ReadAndCheckConfigurationFile(file_options)) 00428 { 00429 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while reading and checking cardiac deformation's configuration file !" << endl); 00430 return 1; 00431 } 00432 // Provide options if any 00433 if (list_options!="" && mp_DeformationCard->ReadAndCheckOptionsList(list_options)) 00434 { 00435 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while parsing and reading cardiac deformation's options !" << endl); 00436 return 1; 00437 } 00438 // Check parameters 00439 if (mp_DeformationCard->CheckParameters()) 00440 { 00441 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while checking cardiac deformation parameters !" << endl); 00442 return 1; 00443 } 00444 // Initialize the deformation 00445 if (mp_DeformationCard->Initialize()) 00446 { 00447 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while initializing cardiac deformation !" << endl); 00448 return 1; 00449 } 00450 // Tell the DynamicDataManager that cardiac motion is enabled 00451 mp_ID->SetCardMotionFlagOn(); 00452 } 00453 00454 // --------------------------------------------------------------------------------------------------- 00455 // Manage deformation for involuntary motion 00456 // --------------------------------------------------------------------------------------------------- 00457 if (m_UseDeformationInv) 00458 { 00459 // ______________________________________________________________________________ 00460 // Get the deformation name in the options and isolate the real deformation's options 00461 00462 // Search for a colon ":", this indicates that a configuration file is provided after the deformation name 00463 colon = m_optionsCard.find_first_of(":"); 00464 comma = m_optionsCard.find_first_of(","); 00465 00466 // Case 1: we have a colon 00467 if (colon!=string::npos) 00468 { 00469 // Get the deformation name before the colon 00470 deformation = m_optionsInv.substr(0,colon); 00471 // Get the configuration file after the colon 00472 file_options = m_optionsInv.substr(colon+1); 00473 // List of options is empty 00474 list_options = ""; 00475 } 00476 // Case 2: we have a comma 00477 else if (comma!=string::npos) 00478 { 00479 // Get the deformation name before the first comma 00480 deformation = m_optionsInv.substr(0,comma); 00481 // Get the list of options after the first comma 00482 list_options = m_optionsInv.substr(comma+1); 00483 // Configuration file is empty 00484 file_options = ""; 00485 } 00486 // Case 3: no colon and no comma (a single deformation name) 00487 else 00488 { 00489 // Get the deformation name 00490 deformation = m_optionsInv; 00491 // Configuration file is empty 00492 file_options = ""; 00493 // List of options is empty 00494 list_options = ""; 00495 } 00496 00497 // Create the deformation 00498 if (list[deformation]) mp_DeformationInv = list[deformation](); 00499 else 00500 { 00501 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> Deformation '" << deformation << "' does not exist !" << endl); 00502 return 1; 00503 } 00504 // Set parameters 00505 mp_DeformationInv->SetImageDimensionsAndQuantification(mp_ID); 00506 mp_DeformationInv->SetVerbose(m_verbose); 00507 mp_DeformationInv->SetNbTransformations(1); // TODO ! 00508 00509 00510 // Provide configuration file if any 00511 if (file_options!="" && mp_DeformationInv->ReadAndCheckConfigurationFile(file_options)) 00512 { 00513 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while reading and checking involuntary motion deformation's configuration file !" << endl); 00514 return 1; 00515 } 00516 // Provide options if any 00517 if (list_options!="" && mp_DeformationInv->ReadAndCheckOptionsList(list_options)) 00518 { 00519 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while parsing and reading involuntary motion deformation's options !" << endl); 00520 return 1; 00521 } 00522 // Check parameters 00523 if (mp_DeformationInv->CheckParameters()) 00524 { 00525 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while checking involuntary motion deformation parameters !" << endl); 00526 return 1; 00527 } 00528 // Initialize the deformation 00529 if (mp_DeformationInv->Initialize()) 00530 { 00531 Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while initializing involuntary motion deformation !" << endl); 00532 return 1; 00533 } 00534 00535 // Tell the DynamicDataManager that involuntary motion is enabled 00536 mp_ID->SetPMotionFlagOn(); 00537 } 00538 00539 // Normal end 00540 return 0; 00541 } 00542 00543 // ===================================================================== 00544 // --------------------------------------------------------------------- 00545 // --------------------------------------------------------------------- 00546 // ===================================================================== 00547 /* 00548 \fn ApplyDeformationForSensitivityGeneration 00549 \param oImageSpace* ap_Image : required to access oImageSpace image matrices 00550 \param int a_defDirection : direction of the deformation (forward/backward) 00551 \param int a_defType : Nature of the motion (Respiratory/Cardiac/Involuntary Patient) 00552 \param int fr 00553 \param int rg 00554 \param int cg 00555 \brief Apply deformations during the list-mode sensitivity image generation 00556 \details Perform deformation of type 'a_defType' on the forward_image or the backward_image matrices corresponding to the current fr, rg, cg (if any), and depending on the defDirection. 00557 \todo Some changes required if we merge respiratory/cardiac motion objects 00558 \todo Check and implement patient motion 00559 \return 0 if success, positive value otherwise 00560 */ 00561 int oDeformationManager::ApplyDeformationForSensitivityGeneration(oImageSpace* ap_Image, int a_defDirection, int a_defType, int fr, int rg, int cg) 00562 { 00563 #ifdef CASTOR_DEBUG 00564 if (!m_initialized) 00565 { 00566 Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration() -> Called while not initialized !" << endl); 00567 Exit(EXIT_DEBUG); 00568 } 00569 #endif 00570 00571 if (a_defType == DEF_RESP_MOT && m_UseDeformationResp) 00572 { 00573 if (m_verbose>=2) 00574 { 00575 string direction = "FORWARD"; if (a_defDirection==BACKWARD_DEFORMATION) direction = "BACKWARD"; 00576 Cout("oDeformationManager::ApplyDeformationForSensitivityGeneration()-> '" << direction 00577 << "' Deformation for respiratory motion, for resp gate " <<rg 00578 << " and card gate " <<cg<<"." <<endl); 00579 } 00580 if (mp_DeformationResp->PerformSensitivityDeformation(ap_Image, a_defDirection, rg, fr, rg, cg) ) 00581 { 00582 Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration()-> An error occured while performing deformation for respiratory motion correction for the sensitivity image generation !" << endl); 00583 return 1; 00584 } 00585 } 00586 00587 if (a_defType == DEF_CARD_MOT && m_UseDeformationCard) 00588 { 00589 if (m_verbose>=2) 00590 { 00591 string direction = "FORWARD"; if (a_defDirection==BACKWARD_DEFORMATION) direction = "BACKWARD"; 00592 Cout("oDeformationManager::ApplyDeformationForSensitivityGeneration()-> '" << direction 00593 << "' Deformation for cardiac motion, for resp gate " <<rg 00594 << " and card gate " <<cg<<"." <<endl); 00595 } 00596 if (mp_DeformationCard->PerformSensitivityDeformation(ap_Image, a_defDirection, cg, fr, rg, cg) ) 00597 { 00598 Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration()-> An error occured while performing deformation for cardiac motion correction for the sensitivity image generation !" << endl); 00599 return 1; 00600 } 00601 } 00602 00603 if (a_defType == DEF_IPAT_MOT && m_UseDeformationInv) 00604 { 00605 if (m_verbose>=2) 00606 { 00607 string direction = "FORWARD"; if (a_defDirection==BACKWARD_DEFORMATION) direction = "BACKWARD"; 00608 Cout("oDeformationManager::ApplyDeformationForSensitivityGeneration()-> '" << direction 00609 << "' Deformation for involuntary patient motion, for resp gate " <<rg 00610 << " and card gate " <<cg<<"." <<endl); 00611 } 00612 //if (mp_DeformationInv->PerformSensitivityDeformation(ap_Image, a_defDirection, GET_INDEX_HERE!!!, fr, rg, cg) ) //TODO 00613 //{ 00614 // Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration()-> An error occured while performing deformation for patient involuntary motion correction for the sensitivity image generation !" << endl); 00615 // return 1; 00616 //} 00617 } 00618 00619 return 0; 00620 } 00621 00622 // ===================================================================== 00623 // --------------------------------------------------------------------- 00624 // --------------------------------------------------------------------- 00625 // ===================================================================== 00626 /* 00627 \fn ApplyDeformationsToForwardImage 00628 \param oImageSpace* ap_Image : required to access oImageSpace image matrices 00629 \brief Apply initial deformations on the forwardImage before loop on events 00630 \todo May not be required anymore for the current implementation (always reference position at start of subset) 00631 \return 0 if success, positive value otherwise 00632 */ 00633 int oDeformationManager::ApplyDeformationsToForwardImage(oImageSpace* ap_Image) 00634 { 00635 #ifdef CASTOR_DEBUG 00636 if (!m_initialized) 00637 { 00638 Cerr("***** oDeformationManager::ApplyDeformationsToForwardImage() -> Called while not initialized !" << endl); 00639 Exit(EXIT_DEBUG); 00640 } 00641 #endif 00642 00643 int fr = mp_ID->GetCurrentTimeFrame(0); 00644 int rimg = mp_ID->GetCurrentRespImage(0); 00645 int cimg = mp_ID->GetCurrentCardImage(0); 00646 00647 fr = (fr<0) ? 0 : fr ; 00648 00649 if (m_UseDeformationResp) 00650 { 00651 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationToForwardImage-> Deformation of respiratory type, gate # " << mp_ID->GetCurrentRespGate(0) 00652 << ", for resp image " <<rimg 00653 << " and card image " <<cimg<<"." 00654 << " We are Frame # " << fr <<endl); 00655 if(mp_DeformationResp->ApplyDeformationsToForwardImage(ap_Image, mp_ID->GetCurrentRespGate(0), fr, rimg, cimg) ) 00656 { 00657 Cerr("***** oDeformationManager::ApplyDeformationsToForwardImage()-> An error occured while performing initial deformation of the forward image !" << endl); 00658 return 1; 00659 } 00660 } 00661 00662 if (m_UseDeformationCard) 00663 { 00664 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationToForwardImage-> Deformation of cardiac type, gate # " << mp_ID->GetCurrentCardGate(0) 00665 << ", for resp image " <<rimg 00666 << " and card image " <<cimg<<"." 00667 << " We are Frame # " << fr <<endl); 00668 if(mp_DeformationCard->ApplyDeformationsToForwardImage(ap_Image, mp_ID->GetCurrentCardGate(0), fr, rimg, cimg) ) 00669 { 00670 Cerr("***** oDeformationManager::ApplyDeformationsToForwardImage()-> An error occured while performing initial deformation of the forward image !" << endl); 00671 return 1; 00672 } 00673 } 00674 00675 if (m_UseDeformationInv) 00676 { 00677 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationToForwardImage-> Deformation of involuntary motion type, gate # " << mp_ID->GetCurrentPMotionIndex(0) 00678 << ", for resp image " <<rimg 00679 << " and card image " <<cimg<<"." <<endl); 00680 if(mp_DeformationInv->ApplyDeformationsToForwardImage(ap_Image, mp_ID->GetCurrentPMotionIndex(0), fr, rimg, cimg) ) 00681 { 00682 Cerr("***** oDeformationManager::ApplyDeformationsToForwardImage()-> An error occured while performing initial deformation of the forward image !" << endl); 00683 return 1; 00684 } 00685 } 00686 00687 return 0; 00688 } 00689 00690 // ===================================================================== 00691 // --------------------------------------------------------------------- 00692 // --------------------------------------------------------------------- 00693 // ===================================================================== 00694 /* 00695 \fn PerformDeformation 00696 \param oImageSpace* ap_Image : required to access oImageSpace image matrices 00697 \brief Apply deformations during reconstruction 00698 \details Call the eponym function for the deformation object, 00699 as well as PerformHistoSensitivityDeformation() if data mode is histogram. 00700 \todo why the check on frames ? 00701 \return 0 if success, positive value otherwise 00702 */ 00703 int oDeformationManager::PerformDeformation(oImageSpace* ap_Image) 00704 { 00705 #ifdef CASTOR_DEBUG 00706 if (!m_initialized) 00707 { 00708 Cerr("***** oDeformationManager::PerformDeformation() -> Called while not initialized !" << endl); 00709 Exit(EXIT_DEBUG); 00710 } 00711 #endif 00712 00713 int fr = mp_ID->GetCurrentTimeFrame(0); 00714 int rimg = mp_ID->GetCurrentRespImage(0); 00715 int cimg = mp_ID->GetCurrentCardImage(0); 00716 00717 fr = (fr<0) ? 0 : fr ; 00718 00719 if (m_UseDeformationResp && (m_currentRespGate!=mp_ID->GetCurrentRespGate(0)) ) 00720 { 00721 if(m_verbose >=3) Cout("oDeformationManager::PerformDeformation-> Deformation of respiratory type, gate # " << mp_ID->GetCurrentRespGate(0) 00722 << ", for resp image " <<rimg 00723 << " and card image " <<cimg<<"." 00724 << " We are Frame # " << fr << endl); 00725 if(mp_DeformationResp->PerformDeformation(ap_Image, mp_ID->GetCurrentRespGate(0), fr, rimg, cimg) ) 00726 { 00727 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing image deformation during the reconstruction !" << endl); 00728 return 1; 00729 } 00730 00731 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00732 if(m_dataMode == MODE_HISTOGRAM ) 00733 if( mp_DeformationResp->PerformHistoSensitivityDeformation(ap_Image, mp_ID->GetCurrentRespGate(0), fr, rimg, cimg) ) 00734 { 00735 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing sensitivity image deformation (histogram mode) during the reconstruction !" << endl); 00736 return 1; 00737 } 00738 00739 m_currentRespGate = mp_ID->GetCurrentRespGate(0); 00740 } 00741 00742 if (m_UseDeformationCard && (m_currentCardGate!=mp_ID->GetCurrentCardGate(0)) ) 00743 { 00744 if(m_verbose >=3) Cout("oDeformationManager::PerformDeformation-> Deformation of cardiac type, gate # " << mp_ID->GetCurrentCardGate(0) 00745 << ", for resp image " <<rimg 00746 << " and card image " <<cimg<<"." <<endl); 00747 if(mp_DeformationCard->PerformDeformation(ap_Image, mp_ID->GetCurrentCardGate(0), fr, rimg, cimg) ) 00748 { 00749 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing image deformation during the reconstruction !" << endl); 00750 return 1; 00751 } 00752 00753 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00754 if(m_dataMode == MODE_HISTOGRAM ) 00755 if( mp_DeformationCard->PerformHistoSensitivityDeformation(ap_Image, mp_ID->GetCurrentCardGate(0), fr, rimg, cimg) ) 00756 { 00757 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing sensitivity image deformation (histogram mode) during the reconstruction !" << endl); 00758 return 1; 00759 } 00760 00761 m_currentCardGate = mp_ID->GetCurrentCardGate(0); 00762 } 00763 00764 if (m_UseDeformationInv && (m_currentPMotionIndex!=mp_ID->GetCurrentPMotionIndex(0)) ) 00765 { 00766 // TODO: pay attention here to the indexation because the deformations are based on a number of time-triggers 00767 if(m_verbose >=3) Cout("oDeformationManager::PerformDeformation-> Deformation of involuntary motion type, gate # " << mp_ID->GetCurrentPMotionIndex(0) 00768 << ", for resp image " <<rimg 00769 << " and card image " <<cimg<<"." <<endl); 00770 if(mp_DeformationInv->PerformDeformation(ap_Image, mp_ID->GetCurrentPMotionIndex(0), fr, rimg, cimg) ) 00771 { 00772 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing image deformation during the reconstruction !" << endl); 00773 return 1; 00774 } 00775 00776 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00777 if(m_dataMode == MODE_HISTOGRAM ) 00778 if( mp_DeformationInv->PerformHistoSensitivityDeformation(ap_Image, mp_ID->GetCurrentPMotionIndex(0), fr, rimg, cimg) ) 00779 { 00780 Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing sensitivity image deformation (histogram mode) during the reconstruction !" << endl); 00781 return 1; 00782 } 00783 00784 m_currentPMotionIndex = mp_ID->GetCurrentPMotionIndex(0); 00785 } 00786 00787 return 0; 00788 } 00789 00790 // ===================================================================== 00791 // --------------------------------------------------------------------- 00792 // --------------------------------------------------------------------- 00793 // ===================================================================== 00794 /* 00795 \fn ApplyDeformationsToBackwardImage 00796 \param oImageSpace* ap_Image : required to access oImageSpace image matrices 00797 \brief Apply final backward deformations on the backward image 00798 \details Call the eponym function for the deformation object, as well as >ApplyDeformationsToHistoSensitivityImage() if data mode is histogram. 00799 Then reinitialize the temporary backup deformation images (the backward image, and the sensitivity image if data mode is histogram) 00800 \return 0 if success, positive value otherwise 00801 */ 00802 int oDeformationManager::ApplyDeformationsToBackwardImage(oImageSpace* ap_Image) 00803 { 00804 #ifdef CASTOR_DEBUG 00805 if (!m_initialized) 00806 { 00807 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage() -> Called while not initialized !" << endl); 00808 Exit(EXIT_DEBUG); 00809 } 00810 #endif 00811 00812 if (m_UseDeformationResp) 00813 { 00814 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationsToBackwardImage-> Deformation of respiratory type, gate # " 00815 << mp_ID->GetCurrentRespGate(0)<< "." <<endl); 00816 if(mp_DeformationResp->ApplyDeformationsToBackwardImage(ap_Image, mp_ID->GetCurrentRespGate(0)) ) 00817 { 00818 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation !" << endl); 00819 return 1; 00820 } 00821 00822 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00823 if(m_dataMode == MODE_HISTOGRAM) 00824 if(mp_DeformationResp->ApplyDeformationsToHistoSensitivityImage(ap_Image, mp_ID->GetCurrentRespGate(0)) ) 00825 { 00826 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation of the sensitivity image !" << endl); 00827 return 1; 00828 } 00829 } 00830 00831 if (m_UseDeformationCard) 00832 { 00833 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationsToBackwardImage-> Deformation of cardiac type, gate # " 00834 << mp_ID->GetCurrentCardGate(0) << "." <<endl); 00835 if(mp_DeformationCard->ApplyDeformationsToBackwardImage(ap_Image, mp_ID->GetCurrentCardGate(0)) ) 00836 { 00837 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation !" << endl); 00838 return 1; 00839 } 00840 00841 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00842 if(m_dataMode == MODE_HISTOGRAM) 00843 if(mp_DeformationCard->ApplyDeformationsToHistoSensitivityImage(ap_Image, mp_ID->GetCurrentCardGate(0)) ) 00844 { 00845 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation of the sensitivity image !" << endl); 00846 return 1; 00847 } 00848 } 00849 00850 if (m_UseDeformationInv) 00851 { 00852 if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationsToBackwardImage-> Deformation of involuntary motion type, gate # " 00853 << mp_ID->GetCurrentPMotionIndex(0) << "." <<endl); 00854 if( mp_DeformationInv->ApplyDeformationsToBackwardImage(ap_Image, mp_ID->GetCurrentPMotionIndex(0)) ) 00855 { 00856 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation !" << endl); 00857 return 1; 00858 } 00859 00860 // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM) 00861 if(m_dataMode == MODE_HISTOGRAM) 00862 if(mp_DeformationInv->ApplyDeformationsToHistoSensitivityImage(ap_Image, mp_ID->GetCurrentPMotionIndex(0)) ) 00863 { 00864 Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation of the sensitivity image !" << endl); 00865 return 1; 00866 } 00867 } 00868 00869 // Reinitialize temporary deformation image(s) 00870 if (m_UseDeformationResp || m_UseDeformationCard || m_UseDeformationInv) 00871 { 00872 ap_Image->InitBwdImageForDeformation(); 00873 00874 if(m_dataMode == MODE_HISTOGRAM) 00875 ap_Image->InitSensImageForDeformation(); 00876 } 00877 00878 return 0; 00879 }