241 else cout <<
"This optimizer is a total non-sense, not compatible with histogram nor list-mode data !!!" << endl;
246 else cout <<
"This optimizer is a total non-sense, not compatible with emission nor transmission data !!!" << endl;
259 Cerr(
"***** vOptimizer::CheckParameters() -> oImageDimensionsAndQuantification is null !" << endl);
265 Cerr(
"***** vOptimizer::CheckParameters() -> oImageSpace is null !" << endl);
271 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data mode provided !" << endl);
277 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data type provided !" << endl);
283 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data specificity provided (emission or transmission) !" << endl);
289 Cerr(
"***** vOptimizer::CheckParameters() -> Verbose level is negative !" << endl);
295 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with listmode data !" << endl);
301 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with histogram data !" << endl);
307 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with emission data !" << endl);
313 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with transmission data !" << endl);
319 Cerr(
"***** vOptimizer::CheckParameters() -> Asked to compute FOMs in the data-space whereas the verbose is not set !" << endl);
325 Cerr(
"***** vOptimizer::CheckParameters() -> Asked to compute image update statistics whereas the verbose is not set !" << endl);
331 Cerr(
"***** vOptimizer::CheckParameters() -> Computing FOMs in the data-space with list-mode data is not possible !" << endl);
337 Cerr(
"***** vOptimizer::CheckParameters() -> A problem occurred while checking parameters specific to the optimizer module !" << endl);
418 Cerr(
"***** vOptimizer::Initialize() -> A problem occurred while initializing stuff specific to the optimizer module !" << endl);
456 Cerr(
"***** vOptimizer::PreDataUpdateStep() -> A problem occurred while applying the specific pre-data-update step of the optimizer module !" << endl);
484 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred while applying the specific post-data-update step of the optimizer module !" << endl);
526 bool problem =
false;
530 #pragma omp parallel for private(v) schedule(guided) 536 th = omp_get_thread_num();
541 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred while precomputing the local step of the penalty for voxel " << v <<
" !" << endl);
555 m4p_FOMPenalty[fr][rg][cg][th] += time_basis_coef * resp_basis_coef * card_basis_coef * penalty_value;
563 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred in the multi-threaded loop for the penalty, stop now !" << endl);
581 Cout(
"vOptimizer::PreImageUpdateStep() -> Optimizer figures-of-merit related to the objective function" << endl);
603 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Number of data channels used in optimization: " <<
m4p_FOMNbBins[fr][rg][cg][0] << endl);
604 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Mean number of data counts per channel: " <<
m4p_FOMNbData[fr][rg][cg][0] << endl);
607 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Penalty: " <<
m4p_FOMPenalty[fr][rg][cg][0] << endl);
610 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> RMSE: " <<
m4p_FOMRMSE[fr][rg][cg][0]
615 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Log-likelihood: " <<
m4p_FOMLogLikelihood[fr][rg][cg][0] << endl);
616 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> RMSE: " <<
m4p_FOMRMSE[fr][rg][cg][0] << endl);
643 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
662 if (time_basis_coef==0.)
continue;
668 if (resp_basis_coef==0.)
continue;
674 if (card_basis_coef==0.)
continue;
676 FLTNB global_basis_coef = time_basis_coef * resp_basis_coef * card_basis_coef;
722 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
735 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
758 Cerr(
"***** vOptimizer::DataStep3BackwardProjectSensitivity() -> A problem occurred while performing the sensitivity specific operations !" << endl);
775 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
788 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
809 Cerr(
"***** vOptimizer::DataStep5ComputeCorrections() -> A problem occurred while performing specific data space operations !" << endl);
824 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
837 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
849 if (time_basis_coef==0.)
continue;
855 if (resp_basis_coef==0.)
continue;
861 if (card_basis_coef==0.)
continue;
863 FLTNB global_basis_coef = time_basis_coef * resp_basis_coef * card_basis_coef;
892 int a_timeFrame,
int a_respGate,
int a_cardGate,
902 if (model>1.e-10)
m4p_FOMLogLikelihood[a_timeFrame][a_respGate][a_cardGate][a_thread] += data*log(model)-model;
904 m4p_FOMRMSE[a_timeFrame][a_respGate][a_cardGate][a_thread] += (data-model)*(data-model);
906 m4p_FOMNbBins[a_timeFrame][a_respGate][a_cardGate][a_thread]++;
908 m4p_FOMNbData[a_timeFrame][a_respGate][a_cardGate][a_thread] += data;
922 if (
m_verbose>=3)
Cout(
"vOptimizer::UpdateVisitedVoxels() -> Tick visited voxels based on sensitivity" << endl);
969 else Cout(spaces_tbf <<
"--> Time basis function: " << tbf+1 << endl);
978 else Cout(spaces_tbf << spaces_rbf <<
"--> Respiratory basis function: " << rbf+1 << endl);
987 else Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
"--> Cardiac basis function: " << cbf+1 << endl);
1010 #pragma omp parallel for private(v) schedule(guided) 1016 th = omp_get_thread_num();
1021 if (sensitivity<=0.)
continue;
1045 Cerr(
"***** vOptimizer::ImageUpdateStep() -> A problem occurred while performing image space specific operations of the optimizer !" << endl);
1068 if (error)
return 1;
1089 mp_imageStatMean[0] = (count1*mp_imageStatMean[0] + count2*mp_imageStatMean[th]) / count12;
1093 mp_correctionStatMean[0] = (count1*mp_correctionStatMean[0] + count2*mp_correctionStatMean[th]) / count12;
1099 Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
" --> Image update step " 1102 Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
" --> New image estimate" 1151 int a_timeBasisFunction,
int a_respBasisFunction,
int a_cardBasisFunction,
1155 FLTNB sensitivity = 0.;
1161 if (time_basis_coef==0.)
continue;
1167 if (resp_basis_coef==0.)
continue;
1173 if (card_basis_coef==0.)
continue;
1175 sensitivity += a4p_sensitivityMatrix[fr][rg][cg][a_voxel] *
1176 time_basis_coef * resp_basis_coef * card_basis_coef;
FLTNB **** m4p_forwardImage
int m_requiredPenaltyDerivativesOrder
virtual FLTNB GetBlankValue()
This is a pure virtual function implemented in the child classes.
FLTNB ForwardProjectWithSPECTAttenuation(FLTNB *ap_attenuation, FLTNB *ap_image=NULL)
Forward projects the provided image for the current TOF bin with an inner loop on the attenuation (fo...
int GetNbCardBasisFunctions()
Get the number of cardiac basis functions.
virtual FLTNB GetAdditiveCorrections(int a_bin)=0
Pure virtual function implemented in the child classes.
bool m_listmodeCompatibility
virtual int DataStep2Optional(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function which does nothing but being virtual.
HPFLTNB **** m4p_FOMNbData
FLTNB GetRespBasisCoefficient(int a_respBasisFunction, int a_respGate)
Get the respiratory basis coefficients for the provided respiratory gate and basis function...
void SetCurrentTOFBin(int a_TOFBin)
This function is used to set the current TOF bin that is used.
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
FLTNB ComputeSensitivity(FLTNB ****a4p_sensitivityImage, int a_timeBasisFunction, int a_respBasisFunction, int a_cardBasisFunction, int a_voxel)
A function used to compute the sensitivity of a given voxel and a given set of dynamic basis function...
virtual int ImageUpdateStep()
A public function used to perform the image update step of the optimizer.
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.
virtual int CheckSpecificParameters()=0
A private function used to check the parameters settings specific to the child optimizer.
int GetNbTimeBasisFunctions()
Get the number of time basis functions.
vOptimizer()
The constructor of vOptimizer.
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...
virtual FLTNB GetMultiplicativeCorrections()=0
This is a pure virtual function implemented in the child classes.
int GetThreadNumber()
This function is used to get the thread number associated to this line.
uint64_t **** m4p_FOMNbBins
HPFLTNB * mp_correctionStatMean
int PreDataUpdateStep()
A public function used to do stuff that need to be done at the beginning of a subset (before the data...
virtual 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)=0
A private function used to compute the correction term in the data space from the provided data...
bool GetRespStaticFlag()
Get the respiratory static flag that says if the reconstruction has only one respiratory gate or not...
FLTNB * mp_visitedVoxelsImage
virtual int DataStep6Optional(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function which does nothing but being virtual.
INTNB * mp_imageStatNbVox
void BackwardProject(FLTNB *ap_image, FLTNB a_value)
Simply backward projects the provided value inside the provided image, for the current TOF bin...
bool m_needGlobalSensitivity
FLTNB ****** m6p_backwardImage
bool GetCardStaticFlag()
Get the cardiac static flag that says if the reconstruction has only one cardiac gate or not...
bool m_emissionCompatibility
void BackwardProjectWithSPECTAttenuation(FLTNB *ap_attenuation, FLTNB *ap_image, FLTNB a_value)
Backward project the provided value inside the provided image with an inner loop on the attenuation (...
virtual int DataStep3BackwardProjectSensitivity(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function used to back-project the sensitivity terms for the provided event.
virtual int InitializeSpecific()=0
A private function used to initialize everything specific to the child optimizer. ...
int GetNbThreadsMax()
Get the maximum between the number of threads used for projections and image operations.
void BackwardProject(oProjectionLine *ap_Line, FLTNB *ap_image, FLTNB a_value)
A function used to backward project the provided value into the provided image, based on the provided...
virtual 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)=0
A private function used to update the image value from the provided data.
virtual FLTNB GetEventValue(int a_bin)=0
Pure virtual function implemented in the child classes.
virtual int DataStep1ForwardProjectModel(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function used to compute the model: forward projection of the provided event.
Declaration of class vOptimizer.
FLTNB ** m2p_attenuationImage
bool m_histogramCompatibility
bool m_optimizerImageStatFlag
FLTNB GetQuantificationFactor(int a_bed, int a_frame, int a_respGate, int a_cardGate)
Get the quantification factor corresponding to the provided bed, frame, respiratory and cardiac gates...
virtual int DataStep8ComputeFOM(oProjectionLine *ap_Line, vEvent *ap_Event, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function used to update the computation of figures-of-merit in the data space.
HPFLTNB **** m4p_FOMPenalty
FLTNB GetTimeBasisCoefficient(int a_timeBasisFunction, int a_timeFrame)
Get the time basis coefficients for the provided frame and basis function.
bool GetTimeStaticFlag()
Get the time static flag that says if the reconstruction has only one frame or not.
HPFLTNB * mp_imageStatVariance
#define SPEC_TRANSMISSION
virtual ~vOptimizer()
The destructor of vOptimizer.
virtual int PreImageUpdateSpecificStep()
A private function used to perform any step required by the child optimizer, between the loop on even...
int PreImageUpdateStep()
A public function used to do stuff that need to be done between the loop over events and the image up...
bool m_transmissionCompatibility
This class is designed to manage and store system matrix elements associated to a vEvent...
int GetNbCardGates()
Get the number of cardiac gates.
virtual FLTNB ComputePenaltyValue(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)=0
A public function computing the value of the penalty function.
int Initialize()
A public function used to initialize the optimizer.
virtual int DataStep4Optional(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function which does nothing but being virtual.
oImageSpace * mp_ImageSpace
Mother class for the Event objects.
int GetNbThreadsForImageComputation()
Get the number of threads used for image operations.
int GetNbTimeFrames()
Get the number of time frames.
FLTNB ForwardProject(FLTNB *ap_image=NULL)
Simply forward projects the provided image if not null, or else 1, for the current TOF bin...
INTNB GetNbVoxXYZ()
Get the total number of voxels.
virtual int DataStep5ComputeCorrections(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function used to compute the correction terms in the data space, for the provided event...
int GetNbTOFBins()
This function is used to get the number of TOF bins in use.
HPFLTNB * mp_imageStatMean
int GetNbThreadsForProjection()
Get the number of threads used for projections.
int UpdateVisitedVoxels()
A public function used to update the 'visited' voxels after each subset.
int GetNbRespGates()
Get the number of respiratory gates.
virtual void ShowHelpSpecific()=0
A function used to show help about the child module.
FLTNB GetFrameDurationInSec(int a_bed, int a_frame)
Get the frame duration for the given bed, in seconds as a FLTNB.
virtual 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)=0
A private function used to compute the sensitivity weight associated to the provided data...
virtual int DataStep7BackwardProjectCorrections(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
A public function used to back-project the correction terms into the backward correction image...
void ShowHelp()
A function used to show help about the optimizer.
HPFLTNB * mp_correctionStatVariance
FLTNB ** m2p_forwardValues
int GetNbRespBasisFunctions()
Get the number of respiratory basis functions.
FLTNB ***** m5p_sensitivity
HPFLTNB **** m4p_FOMLogLikelihood
FLTNB *** m3p_backwardValues
int CheckParameters()
A public function used to check the parameters settings.
virtual int PreDataUpdateSpecificStep()
A private function used to perform any step required by the child optimizer, before the loop on event...
FLTNB GetCardBasisCoefficient(int a_cardBasisFunction, int a_cardGate)
Get the cardiac basis coefficients for the provided cardiac gate and basis function.