105 Cout(
"iScannerCT::DescribeSpecific() -> Here is some specific content of the CT scanner" << endl);
111 Cout(
" --> Projection angles: " << endl);
117 for (
int p=0 ; p<10 ; p++)
138 Cout(
" --> Total number of transaxial pixels as defined in the system file: " <<
m_nbPixelsTrans << endl);
140 Cout(
" --> Gap size between each transaxial pixe as defined in the system file: " <<
m_gapSizeTrans << endl);
141 Cout(
" --> Total number of axial pixels as defined in the system file: " <<
m_nbPixelsAxial << endl);
143 Cout(
" --> Gap size between each axial pixel as defined in the system file: " <<
m_gapSizeAxial << endl);
145 Cout(
" --> Width of the source, along the direction tangential to the scanner radius: " <<
m_spotSizeWidth << endl);
146 Cout(
" --> Depth of the source, along the direction of the scanner radius: " <<
m_spotSizeDepth << endl);
161 if (
m_verbose>=
VERBOSE_NORMAL)
Cout(
"iScannerCT::Instantiate() -> Create scanner structure and read parameters from configuration file" << endl);
169 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the transaxial number of pixels !" << endl);
174 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the transaxial pixel size !" << endl);
179 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the axial number of pixels !" << endl);
184 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the axial pixel size !" << endl);
189 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read detector depth !" << endl);
194 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read detector to COR distance as \"detector radius\" !" << endl);
199 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read source to COR distance as \"source radius\" !" << endl);
204 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the spot size width !" << endl);
209 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the spot size height !" << endl);
217 Cerr(
"***** iScannerSPECTConv::Instantiate() -> An error occurred while trying to read the multiple bed displacement in the scanner header file !" << endl);
252 if (!a_scannerFileIsLUT)
256 Cerr(
"***** iScannerCT::BuildLUT() -> A problem occurred while generating scanner LUT !" << endl);
264 Cerr(
"***** iScannerCT::BuildLUT() -> A problem occurred while loading scanner LUT !" << endl);
285 Cerr(
"***** iScannerCT::CheckParameters()-> Number of crystals has not been initialized !" <<endl);
290 Cerr(
"***** iScannerCT::CheckParameters()-> Number of projection angles has not been initialized !" <<endl);
295 Cerr(
"***** iScannerCT::CheckParameters()-> Number of transaxial/axial pixels have not correctly been initialized ! (should be >0)" <<endl);
300 Cerr(
"***** iScannerCT::CheckParameters()-> Transaxial/axial pixel sizes have not correctly been initialized ! (should be >0)" <<endl);
305 Cerr(
"***** iScannerCT::CheckParameters()-> Transaxial/axial pixel gap sizes have not correctly been initialized ! (should be >0)" <<endl);
310 Cerr(
"***** iScannerCT::CheckParameters()-> Crystal depth has not correctly been initialized ! (should be >0)" <<endl);
315 Cerr(
"***** iScannerCT::CheckParameters()-> Projection angles have not correctly been initialized !" <<endl);
320 Cerr(
"***** iScannerCT::CheckParameters()-> Distance between center of rotation and detector surface has not correctly been initialized !" <<endl);
325 Cerr(
"***** iScannerCT::CheckParameters()-> Distance between center of rotation and source surface has not correctly been initialized !" <<endl);
332 Cerr(
"***** iScannerCT::CheckParameters()-> LUT elements (crystal central positions) have not correctly been initialized !" <<endl);
339 Cerr(
"***** iScannerCT::CheckParameters()-> LUT elements (crystal orientations) have not correctly been initialized !" <<endl);
346 Cerr(
"***** iScannerCT::CheckParameters()-> LUT elements (crystal focal positions) have not correctly been initialized !" <<endl);
370 Cerr(
"***** iScannerCT::Initialize() -> Parameters have not been checked !" << endl);
388 Cerr(
"iScannerCT::LoadLUT() -> Not yet implemented !" << endl);
407 omp_set_num_threads(nb_threads);
418 crystal_center_ref[c] =
new oMatrix(3,1);
424 for (
int th=0; th<nb_threads; th++)
426 crystal_center_out[th] =
new oMatrix(3,1);
427 source_center_out[th] =
new oMatrix(3,1);
434 rotation_mtx[i] =
new oMatrix(3,3);
450 Cerr(
"***** iScannerCT::ComputeLUT() -> An error occurred while trying to read the transaxial gap size !" << endl);
456 Cerr(
"***** iScannerCT::ComputeLUT() -> An error occurred while trying to read the axial gap size !" << endl);
469 crystal_center_ref[ii + m_nbPixelsTrans * jj]->
SetMatriceElt(0,0,Xcryst);
472 crystal_center_ref[ii + m_nbPixelsTrans * jj]->
SetMatriceElt(2,0,Zcryst);
489 #pragma omp parallel for private(a) schedule(guided) 495 th = omp_get_thread_num();
501 int cryID = a*m_nbPixels + c;
504 rotation_mtx[a]->
Multiplication(crystal_center_ref[c], crystal_center_out[th]);
515 rotation_mtx[a]->
Multiplication(source_center_ref, source_center_out[th]);
523 delete rotation_mtx[i];
524 delete[] rotation_mtx;
526 delete crystal_center_ref[c];
527 delete[] crystal_center_ref;
528 delete source_center_ref;
529 for (
int th=0; th<nb_threads; th++)
531 delete crystal_center_out[th];
532 delete source_center_out[th];
534 delete[] crystal_center_out;
535 delete[] source_center_out;
549 FLTNB ap_Orientation1[3],
FLTNB ap_Orientation2[3],
559 Cerr(
"***** iScannerCT::GetPositionsAndOrientations() -> Projection index (" << a_index1 <<
") out of range [0:" <<
m_nbOfProjections-1 <<
"] !" << endl);
566 Cerr(
"***** iScannerCT::GetPositionsAndOrientations() -> Pixel index (" << a_index2 <<
") out of range [0:" <<
m_nbPixels-1 <<
"] !" << endl);
590 else if (ap_POI2[2]<0.)
592 Cerr(
"***** iScannerCT::GetPositionsAndOrientations() -> POI management not implemented yet for CT !" << endl);
596 else if (ap_POI2[0]==0. && ap_POI2[1]==0.)
598 Cerr(
"***** iScannerCT::GetPositionsAndOrientations() -> POI management not implemented yet for CT !" << endl);
604 Cerr(
"***** iScannerCT::GetPositionsAndOrientations() -> POI management not implemented yet for CT !" << endl);
626 FLTNB ap_Orientation1[3],
FLTNB ap_Orientation2[3] )
630 Cerr(
"***** iScannerCT::GetRdmPositionsAndOrientations() -> Not yet implemented for CT !" << endl);
644 Cerr(
"***** iScannerCT::GetPositionWithRandomDepth() -> This function was implemented for PET testing purpose. Not implemented for CT !" << endl);
654 FLTNB ap_CornerInf1[3],
FLTNB ap_CornerSup1[3],
655 FLTNB ap_CornerInf2[3],
FLTNB ap_CornerSup2[3])
658 Cerr(
"***** iScannerCT::GetTwoCorners() -> Not implemented yet !" << endl);
668 FLTNB ap_pos_line_point1[3],
FLTNB ap_pos_line_point2[3],
669 FLTNB ap_pos_point1_x[4],
FLTNB ap_pos_point1_y[4],
FLTNB ap_pos_point1_z[4],
670 FLTNB ap_pos_point2_x[4],
FLTNB ap_pos_point2_y[4],
FLTNB ap_pos_point2_z[4]
678 Cerr(
"***** iScannerCT::GetPositionEdge() -> Crystal index or projection index out of range !" << endl);
683 int global_index =
m_nbPixels * a_index1 + a_index2;
694 ap_pos_point1_x[ 0 ] = ap_pos_line_point1[ 0 ] - half_spot_size_trans * -
mp_crystalOrientationY[ global_index ];
695 ap_pos_point1_x[ 1 ] = ap_pos_line_point1[ 0 ] + half_spot_size_trans * -mp_crystalOrientationY[ global_index ];
696 ap_pos_point1_x[ 2 ] = ap_pos_line_point1[ 0 ];
697 ap_pos_point1_x[ 3 ] = ap_pos_line_point1[ 0 ];
700 ap_pos_point1_y[ 0 ] = ap_pos_line_point1[ 1 ] - half_spot_size_trans *
mp_crystalOrientationX[ global_index ];
701 ap_pos_point1_y[ 1 ] = ap_pos_line_point1[ 1 ] + half_spot_size_trans * mp_crystalOrientationX[ global_index ];
702 ap_pos_point1_y[ 2 ] = ap_pos_line_point1[ 1 ];
703 ap_pos_point1_y[ 3 ] = ap_pos_line_point1[ 1 ];
706 ap_pos_point1_z[ 0 ] = ap_pos_line_point1[ 2 ];
707 ap_pos_point1_z[ 1 ] = ap_pos_line_point1[ 2 ];
708 ap_pos_point1_z[ 2 ] = ap_pos_line_point1[ 2 ] - half_spot_size_axial;
709 ap_pos_point1_z[ 3 ] = ap_pos_line_point1[ 2 ] + half_spot_size_axial;
714 ap_pos_point2_x[ 0 ] = ap_pos_line_point2[ 0 ] + half_pixel_trans * mp_crystalOrientationY[ global_index ];
715 ap_pos_point2_x[ 1 ] = ap_pos_line_point2[ 0 ] - half_pixel_trans * mp_crystalOrientationY[ global_index ];
716 ap_pos_point2_x[ 2 ] = ap_pos_line_point2[ 0 ];
717 ap_pos_point2_x[ 3 ] = ap_pos_line_point2[ 0 ];
720 ap_pos_point2_y[ 0 ] = ap_pos_line_point2[ 1 ] + half_pixel_trans * -mp_crystalOrientationX[ global_index ];
721 ap_pos_point2_y[ 1 ] = ap_pos_line_point2[ 1 ] - half_pixel_trans * -mp_crystalOrientationX[ global_index ];
722 ap_pos_point2_y[ 2 ] = ap_pos_line_point2[ 1 ];
723 ap_pos_point2_y[ 3 ] = ap_pos_line_point2[ 1 ];
726 ap_pos_point2_z[ 0 ] = ap_pos_line_point2[ 2 ];
727 ap_pos_point2_z[ 1 ] = ap_pos_line_point2[ 2 ];
728 ap_pos_point2_z[ 2 ] = ap_pos_line_point2[ 2 ] - half_pixel_axial;
729 ap_pos_point2_z[ 3 ] = ap_pos_line_point2[ 2 ] + half_pixel_axial;
753 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() -> Error while reading number of projections in the header data file " << endl);
759 FLTNB first_and_last_angles[2] = {-1.,-1.};
768 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() -> Error while reading Angle mandatory field in the header data file '" << endl);
772 string rotation_direction =
"";
775 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() -> Error while reading head rotation orientation in the header data file " << endl);
780 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() ->Error occurred while trying to initialize scanner rotation orientation " << endl);
790 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() -> Error while reading Angles field in the header data file !'" << endl);
796 (first_and_last_angles[0] <0 || first_and_last_angles[1] <0) )
798 Cerr(
"***** iScannerCT::GetGeometricInfoFromDataFile() -> No information on projection angles provided in the datafile !'" << endl);
799 Cerr(
" This information should be provided using either the 'Angles' tag, or both 'First angles', 'Last angles' tags !'" << endl);
805 while (first_and_last_angles[0]>=360.) first_and_last_angles[0] -= 360.;
806 while (first_and_last_angles[0]<0.) first_and_last_angles[0] += 360.;
807 while (first_and_last_angles[1]>=360.) first_and_last_angles[1] -= 360.;
808 while (first_and_last_angles[1]<0.) first_and_last_angles[1] += 360.;
812 FLTNB angle_increment = dir*(first_and_last_angles[1] - first_and_last_angles[0]);
813 while (angle_increment>=360.) angle_increment -= 360.;
814 while (angle_increment<0.) angle_increment += 360.;
819 angles[a] = first_and_last_angles[0] + dir * angle_increment * ((
FLTNB)a);
820 while (angles[a]>=360.) angles[a] -= 360.;
821 while (angles[a]<0.) angles[a] += 360.;
824 angles[m_nbOfProjections-1] = first_and_last_angles[1];
844 int* ap_detectorRotDirection)
848 if (
m_verbose>=
VERBOSE_DETAIL)
Cout(
"iScannerCT::GetCTSpecificParameters() -> Copy pointers inside scanner to the datafile to get information" << endl
849 <<
" depending on the datafile inside the scanner" << endl);
853 Cerr(
"***** iScannerCT::GetCTSpecificParameters() -> Parameters have not been checked !" << endl);
872 cout <<
"This scanner class is dedicated to the description of CT systems." << endl;
iScannerCT()
iScannerCT constructor. Initialize the member variables to their default values.
int LoadLUT()
Load a precomputed scanner LUT.
static sScannerManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
#define VERBOSE_DEBUG_EVENT
FLTNB * mp_crystalOrientationZ
int GetPositionWithRandomDepth(int a_index1, int a_index2, FLTNB ap_Position1[3], FLTNB ap_Position2[3])
Get the positions and orientations of scanner elements from their indices, with a random depth...
FLTNB m_CORtoDetectorDistance
FLTNB * mp_projectionAngles
FLTNB * mp_sourcePositionX
int ComputeLUT()
Computes the LUT of the scanner from a generic (.geom) file.
int GetRdmPositionsAndOrientations(int a_index1, int a_index2, FLTNB ap_Position1[3], FLTNB ap_Position2[3], FLTNB ap_Orientation1[3], FLTNB ap_Orientation2[3])
Get the focal point and random positions on the crystal surface and its orientations from the event i...
FLTNB m_defaultBedDisplacementInMm
FLTNB * mp_crystalOrientationX
int Initialize()
Check general initialization and set several parameters to their default value.
Declaration of class iScannerCT.
string GetPathToScannerFile()
int GetGeometricInfoFromDataFile(string a_pathToDF)
Recover geometric informations specific to the scanner class from the datafile header.
uint16_t m_nbOfProjections
int BuildLUT(bool a_scannerFileIsLUT)
Call the functions to generate the LUT or read the user-made LUT depending on the user choice...
oImageDimensionsAndQuantification * mp_ID
FLTNB m_CORtoSourceDistance
#define VERBOSE_DEBUG_LIGHT
virtual int SetRotDirection(string a_rotDirection)
Set rotation direction of the system.
int CheckParameters()
Check that all parameters have been correctly initialized.
FLTNB * mp_sourcePositionY
FLTNB * mp_crystalOrientationY
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 GetNbThreadsMax()
Get the maximum between the number of threads used for projections and image operations.
Singleton class that Instantiate and initialize the scanner object.
FLTNB * mp_crystalCentralPositionX
void DescribeSpecific()
Implementation of the pure virtual eponym function that simply prints info about the scanner...
Declaration of class sScannerManager.
HPFLTNB GetMatriceElt(uint16_t l, uint16_t c)
bool m_allParametersChecked
#define KEYWORD_MANDATORY
int GetTwoCorners(int a_index1, int a_index2, FLTNB ap_CornerInf1[3], FLTNB ap_CornerSup1[3], FLTNB ap_CornerInf2[3], FLTNB ap_CornerSup2[3])
Get the cartesian coordinaters of the two opposite corners of a scanner element.
int GetEdgesCenterPositions(int a_index1, int a_index2, FLTNB ap_pos_line_point1[3], FLTNB ap_pos_line_point2[3], FLTNB ap_pos_point1_x[4], FLTNB ap_pos_point1_y[4], FLTNB ap_pos_point1_z[4], FLTNB ap_pos_point2_x[4], FLTNB ap_pos_point2_y[4], FLTNB ap_pos_point2_z[4])
Implementation of the pure virtual function from vScanner. Get the cartesian coordinaters of the ce...
Declaration of class sOutputManager.
~iScannerCT()
iScannerCT destructor.
Structure designed for basic matrices operations.
FLTNB * mp_crystalCentralPositionY
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
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)
This is a pure virtual method that must be implemented by children. Get the central positions and o...
int Multiplication(oMatrix *ap_Mtx, oMatrix *ap_MtxResult)
Multiply the member matrix with the matrix provided in 1st parameter Return the result in the matric ...
int GetCTSpecificParameters(uint16_t *ap_nbOfProjections, FLTNB *&ap_angles, int *ap_detectorRotDirection)
Set pointers passed in argument with the related CT specific variables This function is used to rec...
int SetMatriceElt(uint16_t l, uint16_t c, HPFLTNB a_val)
Set the matrix element corresponding to the argument indices with the provided value.
int Instantiate(bool a_scannerFileIsLUT)
Get mandatory informations from the scanner file and allocate memory for the member variables...
FLTNB * mp_crystalCentralPositionZ
Generic class for scanner objects.
void ShowHelp()
Display help.
FLTNB * mp_sourcePositionZ