9 #include "gVariables.hh" 10 #include "gOptions.hh" 11 #include "oAnalyticProjection.hh" 12 #include "oImageConvolverManager.hh" 13 #include "oImageDimensionsAndQuantification.hh" 14 #include "iDataFilePET.hh" 15 #include "iDataFileSPECT.hh" 16 #include "sOutputManager.hh" 17 #include "sScannerManager.hh" 18 #include "sRandomNumberGenerator.hh" 19 #include "iScannerPET.hh" 35 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
36 if (mpi_rank!=0)
return;
41 cout <<
"Usage: castor-proj.exe -img path_to_file.hdr -sc name -(f/d)out output [settings]" << endl;
43 cout <<
"[Main options]:" << endl;
44 cout <<
" -img path_to_img.hdr : Give the interfile header of the image to project (no default)." << endl;
45 cout <<
" -sc scanner_alias : Give the scanner model. It must correspond to the name of one of the file in the scanner repository (w/o file extension)" << endl;
46 cout <<
" -fout name : Give the root name for all output files (no default, alternative to -dout)" << endl;
47 cout <<
" -dout name : Give the name of the output directory where all output files will be written (no default, alternative to -fout)" << endl;
48 cout <<
" -fileType type : Give the type of events that will be generated : ('TYPE_PET' ou '0' = PET, 'TYPE_SPECT' ou '1' = SPECT) (default : TYPE_PET)" << endl;
49 cout <<
" -vb : Give the verbosity level, from 0 (no verbose) to above 5 (at the event level) (default: 1)." << endl;
51 cout <<
"[Specific options]:" << endl;
52 cout <<
" -help-in : Print out specific help about input settings." << endl;
53 cout <<
" -help-out : Print out specific help about output settings." << endl;
54 cout <<
" -help-proj : Print out specific help about projector settings." << endl;
55 cout <<
" -help-comp : Print out specific help about computing settings." << endl;
56 cout <<
" -help-misc : Print out specific help about miscellaneous and verbose settings." << endl;
57 cout <<
" -help-dynamic : Print out specific help about dynamic options." << endl;
58 cout <<
" -help-pet : Print out specific help about PET settings for analytic projection." << endl;
59 cout <<
" -help-spect : Print out specific help about SPECT settings for analytic projection." << endl;
61 cout <<
"[Implemented Modules]:" << endl;
62 cout <<
" -help-scan : Show the list of all scanners from the configuration directory." << endl;
63 cout <<
" -help-projm : Show the list and description of all implemented projectors." << endl;
65 cout <<
" --help,-h,-help : Print out this help page." << endl;
68 cout <<
" Compiled with MPI" << endl;
71 cout <<
" Compiled with OpenMP" << endl;
74 cout <<
" Compiled for GPU" << endl;
76 #if defined(CASTOR_OMP) || defined(CASTOR_MPI) || defined(CASTOR_GPU) 80 cout <<
" Build date: " << BUILD_DATE << endl;
84 cout <<
" This program is part of the CASToR release version " <<
CASTOR_VERSION <<
"." << endl;
106 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
107 if (mpi_rank!=0)
return;
111 cout <<
"[Input settings]:" << endl;
113 cout <<
" -off x,y,z : Give the offset of the field-of-view in each dimension, in mm (default: 0.,0.,0.)." << endl;
115 cout <<
" -atn path_to_img.hdr : Give the interfile header of an input attenuation image (unit has to be cm-1) (default: uniform value)." << endl;
117 cout <<
" -help-in : Print out this help." << endl;
136 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
137 if (mpi_rank!=0)
return;
141 cout <<
"[Output settings]:" << endl;
143 cout <<
" -fout name : Give the root name for all output files. All output files will be written as 'name_suffix.ext'." << endl;
144 cout <<
" So the provided name should not end with '.' or '/' character. (no default, alternative to -dout)" << endl;
145 cout <<
" -dout name : Give the name of the output directory where all output files will be written. All files will also" << endl;
146 cout <<
" be prefixed by the name of the directory. The provided name should not end with '.' or '/' character." << endl;
147 cout <<
" (no default, alternative to -fout)" << endl;
149 cout <<
" -olut : If a scanner LUT (geometry information) is computed from a .geom file, it will be written on disk in the scanner repository" << endl;
151 cout <<
" -onbp prec : By default, numbers are displayed using scientific format. This option allows to customize the format and precision" << endl;
152 cout <<
" : The format is format,precision. f is the format (s=scientific, f=fixed), p is the precision" << endl;
153 cout <<
" eg: -onbp f,5 --> fixed with 5 digits precision, -onbp --> scientifici with max precision." << endl;
155 cout <<
" -help-out : Print out this help." << endl;
174 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
175 if (mpi_rank!=0)
return;
178 cout <<
"[Projector settings]:" << endl;
180 cout <<
" -proj param : Give the projector to be used for both forward and backward projections, along with a configuration file (proj:file.conf)" << endl;
181 cout <<
" or the list of parameters associated to the projector (proj,param1,param2,...). If the projector only is specified, the" << endl;
182 cout <<
" default configuration file is used. By default, the Siddon projector is used." << endl;
184 cout <<
" -proj-comp : Give the strategy for projection line computation. Here are the three different strategies that can be used:" << endl;
185 cout <<
" 1 : Image-based system matrix elements storage: The voxels weights are added in a matrix representing the whole image, so" << endl;
186 cout <<
" the addition of a new line to the previous ones is straightforward only by adding the weights to the corresponding voxels." << endl;
187 cout <<
" As it is insanely long, it can possibly be used for example with extremely complex projectors that makes use of huge number" << endl;
188 cout <<
" of ray tracings for a single event, where the list of contributions can become longer than the number of voxels in the image." << endl;
189 cout <<
" 2 : Fixed-size list storage of system matrix elements: The voxels are added one by one in two separated lists, one containing voxel" << endl;
190 cout <<
" indices and the other voxel weights. When a voxel is added to the oProjectionLine, it is simply pilled-up to the list. The list" << endl;
191 cout <<
" has a fixed size which is provided by the EstimateMaxNumberOfVoxelsPerLine() function from the vProjector class. There are no" << endl;
192 cout <<
" ckecks at all for possible buffer overflows. This is the fastest strategy and default one." << endl;
193 cout <<
" 3 : Adaptative-size list storage of system matrix elements: This is the same as the fixed-size strategy except that the size can be" << endl;
194 cout <<
" upgraded if the current number of contributing voxels exceed the list's size. The first allocated size corresponds to the diagonal" << endl;
195 cout <<
" of the image. During the first iteration, this size will be upgraded until it will reach a size suitable for all events. Thus it" << endl;
196 cout <<
" is a bit slower than the fixed-list strategy during the first iteration, but is optimal with respect to RAM usage." << endl;
198 cout <<
" -help-projm : Print out specific help about projector settings." << endl;
200 cout <<
" -help-proj : Print out this help." << endl;
219 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
220 if (mpi_rank!=0)
return;
224 cout <<
"[Computation settings]:" << endl;
227 cout <<
" -th param : Set the number of threads for parallel computation (default: 1). If 0 is given, then the maximum number of available threads is automatically determined." << endl;
228 cout <<
" Can also give two parameters separated by a comma (e.g. 16,4), to distinguish between the number of threads for projection and image operations respectively." << endl;
232 cout <<
" -gpu : Flag to say that we want to use the GPU device (default: use the CPU only)." << endl;
235 cout <<
" -conv param : Give an image convolver model to be used within the algorithm, along with a configuration file (conv:file.conf) or the" << endl;
236 cout <<
" list of parameters associated to the convolver (conv,param1,param2,...). If the convolver only is specified, its default" << endl;
237 cout <<
" configuration file is used. By default, no convolver is applied" << endl;
239 cout <<
" -help-conv : Show the list and description of all implemented image convolvers." << endl;
241 cout <<
" -noise poisson : Give the noise model to be used. Only Poisson noise is implemented for the moment (default : no noise model)" << endl;
243 cout <<
" -rng : Give a seed for the random number generator (should be >=0)" << endl;
245 cout <<
" -no0 : Discard zero events (not saved)." << endl;
247 cout <<
" -help-comp : Print out this help." << endl;
250 cout <<
" Compiled with MPI" << endl;
253 cout <<
" Compiled with OpenMP" << endl;
256 cout <<
" Compiled for GPU" << endl;
258 #if defined(CASTOR_OMP) || defined(CASTOR_MPI) || defined(CASTOR_GPU) 278 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
279 if (mpi_rank!=0)
return;
283 cout <<
"[Dynamic settings]:" << endl;
285 cout <<
" -frm list : Give the framing for the reconstruction where 'list' is a list of all frames durations in seconds separated" << endl;
286 cout <<
" by commas. To specify a dead frame, add 'df' concatenated to the frame duration. Milliseconds maximum precision." << endl;
287 cout <<
" (default: read from the 'image duration (sec)' key in the interfile image header" << endl;
289 cout <<
" (about gated images) : An image contening several respiratory/cardiac 'gates' can be provided to generate one datafile containing histograms of these gated images." << endl;
290 cout <<
" The number of gates being directly read from the 'number of respiratory gates' and 'number of cardiac gates' keys in the interfile header" << endl;
292 cout <<
" -help-dynamic : Print out this help." << endl;
311 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
312 if (mpi_rank!=0)
return;
315 cout <<
"[SPECT settings]:" << endl;
317 cout <<
" -SPECT_bins par : Give two integer parameters corresponding to the transaxial number of bins, separated by a comma (nbBinsX, nbBinsY). " << endl;
318 cout <<
" Default = transaxial number of pixels in the SPECT scanner file " << endl;
320 cout <<
" -SPECT_ang par : Give the total number of projections, followed by the first angle and the angle step in float" << endl;
321 cout <<
" Format : nb_projs:first_angle,step_angle" << endl;
323 cout <<
" -SPECT_c_ang par : SPECT custom angles : give the total number of projections, followed by the projections angles in float" << endl;
324 cout <<
" Format : nb_projs:angle1,angle2,... " << endl;
326 cout <<
" -SPECT_radius par : Give a distance between center of rotation to detectors which will be used for all heads" << endl;
328 cout <<
" -SPECT_rot par : Give the heads rotation direction. Accept two parameters: CW (clockwise, default), CCW (counter-clockwise)" << endl;
330 cout <<
" -help-spect : Print out this specific help." << endl;
349 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
350 if (mpi_rank!=0)
return;
353 cout <<
"[PET settings]:" << endl;
355 cout <<
" -PET_maxAxialDiffmm param : Set the maximum axial difference in mm between two crystals in a LOR (default = no restriction)" << endl;
374 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
375 if (mpi_rank!=0)
return;
379 cout <<
"[Miscellaneous settings]:" << endl;
381 cout <<
" -vb : Give the general verbosity level, from 0 (no verbose) to 5 and above (at the event level) (default: 1)." << endl;
382 cout <<
" -vb-algo : Give the verbose level specific to the analytic projection algorithm (default: same as general verbose level)." << endl;
383 cout <<
" -vb-proj : Give the verbose level specific to the projector (default: same as general verbose level)." << endl;
384 cout <<
" -vb-conv : Give the verbose level specific to the image convolver (default: same as general verbose level)." << endl;
385 cout <<
" -vb-scan : Give the verbose level specific to the scanner (default: same as general verbose level)." << endl;
386 cout <<
" -vb-data : Give the verbose level specific to the data and image management (default: same as general verbose level)." << endl;
388 cout <<
" -conf : Give the path to the CASToR config directory (default: located through the CASTOR_CONFIG environment variable)." << endl;
390 cout <<
" -help-misc : Print out this help." << endl;
405 int main(
int argc,
char** argv)
414 MPI_Init(&argc, &argv );
415 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
416 MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
421 if (mpi_rank==0) cout << endl;
429 int nb_VoxX=-1, nb_VoxY=-1, nb_VoxZ=-1;
430 FLTNB fov_SizeX=-1, fov_SizeY=-1, fov_SizeZ=-1;
431 FLTNB vox_SizeX=-1, vox_SizeY=-1, vox_SizeZ=-1;
433 FLTNB offsetX = 0, offsetY = 0, offsetZ = 0;
436 string path_to_initial_img =
"";
438 string path_to_attenuation_img =
"";
440 string scanner_name =
"";
447 string frame_list =
"";
448 FLTNB acquisition_duration_sec = 0.;
451 int nb_resp_gates = 1;
453 int nb_card_gates = 1;
459 FLTNB max_axial_diff_mm = -1.;
462 string path_dout =
"";
464 string path_fout =
"";
467 bool save_LUT_flag =
false;
470 string noise_model =
"";
473 string options_projector =
"incrementalSiddon";
479 vector<string> options_image_convolver;
482 bool discard_nil_events_flag =
false;
485 bool gpu_flag =
false;
487 int data_file_percentage_load = 0;
490 string onb_prec =
"s,0";
493 int verbose_general = 1,
501 string path_to_config_dir =
"";
504 int64_t seed_RNG = -1;
506 string nb_threads =
"1";
511 uint16_t SPECT_nb_bins[2] = {0, 0};
513 uint32_t SPECT_nb_projection_angles = 0;
515 FLTNB* SPECT_projection_angles = NULL;
517 FLTNB SPECT_first_angle= -1., SPECT_step_angle=-1.;
519 FLTNB SPECT_radius = -1.;
521 string SPECT_rot =
"CW";
527 for (
int i=1; i<argc; i++)
529 string option = (string)argv[i];
531 if (option==
"-h" || option==
"--help" || option==
"-help")
ShowHelp(0,mpi_rank);
534 else if (option==
"-help-scan")
537 Cerr(
"***** castor-proj() -> An error occurred when trying to output the available scanners from the scanner repository !'" << endl;);
543 else if (option==
"-help-projm")
553 else if (option==
"-help-conv")
564 else if (option==
"-help-in")
570 else if (option==
"-help-out")
576 else if (option==
"-help-proj")
582 else if (option==
"-help-comp")
588 else if (option==
"-help-dynamic")
594 else if (option==
"-help-pet")
600 else if (option==
"-help-spect")
606 else if (option==
"-help-misc")
612 else if (option==
"-off")
616 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
624 Cerr(
"***** castor-proj() -> Invalid argument " << argv[i+1] <<
" for option " << option <<
" !" << endl);
634 else if (option==
"-frm")
638 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
641 frame_list = (string)argv[i+1];
646 else if (option==
"-sc")
650 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
653 scanner_name = argv[i+1];
658 else if (option==
"-img")
662 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
665 path_to_initial_img = argv[i+1];
670 else if (option==
"-fileType")
674 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
678 string input_str = argv[i+1];
680 if(!input_str.compare(
"TYPE_PET") )
682 else if(!input_str.compare(
"TYPE_SPECT") )
684 else if(!input_str.compare(
"TYPE_CT") )
690 Cerr(
"***** castor-proj() -> Exception when trying to read provided entry '" << input_str <<
" for option: " << option << endl);
699 else if (option==
"-atn")
703 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
706 path_to_attenuation_img = argv[i+1];
711 else if (option==
"-bed")
715 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
718 nb_beds = atoi(argv[i+1]);
723 else if (option==
"-PET_maxAxialDiffmm")
727 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
730 max_axial_diff_mm = atoi(argv[i+1]);
735 else if (option==
"-dout")
739 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
742 path_dout = argv[i+1];
746 else if (option==
"-fout")
750 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
753 path_fout = argv[i+1];
757 else if (option==
"-olut")
759 save_LUT_flag =
true;
762 else if (option==
"-onbp")
766 Cerr(
"***** castor-recon() -> Argument missing for option: " << option << endl);
769 onb_prec = argv[i+1];
772 else if (option==
"-noise")
776 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
779 noise_model = argv[i+1];
783 else if (option==
"-proj")
787 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
790 options_projector = (string)argv[i+1];
795 else if (option==
"-proj-comp")
799 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
802 projector_computation_strategy = atoi(argv[i+1]);
807 else if (option==
"-conv")
811 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
814 string convolver = (string)argv[i+1];
815 convolver.append(
"::forward");
816 options_image_convolver.push_back(convolver);
821 else if (option==
"-no0")
823 discard_nil_events_flag =
true;
829 else if (option==
"-vb")
833 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
838 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_general <<
" for option: " << option << endl);
845 else if (option==
"-vb-algo")
849 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
854 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_algo <<
" for option: " << option << endl);
861 else if (option==
"-vb-proj")
865 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
870 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_proj <<
" for option: " << option << endl);
877 else if (option==
"-vb-conv")
881 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
886 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_conv <<
" for option: " << option << endl);
893 else if (option==
"-vb-scan")
897 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
902 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_scan <<
" for option: " << option << endl);
909 else if (option==
"-vb-data")
913 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
918 Cerr(
"***** castor-proj() -> Exception when trying to read provided verbosity level '" << verbose_data <<
" for option: " << option << endl);
926 else if (option==
"-rng")
930 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
935 Cerr(
"***** castor-proj() -> Exception when trying to read provided number '" << seed_RNG <<
" for option: " << option << endl);
942 else if (option==
"-conf")
946 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
949 path_to_config_dir = (string)argv[i+1];
954 else if (option==
"-gpu")
960 else if (option==
"-th")
964 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
967 nb_threads = (string)argv[i+1];
972 else if (option==
"-load")
976 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
979 data_file_percentage_load = atoi(argv[i+1]);
980 if (data_file_percentage_load>100 || data_file_percentage_load<0)
982 Cerr(
"***** castor-proj() -> Incorrect initialization of the size data buffer" << endl);
983 Cerr(
" Number provided: " << argv[i+1] <<
" is not in the expected [0;100] interval" << endl);
988 else if (option==
"-SPECT_bins")
992 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
998 Cerr(
"***** castor-proj() -> Invalid argument " << argv[i+1] <<
" for option " << option <<
" !" << endl);
999 Cerr(
"***** castor-proj() -> Expected two uint16 parameters separated by a comma" << endl);
1007 else if (option==
"-SPECT_c_ang")
1011 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
1016 string input_str = argv[i+1];
1017 size_t colon = input_str.find_first_of(
":");
1019 if (colon==string::npos)
1021 Cerr(
"***** castor-proj() -> Parsing error : colon missing in option: " << option << endl);
1028 Cerr(
"***** castor-proj() -> An error occurred while trying to read the number of SPECT projection values " << input_str.substr(0,colon) <<
" for option " << option <<
" !" << endl);
1032 SPECT_projection_angles =
new FLTNB[SPECT_nb_projection_angles];
1034 if(
ReadStringOption(input_str.substr(colon+1), SPECT_projection_angles, SPECT_nb_projection_angles,
",", option))
1036 Cerr(
"***** castor-proj() -> Invalid argument " << argv[i+1] <<
" for option " << option <<
" !" << endl);
1044 else if (option==
"-SPECT_ang")
1048 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
1053 string input_str = argv[i+1];
1054 size_t colon = input_str.find_first_of(
":");
1056 if (colon==string::npos)
1058 Cerr(
"***** castor-proj() -> Parsing error : colon missing in option: " << option << endl);
1065 Cerr(
"***** castor-proj() -> An error occurred while trying to read the number of SPECT projection values " << input_str.substr(0,colon) <<
" for option " << option <<
" !" << endl);
1072 Cerr(
"***** castor-proj() -> Invalid argument " << argv[i+1] <<
" for option " << option <<
" !" << endl);
1077 SPECT_first_angle = input[0];
1078 SPECT_step_angle = input[1];
1084 else if (option==
"-SPECT_radius")
1088 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
1096 Cerr(
"***** castor-proj() -> An error occurred while trying to read the SPECT global radius " << argv[i+1] <<
" for option " << option <<
" !" << endl);
1103 else if (option==
"-SPECT_rot")
1107 Cerr(
"***** castor-proj() -> Argument missing for option: " << option << endl);
1113 SPECT_rot = argv[i+1];
1115 if(SPECT_rot !=
"CW" && SPECT_rot !=
"CCW")
1117 Cerr(
"***** castor-proj() -> '" << SPECT_rot <<
"' is unknown argument for option " << option <<
".");
1118 Cerr(
" SPECT rotation direction must be either 'CW' (clockwise) or 'CCW' (counter-clockwise) !" << endl);
1127 if (mpi_rank==0)
Cerr(
"***** castor-proj() -> Unknown option '" << option <<
"' !" << endl);
1134 MPI_Barrier(MPI_COMM_WORLD);
1139 if (verbose_algo==-1) verbose_algo = verbose_general;
1140 if (verbose_proj==-1) verbose_proj = verbose_general;
1141 if (verbose_conv==-1) verbose_conv = verbose_general;
1142 if (verbose_scan==-1) verbose_scan = verbose_general;
1143 if (verbose_data==-1) verbose_data = verbose_general;
1156 if (scanner_name.empty())
1158 Cerr(
"***** castor-proj() -> Please provide a scanner name (format: Modality_Constuctor_Model) :" << endl);
1159 Cerr(
" -sc scanner_alias: Give the scanner model." << endl);
1160 Cerr(
" It must correspond to the name of one of the file in the scanner repository (without file extension)" << endl);
1165 if (verbose_general>=2)
Cout(
" selected scanner name: " << scanner_name << endl);
1169 if (path_fout.empty() && path_dout.empty())
1171 Cerr(
"***** castor-proj() -> Please provide an output option for output files (-fout or -dout) !" << endl);
1175 if (!path_fout.empty() && !path_dout.empty())
1177 Cerr(
"***** castor-proj() -> Please provide either output option -fout or -dout but not both !" << endl);
1182 if (path_to_initial_img.empty())
1184 Cerr(
"***** castor-proj() -> -img path_to_img.hdr : Give an interfile header of the image to project" << endl);
1189 if (verbose_general>=2)
Cout(
" selected input image path: " << path_to_initial_img << endl);
1207 p_outputManager->
SetVerbose(verbose_general);
1210 vector <string> vpath_to_initial_img;
1211 vpath_to_initial_img.push_back(path_to_initial_img);
1219 Cerr(
"***** castor-proj() -> A problem occurred while checking for the config directory path !" << endl);
1226 Cerr(
"***** castor-proj() -> A problem occurred while initializing output directory !" << endl);
1232 Cerr(
"***** castor-proj() -> A problem occurred while logging command line arguments !" << endl);
1253 scanner_name = (scanner_name.find(
OS_SEP)) ?
1254 scanner_name.substr(scanner_name.find_last_of(
OS_SEP)+1) :
1259 Cerr(
"***** castor-proj() -> A problem occurred while searching for scanner system !" << endl);
1265 Cerr(
"***** castor-proj() -> A problem occurred during scanner object construction !" << endl);
1271 Cerr(
"***** castor-proj() -> A problem occurred while creating Scanner object !" << endl);
1281 Cerr(
"***** castor-proj() -> A problem occurred while setting PET geometric parameters !" << endl);
1288 SPECT_nb_projection_angles,
1291 SPECT_projection_angles,
1295 Cerr(
"***** castor-proj() -> A problem occurred while setting SPECT geometric parameters !" << endl);
1303 Cerr(
"***** castor-proj() -> A problem occurred while generating/reading the LUT !" << endl);
1311 Cerr(
"***** castor-proj() -> A problem occurred while checking scanner manager parameters !" << endl);
1316 Cerr(
"***** castor-proj() -> A problem occurred while initializing scanner !" << endl);
1330 Cerr(
"***** castor-proj() -> An error occurred while trying to read the interfile header of file reading file " << path_to_initial_img <<
" !" << endl);
1336 nb_VoxX = nb_VoxX<0 ? IF.
mtx_size[0] : nb_VoxX ;
1337 nb_VoxY = nb_VoxY<0 ? IF.
mtx_size[1] : nb_VoxY ;
1338 nb_VoxZ = nb_VoxZ<0 ? IF.
mtx_size[2] : nb_VoxZ ;
1352 if (frame_list ==
"")
1354 vector <string> image_filenames;
1355 if (
IntfIsMHD(path_to_initial_img, image_filenames) )
1357 Cerr(
"***** castor-proj() -> Error : while trying to read the interfile header '"<< path_to_initial_img <<
"' !" << endl);
1366 if(image_filenames.size() > 1)
1373 Cerr(
"***** castor-proj() -> Interfile reading error of the input image :"<<endl);
1375 <<
"' does not match the actual number of time frames * respiratory gates * cardiac gates ) '"<< IF.
nb_time_frames *
1407 frame_list.append(ss.str());
1416 frame_list.append(
":").append(ss.str());
1419 frame_list.append(
",").append(ss.str());
1426 frame_list.append(
",").append(ss.str());
1464 frame_list.append(
":").append(ss.str());
1473 Cerr(
"***** castor-proj() -> Interfile reading error of the input image :"<<endl);
1475 <<
"' does not match the actual number of time frames * respiratory gates * cardiac gates ) '"<< IF.
nb_time_frames <<
"' !" << endl);
1509 frame_list.append(ss.str());
1518 frame_list.append(
":").append(ss.str());
1521 frame_list.append(
",").append(ss.str());
1528 frame_list.append(
",").append(ss.str());
1536 frame_list.append(
":").append(ss.str());
1547 frame_list.append(
"0:").append(ss.str());
1558 if(nb_VoxX<0 || nb_VoxY<0 || nb_VoxZ<0)
1565 if ( (fov_SizeX<0 || fov_SizeY<0 || fov_SizeZ<0) && (vox_SizeX<0 || vox_SizeY<0 || vox_SizeZ<0) )
1586 if (verbose_general>=2)
1588 Cout(
" Image dimensions for analytical projections: " << endl);
1589 Cout(
" voxels number (X,Y,Z): " << nb_VoxX <<
"," << nb_VoxY <<
"," << nb_VoxZ << endl);
1590 Cout(
" voxels size (X,Y,Z): " << vox_SizeX <<
"," << vox_SizeY <<
"," << vox_SizeZ << endl);
1591 Cout(
" FOV (X,Y,Z): " << fov_SizeX <<
"," << fov_SizeY <<
"," << fov_SizeZ << endl);
1600 p_ImageDimensionsAndQuantification->
SetNbVoxX(nb_VoxX);
1601 p_ImageDimensionsAndQuantification->
SetNbVoxY(nb_VoxY);
1602 p_ImageDimensionsAndQuantification->
SetNbVoxZ(nb_VoxZ);
1603 p_ImageDimensionsAndQuantification->
SetNbThreads(nb_threads);
1604 p_ImageDimensionsAndQuantification->
SetNbBeds(nb_beds);
1605 p_ImageDimensionsAndQuantification->
SetVoxSizeX(vox_SizeX);
1606 p_ImageDimensionsAndQuantification->
SetVoxSizeY(vox_SizeY);
1607 p_ImageDimensionsAndQuantification->
SetVoxSizeZ(vox_SizeZ);
1608 p_ImageDimensionsAndQuantification->
SetFOVSizeX(fov_SizeX);
1609 p_ImageDimensionsAndQuantification->
SetFOVSizeY(fov_SizeY);
1610 p_ImageDimensionsAndQuantification->
SetFOVSizeZ(fov_SizeZ);
1612 p_ImageDimensionsAndQuantification->
SetOffsetX(offsetX);
1613 p_ImageDimensionsAndQuantification->
SetOffsetY(offsetY);
1614 p_ImageDimensionsAndQuantification->
SetOffsetZ(offsetZ);
1615 p_ImageDimensionsAndQuantification->
SetVerbose(verbose_data);
1616 p_ImageDimensionsAndQuantification->
SetNbRespGates(nb_resp_gates);
1617 p_ImageDimensionsAndQuantification->
SetNbCardGates(nb_card_gates);
1618 p_ImageDimensionsAndQuantification->
SetFrames(frame_list);
1621 Cerr(
"***** castor-proj() -> A problem occurred while checking image dimensions parameters !" << endl);
1624 if (p_ImageDimensionsAndQuantification->
Initialize())
1626 Cerr(
"***** castor-proj() -> A problem occurred while initializing image dimensions !" << endl);
1631 if (p_ImageDimensionsAndQuantification->
InitDynamicData(
"", 0, 0, 0, nb_resp_gates, nb_card_gates ) )
1633 Cerr(
"***** castor-proj() -> A problem occurred while initializing Dynamic data manager's class !" << endl);
1658 Cerr(
"***** castor-proj() -> Unknown scanner type !" << endl);
1665 Cerr(
"***** castor-proj() -> Only PET type events are allowed while using a PET scanner !" << endl);
1666 Cerr(
"***** castor-proj() -> (use '-fileType' to define modality (0=PET, 1=SPECT, 2=CT) )" << endl);
1669 for (
int i=0 ; i<nb_beds ; i++)
1672 if(path_to_attenuation_img !=
"")
1673 (
dynamic_cast<iDataFilePET*
>(p_DataFile[i]))->SetAtnCorrectionFlagOn();
1680 Cerr(
"***** castor-proj() -> Only SPECT type events are allowed while using a SPECT scanner !" << endl);
1681 Cerr(
"***** castor-proj() -> (use '-fileType' to define modality (0=PET, 1=SPECT, 2=CT) )" << endl);
1684 for (
int i=0 ; i<nb_beds ; i++)
1691 Cerr(
"***** castor-proj() -> Unsupported scanner type !" << endl);
1696 for (
int fr=0 ; fr<p_ImageDimensionsAndQuantification->
GetNbTimeFrames() ; fr++)
1703 for (
int bed=0 ; bed<nb_beds ; bed++)
1713 p_DataFile[bed]->
SetDuration(acquisition_duration_sec);
1715 if(p_DataFile[bed]->CheckParameters())
1717 Cerr(
"***** castor-proj() -> A problem occurred while checking datafile parameters ! Abort." << endl);
1757 p_ProjectorManager->
SetVerbose(verbose_proj);
1762 Cerr(
"***** castor-proj() -> A problem occurred while checking projector manager's parameters !" << endl);
1769 Cerr(
"***** castor-proj() -> A problem occurred while initializing projector manager !" << endl);
1783 p_ImageConvolverManager->
SetVerbose(verbose_conv);
1785 p_ImageConvolverManager->
SetOptions(options_image_convolver);
1790 Cerr(
"***** castor-proj() -> A problem occurred while checking optimizer manager's parameters !" << endl);
1796 Cerr(
"***** castor-proj() -> A problem occurred while initializing optimizer manager !" << endl);
1817 p_Projection->
InitOptimizer(p_ImageDimensionsAndQuantification);
1820 Cerr(
"***** castor-proj() -> A problem occurred while initializing noise model !" << endl);
1838 if (p_Projection->
Launch())
1840 Cerr(
"***** castor-proj() ->Error occurred during Projections" << endl;);
1848 if(SPECT_projection_angles)
delete SPECT_projection_angles;
1850 if (verbose_general>=5)
Cout(
"----- Deleting CASToR objects ... -----" << endl);
1851 delete p_Projection;
1852 delete p_ImageSpace;
1853 delete p_ImageConvolverManager;
1854 delete p_ProjectorManager;
1858 for (
int i=0 ; i<nb_beds ; i++)
delete p_DataFile[i];
1859 delete[] p_DataFile;
1860 delete p_ImageDimensionsAndQuantification;
1863 if (verbose_general>=5)
Cout(
"----- CASToR objects successfully deleted -----" << endl);
1866 if (verbose_general>=1)
Cout(endl);
1870 return EXIT_SUCCESS;
void SetDataMode(int a_dataMode)
void SetVerbose(int a_verboseLevel)
This class is designed to be a mother virtual class for DataFile.
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.
void SetNbCardGates(int a_nbCardGates)
void SetVerbose(int a_verbose)
void SetPathAtnImage(string a_pathToAtnImg)
static void ShowCommonHelp()
This function is used to print out some help about the use of options common to all projectors...
void SetVerbose(int a_verboseLevel)
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
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 GetFrameDurationInSec(int a_bed, int a_frame)
This class manages the analytic projection of an image and the computation of the associated datafile...
void SetOptionsCommon(const string &a_optionsCommon)
int Initialize()
A function used to initialize the manager and the projectors or system matrices it manages...
int FindScannerSystem(string a_scannerName)
void SetImageSpace(oImageSpace *ap_ImageSpace)
void SetFOVSizeX(FLTNB a_fovSizeX)
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
int BuildScannerObject()
Instantiate the specific scanner object related to the modality, and set verbosity of scanner object...
int IntfIsMHD(string a_pathToFile, vector< string > &ap_lPathToImgs)
Check if the string in argument contains the path to a Interfile metaheader.
void SetVoxSizeY(FLTNB a_voxSizeY)
void SetOptionsForward(const string &a_optionsForward)
int CheckParameters()
A function used to check the parameters settings.
void ShowHelpDynamic()
Display command line options related to the dynamic features for castor-proj.
void SetOffsetZ(FLTNB a_offsetZ)
void SetVerbose(int a_verboseLevel)
void SetVoxSizeX(FLTNB a_voxSizeX)
void SetDuration(FLTNB a_value)
void SetNbRespGates(int a_nbRespGates)
void SetNbVoxY(INTNB a_nbVoxY)
virtual int ComputeSizeEvent()=0
This function is implemented in child classes Computation of the size of each event according to th...
string GetPathToScannerFile()
void SetVerbose(int a_verboseLevel)
Set verbosity level.
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
void ShowHelpProj()
Display command line options related to the Projector module for castor-proj.
void SetSaveLUTFlag(bool a_flag)
void IntfKeyPrintFields(Intf_fields a_IF)
Print all the keys of the Intf_fields structure passed in parameter, as well as their values for debu...
int CheckParameters()
Check if all parameters have been correctly initialized, and call the CheckParameters function of the...
int SetNbThreads(const string &a_nbThreads)
int SetOutNbPrec(string a_format)
int InstantiateScanner()
Instantiate scanner using the related function in the scanner classes.
int LogCommandLine(int argc, char **argv)
static sAddonManager * GetInstance()
void SetDataFile(vDataFile **a2p_DataFile)
vector< FLTNB > image_start_time
void SetFOVSizeY(FLTNB a_fovSizeY)
#define FIXED_LIST_COMPUTATION_STRATEGY
int InitNoiseModel(string aNoiseModel)
void SetNbVoxZ(INTNB a_nbVoxZ)
int CheckConfigDir(const string &a_path)
void SetOffsetY(FLTNB a_offsetY)
int CheckParameters()
A function used to check the parameters settings.
void SetNoZeroEvent(bool a_flag)
void SetNbBeds(int a_nbBeds)
#define SCANNER_SPECT_CONVERGENT
void SetImageConvolverManager(oImageConvolverManager *ap_ImageConvolverManager)
int BuildLUT()
Call the eponym function of the scanner class.
int Initialize()
A function used to initialize all that is needed.
Singleton class that manages output writing on disk (images, sinograms, etc). It also manages loggi...
void SetComputationStrategy(int a_computationStrategy)
void SetOptionsBackward(const string &a_optionsBackward)
void SetDataType(int a_dataType)
void SetFOVSizeZ(FLTNB a_fovSizeZ)
void SetDataFile(vDataFile *ap_DataFile)
Singleton class that Instantiate and initialize the scanner object.
int Initialize(int a_nbThreads, int a_nbExtra)
Instantiate pseudo random number generators, one per thread by default, and additional extra ones if ...
int PROJ_SetPETSpecificParameters(FLTNB a_maxAxialDiffmm)
void ShowHelpComputation()
Display command line options related to the computation settings for castor-proj. ...
virtual int PrepareDataFile()=0
This function is implemented in child classes Store different kind of information inside arrays (da...
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Inherit from vDataFile. Class that manages the reading of a SPECT input file (header + data)...
int main(int argc, char **argv)
This class is designed to manage the different image convolvers and to apply them.
void ShowHelpInput()
Display command line options related to input settings for castor-proj.
int Launch()
Just call either the LaunchCPU or the LaunchGPU function as asked for.
vScanner * GetScannerObject()
int CheckParameters()
A function used to check the parameters settings.
int InitDynamicData(string a_pathTo4DDataSplittingFile, int a_respMotionCorrectionFlag, int a_cardMotionCorrectionFlag, int a_invMotionCorrectionFlag, int a_nbRespGates, int a_nbCardGates)
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
void ShowHelpProjector()
Show help about all implemented projectors.
void ShowHelpOutput()
Display command line options related to output settings for castor-proj.
#define KEYWORD_MANDATORY
int PROJ_SetSPECTSpecificParameters(uint16_t *ap_nbOfBins, uint32_t a_nbOfProjections, FLTNB a_firstAngle, FLTNB a_stepAngle, FLTNB *ap_projectionAngles, FLTNB a_CORtoDetectorDistance, string a_rotDirection)
void SetScanner(vScanner *ap_Scanner)
static void ShowCommonHelp()
This function does not take any parameter and is used to display some help about the syntax of the op...
Singleton class that generate a thread-safe random generator number for openMP As singleton...
void IntfKeyInitFields(Intf_fields *ap_IF)
Init the file of an Interfile fields structure passed in parameter to their default values...
void SetGPUflag(bool a_flagGPU)
void ShowHelp(int a_returnCode, int a_mpiRank)
void SetFOVOutMasking(FLTNB a_fovOutPercent, INTNB a_nbSliceOutMask)
int Initialize()
Initialization : .
#define SCANNER_SPECT_PINHOLE
void SetNbBeds(int a_nbBeds)
void SetVoxSizeZ(FLTNB a_voxSizeZ)
void SetVerbose(int a_verboseLevel)
void ShowHelpMiscellaneous()
Display command line settings related to SPECT modality for castor-proj.
This class is designed to manage the projection part of the reconstruction.
Interfile fields. This structure contains all the Interfile keys currently managed by CASToR Decl...
void SetBedIndex(int a_bedIndex)
void GetUserEndianness()
Check user/host computer endianness and write it to the global variable User_Endianness.
This class holds all the matrices in the image domain that can be used in the algorithm: image...
int GetNbTimeFrames()
Get the number of time frames.
int InitOutputDirectory(const string &a_pathFout, const string &a_pathDout)
int ConvertFromString(const string &a_str, string *a_result)
Copy the 'a_str' string in the position pointed by 'a_result'.
vector< FLTNB > image_duration
void SetOptions(vector< string > a_options)
void SetProjectorManager(oProjectorManager *ap_ProjectorManager)
void SetNbVoxX(INTNB a_nbVoxX)
void SetScanner(vScanner *ap_Scanner)
void SetOffsetX(FLTNB a_offsetX)
This class is designed to manage all dimensions and quantification related stuff. ...
int GetNbThreadsForProjection()
Get the number of threads used for projections.
void SetVerbose(int a_verboseLevel)
void SetFrames(const string &a_frameList)
virtual int PROJ_GetScannerSpecificParameters()=0
This function is implemented in child classes It is used to set several variables of the datafile w...
void SetDataFileName(vector< string > ap_dataFileName)
int IntfReadHeader(const string &a_pathToHeaderFile, Intf_fields *ap_IntfFields, int vb)
Read an Interfile header.
void SetPathInitImage(string a_pathToInitialImage)
void SetVerbose(int a_verbose)
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...
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Inherit from vDataFile. Class that manages the reading of a PET input file (header + data)...
void InitOptimizer(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
virtual int PROJ_InitFile()=0
This function is implemented in child classes Initialize the fstream objets for output writing as w...
void SetVerbose(int a_verboseLevel)
int Initialize()
A function used to initialize the manager and all image convolvers it manages.
void ShowHelpImageConvolver()
Show help about all implemented image convolvers.