9 #include "sOutputManager.hh" 134 cout <<
"This optimizer is the A-Penalized Preconditioned Gradient algorithm (A-PPGML) from M. Millardet et al, IEEE TRPMS," << endl;
135 cout <<
"2021, vol. 6, pp. 629-640. It is based on the same idea as AML, which is allowing for negative values in the image" << endl;
136 cout <<
"by shifting an algorithm enforcing positive values. APPGML can be seen as a shifted version of PPGML with a lower" << endl;
137 cout <<
"bound A. This algorithm allows for negative image values in case the provided bound is also negative. The shift is" << endl;
138 cout <<
"applied uniformly in the whole image unless a shift image is provided. This shift image allows to customize the" << endl;
139 cout <<
"shift value applied in each voxel. The algorithm can also use penalized reconstruction because it is based on PPGML." << endl;
140 cout <<
"The following options can be used (in this particular order when provided as a list):" << endl;
141 cout <<
" initial image value: to set the uniform voxel value for the initial image" << endl;
142 cout <<
" denominator threshold: to set the threshold of the data space denominator under which the ratio is set to 1" << endl;
143 cout <<
" minimum image update: to set the minimum of the image update factor under which it stays constant (0 or a negative value" << endl;
144 cout <<
" means no minimum thus allowing a 0 update)" << endl;
145 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;
146 cout <<
" no maximum)" << endl;
147 cout <<
" bound: to set the lower bound value to apply the shift (must be negative to authorize negative values)" << endl;
148 cout <<
" shift image path: provide an image used to applied non-uniform shift within the reconstructed image. The values of the" << endl;
149 cout <<
" shift image weight the shift applied to every voxel (0 means the voxel is not shifted, 1 means the" << endl;
150 cout <<
" voxel is shifted by the bound, and t means the voxel is shifted by t times the bound). If no shift" << endl;
151 cout <<
" image is provided, the shift is equal to the bound and is applied uniformly on the whole image" << endl;
161 string key_word =
"";
165 key_word =
"initial image value";
168 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
172 key_word =
"denominator threshold";
175 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
179 key_word =
"minimum image update";
182 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
186 key_word =
"maximum image update";
189 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
196 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
200 key_word =
"region image path";
203 Cerr(
"***** iOptimizerAPPGML::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
218 Cerr(
"***** iOptimizerAPPGML::ReadOptionsList() -> Options can be specified only using a configuration file !" << endl);
232 Cerr(
"***** iOptimizerAPPGML->CheckSpecificParameters() -> Provided initial image value (" <<
m_initialValue <<
") must be strictly positive !" << endl);
238 Cerr(
"***** iOptimizerAPPGML->CheckSpecificParameters() -> Provided data space denominator threshold (" <<
m_dataSpaceDenominatorThreshold <<
") must be strictly positive !" << endl);
250 Cerr(
"***** iOptimizerAPPGML::CheckSpecificParameters() -> The initial image value (" <<
m_initialValue <<
") must be higher than or equal to the provided bound value (" <<
m_bound <<
") !" << endl);
336 Cerr(
"***** iOptimizerAPPGML::InitializeSpecific() -> Error reading interfile image '" <<
m_regionImagePath <<
"' !" << endl);
341 Cerr(
"***** iOptimizerAPPGML::InitializeSpecific() -> Error reading interfile image '" <<
m_regionImagePath <<
"' !" << endl);
348 Cout(
"iOptimizerAPPGML::InitializeSpecific() -> Use the APPGML optimizer" << endl);
354 else Cerr(
"!!!!! The minimum update value is not set, if using subsets, voxels could be trapped in 0 value causing some negative bias !" << endl);
358 else Cout(
" --> Uniform shift across the whole image" << endl);
378 Cerr(
"***** iOptimizerAPPGML::PreDataUpdateSpecificStep() -> A problem occurred while applying image convolver to region to apply shift !" << endl);
400 #pragma omp parallel for private(v) schedule(guided) 423 FLTNB a_multiplicativeCorrections,
FLTNB a_additiveCorrections,
FLTNB a_blankValue,
438 FLTNB a_multiplicativeCorrections,
FLTNB a_additiveCorrections,
FLTNB a_blankValue,
447 if (a_data<0.) a_data = 0.;
450 FLTNB numerator = a_data - a_forwardModel;
454 *ap_backwardValues = numerator / denominator;
478 if (
m_verbose>=1)
Cout(
"iOptimizerAPPGML::PreImageUpdateSpecificStep() -> Compute penalty term" << endl);
483 Cerr(
"***** iOptimizerAPPGML::PreImageUpdateSpecificStep() -> A problem occurred while computing the penalty pre-processing step !" << endl);
497 bool problem =
false;
501 #pragma omp parallel for private(v) schedule(guided) 507 th = omp_get_thread_num();
512 Cerr(
"***** iOptimizerAPPGML::PreImageUpdateSpecificStep() -> A problem occurred while computing the penalty local pre-processing step for voxel " << v <<
" !" << endl);
522 Cerr(
"***** iOptimizerAPPGML::PreImageUpdateSpecificStep() -> A problem occurred inside the multi-threaded loop, stop now !" << endl);
539 FLTNB a_sensitivity,
FLTNB* ap_correctionValues,
INTNB a_voxel,
int tbf,
int rbf,
int cbf )
547 image_update_factor = 1. + image_update_factor / a_sensitivity;
553 *ap_newImageValue = a_currentImageValue * image_update_factor;
555 if (!isfinite(*ap_newImageValue)) *ap_newImageValue = a_currentImageValue;
FLTNB * mp_specificRegionOfInterestConvolved
FLTNB * mp_specificRegionOfInterest
int m_requiredPenaltyDerivativesOrder
int GetNbCardBasisFunctions()
Get the number of cardiac basis functions.
#define INTF_LERP_ENABLED
bool m_listmodeCompatibility
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
int InitializeSpecific()
This function is used to initialize specific stuff to the child optimizer.
int ImageSpaceSpecificOperations(FLTNB a_currentImageValue, FLTNB *ap_newImageValue, FLTNB a_sensitivity, FLTNB *ap_correctionValues, INTNB a_voxel, int tbf=-1, int rbf=-1, int cbf=-1)
This function perform the image update step specific to the optimizer.
int PreImageUpdateSpecificStep()
A private function used to compute the penalty term update adaptive alpha of the ADMM algorithm...
int ApplyConvolution(FLTNB *ap_image)
A function that simply calls the eponym function from the vImageConvolver.
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...
virtual int LocalPreProcessingStep(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
int GetNbTimeBasisFunctions()
Get the number of time basis functions.
FLTNB ForwardProject(oProjectionLine *ap_Line, FLTNB *ap_image=NULL)
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
FLTNB m_minimumImageUpdateFactor
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
FLTNB **** m4p_imageNotShifted
int IntfReadImage(const string &a_pathToHeaderFile, FLTNB *ap_ImgMatrix, oImageDimensionsAndQuantification *ap_ID, int vb, bool a_lerpFlag)
Main function dedicated to Interfile 3D image loading.
bool m_emissionCompatibility
virtual int GlobalPreProcessingStep()
A public function computing a global pre-processing step for the penalty.
bool m_histogramCompatibility
FLTNB **** m4p_secondDerivativePenaltyImage
void ShowHelpSpecific()
A function used to show help about the child optimizer.
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) ...
FLTNB m_dataSpaceDenominatorThreshold
oImageSpace * mp_ImageSpace
#define KEYWORD_MANDATORY
bool m_transmissionCompatibility
This class is designed to generically described any iterative optimizer.
This class is designed to manage and store system matrix elements associated to a vEvent...
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child optimizer.
Declaration of class iOptimizerAPPGML.
int GetNbThreadsForImageComputation()
Get the number of threads used for image operations.
INTNB GetNbVoxXYZ()
Get the total number of voxels.
virtual FLTNB ComputeSecondDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)=0
virtual FLTNB ComputeFirstDerivative(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)=0
iOptimizerAPPGML()
The constructor of iOptimizerAPPGML.
virtual int PreDataUpdateSpecificStep()
A private function used to compute some norms for the image update.
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...
int GetNbRespBasisFunctions()
Get the number of respiratory basis functions.
oImageConvolverManager * mp_ImageConvolverManager
FLTNB **** m4p_firstDerivativePenaltyImage
~iOptimizerAPPGML()
The destructor of iOptimizerAPPGML.
FLTNB m_maximumImageUpdateFactor