106 Cout(
"iScannerPET::DescribeSpecific() -> Here is some specific content of the PET scanner" << endl);
114 if(l>0)
Cout(
" --> Layer "<<l<<
":"<< endl);
150 if (
m_verbose>=
VERBOSE_NORMAL)
Cout(
"iScannerPET::Instantiate() -> Create scanner structure and read parameters from configuration file"<< endl);
159 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the number of layers in the scanner header file !" << endl);
165 Cerr(
"***** iScannerPET::Instantiate() -> Incorrect value for the number of layer (must be >0) !" << endl);
171 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the number of elements in the scanner header file !" << endl);
199 if (a_scannerFileIsLUT)
206 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the crystals size in the scanner header file !" << endl);
217 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the crystals size in the scanner header file !" << endl);
234 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the mean depth of interaction in the scanner header file !" << endl);
239 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the min angle difference in the scanner header file !" << endl);
244 Cerr(
"***** iScannerPET::Instantiate() -> An error occurred while trying to read the multiple bed displacement in the scanner header file !" << endl);
274 if (
m_verbose>=
VERBOSE_NORMAL)
Cout(
"iScannerPET::BuildLUT() -> Build LUT for scanner elements coordinates and orientations"<< endl);
277 if (!a_scannerFileIsLUT)
281 Cerr(
"***** iScannerPET::BuildLUT() -> A problem occured while generating scanner LUT !" << endl);
289 Cerr(
"***** iScannerPET::BuildLUT() -> A problem occured while loading scanner LUT !" << endl);
314 Cerr(
"***** iScannerPET::CheckParameters() -> Scanner type not initialized !" << endl);
319 Cerr(
"***** iScannerPET::CheckParameters() -> Verbosity not initialized !" << endl);
324 Cerr(
"***** iScannerPET::CheckParameters() -> Incorrect value for the number of layer (must be >0) !" << endl);
329 Cerr(
"***** iScannerPET::CheckParameters() -> Number of crystals not initialized !" << endl);
334 Cerr(
"***** iScannerPET::CheckParameters() -> Number of crystals in layer(s) not initialized !" << endl);
339 Cerr(
"***** iScannerPET::CheckParameters() -> Crystals central positions not initialized !" << endl);
344 Cerr(
"***** iScannerPET::CheckParameters() -> Crystals orientations not initialized !" << endl);
349 Cerr(
"***** iScannerPET::CheckParameters() -> Crystals dimensions not initialized !" << endl);
354 Cout(
"***** iScannerPET::CheckParameters() -> Mean depth of interaction not initialized !" << endl);
359 Cerr(
"***** iScannerPET::CheckParameters() -> Minimum angle difference not initialized !" << endl);
364 Cerr(
"***** iScannerPET::CheckParameters() -> Scanner type not initialized !" << endl);
369 Cerr(
"***** iScannerPET::CheckParameters() -> Scanner type not initialized !" << endl);
396 Cerr(
"***** iScannerPET::Initialize() -> Parameters have not been checked !" << endl);
434 Cerr(
"***** iScannerPET::LoadLUT() -> An error occurred while trying to read a mandatory parameter in the scanner header file !" << endl);
442 scanner_lut_file = scanner_lut_file.substr(0, scanner_lut_file.find_last_of(
".")).append(
".lut");
445 FILE* LUT_file = fopen(scanner_lut_file.c_str(),
"rb");
448 Cerr(
"***** iScannerPET::LoadLUT() -> Input LUT file '" << scanner_lut_file <<
"' is missing or corrupted !" << endl);
453 int nb_data_read = 0;
458 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
460 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
462 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
465 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
467 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
469 nb_data_read += fread(&buffer,
sizeof(
FLTNBLUT),1,LUT_file);
477 if (nb_data_read!=m_nbCrystals*6)
479 Cerr(
"***** iScannerPET::LoadLUT() -> Failed to read all data in input LUT file '" << scanner_lut_file <<
"' !" << endl);
512 int *nb_ang_rsector_lyr,
522 *rsector_first_angle_lyr,
523 *rsector_angular_span_lyr,
524 *gap_axl_rsector_lyr,
529 *gap_trs_crystal_lyr,
530 *gap_axl_crystal_lyr;
552 string rotation_direction =
"";
564 Cerr(
"***** iScannerPET::ComputeLUT() -> An error occurred while trying to read a mandatory parameter for scanner LUT generation in the scanner header file !" << endl);
574 nb_axl_rsector_lyr[ l ] =1;
575 nb_trs_mod_lyr[ l ] =1;
576 nb_axl_mod_lyr[ l ] =1;
577 nb_trs_submod_lyr[ l ] = 1;
578 nb_axl_submod_lyr[ l ] = 1;
579 gap_axl_rsector_lyr[ l ] = 0.;
580 gap_trs_mod_lyr[ l ] = 0.;
581 gap_axl_mod_lyr[ l ] = 0.;
582 gap_trs_submod_lyr[ l ] = 0.;
583 gap_axl_submod_lyr[ l ] = 0.;
584 gap_trs_crystal_lyr[ l ] = 0.;
585 gap_axl_crystal_lyr[ l ] = 0.;
586 rsector_first_angle_lyr[ l ] = 0;
587 rsector_angular_span_lyr[ l ] = 360.;
606 Cerr(
"***** iScannerPET::ComputeLUT() -> An error occurred while trying to read an optionnal parameter for scanner LUT generation in the scanner header file !" << endl);
611 uint16_t *p_nbRings =
new uint16_t[
m_nbLayers];
613 p_nbRings[lyr] = nb_axl_rsector_lyr[ lyr ]
614 * nb_axl_mod_lyr[ lyr ]
615 * nb_axl_submod_lyr[ lyr ]
616 * nb_axl_crystal_lyr[ lyr ];
621 Cerr(
"***** iScannerPET::ComputeLUT() -> Error occured while trying to initialize head rotation orientation " << endl);
628 int rsector_nb_zshift;
636 Cerr(
"***** iScannerPET::ComputeLUT() -> Error occurred when trying to read z-shift nb !" << endl);
640 else if( rvalue > 1 || rsector_nb_zshift==0)
642 rsector_nb_zshift = 1;
643 zshift =
new FLTNBLUT[rsector_nb_zshift];
649 zshift =
new FLTNBLUT[rsector_nb_zshift];
653 Cerr(
"***** iScannerPET::ComputeLUT() -> No data found about modules z-shift in the scanner header file, whereas z-shift is enabled !" << endl);
659 int nb_crystals_cur = 0;
667 int nb_ang_rsector = nb_ang_rsector_lyr[lyr],
668 nb_axl_rsector = nb_axl_rsector_lyr[lyr],
669 nb_trs_mod = nb_trs_mod_lyr[lyr],
670 nb_axl_mod = nb_axl_mod_lyr[lyr],
671 nb_trs_submod = nb_trs_submod_lyr[lyr],
672 nb_axl_submod = nb_axl_submod_lyr[lyr],
673 nb_trs_crystal = nb_trs_crystal_lyr[lyr],
674 nb_axl_crystal = nb_axl_crystal_lyr[lyr];
677 rsector_first_angle = rsector_first_angle_lyr[lyr],
678 angular_span = rsector_angular_span_lyr[lyr],
679 gap_axl_rsector = gap_axl_rsector_lyr[lyr],
680 gap_trs_mod = gap_trs_mod_lyr[lyr],
681 gap_axl_mod = gap_axl_mod_lyr[lyr],
682 gap_trs_submod = gap_trs_submod_lyr[lyr],
683 gap_axl_submod = gap_axl_submod_lyr[lyr],
684 gap_trs_crystal = gap_trs_crystal_lyr[lyr],
685 gap_axl_crystal = gap_axl_crystal_lyr[lyr];
689 FLTNBLUT size_trs_mod = nb_trs_submod*size_trs_submod + (nb_trs_submod-1)*gap_trs_submod;
690 FLTNBLUT size_axl_mod = nb_axl_submod*size_axl_submod + (nb_axl_submod-1)*gap_axl_submod;
691 FLTNBLUT size_trs_rsector = nb_trs_mod*size_trs_mod + (nb_trs_mod-1)*gap_trs_mod;
692 FLTNBLUT size_axl_rsector = nb_axl_mod*size_axl_mod + (nb_axl_mod-1)*gap_axl_mod;
695 int nb_rsectors = nb_ang_rsector * nb_axl_rsector;
696 int nb_mod = nb_axl_mod * nb_trs_mod;
697 int nb_submod = nb_axl_submod * nb_trs_submod;
698 int nb_crystal = nb_axl_crystal * nb_trs_crystal;
701 int nb_crystals = nb_rsectors*nb_mod*nb_submod*nb_crystal + nb_crystals_cur;
704 Cerr(
"***** iScannerPET::ComputeLUT() -> Computed number of crystals computed from the geom file ("<< nb_crystals
705 <<
") > not consistent with the total number of crystals (including potential layers) provided in the geom file ("<<
m_nbCrystals <<
") !" << endl);
719 oMatrix ******crystal_center =
new oMatrix *****[nb_ang_rsector+1];
721 for(
int rsa = 0; rsa < nb_ang_rsector+1 ; rsa++)
723 crystal_center[rsa] =
new oMatrix ****[ nb_axl_rsector ];
725 for (
int i = 0; i<nb_axl_rsector ; i++)
727 crystal_center[rsa][i] =
new oMatrix ***[ nb_mod ];
729 for (
int j = 0; j<nb_mod ; j++)
731 crystal_center[rsa][i][j] =
new oMatrix **[ nb_submod ];
733 for (
int k = 0; k<nb_submod; k++)
735 crystal_center[rsa][i][j][k] =
new oMatrix*[ nb_crystal ];
737 for (
int l = 0; l<nb_crystal; l++)
739 crystal_center[rsa][i][j][k][l] =
new oMatrix(3,1);
751 for(
int i=0; i<nb_ang_rsector; i++)
752 rotation_mtx[i] =
new oMatrix(3,3);
755 FLTNBLUT rsector_first_angle_rad = rsector_first_angle*M_PI/180.;
756 FLTNBLUT angular_span_rad = angular_span*M_PI/180.;
762 for (
int i = 0; i<nb_ang_rsector; i++)
764 FLTNBLUT angle = remainderf(rsector_first_angle_rad + ((
FLTNBLUT)i)*angular_span_rad/((
FLTNBLUT)(nb_ang_rsector)), 2.*M_PI);
778 for (
int r=0; r < nb_axl_rsector ; r++)
781 FLTNBLUT x_start_r = (-dir*size_trs_rsector) / 2.;
782 FLTNBLUT z_start_r = -(nb_axl_rsector*size_axl_rsector + (nb_axl_rsector-1)*gap_axl_rsector) / 2.;
784 z_start_r += r * (size_axl_rsector + gap_axl_rsector);
786 for (
int i=0; i < nb_mod ; i++)
794 x_start_m += dir*(i%nb_trs_mod) * (size_trs_mod + gap_trs_mod);
795 z_start_m += int(i/nb_trs_mod) * (size_axl_mod + gap_axl_mod);
797 for (
int j=0 ; j < nb_submod ; j++)
802 x_start_sm += dir*(j%nb_trs_submod) * (size_trs_submod + gap_trs_submod);
803 z_start_sm += int(j/nb_trs_submod) * (size_axl_submod + gap_axl_submod);
805 for (
int k=0 ; k < nb_crystal ; k++)
826 for (
int rsa=0 ; rsa<nb_ang_rsector ; rsa++)
827 for (
int rs=0 ; rs<nb_axl_rsector ; rs++)
828 for (
int m=0 ; m<nb_mod ; m++)
829 for (
int sm=0 ; sm<nb_submod ; sm++)
830 for (
int c=0 ; c<nb_crystal ; c++)
833 int cryID = rs * nb_axl_mod * nb_axl_submod * nb_axl_crystal * number_crystals_in_ring
834 + int(m/nb_trs_mod) * nb_axl_submod * nb_axl_crystal * number_crystals_in_ring
835 + int(sm/nb_trs_submod) * nb_axl_crystal * number_crystals_in_ring
836 + int(c/nb_trs_crystal) * number_crystals_in_ring
837 + rsa * nb_trs_mod * nb_trs_submod * nb_trs_crystal
838 + m%nb_trs_mod * nb_trs_submod * nb_trs_crystal
839 + sm%nb_trs_submod * nb_trs_crystal
844 rotation_mtx[rsa]->
Multiplication(crystal_center[0][rs][m][sm][c], crystal_center[rsa+1][rs][m][sm][c]);
863 for (
int rsa = 0; rsa<nb_ang_rsector+1 ; rsa++)
864 for (
int i = 0; i<nb_axl_rsector ; i++)
865 for (
int j = 0; j<nb_mod; j++)
866 for (
int k = 0; k<nb_submod; k++)
867 for (
int l = 0; l<nb_crystal; l++)
869 delete crystal_center[rsa][i][j][k][l];
873 for(
int rsa = 0; rsa < nb_ang_rsector+1 ; rsa++)
874 for(
int i = 0; i < nb_axl_rsector ; i++)
875 for (
int j = 0; j<nb_mod; j++)
876 for (
int k = 0; k<nb_submod; k++)
878 delete[] crystal_center[rsa][i][j][k];
881 for(
int rsa = 0; rsa < nb_ang_rsector+1 ; rsa++)
882 for(
int i = 0; i < nb_axl_rsector ; i++)
883 for (
int j = 0; j<nb_mod; j++)
885 delete[] crystal_center[rsa][i][j];
888 for(
int rsa = 0; rsa < nb_ang_rsector+1 ; rsa++)
889 for(
int i = 0; i < nb_axl_rsector ; i++)
891 delete[] crystal_center[rsa][i];
894 for(
int rsa = 0; rsa < nb_ang_rsector+1 ; rsa++)
895 delete[] crystal_center[rsa];
898 for(
int i = 0; i < nb_ang_rsector ; i++)
899 delete rotation_mtx[i];
901 delete[] crystal_center;
902 delete[] rotation_mtx;
914 string path_to_LUT = path_to_geom_file.substr(0, path_to_geom_file.find_last_of(
"."));
915 string path_to_header_LUT = path_to_LUT +
".ghscan";
916 path_to_LUT.append(
".glut");
920 ofstream LUT_file, header_LUT_file;
921 LUT_file.open(path_to_LUT.c_str(), ios::binary | ios::out);
939 header_LUT_file.open(path_to_header_LUT.c_str(), ios::out);
941 string scanner_name = path_to_geom_file.substr(0, path_to_geom_file.find_last_of(
"."));
942 header_LUT_file <<
"scanner name:" <<
" " <<
GetFileFromPath(scanner_name) << endl;
943 header_LUT_file <<
"modality:" <<
" " <<
"PET" << endl;
945 header_LUT_file <<
"scanner radius:" <<
" " << radius_lyr[0];
947 header_LUT_file <<
"," << radius_lyr[lyr] ; header_LUT_file << endl;
949 header_LUT_file <<
"number of elements:" <<
" " << m_nbCrystals << endl;
950 header_LUT_file <<
"number of layers:" <<
" " << m_nbLayers << endl;
953 header_LUT_file <<
","<< mp_nbCrystalsInLayer[lyr] ; header_LUT_file << endl;
957 header_LUT_file <<
","<< mp_sizeCrystalDepth[lyr] ; header_LUT_file << endl;
961 header_LUT_file <<
","<< mp_sizeCrystalTrans[lyr] ; header_LUT_file << endl;
965 header_LUT_file <<
","<< mp_sizeCrystalAxial[lyr] ; header_LUT_file << endl;
968 uint32_t def_dim_trs = 0, def_dim_axl = 0;
969 FLTNB def_FOV_trs = -1., def_FOV_axl = -1;
976 Cerr(
"***** iScannerPET::ComputeLUT() -> Error occurred when trying to read transaxial/axial dimensions and voxel sizes from scanner geom file !" << endl);
980 header_LUT_file <<
"voxels number transaxial:" <<
" " << def_dim_trs << endl;
981 header_LUT_file <<
"voxels number axial:" <<
" " << def_dim_axl << endl;
983 header_LUT_file <<
"field of view transaxial:" <<
" " << def_FOV_trs << endl;
984 header_LUT_file <<
"field of view axial:" <<
" " << def_FOV_axl << endl;
990 header_LUT_file <<
"," << mp_meanDepthOfInteraction[lyr] ;
991 header_LUT_file <<
" #optional (default value : center of crystal ). Input value must correspond to the distance from the crystal surface, or negative value if default" << endl;
995 if(
m_verbose>=2)
Cout(
"iScannerPET::ComputeLUT() -> Header LUT file writing completed" << endl);
999 delete[] nb_ang_rsector_lyr;
1000 delete[] nb_axl_rsector_lyr;
1001 delete[] nb_trs_mod_lyr;
1002 delete[] nb_axl_mod_lyr;
1003 delete[] nb_trs_submod_lyr;
1004 delete[] nb_axl_submod_lyr;
1005 delete[] nb_trs_crystal_lyr;
1006 delete[] nb_axl_crystal_lyr;
1008 delete[] radius_lyr;
1009 delete[] rsector_angular_span_lyr;
1010 delete[] rsector_first_angle_lyr;
1012 delete[] gap_axl_rsector_lyr;
1013 delete[] gap_trs_mod_lyr;
1014 delete[] gap_axl_mod_lyr;
1015 delete[] gap_trs_submod_lyr;
1016 delete[] gap_axl_submod_lyr;
1017 delete[] gap_trs_crystal_lyr;
1018 delete[] gap_axl_crystal_lyr;
1047 FLTNB ap_Position1[3],
FLTNB ap_Position2[3],
1048 FLTNB ap_Orientation1[3],
FLTNB ap_Orientation2[3],
1056 Cerr(
"***** iScannerPET::GetPositionsAndOrientations() -> Crystal index 1 (" << a_index1 <<
") out of range [0:" <<
m_nbCrystals-1 <<
"] !" << endl);
1061 Cerr(
"***** iScannerPET::GetPositionsAndOrientations() -> Crystal index 2 (" << a_index2 <<
") out of range [0:" <<
m_nbCrystals-1 <<
"] !" << endl);
1084 else if (ap_POI1[2]<0.)
1089 else if (ap_POI1[0]==0. && ap_POI1[1]==0.)
1111 else if (ap_POI2[2]<0.)
1116 else if (ap_POI2[0]==0. && ap_POI2[1]==0.)
1164 FLTNB ap_Position1[3],
FLTNB ap_Position2[3],
1165 FLTNB ap_Orientation1[3],
FLTNB ap_Orientation2[3] )
1172 Cerr(
"***** iScannerPET::GetRdmPositionsAndOrientations() -> Crystal index 1 (" << a_index1 <<
") out of range [0:" <<
m_nbCrystals-1 <<
"] !" << endl);
1177 Cerr(
"***** iScannerPET::GetRdmPositionsAndOrientations() -> Crystal index 2 (" << a_index2 <<
") out of range [0:" <<
m_nbCrystals-1 <<
"] !" << endl);
1184 Cerr(
"***** iScannerPET::GetRdmPositionsAndOrientations() -> Crystal sizes are unknown or equal to 0. Crystal dimensions are mandatory for this function !" << endl);
1199 FLTNB axial1 = (rdm_axl1-0.5) * size_crystalAxial1;
1200 FLTNB trans1 = (rdm_trs1-0.5) * size_crystalTrans1;
1201 FLTNB depth1 = (rdm_depth1-0.5) * size_crystalDepth1;
1214 + depth1 * mp_crystalOrientationZ[a_index1]
1215 + axial1 * sqrt(1-mp_crystalOrientationZ[a_index1] * mp_crystalOrientationZ[a_index1]);
1220 ap_Orientation1[2] = mp_crystalOrientationZ[a_index1];
1231 FLTNB axial2 = (rdm_axl2-0.5) * size_crystalAxial2;
1232 FLTNB trans2 = (rdm_trs2-0.5) * size_crystalTrans2;
1233 FLTNB depth2 = (rdm_depth2-0.5) * size_crystalDepth2;
1246 + depth2 * mp_crystalOrientationZ[a_index2]
1247 + axial2 * sqrt(1-mp_crystalOrientationZ[a_index2] * mp_crystalOrientationZ[a_index2]);
1252 ap_Orientation2[2] = mp_crystalOrientationZ[a_index2];
1318 FLTNB ap_CornerInf1[3],
FLTNB ap_CornerSup1[3],
1319 FLTNB ap_CornerInf2[3],
FLTNB ap_CornerSup2[3])
1325 Cerr(
"***** iScannerPET::GetTwoCorners() -> Crystal index out of range !" << endl);
1332 Cerr(
"***** iScannerPET::GetRdmPositionsAndOrientations() -> Crystal sizes are unknown or equal to 0. Crystal dimensions are mandatory for this function !" << endl);
1336 Cerr(
"***** iScannerPET::GetTwoCorners() -> Not implemented yet !" << endl);
1346 FLTNB ap_pos_line_point1[3],
FLTNB ap_pos_line_point2[3],
1347 FLTNB ap_pos_point1_x[4],
FLTNB ap_pos_point1_y[4],
FLTNB ap_pos_point1_z[4],
1348 FLTNB ap_pos_point2_x[4],
FLTNB ap_pos_point2_y[4],
FLTNB ap_pos_point2_z[4]
1356 Cerr(
"***** iScannerPET::GetEdgesCenterPositions() -> Crystal indices out of range !" << endl);
1369 ap_pos_point1_x[ 0 ] = ap_pos_line_point1[ 0 ] - half_crystal_trans_1 *
mp_crystalOrientationY[ a_index1 ];
1370 ap_pos_point1_x[ 1 ] = ap_pos_line_point1[ 0 ] + half_crystal_trans_1 * mp_crystalOrientationY[ a_index1 ];
1371 ap_pos_point1_x[ 2 ] = ap_pos_line_point1[ 0 ];
1372 ap_pos_point1_x[ 3 ] = ap_pos_line_point1[ 0 ];
1375 ap_pos_point1_y[ 0 ] = ap_pos_line_point1[ 1 ] + half_crystal_trans_1 *
mp_crystalOrientationX[ a_index1 ];
1376 ap_pos_point1_y[ 1 ] = ap_pos_line_point1[ 1 ] - half_crystal_trans_1 * mp_crystalOrientationX[ a_index1 ];
1377 ap_pos_point1_y[ 2 ] = ap_pos_line_point1[ 1 ];
1378 ap_pos_point1_y[ 3 ] = ap_pos_line_point1[ 1 ];
1381 ap_pos_point1_z[ 0 ] = ap_pos_line_point1[ 2 ];
1382 ap_pos_point1_z[ 1 ] = ap_pos_line_point1[ 2 ];
1383 ap_pos_point1_z[ 2 ] = ap_pos_line_point1[ 2 ] - half_crystal_axial_1;
1384 ap_pos_point1_z[ 3 ] = ap_pos_line_point1[ 2 ] + half_crystal_axial_1;
1389 ap_pos_point2_x[ 0 ] = ap_pos_line_point2[ 0 ] + half_crystal_trans_2 * mp_crystalOrientationY[ a_index2 ];
1390 ap_pos_point2_x[ 1 ] = ap_pos_line_point2[ 0 ] - half_crystal_trans_2 * mp_crystalOrientationY[ a_index2 ];
1391 ap_pos_point2_x[ 2 ] = ap_pos_line_point2[ 0 ];
1392 ap_pos_point2_x[ 3 ] = ap_pos_line_point2[ 0 ];
1395 ap_pos_point2_y[ 0 ] = ap_pos_line_point2[ 1 ] - half_crystal_trans_2 * mp_crystalOrientationX[ a_index2 ];
1396 ap_pos_point2_y[ 1 ] = ap_pos_line_point2[ 1 ] + half_crystal_trans_2 * mp_crystalOrientationX[ a_index2 ];
1397 ap_pos_point2_y[ 2 ] = ap_pos_line_point2[ 1 ];
1398 ap_pos_point2_y[ 3 ] = ap_pos_line_point2[ 1 ];
1401 ap_pos_point2_z[ 0 ] = ap_pos_line_point2[ 2 ];
1402 ap_pos_point2_z[ 1 ] = ap_pos_line_point2[ 2 ];
1403 ap_pos_point2_z[ 2 ] = ap_pos_line_point2[ 2 ] - half_crystal_axial_2;
1404 ap_pos_point2_z[ 3 ] = ap_pos_line_point2[ 2 ] + half_crystal_axial_2;
1427 while (a_idx >= sum_crystals)
1465 abs_angle = (abs_angle>1.) ? 1 : abs_angle;
1466 abs_angle = (abs_angle<-1.) ? -1 : abs_angle;
1468 FLTNB angle_diff = acos(abs_angle);
1503 Cerr(
"***** iScannerPET::GetGeometricInfoFromDataFile() -> Error while reading max number of ring difference in the header data file '" << endl);
1530 Cerr(
"***** iScannerPET::PROJ_GetPETSpecificParameters() -> Parameters have not been checked !" << endl);
1550 cout <<
"This scanner class is dedicated to the description of PET systems." << endl;
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...
#define VERBOSE_DEBUG_MAX
int CheckParameters()
Check if all parameters have been correctly initialized.
static sScannerManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
static sRandomNumberGenerator * 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_sizeCrystalAxial
int Instantiate(bool a_scannerFileIsLUT)
Get mandatory informations from the scanner file and allocate memory for the member variables...
int IsAvailableLOR(int a_elt1, int a_elt2)
Check if the LOR formed by the crystalf whose indices are passed in parameters is available according...
FLTNB * mp_crystalOrientationX
int Initialize()
Check general initialization and set several parameters to their default value.
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.
FLTNB m_minAngleDifference
FLTNB * mp_crystalOrientationY
oMatrix * mp_positionMatrix_out
FLTNB m_defaultBedDisplacementInMm
FLTNB * mp_meanDepthOfInteraction
string GetPathToScannerFile()
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 random positions of the scanner elements and their orientations from their indices.
FLTNB * mp_crystalOrientationZ
string GetFileFromPath(const string &a_pathToFile)
Simply return the file from a path string passed in parameter.
Declaration of class iScannerPET.
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...
FLTNB * mp_crystalCentralPositionZ
oMatrix * mp_rotationMatrix
int GetGeometricInfoFromDataFile(string a_pathToDataFilename)
Retrieve PET geometric informations from the datafile.
#define VERBOSE_DEBUG_LIGHT
virtual int SetRotDirection(string a_rotDirection)
Set rotation direction of the system.
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...
Singleton class that Instantiate and initialize the scanner object.
int GetLayer(int a_idx)
Get the layer from which the 'a_index' crystal belongs to.
int SetMatriceElt(uint16_t l, uint16_t c, FLTNB a_val)
Set the matrix element corresponding to the argument indices with the provided value.
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)
Get the central positions and orientations of the scanner elements from their indices.
Declaration of class sScannerManager.
bool SaveLUTFlag()
Get flag indicating a LUT generated by a geom file should be written on disk or not.
FLTNB * mp_sizeCrystalDepth
int PROJ_GetPETSpecificParameters(FLTNB *ap_maxAxialDiffmm)
Set pointers passed in argument with the related PET specific variables This function is used to reco...
HPFLTNB GenerateRdmNber()
Generate a random number for the thread which index is recovered from the OpenMP function.
bool m_allParametersChecked
#define KEYWORD_MANDATORY
FLTNB * mp_crystalCentralPositionY
Singleton class that generate a thread-safe random generator number for openMP As singleton...
int LoadLUT()
Load a precomputed scanner LUT.
iScannerPET()
iScannerPET constructor. Initialize the member variables to their default values. ...
Declaration of class sOutputManager.
void ShowHelp()
Display help.
oMatrix * mp_positionMatrix_ref
Structure designed for basic matrices operations.
FLTNB * mp_crystalCentralPositionX
FLTNB * mp_sizeCrystalTrans
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
~iScannerPET()
iScannerPET destructor.
int BuildLUT(bool a_scannerFileIsLUT)
Call the functions to generate the LUT or read the user-made LUT depending on the user choice...
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 ...
void DescribeSpecific()
Implementation of the pure virtual eponym function that simply prints info about the scanner...
Generic class for scanner objects.
int * mp_nbCrystalsInLayer
#define KEYWORD_OPTIONAL_ERROR
bool FLTNBIsEqual(FLTNB a, FLTNB b, FLTNB a_eps)
Comparison of FLTNB numbers.
int ComputeLUT()
Compute the LUT of the scanner from a generic (.geom) file.