8 #include "gVariables.hh" 9 #include "oSensitivityGenerator.hh" 10 #include "iDataFilePET.hh" 65 for (
int fr=0; fr<actual_nb_frames; fr++)
84 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Image dimensions and quantification object is null !" << endl);
89 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Image space object is null !" << endl);
94 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Scanner object is null !" << endl);
99 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Projector manager object is null !" << endl);
104 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Convolver manager object is null !" << endl);
109 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Deformation manager object is null !" << endl);
114 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Data file array is null !" << endl);
121 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Data file object for bed " << b+1 <<
" is null !" << endl);
127 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Verbose level is negative !" << endl);
133 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> It was asked to compute global sensitivity from the provided datafile whereas it is not a histogram !" << endl);
141 Cerr(
"***** oSensitivityGenerator::CheckParameters() -> Global sensitivity computation from histogram does not work wth dynamic data yet !" << endl);
160 Cerr(
"***** oSensitivityGenerator::Initialize() -> Must call the CheckParameters() function before initialization !" << endl);
164 if (
m_verbose>=2)
Cout(
"oSensitivityGenerator::Initialize() -> Start initialization" << endl);
168 Cerr(
"***** oSensitivityGenerator::Initialize() -> Sensitivity for SPECT and CT not yet implemented !" << endl);
180 Cerr(
"***** oSensitivityGenerator::Initialize() -> A problem occurred while initializing the normalization data files !" << endl);
186 Cerr(
"***** oSensitivityGenerator::Initialize() -> A problem occurred while initializing the attenuation files !" << endl);
240 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> Normalization correction is included in the data file while it is not in the sensitivity computation !" << endl);
249 if (
m_verbose>=2)
Cout(
"oSensitivityGenerator::InitializeNormalizationFiles() -> Initialize normalization files" << endl);
259 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> Number of normalization files options should be one or equal to the number of data files !" << endl);
291 vector<string> normalization_files;
293 int bed_data_file_name_index = bed;
298 while (comma!=string::npos)
319 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> Number of normalization files for bed " << bed+1 <<
" should be one or equal to the number of frames !" << endl);
354 bool affect_quantification_flag =
false;
357 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> A problem occurred during normalization datafile header reading !" << endl);
362 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> A problem occurred while checking normalization datafile parameters !" << endl);
367 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> A problem occurred in normalization datafile event size computation !" << endl);
372 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> A problem occurred in normalization datafile initialization !" << endl);
377 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> A problem occurred in normalization datafile preparation !" << endl);
383 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> Normalization data file used for sensitivity computation must be either histogram or normalization mode !" << endl);
393 Cerr(
"***** oSensitivityGenerator::InitializeNormalizationFiles() -> Unknown scanner type (" << p_ScannerManager->
GetScannerType() <<
") or not yet implemented !" << endl);
424 Cerr(
"***** oSensitivityGenerator::InitializeAttenuationFiles() -> Attenuation correction is included in the data file while it is not in the sensitivity computation !" << endl);
435 Cout(
"oSensitivityGenerator::InitializeAttenuationFiles() -> Ignore provided mumap and consider ACF provided in the normalization data file" << endl);
440 if (
m_verbose>=2)
Cout(
"oSensitivityGenerator::InitializeAttenuationFiles() -> Allocate and read attenuation images (assumed to be in cm-1)" << endl);
445 Cerr(
"***** oSensitivityGenerator::Initialize() -> A problem occurred while initializing the attenuation image into the image space !" << endl);
480 if (
m_verbose>=1)
Cout(
"oSensitivityGenerator::Launch() -> Start the sensitivity computation" << endl);
509 Cerr(
"***** oSensitivityGenerator::LaunchCPU() -> A problem occurred while computing the sensitivity using the histogram data file for bed " << bed+1 <<
" !" << endl);
518 Cerr(
"***** oSensitivityGenerator::LaunchCPU() -> A problem occurred while computing the sensitivity using the normalization file for bed " << bed+1 <<
" !" << endl);
527 Cerr(
"***** oSensitivityGenerator::LaunchCPU() -> A problem occurred while computing the sensitivity from scanner elements for bed " << bed+1 <<
" !" << endl);
597 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> This functionality is only available for non-gated reconstruction without image-based motion correction. For these types of reconstruction, the sensitivity must be estimated from the scanner geometry instead !" << endl);
605 else Cout(
"oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> Start computation" << endl);
609 clock_t clock_start = clock();
610 time_t time_start = time(NULL);
613 bool problem =
false;
620 int64_t index_start = 0;
621 int64_t index_stop = 0;
628 int64_t index = 0, printing_index = 0;
629 #pragma omp parallel for private(index) schedule(static, 1) 630 for ( index = index_start ; index < index_stop ; index++)
635 th = omp_get_thread_num();
640 if (printing_index%1000==0)
642 int percent = ((int)( ((
FLTNB)(index-index_start)) * 100. / ((
FLTNB)(index_stop-index_start)) ));
643 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 644 << percent <<
" % " << flush;
652 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> An error occurred while getting the event from index " 653 << index <<
" (thread " << th <<
") !" << endl);
664 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> A problem occurred while computing the projection line !" << endl);
673 int no_resp_gate = 0;
674 int no_card_gate = 0;
678 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> A problem occurred while processing a line !" << endl);
684 MPI_Barrier(MPI_COMM_WORLD);
689 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 690 <<
" --> 100 % " << endl;
694 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromHistogramDataFile() -> A problem occurred inside the parallel loop over events !" << endl);
699 clock_t clock_stop = clock();
700 time_t time_stop = time(NULL);
702 Cout(
" --> Time spent for sensitivity generation for bed " << a_bed+1 <<
" | User: " << time_stop-time_start
703 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
705 Cout(
" --> Time spent for sensitivity generation | User: " << time_stop-time_start
706 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
723 else Cout(
"oSensitivityGenerator::ComputeSensitivityFromNormalizationFile() -> Start computation" << endl);
735 clock_t clock_start = clock();
736 time_t time_start = time(NULL);
743 cout <<
" --> Processing frame " << fr+1 << endl;
753 cout <<
" --> Processing respiratory gate " << rg+1 << endl;
759 cout <<
" --> Processing cardiac gate " << cg+1 << endl;
770 bool problem =
false;
777 int64_t index_start = 0;
778 int64_t index_stop = 0;
782 uint64_t progression_index_total = (index_stop-index_start)
788 int64_t index = 0, printing_index = 0;
789 #pragma omp parallel for private(index) schedule(static, 1) 790 for ( index = index_start ; index < index_stop ; index++)
795 th = omp_get_thread_num();
814 if (printing_index%1000==0)
816 int64_t progression_chunk = (int64_t)((
FLTNB)(index_stop-index_start));
819 + cg * progression_chunk
822 int64_t percent = (int64_t) (( ((
FLTNB)progression_index_current)/((
FLTNB)progression_index_total) ) * ((
FLTNB)100));
823 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 824 << percent <<
" % " << flush;
834 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromNormalizationFile() -> An error occurred while getting the event from index " 835 << index <<
" (thread " << th <<
") !" << endl);
845 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromNormalizationFile() -> A problem occurred while computing the projection line !" << endl);
854 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromNormalizationFile() -> A problem occurred while processing a line !" << endl);
859 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 860 <<
" --> 100 % " << endl;
864 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromNormalizationFile() -> A problem occurred inside the parallel loop over events !" << endl);
873 clock_t clock_stop = clock();
874 time_t time_stop = time(NULL);
876 Cout(
" --> Time spent for sensitivity generation for bed " << a_bed+1 <<
" | User: " << time_stop-time_start
877 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
879 Cout(
" --> Time spent for sensitivity generation | User: " << time_stop-time_start
880 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
897 else Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Start computation" << endl);
907 clock_t clock_start = clock();
908 time_t time_start = time(NULL);
911 int64_t main_loop_start_index = 0 ;
912 int64_t main_loop_stop_index = 0;
918 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromScanner() -> An error occurred when trying to initialize main loop stop index !" << endl);
923 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromScanner() -> An error occurred when trying to initialize inner loop start index !" << endl);
929 int64_t* progression_elts_array =
new int64_t[nb_total_elts*
sizeof(int64_t)];
930 progression_elts_array[0] = 0;
936 uint64_t printing_index = 0;
954 progression_index_total = 0 ;
971 MPI_Barrier(MPI_COMM_WORLD);
976 while (idx_elt< nb_total_elts
981 && main_loop_start_index == 0
983 main_loop_start_index = idx_elt;
989 main_loop_stop_index = idx_elt;
995 " start/stop: " << main_loop_start_index <<
"/" << main_loop_stop_index << endl);
1019 uint16_t nb_dyn_img_processed=0;
1026 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Processing frame " << fr+1 << endl);
1033 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Processing 1st motion image for sensitivity " << rg+1 << endl);
1040 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Processing 2nd motion image for sensitivity " << cg+1 << endl);
1044 if( ( nb_dyn_img_processed == 0 )
1059 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Generate sensitivity image" << endl);
1061 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Generate sensitivity image" << endl);
1073 bool problem =
false;
1082 #pragma omp parallel for private(idx_elt1) schedule(static, 1) 1083 for(idx_elt1=main_loop_start_index ; idx_elt1<main_loop_stop_index ; idx_elt1++)
1088 <<
" OMP ID " << omp_get_thread_num() <<
" start/stop: " << main_loop_start_index <<
"/" << main_loop_stop_index << endl);
1094 th = omp_get_thread_num();
1102 for (int64_t idx_elt2=inner_loop_start_index ; idx_elt2<inner_loop_stop_index ; idx_elt2++)
1107 if (
m_verbose>=2 && printing_index%10000==0)
1109 int64_t progression_index_current;
1111 progression_index_current = p_scannerManager->
PROJ_GetCurrentProgression(idx_elt1, idx_elt2, progression_elts_array, nb_dyn_img_processed);
1113 int64_t percent = (int64_t) (( ((
FLTNB)progression_index_current)/((
FLTNB)progression_index_total) ) * ((
FLTNB)100));
1116 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 1117 << percent <<
" % ";
1132 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromScanner() -> A problem occurred while computing the projection line !" << endl);
1142 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromScanner() -> A problem occurred while processing a line !" << endl);
1149 MPI_Barrier(MPI_COMM_WORLD);
1155 Cerr(
"***** oSensitivityGenerator::ComputeSensitivityFromScanner() -> A problem occurred inside the parallel loop over events !" << endl);
1159 nb_dyn_img_processed++;
1166 Cout(
"oSensitivityGenerator::ComputeSensitivityFromScanner() -> Duplicate sensitivity image" << endl);
1208 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 1209 <<
" --> 100 % " << endl;
1211 delete[] progression_elts_array;
1214 clock_t clock_stop = clock();
1215 time_t time_stop = time(NULL);
1217 Cout(
" --> Time spent for sensitivity generation for bed " << a_bed+1 <<
" | User: " << time_stop-time_start
1218 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
1220 Cout(
" --> Time spent for sensitivity generation | User: " << time_stop-time_start
1221 <<
" sec | CPU: " << (clock_stop-clock_start)/((
FLTNB)CLOCKS_PER_SEC) <<
" sec" << endl);
1243 if (multiplicative_factor<=0.)
return 0;
1247 if (quantification_factor<=0.)
return 0;
1254 FLTNB attenuation_correction_factor = 1.;
1260 FLTNB cumulative_mu = 0.;
1269 attenuation_correction_factor = max(((
FLTNB)1.),exp(cumulative_mu*((
FLTNB)0.1)));
1277 FLTNB lor_sensitivity = 1. / (quantification_factor * attenuation_correction_factor * multiplicative_factor);
1308 merge_dynamic_files )
This class is designed to be a mother virtual class for DataFile.
bool GetNormCorrectionFlag()
Simply return m_normCorrectionFlag.
static sScannerManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
void GetEventIndexStartAndStop(int64_t *ap_indexStart, int64_t *ap_indexStop, int a_subsetNum=0, int a_NbSubsets=1)
oImageConvolverManager * mp_ImageConvolverManager
int ProcessThisLine(oProjectionLine *ap_Line, vEvent *ap_Event, int a_bed, int a_frame, int a_respGate, int a_cardGate, int a_thread)
void LMS_CopyAtnToForwardImage(bool a_use1stMotion, bool a_use2ndMotion)
int GetPMotionFirstIndexForFrame(int a_fr)
int64_t PROJ_GetModalityStartValueInnerLoop(int64_t a_elt1)
#define MODE_NORMALIZATION
uint64_t * mp_lineCounter
oSensitivityGenerator()
The constructor of oSensitivityGenerator.
int Initialize()
A public function used to initialize the sensitivity generator.
int LMS_SaveSensitivityImage(const string &a_pathToSensitivityImage, oDeformationManager *ap_DeformationManager)
bool m_oneNormalizationFileForAllBeds
int m_nbAtnRespGateImages
string GetPathToSensitivityImage()
This function return the path to the sensitivity image.
int64_t PROJ_GetProgressionFinalValue()
Get numerator value according to the modality to compute percent progression during the projection pr...
bool m_oneNormalizationFileForAllFrames
void SetVerbose(int a_verboseLevel)
bool GetIgnoreAttnCorrectionFlag()
Get the boolean that says if the attenuation correction is ignored or not.
~oSensitivityGenerator()
The destructor of oSensitivityGenerator.
vDataFile *** m3p_NormalizationDataFile
int Launch()
A public function used to launch the sensitivity generator (compute the sensitivity image) ...
virtual FLTNB GetMultiplicativeCorrections()=0
This is a pure virtual function implemented in the child classes.
void LMS_InstantiateForwardImage()
Allocate memory for the forward image matrices (for list-mode sensitivity generation) ...
int GetPMotionLastIndexForFrame(int a_fr)
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
int InitAttenuationImage(const string &a_pathToAtnImage)
FLTNB ****** m6p_backwardImage
bool GetIgnoreNormCorrectionFlag()
Get the boolean that says if the normalization correction is ignored or not.
vEvent * GetEvent(int64_t a_eventIndex, int a_th=0)
INTNB GetVoxelIndex(int a_direction, int a_TOFBin, INTNB a_voxelInLine)
bool m_computeFromHistogramFlag
const string & GetPathName()
bool m_inverseDataFileOrderFlag
int m_nbAtnCardGateImages
Singleton class that manages output writing on disk (images, sinograms, etc). It also manages loggi...
int ComputeSensitivityFromNormalizationFile(int a_bed)
INTNB GetCurrentNbVoxels(int a_direction, int a_TOFBin)
oDeformationManager * mp_DeformationManager
void LMS_DeallocateSensitivityImage()
Free memory for the sensitivity image matrices (for list-mode sensitivity generation) ...
int GetNbBeds()
Get the number of bed positions.
Singleton class that Instantiate and initialize the scanner object.
vector< string > mp_pathToNormalizationFileName
int GetMPISize()
Get the MPI size (the number of MPI instances)
void ResetCurrentDynamicIndices()
Call the eponym function from the oDynamicDataManager class using the member object.
int64_t PROJ_GetCurrentProgression(int64_t a_elt1, int64_t a_elt2, int64_t *ap_nbEltsArray, uint16_t a_nbDynImgProcessed)
oProjectionLine * ComputeProjectionLine(vEvent *ap_Event, int a_th)
FLTNB GetQuantificationFactor(int a_bed, int a_frame, int a_respGate, int a_cardGate)
int InitializeAttenuationFiles()
Initialize the attenuation images provided for sensitivity computation.
void SetHeaderDataFileName(const string &a_headerFileName)
void ApplyBedOffset(int a_bed)
vEvent * PROJ_GenerateEvent(int idx_elt1, int idx_elt2, int a_th)
bool NotEmptyLine()
This function is used to know if the line contains any voxel contribution.
int LaunchCPU()
Launch the computation of the sensitivity image (CPU version)
bool m_forwardProjectAttenuation
bool m_mumapAttenuationFlag
FLTNB **** m4p_forwardImage
virtual int GetSystemNbElts()=0
This is a pure virtual method that must be implemented by children.
int GetNb1stMotImgsForLMS(int a_fr)
oImageSpace * mp_ImageSpace
void ReduceBackwardImage(int a_imageIndex, int a_timeIndex, int a_respIndex, int a_cardIndex)
This class is designed to manage and store system matrix elements associated to a vEvent...
const string & GetBaseName()
FLTNB GetVoxelWeights(int a_direction, int a_TOFBin, INTNB a_voxelInLine)
string m_pathToSensitivityImage
void InstantiateBackwardImageFromDynamicBins()
Allocate memory for the backward image matrices and initialize them.
void LMS_DeallocateAttenuationImage()
Free memory for the Attenuation image matrices (for analytical projection or list-mode sensitivity ge...
int GetNbCardGates()
Get the number of cardiac gates.
bool MergeDynImages()
Indicate if a dynamic serie of 3D images should be merged in one file (true) or written on disk as on...
void SetBedIndex(int a_bedIndex)
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.
INTNB GetNbVoxXYZ()
Get the total number of voxels.
vDataFile ** m2p_DataFile
int GetNb2ndMotImgsForLMS()
call the eponym function from the oDynamicDataManager object
string m_pathToAttenuationImage
int InitializeNormalizationFiles()
Initialize the normalization datafiles provided for sensitivity computation.
int CheckParameters()
A public function used to check the parameters settings.
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.
oProjectorManager * mp_ProjectorManager
int ComputeSensitivityFromHistogramDataFile(int a_bed)
#define DYN_RECO_MCGATING
int GetNbRespGates()
Get the number of respiratory gates.
int64_t PROJ_GetModalityStopValueMainLoop()
Get the stop value for the main loop of analytic projection depending on the modality.
int ConvolveSensitivity(oImageSpace *ap_ImageSpace)
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
virtual int IsAvailableLOR(int a_elt1, int a_elt2)
int ComputeSensitivityFromScanner(int a_bed)
bool GetAtnCorrectionFlag()
Simply return m_atnCorrectionFlag.
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
void DeallocateBackwardImageFromDynamicBins()
Free memory of the backward image matrices.
Inherit from vDataFile. Class that manages the reading of a PET input file (header + data)...
void LMS_InstantiateSensitivityImage()
Allocate memory for the sensitivity image matrices (for list-mode sensitivity generation) ...
int GetMPIRank()
Get the MPI instance number (the rank)
void LMS_CopyBackwardToSensitivity()
void LMS_DeallocateForwardImage()
Free memory for the forward image matrices (for list-mode sensitivity generation) ...