8 #include "gVariables.hh" 10 #include "oImageDimensionsAndQuantification.hh" 11 #include "vDataFile.hh" 12 #include "iDataFilePET.hh" 13 #include "iDataFileSPECT.hh" 14 #include "iDataFileCT.hh" 15 #include "sOutputManager.hh" 16 #include "sRandomNumberGenerator.hh" 35 cout <<
"Usage: castor-datafileShuffler -df datafile.cdh -(f/d)out output" << endl;
37 cout <<
"This program can be used to shuffle the order of events of a histogram datafile." << endl;
39 cout <<
"[Mandatory parameters]:" << endl;
40 cout <<
" -df datafile.cdh : Give a CASToR list-mode datafile." << endl;
41 cout <<
" -fout name : Give the root name for all output files (no default, alternative to -dout)" << endl;
42 cout <<
" -dout name : Give the name of the output directory where all output files will be written (no default, alternative to -fout)" << endl;
44 cout <<
"[Options]:" << endl;
45 cout <<
" -seed value : Give a seed for the random number generator (should be >=0)" << endl;
46 cout <<
" -vb value : Give the verbosity level, from 0 (no verbose) to 2 (default: 1)" << endl;
47 cout <<
" --help,-h,-help : Print out this help page." << endl;
50 cout <<
" Build date: " << BUILD_DATE << endl;
54 cout <<
" This program is part of the CASToR release version " <<
CASTOR_VERSION <<
"." << endl;
67 int main(
int argc,
char** argv)
75 MPI_Init(&argc, &argv);
76 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
77 MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
78 if (mpi_rank!=0)
return 0;
104 string path_dout =
"";
106 string path_fout =
"";
115 int64_t random_generator_seed = -1;
122 for (
int i=1; i<argc; i++)
125 string option = (string)argv[i];
132 if (option==
"-h" || option==
"--help" || option==
"-help")
138 else if (option==
"-seed")
142 Cerr(
"***** castor-datafileShuffler() -> Argument missing for option: " << option << endl);
147 Cerr(
"***** castor-datafileShuffler() -> Exception when trying to read provided number '" << random_generator_seed <<
" for option: " << option << endl);
153 else if (option==
"-vb")
157 Cerr(
"***** castor-datafileShuffler() -> Argument missing for option: " << option << endl);
162 Cerr(
"***** castor-datafileShuffler() -> Exception when trying to read provided verbosity level '" << verbose <<
" for option: " << option << endl);
173 else if (option==
"-df")
177 Cerr(
"***** castor-datafileShuffler() -> Argument missing for option: " << option << endl);
180 datafile = (string)argv[i+1];
189 else if (option==
"-dout")
193 Cerr(
"***** castor-datafileShuffler() -> Argument missing for option: " << option << endl);
196 path_dout = argv[i+1];
200 else if (option==
"-fout")
204 Cerr(
"***** castor-datafileShuffler() -> Argument missing for option: " << option << endl);
207 path_fout = argv[i+1];
217 Cerr(
"***** castor-datafileShuffler() -> Unknown option '" << option <<
"' !" << endl);
229 Cerr(
"***** castor-datafileShuffler() -> Please provide an input datafile !" << endl);
233 if (path_fout.empty() && path_dout.empty())
235 Cerr(
"***** castor-datafileShuffler() -> Please provide an output option for output files (-fout or -dout) !" << endl);
239 if (!path_fout.empty() && !path_dout.empty())
241 Cerr(
"***** castor-datafileShuffler() -> Please provide either output option -fout or -dout but not both !" << endl);
256 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while initializing output directory !" << endl);
262 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while logging command line arguments !" << endl);
272 string scanner_name =
"";
275 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while trying to find the system name in the datafile header !" << endl);
280 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while searching for scanner system !" << endl);
285 Cerr(
"***** castor-datafileShuffler() -> A problem occurred during scanner object construction ! !" << endl);
290 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while creating Scanner object !" << endl);
295 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while retrieving scanner fields from the datafile header !" << endl);
300 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while generating/reading the LUT !" << endl);
319 Cerr(
"***** castor-datafileShuffler() -> Unknown scanner type (" << p_ScannerManager->
GetScannerType() <<
") for datafile construction ! Abort." << endl);
326 bool do_not_affect_quantification =
false;
329 Cerr(
"***** castor-datafileShuffler() -> A problem occurred during datafile header reading ! Abort." << endl);
334 Cerr(
"***** castor-datafileShuffler() -> A problem occurred while checking datafile parameters ! Abort." << endl);
339 Cerr(
"***** castor-datafileShuffler() -> A problem occurred in datafile initialization ! Abort." << endl);
344 Cerr(
"***** castor-datafileShuffler() -> A problem occurred in datafile initialization ! Abort." << endl);
349 Cerr(
"***** castor-datafileShuffler() -> A problem occurred in datafile preparation ! Abort." << endl);
355 Cerr(
"***** castor-datafileShuffler() -> The input datafile is not a histogram, this program is only suitable to histogram files !" << endl);
371 Cerr(
"***** castor-datafileShuffler() -> An error occurred while setting parameters of output file from input file !" << endl);
377 Cerr(
"***** castor-datafileShuffler() -> An error occurred while opening file for writing !" << endl);
386 int64_t nb_events = p_DataFile->
GetSize();
388 if (verbose>=1)
Cout(
"castor-datafileShuffler() -> Build a random indices list for " << nb_events <<
" events" << endl);
389 if (verbose>=2)
Cout(
" --> Allocate random indices list" << endl);
391 vector<int64_t> p_random_indices(nb_events);
392 vector<int64_t> p_random_numbers(nb_events);
394 for (int64_t i=0; i<nb_events; i++) p_random_indices[i] = i;
396 if (random_generator_seed==-1)
399 mt19937 rd(time(NULL));
400 random_generator_seed = rd();
405 if (random_generator_seed<0)
407 Cerr(
"***** castor-datafileShuffler() -> Must provide a random generator seed that is positive !" << endl);
412 if (verbose>=2)
Cout(
" --> General random seed: " << random_generator_seed << endl);
414 mt19937 random_seeder(random_generator_seed);
418 nb_threads = omp_get_num_procs();
419 if (verbose>=2)
Cout(
" --> Use " << nb_threads <<
" threads" << endl);
421 mt19937** p_random_generators = (mt19937**)malloc(nb_threads*
sizeof(mt19937*));
422 for (
int th=0; th<nb_threads; th++) p_random_generators[th] =
new mt19937(random_seeder());
424 uniform_int_distribution<int64_t> random_distribution(0, nb_events-1);
426 if (verbose>=2)
Cout(
" --> Shoot random numbers" << endl);
428 int64_t printing_index = 0;
430 #pragma omp parallel for private(i) schedule(static) 431 for (i=0; i<nb_events; i++)
436 th = omp_get_thread_num();
439 if (th==0 && verbose>=2)
441 if (printing_index%5000==0)
443 int percent = ((int)( ((
FLTNB)(i)) * 100. / ((
FLTNB)(nb_events/nb_threads)) ));
444 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 445 << percent <<
" % " << flush;
450 p_random_numbers[i] = random_distribution(*p_random_generators[th]);
455 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 456 <<
" --> 100 % " << endl;
457 Cout(
" --> Apply random permutations" << endl);
461 for (int64_t i=0; i<nb_events; i++)
466 if (printing_index%5000==0)
468 int percent = ((int)( ((
FLTNB)(i)) * 100. / ((
FLTNB)(nb_events)) ));
469 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 470 << percent <<
" % " << flush;
475 int64_t index = p_random_numbers[i];
476 int64_t content = p_random_indices[i];
477 p_random_indices[i] = p_random_indices[index];
478 p_random_indices[index] = content;
481 if (verbose>=2) cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 482 <<
" --> 100 % " << endl;
489 if (verbose>=1)
Cout(
"castor-datafileShuffler() -> Read and write events" << endl);
492 for (int64_t i=0; i<nb_events; i++)
497 if (printing_index%10000==0)
499 int percent = ((int)( ((
FLTNB)(i)) * 100. / ((
FLTNB)(nb_events)) ));
500 cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b " 501 << percent <<
" % " << flush;
506 int64_t index = p_random_indices[i];
510 Cerr(
"***** castor-datafileShuffler() -> An error occurred while getting the event from index " << index <<
" !" << endl);
512 Cerr(
"***** castor-datafileShuffler() -> An error occurred while closing file during writing !" << endl);
519 if (verbose>=2) cout <<
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" 520 <<
" --> 100 % " << endl;
524 Cerr(
"***** castor-datafileShuffler() -> An error occurred while closing file after writing !" << endl);
532 Cerr(
"***** castor-datafileShuffler() -> An error occurred while writing output header file !" << endl);
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.
void SetVerbose(int a_verbose)
int CheckParameters()
Check the initialization of member variables Call the CheckSpecificParameters() function implemente...
virtual int WriteHeader()=0
This function is implemented in child classes. Generate a header file according to the data output ...
int FindScannerSystem(string a_scannerName)
int BuildScannerObject()
Instantiate the specific scanner object related to the modality, and set verbosity of scanner object...
int SetParametersFrom(vDataFile *ap_DataFile)
virtual int WriteEvent(vEvent *ap_Event, int a_th=0)=0
int ReadInfoInHeader(bool a_affectQuantificationFlag=true)
void SetVerbose(int a_verboseLevel)
virtual int ComputeSizeEvent()=0
This function is implemented in child classes Computation of the size of each event according to th...
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
int InitializeMappedFile()
Check the datafile existency, map it to memory and get the raw char* pointer. .
int InstantiateScanner()
Instantiate scanner using the related function in the scanner classes.
int LogCommandLine(int argc, char **argv)
vEvent * GetEvent(int64_t a_eventIndex, int a_th=0)
int CloseFile()
Close as many binary file stream for writing.
#define SCANNER_SPECT_CONVERGENT
int BuildLUT()
Call the eponym function of the scanner class.
Singleton class that manages output writing on disk (images, sinograms, etc). It also manages loggi...
Singleton class that Instantiate and initialize the scanner object.
virtual int PrepareDataFile()=0
This function is implemented in child classes Store different kind of information inside arrays (da...
Inherit from vDataFile. Class that manages the reading of a SPECT input file (header + data)...
void SetHeaderDataFileName(const string &a_headerFileName)
int OpenFileForWriting(string a_suffix="")
void SetMPIRank(int a_mpiRank)
#define KEYWORD_MANDATORY
void SetNbEvents(int64_t a_value)
void SetBedIndex(int a_bedIndex)
Mother class for the Event objects.
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'.
Inherit from vDataFile. Class that manages the reading of a CT input file (header + data)...
This class is designed to manage all dimensions and quantification related stuff. ...
void SetVerbose(int a_verboseLevel)
void SetDefault()
A function used to set number of threads and MPI instances to 1 and bypass the CheckParameters() func...
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)...
int GetGeometricInfoFromDataFile(string a_pathToDataFilename)