8 #include "vOptimizer.hh" 219 else cout <<
"This optimizer is a total non-sense, not compatible with histogram nor list-mode data !!!" << endl;
224 else cout <<
"This optimizer is a total non-sense, not compatible with emission nor transmission data !!!" << endl;
237 Cerr(
"***** vOptimizer::CheckParameters() -> oImageDimensionsAndQuantification is null !" << endl);
243 Cerr(
"***** vOptimizer::CheckParameters() -> oImageSpace is null !" << endl);
249 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data mode provided !" << endl);
255 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data type provided !" << endl);
261 Cerr(
"***** vOptimizer::CheckParameters() -> No or meaningless data specificity provided (emission or transmission) !" << endl);
267 Cerr(
"***** vOptimizer::CheckParameters() -> Verbose level is negative !" << endl);
273 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with listmode data !" << endl);
279 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with histogram data !" << endl);
285 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with emission data !" << endl);
291 Cerr(
"***** vOptimizer::CheckParameters() -> The selected optimizer is not compatible with transmission data !" << endl);
297 Cerr(
"***** vOptimizer::CheckParameters() -> Asked to compute FOMs in the data-space whereas the verbose is not set !" << endl);
303 Cerr(
"***** vOptimizer::CheckParameters() -> Asked to compute image update statistics whereas the verbose is not set !" << endl);
309 Cerr(
"***** vOptimizer::CheckParameters() -> Computing FOMs in the data-space with list-mode data is not possible !" << endl);
315 Cerr(
"***** vOptimizer::CheckParameters() -> A problem occurred while checking parameters specific to the optimizer module !" << endl);
396 Cerr(
"***** vOptimizer::Initialize() -> A problem occurred while initializing stuff specific to the optimizer module !" << endl);
434 Cerr(
"***** vOptimizer::PreDataUpdateStep() -> A problem occurred while applying the specific pre-data-update step of the optimizer module !" << endl);
462 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred while applying the specific post-data-update step of the optimizer module !" << endl);
504 bool problem =
false;
508 #pragma omp parallel for private(v) schedule(guided) 514 th = omp_get_thread_num();
519 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred while precomputing the local step of the penalty for voxel " << v <<
" !" << endl);
533 m4p_FOMPenalty[fr][rg][cg][th] += time_basis_coef * resp_basis_coef * card_basis_coef * penalty_value;
541 Cerr(
"***** vOptimizer::PreImageUpdateStep() -> A problem occurred in the multi-threaded loop for the penalty, stop now !" << endl);
559 Cout(
"vOptimizer::PreImageUpdateStep() -> Optimizer figures-of-merit related to the objective function" << endl);
581 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Number of data channels used in optimization: " <<
m4p_FOMNbBins[fr][rg][cg][0] << endl);
582 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Mean number of data counts per channel: " <<
m4p_FOMNbData[fr][rg][cg][0] << endl);
585 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Penalty: " <<
m4p_FOMPenalty[fr][rg][cg][0] << endl);
588 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> RMSE: " <<
m4p_FOMRMSE[fr][rg][cg][0]
593 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> Log-likelihood: " <<
m4p_FOMLogLikelihood[fr][rg][cg][0] << endl);
594 Cout(spaces_fr << spaces_rg << spaces_cg <<
" --> RMSE: " <<
m4p_FOMRMSE[fr][rg][cg][0] << endl);
621 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
640 if (time_basis_coef==0.)
continue;
646 if (resp_basis_coef==0.)
continue;
652 if (card_basis_coef==0.)
continue;
654 FLTNB global_basis_coef = time_basis_coef * resp_basis_coef * card_basis_coef;
703 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
716 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
739 Cerr(
"***** vOptimizer::DataStep3BackwardProjectSensitivity() -> A problem occurred while performing the sensitivity specific operations !" << endl);
756 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
769 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
790 Cerr(
"***** vOptimizer::DataStep5ComputeCorrections() -> A problem occurred while performing specific data space operations !" << endl);
805 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
818 int a_bed,
int a_timeFrame,
int a_respGate,
int a_cardGate,
830 if (time_basis_coef==0.)
continue;
836 if (resp_basis_coef==0.)
continue;
842 if (card_basis_coef==0.)
continue;
844 FLTNB global_basis_coef = time_basis_coef * resp_basis_coef * card_basis_coef;
873 int a_timeFrame,
int a_respGate,
int a_cardGate,
883 if (model>1.e-10)
m4p_FOMLogLikelihood[a_timeFrame][a_respGate][a_cardGate][a_thread] += data*log(model)-model;
885 m4p_FOMRMSE[a_timeFrame][a_respGate][a_cardGate][a_thread] += (data-model)*(data-model);
887 m4p_FOMNbBins[a_timeFrame][a_respGate][a_cardGate][a_thread]++;
889 m4p_FOMNbData[a_timeFrame][a_respGate][a_cardGate][a_thread] += data;
903 if (
m_verbose>=3)
Cout(
"vOptimizer::UpdateVisitedVoxels() -> Tick visited voxels based on sensitivity" << endl);
950 else Cout(spaces_tbf <<
"--> Time basis function: " << tbf+1 << endl);
959 else Cout(spaces_tbf << spaces_rbf <<
"--> Respiratory basis function: " << rbf+1 << endl);
968 else Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
"--> Cardiac basis function: " << cbf+1 << endl);
991 #pragma omp parallel for private(v) schedule(guided) 997 th = omp_get_thread_num();
1002 if (sensitivity<=0.)
continue;
1026 Cerr(
"***** vOptimizer::ImageUpdateStep() -> A problem occurred while performing image space specific operations of the optimizer !" << endl);
1049 if (error)
return 1;
1070 mp_imageStatMean[0] = (count1*mp_imageStatMean[0] + count2*mp_imageStatMean[th]) / count12;
1074 mp_correctionStatMean[0] = (count1*mp_correctionStatMean[0] + count2*mp_correctionStatMean[th]) / count12;
1080 Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
" --> Image update step " 1083 Cout(spaces_tbf << spaces_rbf << spaces_cbf <<
" --> New image estimate" 1132 int a_timeBasisFunction,
int a_respBasisFunction,
int a_cardBasisFunction,
1136 FLTNB sensitivity = 0.;
1142 if (time_basis_coef==0.)
continue;
1148 if (resp_basis_coef==0.)
continue;
1154 if (card_basis_coef==0.)
continue;
1156 sensitivity += a4p_sensitivityMatrix[fr][rg][cg][a_voxel] *
1157 time_basis_coef * resp_basis_coef * card_basis_coef;
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
int m_requiredPenaltyDerivativesOrder
FLTNB * mp_visitedVoxelsImage
virtual FLTNB GetBlankValue()
This is a pure virtual function implemented in the child classes.
FLTNB ForwardProjectWithSPECTAttenuation(FLTNB *ap_attenuation, FLTNB *ap_image=NULL)
int GetNbCardBasisFunctions()
Get the number of cardiac basis functions.
FLTNB GetFrameDurationInSec(int a_bed, int a_frame)
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
bool m_listmodeCompatibility
FLTNB GetTimeBasisCoefficient(int a_timeBasisFunction, int a_timeFrame)
virtual int DataStep2Optional(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
uint64_t **** m4p_FOMNbBins
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
HPFLTNB **** m4p_FOMPenalty
FLTNB ComputeSensitivity(FLTNB ****a4p_sensitivityImage, int a_timeBasisFunction, int a_respBasisFunction, int a_cardBasisFunction, int a_voxel)
virtual FLTNB GetAdditiveCorrections(int a_bin)=0
virtual int ImageUpdateStep()
A public function used to perform the image update step of the optimizer.
HPFLTNB **** m4p_FOMNbData
virtual int LocalPreProcessingStep(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)
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.
HPFLTNB * mp_imageStatMean
FLTNB ForwardProject(oProjectionLine *ap_Line, FLTNB *ap_image=NULL)
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.
FLTNB ** m2p_attenuationImage
int PreDataUpdateStep()
A public function used to do stuff that need to be done at the beginning of a subset (before the data...
bool GetRespStaticFlag()
Get the respiratory static flag that says if the reconstruction has only one respiratory gate or not...
FLTNB ****** m6p_backwardImage
HPFLTNB **** m4p_FOMLogLikelihood
virtual int DataStep6Optional(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
void BackwardProject(FLTNB *ap_image, FLTNB a_value)
HPFLTNB * mp_correctionStatMean
INTNB * mp_imageStatNbVox
FLTNB ** m2p_forwardValues
bool m_needGlobalSensitivity
FLTNB *** m3p_backwardValues
bool GetCardStaticFlag()
Get the cardiac static flag that says if the reconstruction has only one cardiac gate or not...
bool m_emissionCompatibility
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
FLTNB GetRespBasisCoefficient(int a_respBasisFunction, int a_respGate)
void BackwardProjectWithSPECTAttenuation(FLTNB *ap_attenuation, FLTNB *ap_image, FLTNB a_value)
virtual int DataStep3BackwardProjectSensitivity(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
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)
virtual int DataStep1ForwardProjectModel(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
bool GateDurationProvided()
HPFLTNB * mp_imageStatVariance
FLTNB GetCardBasisCoefficient(int a_cardBasisFunction, int a_cardGate)
bool m_histogramCompatibility
bool m_optimizerImageStatFlag
FLTNB GetQuantificationFactor(int a_bed, int a_frame, int a_respGate, int a_cardGate)
virtual int DataStep8ComputeFOM(oProjectionLine *ap_Line, vEvent *ap_Event, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
bool GetTimeStaticFlag()
Get the time static flag that says if the reconstruction has only one frame or not.
oImageSpace * mp_ImageSpace
FLTNB ***** m5p_sensitivity
HPFLTNB * mp_correctionStatVariance
#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...
virtual FLTNB GetEventValue(int a_bin)=0
FLTNB **** m4p_forwardImage
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...
HPFLTNB GetdurationPerGate(int a_fr, int a_respGate)
int GetNbCardGates()
Get the number of cardiac gates.
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)
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)
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)
int GetNbTOFBins()
This function is used to get the number of TOF bins in use.
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.
void SetCurrentTOFBin(int a_TOFBin)
virtual int DataStep7BackwardProjectCorrections(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_timeFrame, int a_respGate, int a_cardGate, int a_thread)
void ShowHelp()
A function used to show help about the optimizer.
int GetNbRespBasisFunctions()
Get the number of respiratory basis functions.
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...
virtual FLTNB ComputePenaltyValue(int a_tbf, int a_rbf, int a_cbf, INTNB a_voxel, int a_th)=0