CASToR  2.0
Tomographic Reconstruction (PET/SPECT/CT)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
oDynamicModelManager.cc
Go to the documentation of this file.
1 /*
2 This file is part of CASToR.
3 
4  CASToR is free software: you can redistribute it and/or modify it under the
5  terms of the GNU General Public License as published by the Free Software
6  Foundation, either version 3 of the License, or (at your option) any later
7  version.
8 
9  CASToR is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  details.
13 
14  You should have received a copy of the GNU General Public License along with
15  CASToR (in file GNU_GPL.TXT). If not, see <http://www.gnu.org/licenses/>.
16 
17 Copyright 2017-2018 all CASToR contributors listed below:
18 
19  --> current contributors: Thibaut MERLIN, Simon STUTE, Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Mael MILLARDET
20  --> past contributors: Valentin VIELZEUF
21 
22 This is CASToR version 2.0.
23 */
24 
31 #include "oDynamicModelManager.hh"
32 #include "sAddonManager.hh"
33 
34 // =====================================================================
35 // ---------------------------------------------------------------------
36 // ---------------------------------------------------------------------
37 // =====================================================================
38 /*
39  \fn oDynamicModelManager
40  \brief Constructor of oDynamicModelManager. Simply set all data members to default values.
41 */
43 {
44  // Image dimensions
45  mp_ID = NULL;
46  // Options for each model type
47  m_options = "";
48 
49  // Model object and associated bool
50  mp_DynamicModel = NULL;
51  m_UseModel = false;
52 
53  // Verbosity
54  m_verbose = -1;
55  m_checked = false;
56  m_initialized = false;
57 }
58 
59 // =====================================================================
60 // ---------------------------------------------------------------------
61 // ---------------------------------------------------------------------
62 // =====================================================================
63 /*
64  \fn ~oDynamicModelManager
65  \brief Destructor of oDynamicModelManager. Free memory from all allocated tabs.
66 */
68 {
69  // Delete model objects
70  if (mp_DynamicModel) delete mp_DynamicModel;
71 }
72 
73 // =====================================================================
74 // ---------------------------------------------------------------------
75 // ---------------------------------------------------------------------
76 // =====================================================================
77 /*
78  \fn CheckParameters
79  \brief This function is used to check parameters after the latter
80  have been all set using Set functions.
81  \return 0 if success, positive value otherwise.
82 */
84 {
85  #ifdef CASTOR_VERBOSE
86  if (m_verbose>=2) Cout("oDynamicModelManager::CheckParameters() ..."<< endl);
87  #endif
88 
89  // Check image dimensions
90  if (mp_ID==NULL)
91  {
92  Cerr("***** oDynamicModelManager::CheckParameters() -> No image dimensions provided !" << endl);
93  return 1;
94  }
95  // Check verbosity
96  if (m_verbose<0)
97  {
98  Cerr("***** oDynamicModelManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
99  return 1;
100  }
101 
102  // Normal end
103  m_checked = true;
104  return 0;
105 }
106 
107 // =====================================================================
108 // ---------------------------------------------------------------------
109 // ---------------------------------------------------------------------
110 // =====================================================================
111 /*
112  \fn Initialize
113  \brief Set the dynamic model flag and instanciate/initialize model objects
114  through the ParseOptionsAndInitializeDeformations() private function.
115  \return 0 if success, positive value otherwise.
116 */
118 {
119  // Forbid initialization without check
120  if (!m_checked)
121  {
122  Cerr("***** oDynamicModelManager::Initialize() -> Must call CheckParameters() before Initialize() !" << endl);
123  return 1;
124  }
125 
126  // Check options
127  if (m_options=="")
128  {
129  m_initialized = true;
130  m_UseModel = false;
131  return 0;
132  }
133 
134  // We have a model
135  m_UseModel = true;
136 
137  // Verbose
138  if (m_verbose>=1) Cout("oDynamicModelManager::Initialize() -> Initialize models" << endl);
139 
140  // Parse model options and initialize them
142  {
143  Cerr("***** oDynamicModelManager::Initialize() -> A problem occured while parsing model options and initializing them !" << endl);
144  return 1;
145  }
146 
147  // Normal end
148  m_initialized = true;
149  return 0;
150 }
151 
152 // =====================================================================
153 // ---------------------------------------------------------------------
154 // ---------------------------------------------------------------------
155 // =====================================================================
156 /*
157  \fn ParseOptionsAndInitializeProjectors
158  \brief Parse dynamic model options contained in the previously provided
159  strings. This function is called inside the Initialize() function.
160  \details Manage the options reading and initialize specific vDynamicModel
161  Options are a string containing first the name of the model,
162  then either a ':' and a configuration file specific to the model
163  - or - as many ',' as needed parameters for this model.
164  Specific pure virtual functions of the vDynamicModel are used to read parameters and initialize them.
165  \return 0 if success, positive value otherwise
166 */
168 {
169  #ifdef CASTOR_VERBOSE
170  if (m_verbose>=3) Cout("oDynamicModelManager::ParseOptionsAndInitializeModel ..."<< endl);
171  #endif
172 
173  string dynamic_model = "";
174  string list_options = "";
175  string file_options = "";
176 
177  // This is for the automatic initialization of the models
178  typedef vDynamicModel *(*maker_dynamic_model) ();
179 
180  // Get model's list from addon manager
181  std::map <string,maker_dynamic_model> list = sAddonManager::GetInstance()->mp_listOfDynamicModels;
182 
183  size_t colon, comma;
184 
185  // ---------------------------------------------------------------------------------------------------
186  // Manage model for respiratory motion
187  // ---------------------------------------------------------------------------------------------------
188 
189  // First, check if we have dynamic data
190  if (mp_ID->GetNbTimeFrames() <= 1 &&
191  mp_ID->GetNbRespGates() <= 1 &&
192  mp_ID->GetNbCardGates() <= 1)
193  {
194  Cerr("***** oDynamicModelManager::CheckParameters() -> Dynamic model should be used with more than one time frame/dynamic gate !" << endl);
195  return 1;
196  }
197 
198  // ______________________________________________________________________________
199  // Get the model name in the options and isolate the real model's options
200 
201  // Search for a colon ":", this indicates that a configuration file is provided after the model name
202  colon = m_options.find_first_of(":");
203  comma = m_options.find_first_of(",");
204 
205  // Case 1: we have a colon
206  if (colon!=string::npos)
207  {
208  // Get the model name before the colon
209  dynamic_model = m_options.substr(0,colon);
210  // Get the configuration file after the colon
211  file_options = m_options.substr(colon+1);
212  // List of options is empty
213  list_options = "";
214  }
215  // Case 2: we have a comma
216  else if (comma!=string::npos)
217  {
218  // Get the model name before the first comma
219  dynamic_model = m_options.substr(0,comma);
220  // Get the list of options after the first comma
221  list_options = m_options.substr(comma+1);
222  // Configuration file is empty
223  file_options = "";
224  }
225  // Case 3: no colon and no comma (a single model name)
226  else
227  {
228  // Get the model name
229  dynamic_model = m_options;
230  // Configuration file is empty
231  file_options = "";
232  // List of options is empty
233  list_options = "";
234  }
235 
236  // Create the model
237  if (list[dynamic_model]) mp_DynamicModel = list[dynamic_model]();
238  else
239  {
240  Cerr("***** oDynamicModelManager::ParseOptionsAndInitializeModel() -> Model '" << dynamic_model << "' does not exist !" << endl);
242  return 1;
243  }
246  // Provide configuration file if any
247  if (file_options!="" && mp_DynamicModel->ReadAndCheckConfigurationFile(file_options))
248  {
249  Cerr("***** oDynamicModelManager::ParseOptionsAndInitializeModel() -> A problem occured while reading and checking frame dynamic model's configuration file !" << endl);
250  return 1;
251  }
252  // Provide options if any
253  if (list_options!="" && mp_DynamicModel->ReadAndCheckOptionsList(list_options))
254  {
255  Cerr("***** oDynamicModelManager::ParseOptionsAndInitializeModel() -> A problem occured while parsing and reading frame dynamic model's options !" << endl);
256  return 1;
257  }
258  // Check parameters
260  {
261  Cerr("***** oDynamicModelManager::ParseOptionsAndInitializeModel() -> A problem occured while checking frame dynamic model parameters !" << endl);
262  return 1;
263  }
264  // Initialize the model
266  {
267  Cerr("***** oDynamicModelManager::ParseOptionsAndInitializeModel() -> A problem occured while initializing frame dynamic model !" << endl);
268  return 1;
269  }
270 
271  // Normal end
272  return 0;
273 }
274 
275 // =====================================================================
276 // ---------------------------------------------------------------------
277 // ---------------------------------------------------------------------
278 // =====================================================================
279 /*
280  \fn ApplyDynamicModel
281  \param ap_ImageS : pointer to the ImageSpace
282  \param a_iteration : index of the actual iteration
283  \param a_subset : index of the actual subset
284  \brief Call successively EstimateModelParameters() ans EstimateImageWithModel()
285  functions of the dynamic model object is 'm_UseModel' is on.
286  \return 0 if success, positive value otherwise
287 */
288 int oDynamicModelManager::ApplyDynamicModel(oImageSpace* ap_ImageS, int a_iteration, int a_subset)
289 {
290  #ifdef CASTOR_DEBUG
291  if (!m_initialized)
292  {
293  Cerr("***** oDynamicModelManager::ApplyDynamicModel() -> Called while not initialized !" << endl);
294  Exit(EXIT_DEBUG);
295  }
296  #endif
297 
298  if (m_UseModel)
299  {
300  // Verbose
301  if(m_verbose>=2) Cout("oDynamicModelManager::ApplyDynamicModel ..."<< endl);
302 
303  // Estimate model parameters
304  if( mp_DynamicModel->EstimateModelParameters(ap_ImageS, a_iteration, a_subset) )
305  {
306  Cerr("***** oDynamicModelManager::StepPostProcessInsideSubsetLoop() -> A problem occured while applying dynamic model to current estimate images !" << endl);
307  return 1;
308  }
309 
310  // Generate the serie of dynamic images using the model parameters
311  if( mp_DynamicModel->EstimateImageWithModel(ap_ImageS, a_iteration, a_subset) )
312  {
313  Cerr("***** oDynamicModelManager::StepPostProcessInsideSubsetLoop() -> A problem occured while applying dynamic model to current estimate images !" << endl);
314  return 1;
315  }
316  }
317 
318  return 0;
319 }
320 
321 // =====================================================================
322 // ---------------------------------------------------------------------
323 // ---------------------------------------------------------------------
324 // =====================================================================
325 /*
326  \fn SaveParametricImages
327  \param a_iteration : current iteration index
328  \param a_subset : current number of subsets (or -1 by default)
329  \brief Call SaveCoeffImages() function of the dynamic model object is
330  'm_UseModel' is on, in order to save any parameter image
331  \return 0 if success, positive value otherwise
332 */
333 int oDynamicModelManager::SaveParametricImages(int a_iteration, int a_subset)
334 {
335  if (m_UseModel)
336  {
337  // Verbose
338  if(m_verbose>=2) Cout("oDynamicModelManager::SaveParametricImages ..."<< endl);
339 
340  // Write output parametric images if required
342 
343  // Apply Masking if required
345  {
346  Cerr("***** oDynamicModelManager::SaveParametricImages() -> A problem occured while trying to apply FOV masking on parametric images !" << endl);
347  return 1;
348  }
349 
350  // Save images
351  if (mp_DynamicModel->SaveParametricImages(a_iteration, a_subset))
352  {
353  Cerr("***** oDynamicModelManager::SaveParametricImages() -> A problem occured while trying to save image coefficients !" << endl);
354  return 1;
355  }
356  }
357  return 0;
358 }
359 
360 // =====================================================================
361 // ---------------------------------------------------------------------
362 // ---------------------------------------------------------------------
363 // =====================================================================
Declaration of class oDynamicModelManager.
virtual int CheckParameters()
This function is used to check parameters after the latter have been all set using Set functions...
void ShowHelpDynamicModel()
Show help about all implemented dynamic models.
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Set the image dimensions in use.
This is the mother class of dynamic model classes.
virtual int ApplyOutputFOVMaskingOnParametricImages()
Mask the outside of the transaxial FOV based on the m_fovOutPercent.
virtual int ReadAndCheckOptionsList(string a_listOptions)=0
This function is used to read parameters from a string. It is pure virtual so must be implemented b...
oDynamicModelManager()
Constructor of oDynamicModelManager. Simply set all data members to default values.
int Initialize()
Set the dynamic model flag and instanciate/initialize model objects through the ParseOptionsAndInitia...
virtual int Initialize()=0
This function is used to initialize specific data related to the child deformation model...
void Exit(int code)
static sAddonManager * GetInstance()
int ParseOptionsAndInitializeModel()
Parse dynamic model options contained in the previously provided strings. This function is called ins...
#define Cerr(MESSAGE)
virtual int ReadAndCheckConfigurationFile(string a_fileOptions)=0
This function is used to read options from a configuration file. It is pure virtual so must be impl...
int SaveParametricImages(int a_iteration, int a_subset=-1)
Call SaveParametricImages() function of the dynamic model object is 'm_UseModel' is on...
oImageDimensionsAndQuantification * mp_ID
void SetVerbose(int a_verbose)
Set the verbose level.
vDynamicModel * mp_DynamicModel
int CheckParameters()
This function is used to check parameters after the latter have been all set using Set functions...
int GetNbCardGates()
Get the number of cardiac gates.
std::map< string, maker_dynamic_model > mp_listOfDynamicModels
This class holds all the matrices in the image domain that can be used in the algorithm: image...
Definition: oImageSpace.hh:61
int GetNbTimeFrames()
Get the number of time frames.
#define EXIT_DEBUG
Definition: gVariables.hh:97
virtual int EstimateImageWithModel(oImageSpace *ap_Image, int a_ite, int a_sset)=0
This function is pure virtual so must be implemented by children. It is used to fit the dynamic mod...
int GetNbRespGates()
Get the number of respiratory gates.
#define Cout(MESSAGE)
virtual void ComputeOutputParImage()
Compute output image using the m2p_parametricImages matrix Store the result in the m2p_outputParImage...
~oDynamicModelManager()
Destructor of oDynamicModelManager. Free memory from all allocated tabs.
virtual int EstimateModelParameters(oImageSpace *ap_Image, int a_ite, int a_sset)=0
This function is pure virtual so must be implemented by children. It can be used to estimate any te...
virtual int SaveParametricImages(int a_iteration, int a_subset=-1)
This function is pure virtual so must be implemented by children Call SaveParametricImages() functi...
int ApplyDynamicModel(oImageSpace *ap_ImageS, int a_iteration, int a_subset)
Declaration of class sAddonManager.