CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
iOptimizerNEGML.cc
Go to the documentation of this file.
1 
2 /*
3  Implementation of class iOptimizerNEGML
4 
5  - separators: X
6  - doxygen: X
7  - default initialization: X
8  - CASTOR_DEBUG:
9  - CASTOR_VERBOSE:
10 */
11 
18 #include "iOptimizerNEGML.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 NEGML
36  // NEGML does not accept penalties
37  //m_penaltyEnergyFunctionDerivativesOrder = 0;
38  // NEGML is only compatible with histogram data
41 
42  // --------------------------
43  // Specific member parameters
44  // --------------------------
45 
46  // This is the NEGML psi parameter
47  m_psi = -1.;
48 }
49 
50 // =====================================================================
51 // ---------------------------------------------------------------------
52 // ---------------------------------------------------------------------
53 // =====================================================================
54 
56 {
57 }
58 
59 // =====================================================================
60 // ---------------------------------------------------------------------
61 // ---------------------------------------------------------------------
62 // =====================================================================
63 
65 {
66  cout << "This optimizer is the NEGML algorithm from K. Van Slambrouck et al, IEEE TMI, Jan 2015, vol. 34, pp. 126-136." << endl;
67  cout << "Subsets can be used. This implementation only consider the psi parameter, but not the alpha image design parameter" << endl;
68  cout << "which is supposed to be 1 for all voxels. It implements equation 17 of the reference paper." << endl;
69  cout << "The following options can be used (in this particular order when provided as a list):" << endl;
70  cout << " initial image value: to set the uniform voxel value for the initial image" << endl;
71  cout << " psi: to set the psi parameter that sets the transition from Poisson to Gaussian statistics (must be positive)." << endl;
72  cout << " (if set to 0, then it is taken to infinity and implements equation 21 in the reference paper)." << endl;
73 }
74 
75 // =====================================================================
76 // ---------------------------------------------------------------------
77 // ---------------------------------------------------------------------
78 // =====================================================================
79 
80 int iOptimizerNEGML::ReadConfigurationFile(const string& a_configurationFile)
81 {
82  string key_word = "";
83  // Read the initial image value option
84  key_word = "initial image value";
85  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_initialValue, 1, KEYWORD_MANDATORY))
86  {
87  Cerr("***** iOptimizerNEGML::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
88  return 1;
89  }
90  // Read the psi value option
91  key_word = "psi";
92  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_psi, 1, KEYWORD_MANDATORY))
93  {
94  Cerr("***** iOptimizerNEGML::ReadAndCheckConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
95  return 1;
96  }
97  // Normal end
98  return 0;
99 }
100 
101 // =====================================================================
102 // ---------------------------------------------------------------------
103 // ---------------------------------------------------------------------
104 // =====================================================================
105 
106 int iOptimizerNEGML::ReadOptionsList(const string& a_optionsList)
107 {
108  // There are 2 floating point variables as options
109  FLTNB options[2];
110  // Read them
111  if (ReadStringOption(a_optionsList, options, 2, ",", "NEGML configuration"))
112  {
113  Cerr("***** iOptimizerNEGML::ReadAndCheckConfigurationFile() -> Failed to correctly read the list of options !" << endl);
114  return 1;
115  }
116  // Affect options
117  m_initialValue = options[0];
118  m_psi = options[1];
119  // Normal end
120  return 0;
121 }
122 
123 // =====================================================================
124 // ---------------------------------------------------------------------
125 // ---------------------------------------------------------------------
126 // =====================================================================
127 
129 {
130  // Check that the psi value is positive (a zero value means we take psi to infinity)
131  if (m_psi<0.)
132  {
133  Cerr("***** iOptimizerNEGML::Initialize() -> Provided psi value (" << m_psi << ") must be positive !" << endl);
134  return 1;
135  }
136  // Normal end
137  return 0;
138 }
139 
140 // =====================================================================
141 // ---------------------------------------------------------------------
142 // ---------------------------------------------------------------------
143 // =====================================================================
144 
146 {
147  // Verbose
148  if (m_verbose>=2)
149  {
150  Cout("iOptimizerNEGML::Initialize() -> Use the NEGML optimizer" << endl);
151  if (m_verbose>=3)
152  {
153  Cout(" --> Initial image value: " << m_initialValue << endl);
154  if (m_psi>0.) Cout(" --> Psi: " << m_psi << endl);
155  else if (m_psi==0.) Cout(" --> Psi taken to infinity" << endl);
156  }
157  }
158  // Normal end
159  return 0;
160 }
161 
162 // =====================================================================
163 // ---------------------------------------------------------------------
164 // ---------------------------------------------------------------------
165 // =====================================================================
166 
167 int iOptimizerNEGML::SensitivitySpecificOperations( FLTNB a_data, FLTNB a_forwardModel, FLTNB* ap_weight,
168  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections,
169  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
170 {
171  // With psi taken to infinity, the weight is the forward projection of a uniform 1 image
172  if (m_psi==0.) *ap_weight = ForwardProject(ap_Line);
173  // Line weight here is a forward projection of alpha image divided by the max between psi and the forward model
174  else *ap_weight = ForwardProject(ap_Line) / max( m_psi , a_forwardModel );
175  // That's all
176  return 0;
177 }
178 
179 // =====================================================================
180 // ---------------------------------------------------------------------
181 // ---------------------------------------------------------------------
182 // =====================================================================
183 
184 int iOptimizerNEGML::DataSpaceSpecificOperations( FLTNB a_data, FLTNB a_forwardModel, FLTNB* ap_backwardValues,
185  FLTNB a_multiplicativeCorrections, FLTNB a_additiveCorrections,
186  FLTNB a_quantificationFactor, oProjectionLine* ap_Line )
187 {
188  // Compute numerator
189  FLTNB numerator = a_data - a_forwardModel;
190  // Compute denominator that will be strictly positive
191  FLTNB denominator = 1.;
192  if (m_psi>0.) denominator = max( m_psi , a_forwardModel );
193  // Update backward values
194  *ap_backwardValues = numerator / denominator;
195  // That's all
196  return 0;
197 }
198 
199 // =====================================================================
200 // ---------------------------------------------------------------------
201 // ---------------------------------------------------------------------
202 // =====================================================================
203 
204 int iOptimizerNEGML::ImageSpaceSpecificOperations( FLTNB a_currentImageValue, FLTNB* ap_newImageValue,
205  FLTNB a_sensitivity, FLTNB* ap_correctionValues )
206 {
207  // Compute image update factor
208  FLTNB image_update_factor = *ap_correctionValues / a_sensitivity;
209  // Update image
210  *ap_newImageValue = a_currentImageValue + image_update_factor;
211  // End
212  return 0;
213 }
214 
215 // =====================================================================
216 // ---------------------------------------------------------------------
217 // ---------------------------------------------------------------------
218 // =====================================================================
#define FLTNB
Definition: gVariables.hh:55
FLTNB m_initialValue
Definition: vOptimizer.hh:587
bool m_listmodeCompatibility
Definition: vOptimizer.hh:588
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
#define Cerr(MESSAGE)
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.
int m_nbBackwardImages
Definition: vOptimizer.hh:583
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...
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.
bool m_histogramCompatibility
Definition: vOptimizer.hh:589
#define KEYWORD_MANDATORY
Definition: gOptions.hh:25
Declaration of class iOptimizerNEGML.
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...
Declaration of class sOutputManager.
void ShowHelpSpecific()
A function used to show help about the child optimizer.
iOptimizerNEGML()
The constructor of iOptimizerNEGML.
~iOptimizerNEGML()
The destructor of iOptimizerNEGML.
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
#define Cout(MESSAGE)
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 InitializeSpecific()
This function is used to initialize specific stuff to the child optimizer.
int CheckSpecificParameters()
A private function used to check the parameters settings specific 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 '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