CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
oDeformationManager.cc
Go to the documentation of this file.
1 
2 /*
3  Implementation of class oDeformationManager
4 
5  - separators: X
6  - doxygen: X
7  - default initialization: X
8  - CASTOR_DEBUG: X
9  - CASTOR_VERBOSE: X
10 */
11 
18 #include "oDeformationManager.hh"
19 #include "sAddonManager.hh"
20 
21 
22 
23 // =====================================================================
24 // ---------------------------------------------------------------------
25 // ---------------------------------------------------------------------
26 // =====================================================================
27 /*
28  \fn oDeformationManager
29  \brief Constructor of oDeformationManager. Simply set all data members to default values.
30 */
32 {
33  // Image dimensions
34  mp_ID = NULL;
35  // Options for deformation
36  m_options = "";
37 
38  // Deformation objects and associated bool
39  mp_Deformation = NULL;
40 
41  m_UseDeformationResp = false;
42  m_UseDeformationCard = false;
43  m_UseDeformationIPat = false;
44 
45  // Variable indicating the number of transformations
47 
48  // Verbosity
49  m_verbose = -1;
50  // Data mode
51  m_dataMode = -1;
52  // Not checked yet
53  m_checked = false;
54  // Not initialized yet
55  m_initialized = false;
56 }
57 
58 // =====================================================================
59 // ---------------------------------------------------------------------
60 // ---------------------------------------------------------------------
61 // =====================================================================
62 /*
63  \fn ~oDeformationManager
64  \brief Destructor of oDeformationManager. Free memory from all allocated tabs.
65 */
67 {
68  // Delete deformation objects
69  if (m_initialized)
70  if (mp_Deformation!= NULL) delete mp_Deformation;
71 }
72 
73 
74 
75 // =====================================================================
76 // ---------------------------------------------------------------------
77 // ---------------------------------------------------------------------
78 // =====================================================================
79 /*
80  \fn oDeformationManager::SetMotionType
81  \param a_motionType
82  \brief Set the nature of motion correction (Deformation type macro)
83 */
84 void oDeformationManager::SetMotionType(int a_motionType)
85 {
86  switch (a_motionType)
87  {
88  case DEF_RESP_MOT : m_UseDeformationResp = true; break;
89  case DEF_CARD_MOT : m_UseDeformationCard = true; break;
90  case DEF_IPAT_MOT : m_UseDeformationIPat = true; break;
91  case DEF_DUAL_MOT : {m_UseDeformationResp = true; m_UseDeformationCard = true;} break;
92  default : {m_UseDeformationResp = false;
93  m_UseDeformationCard = false;
94  m_UseDeformationIPat = false;}
95  }
96 }
97 
98 
99 
100 
101 // =====================================================================
102 // ---------------------------------------------------------------------
103 // ---------------------------------------------------------------------
104 // =====================================================================
105 /*
106  \fn CheckParameters
107  \brief This function is used to check parameters after the latter
108  have been all set using Set functions.
109  \return 0 if success, positive value otherwise.
110 */
112 {
113  // Verbose
114  if (m_verbose>=4) Cout("oDeformationManager::CheckParameters() -> Check parameters before initialization"<< endl);
115  // Check image dimensions
116  if (mp_ID==NULL)
117  {
118  Cerr("***** oDeformationManager::CheckParameters() -> No image dimensions provided !" << endl);
119  return 1;
120  }
121  // Check resp gates
122  if (m_nbTransformations<0)
123  {
124  Cerr("***** oDeformationManager::CheckParameters() -> Wrong number of respiratory gates !" << endl);
125  return 1;
126  }
127  // Check verbosity
128  if (m_verbose<0)
129  {
130  Cerr("***** oDeformationManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
131  return 1;
132  }
133  // Check data mode
134  if (m_dataMode<0)
135  {
136  Cerr("***** oDeformationManager::CheckParameters() -> Wrong data mode provided ! (should be =0 (list-mode) or =1 (histogram)" << endl);
137  return 1;
138  }
139  // Normal end
140  m_checked = true;
141  return 0;
142 }
143 
144 
145 // =====================================================================
146 // ---------------------------------------------------------------------
147 // ---------------------------------------------------------------------
148 // =====================================================================
149 /*
150  \fn Initialize
151  \brief Set the flags for the different motion types and instanciate/initialize deformation objects
152  through the ParseOptionsAndInitializeDeformations() private function.
153  \return 0 if success, positive value otherwise.
154 */
156 {
157  // Forbid initialization without check
158  if (!m_checked)
159  {
160  Cerr("***** oDeformationManager::Initialize() -> Must call CheckParameters() before Initialize() !" << endl);
161  return 1;
162  }
163 
164  // Initialize current gate/involuntary motion index
165  m_curMotIdx = 0;
166 
167  // Return if no deformation
169  {
170  m_initialized = true;
171  return 0;
172  }
173 
174  // Verbose
175  if (m_verbose>=1) Cout("oDeformationManager::Initialize() -> Initialize deformations" << endl);
176 
177  // Parse deformation options and initialize them
179  {
180  Cerr("***** oDeformationManager::Initialize() -> A problem occured while parsing deformation options and initializing them !" << endl);
181  return 1;
182  }
183 
184  // Normal end
185  m_initialized = true;
186  return 0;
187 }
188 
189 // =====================================================================
190 // ---------------------------------------------------------------------
191 // ---------------------------------------------------------------------
192 // =====================================================================
193 /*
194  \fn ParseOptionsAndInitializeProjectors
195  \brief Parse respiratory/cardiac/involuntary patient motion options contained in the previously provided
196  strings. This function is called inside the Initialize() function.
197  \details Manage the options reading and initialize specific vDeformation
198  Options are a string containing first the name of the deformation,
199  then either a ':' and a configuration file specific to the deformation
200  - or - as many ',' as needed parameters for this deformation.
201  Specific pure virtual functions of the vDeformation are used to read parameters and initialize them.
202  \todo Some cleaning if we merge respiratory and cardiac motion objects
203  \return 0 if success, positive value otherwise
204 */
206 {
207  if (m_verbose>=2) Cout("oDeformationManager::ParseOptionsAndInitializeDeformations ..."<< endl);
208 
209  string deformation = "";
210  string list_options = "";
211  string file_options = "";
212 
213  // This is for the automatic initialization of the deformations
214  typedef vDeformation *(*maker_deformation) ();
215 
216  // Get deformation's list from addon manager
217  std::map <string,maker_deformation> list = sAddonManager::GetInstance()->mp_listOfDeformations;
218 
219  size_t colon, comma;
220 
221  // ---------------------------------------------------------------------------------------------------
222  // Manage deformation for respiratory motion
223  // ---------------------------------------------------------------------------------------------------
225  {
226  // ______________________________________________________________________________
227  // Get the deformation name in the options and isolate the real deformation's options
228 
229  // Search for a colon ":", this indicates that a configuration file is provided after the deformation name
230  colon = m_options.find_first_of(":");
231  comma = m_options.find_first_of(",");
232 
233  // Case 1: we have a colon
234  if (colon!=string::npos)
235  {
236  // Get the deformation name before the colon
237  deformation = m_options.substr(0,colon);
238  // Get the configuration file after the colon
239  file_options = m_options.substr(colon+1);
240  // List of options is empty
241  list_options = "";
242  }
243  // Case 2: we have a comma
244  else if (comma!=string::npos)
245  {
246  // Get the deformation name before the first comma
247  deformation = m_options.substr(0,comma);
248  // Get the list of options after the first comma
249  list_options = m_options.substr(comma+1);
250  // Configuration file is empty
251  file_options = "";
252  }
253  // Case 3: no colon and no comma (a single deformation name)
254  else
255  {
256  // Get the deformation name
257  deformation = m_options;
258  // Configuration file is empty
259  file_options = "";
260  // List of options is empty
261  list_options = "";
262  }
263 
264  // Create the deformation
265  if (list[deformation]) mp_Deformation = list[deformation]();
266  else
267  {
268  Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> Deformation '" << deformation << "' does not exist !" << endl);
270  return 1;
271  }
272  // Set parameters
276 
277  // Provide configuration file if any
278  if (file_options!="" && mp_Deformation->ReadAndCheckConfigurationFile(file_options))
279  {
280  Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while reading and checking respiratory deformation's configuration file !" << endl);
281  return 1;
282  }
283  // Provide options if any
284  if (list_options!="" && mp_Deformation->ReadAndCheckOptionsList(list_options))
285  {
286  Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while parsing and reading respiratory deformation's options !" << endl);
287  return 1;
288  }
289 
290  // Check parameters
292  {
293  Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while checking respiratory deformation parameters !" << endl);
294  return 1;
295  }
296  // Initialize the deformation
297  if (mp_Deformation->Initialize())
298  {
299  Cerr("***** oDeformationManager::ParseOptionsAndInitializeDeformations() -> A problem occured while initializing respiratory deformation !" << endl);
300  return 1;
301  }
302 
303  }
304 
305 
306  // Normal end
307  return 0;
308 }
309 
310 
311 
312 // =====================================================================
313 // ---------------------------------------------------------------------
314 // ---------------------------------------------------------------------
315 // =====================================================================
316 /*
317  \fn InstantiateImageForDeformation
318  \param oImageSpace* ap_Image : required to call oImageSpace instanciation functions
319  \brief If deformation is enabled, ask the Image Space to Instantiate the temporary backward image for deformation
320  If reconstruction is in histogram mode, the temporal sensitivity image is instanciated as well
321 */
323 {
325  {
326  // Verbose
327  if(m_verbose>=2) Cout("oDeformationManager::InstantiateImageForDeformation() -> Instantiate buffer images"<< endl);
328  // Instantiate buffer image for backward deformation
330  // In histogram mode, need another buffer image for sensitivity deformation
332  }
333 }
334 
335 // =====================================================================
336 // ---------------------------------------------------------------------
337 // ---------------------------------------------------------------------
338 // =====================================================================
339 /*
340  \fn DeallocateImageForDeformation
341  \param oImageSpace* ap_Image : required to call oImageSpace deallocation functions
342  \brief If deformation is enabled, ask the Image Space to free memory of the temporary backward image for deformation
343  If reconstruction is in histogram mode, the temporal sensitivity image is deallocated as well
344 */
346 {
348  {
349  // Verbose
350  if(m_verbose>=2) Cout("oDeformationManager::DeallocateImageForDeformation() -> Deallocate buffer images"<< endl);
351  // Deallocate backward buffer image
353  // In histogram mode, deallocate sensitivity buffer image
355  }
356 }
357 
358 // =====================================================================
359 // ---------------------------------------------------------------------
360 // ---------------------------------------------------------------------
361 // =====================================================================
362 /*
363  \fn InitImageForDeformation
364  \param oImageSpace* ap_Image : required to call oImageSpace initialization functions
365  \brief If deformation is enabled, ask the Image Space to initialize the temporary backward image for deformation
366  If reconstruction is in histogram mode, the temporal sensitivity image is initialized as well
367 */
369 {
371  {
372  if(m_verbose>=2) Cout("oDeformationManager::InitImageForDeformation() -> Initialize buffer images"<< endl);
373  ap_Image->InitBwdImageForDeformation();
375  }
376 }
377 
378 
379 
380 // =====================================================================
381 // ---------------------------------------------------------------------
382 // ---------------------------------------------------------------------
383 // =====================================================================
384 /*
385  \fn ApplyDeformationForSensitivityGeneration
386  \param oImageSpace* ap_Image : required to access oImageSpace image matrices
387  \param int a_defDirection : direction of the deformation (forward/backward)
388  //\param int a_defType : Nature of the motion (Respiratory/Cardiac/Involuntary Patient)
389  \param int fr
390  \param int rg
391  \param int cg
392  \brief Apply deformations during the list-mode sensitivity image generation
393  \details Perform deformation on the forward_image or the backward_image matrices corresponding to the current fr, rg, cg (if any), and depending on the defDirection.
394  \todo Some changes required if we merge respiratory/cardiac motion objects
395  \todo Check and implement patient motion
396  \return 0 if success, positive value otherwise
397 */
398 int oDeformationManager::ApplyDeformationForSensitivityGeneration(oImageSpace* ap_Image, int a_defDirection, int fr, int rg, int cg)
399 {
400  #ifdef CASTOR_DEBUG
401  if (!m_initialized)
402  {
403  Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration() -> Called while not initialized !" << endl);
404  Exit(EXIT_DEBUG);
405  }
406  #endif
407 
408  // Get the deformation index corresponding to the motion
409  int idx = -1;
410 
411 
412  // TODO : Ipat motion management
413 
415  idx = rg;
416  else if (m_UseDeformationCard)
417  idx = cg;
418  //else if (m_UseDeformationIPat) // TODO
419  // idx = TODO;
420  else
421  return 0; // no deformation to perform
422 
423 
424  // --- DEFORMATION MANAGEMENT ---
425 
426  if (m_verbose>=2)
427  {
428  Cout("oDeformationManager::ApplyDeformationForSensitivityGeneration()-> '" << endl);
429 
430  if(a_defDirection==BACKWARD_DEFORMATION)
431  Cout("BACKWARD Deformation for respiratory motion, for resp gate "<<rg << " and card gate " <<cg<<"." <<endl);
432  else
433  Cout("FORWARD Deformation for respiratory motion, for resp gate "<<rg << " and card gate " <<cg<<"." <<endl);
434  }
435 
436  if (mp_Deformation->PerformSensitivityDeformation(ap_Image, a_defDirection, idx, fr, rg, cg) )
437  {
438  Cerr("***** oDeformationManager::ApplyDeformationForSensitivityGeneration()-> An error occured while performing deformation for respiratory motion correction for the sensitivity image generation !" << endl);
439  return 1;
440  }
441 
442  return 0;
443 }
444 
445 
446 
447 // =====================================================================
448 // ---------------------------------------------------------------------
449 // ---------------------------------------------------------------------
450 // =====================================================================
451 /*
452  \fn PerformDeformation
453  \param oImageSpace* ap_Image : required to access oImageSpace image matrices
454  \brief Apply deformations during reconstruction
455  \details Call the eponym function for the deformation object,
456  as well as PerformHistoSensitivityDeformation() if data mode is histogram.
457  \todo why the check on frames ?
458  \return 0 if success, positive value otherwise
459 */
461 {
462  #ifdef CASTOR_DEBUG
463  if (!m_initialized)
464  {
465  Cerr("***** oDeformationManager::PerformDeformation() -> Called while not initialized !" << endl);
466  Exit(EXIT_DEBUG);
467  }
468  #endif
469 
470  int fr = mp_ID->GetCurrentTimeFrame(0);
471  int rimg = mp_ID->GetCurrentRespImage(0);
472  int cimg = mp_ID->GetCurrentCardImage(0);
473 
474  //fr = (fr<0) ? 0 : fr ;
475 
476  // Get the deformation index corresponding to the motion
477  int idx = -1;
478 
480  idx = mp_ID->GetCurrentRespGate(0);
481  else if (m_UseDeformationCard)
482  idx = mp_ID->GetCurrentCardGate(0);
483  else if (m_UseDeformationIPat)
484  idx = mp_ID->GetCurrentPMotionIndex(0);
485  else
486  return 0; // no deformation to perform
487 
488 
489  // --- DEFORMATION MANAGEMENT ---
490 
491  if (m_curMotIdx != idx)
492  {
493  if(m_verbose >=3) Cout("oDeformationManager::PerformDeformation-> Gate/motion subset # " << idx
494  << ", for resp image " <<rimg
495  << " and card image " <<cimg<<"."
496  << " Frame # " << fr << endl);
497  if(mp_Deformation->PerformDeformation(ap_Image, idx, fr, rimg, cimg) )
498  {
499  Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing image deformation during the reconstruction !" << endl);
500  return 1;
501  }
502 
503  // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM)
504  if(m_dataMode == MODE_HISTOGRAM )
505  if( mp_Deformation->PerformHistoSensitivityDeformation(ap_Image, idx, fr, rimg, cimg) )
506  {
507  Cerr("***** oDeformationManager::PerformDeformation()-> An error occured while performing sensitivity image deformation (histogram mode) during the reconstruction !" << endl);
508  return 1;
509  }
510 
511  m_curMotIdx = idx;
512  }
513 
514  return 0;
515 }
516 
517 
518 
519 
520 // =====================================================================
521 // ---------------------------------------------------------------------
522 // ---------------------------------------------------------------------
523 // =====================================================================
524 /*
525  \fn ApplyDeformationsToBackwardImage
526  \param oImageSpace* ap_Image : required to access oImageSpace image matrices
527  \brief Apply final backward deformations on the backward image
528  \details Call the eponym function for the deformation object, as well as >ApplyDeformationsToHistoSensitivityImage() if data mode is histogram.
529  Then reinitialize the temporary backup deformation images (the backward image, and the sensitivity image if data mode is histogram)
530  \return 0 if success, positive value otherwise
531 */
533 {
534  #ifdef CASTOR_DEBUG
535  if (!m_initialized)
536  {
537  Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage() -> Called while not initialized !" << endl);
538  Exit(EXIT_DEBUG);
539  }
540  #endif
541 
542  // Get the deformation index corresponding to the motion
543  int idx = -1;
544 
546  idx = mp_ID->GetCurrentRespGate(0);
547  else if (m_UseDeformationCard)
548  idx = mp_ID->GetCurrentCardGate(0);
549  else if (m_UseDeformationIPat)
550  idx = mp_ID->GetCurrentPMotionIndex(0);
551  else
552  return 0; // no deformation to perform
553 
554 
555  // --- DEFORMATION MANAGEMENT ---
556 
557  //if (m_UseDeformationResp)
558  //{
559  if(m_verbose >=3) Cout("oDeformationManager::ApplyDeformationsToBackwardImage-> Deformation for gate #" << idx<< "." <<endl);
561  {
562  Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation !" << endl);
563  return 1;
564  }
565 
566  // Perform deformation of the sensitivity image ((PET) MODE_HISTOGRAM)
569  {
570  Cerr("***** oDeformationManager::ApplyDeformationsToBackwardImage()-> An error occured while performing final backward image deformation of the sensitivity image !" << endl);
571  return 1;
572  }
573 
574  ap_Image->InitBwdImageForDeformation();
575 
577  ap_Image->InitSensImageForDeformation();
578 
579  return 0;
580 }
void SetVerbose(int a_verbose)
Set the verbose level.
Definition: vDeformation.hh:76
int ApplyDeformationForSensitivityGeneration(oImageSpace *ap_Image, int a_defDirection, int fr, int rg, int cg)
Apply deformations during the list-mode sensitivity image generation.
int GetCurrentCardImage(int a_th)
call the eponym function from the oDynamicDataManager object
void DeallocateBwdImageForDeformation()
Free memory for the buffer backward image required for image-based deformation.
Definition: oImageSpace.cc:794
int GetCurrentCardGate(int a_th)
call the eponym function from the oDynamicDataManager object
#define MODE_HISTOGRAM
Definition: vDataFile.hh:36
int PerformDeformation(oImageSpace *ap_Image)
Apply deformations during reconstruction.
oImageDimensionsAndQuantification * mp_ID
int ParseOptionsAndInitializeDeformations()
Parse respiratory/cardiac/involuntary patient motion options contained in the previously provided str...
int GetCurrentPMotionIndex(int a_th)
call the eponym function from the oDynamicDataManager object
void SetNbTransformations(int a_nbTransformations)
Set the number of transformation in the data to be performed on the dataset (equal to the number of g...
Definition: vDeformation.hh:84
void ShowHelpDeformation()
Show help about all implemented deformations.
virtual int ReadAndCheckConfigurationFile(const string &a_fileOptions)=0
This function is used to read options from a configuration file. It is pure virtual so must be impl...
void InitSensImageForDeformation()
Initialize the buffer sensitivity image dedicated to image-based deformation, if required (histogram ...
Declaration of class oDeformationManager.
virtual int PerformHistoSensitivityDeformation(oImageSpace *ap_Image, int a_defIdx, int fr, int rimg, int cimg)
Apply deformations on the sensitivity image during reconstruction in histogram mode.
void SetMotionType(int a_motionType)
Set the nature of motion correction (Deformation type macro)
virtual int Initialize()=0
This function is used to initialize specific data related to the child deformation model...
int ApplyDeformationsToBackwardImage(oImageSpace *ap_Image)
Apply final backward deformations on the backward image.
int GetCurrentRespGate(int a_th)
call the eponym function from the oDynamicDataManager object
virtual int CheckParameters()
This function is used to check parameters after the latter have been all set using Set functions...
Definition: vDeformation.cc:66
void Exit(int code)
virtual int ApplyDeformationsToBackwardImage(oImageSpace *ap_Image, int a_defIdx)
Apply backward transformation of the backward image to the reference position.
static sAddonManager * GetInstance()
#define DEF_DUAL_MOT
#define Cerr(MESSAGE)
void InitBwdImageForDeformation()
Initialize the buffer backward image dedicated to image-based deformation.
void InstantiateBwdImageForDeformation()
Memory allocation for the buffer backward image required for image-based deformation.
Definition: oImageSpace.cc:755
#define DEF_RESP_MOT
virtual int PerformDeformation(oImageSpace *ap_Image, int a_defIdx, int fr, int rimg, int cimg)
Apply deformations during reconstruction.
#define BACKWARD_DEFORMATION
Definition: vDeformation.hh:16
This is the mother class of image-based transformation class.
Definition: vDeformation.hh:44
#define DEF_CARD_MOT
void InstantiateImageForDeformation(oImageSpace *ap_Image)
If deformation is enabled, ask the Image Space to Instantiate the temporary backward image for deform...
int CheckParameters()
This function is used to check parameters after the latter have been all set using Set functions...
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Set the image dimensions in use.
Definition: vDeformation.hh:69
void InitImageForDeformation(oImageSpace *ap_Image)
If deformation is enabled, ask the Image Space to initialize the temporary backward image for deforma...
~oDeformationManager()
Destructor of oDeformationManager. Free memory from all allocated tabs.
std::map< string, maker_deformation > mp_listOfDeformations
#define DEF_IPAT_MOT
virtual int PerformSensitivityDeformation(oImageSpace *ap_Image, int a_defDirection, int a_defIdx, int fr, int rg, int cg)
Apply image deformations during sensitivity image generation for list-mode.
int Initialize()
Set the flags for the different motion types and instanciate/initialize deformation objects through t...
This class holds all the matrices in the image domain that can be used in the algorithm: image...
Definition: oImageSpace.hh:41
void DeallocateSensImageForDeformation()
Definition: oImageSpace.cc:859
#define EXIT_DEBUG
Definition: gVariables.hh:69
virtual int ReadAndCheckOptionsList(const string &a_listOptions)=0
This function is used to read parameters from a string. It is pure virtual so must be implemented b...
oDeformationManager()
Constructor of oDeformationManager. Simply set all data members to default values.
#define Cout(MESSAGE)
void InstantiateSensImageForDeformation()
Memory allocation for the buffer sensitivity image required for image-based deformation (only for PET...
Definition: oImageSpace.cc:830
virtual int ApplyDeformationsToHistoSensitivityImage(oImageSpace *ap_Image, int a_defIdx)
Apply backward transformations of the sensitivity image to the reference position (histogram mode) ...
vDeformation * mp_Deformation
void DeallocateImageForDeformation(oImageSpace *ap_Image)
If deformation is enabled, ask the Image Space to free memory of the temporary backward image for def...
int GetCurrentRespImage(int a_th)
call the eponym function from the oDynamicDataManager object
Declaration of class sAddonManager.
int GetCurrentTimeFrame(int a_th)
call the eponym function from the oDynamicDataManager object