CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
castor-PetScannerLutEx.cc
Go to the documentation of this file.
1 
14 #include "gVariables.hh"
15 #include "gOptions.hh"
16 #include "sOutputManager.hh"
17 #include "oMatrix.hh"
18 
19 
25 void ShowHelp(int a_returnCode)
26 {
27  cout << endl;
28  cout << "Usage: castor-PetScannerLutEx -alias scanner_name [settings]" << endl;
29  cout << endl;
30  cout << "[Input settings]:" << endl;
31  cout << " -alias scanner_name : give the alias of the scanner for which the LUT will be generated (suggested template Modality-Constructor-Model (ex: PET_GE_DLS)" << endl;
32  cout << " the resulting file will be written in the scanner repository (default : /config/scanner directory)" << endl;
33  cout << endl;
34  #ifdef CASTOR_VERSION
35  cout << " This program is part of the CASToR release version " << CASTOR_VERSION << "." << endl;
36  cout << endl;
37  #endif
38  Exit(a_returnCode);
39 }
40 
41 
42 
47 int main(int argc, char** argv)
48 {
49  // No argument, then show help
50  if (argc==1) ShowHelp(0);
51 
52  string scanner_name = "";
53  string path_to_LUT = "";
54  string path_to_headerLUT = "";
55  ofstream LUT_file, header_LUT_file;
56 
57  // ============================================================================================================
58  // Read command-line parameters
59  // ============================================================================================================
60  for (int i=1; i<argc; i++)
61  {
62  string option = (string)argv[i];
63 
64  if (option=="-h" || option=="--help" || option=="-help") ShowHelp(0);
65 
66  else if (option=="-alias")
67  {
68  if (i>=argc-1)
69  {
70  cerr << "***** castor-PetScannerLutEx :: Argument missing for option: " << option << endl;
71  Exit(EXIT_FAILURE);
72  }
73  scanner_name = argv[i+1];
74  string path_base = sOutputManager::GetInstance()->GetPathToConfigDir();
75 
76  path_base.append("scanner");
77  path_to_LUT = path_base+OS_SEP;
78  path_to_headerLUT = path_base+OS_SEP;
79  path_to_LUT.append(scanner_name.c_str()).append(".lut");
80  path_to_headerLUT.append(scanner_name.c_str()).append(".hscan");
81  i++;
82  }
83  else
84  {
85  cerr << "***** castor-PetScannerLutEx :: Unknown option '" << option << "' !" << endl;
86  Exit(EXIT_FAILURE);
87  }
88  }
89 
90 
91 
92  // ============================================================================================================
93  // Checks options have been provided
94  // ============================================================================================================
95 
96  // Checks
97  // output directory
98  if (scanner_name.empty() )
99  {
100  cerr << "***** castor-PetScannerLutEx :: Please provide an alias for this scanner !" << endl;
101  ShowHelp(0);
102  Exit(EXIT_FAILURE);
103  }
104  else
105  {
106  cout << endl << "Generating LUT with the following alias: " << scanner_name << "... " << endl << endl;
107  }
108 
109 
110 
111  // ============================================================================================================
112  // Input parameter declarations
113  // ============================================================================================================
114  int nb_rings;
115  int nb_elts;
116  FLTNBLUT min_trs_angle_diff;
117  string scanner_modality;
118  string description;
119  FLTNBLUT angular_span;
120 
121  int *nb_rsectors_lyr,
122  *nb_trans_mod_lyr,
123  *nb_axial_mod_lyr,
124  *nb_trans_submod_lyr,
125  *nb_axial_submod_lyr,
126  *nb_trans_crystal_lyr,
127  *nb_axial_crystal_lyr,
128  *nb_crystals_lyr;
129 
130  FLTNBLUT *radius_lyr,
131  *gap_trans_mod_lyr,
132  *gap_axial_mod_lyr,
133  *gap_trans_submod_lyr,
134  *gap_axial_submod_lyr,
135  *gap_trans_crystal_lyr,
136  *gap_axial_crystal_lyr,
137  *crystal_size_depth_lyr,
138  *crystal_size_trans_lyr,
139  *crystal_size_axial_lyr,
140  *mean_depth_of_interaction_lyr;
141 
142 
143  // Layer-dependent variables
144  int nbLayers = 1;
145  nb_rsectors_lyr = new int[nbLayers];
146  nb_trans_mod_lyr = new int[nbLayers];
147  nb_axial_mod_lyr = new int[nbLayers];
148  nb_trans_submod_lyr = new int[nbLayers];
149  nb_axial_submod_lyr = new int[nbLayers];
150  nb_trans_crystal_lyr = new int[nbLayers];
151  nb_axial_crystal_lyr = new int[nbLayers];
152  nb_crystals_lyr = new int[nbLayers];
153 
154  radius_lyr = new FLTNBLUT[nbLayers];
155 
156  gap_trans_mod_lyr = new FLTNBLUT[nbLayers];
157  gap_axial_mod_lyr = new FLTNBLUT[nbLayers];
158  gap_trans_submod_lyr = new FLTNBLUT[nbLayers];
159  gap_axial_submod_lyr = new FLTNBLUT[nbLayers];
160  gap_trans_crystal_lyr = new FLTNBLUT[nbLayers];
161  gap_axial_crystal_lyr = new FLTNBLUT[nbLayers];
162  crystal_size_depth_lyr = new FLTNBLUT[nbLayers];
163  crystal_size_trans_lyr = new FLTNBLUT[nbLayers];
164  crystal_size_axial_lyr = new FLTNBLUT[nbLayers];
165  mean_depth_of_interaction_lyr = new FLTNBLUT[nbLayers];
166 
167 
168  // Initialize value of each scanner element according to the scanner system
169 
170  description = "User-made LUT of a GATE model of the GE DRX PET scanner system, generated by the castor-PetScannerLutEx script";
171  scanner_modality = "PET";
172 
173  // System minimal transaxial angle difference between two scanner elements
174  // to get a LOR
175  min_trs_angle_diff = 40.;
176 
177  // radius in mm (from isocenter to crystal surface)
178  radius_lyr[0]= 443;
179 
180  // nb scanner elements
181  nb_rsectors_lyr[0] = 70;
182  nb_trans_mod_lyr[0] = 1;
183  nb_axial_mod_lyr[0] = 4;
184  nb_trans_submod_lyr[0] = 1;
185  nb_axial_submod_lyr[0] = 1;
186  nb_trans_crystal_lyr[0] = 9;
187  nb_axial_crystal_lyr[0] = 6;
188 
189 
190  // Gaps between scanner elements
191  gap_trans_mod_lyr[0] = 0;
192  gap_axial_mod_lyr[0] = 1.75;
193  gap_trans_submod_lyr[0] = 0;
194  gap_axial_submod_lyr[0] = 0;
195  gap_trans_crystal_lyr[0] = 0.065;
196  gap_axial_crystal_lyr[0] = 0.1;
197 
198  // crystal dimensions (mm)
199  crystal_size_depth_lyr[0] = 30;
200  crystal_size_trans_lyr[0] = 4.230;
201  crystal_size_axial_lyr[0] = 6.350;
202 
203  // mean depth of interaction in the crystal (mm)
204  // negative value means no depth of interaction
205  mean_depth_of_interaction_lyr[0] = -1.;
206 
207  // angular span in degree = 360 by defaut
208  // (rsectors will be uniformly positionned according to this value)
209  angular_span = 360.;
210 
211  // Default reconstruction parameters for the scanner
212  int default_dim_trans, default_dim_axial;
213  default_dim_trans = 256;
214  default_dim_axial = 47;
215 
216  // default field of view
217  FLTNBLUT default_FOV_trans, default_FOV_axial; //mm
218  default_FOV_trans = 700;
219  default_FOV_axial = 153.69;
220 
221 
222  // Z-shifts (rsector axial shift for each module)
223 
224  // Default initialization
225  int nb_rsctr_axial_shift = 1;
226  FLTNBLUT *rsctr_zshift;
227  rsctr_zshift = new FLTNBLUT[nb_rsctr_axial_shift];
228 
229  // System contains z-shifts)
230  if(nb_rsctr_axial_shift > 1)
231  {
232  for(int zs=0 ; zs<nb_rsctr_axial_shift ; zs++)
233  rsctr_zshift[zs] = 0.; // Add specific z-shift values for each layer
234  }
235  // No z-shift, default initialization
236  else
237  rsctr_zshift[0] = 0.;
238 
239 
240  // Compute the total number of elements
241  nb_elts = 0;
242  for(int lyr=0 ; lyr<nbLayers ; lyr++)
243  nb_elts += nb_rsectors_lyr[lyr] * nb_trans_mod_lyr[lyr] * nb_axial_mod_lyr[lyr]
244  * nb_trans_submod_lyr[lyr] * nb_axial_submod_lyr[lyr]
245  * nb_trans_crystal_lyr[lyr] * nb_axial_crystal_lyr[lyr];
246 
247  // Cumulative number of crystal (in order to keep track of crystal index if nb_layer>1)
248  uint32_t nb_cry_cur = 0;
249 
250  // Number of crystal in this layer
251  uint32_t nb_cry_in_layer = 0;
252 
253  // Loop on layers.
254  // Write the crytal LUT elements successively for each layer
255  for(int lyr=0 ; lyr<nbLayers ; lyr++)
256  {
257  // Default position for the first rsector in CASToR is directly above isocenter
258  // The gate model of this scanner locates the first rsector on the right side of the scanner
259  // This variable allows to provides the position of the first rsector in comparison with
260  // CASToR convention
261  // This is required to recover angular orientations of the crystals
262  FLTNBLUT rsector_first_angle = 90;
263 
264  int nb_rsectors = nb_rsectors_lyr[lyr],
265  nb_trans_mod = nb_trans_mod_lyr[lyr],
266  nb_axial_mod = nb_axial_mod_lyr[lyr],
267  nb_trans_submod = nb_trans_submod_lyr[lyr],
268  nb_axial_submod = nb_axial_submod_lyr[lyr],
269  nb_trans_crystal = nb_trans_crystal_lyr[lyr],
270  nb_axial_crystal = nb_axial_crystal_lyr[lyr];
271 
272  FLTNBLUT radius = radius_lyr[lyr],
273  gap_trans_mod = gap_trans_mod_lyr[lyr],
274  gap_axial_mod = gap_axial_mod_lyr[lyr],
275  gap_trans_submod = gap_trans_submod_lyr[lyr],
276  gap_axial_submod = gap_axial_submod_lyr[lyr],
277  gap_trans_crystal = gap_trans_crystal_lyr[lyr],
278  gap_axial_crystal = gap_axial_crystal_lyr[lyr],
279  crystal_size_trans = crystal_size_trans_lyr[lyr],
280  crystal_size_axial = crystal_size_axial_lyr[lyr],
281  crystal_size_depth = crystal_size_depth_lyr[lyr];
282 
283  // Compute system element sizes
284  FLTNBLUT size_trans_submod = nb_trans_crystal*crystal_size_trans + (nb_trans_crystal-1)*gap_trans_crystal;
285  FLTNBLUT size_axial_submod = nb_axial_crystal*crystal_size_axial + (nb_axial_crystal-1)*gap_axial_crystal;
286  FLTNBLUT size_trans_mod = nb_trans_submod*size_trans_submod + (nb_trans_submod-1)*gap_trans_submod;
287  FLTNBLUT size_axial_mod = nb_axial_submod*size_axial_submod + (nb_axial_submod-1)*gap_axial_submod;
288 
289  int nb_mod = nb_axial_mod*nb_trans_mod;
290  int nb_submod = nb_axial_submod*nb_trans_submod;
291  int nb_crystal = nb_trans_crystal*nb_axial_crystal;
292 
293  nb_cry_in_layer = nb_rsectors
294  * nb_mod
295  * nb_submod
296  * nb_crystal;
297 
298  nb_crystals_lyr[lyr] = nb_cry_in_layer;
299 
300  nb_rings = nb_rsectors
301  * nb_trans_mod
302  * nb_trans_submod
303  * nb_trans_crystal;
304 
305  int number_crystals_in_ring = nb_crystals_lyr[lyr]/nb_rings;
306 
307  // Variables gathering the LUT elements
308  FLTNBLUT* crystal_positionX = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
309  FLTNBLUT* crystal_positionY = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
310  FLTNBLUT* crystal_positionZ = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
311  FLTNBLUT* crystal_orientationX = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
312  FLTNBLUT* crystal_orientationY = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
313  FLTNBLUT* crystal_orientationZ = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
314 
315 
316  // ============================================================================================================
317  // Main part of the program: Generate the LUT
318  // ============================================================================================================
319 
320  // Loop to nb_rsectors+1. crystal_center[0] will be used to gather position of the reference rsector (directly above isocenter)
321  oMatrix *****crystal_center = new oMatrix ****[nb_rsectors];
322 
323  for(int i = 0; i < nb_rsectors+1 ; i++)
324  {
325  crystal_center[i] = new oMatrix ***[nb_axial_mod*nb_trans_mod];
326 
327  for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
328  {
329  crystal_center[i][j] = new oMatrix **[nb_axial_submod*nb_trans_submod];
330 
331  for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
332  {
333  crystal_center[i][j][k] = new oMatrix*[nb_axial_crystal*nb_trans_crystal];
334 
335  for (int l = 0; l<nb_axial_crystal*nb_trans_crystal; l++)
336  crystal_center[i][j][k][l] = new oMatrix(3,1);
337  }
338  }
339  }
340 
341 
342  // ============================================================================================================
343  // Generation of the rotation matrix allowing to compute the position of all the rsectors.
344  // ============================================================================================================
345  oMatrix** rotation_mtx = new oMatrix*[nb_rsectors];
346 
347  for(int i=0; i<nb_rsectors; i++)
348  rotation_mtx[i] = new oMatrix(3,3);
349 
350  FLTNBLUT angular_span_rad = angular_span*M_PI/180.;
351  for (int i = 0; i<nb_rsectors; i++)
352  {
353  FLTNBLUT angle = remainderf((FLTNB)i*angular_span_rad/((FLTNB)nb_rsectors), 2.*M_PI);
354 
355  rotation_mtx[i]->SetMatriceElt(0,0,cos(angle) );
356  rotation_mtx[i]->SetMatriceElt(1,0,-sin(angle) );
357  rotation_mtx[i]->SetMatriceElt(2,0,0);
358  rotation_mtx[i]->SetMatriceElt(0,1,sin(angle) );
359  rotation_mtx[i]->SetMatriceElt(1,1,cos(angle) );
360  rotation_mtx[i]->SetMatriceElt(2,1,0);
361  rotation_mtx[i]->SetMatriceElt(0,2,0);
362  rotation_mtx[i]->SetMatriceElt(1,2,0);
363  rotation_mtx[i]->SetMatriceElt(2,2,1);
364  }
365 
366 
367 
368  // ============================================================================================================
369  // Compute scanner elements positions for the first rsector
370  // (For the example scanner, it is located and centered on the right side of isocenter in the GATE model
371  // ============================================================================================================
372 
373  for (int i=0; i < nb_mod ; i++)
374  {
375  // Define the transaxial and axial edge start positions for the rsector
376  FLTNBLUT y_start_m = (nb_trans_mod*size_trans_mod + (nb_trans_mod-1)*gap_trans_mod) / 2;
377  FLTNBLUT z_start_m = -(nb_axial_mod*size_axial_mod + (nb_axial_mod-1)*gap_axial_mod) / 2 ;
378 
379  // Define the transaxial and axial edge start positions for the i-Module in the rsector.
380  // Enumeration starting with the transaxial modules.
381  y_start_m -= (i%nb_trans_mod) * (size_trans_mod + gap_trans_mod);
382  z_start_m += int(i/nb_trans_mod) * (size_axial_mod + gap_axial_mod);
383 
384  for (int j=0 ; j < nb_submod ; j++)
385  {
386  FLTNBLUT y_start_sm = y_start_m;
387  FLTNBLUT z_start_sm = z_start_m;
388 
389  y_start_sm -= (j%nb_trans_submod) * (size_trans_submod + gap_trans_submod);
390  z_start_sm += int(j/nb_trans_submod) * (size_axial_submod + gap_axial_submod);
391 
392  for (int k=0 ; k < nb_crystal ; k++)
393  {
394  // Define the transaxial and axial center positions for the j-SubModule (crystal) i-Module of the rsector.
395  // Enumeration starting with the transaxial submodules.
396  FLTNBLUT Xcrist = radius + crystal_size_depth/2;
397  FLTNBLUT Ycrist = y_start_sm - (k%nb_trans_crystal) * (crystal_size_trans + gap_trans_crystal) - crystal_size_trans/2;
398  FLTNBLUT Zcrist = z_start_sm + int(k/nb_trans_crystal) * (crystal_size_axial + gap_axial_crystal) + crystal_size_axial/2;
399 
400  crystal_center[0][i][j][k]->SetMatriceElt(0,0,Xcrist);
401  crystal_center[0][i][j][k]->SetMatriceElt(1,0,Ycrist);
402  crystal_center[0][i][j][k]->SetMatriceElt(2,0,Zcrist);
403  }
404  }
405  }
406 
407 
408  // ============================================================================================================
409  // Loop over all the other rsectors.
410  // Mandatory informations about crystals are recovered in :
411  // crystal_position(X,Y,Z) : Cartesian positions of the center of the crystals
412  // crystal_orientation(X,Y,Z) : Vector orientation recovering crystal angles
413  // (usually identical for all crystals inside the same rsector)
414  // ============================================================================================================
415 
416  for (int rs=0 ; rs<nb_rsectors ; rs++)
417  {
418 
419  // Compute angle for orientation vector for this rsector
420  FLTNBLUT rsector_first_angle_rad = rsector_first_angle*M_PI/180.;
421  FLTNBLUT orientation_angle = remainderf(rsector_first_angle_rad + (FLTNB)rs*angular_span_rad/((FLTNB)nb_rsectors), 2.*M_PI);
422 
423  for (int j=0 ; j<nb_mod ; j++)
424  for (int k=0 ; k<nb_submod ; k++)
425  for (int l=0 ; l<nb_crystal ; l++)
426  {
427  // crystal indexation
428  int cryID = int(j/nb_trans_mod)*nb_axial_submod*nb_axial_crystal*number_crystals_in_ring // = nb indexed crystals in the rings covered by the previous (axial) modules
429  + int(k/nb_trans_submod)*nb_axial_crystal*number_crystals_in_ring // = nb indexed crystals in the rings covered by the previous (axial) submodules
430  + int(l/nb_trans_crystal)*number_crystals_in_ring // = nb indexed crystals in the rings covered by the previous (axial) crystals
431  + rs*nb_trans_mod*nb_trans_submod*nb_trans_crystal // = nb indexed crystals in the previous rsectors
432  + j/nb_axial_mod*nb_trans_submod*nb_trans_crystal // = nb indexed crystals in the previous modules
433  + k/nb_axial_submod*nb_trans_crystal // = nb indexed crystals in the previous submodules
434  + l%nb_trans_crystal // previous crystals in the submodule
435  + nb_cry_cur; // = number of crystals already indexed if lyr>0
436 
437  rotation_mtx[rs]->Multiplication(crystal_center[0][j][k][l], crystal_center[rs+1][j][k][l]);
438  crystal_positionX[cryID] = crystal_center[rs+1][j][k][l]->GetMatriceElt(0,0);
439  crystal_positionY[cryID] = crystal_center[rs+1][j][k][l]->GetMatriceElt(1,0);
440  crystal_positionZ[cryID] = crystal_center[rs+1][j][k][l]->GetMatriceElt(2,0);
441  crystal_positionZ[cryID] += rsctr_zshift[rs%nb_rsctr_axial_shift];
442 
443  crystal_orientationX[cryID] = cos(orientation_angle);
444  crystal_orientationY[cryID] = sin(orientation_angle);
445  crystal_orientationZ[cryID] = 0;
446  }
447  }
448 
449  // Update nb of crystal for systems with (required if nb_layers>1)
450  nb_cry_cur += nb_crystals_lyr[lyr];
451 
452  // ============================================================================================================
453  // Write the binary LUT file (append if nb_layers > 1)
454  // ============================================================================================================
455 
456  cout << ">>> Start writing binary LUT file for layer #" << lyr << "..." << endl;
457  // Write binary file, overwrite mode
458  if(lyr == 0)
459  LUT_file.open(path_to_LUT.c_str(), ios::binary | ios::out);
460  // Append otherwise (data for crystals from the next layer)
461  else
462  LUT_file.open(path_to_LUT.c_str(), ios::binary | ios::out | ios::app);
463 
464 
465  // Write the corresponding crystal parameters in the LUT
466  for(int i=0 ; i<nb_crystals_lyr[lyr] ; i++)
467  {
468  LUT_file.write(reinterpret_cast<char*>(&crystal_positionX[i]), sizeof(FLTNBLUT));
469  LUT_file.write(reinterpret_cast<char*>(&crystal_positionY[i]), sizeof(FLTNBLUT));
470  LUT_file.write(reinterpret_cast<char*>(&crystal_positionZ[i]), sizeof(FLTNBLUT));
471  LUT_file.write(reinterpret_cast<char*>(&crystal_orientationX[i]), sizeof(FLTNBLUT));
472  LUT_file.write(reinterpret_cast<char*>(&crystal_orientationY[i]), sizeof(FLTNBLUT));
473  LUT_file.write(reinterpret_cast<char*>(&crystal_orientationZ[i]), sizeof(FLTNBLUT));
474  }
475 
476  LUT_file.close();
477  cout << ">>> Binary LUT writing OK" << endl;
478 
479  // ============================================================================================================
480  // Free memory
481  // ============================================================================================================
482 
483  // Delete objects
484 
485  for (int i = 0; i < nb_rsectors ; i++)
486  for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
487  for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
488  for (int l = 0; l<nb_axial_crystal*nb_trans_crystal; l++)
489  delete crystal_center[i][j][k][l];
490 
491  for(int i = 0; i < nb_rsectors ; i++)
492  for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
493  for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
494  delete[] crystal_center[i][j][k];
495 
496  for(int i = 0; i < nb_rsectors ; i++)
497  for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
498  delete[] crystal_center[i][j];
499 
500  for(int i = 0; i < nb_rsectors ; i++)
501  {
502  delete[] crystal_center[i];
503  delete rotation_mtx[i];
504  }
505 
506  delete[] crystal_center;
507  delete[] rotation_mtx;
508  delete crystal_positionX;
509  delete crystal_positionY;
510  delete crystal_positionZ;
511  delete crystal_orientationX;
512  delete crystal_orientationY;
513  delete crystal_orientationZ;
514 
515  } // end of loop on layers
516 
517 
518  // ============================================================================================================
519  // Write header file
520  // ============================================================================================================
521 
522  cout << ">>> Start writing header LUT file..." << endl;
523  header_LUT_file.open(path_to_headerLUT.c_str(), ios::out);
524 
525  header_LUT_file << "scanner name:" << " " << scanner_name << endl;
526  header_LUT_file << "modality:" << " " << scanner_modality << endl;
527 
528  header_LUT_file << "scanner radius:" << " " << radius_lyr[0];
529  for (int lyr=1 ; lyr<nbLayers ; lyr++)
530  header_LUT_file << "," << radius_lyr[lyr] ; header_LUT_file << endl;
531 
532  header_LUT_file << "number of rings in scanner:" << " " << nb_rings << endl;
533  header_LUT_file << "number of elements:" << " " << nb_elts << endl;
534  header_LUT_file << "number of layers:" << " " << nbLayers << endl;
535  header_LUT_file << "number of crystals in layer(s):" << " " << nb_crystals_lyr[0];
536  for (int lyr=1 ; lyr<nbLayers ; lyr++)
537  header_LUT_file << ","<< nb_crystals_lyr[lyr] ; header_LUT_file << endl;
538 
539  header_LUT_file << "crystals size depth:" << " " << crystal_size_depth_lyr[0];
540  for (int lyr=1 ; lyr<nbLayers ; lyr++)
541  header_LUT_file << ","<< crystal_size_depth_lyr[lyr] ; header_LUT_file << endl;
542 
543  header_LUT_file << "crystals size transaxial:" << " " << crystal_size_trans_lyr[0];
544  for (int lyr=1 ; lyr<nbLayers ; lyr++)
545  header_LUT_file << ","<< crystal_size_trans_lyr[lyr] ; header_LUT_file << endl;
546 
547  header_LUT_file << "crystals size axial:" << " " << crystal_size_axial_lyr[0];
548  for (int lyr=1 ; lyr<nbLayers ; lyr++)
549  header_LUT_file << ","<< crystal_size_axial_lyr[lyr] ; header_LUT_file << endl;
550 
551 
552  //default reconstruction parameters
553  header_LUT_file << "voxels number transaxial:" << " " << default_dim_trans << endl;
554  header_LUT_file << "voxels number axial:" << " " << default_dim_axial << endl;
555 
556  header_LUT_file << "field of view transaxial:" << " " << default_FOV_trans << endl;
557  header_LUT_file << "field of view axial:" << " " << default_FOV_axial << endl;
558 
559  header_LUT_file << "min angle difference:" << " " << min_trs_angle_diff << " #deg" << endl;
560 
561  header_LUT_file << "mean depth of interaction:" << " " << mean_depth_of_interaction_lyr[0];
562  for (int lyr=1 ; lyr<nbLayers ; lyr++)
563  header_LUT_file << ","<< mean_depth_of_interaction_lyr[lyr] ;
564  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;
565 
566  header_LUT_file << "description:" << " " << description << endl;
567 
568  cout << ">>> Header LUT file writing OK" << endl;
569 
570  // Free memory
571  delete rsctr_zshift;
572  delete nb_rsectors_lyr;
573  delete nb_trans_mod_lyr;
574  delete nb_axial_mod_lyr;
575  delete nb_trans_submod_lyr;
576  delete nb_axial_submod_lyr;
577  delete nb_trans_crystal_lyr;
578  delete nb_axial_crystal_lyr;
579 
580  delete radius_lyr;
581  delete gap_trans_mod_lyr;
582  delete gap_axial_mod_lyr;
583  delete gap_trans_submod_lyr;
584  delete gap_axial_submod_lyr;
585  delete gap_trans_crystal_lyr;
586  delete gap_axial_crystal_lyr;
587  delete crystal_size_depth_lyr;
588  delete crystal_size_trans_lyr;
589  delete crystal_size_axial_lyr;
590 
591  cout << "Binary file has been created in: " << path_to_LUT << endl;
592  cout << "Header file has been created in: " << path_to_headerLUT << endl << endl;
593  cout << "End of LUT generation" << endl << endl;
594 
595  return EXIT_SUCCESS;
596 }
597 
This header file is mainly used to declare some macro definitions and all includes needed from the st...
#define FLTNB
Definition: gVariables.hh:55
int main(int argc, char **argv)
int SetMatriceElt(uint16_t l, uint16_t c, FLTNBLUT a_val)
Set the matrix element corresponding to the argument indices with the provided value.
Definition: oMatrix.cc:127
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
void Exit(int code)
#define FLTNBLUT
Definition: gVariables.hh:61
const string & GetPathToConfigDir()
Return the path to the CASTOR config directory.
int Multiplication(oMatrix *a_Mtx, oMatrix *a_MtxResult)
Multiply the member matrix with the matrix provided in 1st parameter Return the result in the matric ...
Definition: oMatrix.cc:173
Declaration of class oMatrix.
FLTNBLUT GetMatriceElt(uint16_t l, uint16_t c)
Definition: oMatrix.cc:154
#define OS_SEP
Declaration of class sOutputManager.
Structure designed for basic matrices operations.
Definition: oMatrix.hh:20
This file is used for all kind of different functions designed for options parsing and ASCII file rea...
#define CASTOR_VERSION
Definition: gVariables.hh:44
void ShowHelp(int a_returnCode)