CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
iOptimizerOriginalAML.cc
Go to the documentation of this file.
1 
2 /*
3  Implementation of class iOptimizerOriginalAML
4 
5  - separators: X
6  - doxygen: X
7  - default initialization: X
8  - CASTOR_DEBUG:
9  - CASTOR_VERBOSE:
10 */
11 
18 #include "iOptimizerOriginalAML.hh"
19 #include "sOutputManager.hh"
20 
21 // =====================================================================
22 // ---------------------------------------------------------------------
23 // ---------------------------------------------------------------------
24 // =====================================================================
25 
27 {
28  // ---------------------------
29  // Mandatory member parameters
30  // ---------------------------
31 
32  // Initial value at 1
33  m_initialValue = 1.;
34  // Only one backward image for AML
36  // AML does not accept penalties
37  //m_penaltyEnergyFunctionDerivativesOrder = 0;
38  // AML is only compatible with histogram data
41 
42  // --------------------------
43  // Specific member parameters
44  // --------------------------
45 
46  // Threshold applied to the denominator of the data space operation to avoid to high ratios
48  // This is the AML bound parameter
49  m_bound = 1.;
50 }
51 
52 // =====================================================================
53 // ---------------------------------------------------------------------
54 // ---------------------------------------------------------------------
55 // =====================================================================
56 
58 {
59 }
60 
61 // =====================================================================
62 // ---------------------------------------------------------------------
63 // ---------------------------------------------------------------------
64 // =====================================================================
65 
67 {
68  cout << "This optimizer is the AML algorithm derived from the AB-EMML of C. Byrne, Inverse Problems, 1998, vol. 14, pp. 1455-67." << endl;
69  cout << "The bound B is taken to infinity, so only the bound A can be parameterized." << endl;
70  cout << "This bound must be quantitative (same unit as the reconstructed image)." << endl;
71  cout << "It is provided as a single value and thus assuming a uniform bound." << endl;
72  cout << "Subsets can be used." << endl;
73  cout << "With a negative or null bound, this algorithm implements equation 6 of A. Rahmim et al, Phys. Med. Biol., 2012, vol. 57, pp. 733-55." << endl;
74  cout << "If a positive bound is provided, then we suppose that the bound A is taken to minus infinity. In that case, this algorithm implements" << endl;
75  cout << "equation 22 of K. Van Slambrouck et al, IEEE TMI, Jan 2015, vol. 34, pp. 126-136." << endl;
76  cout << "The following options can be used (in this particular order when provided as a list):" << endl;
77  cout << " initial image value: to set the uniform voxel value for the initial image" << endl;
78  cout << " denominator threshold: to set the threshold of the data space denominator under which the ratio is set to 1" << endl;
79  cout << " bound: to set the bound parameter that shift the Poisson law (quantitative, negative or null for standard AML and positive for infinite AML)." << endl;
80 }
81 
82 // =====================================================================
83 // ---------------------------------------------------------------------
84 // ---------------------------------------------------------------------
85 // =====================================================================
86 
87 int iOptimizerOriginalAML::ReadConfigurationFile(const string& a_configurationFile)
88 {
89  string key_word = "";
90  // Read the initial image value option
91  key_word = "initial image value";
92  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_initialValue, 1, KEYWORD_MANDATORY))
93  {
94  Cerr("***** iOptimizerOriginalAML::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
95  return 1;
96  }
97  // Read the denominator threshold option
98  key_word = "denominator threshold";
99  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_dataSpaceDenominatorThreshold, 1, KEYWORD_MANDATORY))
100  {
101  Cerr("***** iOptimizerOriginalAML::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
102  return 1;
103  }
104  // Read the bound value
105  key_word = "bound";
106  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_bound, 1, KEYWORD_MANDATORY))
107  {
108  Cerr("***** iOptimizerOriginalAML::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
109  return 1;
110  }
111  // Normal end
112  return 0;
113 }
114 
115 // =====================================================================
116 // ---------------------------------------------------------------------
117 // ---------------------------------------------------------------------
118 // =====================================================================
119 
120 int iOptimizerOriginalAML::ReadOptionsList(const string& a_optionsList)
121 {
122  // There are 3 floating point variables as options
123  FLTNB options[3];
124  // Read them
125  if (ReadStringOption(a_optionsList, options, 3, ",", "AML configuration"))
126  {
127  Cerr("***** iOptimizerOriginalAML::ReadAndCheckConfigurationFile() -> Failed to correctly read the list of options !" << endl);
128  return 1;
129  }
130  // Affect options
131  m_initialValue = options[0];
132  m_dataSpaceDenominatorThreshold = options[1];
133  m_bound = options[2];
134  // Normal end
135  return 0;
136 }
137 
138 // =====================================================================
139 // ---------------------------------------------------------------------
140 // ---------------------------------------------------------------------
141 // =====================================================================
142 
144 {
145  // Check that denominator threshold value is strictly positive
147  {
148  Cerr("***** iOptimizerOriginalAML->Initialize() -> Provided data space denominator threshold (" << m_dataSpaceDenominatorThreshold << ") must be strictly positive !" << endl);
149  return 1;
150  }
151  // If a negative or null bound is provided (standard AML), then check that the initial image value is above the provided bound
152  if (m_bound<=0. && m_initialValue<m_bound)
153  {
154  Cerr("***** iOptimizerOriginalAML::Initialize() -> The initial image value (" << m_initialValue << ") must be higher than or equal to the provided bound value ("
155  << m_bound << ") !" << endl);
156  return 1;
157  }
158  // Normal end
159  return 0;
160 }
161 
162 // =====================================================================
163 // ---------------------------------------------------------------------
164 // ---------------------------------------------------------------------
165 // =====================================================================
166 
168 {
169  // Verbose
170  if (m_verbose>=2)
171  {
172  Cout("iOptimizerOriginalAML::Initialize() -> Use the AML optimizer" << endl);
173  if (m_verbose>=3)
174  {
175  Cout(" --> Initial image value: " << m_initialValue << endl);
176  Cout(" --> Data space denominator threshold: " << m_dataSpaceDenominatorThreshold << endl);
177  if (m_bound<=0.) Cout(" --> Bound value: " << m_bound << endl);
178  else Cout(" --> Bound value taken to minus infinity" << endl);
179  }
180  }
181  // Normal end
182  return 0;
183 }
184 
185 // =====================================================================
186 // ---------------------------------------------------------------------
187 // ---------------------------------------------------------------------
188 // =====================================================================
189 
191  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections,
192  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
193 {
194  // Line weight here is a simply 1
195  *ap_weight = 1.;
196  // That's all
197  return 0;
198 }
199 
200 // =====================================================================
201 // ---------------------------------------------------------------------
202 // ---------------------------------------------------------------------
203 // =====================================================================
204 
205 int iOptimizerOriginalAML::DataSpaceSpecificOperations( FLTNB a_data, FLTNB a_forwardModel, FLTNB* ap_backwardValues,
206  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections,
207  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
208 {
209  // Implementation of the standard AML (bound is negative or null)
210  if (m_bound<=0.)
211  {
212  // Compute the bound projection
213  FLTNB shift = ForwardProject(ap_Line) * m_bound;
214  // Compute denominator (this is the shifted model)
215  FLTNB denominator = a_forwardModel - shift;
216  // If the denominator is to close to zero, then ignore this data
217  if (denominator<=m_dataSpaceDenominatorThreshold) *ap_backwardValues = 1.;
218  // Otherwise, do it normally
219  else
220  {
221  // Compute numerator (this is the shifted data)
222  FLTNB numerator = a_data - shift;
223  // Truncate to 0 if negative
224  if (numerator<0.) *ap_backwardValues = 0.;
225  // Otherwise, update backward values
226  else *ap_backwardValues = numerator / denominator;
227  }
228  }
229  // Implementation of AML with the bound taken to minus infinity (when the provided bound is positive)
230  else
231  {
232  *ap_backwardValues = (a_data - a_forwardModel) / ForwardProject(ap_Line);
233  }
234  // That's all
235  return 0;
236 }
237 
238 // =====================================================================
239 // ---------------------------------------------------------------------
240 // ---------------------------------------------------------------------
241 // =====================================================================
242 
243 int iOptimizerOriginalAML::ImageSpaceSpecificOperations( FLTNB a_currentImageValue, FLTNB* ap_newImageValue,
244  FLTNB a_sensitivity, FLTNB* ap_correctionValues )
245 {
246  // Compute image update factor
247  FLTNB image_update_factor = *ap_correctionValues / a_sensitivity;
248  // Update image for the standard AML (bound is negative or null)
249  if (m_bound<=0.) *ap_newImageValue = m_bound + (a_currentImageValue - m_bound) * image_update_factor;
250  // Update image for a bound taken to minus infinity (when the provided bound is positive)
251  else *ap_newImageValue = a_currentImageValue + image_update_factor;
252  // End
253  return 0;
254 }
255 
256 // =====================================================================
257 // ---------------------------------------------------------------------
258 // ---------------------------------------------------------------------
259 // =====================================================================
#define FLTNB
Definition: gVariables.hh:55
FLTNB m_initialValue
Definition: vOptimizer.hh:587
bool m_listmodeCompatibility
Definition: vOptimizer.hh:588
iOptimizerOriginalAML()
The constructor of iOptimizerOriginalAML.
int ImageSpaceSpecificOperations(FLTNB a_currentImageValue, FLTNB *ap_newImageValue, FLTNB a_sensitivity, FLTNB *ap_correctionValues)
This function perform the image update step specific to the optimizer.
FLTNB ForwardProject(oProjectionLine *ap_Line, FLTNB *ap_image=NULL)
A function used to forward project the provided image (or 1 if NULL), based on the provided oProjecti...
Definition: vOptimizer.cc:913
int DataSpaceSpecificOperations(FLTNB a_data, FLTNB a_forwardModel, FLTNB *ap_backwardValues, FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_quantificationFactor, oProjectionLine *ap_Line)
This function performs the data space operations specific to the optimizer (computes the values to be...
Declaration of class iOptimizerOriginalAML.
#define Cerr(MESSAGE)
int m_nbBackwardImages
Definition: vOptimizer.hh:583
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:111
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
void ShowHelpSpecific()
A function used to show help about the child optimizer.
bool m_histogramCompatibility
Definition: vOptimizer.hh:589
#define KEYWORD_MANDATORY
Definition: gOptions.hh:25
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child optimizer.
This class is designed to generically described any iterative optimizer.
Definition: vOptimizer.hh:36
This class is designed to manage and store system matrix elements associated to a vEvent...
~iOptimizerOriginalAML()
The destructor of iOptimizerOriginalAML.
int InitializeSpecific()
This function is used to initialize specific stuff to the child optimizer.
Declaration of class sOutputManager.
int SensitivitySpecificOperations(FLTNB a_data, FLTNB a_forwardModel, FLTNB *ap_weight, FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections, FLTNB a_quantificationFactor, oProjectionLine *ap_Line)
This function compute the weight associated to the provided event (for sensitivity computation) ...
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
#define Cout(MESSAGE)
int ReadStringOption(const string &a_input, T *ap_return, int a_nbElts, const string &sep, const string &a_option)
Parse the 'a_input' string corresponding to the 'a_option' into 'a_nbElts' elements, using the 'sep' separator. The results are returned in the templated 'ap_return' dynamic templated array. Call "ConvertFromString()" to perform the correct conversion depending on the type of the data to convert.
Definition: gOptions.cc:50