CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
iOptimizerOneStepLate.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-2019 all CASToR contributors listed below:
18 
19  --> Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Thibaut MERLIN, Mael MILLARDET, Simon STUTE, Valentin VIELZEUF
20 
21 This is CASToR version 3.0.
22 */
23 
30 #include "iOptimizerOneStepLate.hh"
31 #include "sOutputManager.hh"
32 
33 // =====================================================================
34 // ---------------------------------------------------------------------
35 // ---------------------------------------------------------------------
36 // =====================================================================
37 
39 {
40  // ---------------------------
41  // Mandatory member parameters
42  // ---------------------------
43 
44  // Initial value at 1
45  m_initialValue = 1.;
46  // Only one backward image
48  // OSL accepts penalties, which must have a derivative order of 1 minimum
50  // OSL is compatible with listmode and histogram data
53  // OSL is only compatible with emission data
56 
57  // --------------------------
58  // Specific member parameters
59  // --------------------------
60 
65  m_displayWarningFlag = true;
66 }
67 
68 // =====================================================================
69 // ---------------------------------------------------------------------
70 // ---------------------------------------------------------------------
71 // =====================================================================
72 
74 {
75  // Delete the penalty image
76  // Note: there is no need to deallocate the images themselves as they are allocate using the
77  // miscellaneous image function from the image space, which automatically deals with
78  // memory deallocations.
80  {
81  // Loop over time basis functions
83  {
85  {
86  // Loop over respiratory basis functions
88  {
89  if (m4p_firstDerivativePenaltyImage[tbf][rbf])
90  {
91  free(m4p_firstDerivativePenaltyImage[tbf][rbf]);
92  }
93  }
95  }
96  }
98  }
99  // If the warning about negative sensitivity+penalty has been printed out, we print it again
100  // here at the end to be sure that the user is paying attention to it.
102  {
103  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
104  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
105  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
106  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
107  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
108  Cerr("!!!!! iOptimizerOneStepLate::Destructor() -> Several times, the update factor was not positive and was set to 1. !!!!!" << endl);
109  Cerr("!!!!! For convenience, it was advertised only the first time. But this may be a sign that the penalty strength !!!!!" << endl);
110  Cerr("!!!!! is too high for this approximative algorithm. It may also be due to voxels close to FOV extremities. Be !!!!!" << endl);
111  Cerr("!!!!! sure to double check your images ! !!!!!" << endl);
112  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
113  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
114  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
115  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
116  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
117  }
118 }
119 
120 // =====================================================================
121 // ---------------------------------------------------------------------
122 // ---------------------------------------------------------------------
123 // =====================================================================
124 
126 {
127  cout << "This optimizer is the One-Step-Late algorithm from P. J. Green, IEEE TMI, Mar 1990, vol. 9, pp. 84-93." << endl;
128  cout << "Subsets can be used as for OSEM. It accepts penalty terms that have a derivative order of at least one." << endl;
129  cout << "Without penalty, it is stricly equivalent to the MLEM algorithm." << endl;
130  cout << "It is numerically implemented in the multiplicative form (as opposed to the gradient form)." << endl;
131  cout << "The following options can be used (in this particular order when provided as a list):" << endl;
132  cout << " initial image value: to set the uniform voxel value for the initial image" << endl;
133  cout << " denominator threshold: to set the threshold of the data space denominator under which the ratio is set to 1" << endl;
134  cout << " minimum image update: to set the minimum of the image update factor under which it stays constant (0 or a negative value" << endl;
135  cout << " means no minimum thus allowing a 0 update)" << endl;
136  cout << " maximum image update: to set the maximum of the image update factor over which it stays constant (0 or a negative value means" << endl;
137  cout << " no maximum)" << endl;
138 }
139 
140 // =====================================================================
141 // ---------------------------------------------------------------------
142 // ---------------------------------------------------------------------
143 // =====================================================================
144 
145 int iOptimizerOneStepLate::ReadConfigurationFile(const string& a_configurationFile)
146 {
147  string key_word = "";
148  // Read the initial image value option
149  key_word = "initial image value";
150  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_initialValue, 1, KEYWORD_MANDATORY))
151  {
152  Cerr("***** iOptimizerOneStepLate::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
153  return 1;
154  }
155  // Read the denominator threshold option
156  key_word = "denominator threshold";
157  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_dataSpaceDenominatorThreshold, 1, KEYWORD_MANDATORY))
158  {
159  Cerr("***** iOptimizerOneStepLate::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
160  return 1;
161  }
162  // Read the minimum image update option
163  key_word = "minimum image update";
164  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_minimumImageUpdateFactor, 1, KEYWORD_MANDATORY))
165  {
166  Cerr("***** iOptimizerOneStepLate::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
167  return 1;
168  }
169  // Read the maximum image update option
170  key_word = "maximum image update";
171  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_maximumImageUpdateFactor, 1, KEYWORD_MANDATORY))
172  {
173  Cerr("***** iOptimizerOneStepLate::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
174  return 1;
175  }
176  // Normal end
177  return 0;
178 }
179 
180 // =====================================================================
181 // ---------------------------------------------------------------------
182 // ---------------------------------------------------------------------
183 // =====================================================================
184 
185 int iOptimizerOneStepLate::ReadOptionsList(const string& a_optionsList)
186 {
187  // There are 4 floating point variables as options
188  const int nb_options = 4;
189  FLTNB options[nb_options];
190  // Read them
191  if (ReadStringOption(a_optionsList, options, nb_options, ",", "OneStepLate configuration"))
192  {
193  Cerr("***** iOptimizerOneStepLate::ReadAndCheckConfigurationFile() -> Failed to correctly read the list of options !" << endl);
194  return 1;
195  }
196  // Affect options
197  m_initialValue = options[0];
198  m_dataSpaceDenominatorThreshold = options[1];
199  m_minimumImageUpdateFactor = options[2];
200  m_maximumImageUpdateFactor = options[3];
201  // Normal end
202  return 0;
203 }
204 
205 // =====================================================================
206 // ---------------------------------------------------------------------
207 // ---------------------------------------------------------------------
208 // =====================================================================
209 
211 {
212  // Check that initial image value is strictly positive
213  if (m_initialValue<=0.)
214  {
215  Cerr("***** iOptimizerOneStepLate->Initialize() -> Provided initial image value (" << m_initialValue << ") must be strictly positive !" << endl);
216  return 1;
217  }
218  // Check that denominator threshold value is strictly positive
220  {
221  Cerr("***** iOptimizerOneStepLate->Initialize() -> Provided data space denominator threshold (" << m_dataSpaceDenominatorThreshold << ") must be strictly positive !" << endl);
222  return 1;
223  }
224  // Check that maximum image update factor is higher than the minimum
226  {
227  Cerr("***** iOptimizerOneStepLate->Initialize() -> Provided minimum/maximum (" << m_minimumImageUpdateFactor << "/" << m_maximumImageUpdateFactor << " are inconsistent !" << endl);
228  return 1;
229  }
230  // Cannot deal with list-mode transmission data
232  {
233  Cerr("***** iOptimizerMLEM->CheckSpecificParameters() -> Cannot reconstruct list-mode transmission data !" << endl);
234  return 1;
235  }
236  // Normal end
237  return 0;
238 }
239 
240 // =====================================================================
241 // ---------------------------------------------------------------------
242 // ---------------------------------------------------------------------
243 // =====================================================================
244 
246 {
247  // Allocate and create the penalty image
249  // Loop over time basis functions
250  for (int tbf=0; tbf<mp_ImageDimensionsAndQuantification->GetNbTimeBasisFunctions(); tbf++)
251  {
253  // Loop over respiratory basis functions
254  for (int rbf=0; rbf<mp_ImageDimensionsAndQuantification->GetNbRespBasisFunctions(); rbf++)
255  {
257  // Loop over cardiac basis functions
258  for (int cbf=0; cbf<mp_ImageDimensionsAndQuantification->GetNbCardBasisFunctions(); cbf++)
259  {
260  // Get a pointer to a newly allocated image
261  m4p_firstDerivativePenaltyImage[tbf][rbf][cbf] = mp_ImageSpace -> AllocateMiscellaneousImage();
262  // Initialize to 0, in case the penalty is not used
263  for (INTNB v=0; v<mp_ImageDimensionsAndQuantification->GetNbVoxXYZ(); v++) m4p_firstDerivativePenaltyImage[tbf][rbf][cbf][v] = 0.;
264  }
265  }
266  }
267  // Force the display of the OSL warning (when sensitivity+penalty is negative or null in the image update step)
268  m_displayWarningFlag = true;
269  // Verbose
270  if (m_verbose>=2)
271  {
272  Cout("iOptimizerOneStepLate::Initialize() -> Use the OneStepLate optimizer" << endl);
273  if (m_verbose>=3)
274  {
275  Cout(" --> Initial image value: " << m_initialValue << endl);
276  Cout(" --> Data space denominator threshold: " << m_dataSpaceDenominatorThreshold << endl);
277  if (m_minimumImageUpdateFactor>0.) Cout(" --> Minimum image update factor: " << m_minimumImageUpdateFactor << endl);
278  else Cerr("!!!!! The minimum update value is not set, if using subsets, voxels could be trapped in 0 value causing some negative bias !" << endl);
279  if (m_maximumImageUpdateFactor>0.) Cout(" --> Maximum image update factor: " << m_maximumImageUpdateFactor << endl);
280  }
281  }
282  // Normal end
283  return 0;
284 }
285 
286 // =====================================================================
287 // ---------------------------------------------------------------------
288 // ---------------------------------------------------------------------
289 // =====================================================================
290 
292 {
293  // ==========================================================================================
294  // If no penalty, then exit (the penalty image term has been initialized to 0)
295  if (mp_Penalty==NULL) return 0;
296  // Set the number of threads
297  #ifdef CASTOR_OMP
299  #endif
300  // Verbose
301  if (m_verbose>=1) Cout("iOptimizerOneStepLate::PreImageUpdateSpecificStep() -> Compute penalty term" << endl);
302  // ==========================================================================================
303  // Global precomputation step if needed by the penalty
305  {
306  Cerr("***** iOptimizerOneStepLate::PreImageUpdateSpecificStep() -> A problem occurred while computing the penalty pre-processing step !" << endl);
307  return 1;
308  }
309  // ==========================================================================================
310  // Loop over time basis functions
311  for (int tbf=0; tbf<mp_ImageDimensionsAndQuantification->GetNbTimeBasisFunctions(); tbf++)
312  {
313  // Loop over respiratory basis functions
314  for (int rbf=0; rbf<mp_ImageDimensionsAndQuantification->GetNbRespBasisFunctions(); rbf++)
315  {
316  // Loop over cardiac basis functions
317  for (int cbf=0; cbf<mp_ImageDimensionsAndQuantification->GetNbCardBasisFunctions(); cbf++)
318  {
319  // In order to detect problems in the multi-threaded loop
320  bool problem = false;
321  // Voxel index
322  INTNB v;
323  // Multi-threading over voxels
324  #pragma omp parallel for private(v) schedule(guided)
326  {
327  // Get the thread index
328  int th = 0;
329  #ifdef CASTOR_OMP
330  th = omp_get_thread_num();
331  #endif
332  // Local precomputation step if needed by the penalty
333  if (mp_Penalty->LocalPreProcessingStep(tbf,rbf,cbf,v,th))
334  {
335  Cerr("***** iOptimizerOneStepLate::PreImageUpdateSpecificStep() -> A problem occurred while computing the penalty local pre-processing step for voxel " << v << " !" << endl);
336  problem = true;
337  }
338  // Compute the penalty term at first order
339  m4p_firstDerivativePenaltyImage[tbf][rbf][cbf][v] = mp_Penalty->ComputeFirstDerivative(tbf,rbf,cbf,v,th);
340  }
341  // Check for problems
342  if (problem)
343  {
344  Cerr("***** iOptimizerOneStepLate::PreImageUpdateSpecificStep() -> A problem occurred inside the multi-threaded loop, stop now !" << endl);
345  return 1;
346  }
347  }
348  }
349  }
350  // Normal end
351  return 0;
352 }
353 
354 // =====================================================================
355 // ---------------------------------------------------------------------
356 // ---------------------------------------------------------------------
357 // =====================================================================
359  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_blankValue,
360  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
361 {
362  // Line weight here is simply 1
363  *ap_weight = 1.;
364  // That's all
365  return 0;
366 }
367 // =====================================================================
368 // ---------------------------------------------------------------------
369 // ---------------------------------------------------------------------
370 // =====================================================================
371 
372 int iOptimizerOneStepLate::DataSpaceSpecificOperations( FLTNB a_data, FLTNB a_forwardModel, FLTNB* ap_backwardValues,
373  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_blankValue,
374  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
375 {
376  // Case for emission tomography
378  {
379  // Truncate data to 0 if negative
380  if (a_data<0.) a_data = 0.;
381  // If the foward model is too close to zero, then ignore this data (set to 1 and not 0 because this line is taken into account in the sensitivity)
382  if (a_forwardModel>m_dataSpaceDenominatorThreshold) *ap_backwardValues = a_data / a_forwardModel;
383  else *ap_backwardValues = 1.;
384  }
385  // Case for transmission tomography (equivalent of log-converted MLEM from Nuyts et al 1998)
386  else if (m_dataSpec==SPEC_TRANSMISSION)
387  {
388  // Subtract scatters
389  a_data -= a_additiveCorrections;
390  a_forwardModel -= a_additiveCorrections;
391  // Safely ignore this data (set backward value to 1 and return) in 2 different cases:
392  // - if data or model is inferior to 1
393  // - if data or model is higher than blank value
394  if (a_data<1. || a_forwardModel<1. || a_data>a_blankValue || a_forwardModel>a_blankValue)
395  {
396  *ap_backwardValues = 1.;
397  return 0;
398  }
399  // Log-convert the data and the model
400  a_data = log(a_blankValue/a_data);
401  a_forwardModel = log(a_blankValue/a_forwardModel);
402  // If the foward model is to close to zero, then ignore this data (set to 1 and not 0 because this line is taken into account in the sensitivity)
403  if (a_forwardModel>m_dataSpaceDenominatorThreshold) *ap_backwardValues = a_data / a_forwardModel;
404  else *ap_backwardValues = 1.;
405  }
406  // That's all
407  return 0;
408 }
409 
410 // =====================================================================
411 // ---------------------------------------------------------------------
412 // ---------------------------------------------------------------------
413 // =====================================================================
414 
415 int iOptimizerOneStepLate::ImageSpaceSpecificOperations( FLTNB a_currentImageValue, FLTNB* ap_newImageValue,
416  FLTNB a_sensitivity, FLTNB* ap_correctionValues,
417  INTNB a_voxel, int a_tbf, int a_rbf, int a_cbf )
418 {
419  // The update factor
420  FLTNB image_update_factor = 0.;
421  // Compute the sensitivity + penalty term (the penalty term is divided by the current number of subsets, for balance)
422  FLTNB sensitivity_plus_penalty = a_sensitivity + m4p_firstDerivativePenaltyImage[a_tbf][a_rbf][a_cbf][a_voxel]/(FLTNB)mp_nbSubsets[m_currentIteration];
423  // If negative update (which can be caused by the limitation of the OSL algorithm itself)
424  if (sensitivity_plus_penalty <= 0.)
425  {
426  // Do not update the image, so set the update factor to 1
427  image_update_factor = 1.;
429  {
430  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
431  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
432  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
433  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
434  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
435  Cerr("!!!!! iOptimizerOneStepLate::ImageSpaceSpecificOperations() -> The update factor was not positive ! It has been set to 1. !!!!!" << endl);
436  Cerr("!!!!! This may be a sign that the penalty strength is too high, but it may only be due to voxels close to FOV extremities. !!!!!" << endl);
437  Cerr("!!!!! For convenience, this warning will appear only for this update. Be careful about your results ! !!!!!" << endl);
438  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
439  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
440  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
441  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
442  Cerr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl);
443  // Display this warning only once, otherwise, it can be invasive (many voxels next to FOV extremitites can be affected, even with reasonable beta values)
444  m_displayWarningFlag = false;
445  }
446  }
447  // Otherwise, normal update
448  else
449  {
450  // Compute image update factor
451  image_update_factor = *ap_correctionValues / sensitivity_plus_penalty;
452  // Apply minimum image update factor
453  if ( m_minimumImageUpdateFactor > 0. && image_update_factor < m_minimumImageUpdateFactor ) image_update_factor = m_minimumImageUpdateFactor;
454  // Apply maximum image update factor
455  if ( m_maximumImageUpdateFactor > 0. && image_update_factor > m_maximumImageUpdateFactor ) image_update_factor = m_maximumImageUpdateFactor;
456  }
457  // Update image
458  *ap_newImageValue = a_currentImageValue * image_update_factor;
459  // End
460  return 0;
461 }
462 
463 // =====================================================================
464 // ---------------------------------------------------------------------
465 // ---------------------------------------------------------------------
466 // =====================================================================
int m_requiredPenaltyDerivativesOrder
Definition: vOptimizer.hh:697
#define MODE_LIST
Definition: vDataFile.hh:56
int GetNbCardBasisFunctions()
Get the number of cardiac basis functions.
Declaration of class iOptimizerOneStepLate.
#define FLTNB
Definition: gVariables.hh:81
void ShowHelpSpecific()
A function used to show help about the child optimizer.
FLTNB m_initialValue
Definition: vOptimizer.hh:663
bool m_listmodeCompatibility
Definition: vOptimizer.hh:664
int SensitivitySpecificOperations(FLTNB a_data, FLTNB a_forwardModel, FLTNB *ap_weight, FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_blankValue, FLTNB a_quantificationFactor, oProjectionLine *ap_Line)
This function compute the weight associated to the provided event (for sensitivity computation) ...
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
Definition: vOptimizer.hh:669
virtual int LocalPreProcessingStep(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
A public function computing a local pre-processing step for the penalty.
Definition: vPenalty.cc:149
int GetNbTimeBasisFunctions()
Get the number of time basis functions.
int ImageSpaceSpecificOperations(FLTNB a_currentImageValue, FLTNB *ap_newImageValue, FLTNB a_sensitivity, FLTNB *ap_correctionValues, INTNB a_voxel, int a_tbf=-1, int a_rbf=-1, int a_cbf=-1)
This function perform the image update step specific to the optimizer.
int m_dataMode
Definition: vOptimizer.hh:671
int m_dataSpec
Definition: vOptimizer.hh:673
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
#define Cerr(MESSAGE)
bool m_emissionCompatibility
Definition: vOptimizer.hh:666
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
int m_nbBackwardImages
Definition: vOptimizer.hh:659
virtual int GlobalPreProcessingStep()
A public function computing a global pre-processing step for the penalty.
Definition: vPenalty.cc:138
int ReadDataASCIIFile(const string &a_file, const string &a_keyword, T *ap_return, int a_nbElts, bool a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter a...
Definition: gOptions.cc:129
~iOptimizerOneStepLate()
The destructor of iOptimizerOneStepLate.
bool m_histogramCompatibility
Definition: vOptimizer.hh:665
#define KEYWORD_MANDATORY
Definition: gOptions.hh:47
#define SPEC_TRANSMISSION
Definition: vDataFile.hh:92
#define INTNB
Definition: gVariables.hh:92
bool m_transmissionCompatibility
Definition: vOptimizer.hh:667
This class is designed to generically described any iterative optimizer.
Definition: vOptimizer.hh:59
This class is designed to manage and store system matrix elements associated to a vEvent...
vPenalty * mp_Penalty
Definition: vOptimizer.hh:698
int DataSpaceSpecificOperations(FLTNB a_data, FLTNB a_forwardModel, FLTNB *ap_backwardValues, FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_blankValue, FLTNB a_quantificationFactor, oProjectionLine *ap_Line)
This function performs the data space operations specific to the optimizer (computes the values to be...
int m_currentIteration
Definition: vOptimizer.hh:678
Declaration of class sOutputManager.
oImageSpace * mp_ImageSpace
Definition: vOptimizer.hh:670
int GetNbThreadsForImageComputation()
Get the number of threads used for image operations.
INTNB GetNbVoxXYZ()
Get the total number of voxels.
#define SPEC_EMISSION
Definition: vDataFile.hh:90
iOptimizerOneStepLate()
The constructor of iOptimizerOneStepLate.
int * mp_nbSubsets
Definition: vOptimizer.hh:677
#define Cout(MESSAGE)
int InitializeSpecific()
This function is used to initialize specific stuff to the child optimizer.
int ReadStringOption(const string &a_input, T *ap_return, int a_nbElts, const string &sep, const string &a_option)
Parse the &#39;a_input&#39; string corresponding to the &#39;a_option&#39; into &#39;a_nbElts&#39; elements, using the &#39;sep&#39; separator. The results are returned in the templated &#39;ap_return&#39; dynamic templated array. Call "ConvertFromString()" to perform the correct conversion depending on the type of the data to convert.
Definition: gOptions.cc:50
int GetNbRespBasisFunctions()
Get the number of respiratory basis functions.
virtual FLTNB ComputeFirstDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)=0
A public function computing the derivative of the penalty.
int PreImageUpdateSpecificStep()
A private function used to compute the penalty term of the OneStepLate algorithm. ...
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child optimizer.