CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
oDeformationManager.cc
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Defines