![]() |
CASToR
1.0
Tomographic Reconstruction (PET/SPECT)
|
00001 00002 /* 00003 Implementation of class vDeformation 00004 00005 - separators: X 00006 - doxygen: X 00007 - default initialization: X 00008 - CASTOR_DEBUG: X 00009 - CASTOR_VERBOSE: X 00010 */ 00011 00018 #include "vDeformation.hh" 00019 #include "oImageDimensionsAndQuantification.hh" 00020 #include "oImageSpace.hh" 00021 00022 00023 // ===================================================================== 00024 // --------------------------------------------------------------------- 00025 // --------------------------------------------------------------------- 00026 // ===================================================================== 00027 /* 00028 \fn vDeformation 00029 \brief Constructor of vDeformation. Simply set all data members to default values. 00030 */ 00031 vDeformation::vDeformation() 00032 { 00033 mp_ID = NULL; 00034 m_nbTransformations = -1; 00035 m_verbose = -1; 00036 m_checked = false; 00037 m_initialized = false; 00038 } 00039 00040 00041 00042 00043 // ===================================================================== 00044 // --------------------------------------------------------------------- 00045 // --------------------------------------------------------------------- 00046 // ===================================================================== 00047 /* 00048 \fn ~vDeformation 00049 \brief Destructor of vDeformation. 00050 */ 00051 vDeformation::~vDeformation() {} 00052 00053 00054 00055 00056 // ===================================================================== 00057 // --------------------------------------------------------------------- 00058 // --------------------------------------------------------------------- 00059 // ===================================================================== 00066 int vDeformation::CheckParameters() 00067 { 00068 if(m_verbose>=2) Cout("vDeformation::CheckParameters ..."<< endl); 00069 00070 // Check image dimensions 00071 if (mp_ID==NULL) 00072 { 00073 Cerr("***** vDeformation::CheckParameters() -> No image dimensions provided !" << endl); 00074 return 1; 00075 } 00076 00077 // Check verbosity 00078 if (m_verbose<0) 00079 { 00080 Cerr("***** vDeformation::CheckParameters() -> Wrong verbosity level provided !" << endl); 00081 return 1; 00082 } 00083 00084 // Check number of basis functions 00085 if (m_nbTransformations <0) 00086 { 00087 Cerr("***** vDeformation::CheckParameters() -> Number of transformations in the deformation has not been initialized !" << endl); 00088 return 1; 00089 } 00090 00091 // Check parameters of the child class (if this function is overloaded) 00092 if (CheckSpecificParameters()) 00093 { 00094 Cerr("***** vDeformation::CheckParameters() -> An error occurred while checking parameters of the child dynamic class !" << endl); 00095 return 1; 00096 } 00097 00098 // Normal end 00099 m_checked = true; 00100 return 0; 00101 } 00102 00103 00104 00105 00106 // ===================================================================== 00107 // --------------------------------------------------------------------- 00108 // --------------------------------------------------------------------- 00109 // ===================================================================== 00110 /* 00111 \fn ApplyDeformationsToForwardImage 00112 \param ap_Image : required to access the forward image 00113 \param a_defIdx : index of the deformation 00114 \param fr : frame index 00115 \param rimg : respiratory image index 00116 \param cimg : cardiac image index 00117 \brief Apply initial deformations on the forwardImage before loop on events 00118 \todo May not be required anymore for the current implementation (always reference position at start of subset) 00119 \return 0 if success, positive value otherwise 00120 */ 00121 int vDeformation::ApplyDeformationsToForwardImage(oImageSpace* ap_Image, int a_defIdx, int fr, int rimg, int cimg) 00122 { 00123 if (m_verbose >= 2) Cout("vDeformation::ApplyDeformationsToForwardImage ... " <<endl); 00124 00125 #ifdef CASTOR_DEBUG 00126 if (!m_initialized) 00127 { 00128 Cerr("***** vDeformation::ApplyDeformationsToForwardImage() -> Called while not initialized !" << endl); 00129 Exit(EXIT_DEBUG); 00130 } 00131 #endif 00132 00133 if (ApplyDeformations(ap_Image->m4p_forwardImage[fr][rimg][cimg], ap_Image->m4p_forwardImage[fr][rimg][cimg], FORWARD_DEFORMATION, a_defIdx) ) 00134 { 00135 Cerr("***** vDeformation::ApplyDeformationsToForwardImage()-> An error occured while performing initial deformation of the forward image !" << endl); 00136 return 1; 00137 } 00138 00139 return 0; 00140 } 00141 00142 00143 00144 00145 // ===================================================================== 00146 // --------------------------------------------------------------------- 00147 // --------------------------------------------------------------------- 00148 // ===================================================================== 00149 /* 00150 \fn ApplyDeformationsToBackwardImage 00151 \param ap_Image : required to access the backward image and its deformation backup matrice 00152 \param a_defIdx : index of the deformation 00153 \brief Apply backward transformation of the backward image to the reference position 00154 \details Loop on frames 00155 Recover any potential data stored in the backup matrice m2p_defTmpBackwardImage 00156 \return 0 if success, positive value otherwise 00157 */ 00158 int vDeformation::ApplyDeformationsToBackwardImage(oImageSpace* ap_Image, int a_defIdx) 00159 { 00160 if(m_verbose >= 2) Cout("vDeformation::ApplyDeformationsToBackwardImage ... " <<endl); 00161 00162 #ifdef CASTOR_DEBUG 00163 if (!m_initialized) 00164 { 00165 Cerr("***** vDeformation::ApplyDeformationsToBackwardImage() -> Called while not initialized !" << endl); 00166 Exit(EXIT_DEBUG); 00167 } 00168 #endif 00169 00170 for(int bimg=0; bimg<ap_Image->GetNbBackwardImages(); bimg++) 00171 for(int fr=0; fr<mp_ID->GetNbTimeFrames(); fr++) 00172 for(int rimg=0; rimg<mp_ID->GetNbRespGates(); rimg++) 00173 for(int cimg=0; cimg<mp_ID->GetNbCardGates(); cimg++) 00174 { 00175 // Perform backward deformation 00176 if(ApplyDeformations(ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg], ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg], BACKWARD_DEFORMATION, a_defIdx) ) 00177 { 00178 Cerr("***** vDeformation::ApplyDeformationsToBackwardImage()-> An error occured while performing backward deformation of the backward image !" << endl); 00179 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00180 return 1; 00181 } 00182 00183 // Recover the content of the temporary backup deformation image to the backward image 00184 for(int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00185 ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg][v] += ap_Image->m5p_defTmpBackwardImage[bimg][fr][rimg][cimg][v] ; 00186 } 00187 00188 return 0; 00189 } 00190 00191 00192 00193 00194 // ===================================================================== 00195 // --------------------------------------------------------------------- 00196 // --------------------------------------------------------------------- 00197 // ===================================================================== 00198 /* 00199 \fn ApplyDeformationsToHistoSensitivityImage 00200 \param ap_Image : required to access the backward image and its deformation backup matrice 00201 \param a_defIdx : index of the deformation 00202 \brief Apply backward transformations of the sensitivity image to the reference position (histogram mode) 00203 \details Loop on frames 00204 Recover any potential data stored in the backup matrice m4p_defTmpSensitivityImage 00205 \return 0 if success, positive value otherwise 00206 */ 00207 int vDeformation::ApplyDeformationsToHistoSensitivityImage(oImageSpace* ap_Image, int a_defIdx) 00208 { 00209 if(m_verbose >= 2) Cout("vDeformation::ApplyDeformationsToHistoSensitivityImage ... " <<endl); 00210 00211 #ifdef CASTOR_DEBUG 00212 if (!m_initialized) 00213 { 00214 Cerr("***** vDeformation::ApplyDeformationsToHistoSensitivityImage() -> Called while not initialized !" << endl); 00215 Exit(EXIT_DEBUG); 00216 } 00217 #endif 00218 00219 for(int fr=0; fr<mp_ID->GetNbTimeFrames(); fr++) 00220 for(int rimg=0; rimg<mp_ID->GetNbRespGates() ; rimg++) 00221 for(int cimg=0; cimg<mp_ID->GetNbCardGates() ; cimg++) 00222 { 00223 // Perform backward deformation 00224 if( ApplyDeformations(ap_Image->m5p_sensitivity[0][fr][rimg][cimg], ap_Image->m5p_sensitivity[0][fr][rimg][cimg], BACKWARD_DEFORMATION, a_defIdx) ) 00225 { 00226 Cerr("***** vDeformation::ApplyDeformationsToHistoSensitivityImage()-> An error occured while performing backward deformation of the backward image !" << endl); 00227 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00228 return 1; 00229 } 00230 00231 // Recover the content of the temporary backup deformation image to the sensitivity image 00232 for(int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00233 ap_Image->m5p_sensitivity[0][fr][rimg][cimg][v] += ap_Image->m4p_defTmpSensitivityImage[fr][rimg][cimg][v]; 00234 } 00235 00236 return 0; 00237 } 00238 00239 00240 00241 00242 // ===================================================================== 00243 // --------------------------------------------------------------------- 00244 // --------------------------------------------------------------------- 00245 // ===================================================================== 00246 /* 00247 \fn PerformDeformation 00248 \param ap_Image : required to access oImageSpace image matrices 00249 \param a_defIdx : index of the deformation 00250 \param fr : frame index 00251 \param rimg : respiratory image index 00252 \param cimg : cardiac image index 00253 \brief Apply deformations during reconstruction 00254 \details 1. Recover all the data of the multithreaded backward image matrices in the first one (thread index 0) 00255 2. Perform backward deformation of the backward image to the reference position with defIdx-1 00256 3. Add coefficients of the backward image matrice to the temporary backup image matrice & reset backward image 00257 4. Apply forward deformation of the forward image (backward deformation to the reference position with defIdx-1, and forward deformation with defIdx) 00258 \return 0 if success, positive value otherwise 00259 */ 00260 int vDeformation::PerformDeformation(oImageSpace* ap_Image, int a_defIdx, int fr, int rimg, int cimg) 00261 { 00262 if(m_verbose >= 2) Cout("vDeformation::PerformDeformation ... " <<endl); 00263 00264 #ifdef CASTOR_DEBUG 00265 if (!m_initialized) 00266 { 00267 Cerr("***** vDeformation::PerformDeformation() -> Called while not initialized !" << endl); 00268 Exit(EXIT_DEBUG); 00269 } 00270 #endif 00271 00272 // REDUCE 00273 for (int bimg=0; bimg<ap_Image->GetNbBackwardImages(); bimg++) 00274 { 00275 for (int th=1 ; th<mp_ID->GetNbThreadsForProjection() ; th++) //TODO add loops 00276 { 00277 // Synchronisation of the multi-threaded backwardImages inside the first image Reduce) 00278 for(int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00279 ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg][v] += ap_Image->m6p_backwardImage[bimg][th][fr][rimg][cimg][v]; 00280 } 00281 00282 // BACKWARD DEFORMATION of the backward image //TODO add loops 00283 if (ApplyDeformations(ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg], ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg], BACKWARD_DEFORMATION, a_defIdx-1) ) 00284 { 00285 Cerr("***** vDeformation::ApplyDeformations()-> An error occured while performing backward deformation of the backward image !" << endl); 00286 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00287 return 1; 00288 } 00289 00290 // Store Backward deformation update coefficients in the temporary backup image //TODO add loops 00291 for (int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00292 { 00293 ap_Image->m5p_defTmpBackwardImage[bimg][fr][rimg][cimg][v] += ap_Image->m6p_backwardImage[bimg][0][fr][rimg][cimg][v]; 00294 } 00295 } 00296 00297 // Reset the backward images (i.e set all voxels to the specific fr/rimg/cimg to 0) 00298 for (int bimg=0; bimg<ap_Image->GetNbBackwardImages(); bimg++) 00299 for(int th=0 ; th<mp_ID->GetNbThreadsForProjection() ; th++) 00300 for (int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00301 ap_Image->m6p_backwardImage[bimg][th][fr][rimg][cimg][v] = 0.; 00302 00303 00304 // BACKWARD DEFORMATION of the Forward image //TODO add loops 00305 if (ApplyDeformations(ap_Image->m4p_forwardImage[fr][rimg][cimg], ap_Image->m4p_forwardImage[fr][rimg][cimg], BACKWARD_DEFORMATION, a_defIdx-1) ) 00306 { 00307 Cerr("***** vDeformation::ApplyDeformations()-> An error occured while performing backward deformation of the forward image !" << endl); 00308 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00309 return 1; 00310 } 00311 // FORWARD DEFORMATION of the Forward image 00312 if (ApplyDeformations(ap_Image->m4p_forwardImage[fr][rimg][cimg], ap_Image->m4p_forwardImage[fr][rimg][cimg], FORWARD_DEFORMATION, a_defIdx) ) 00313 { 00314 Cerr("***** vDeformation::ApplyDeformations()-> An error occured while performing forward deformation of the forxar image !" << endl); 00315 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00316 return 1; 00317 } 00318 return 0; 00319 } 00320 00321 00322 00323 00324 // ===================================================================== 00325 // --------------------------------------------------------------------- 00326 // --------------------------------------------------------------------- 00327 // ===================================================================== 00328 /* 00329 \fn PerformHistoSensitivityDeformation 00330 \param ap_Image : required to access oImageSpace image matrices 00331 \param a_defIdx : index of the deformation 00332 \param fr : frame index 00333 \param rimg : respiratory image index 00334 \param cimg : cardiac image index 00335 \brief Apply deformations on the sensitivity image during reconstruction in histogram mode 00336 \details 1. Recover all the data of the multithreaded sensitivity image matrice in the first one (thread index 0) 00337 2. Perform backward deformation of the sensitivity image to the reference position with defIdx-1 00338 3. Add coefficients of the sensitivity image matrice to the temporary backup image matrice & reset sensitivity image 00339 \return 0 if success, positive value otherwise 00340 */ 00341 int vDeformation::PerformHistoSensitivityDeformation(oImageSpace* ap_Image, int a_defIdx, int fr, int rimg, int cimg) 00342 { 00343 if(m_verbose >= 2) Cout("vDeformation::PerformHistoSensitivityDeformation ... " <<endl); 00344 00345 #ifdef CASTOR_DEBUG 00346 if (!m_initialized) 00347 { 00348 Cerr("***** vDeformation::PerformHistoSensitivityDeformation() -> Called while not initialized !" << endl); 00349 Exit(EXIT_DEBUG); 00350 } 00351 #endif 00352 00353 // REDUCE 00354 for (int th=1 ; th<mp_ID->GetNbThreadsForProjection() ; th++) 00355 { 00356 // Synchronisation of the multi-threaded sensitivity images inside the first image ) 00357 for(int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00358 ap_Image->m5p_sensitivity[0][fr][rimg][cimg][v] += ap_Image->m5p_sensitivity[th][fr][rimg][cimg][v]; 00359 } 00360 00361 // BACKWARD DEFORMATION of the sensitivity image 00362 if (ApplyDeformations(ap_Image->m5p_sensitivity[0][fr][rimg][cimg], ap_Image->m5p_sensitivity[0][fr][rimg][cimg], BACKWARD_DEFORMATION, a_defIdx-1) ) 00363 { 00364 Cerr("***** vDeformation::PerformHistoSensitivityDeformation()-> An error occured while performing backward deformation of the sensitivity image !" << endl); 00365 Cerr("***** frame index " << fr << " respiratory image index " << rimg<< " cardiac image index " << cimg<< " !" << endl); 00366 return 1; 00367 } 00368 00369 // Store Backward deformation update coefficients in temporary image 00370 for (int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00371 { 00372 ap_Image->m4p_defTmpSensitivityImage[fr][rimg][cimg][v] += ap_Image->m5p_sensitivity[0][fr][rimg][cimg][v]; 00373 } 00374 00375 // Reset the sensitivity images (i.e set all voxels to the specific fr/rimg/cimg to 0) 00376 for (int th=0; th<mp_ID->GetNbThreadsForProjection(); th++) 00377 for (int v=0; v<mp_ID->GetNbVoxXYZ(); v++) 00378 ap_Image->m5p_sensitivity[th][fr][rimg][cimg][v] = 0.; 00379 00380 return 0; 00381 } 00382 00383 00384 00385 00386 // ===================================================================== 00387 // --------------------------------------------------------------------- 00388 // --------------------------------------------------------------------- 00389 // ===================================================================== 00390 /* 00391 \fn PerformSensitivityDeformation 00392 \param ap_Image : required to access oImageSpace image matrices 00393 \param a_defDirection : a direction for the deformation to perform (forward or backward) 00394 \param a_defIdx : index of the deformation 00395 \param fr : frame index 00396 \param rg : respiratory gate index 00397 \param cg : cardiac gate index 00398 \brief Apply image deformations during sensitivity image generation for list-mode 00399 \details Depending on the deformation direction (forward or backward): 00400 Forward : Perform forward deformation of the forward image to the deformation index position 00401 Backward: Perform backward deformation of the backward image to the reference position 00402 \return 0 if success, positive value otherwise 00403 */ 00404 int vDeformation::PerformSensitivityDeformation(oImageSpace* ap_Image, int a_defDirection, int a_defIdx, int fr, int rg, int cg) 00405 { 00406 if(m_verbose >= 2) Cout("vDeformation::PerformSensitivityDeformation ... " <<endl); 00407 00408 #ifdef CASTOR_DEBUG 00409 if (!m_initialized) 00410 { 00411 Cerr("***** vDeformation::PerformSensitivityDeformation() -> Called while not initialized !" << endl); 00412 Exit(EXIT_DEBUG); 00413 } 00414 #endif 00415 00416 if (a_defDirection == FORWARD_DEFORMATION) 00417 { 00418 if (ApplyDeformations(ap_Image->m4p_forwardImage[fr][rg][cg], ap_Image->m4p_forwardImage[fr][rg][cg], a_defDirection, a_defIdx) ) 00419 { 00420 Cerr("***** vDeformation::PerformSensitivityDeformation -> An error occured while performing forward deformation !" << endl); 00421 Cerr("***** frame index " << fr << " respiratory gate index " << rg<< " cardiac gate index " << cg<< " !" << endl); 00422 return 1; 00423 } 00424 } 00425 else if (a_defDirection == BACKWARD_DEFORMATION) 00426 { 00427 if (ApplyDeformations(ap_Image->m6p_backwardImage[0][0][fr][rg][cg], ap_Image->m6p_backwardImage[0][0][fr][rg][cg], a_defDirection, a_defIdx) ) 00428 { 00429 Cerr("***** vDeformation::PerformSensitivityDeformation -> An error occured while performing backward deformation !" << endl); 00430 Cerr("***** frame index " << fr << " respiratory gate index " << rg<< " cardiac gate index " << cg<< " !" << endl); 00431 return 1; 00432 } 00433 } 00434 else 00435 { 00436 Cerr("***** vDeformation::PerformDeformation -> Unknown type of deformation !" << endl); 00437 return 1; 00438 } 00439 00440 return 0; 00441 }