8 #include "vProjector.hh" 10 #include "vDataFile.hh" 85 if (ap_ImageDimensionsAndQuantification==NULL)
87 Cerr(
"***** vProjector::SetImageDimensionsAndQuantification() -> Input image dimensions object is null !" << endl);
116 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
117 if (mpi_rank!=0)
return;
120 cout <<
"------------------------------------------------------------------" << endl;
121 cout <<
"----- Common options for all projectors" << endl;
122 cout <<
"------------------------------------------------------------------" << endl;
123 cout <<
"Only options related to TOF implementation are available." << endl;
124 cout <<
"If used, values for all of the following options must be provided as a list of numbers separated by commas." << endl;
126 cout <<
" the number of standard deviations for truncating the nominal TOF Gaussian distribution (-1 for no truncation)." << endl;
127 cout <<
" whether the TOF weighting function is precomputed (1 for yes, 0 for no)" << endl;
128 cout <<
" whether the TOF weighting function takes properly into account the TOF bin using convolution or integration (1 for yes, 0 for no)." << endl;
130 cout <<
"The default values are -1,1,1" << endl;
145 else cout <<
"This projector is NOT compatible with SPECT attenuation correction." << endl;
156 if (a_optionsList!=
"")
162 Cerr(
"***** vProjector::ReadCommonOptionsList() -> Failed to correctly read the list of options !" << endl);
182 Cerr(
"***** vProjector::CheckParameters() -> Please provide a valid scanner object !" << endl);
188 Cerr(
"***** vProjector::CheckParameters() -> Please provide a valid image dimensions and quantification object !" << endl);
193 Cerr(
"***** vProjector::CheckParameters() -> One or more voxel sizes is negative or null !" << endl);
198 Cerr(
"***** vProjector::CheckParameters() -> One or more number of voxels is negative or null !" << endl);
204 Cerr(
"***** vProjector::CheckParameters() -> TOF flag is incorrect or not set !" << endl);
212 Cerr(
"***** vProjector::CheckParameters() -> Inconsistent TOF related parameters !" << endl);
217 Cout(
"***** vProjector::CheckParameters() -> Warning: quantization TOF bin size wrong or not provided, so switching to TOF list-mode reconstruction which neglects the quantization TOF bin size!" << endl);
223 Cerr(
"***** vProjector::Initialize() -> Per-event TOF resolution can not be used with histogram TOF !" << endl);
229 Cerr(
"***** vProjector::Initialize() -> Per-event TOF resolution can not be used with precomputed TOF weighing estimation !" << endl);
236 Cerr(
"***** vProjector::CheckParameters() -> Verbose level is negative !" << endl);
242 Cerr(
"***** vProjector::CheckParameters() -> An error occurred while checking parameters of the child projector class !" << endl);
261 Cerr(
"***** vProjector::Initialize() -> Must call the CheckParameters() function before initialization !" << endl);
271 FLTNB smallest_tof_resolution_sigma = 1000000.;
279 smallest_tof_resolution_sigma = tof_resolution_sigma[ r ] > smallest_tof_resolution_sigma ?
280 smallest_tof_resolution_sigma :
281 tof_resolution_sigma[ r ];
296 Cout(
" TOF weighting function precomputation... " << endl);
298 ChronoTime start_tof_weights_precmp = std::chrono::system_clock::now();
304 HPFLTNB largest_tof_half_span = -1.;
311 largest_tof_half_span = largest_tof_half_span > (tof_resolution_sigma[ r ] *
m_TOFNbSigmas) ?
312 largest_tof_half_span :
319 if (nb_samples_tof_gauss % 2 == 0) nb_samples_tof_gauss += 1;
337 Cout(
" -> Process TOF resolution: " << r+1 <<
"/" << m_nbTOFResolutions << endl);
342 INTNB mu = nb_samples_tof_gauss/2;
345 #pragma omp parallel for private(g) schedule(guided) 346 for (g=0;g<nb_samples_tof_gauss;g++)
349 FLTNB tof_weight = 0.;
351 HPFLTNB temp = ((
HPFLTNB)(g-mu))/(tof_resolution_sigma[ r ]*m_TOFPrecomputedSamplingFactor);
370 Cerr(
"***** vProjector::Initialize: Implementation of proper bin processins incomplete (need to deal with multi-tof resolution)" << endl);
376 if (nb_samples_tof_bin % 2 == 0) nb_samples_tof_bin += 1;
379 INTNB nb_samples_conv = nb_samples_tof_gauss+nb_samples_tof_bin-1;
384 Cout(
" -> Process TOF resolution: " << r+1 <<
"/" << m_nbTOFResolutions << endl);
389 INTNB mu = nb_samples_conv/2;
392 #pragma omp parallel for private(sgauss) schedule(guided) 393 for (sgauss=0;sgauss<nb_samples_conv;sgauss++)
395 if (sgauss<mu-nb_samples_tof_gauss/2 || sgauss>mu+nb_samples_tof_gauss/2) tof_gauss[sgauss]=0.;
398 HPFLTNB temp = (
HPFLTNB)((sgauss-mu))/(tof_resolution_sigma[ r ]*m_TOFPrecomputedSamplingFactor);
409 for (
INTNB sbin=0;sbin<nb_samples_tof_bin;sbin++) tof_bin[sbin] = tof_bin_value;
416 for (
INTNB c=0;c<nb_samples_conv;c++)
417 for (
INTNB ib=0;ib<nb_samples_tof_bin;ib++)
419 INTNB temp = c-nb_samples_tof_bin/2+ib;
420 if (temp>=0 && temp<nb_samples_conv)
m2p_TOFWeightingFcn[ r ][c] += tof_gauss[temp]*tof_bin[ib];
434 DurationNano duration_tof_weights_precmp = chrono::duration<int64_t,nano>::zero();
435 duration_tof_weights_precmp += std::chrono::system_clock::now() - start_tof_weights_precmp;
438 Cout(
" --> Profiling of the TOF weights precomputation: " << setfill(
'0' )
439 << setw( 2 ) << chrono::duration_cast<Hs> ( duration_tof_weights_precmp ).count() <<
" hours " 440 << setw( 2 ) << chrono::duration_cast<Mins>( duration_tof_weights_precmp %
Hs( 1 ) ).count() <<
" mins " 441 << setw( 2 ) << chrono::duration_cast<Secs>( duration_tof_weights_precmp %
Mins( 1 ) ).count() <<
" secs " 442 << setw( 3 ) << chrono::duration_cast<Ms> ( duration_tof_weights_precmp %
Secs( 1 ) ).count() <<
" ms" << endl);
448 Cout(
" --> TOF weighting function implementation: " << endl);
449 Cout(
" --> Gaussian truncation (number of standard deviations) " <<
m_TOFNbSigmas << endl);
452 Cout(
" --> Precomputed " << endl);
465 Cout(
" --> Computation on the fly " << endl);
478 delete[] tof_resolution_sigma;
484 Cerr(
"***** vProjector::Initialize() -> A problem occurred while calling the specific initialization of the child projector !" << endl);
490 Cout(
"vProjector::Initialize() -> Exit function" << endl);
518 Cerr(
"***** vProjector::Project() -> Called while not initialized !" << endl);
537 ap_ProjectionLine->
SetIndex1(((
int)(ap_index1[0])));
538 ap_ProjectionLine->
SetIndex2(((
int)(ap_index2[0])));
545 Cerr(
"***** vProjector::Project() -> A problem occurred while getting positions and orientations from scanner !" << endl);
566 for (
int i=0; i<3; i++)
570 orientation1[i] = 0.;
571 orientation2[i] = 0.;
574 for (
int l=0; l<a_nbIndices; l++)
578 buffer_position1, buffer_position2,
579 buffer_orientation1, buffer_orientation2,
582 Cerr(
"***** vProjector::Project() -> A problem occurred while getting positions and orientations from scanner !" << endl);
586 for (
int i=0; i<3; i++)
588 position1[i] += buffer_position1[i];
589 position2[i] += buffer_position2[i];
590 orientation1[i] += buffer_orientation1[i];
591 orientation2[i] += buffer_orientation2[i];
595 for (
int i=0; i<3; i++)
597 position1[i] /= ((
FLTNB)a_nbIndices);
598 position2[i] /= ((
FLTNB)a_nbIndices);
599 orientation1[i] /= ((
FLTNB)a_nbIndices);
600 orientation2[i] /= ((
FLTNB)a_nbIndices);
643 Cerr(
"***** vProjector::Project() -> A problem occurred while projecting a line without time-of-flight !" << endl);
650 Cerr(
"***** vProjector::Project() -> A problem occurred while projecting a line with time-of-flight position !" << endl);
657 Cerr(
"***** vProjector::Project() -> A problem occurred while projecting a line with binned time-of-flight !" << endl);
664 #ifdef CASTOR_VERBOSE 667 Cout(
"vProjector::Project() -> Exit function" << endl);
FLTNB m_TOFLargestResolutionInMm
std::chrono::seconds Secs
bool m_compatibleWithSPECTAttenuationCorrection
FLTNB * GetOrientation1()
This function is used to get the pointer to the mp_orientation1 (3-values tab).
FLTNB * GetPOI1()
This function is used to get the pointer to POI of point 1 (3-values tab).
static void ShowCommonHelp()
This function is used to print out some help about the use of options common to all projectors...
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.
FLTNB GetVoxSizeX()
Get the voxel's size along the X axis, in mm.
FLTNB GetVoxSizeZ()
Get the voxel's size along the Z axis, in mm.
FLTNB * GetBufferPosition2()
This function is used to get the pointer to the mp_bufferPosition2 (3-values tab).
std::chrono::time_point< std::chrono::system_clock > ChronoTime
vProjector()
The constructor of vProjector.
int Initialize()
A public function used to initialize the projector.
bool m_TOFWeightingFcnPrecomputedFlag
virtual int ProjectTOFHistogram(int a_direction, oProjectionLine *ap_ProjectionLine)=0
bool m_TOFBinProperProcessingFlag
int Project(int a_direction, oProjectionLine *ap_ProjectionLine, uint32_t *ap_index1, uint32_t *ap_index2, int a_nbIndices)
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
FLTNB * GetBufferPosition1()
This function is used to get the pointer to the mp_bufferPosition1 (3-values tab).
virtual int ProjectWithoutTOF(int a_direction, oProjectionLine *ap_ProjectionLine)=0
bool m_TOFEventResolutionFlag
FLTNB * GetOrientation2()
This function is used to get the pointer to the mp_orientation2 (3-values tab).
HPFLTNB ** m2p_TOFWeightingFcn
FLTNB * mp_TOFProbabilities
virtual int CheckSpecificParameters()=0
A private function used to check the parameters settings specific to the child projector.
void ComputeLineLength()
Simply compute and update the m_length using the associated mp_position1 and mp_position2.
int ReadCommonOptionsList(const string &a_optionsList)
FLTNB GetVoxSizeY()
Get the voxel's size along the Y axis, in mm.
void ApplyOffset()
Apply the offset of oImageDimensionsAndQuantification to the mp_position1 and mp_position2.
FLTNB * GetPosition1()
This function is used to get the pointer to the mp_position1 (3-values tab).
virtual void ShowHelpSpecific()=0
A function used to show help about the child module.
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
FLTNB * GetBufferOrientation1()
This function is used to get the pointer to the mp_bufferOrientation1 (3-values tab).
virtual ~vProjector()
The destructor of vProjector.
int CheckParameters()
A public function used to check the parameters settings.
void SetIndex2(int a_index2)
FLTNB * GetBufferOrientation2()
This function is used to get the pointer to the mp_bufferOrientation2 (3-values tab).
FLTNB * mp_TOFResolutionInMm
FLTNB * mp_TOFGaussianNormCoef
This class is designed to manage and store system matrix elements associated to a vEvent...
FLTNB m_TOFPrecomputedSamplingFactor
virtual int ProjectTOFListmode(int a_direction, oProjectionLine *ap_ProjectionLine)=0
void SetIndex1(int a_index1)
virtual int InitializeSpecific()=0
A private function used to initialize everything specific to the child projector. ...
std::chrono::duration< int64_t, std::nano > DurationNano
INTNB GetNbVoxXYZ()
Get the total number of voxels.
FLTNB m_TOFMeasurementRangeInMm
This class is designed to manage all dimensions and quantification related stuff. ...
FLTNB * GetPosition2()
This function is used to get the pointer to the mp_position2 (3-values tab).
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
virtual INTNB EstimateMaxNumberOfVoxelsPerLine()
This function is used to compute and provide an estimate of the maximum number of voxels that could c...
bool m_compatibleWithCompression
std::chrono::minutes Mins
void ShowHelp()
A function used to show help about the projector.
FLTNB * GetPOI2()
This function is used to get the pointer to POI of point 2 (3-values tab).
int SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
#define TWO_SQRT_TWO_LN_2
void ApplyBedOffset()
Apply the bed offset of m_bedOffset to the mp_position1 and mp_position2.
virtual int GetPositionsAndOrientations(int a_index1, int a_index2, FLTNB ap_Position1[3], FLTNB ap_Position2[3], FLTNB ap_Orientation1[3], FLTNB ap_Orientation2[3], FLTNB *ap_POI1=NULL, FLTNB *ap_POI2=NULL)=0
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.
#define VERBOSE_DEBUG_EVENT
INTNB m_TOFWeightingFcnNbSamples