CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
castor-PetScannerLutEx.cc
Go to the documentation of this file.
00001 
00014 #include "gVariables.hh"
00015 #include "gOptions.hh"
00016 #include "sOutputManager.hh"
00017 #include "oMatrix.hh"
00018 
00019 
00025 void ShowHelp(int a_returnCode)
00026 {
00027   cout << endl;
00028   cout << "Usage:  castor-PetScannerLutEx  -alias scanner_name  [settings]" << endl;
00029   cout << endl;
00030 
00031   cout << "[Input settings]:" << endl;
00032   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;
00033   cout << "                          the resulting file will be written in the scanner repository (default : /config/scanner directory)" << endl;
00034   cout << endl;
00035 
00036   Exit(a_returnCode);
00037 }
00038 
00039 
00040 
00045 int main(int argc, char** argv)
00046 {
00047   // No argument, then show help
00048   if (argc==1) ShowHelp(0);
00049  
00050   string scanner_name = "";
00051   string path_to_LUT = "";
00052   string path_to_headerLUT = "";
00053   ofstream LUT_file, header_LUT_file;
00054   
00055   // ============================================================================================================
00056   // Read command-line parameters
00057   // ============================================================================================================
00058   for (int i=1; i<argc; i++)
00059   {
00060     string option = (string)argv[i];
00061 
00062     if (option=="-h" || option=="--help" || option=="-help") ShowHelp(0);
00063 
00064     else if (option=="-alias")
00065     {
00066       if (i>=argc-1)
00067       {
00068         cerr << "***** castor-PetScannerLutEx :: Argument missing for option: " << option << endl;
00069         Exit(EXIT_FAILURE);
00070       }
00071       scanner_name = argv[i+1];
00072       string path_base = sOutputManager::GetInstance()->GetPathToConfigDir();
00073 
00074       path_base.append("scanner");
00075       path_to_LUT = path_base+OS_SEP;
00076       path_to_headerLUT = path_base+OS_SEP;
00077       path_to_LUT.append(scanner_name.c_str()).append(".lut");
00078       path_to_headerLUT.append(scanner_name.c_str()).append(".hscan");
00079       i++;
00080     }
00081     else
00082     {
00083       cerr << "***** castor-PetScannerLutEx :: Unknown option '" << option << "' !" << endl;
00084       Exit(EXIT_FAILURE);
00085     }
00086   }
00087 
00088 
00089 
00090   // ============================================================================================================
00091   // Checks options have been provided
00092   // ============================================================================================================
00093 
00094   // Checks
00095   // output directory
00096   if (scanner_name.empty() )
00097   {
00098     cerr << "***** castor-PetScannerLutEx :: Please provide an alias for this scanner !" << endl;
00099     ShowHelp(0);
00100     Exit(EXIT_FAILURE);
00101   }
00102   else
00103   {
00104     cout << endl << "Generating LUT with the following alias: " << scanner_name << "... " << endl << endl;
00105   }
00106 
00107 
00108 
00109   // ============================================================================================================
00110   // Input parameter declarations
00111   // ============================================================================================================
00112   int nb_rings;
00113   int nb_elts;
00114   FLTNBLUT min_trs_angle_diff;
00115   string scanner_modality;
00116   string description;
00117   FLTNBLUT angular_span;
00118             
00119   int *nb_rsectors_lyr,
00120       *nb_trans_mod_lyr,
00121       *nb_axial_mod_lyr,
00122       *nb_trans_submod_lyr,
00123       *nb_axial_submod_lyr,
00124       *nb_trans_crystal_lyr,
00125       *nb_axial_crystal_lyr,
00126       *nb_crystals_lyr;
00127               
00128   FLTNBLUT  *radius_lyr,
00129             *gap_trans_mod_lyr,
00130             *gap_axial_mod_lyr,
00131             *gap_trans_submod_lyr,
00132             *gap_axial_submod_lyr,
00133             *gap_trans_crystal_lyr,
00134             *gap_axial_crystal_lyr,
00135             *crystal_size_depth_lyr,  
00136             *crystal_size_trans_lyr,
00137             *crystal_size_axial_lyr,
00138             *mean_depth_of_interaction_lyr;
00139 
00140   
00141   // Layer-dependent variables
00142   int nbLayers = 1;
00143   nb_rsectors_lyr = new int[nbLayers];
00144   nb_trans_mod_lyr = new int[nbLayers];
00145   nb_axial_mod_lyr = new int[nbLayers];
00146   nb_trans_submod_lyr = new int[nbLayers];
00147   nb_axial_submod_lyr = new int[nbLayers];
00148   nb_trans_crystal_lyr = new int[nbLayers];
00149   nb_axial_crystal_lyr = new int[nbLayers];
00150   nb_crystals_lyr = new int[nbLayers];
00151   
00152   radius_lyr = new FLTNBLUT[nbLayers];
00153   
00154   gap_trans_mod_lyr = new FLTNBLUT[nbLayers];
00155   gap_axial_mod_lyr = new FLTNBLUT[nbLayers];
00156   gap_trans_submod_lyr = new FLTNBLUT[nbLayers];
00157   gap_axial_submod_lyr = new FLTNBLUT[nbLayers];
00158   gap_trans_crystal_lyr = new FLTNBLUT[nbLayers];
00159   gap_axial_crystal_lyr = new FLTNBLUT[nbLayers];
00160   crystal_size_depth_lyr = new FLTNBLUT[nbLayers];  
00161   crystal_size_trans_lyr = new FLTNBLUT[nbLayers];
00162   crystal_size_axial_lyr = new FLTNBLUT[nbLayers];
00163   mean_depth_of_interaction_lyr = new FLTNBLUT[nbLayers];
00164 
00165 
00166   // Initialize value of each scanner element according to the scanner system
00167   
00168   description = "User-made LUT of a GATE model of the GE DRX PET scanner system, generated by the castor-PetScannerLutEx script";
00169   scanner_modality = "PET";
00170   
00171   // System minimal transaxial angle difference between two scanner elements
00172   // to get a LOR 
00173   min_trs_angle_diff = 40.;
00174   
00175   // radius in mm (from isocenter to crystal surface) 
00176   radius_lyr[0]= 443; 
00177   
00178   // nb scanner elements
00179   nb_rsectors_lyr[0] = 70;
00180   nb_trans_mod_lyr[0] = 1;
00181   nb_axial_mod_lyr[0] = 4;
00182   nb_trans_submod_lyr[0] = 1;
00183   nb_axial_submod_lyr[0] = 1;
00184   nb_trans_crystal_lyr[0] = 9;
00185   nb_axial_crystal_lyr[0] = 6;
00186 
00187 
00188   // Gaps between scanner elements
00189   gap_trans_mod_lyr[0] = 0;
00190   gap_axial_mod_lyr[0] = 1.75;
00191   gap_trans_submod_lyr[0] = 0;
00192   gap_axial_submod_lyr[0] = 0;
00193   gap_trans_crystal_lyr[0] = 0.065;
00194   gap_axial_crystal_lyr[0] = 0.1;
00195 
00196   // crystal dimensions (mm)
00197   crystal_size_depth_lyr[0] = 30;  
00198   crystal_size_trans_lyr[0] = 4.230;
00199   crystal_size_axial_lyr[0] = 6.350;
00200   
00201   // mean depth of interaction in the crystal (mm) 
00202   // negative value means no depth of interaction
00203   mean_depth_of_interaction_lyr[0] = -1.;
00204   
00205   // angular span in degree = 360 by defaut
00206   // (rsectors will be uniformly positionned according to this value)
00207   angular_span = 360.;
00208   
00209   // Default reconstruction parameters for the scanner
00210   int default_dim_trans, default_dim_axial;
00211   default_dim_trans = 256;
00212   default_dim_axial = 47;
00213   
00214   // default field of view
00215   FLTNBLUT default_FOV_trans, default_FOV_axial; //mm
00216   default_FOV_trans = 700;
00217   default_FOV_axial = 153.69;
00218 
00219 
00220   // Z-shifts (rsector axial shift for each module)
00221       
00222   // Default initialization
00223   int nb_rsctr_axial_shift = 1;
00224   FLTNBLUT *rsctr_zshift;
00225   rsctr_zshift = new FLTNBLUT[nb_rsctr_axial_shift];
00226   
00227   // System contains z-shifts)
00228   if(nb_rsctr_axial_shift > 1)
00229   {
00230     for(int zs=0 ; zs<nb_rsctr_axial_shift ; zs++)
00231       rsctr_zshift[zs] = 0.; // Add specific z-shift values for each layer
00232   }
00233   // No z-shift, default initialization
00234   else
00235     rsctr_zshift[0] = 0.;
00236 
00237 
00238   // Compute the total number of elements
00239   nb_elts = 0;
00240   for(int lyr=0 ; lyr<nbLayers ; lyr++)
00241     nb_elts += nb_rsectors_lyr[lyr] * nb_trans_mod_lyr[lyr] * nb_axial_mod_lyr[lyr] 
00242                                     * nb_trans_submod_lyr[lyr] * nb_axial_submod_lyr[lyr] 
00243                                     * nb_trans_crystal_lyr[lyr] * nb_axial_crystal_lyr[lyr];
00244 
00245   // Cumulative number of crystal (in order to keep track of crystal index if nb_layer>1)
00246   uint32_t nb_cry_cur = 0;
00247   
00248   // Number of crystal in this layer
00249   uint32_t nb_cry_in_layer = 0;
00250   
00251   // Loop on layers. 
00252   // Write the crytal LUT elements successively for each layer
00253   for(int lyr=0 ; lyr<nbLayers ; lyr++)
00254   {
00255     // Default position for the first rsector in CASToR is directly above isocenter
00256     // The gate model of this scanner locates the first rsector on the right side of the scanner
00257     // This variable allows to provides the position of the first rsector in comparison with
00258     // CASToR convention
00259     // This is required to recover angular orientations of the crystals
00260     FLTNBLUT rsector_first_angle = 90;
00261     
00262     int nb_rsectors = nb_rsectors_lyr[lyr],
00263         nb_trans_mod = nb_trans_mod_lyr[lyr],
00264         nb_axial_mod = nb_axial_mod_lyr[lyr],
00265         nb_trans_submod = nb_trans_submod_lyr[lyr],
00266         nb_axial_submod = nb_axial_submod_lyr[lyr],
00267         nb_trans_crystal = nb_trans_crystal_lyr[lyr],
00268         nb_axial_crystal = nb_axial_crystal_lyr[lyr];
00269   
00270     FLTNBLUT  radius = radius_lyr[lyr],
00271               gap_trans_mod = gap_trans_mod_lyr[lyr],
00272               gap_axial_mod = gap_axial_mod_lyr[lyr],
00273               gap_trans_submod = gap_trans_submod_lyr[lyr],
00274               gap_axial_submod = gap_axial_submod_lyr[lyr],
00275               gap_trans_crystal = gap_trans_crystal_lyr[lyr],
00276               gap_axial_crystal = gap_axial_crystal_lyr[lyr],
00277               crystal_size_trans = crystal_size_trans_lyr[lyr],
00278               crystal_size_axial = crystal_size_axial_lyr[lyr],
00279               crystal_size_depth = crystal_size_depth_lyr[lyr];
00280   
00281     // Compute system element sizes
00282     FLTNBLUT size_trans_submod = nb_trans_crystal*crystal_size_trans + (nb_trans_crystal-1)*gap_trans_crystal;
00283     FLTNBLUT size_axial_submod = nb_axial_crystal*crystal_size_axial + (nb_axial_crystal-1)*gap_axial_crystal;
00284     FLTNBLUT size_trans_mod = nb_trans_submod*size_trans_submod + (nb_trans_submod-1)*gap_trans_submod;
00285     FLTNBLUT size_axial_mod = nb_axial_submod*size_axial_submod + (nb_axial_submod-1)*gap_axial_submod;
00286   
00287     int nb_mod = nb_axial_mod*nb_trans_mod;
00288     int nb_submod = nb_axial_submod*nb_trans_submod;
00289     int nb_crystal = nb_trans_crystal*nb_axial_crystal;
00290   
00291     nb_cry_in_layer = nb_rsectors
00292                     * nb_mod
00293                     * nb_submod
00294                     * nb_crystal;
00295     
00296     nb_crystals_lyr[lyr] = nb_cry_in_layer;
00297     
00298     nb_rings = nb_rsectors
00299              * nb_trans_mod
00300              * nb_trans_submod
00301              * nb_trans_crystal;
00302                     
00303     int number_crystals_in_ring = nb_crystals_lyr[lyr]/nb_rings;
00304   
00305     // Variables gathering the LUT elements
00306     FLTNBLUT* crystal_positionX = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00307     FLTNBLUT* crystal_positionY = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00308     FLTNBLUT* crystal_positionZ = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00309     FLTNBLUT* crystal_orientationX = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00310     FLTNBLUT* crystal_orientationY = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00311     FLTNBLUT* crystal_orientationZ = new FLTNBLUT[ nb_crystals_lyr[lyr] ];
00312   
00313   
00314     // ============================================================================================================
00315     // Main part of the program: Generate the LUT
00316     // ============================================================================================================
00317 
00318     // Loop to nb_rsectors+1. crystal_center[0] will be used to gather position of the reference rsector (directly above isocenter)
00319     oMatrix *****crystal_center = new oMatrix ****[nb_rsectors];
00320   
00321     for(int i = 0; i < nb_rsectors+1 ; i++)
00322     {
00323       crystal_center[i] = new oMatrix ***[nb_axial_mod*nb_trans_mod];
00324   
00325       for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
00326       {
00327         crystal_center[i][j] = new oMatrix **[nb_axial_submod*nb_trans_submod];
00328   
00329         for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
00330         {
00331           crystal_center[i][j][k] = new oMatrix*[nb_axial_crystal*nb_trans_crystal];
00332   
00333           for (int l = 0; l<nb_axial_crystal*nb_trans_crystal; l++)
00334             crystal_center[i][j][k][l]  = new oMatrix(3,1);
00335         }
00336       }
00337     }
00338     
00339   
00340     // ============================================================================================================
00341     // Generation of the rotation matrix allowing to compute the position of all the rsectors. 
00342     // ============================================================================================================
00343     oMatrix** rotation_mtx = new oMatrix*[nb_rsectors];
00344   
00345     for(int i=0; i<nb_rsectors; i++)
00346       rotation_mtx[i] = new oMatrix(3,3);
00347 
00348     FLTNBLUT angular_span_rad = angular_span*M_PI/180.;
00349     for (int i = 0; i<nb_rsectors; i++)
00350     {
00351       FLTNBLUT angle = remainderf((FLTNB)i*angular_span_rad/((FLTNB)nb_rsectors), 2.*M_PI);
00352       
00353       rotation_mtx[i]->SetMatriceElt(0,0,cos(angle) );
00354       rotation_mtx[i]->SetMatriceElt(1,0,-sin(angle) );
00355       rotation_mtx[i]->SetMatriceElt(2,0,0);
00356       rotation_mtx[i]->SetMatriceElt(0,1,sin(angle) );
00357       rotation_mtx[i]->SetMatriceElt(1,1,cos(angle) );
00358       rotation_mtx[i]->SetMatriceElt(2,1,0);
00359       rotation_mtx[i]->SetMatriceElt(0,2,0);
00360       rotation_mtx[i]->SetMatriceElt(1,2,0);
00361       rotation_mtx[i]->SetMatriceElt(2,2,1);
00362     }
00363 
00364 
00365 
00366     // ============================================================================================================
00367     // Compute scanner elements positions for the first rsector 
00368     // (For the example scanner, it is located and centered on the right side of isocenter in the GATE model
00369     // ============================================================================================================
00370     
00371     for (int i=0; i < nb_mod ; i++)
00372     {
00373       // Define the transaxial and axial edge start positions for the rsector
00374       FLTNBLUT y_start_m = (nb_trans_mod*size_trans_mod + (nb_trans_mod-1)*gap_trans_mod) / 2;
00375       FLTNBLUT z_start_m = -(nb_axial_mod*size_axial_mod + (nb_axial_mod-1)*gap_axial_mod) / 2 ;
00376   
00377       // Define the transaxial and axial edge start positions for the i-Module in the rsector. 
00378       // Enumeration starting with the transaxial modules.
00379       y_start_m -= (i%nb_trans_mod) *  (size_trans_mod + gap_trans_mod);
00380       z_start_m += int(i/nb_trans_mod) * (size_axial_mod + gap_axial_mod);
00381   
00382       for (int j=0 ; j < nb_submod ; j++)
00383       {
00384         FLTNBLUT y_start_sm = y_start_m;
00385         FLTNBLUT z_start_sm = z_start_m;
00386         
00387         y_start_sm -= (j%nb_trans_submod) *  (size_trans_submod + gap_trans_submod);
00388         z_start_sm += int(j/nb_trans_submod) * (size_axial_submod + gap_axial_submod);
00389          
00390         for (int k=0 ; k < nb_crystal ; k++) 
00391         {
00392           // Define the transaxial and axial center positions for the j-SubModule (crystal) i-Module of the rsector.
00393           // Enumeration starting with the transaxial submodules.
00394           FLTNBLUT Xcrist = radius + crystal_size_depth/2;
00395           FLTNBLUT Ycrist = y_start_sm - (k%nb_trans_crystal) * (crystal_size_trans + gap_trans_crystal) - crystal_size_trans/2; 
00396           FLTNBLUT Zcrist = z_start_sm + int(k/nb_trans_crystal) * (crystal_size_axial + gap_axial_crystal) + crystal_size_axial/2;
00397           
00398           crystal_center[0][i][j][k]->SetMatriceElt(0,0,Xcrist);
00399           crystal_center[0][i][j][k]->SetMatriceElt(1,0,Ycrist);
00400           crystal_center[0][i][j][k]->SetMatriceElt(2,0,Zcrist);
00401         }
00402       }
00403     }
00404   
00405 
00406     // ============================================================================================================
00407     // Loop over all the other rsectors.
00408     // Mandatory informations about crystals are recovered in :
00409     // crystal_position(X,Y,Z) : Cartesian positions of the center of the crystals
00410     // crystal_orientation(X,Y,Z) : Vector orientation recovering crystal angles 
00411     //                             (usually identical for all crystals inside the same rsector)
00412     // ============================================================================================================
00413 
00414     for (int rs=0 ; rs<nb_rsectors ; rs++)
00415     {
00416 
00417       // Compute angle for orientation vector for this rsector
00418       FLTNBLUT rsector_first_angle_rad = rsector_first_angle*M_PI/180.;  
00419       FLTNBLUT orientation_angle = remainderf(rsector_first_angle_rad + (FLTNB)rs*angular_span_rad/((FLTNB)nb_rsectors), 2.*M_PI);
00420 
00421       for (int j=0 ; j<nb_mod ; j++)
00422         for (int k=0 ; k<nb_submod ; k++)
00423           for (int l=0 ; l<nb_crystal ; l++)
00424           {
00425             // crystal indexation
00426             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
00427                       + int(k/nb_trans_submod)*nb_axial_crystal*number_crystals_in_ring // = nb indexed crystals in the rings covered by the previous (axial) submodules
00428                       + int(l/nb_trans_crystal)*number_crystals_in_ring // = nb indexed crystals in the rings covered by the previous (axial) crystals
00429                       + rs*nb_trans_mod*nb_trans_submod*nb_trans_crystal // = nb indexed crystals in the previous rsectors
00430                       + j/nb_axial_mod*nb_trans_submod*nb_trans_crystal // = nb indexed crystals in the previous modules
00431                       + k/nb_axial_submod*nb_trans_crystal // = nb indexed crystals in the previous submodules
00432                       + l%nb_trans_crystal // previous crystals in the submodule
00433                       + nb_cry_cur; // = number of crystals already indexed if lyr>0
00434 
00435             rotation_mtx[rs]->Multiplication(crystal_center[0][j][k][l], crystal_center[rs+1][j][k][l]);
00436             crystal_positionX[cryID]  = crystal_center[rs+1][j][k][l]->GetMatriceElt(0,0);
00437             crystal_positionY[cryID]  = crystal_center[rs+1][j][k][l]->GetMatriceElt(1,0);
00438             crystal_positionZ[cryID]  = crystal_center[rs+1][j][k][l]->GetMatriceElt(2,0);
00439             crystal_positionZ[cryID] += rsctr_zshift[rs%nb_rsctr_axial_shift];
00440 
00441             crystal_orientationX[cryID] = cos(orientation_angle);
00442             crystal_orientationY[cryID] = sin(orientation_angle);
00443             crystal_orientationZ[cryID] = 0;
00444           }
00445     }
00446 
00447     // Update nb of crystal for systems with (required if nb_layers>1)
00448     nb_cry_cur += nb_crystals_lyr[lyr];
00449     
00450     // ============================================================================================================
00451     // Write the binary LUT file (append if nb_layers > 1)
00452     // ============================================================================================================
00453 
00454     cout << ">>> Start writing binary LUT file for layer #" << lyr << "..." << endl;
00455     // Write binary file, overwrite mode
00456     if(lyr == 0)
00457       LUT_file.open(path_to_LUT.c_str(), ios::binary | ios::out);
00458     // Append otherwise (data for crystals from the next layer)
00459     else
00460       LUT_file.open(path_to_LUT.c_str(), ios::binary | ios::out | ios::app);
00461     
00462     
00463     // Write the corresponding crystal parameters in the LUT
00464     for(int i=0 ; i<nb_crystals_lyr[lyr] ; i++)
00465     {
00466       LUT_file.write(reinterpret_cast<char*>(&crystal_positionX[i]), sizeof(FLTNBLUT));
00467       LUT_file.write(reinterpret_cast<char*>(&crystal_positionY[i]), sizeof(FLTNBLUT));
00468       LUT_file.write(reinterpret_cast<char*>(&crystal_positionZ[i]), sizeof(FLTNBLUT));
00469       LUT_file.write(reinterpret_cast<char*>(&crystal_orientationX[i]), sizeof(FLTNBLUT));
00470       LUT_file.write(reinterpret_cast<char*>(&crystal_orientationY[i]), sizeof(FLTNBLUT));
00471       LUT_file.write(reinterpret_cast<char*>(&crystal_orientationZ[i]), sizeof(FLTNBLUT));
00472     }
00473 
00474     LUT_file.close(); 
00475     cout << ">>> Binary LUT writing OK" << endl;
00476     
00477     // ============================================================================================================
00478     // Free memory
00479     // ============================================================================================================
00480   
00481     // Delete objects
00482   
00483     for (int i = 0; i < nb_rsectors ; i++)
00484      for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
00485       for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
00486        for (int l = 0; l<nb_axial_crystal*nb_trans_crystal; l++)
00487          delete crystal_center[i][j][k][l];
00488   
00489     for(int i = 0; i < nb_rsectors ; i++)
00490      for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
00491       for (int k = 0; k<nb_axial_submod*nb_trans_submod; k++)
00492         delete[] crystal_center[i][j][k];
00493 
00494     for(int i = 0; i < nb_rsectors ; i++)
00495      for (int j = 0; j<nb_axial_mod*nb_trans_mod; j++)
00496        delete[] crystal_center[i][j];
00497 
00498     for(int i = 0; i < nb_rsectors ; i++)
00499     {
00500       delete[] crystal_center[i];
00501       delete rotation_mtx[i];
00502     }
00503 
00504     delete[] crystal_center;
00505     delete[] rotation_mtx;
00506     delete crystal_positionX;
00507     delete crystal_positionY;
00508     delete crystal_positionZ;
00509     delete crystal_orientationX;
00510     delete crystal_orientationY;
00511     delete crystal_orientationZ;
00512     
00513   } // end of loop on layers
00514   
00515   
00516   // ============================================================================================================
00517   // Write header file
00518   // ============================================================================================================
00519 
00520   cout << ">>> Start writing header LUT file..." << endl;
00521   header_LUT_file.open(path_to_headerLUT.c_str(), ios::out); 
00522 
00523   header_LUT_file << "scanner name:" << "    " << scanner_name << endl; 
00524   header_LUT_file << "modality:" << "    " << scanner_modality << endl; 
00525   
00526   header_LUT_file << "scanner radius:" << "    " << radius_lyr[0];
00527   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00528     header_LUT_file << "," << radius_lyr[lyr] ; header_LUT_file << endl;
00529     
00530   header_LUT_file << "number of rings in scanner:" << "    " << nb_rings << endl;
00531   header_LUT_file << "number of elements:" << "    " << nb_elts << endl; 
00532   header_LUT_file << "number of layers:" << "    " << nbLayers << endl;
00533   header_LUT_file << "number of crystals in layer(s):" << "    " << nb_crystals_lyr[0];
00534   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00535     header_LUT_file << ","<< nb_crystals_lyr[lyr] ; header_LUT_file << endl;
00536     
00537   header_LUT_file << "crystals size depth:" << "    " << crystal_size_depth_lyr[0];
00538   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00539     header_LUT_file << ","<< crystal_size_depth_lyr[lyr] ; header_LUT_file << endl;
00540     
00541   header_LUT_file << "crystals size transaxial:" << "    " << crystal_size_trans_lyr[0];  
00542   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00543     header_LUT_file << ","<< crystal_size_trans_lyr[lyr] ; header_LUT_file << endl;
00544     
00545   header_LUT_file << "crystals size axial:" << "    " << crystal_size_axial_lyr[0]; 
00546   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00547     header_LUT_file << ","<< crystal_size_axial_lyr[lyr] ; header_LUT_file << endl;
00548     
00549  
00550   //default reconstruction parameters
00551   header_LUT_file << "voxels number transaxial:" << "    " << default_dim_trans << endl;  
00552   header_LUT_file << "voxels number axial:" << "    " << default_dim_axial << endl; 
00553 
00554   header_LUT_file << "field of view transaxial:" << "    " << default_FOV_trans << endl;  
00555   header_LUT_file << "field of view axial:" << "    " << default_FOV_axial << endl; 
00556   
00557   header_LUT_file << "min angle difference:" << "    " << min_trs_angle_diff << " #deg" << endl;
00558   
00559   header_LUT_file << "mean depth of interaction:" << "    " << mean_depth_of_interaction_lyr[0];
00560   for (int lyr=1 ; lyr<nbLayers ; lyr++) 
00561     header_LUT_file << ","<< mean_depth_of_interaction_lyr[lyr] ;
00562   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;
00563   
00564   header_LUT_file << "description:" << "    " << description << endl;
00565   
00566   cout << ">>> Header LUT file writing OK" << endl;
00567     
00568   // Free memory
00569   delete rsctr_zshift;
00570   delete nb_rsectors_lyr;
00571   delete nb_trans_mod_lyr;
00572   delete nb_axial_mod_lyr;
00573   delete nb_trans_submod_lyr;
00574   delete nb_axial_submod_lyr;
00575   delete nb_trans_crystal_lyr;
00576   delete nb_axial_crystal_lyr;
00577 
00578   delete radius_lyr;
00579   delete gap_trans_mod_lyr;
00580   delete gap_axial_mod_lyr;
00581   delete gap_trans_submod_lyr;
00582   delete gap_axial_submod_lyr;
00583   delete gap_trans_crystal_lyr;
00584   delete gap_axial_crystal_lyr;
00585   delete crystal_size_depth_lyr;  
00586   delete crystal_size_trans_lyr;
00587   delete crystal_size_axial_lyr;
00588 
00589   cout << "Binary file has been created in: " << path_to_LUT << endl;
00590   cout << "Header file has been created in: " << path_to_headerLUT << endl << endl;
00591   cout << "End of LUT generation" << endl << endl;
00592   
00593   return EXIT_SUCCESS;
00594 }
00595 
 All Classes Files Functions Variables Typedefs Defines