55 vector<string> values;
60 line = (line.find(
"#") != string::npos) ?
61 line.substr(0, line.find_first_of(
"#")) :
64 size_t foundAdress = line.find(a_key);
66 if (foundAdress != string::npos)
68 values =
Split(a_line);
69 values.erase (values.begin());
88 vector<string>
Split(
string a_line)
91 stringstream ss(a_line);
93 vector<string> tokens;
96 tokens.push_back(buf);
116 for(uint16_t i=0; i < ap_v.size(); i++)
120 for (
int j=0; j<i; j++)
142 int WriteVector(ofstream& file,
const string& a_key, vector <T> a_vals)
144 int n = a_vals.size();
149 for (
int i=0; i < n; i++)
154 file << ss.str() << endl;
156 file << ss.str() <<
",";
160 file << a_key <<
"0" <<endl;
165 template int WriteVector(ofstream& file,
const string& a_key, vector <double> a_vals);
181 int WriteVector(ofstream& file,
const string& a_key, vector <string> a_vals)
183 int n = a_vals.size();
188 for (
int i=0; i < n; i++)
191 file << a_vals[i] << endl;
193 file << a_vals[i] <<
",";
197 file << a_key <<
"0" <<endl;
216 int WriteVector(ofstream& file,
const string& a_key, vector <vector<string> > a_vals)
218 int n = a_vals.size();
220 for (
int i=0; i < n; i++)
221 for (
int j=0; j < 3; j++)
222 if (i == n-1 && j == 2)
223 file << a_vals[i][j] << endl;
225 file << a_vals[i][j] <<
",";
246 ifstream mac_file(a_pathMac, ios::in);
252 while(getline(mac_file, quickLine))
254 vector <string> values;
259 ap_pathToMacFiles.push_back(
GetPathOfFile(a_pathMac)+values[0]);
264 Cerr(
"***** GetGATEMacFiles() -> Couldn't open mac file "<< a_pathMac <<
" !" << endl);
290 vector<string> path_mac_files;
291 path_mac_files.push_back(a_pathMac);
295 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover paths to GATE macro files !" << endl);
299 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
300 cout << f <<
" : " << path_mac_files[f] << endl;
303 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
305 ifstream mac_file(path_mac_files[f], ios::in);
310 while(getline(mac_file, line))
313 if(line.find(
"/gate/systems/") != string::npos )
315 if(line.find(
"/gate/systems/ecat") != string::npos )
318 if(line.find(
"/gate/systems/cylindricalPET") != string::npos )
321 if(line.find(
"/gate/systems/SPECThead") != string::npos )
324 if(line.find(
"/gate/systems/OPET") != string::npos ||
325 line.find(
"/gate/systems/CTSCANNER") != string::npos ||
326 line.find(
"/gate/systems/CPET") != string::npos ||
327 line.find(
"/gate/systems/ecatAccel") != string::npos ||
328 line.find(
"/gate/systems/OpticalSystem") != string::npos )
330 Cerr(
"unsupported system detected (line = " << line <<
") ! "<< endl);
331 Cerr(
"supported systems for this script are cylindricalPET, SPECThead, and ecat" << endl);
338 Cerr(
"***** GetGATESystemType() -> Error : Couldn't open mac file "<< path_mac_files[f] <<
" !" << endl);
375 string& rsector_name,
377 string& submodule_name,
378 string& crystal_name,
379 vector<string>& layers_name,
384 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
386 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
391 while(getline(mac_file, quickLine))
393 vector <string> values;
395 values =
CheckGATECommand(
"/gate/systems/cylindricalPET/rsector/attach", quickLine);
399 rsector_name = values[0];
403 values =
CheckGATECommand(
"/gate/systems/cylindricalPET/module/attach", quickLine);
406 module_name = values[0];
410 values =
CheckGATECommand(
"/gate/systems/cylindricalPET/submodule/attach", quickLine);
413 submodule_name = values[0];
417 values =
CheckGATECommand(
"/gate/systems/cylindricalPET/crystal/attach", quickLine);
420 crystal_name = values[0];
429 values =
CheckGATECommand(
"/gate/systems/cylindricalPET/layer"+ss.str()+
"/attach", quickLine);
432 layers_name.push_back(values[0]);
441 Cerr(
"***** GetGATEAliasesCylindrical()->Couldn't open mac file "<< path_mac_files[f] <<
" !" << endl);
452 Cout(
"***** GetGATEAliasesCylindrical() :: Error : Missing elements in the system architecture" << endl <<
453 " At least two of the following lines are required :" << endl <<
454 " - /gate/systems/cylindricalPET/rsector/attach" << endl <<
455 " - /gate/systems/cylindricalPET/module/attach" << endl <<
456 " - /gate/systems/cylindricalPET/submodule/attach" << endl <<
457 " - /gate/systems/cylindricalPET/crystal/attach" << endl <<
458 " - /gate/systems/cylindricalPET/layeri[i=0..3]/attach" << endl);
464 if(rsector_name.empty())
466 if(module_name.empty())
469 rsector_name = submodule_name;
475 rsector_name = module_name;
482 if(!rsector_name.empty())
Cout(
"Detected rsector container's name : " << rsector_name << endl);
483 if(!module_name.empty())
Cout(
"Detected module container's name : " << module_name << endl);
484 if(!submodule_name.empty())
Cout(
"Detected submodule container's name : " << submodule_name << endl);
485 if(!crystal_name.empty())
Cout(
"Detected crystal container's name : " << crystal_name << endl);
486 for(
size_t l=0 ; l<layers_name.size() ; l++)
487 if(!layers_name[l].empty())
Cout(
"Detected layer #"<< l <<
" container's name : " << layers_name[l] << endl);
516 string& crystal_name,
521 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
523 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
529 while(getline(mac_file, quickLine))
531 vector <string> values;
536 block_name = values[0];
543 crystal_name = values[0];
550 Cerr(
"***** GetGATEAliasesEcat()-> Couldn't open mac file "<< path_mac_files[f].c_str()<<
" !" << endl);
559 Cerr(
"***** GetGATEAliasesEcat() :: Error : Missing elements in the system architecture" << endl
560 <<
" The following lines are required :" << endl
561 <<
" - /gate/systems/ecat/block/attach" << endl
562 <<
" - /gate/systems/ecat/crystal/attach" << endl);
568 Cout(
"First container's name (usually block) is : " << block_name << endl
569 <<
"Second container's name (usually crystal) is : " << crystal_name << endl);
600 string& crystal_name,
606 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
608 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
615 while(getline(mac_file, quickLine))
617 vector <string> values;
619 values =
CheckGATECommand(
"/gate/systems/SPECThead/base/attach", quickLine);
622 base_name = values[0];
626 values =
CheckGATECommand(
"/gate/systems/SPECThead/crystal/attach", quickLine);
629 crystal_name = values[0];
633 values =
CheckGATECommand(
"/gate/systems/SPECThead/pixel/attach", quickLine);
636 pixel_name = values[0];
644 Cerr(
"***** GetGATEAliasesSPECT()-> Couldn't open mac file "<< path_mac_files[f].c_str()<<
" !" << endl);
652 Cerr(
"***** GetGATEAliasesSPECT() :: Error : Missing elements in the system architecture" << endl
653 <<
" The following line is required :" << endl
654 <<
" - /gate/systems/SPECThead/crystal/attach" << endl);
660 Cout(
"Crystal container's name is : " << crystal_name << endl);
686 int32_t nCrystalsTransaxial,
687 int32_t nCrystalsAxial,
691 int32_t nCrystalsPerRing = nBlocksPerRing * nCrystalsTransaxial;
693 int32_t ringID = (int32_t)( blockID/nBlocksPerRing ) * nCrystalsAxial
694 + (int32_t)( crystalID/nCrystalsTransaxial );
696 int32_t castorID = nCrystalsPerRing * ringID
697 + nCrystalsTransaxial*( blockID % nBlocksPerRing )
698 + crystalID % nCrystalsTransaxial;
721 uint32_t a_nProjectionsByHead)
724 int32_t angID = round(a_rotAngle/a_angStep);
727 int32_t castorID = a_headID*a_nProjectionsByHead + angID;
764 float_t a_headAngPitch,
765 float_t a_crystalSizeAxl,
766 float_t a_crystalSizeTrs,
771 int32_t castorID = 0;
774 if (a_nbSimulatedPixels > 1)
776 castorID = a_pixelID;
783 FLTNB sizePixTrs = a_crystalSizeTrs/a_nPixTrs;
784 FLTNB sizePixAxl = a_crystalSizeAxl/a_nPixAxl;
787 uint32_t axialID = (uint32_t)(( a_gPosZ + a_nPixAxl/2*sizePixAxl) / sizePixAxl);
791 float_t ang = a_headID*a_headAngPitch + a_rotAngle;
794 float_t sin_a = sin(-ang*M_PI/180);
795 float_t cos_a = cos(-ang*M_PI/180);
796 float_t trs_pos = a_gPosX*sin_a + a_gPosY*cos_a ;
799 uint32_t transID = (uint32_t)(( trs_pos + a_nPixTrs/2*sizePixTrs) / sizePixTrs);
801 if ( axialID < a_nPixAxl && transID < a_nPixTrs )
803 castorID = axialID*a_nPixTrs + transID;
807 castorID = a_nPixAxl*a_nPixTrs;
846 uint32_t nRsectorsAxial,
847 int a_rsectorIdOrder,
848 uint32_t nModulesTransaxial,
849 uint32_t nModulesAxial,
850 uint32_t nSubmodulesTransaxial,
851 uint32_t nSubmodulesAxial,
852 uint32_t nCrystalsTransaxial,
853 uint32_t nCrystalsAxial,
855 uint32_t* nCrystalPerLayer,
856 vector<uint32_t> nLayersRptTransaxial,
857 vector<uint32_t> nLayersRptAxial,
865 uint32_t castorID = 0;
869 if(nLayersRptTransaxial.size()==0 && nLayersRptAxial.size()==0)
877 for(
int l=0 ; l<layer; l++)
878 castorID += nCrystalPerLayer[l];
880 int32_t nTrsCrystalsPerSubmodule = nCrystalsTransaxial;
881 int32_t nTrsCrystalsPerModule = nTrsCrystalsPerSubmodule * nSubmodulesTransaxial;
882 int32_t nTrsCrystalsPerRsector = nTrsCrystalsPerModule * nModulesTransaxial;
883 int32_t nCrystalsPerRing = nTrsCrystalsPerRsector * nRsectorsAngPos;
887 int32_t rsectorAxlID = 0 ;
888 int32_t rsectorTrsID = 0 ;
891 if(a_rsectorIdOrder == 0)
893 rsectorAxlID = rsectorID/nRsectorsAngPos ;
894 rsectorTrsID = (int32_t)(rsectorID%nRsectorsAngPos) ;
898 rsectorAxlID = rsectorID%nRsectorsAxial ;
899 rsectorTrsID = (int32_t)(rsectorID/nRsectorsAxial) ;
903 int32_t ringID = rsectorAxlID * nModulesAxial * nSubmodulesAxial * nCrystalsAxial
904 + (int32_t)(moduleID/nModulesTransaxial) * nSubmodulesAxial * nCrystalsAxial
905 + (int32_t)(submoduleID/nSubmodulesTransaxial) * nCrystalsAxial
906 + (int32_t)(crystalID/nCrystalsTransaxial);
908 castorID += nCrystalsPerRing * ringID
909 + nTrsCrystalsPerRsector * rsectorTrsID
910 + nTrsCrystalsPerModule * ( moduleID % nModulesTransaxial )
911 + nTrsCrystalsPerSubmodule * ( submoduleID % nSubmodulesTransaxial )
912 + crystalID % nCrystalsTransaxial;
920 uint32_t sum_crystals = nLayersRptTransaxial[layer]
921 * nLayersRptAxial[layer];
924 while (layerID >= (int32_t)sum_crystals)
927 sum_crystals += nLayersRptTransaxial[layer]
928 * nLayersRptAxial[layer];
933 for(
int l=0 ; l<layer ; l++)
934 castorID += nCrystalPerLayer[l];
936 int32_t nTrsCrystalsPerSubmodule = nCrystalsTransaxial * nLayersRptTransaxial[layer];
937 int32_t nTrsCrystalsPerModule = nTrsCrystalsPerSubmodule * nSubmodulesTransaxial;
938 int32_t nTrsCrystalsPerRsector = nTrsCrystalsPerModule * nModulesTransaxial;
939 int32_t nCrystalsPerRing = nTrsCrystalsPerRsector * nRsectorsAngPos;
943 int32_t rsectorAxlID = 0 ;
944 int32_t rsectorTrsID = 0 ;
947 if(a_rsectorIdOrder == 0)
949 rsectorAxlID = rsectorID/nRsectorsAngPos ;
950 rsectorTrsID = (int32_t)(rsectorID%nRsectorsAngPos) ;
954 rsectorAxlID = rsectorID%nRsectorsAxial ;
955 rsectorTrsID = (int32_t)(rsectorID/nRsectorsAxial) ;
959 int32_t ringID = rsectorAxlID * nModulesAxial * nSubmodulesAxial * nCrystalsAxial * nLayersRptAxial[layer]
960 + (int32_t)(moduleID/nModulesTransaxial) * nSubmodulesAxial * nCrystalsAxial * nLayersRptAxial[layer]
961 + (int32_t)(submoduleID/nSubmodulesTransaxial) * nCrystalsAxial * nLayersRptAxial[layer]
962 + (int32_t)(crystalID/nCrystalsTransaxial) * nLayersRptAxial[layer];
964 if(nLayersRptTransaxial.empty() || nLayersRptAxial.empty() )
965 ringID += (int32_t)(layerID/nLayersRptTransaxial[layer]);
967 castorID += nCrystalsPerRing * ringID
968 + nTrsCrystalsPerRsector * rsectorTrsID
969 + nTrsCrystalsPerModule * ( moduleID % nModulesTransaxial )
970 + nTrsCrystalsPerSubmodule * ( submoduleID % nSubmodulesTransaxial )
971 + crystalID % nCrystalsTransaxial
972 + layerID % nLayersRptTransaxial[layer];
996 int comptonPhantom1,
int comptonPhantom2,
997 int rayleighPhantom1,
int rayleighPhantom2)
999 if (eventID1 != eventID2)
1004 if (comptonPhantom1 == 0 && comptonPhantom2 == 0 &&
1005 rayleighPhantom1 == 0 && rayleighPhantom2 == 0)
1010 if (comptonPhantom1 == 1 || comptonPhantom2 == 1 ||
1011 rayleighPhantom1 == 1 || rayleighPhantom2 == 1)
1014 if (comptonPhantom1 > 1 || comptonPhantom2 > 1 ||
1015 rayleighPhantom1 > 1 || rayleighPhantom2 > 1)
1053 uint32_t *nb_crystal_per_layer,
1054 uint32_t &nCrystalsTot,
1055 uint32_t &nCrystalsAxial,
1056 uint32_t &nCrystalsTransaxial,
1057 vector<uint32_t> &nLayersRptAxial,
1058 vector<uint32_t> &nLayersRptTransaxial,
1059 uint32_t &nSubmodulesAxial,
1060 uint32_t &nSubmodulesTransaxial,
1061 uint32_t &nModulesAxial,
1062 uint32_t &nModulesTransaxial,
1063 uint32_t &nRsectorsAxial,
1064 uint32_t &nRsectorsAngPos,
1065 int &rsector_id_order,
1066 uint32_t &start_time_ms,
1067 uint32_t &duration_ms,
1070 vector<string> path_mac_files;
1071 path_mac_files.push_back(a_pathMac);
1076 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover paths to GATE macro files !" << endl);
1080 string rsector_name =
"";
1081 string module_name =
"";
1082 string submodule_name =
"";
1083 string crystal_name =
"";
1084 string mod_rptr_type =
"cubicArray";
1085 string smod_rptr_type =
"cubicArray";
1086 string cry_rptr_type =
"cubicArray";
1087 string lay_rptr_type =
"cubicArray";
1089 vector <string> layers_name;
1090 bool is_rsector_Y_axis =
false;
1093 if(
GetGATEAliasesCylindrical(path_mac_files, rsector_name, module_name, submodule_name, crystal_name, layers_name, vb) )
1095 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover aliases for the elements of the cylindricalPET !" << endl);
1100 nLayers = layers_name.size();
1103 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
1105 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
1108 double time_start =-1.,
1112 while(getline(mac_file, line))
1114 vector <string> values;
1120 kword =
"/gate/"+rsector_name+
"/placement/setTranslation";
1124 if (values.size()>0)
1126 FLTNB rsector_pos_X =0.,
1132 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1137 if(rsector_pos_Y!=0) is_rsector_Y_axis =
true;
1141 kword =
"/gate/"+rsector_name+
"/ring/setRepeatNumber";
1143 if (values.size()>0)
1147 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1154 kword =
"/gate/"+rsector_name+
"/linear/setRepeatNumber";
1156 if (values.size()>0)
1160 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1167 kword =
"/gate/"+rsector_name+
"/cubicArray/setRepeatNumberZ";
1170 if (values.size()>0)
1174 rsector_id_order = nRsectorsAngPos>1 ? 1 : 0 ;
1178 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1189 kword = is_rsector_Y_axis ?
1190 "/gate/"+module_name+
"/cubicArray/setRepeatNumberX":
1191 "/gate/"+module_name+
"/cubicArray/setRepeatNumberY";
1194 if (values.size()>0)
1198 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1203 kword =
"/gate/"+module_name+
"/cubicArray/setRepeatNumberZ";
1205 if (values.size()>0)
1209 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1215 kword =
"/gate/"+module_name+
"/linear/setRepeatNumber";
1217 if (values.size()>0)
1221 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1229 kword = is_rsector_Y_axis ?
1230 "/gate/"+submodule_name+
"/cubicArray/setRepeatNumberX":
1231 "/gate/"+submodule_name+
"/cubicArray/setRepeatNumberY";
1234 if (values.size()>0)
1238 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1243 kword =
"/gate/"+submodule_name+
"/cubicArray/setRepeatNumberZ";
1245 if (values.size()>0)
1249 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1255 kword =
"/gate/"+submodule_name+
"/linear/setRepeatNumber";
1257 if (values.size()>0)
1261 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1270 kword = is_rsector_Y_axis ?
1271 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberX":
1272 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberY";
1274 kword =
"/gate/"+crystal_name+
"/cubicArray/setRepeatNumberY";
1276 if (values.size()>0)
1280 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1285 kword =
"/gate/"+crystal_name+
"/cubicArray/setRepeatNumberZ";
1287 if (values.size()>0)
1291 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1298 kword =
"/gate/"+crystal_name+
"/linear/setRepeatNumber";
1300 if (values.size()>0)
1304 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1313 for(
int l=0 ; l<nLayers ; l++)
1315 kword = is_rsector_Y_axis ?
1316 "/gate/"+layers_name[l]+
"/cubicArray/setRepeatNumberX":
1317 "/gate/"+layers_name[l]+
"/cubicArray/setRepeatNumberY";
1320 if (values.size()>0)
1325 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1328 nLayersRptTransaxial.push_back(val);
1331 kword =
"/gate/"+layers_name[l]+
"/cubicArray/setRepeatNumberZ";
1333 if (values.size()>0)
1338 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1341 nLayersRptAxial.push_back(val);
1345 kword =
"/gate/"+layers_name[l]+
"/linear/setRepeatNumber";
1347 if (values.size()>0)
1352 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1355 nLayersRptAxial.push_back(val);
1362 kword =
"/gate/application/setTimeStart";
1364 if (values.size()>0)
1368 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1373 if (values.size()>1)
1375 if(values[1] ==
"s") time_start *= 1000;
1378 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1380 start_time_ms = time_start;
1383 kword =
"/gate/application/setTimeStop";
1385 if (values.size()>0)
1389 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1394 if (values.size()>1)
1396 if(values[1] ==
"s") time_stop *= 1000;
1399 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1402 kword =
"/gate/application/addSlice";
1404 if (values.size()>0)
1406 double time_slice_tmp=0;
1410 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1415 if (values.size()>1)
1417 if(values[1] ==
"s") time_slice_tmp *= 1000;
1420 Cerr(
"***** dataConversionUtilities::readMacCylindrical()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1422 time_slices += time_slice_tmp;
1427 duration_ms = (time_slices>0) ?
1428 (uint32_t)(time_slices-time_start) :
1431 duration_ms = (time_start>=0 && time_stop>=0) ?
1432 (uint32_t)(time_stop-time_start) :
1441 nCrystalsTot = nRsectorsAngPos * nRsectorsAxial
1442 * nModulesTransaxial * nModulesAxial
1443 * nSubmodulesTransaxial * nSubmodulesAxial
1444 * nCrystalsTransaxial * nCrystalsAxial;
1447 for(
int l=0 ; l<nLayers ; l++)
1449 uint32_t nb_crystals_layer = nRsectorsAngPos * nRsectorsAxial
1450 * nModulesTransaxial * nModulesAxial
1451 * nSubmodulesTransaxial * nSubmodulesAxial
1452 * nCrystalsTransaxial * nCrystalsAxial;
1455 if(nLayersRptTransaxial.size()>0 || nLayersRptAxial.size()>0 )
1456 nb_crystals_layer *= nLayersRptTransaxial[l] * nLayersRptAxial[l];
1458 nb_crystal_per_layer[l] = nb_crystals_layer;
1460 nCrystalsTot += nb_crystals_layer;
1467 Cout(
"-----------------------------------------------------------" << endl);
1468 Cout(
"ReadMacCylindrical()-> Information recovered from mac file:" << endl);
1469 Cout(
"-----------------------------------------------------------" << endl);
1470 Cout(
"Number of rsectors angular position: " << nRsectorsAngPos << endl);
1471 Cout(
"Number of axial rsectors: " << nRsectorsAxial << endl);
1472 Cout(
"Number of axial modules: " << nModulesAxial << endl);
1473 Cout(
"Number of transaxial modules: " << nModulesTransaxial << endl);
1474 Cout(
"Number of axial submodules: " << nSubmodulesAxial << endl);
1475 Cout(
"Number of transaxial submodules: " << nSubmodulesTransaxial << endl);
1476 Cout(
"Number of axial crystals: " << nCrystalsAxial << endl);
1477 Cout(
"Number of transaxial crystals: " << nCrystalsTransaxial << endl);
1480 Cout(
"Number of layers: " << (uint16_t)nLayers << endl);
1481 for(
int l=0 ; l<nLayers ; l++)
1482 Cout(
"Layer "<< l <<
" : Number of crystals: " << nb_crystal_per_layer[l] << endl);
1484 Cout(
"Total number of crystals (including layers): " << nCrystalsTot << endl);
1485 Cout(
"Acquisition start time (ms): " << start_time_ms << endl);
1486 Cout(
"Acquisition duration (ms): " << duration_ms << endl);
1487 Cout(
"-----------------------------------------------------------" << endl << endl);
1513 uint32_t &nCrystalsTot,
1514 uint32_t &nCrystalsAxial,
1515 uint32_t &nCrystalsTransaxial,
1516 uint32_t &nBlocksLine,
1517 uint32_t &nBlocksPerRing,
1518 uint32_t &start_time_ms,
1519 uint32_t &duration_ms,
1523 vector<string> path_mac_files;
1524 path_mac_files.push_back(a_pathMac);
1527 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover paths to GATE macro files !" << endl);
1531 string block_name =
"block";
1532 string crystal_name =
"crystal";
1533 bool is_block_Y_axis =
false;
1538 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover aliases for the elements of the ecat !" << endl);
1544 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
1546 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
1549 double time_start=-1.,
1553 while(getline(mac_file, line))
1555 vector <string> values;
1558 kword =
"/gate/"+block_name+
"/placement/setTranslation";
1560 if (values.size()>0)
1562 FLTNB block_pos_X=0.,
1568 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
1573 if(block_pos_Y!=0) is_block_Y_axis =
true;
1576 kword =
"/gate/"+block_name+
"/ring/setRepeatNumber";
1578 if (values.size()>0)
1582 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1587 kword =
"/gate/"+block_name+
"/linear/setRepeatNumber";
1589 if (values.size()>0)
1593 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1598 kword = is_block_Y_axis ?
1599 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberX":
1600 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberY";
1603 if (values.size()>0)
1607 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1612 kword =
"/gate/"+crystal_name+
"/cubicArray/setRepeatNumberZ";
1614 if (values.size()>0)
1618 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1624 kword =
"/gate/application/setTimeStart";
1626 if (values.size()>0)
1630 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1635 if (values.size()>1)
1637 if(values[1] ==
"s") time_start *= 1000;
1640 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1642 start_time_ms = time_start;
1645 kword =
"/gate/application/setTimeStop";
1647 if (values.size()>0)
1651 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1656 if (values.size()>1)
1658 if(values[1] ==
"s") time_stop *= 1000;
1661 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1664 kword =
"/gate/application/addSlice";
1666 if (values.size()>0)
1668 double time_slice_tmp=0;
1672 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1677 if (values.size()>1)
1679 if(values[1] ==
"s") time_slice_tmp *= 1000;
1682 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1684 time_slices = time_slice_tmp;
1689 duration_ms = (time_slices>0) ?
1690 (uint32_t)(time_slices-time_start) :
1693 duration_ms = (time_start>=0 && time_stop>=0) ?
1694 (uint32_t)(time_stop-time_start) :
1701 nCrystalsTot = nCrystalsTransaxial * nCrystalsAxial
1702 * nBlocksLine * nBlocksPerRing;
1708 Cout(
"-----------------------------------------------------" << endl);
1709 Cout(
"ReadMacECAT()-> Information recovered from mac file:" << endl);
1710 Cout(
"-----------------------------------------------------" << endl);
1711 Cout(
"Number of blocks per ring: " << nBlocksPerRing << endl);
1712 Cout(
"Number of axial blocks: " << nBlocksLine << endl);
1713 Cout(
"Number of axial crystals: " << nCrystalsAxial << endl);
1714 Cout(
"Number of transaxial crystals: " << nCrystalsTransaxial << endl);
1715 Cout(
"Total number of crystals: " << nCrystalsTot << endl);
1716 Cout(
"Acquisition start time (ms): " << start_time_ms << endl);
1717 Cout(
"Acquisition duration (ms): " << duration_ms << endl);
1718 Cout(
"-----------------------------------------------------" << endl << endl);
1750 float_t &a_distToDetector,
1752 uint32_t &a_nPixAxl,
1753 uint32_t &a_nPixTrs,
1754 float_t &a_crystalSizeAxl,
1755 float_t &a_crystalSizeTrs,
1756 uint32_t &a_nProjectionsTot,
1757 uint32_t &a_nProjectionsByHead,
1758 float_t &a_head1stAngle,
1759 float_t &a_headAngPitch,
1760 float_t &a_headAngStepDeg,
1761 int &a_headRotDirection,
1762 uint32_t &a_start_time_ms,
1763 uint32_t &a_duration_ms,
1767 vector<string> path_mac_files;
1768 path_mac_files.push_back(a_pathMac);
1772 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover paths to GATE macro files !" << endl);
1776 string head_name =
"SPECThead";
1777 string crystal_name =
"crystal";
1778 string pixel_name =
"pixel";
1779 string head_orbit_name =
"";
1780 bool is_head_Y_axis =
false;
1785 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover aliases for the elements of the ecat !" << endl);
1790 double time_start=-1.,
1795 head_rot_speed =-1.;
1798 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
1800 ifstream mac_file(path_mac_files[f].c_str(), ios::in);
1804 while(getline(mac_file, line))
1806 vector <string> values;
1808 kword =
"/gate/"+head_name+
"/placement/setTranslation";
1810 if (values.size()>0)
1812 FLTNB head_pos_X=0.,
1818 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1823 if(head_pos_Y!=0) is_head_Y_axis =
true;
1825 a_distToDetector = is_head_Y_axis ? abs(head_pos_Y) : abs(head_pos_X) ;
1830 kword =
"/gate/"+head_name+
"/ring/setRepeatNumber";
1832 if (values.size()>0)
1836 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1841 kword =
"/gate/"+head_name+
"/ring/setFirstAngle";
1843 if (values.size()>0)
1847 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1852 kword =
"/gate/"+head_name+
"/ring/setAngularPitch";
1854 if (values.size()>0)
1858 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1863 kword =
"/gate/"+head_name+
"/moves/insert";
1865 if (values.size()>0)
1869 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1874 kword =
"/gate/"+head_name+
"/"+head_orbit_name+
"/setSpeed";
1876 if (values.size()>0)
1880 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1885 kword =
"/gate/"+head_name+
"/"+head_orbit_name+
"/setPoint2";
1887 if (values.size()>0)
1892 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
1900 kword = is_head_Y_axis ?
1901 "/gate/"+crystal_name+
"/geometry/setXLength":
1902 "/gate/"+crystal_name+
"/geometry/setYLength";
1905 if (values.size()>0)
1909 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1915 kword =
"/gate/"+crystal_name+
"/geometry/setZLength";
1917 if (values.size()>0)
1921 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1928 kword = is_head_Y_axis ?
1929 "/gate/"+pixel_name+
"/cubicArray/setRepeatNumberX":
1930 "/gate/"+pixel_name+
"/cubicArray/setRepeatNumberY";
1934 if (values.size()>0)
1938 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1943 kword =
"/gate/"+pixel_name+
"/cubicArray/setRepeatNumberZ";
1945 if (values.size()>0)
1949 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
1954 kword =
"/gate/application/setTimeStart";
1956 if (values.size()>0)
1960 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1965 if (values.size()>1)
1967 if(values[1] ==
"s") time_start *= 1000;
1970 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1972 a_start_time_ms = time_start;
1975 kword =
"/gate/application/setTimeSlice";
1977 if (values.size()>0)
1981 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
1986 if (values.size()>1)
1988 if(values[1] ==
"s") time_slice *= 1000;
1991 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
1993 time_slice_ms = time_slice;
1996 kword =
"/gate/application/setTimeStop";
1998 if (values.size()>0)
2002 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
2007 if (values.size()>1)
2009 if(values[1] ==
"s") time_stop *= 1000;
2012 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
2015 kword =
"/gate/application/addSlice";
2017 if (values.size()>0)
2019 double time_slice_tmp=0;
2023 Cerr(
"***** dataConversionUtilities::readMacECAT()-> Error occured while trying to get value from entry '"<< kword <<
"' in file " << path_mac_files[f] <<
"!");
2028 if (values.size()>1)
2030 if(values[1] ==
"s") time_slice_tmp *= 1000;
2033 Cerr(
"***** dataConversionUtilities::readMacECAT()-> WARNING : can't read unit of '"<< kword <<
". Assuming time in seconds");
2035 time_slices = time_slice_tmp;
2042 a_duration_ms = (time_slices>0) ?
2043 (uint32_t)(time_slices-time_start) :
2047 a_duration_ms = (time_start>=0 && time_stop>=0) ?
2048 (uint32_t)(time_stop-time_start) :
2053 a_nProjectionsByHead = a_duration_ms / time_slice_ms;
2054 a_nProjectionsTot = a_nHeads*a_nProjectionsByHead;
2057 a_headAngPitch = (a_headAngPitch<0) ?
2061 a_headAngStepDeg = head_rot_speed*time_slice_ms/1000.;
2063 if(head_rot_speed<0)
2065 Cerr(
"***** GetGATESystemType() -> Error couldn't find line '/gate/"+head_name+
"/"+head_orbit_name+
"/setSpeed' !" << endl);
2066 Cerr(
" This information is mandatory to compute the projection angle step." << endl);
2072 Cerr(
"***** GetGATESystemType() -> Error couldn't find line '/gate/application/setTimeSlice' !" << endl);
2073 Cerr(
" This information is mandatory to compute the projection angle step." << endl);
2077 if(a_duration_ms == 0)
2081 Cerr(
"***** GetGATESystemType() -> Error couldn't compute acquisition find line '/gate/application/setTimeStop' !" << endl);
2082 Cerr(
" This information is mandatory to compute the acquisition duration." << endl);
2087 Cerr(
"***** GetGATESystemType() -> Error couldn't compute acquisition find line '/gate/application/setTimeStart' !" << endl);
2088 Cerr(
" This information is mandatory to compute the acquisition duration." << endl);
2099 Cout(
"-----------------------------------------------------" << endl);
2100 Cout(
"ReadMacSPECT()-> Information recovered from mac file:" << endl);
2101 Cout(
"-----------------------------------------------------" << endl);
2102 Cout(
"Distance to detector: " << a_distToDetector << endl);
2103 Cout(
"Number of heads: " << a_nHeads << endl);
2104 Cout(
"Number of axial pixels: " << a_nPixAxl << endl);
2105 Cout(
"Number of transaxial pixels: " << a_nPixTrs << endl);
2106 Cout(
"Crystal axial size: " << a_crystalSizeAxl << endl);
2107 Cout(
"Crystal transaxial size: " << a_crystalSizeTrs << endl);
2108 Cout(
"Number of projections per head: " << a_nProjectionsByHead << endl);
2109 Cout(
"Total number of projections: " << a_nProjectionsTot << endl);
2110 Cout(
"Head(s) first transaxial angle: " << a_head1stAngle << endl);
2111 Cout(
"Head(s) angular pitch: " << a_headAngPitch << endl);
2112 Cout(
"Angular step between projections (deg): " << a_headAngStepDeg << endl);
2113 Cout(
"Rotation direction (0=CW, 1=CCW): " << a_headRotDirection << endl);
2114 Cout(
"Acquisition start time (ms): " << a_start_time_ms << endl);
2115 Cout(
"Acquisition duration (ms): " << a_duration_ms << endl);
2116 Cout(
"-----------------------------------------------------" << endl << endl);
2149 float_t &a_distToDetector,
2151 uint32_t &a_nPixAxl,
2152 uint32_t &a_nPixTrs,
2153 float_t &a_crystalSizeAxl,
2154 float_t &a_crystalSizeTrs,
2155 uint32_t &a_nProjectionsTot,
2156 uint32_t &a_nProjectionsByHead,
2157 float_t &a_head1stAngle,
2158 float_t &a_headAngPitchDeg,
2159 float_t &a_headAngStepDeg,
2160 int &a_headRotDirection,
2161 uint32_t &a_start_time_ms,
2162 uint32_t &a_duration_ms,
2169 key =
"matrix size [1]";
2172 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2173 Cerr(
" Either key not found or conversion error" << endl);
2177 key =
"matrix size [2]";
2180 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2181 Cerr(
" Either key not found or conversion error" << endl);
2185 FLTNB size_pix_trs = 1.,
2188 key =
"scaling factor (mm/pixel) [1]";
2191 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2192 Cerr(
" Either key not found or conversion error" << endl);
2196 key =
"scaling factor (mm/pixel) [2]";
2199 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2200 Cerr(
" Either key not found or conversion error" << endl);
2204 key =
"total number of images";
2207 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2208 Cerr(
" Either key not found or conversion error" << endl);
2212 key =
"number of projections";
2215 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2216 Cerr(
" Either key not found or conversion error" << endl);
2220 key =
"number of detector heads";
2223 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2224 Cerr(
" Either key not found or conversion error" << endl);
2228 key =
"study duration (sec)";
2231 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2232 Cerr(
" Either key not found or conversion error" << endl);
2236 a_duration_ms *= 1000;
2239 FLTNB size_crystal_X =0.,
2242 key =
"crystal x dimension (cm)";
2245 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2246 Cerr(
" Either key not found or conversion error" << endl);
2250 key =
"crystal y dimension (cm)";
2253 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2254 Cerr(
" Either key not found or conversion error" << endl);
2258 key =
"crystal z dimension (cm)";
2261 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2262 Cerr(
" Either key not found or conversion error" << endl);
2268 if(size_crystal_X>0 && size_crystal_Y>0)
2269 a_crystalSizeTrs = (size_crystal_X>size_crystal_Y) ? size_crystal_X*10. : size_crystal_Y*10.;
2270 a_crystalSizeAxl = (a_crystalSizeAxl>0) ? a_crystalSizeAxl*10. : a_crystalSizeAxl ;
2273 FLTNB head_pos_X =-1.,
2277 key =
"head x translation (cm)";
2280 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2281 Cerr(
" Either key not found or conversion error" << endl);
2285 key =
"head y translation (cm)";
2288 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2289 Cerr(
" Either key not found or conversion error" << endl);
2293 key =
"head z translation (cm)";
2296 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2297 Cerr(
" Either key not found or conversion error" << endl);
2302 if(head_pos_X > head_pos_Y)
2303 a_distToDetector = head_pos_X > head_pos_Z ? head_pos_X*10 : head_pos_Z*10;
2305 a_distToDetector = head_pos_Y > head_pos_Z ? head_pos_Y*10 : head_pos_Z*10;
2308 key =
"direction of rotation";
2312 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2313 Cerr(
" Either key not found or conversion error" << endl);
2321 key =
"start angle";
2324 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2325 Cerr(
" Either key not found or conversion error" << endl);
2329 key =
"extent of rotation";
2330 uint32_t extent_rotation =360;
2333 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2334 Cerr(
" Either key not found or conversion error" << endl);
2338 a_headAngStepDeg = (
FLTNB)extent_rotation / a_nProjectionsByHead;
2340 float_t first_angle = 0;
2341 float_t second_angle = extent_rotation;
2343 key =
"start angle";
2346 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2347 Cerr(
" Either key not found or conversion error" << endl);
2351 key =
"start angle";
2354 Cerr(
"***** castor-GATERootToCastor :: Error when trying to read key: '"<< key <<
"' in interfile : " << a_pathIntf <<
"!" << endl);
2355 Cerr(
" Either key not found or conversion error" << endl);
2359 a_headAngPitchDeg = second_angle - first_angle;
2384 string scanner_name =
GetFileFromPath(a_pathGeom.substr(0,a_pathGeom.find(
".geom")));
2385 double scanner_radius = 0.;
2386 uint32_t number_of_elements = 0;
2387 string description =
"PET system extracted from GATE macro: " + a_pathMac;
2390 string rsector_name =
"";
2391 uint32_t number_of_rsectors_ang = 1;
2392 uint32_t number_of_rsectors_axl = 1;
2393 double rsector_step_axl = 0.;
2394 double rsector_gap_axl = 0.;
2395 double rsector_first_angle = 0.;
2396 double rsector_angular_span = 360.;
2397 double rsector_pos_X = 0.;
2398 double rsector_pos_Y = 0.;
2399 uint32_t rsector_nb_zshifts = 0;
2400 vector <double> vec_rsector_Z_Shift;
2401 bool is_rsector_Y_axis =
false;
2402 double rsector_size_trs;
2403 double rsector_size_axl;
2406 string module_name =
"";
2407 uint32_t number_of_modules_trs = 1;
2408 uint32_t number_of_modules_axl = 1;
2409 double module_step_trs = 0.;
2410 double module_step_axl = 0.;
2411 double module_gap_trs = 0.;
2412 double module_gap_axl = 0.;
2413 double module_size_trs;
2414 double module_size_axl;
2417 string submodule_name =
"";
2418 uint32_t number_of_submodules_trs = 1;
2419 uint32_t number_of_submodules_axl = 1;
2420 double submodule_step_trs = 0.;
2421 double submodule_step_axl = 0.;
2422 double submodule_gap_trs = 0.;
2423 double submodule_gap_axl = 0.;
2424 double submodule_size_trs;
2425 double submodule_size_axl;
2428 string crystal_name =
"";
2429 uint32_t number_of_crystals_trs = 1;
2430 uint32_t number_of_crystals_axl = 1;
2431 double crystal_step_trs = 0.;
2432 double crystal_step_axl = 0.;
2433 double crystal_gap_trs = 0.;
2434 double crystal_gap_axl = 0.;
2435 double crystal_size_depth = 0.;
2436 double crystal_size_trs = 0.;
2437 double crystal_size_axl = 0.;
2441 int number_of_layers = 0;
2442 string n_layers =
"1";
2443 vector <uint32_t> number_of_lyr_elts_trs;
2444 vector <uint32_t> number_of_lyr_elts_axl;
2446 vector <string> layers_names;
2447 vector <vector <double> > layers_positions;
2448 vector <double> layers_size_depth;
2449 vector <double> layers_size_trs;
2450 vector <double> layers_size_axl;
2452 vector <double> layers_step_trs;
2453 vector <double> layers_step_axl;
2456 uint32_t voxels_number_trs;
2457 uint32_t voxels_number_axl;
2460 double mean_depth_of_interaction = -1.;
2461 double min_angle_diff = 0.;
2466 vector <string> vec_scanner_radius;
2469 vector <string> vec_number_of_rsectors_ang;
2470 vector <string> vec_number_of_rsectors_axl;
2471 vector <string> vec_rsector_gap_trs;
2472 vector <string> vec_rsector_gap_axl;
2473 vector <string> vec_rsector_first_angle;
2477 vector <string> vec_number_of_modules_trs;
2478 vector <string> vec_number_of_modules_axl;
2479 vector <string> vec_module_gap_trs;
2480 vector <string> vec_module_gap_axl;
2483 vector <string> vec_number_of_submodules_trs;
2484 vector <string> vec_number_of_submodules_axl;
2485 vector <string> vec_submodule_gap_trs;
2486 vector <string> vec_submodule_gap_axl;
2489 vector <string> vec_number_of_crystals_trs;
2490 vector <string> vec_number_of_crystals_axl;
2491 vector <string> vec_crystal_gap_trs;
2492 vector <string> vec_crystal_gap_axl;
2495 vector <string> vec_mean_depth_of_interaction;
2496 vector <string> vec_min_angle_diff;
2498 vector<string> path_mac_files;
2499 path_mac_files.push_back(a_pathMac);
2504 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover paths to GATE macro files !" << endl);
2509 if(
GetGATEAliasesCylindrical(path_mac_files, rsector_name, module_name, submodule_name, crystal_name, layers_names, 2) )
2511 Cerr(
"***** GetGATESystemType() -> Error occured when trying to recover aliases for the elements of the cylindricalPET !" << endl);
2516 n_layers = layers_names.size();
2520 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
2522 ifstream systemMac(path_mac_files[f].c_str(), ios::in);
2526 while(getline(systemMac, line))
2528 vector <string> values;
2535 entry =
"/gate/"+rsector_name+
"/placement/setTranslation";
2539 if (values.size()>0)
2544 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2550 if(rsector_pos_X!=0 && rsector_pos_Y !=0)
2552 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2553 Cerr(
" Rsector cartesian coordinates on either the X or Y axis expected to be equal to 0 "<< endl);
2558 if(rsector_pos_Y!=0) is_rsector_Y_axis =
true;
2560 scanner_radius += is_rsector_Y_axis ? abs(rsector_pos_Y) : abs(rsector_pos_X) ;
2564 entry = is_rsector_Y_axis ?
2565 "/gate/"+rsector_name+
"/geometry/setYLength" :
2566 "/gate/"+rsector_name+
"/geometry/setXLength";
2569 if (values.size()>0)
2571 double rsector_size_depth = 0.;
2574 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2578 scanner_radius -= rsector_size_depth/2;
2583 entry = is_rsector_Y_axis ?
2584 "/gate/"+rsector_name+
"/geometry/setXLength":
2585 "/gate/"+rsector_name+
"/geometry/setYLength";
2588 if (values.size()>0)
2592 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2601 entry =
"/gate/"+rsector_name+
"/ring/setModuloNumber";
2603 if (values.size()>0)
2607 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2612 entry =
"/gate/"+rsector_name+
"/ring/setRepeatNumber";
2614 if (values.size()>0)
2618 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2626 entry =
"/gate/"+rsector_name+
"/linear/setRepeatNumber";
2628 if (values.size()>0)
2632 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2640 entry =
"/gate/"+rsector_name+
"/linear/setRepeatVector";
2642 if (values.size()>0)
2646 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2653 entry = is_rsector_Y_axis ?
2654 "/gate/"+rsector_name+
"/cubicArray/setRepeatNumberX":
2655 "/gate/"+rsector_name+
"/cubicArray/setRepeatNumberY";
2658 if (values.size()>0)
2660 uint32_t number_of_rsectors_trs;
2664 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2671 if(number_of_rsectors_trs>1)
2673 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Error while trying to parse line: " << line<< endl);
2674 Cerr(
" The GATE system contains more than one 'transaxial' rsector " << endl);
2675 Cerr(
" The current implementation does not support such cylindricalPET model" << endl);
2676 Cerr(
" Manual implementation of the system is required (ex: model the transaxial rsectors as modules)" << endl);
2682 entry =
"/gate/"+rsector_name+
"/cubicArray/setRepeatNumberZ";
2685 if (values.size()>0)
2689 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2695 entry =
"/gate/"+rsector_name+
"/cubicArray/setRepeatVector";
2697 if (values.size()>0)
2701 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2709 entry =
"/gate/"+rsector_name+
"/geometry/setZLength";
2711 if (values.size()>0)
2715 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2722 entry =
"/gate/"+rsector_name+
"/ring/setFirstAngle";
2724 if (values.size()>0)
2728 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2733 entry =
"/gate/"+rsector_name+
"/ring/setAngularSpan";
2735 if (values.size()>0)
2739 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2745 for (
int i=1; i <8; i++)
2747 entry =
"/gate/"+rsector_name+
"/ring/setZShift"+
toString(i);
2749 if (values.size()>0)
2754 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2758 vec_rsector_Z_Shift.push_back(zshift);
2766 entry = is_rsector_Y_axis ?
2767 "/gate/"+module_name+
"/cubicArray/setRepeatNumberX":
2768 "/gate/"+module_name+
"/cubicArray/setRepeatNumberY";
2771 if (values.size()>0)
2775 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2783 entry =
"/gate/"+module_name+
"/cubicArray/setRepeatNumberZ";
2786 if (values.size()>0)
2790 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2796 entry = is_rsector_Y_axis ?
2797 "/gate/"+module_name+
"/geometry/setXLength":
2798 "/gate/"+module_name+
"/geometry/setYLength";
2801 if (values.size()>0)
2805 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2811 entry =
"/gate/"+module_name+
"/geometry/setZLength";
2813 if (values.size()>0)
2817 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2822 entry =
"/gate/"+module_name+
"/cubicArray/setRepeatVector";
2824 if (values.size()>0)
2826 string trs_step = is_rsector_Y_axis ?
2833 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2842 entry =
"/gate/"+module_name+
"/linear/setRepeatNumber";
2845 if (values.size()>0)
2849 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2854 entry =
"/gate/"+module_name+
"/linear/setRepeatVector";
2856 if (values.size()>0)
2860 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2867 entry = is_rsector_Y_axis ?
2868 "/gate/"+submodule_name+
"/cubicArray/setRepeatNumberX":
2869 "/gate/"+submodule_name+
"/cubicArray/setRepeatNumberY";
2873 if (values.size()>0)
2877 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2882 entry =
"/gate/"+submodule_name+
"/cubicArray/setRepeatNumberZ";
2884 if (values.size()>0)
2888 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2896 entry = is_rsector_Y_axis ?
2897 "/gate/"+submodule_name+
"/geometry/setXLength":
2898 "/gate/"+submodule_name+
"/geometry/setYLength";
2901 if (values.size()>0)
2905 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2910 entry =
"/gate/"+submodule_name+
"/geometry/setZLength";
2912 if (values.size()>0)
2916 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2921 entry =
"/gate/"+submodule_name+
"/cubicArray/setRepeatVector";
2923 if (values.size()>0)
2925 string trs_step = is_rsector_Y_axis ?
2932 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2940 entry =
"/gate/"+submodule_name+
"/linear/setRepeatNumber";
2943 if (values.size()>0)
2947 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2953 entry =
"/gate/"+submodule_name+
"/linear/setRepeatVector";
2955 if (values.size()>0)
2959 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2969 entry = is_rsector_Y_axis ?
2970 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberX":
2971 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberY";
2975 if (values.size()>0)
2979 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2984 entry =
"/gate/"+crystal_name+
"/cubicArray/setRepeatNumberZ";
2986 if (values.size()>0)
2990 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
2996 entry =
"/gate/"+crystal_name+
"/geometry/setXLength";
2998 if (values.size()>0)
3003 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3007 if (is_rsector_Y_axis)
3008 crystal_size_trs = x_length;
3010 crystal_size_depth = x_length;
3013 entry =
"/gate/"+crystal_name+
"/geometry/setYLength";
3015 if (values.size()>0)
3020 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3024 if (is_rsector_Y_axis)
3025 crystal_size_depth = y_length;
3027 crystal_size_trs = y_length;
3031 entry =
"/gate/"+crystal_name+
"/geometry/setZLength";
3033 if (values.size()>0)
3037 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3042 entry =
"/gate/"+crystal_name+
"/cubicArray/setRepeatVector";
3044 if (values.size()>0)
3046 string trs_step = is_rsector_Y_axis ?
3053 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3059 entry =
"/gate/"+crystal_name+
"/linear/setRepeatNumber";
3062 if (values.size()>0)
3066 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3071 entry =
"/gate/"+crystal_name+
"/linear/setRepeatVector";
3073 if (values.size()>0)
3077 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3086 entry =
"/gate/"+crystal_name+
"/daughters/name";
3088 if (values.size()>0)
3090 layers_names.push_back(values[0]);
3095 for (
int i=0; i < number_of_layers; i++)
3098 entry =
"/gate/"+layers_names[i]+
"/placement/setTranslation";
3101 if (values.size()>0)
3103 vector<double> layer_pos;
3104 for(
int d=0 ; d<3 ; d++)
3109 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3112 layer_pos.push_back(pos);
3115 if(is_rsector_Y_axis)
3117 double pos = layer_pos[1];
3118 layer_pos[1] = layer_pos[0];
3122 layers_positions.push_back(layer_pos);
3127 entry =
"/gate/"+layers_names[i]+
"/geometry/setXLength";
3130 if (values.size()>0)
3135 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3139 if (is_rsector_Y_axis)
3140 layers_size_trs.push_back(xlength);
3142 layers_size_depth.push_back(xlength);
3146 entry =
"/gate/"+layers_names[i]+
"/geometry/setYLength";
3148 if (values.size()>0)
3153 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3156 if (is_rsector_Y_axis)
3157 layers_size_depth.push_back(ylength);
3159 layers_size_trs.push_back(ylength);
3162 entry =
"/gate/"+layers_names[i]+
"/geometry/setZLength";
3164 if (values.size()>0)
3169 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3172 layers_size_axl.push_back(zlength);
3178 entry = is_rsector_Y_axis ?
3179 "/gate/"+layers_names[i]+
"/cubicArray/setRepeatNumberX":
3180 "/gate/"+layers_names[i]+
"/cubicArray/setRepeatNumberY";
3183 if (values.size()>0)
3188 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3191 number_of_lyr_elts_trs.push_back(step_trs);
3194 entry =
"/gate/"+layers_names[i]+
"/cubicArray/setRepeatNumberZ";
3196 if (values.size()>0)
3201 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3204 number_of_lyr_elts_axl.push_back(step_axl);
3207 entry =
"/gate/"+layers_names[i]+
"/cubicArray/setRepeatVector";
3209 if (values.size()>0)
3211 string trs_step = is_rsector_Y_axis ?
3215 double step_trs, step_axl;
3219 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3224 layers_step_trs.push_back(step_trs);
3225 layers_step_axl.push_back(step_axl);
3230 entry =
"/gate/"+layers_names[i]+
"/linear/setRepeatNumber";
3233 if (values.size()>0)
3238 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3241 number_of_lyr_elts_axl.push_back(step_axl);
3245 entry =
"/gate/"+layers_names[i]+
"/linear/setRepeatVector";
3247 if (values.size()>0)
3252 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3256 layers_step_axl.push_back(step_axl);
3262 entry =
"/gate/digitizer/Coincidences/minSectorDifference";
3264 if (values.size()>0)
3266 FLTNB min_sector_diff= 0.;
3270 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3274 min_angle_diff = 360./number_of_rsectors_ang*min_sector_diff;
3283 if(number_of_layers == 0)
3285 number_of_elements = number_of_rsectors_ang
3286 * number_of_rsectors_axl
3287 * number_of_modules_trs
3288 * number_of_modules_axl
3289 * number_of_submodules_trs
3290 * number_of_submodules_axl
3291 * number_of_crystals_trs
3292 * number_of_crystals_axl;
3295 for(
int l=0 ; l<number_of_layers ; l++)
3297 int32_t nb_crystals_layer = number_of_rsectors_ang
3298 * number_of_rsectors_axl
3299 * number_of_modules_trs
3300 * number_of_modules_axl
3301 * number_of_submodules_trs
3302 * number_of_submodules_axl
3303 * number_of_crystals_trs
3304 * number_of_crystals_axl;
3307 if(number_of_lyr_elts_trs.size()>0 || number_of_lyr_elts_axl.size()>0 )
3308 nb_crystals_layer *= number_of_lyr_elts_trs[l] * number_of_lyr_elts_axl[l];
3310 number_of_elements += nb_crystals_layer;
3317 if (crystal_step_axl - crystal_size_axl >= 0)
3318 crystal_gap_axl = crystal_step_axl - crystal_size_axl;
3320 if (crystal_step_trs - crystal_size_trs >= 0)
3321 crystal_gap_trs = crystal_step_trs - crystal_size_trs;
3324 submodule_size_axl = crystal_size_axl*number_of_crystals_axl + crystal_gap_axl*(number_of_crystals_axl-1);
3325 submodule_size_trs = crystal_size_trs*number_of_crystals_trs + crystal_gap_trs*(number_of_crystals_trs-1);
3328 if (submodule_step_axl - submodule_size_axl >= 0)
3329 submodule_gap_axl = submodule_step_axl - submodule_size_axl;
3331 if (submodule_step_trs - submodule_size_trs >= 0)
3332 submodule_gap_trs = submodule_step_trs - submodule_size_trs;
3335 module_size_axl = submodule_size_axl*number_of_submodules_axl + submodule_gap_axl*(number_of_submodules_axl-1);
3336 module_size_trs = submodule_size_trs*number_of_submodules_trs + submodule_gap_trs*(number_of_submodules_trs-1);
3339 if (module_step_axl - module_size_axl >= 0)
3340 module_gap_axl = module_step_axl - module_size_axl;
3342 if (module_step_trs - module_size_trs >= 0)
3343 module_gap_trs = module_step_trs - module_size_trs;
3346 rsector_size_axl = module_size_axl*number_of_modules_axl + module_gap_axl*(number_of_modules_axl-1);
3347 rsector_size_trs = module_size_trs*number_of_modules_trs + module_gap_trs*(number_of_modules_trs-1);
3351 if (rsector_step_axl - rsector_size_axl >= 0)
3352 rsector_gap_axl = rsector_step_axl - rsector_size_axl;
3356 fov_axl = rsector_size_axl * number_of_rsectors_axl
3357 + (number_of_rsectors_axl-1)*rsector_gap_axl;
3361 voxels_number_axl = ( number_of_crystals_axl
3362 * number_of_submodules_axl
3363 * number_of_modules_axl
3364 * number_of_rsectors_axl )
3368 fov_trs = (2*scanner_radius ) / 1.5;
3372 voxels_number_trs = ( number_of_crystals_trs
3373 * number_of_submodules_trs
3374 * number_of_modules_trs
3375 * number_of_rsectors_ang )
3381 rsector_first_angle -= round(atan2f(rsector_pos_X , rsector_pos_Y) * 180. / M_PI);
3384 if (number_of_layers > 0)
3386 for (
int l=0; l < number_of_layers ; l++)
3389 vec_scanner_radius.push_back(
toString(scanner_radius+layers_positions[l][0]) );
3392 vec_number_of_rsectors_ang.push_back(
toString(number_of_rsectors_ang) );
3393 vec_number_of_rsectors_axl.push_back(
toString(number_of_rsectors_axl) );
3394 vec_rsector_gap_axl.push_back(
toString(rsector_gap_axl) );
3395 vec_rsector_first_angle.push_back(
toString(rsector_first_angle) );
3398 vec_number_of_modules_trs.push_back(
toString(number_of_modules_trs) );
3399 vec_number_of_modules_axl.push_back(
toString(number_of_modules_axl) );
3400 vec_module_gap_trs.push_back(
toString(module_gap_trs) );
3401 vec_module_gap_axl.push_back(
toString(module_gap_axl) );
3404 vec_number_of_submodules_trs.push_back(
toString(number_of_submodules_trs) );
3405 vec_number_of_submodules_axl.push_back(
toString(number_of_submodules_axl) );
3406 vec_submodule_gap_trs.push_back(
toString(submodule_gap_trs) );
3407 vec_submodule_gap_axl.push_back(
toString(submodule_gap_axl) );
3410 uint32_t nb_tot_trs_cry = (number_of_lyr_elts_trs.size()>0) ?
3411 number_of_lyr_elts_trs[l]*number_of_crystals_trs :
3412 number_of_crystals_trs ;
3414 uint32_t nb_tot_axl_cry = (number_of_lyr_elts_axl.size()>0) ?
3415 number_of_lyr_elts_axl[l]*number_of_crystals_axl :
3416 number_of_crystals_axl ;
3418 vec_number_of_crystals_trs.push_back(
toString(nb_tot_trs_cry) );
3419 vec_number_of_crystals_axl.push_back(
toString(nb_tot_axl_cry) );
3424 if(layers_step_trs.size()>0 ||
3425 layers_step_axl.size()>0)
3427 if (layers_step_trs[l] - layers_size_trs[l] >= 0)
3428 crystal_gap_trs = layers_step_trs[l] - layers_size_trs[l];
3430 if (layers_step_axl[l] - layers_size_axl[l] >= 0)
3431 crystal_gap_axl = layers_step_axl[l] - layers_size_axl[l];
3434 vec_crystal_gap_trs.push_back(
toString(crystal_gap_trs) );
3435 vec_crystal_gap_axl.push_back(
toString(crystal_gap_axl) );
3438 vec_mean_depth_of_interaction.push_back(
toString(mean_depth_of_interaction) );
3439 vec_min_angle_diff.push_back(
toString(min_angle_diff) );
3445 layers_size_depth.push_back( crystal_size_depth );
3446 layers_size_trs.push_back( crystal_size_trs );
3447 layers_size_axl.push_back( crystal_size_axl );
3451 vec_scanner_radius.push_back(
toString(scanner_radius) );
3454 vec_number_of_rsectors_ang.push_back(
toString(number_of_rsectors_ang) );
3455 vec_number_of_rsectors_axl.push_back(
toString(number_of_rsectors_axl) );
3456 vec_rsector_gap_axl.push_back(
toString(rsector_gap_axl) );
3457 vec_rsector_first_angle.push_back(
toString(rsector_first_angle) );
3460 vec_number_of_modules_trs.push_back(
toString(number_of_modules_trs) );
3461 vec_number_of_modules_axl.push_back(
toString(number_of_modules_axl) );
3462 vec_module_gap_trs.push_back(
toString(module_gap_trs) );
3463 vec_module_gap_axl.push_back(
toString(module_gap_axl) );
3466 vec_number_of_submodules_trs.push_back(
toString(number_of_submodules_trs) );
3467 vec_number_of_submodules_axl.push_back(
toString(number_of_submodules_axl) );
3468 vec_submodule_gap_trs.push_back(
toString(submodule_gap_trs) );
3469 vec_submodule_gap_axl.push_back(
toString(submodule_gap_axl) );
3472 vec_number_of_crystals_trs.push_back(
toString(number_of_crystals_trs) );
3473 vec_number_of_crystals_axl.push_back(
toString(number_of_crystals_axl) );
3474 vec_crystal_gap_trs.push_back(
toString(crystal_gap_trs) );
3475 vec_crystal_gap_axl.push_back(
toString(crystal_gap_axl) );
3478 vec_mean_depth_of_interaction.push_back(
toString(mean_depth_of_interaction) );
3479 vec_min_angle_diff.push_back(
toString(min_angle_diff) );
3482 number_of_layers = 1;
3487 ofstream fileGeom(a_pathGeom.c_str(), ios::out | ios::trunc);
3490 fileGeom <<
"# comments" << endl;
3491 fileGeom <<
"# Y _________ "<< endl;
3492 fileGeom <<
"# | / _ \\ \\ "<< endl;
3493 fileGeom <<
"# | | / \\ | |"<< endl;
3494 fileGeom <<
"# |_____ Z | | | | |"<< endl;
3495 fileGeom <<
"# \\ | | | | |" << endl;
3496 fileGeom <<
"# \\ | \\_/ | |" << endl;
3497 fileGeom <<
"# X \\___/_____/" << endl;
3498 fileGeom <<
"# Left-handed axis orientation"<< endl;
3499 fileGeom <<
"# scanner axis is z" << endl;
3500 fileGeom <<
"# positions in millimeters"<< endl;
3501 fileGeom <<
"# Use comma without space as separator in the tables." << endl;
3503 fileGeom <<
""<< endl;
3506 fileGeom <<
"# MANDATORY FIELDS"<< endl;
3507 fileGeom <<
"modality : " << modality << endl;
3508 fileGeom <<
"scanner name : " << scanner_name << endl;
3509 fileGeom <<
"number of elements : " << number_of_elements << endl;
3510 fileGeom <<
"number of layers : " << number_of_layers << endl;
3511 fileGeom <<
"" << endl;
3512 fileGeom <<
"voxels number transaxial : " << voxels_number_trs << endl;
3513 fileGeom <<
"voxels number axial : " << voxels_number_axl << endl;
3515 fileGeom <<
"field of view transaxial : " << fov_trs << endl;
3516 fileGeom <<
"field of view axial : " << fov_axl << endl << endl;
3517 fileGeom <<
"description : " << description << endl;
3518 fileGeom <<
"" << endl;
3519 WriteVector(fileGeom,
"scanner radius : ",vec_scanner_radius);
3520 WriteVector(fileGeom,
"number of rsectors : ",vec_number_of_rsectors_ang);
3521 WriteVector(fileGeom,
"number of crystals transaxial : ",vec_number_of_crystals_trs);
3522 WriteVector(fileGeom,
"number of crystals axial : ",vec_number_of_crystals_axl);
3523 fileGeom <<
""<< endl;
3524 WriteVector(fileGeom,
"crystals size depth : ", layers_size_depth);
3525 WriteVector(fileGeom,
"crystals size transaxial : ", layers_size_trs);
3526 WriteVector(fileGeom,
"crystals size axial : ", layers_size_axl);
3527 fileGeom <<
""<< endl;
3528 fileGeom <<
""<< endl;
3531 fileGeom <<
"# OPTIONAL FIELDS"<< endl;
3532 WriteVector(fileGeom,
"rsectors first angle : ",vec_rsector_first_angle);
3533 WriteVector(fileGeom,
"number of rsectors axial : ",vec_number_of_rsectors_axl);
3534 WriteVector(fileGeom,
"rsector gap transaxial : ",vec_rsector_gap_trs);
3535 WriteVector(fileGeom,
"rsector gap axial : ",vec_rsector_gap_axl);
3536 WriteVector(fileGeom,
"number of modules transaxial : ",vec_number_of_modules_trs);
3537 WriteVector(fileGeom,
"number of modules axial : ",vec_number_of_modules_axl);
3538 WriteVector(fileGeom,
"module gap transaxial : ",vec_module_gap_trs);
3539 WriteVector(fileGeom,
"module gap axial : ",vec_module_gap_axl);
3540 WriteVector(fileGeom,
"number of submodules transaxial : ",vec_number_of_submodules_trs);
3541 WriteVector(fileGeom,
"number of submodules axial : ",vec_number_of_submodules_axl);
3542 WriteVector(fileGeom,
"submodule gap transaxial : ",vec_submodule_gap_trs);
3543 WriteVector(fileGeom,
"submodule gap axial : ",vec_submodule_gap_axl);
3544 WriteVector(fileGeom,
"crystal gap transaxial : ",vec_crystal_gap_trs);
3545 WriteVector(fileGeom,
"crystal gap axial : ",vec_crystal_gap_axl);
3546 WriteVector(fileGeom,
"mean depth of interaction : ", vec_mean_depth_of_interaction);
3547 fileGeom <<
"rotation direction : CCW " << endl;
3548 fileGeom <<
""<< endl;
3551 if(min_angle_diff > 0.) fileGeom <<
"min angle difference : " << min_angle_diff << endl;
3554 if(rsector_angular_span >= 360.0005 ||
3555 rsector_angular_span <= 359.9995 )
3557 rsector_angular_span *= (double)number_of_rsectors_ang/(
double)(number_of_rsectors_ang-1);
3558 fileGeom <<
"rsectors angular span : " << rsector_angular_span << endl;
3561 if(rsector_nb_zshifts > 0) fileGeom <<
"rsectors nbZShift :" << rsector_nb_zshifts << endl;
3562 if(!vec_rsector_Z_Shift.empty())
WriteVector(fileGeom,
"rsectors ZShift : ", vec_rsector_Z_Shift);
3566 cout <<
"Output geom file written at :" << a_pathGeom << endl;
3570 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Couldn't open geom file for writing "<< a_pathGeom <<
" !" << endl);
3598 string scanner_name =
GetFileFromPath(a_pathGeom.substr(0,a_pathGeom.find_first_of(
".geom")));
3599 double scanner_radius = 0.;
3600 uint32_t number_of_elements = 0;
3601 string description =
"ECAT system extracted from GATE macro: " + a_pathMac;
3604 string block_name =
"block";
3605 uint32_t number_of_blocks = 1;
3606 uint32_t number_of_blocks_trs = 1;
3607 uint32_t number_of_blocks_axl = 1;
3608 double block_step_trs = 0.;
3609 double block_step_axl = 0.;
3610 double block_gap_trs = 0.;
3611 double block_gap_axl = 0.;
3612 double block_size_Y;
3613 double block_size_Z;
3614 double block_pos_X = 0.;
3615 double block_pos_Y = 0.;
3616 double block_first_angle = 0.;
3617 double block_angular_span = 360.;
3618 uint32_t block_nb_zshifts = 0;
3619 vector <double> vec_block_Z_Shift;
3620 bool is_block_Y_axis =
false;
3625 string crystal_name =
"crystal";
3626 uint32_t number_of_crystals_trs = 1;
3627 uint32_t number_of_crystals_axl = 1;
3628 double crystal_step_trs = 0.;
3629 double crystal_step_axl = 0.;
3630 double crystal_gap_trs = 0.;
3631 double crystal_gap_axl = 0.;
3632 double crystal_size_depth = 0.;
3633 double crystal_size_trs = 0.;
3634 double crystal_size_axl = 0.;
3637 uint32_t voxels_number_trs;
3638 uint32_t voxels_number_axl;
3641 double min_angle_diff = 0.;
3643 vector<string> path_mac_files;
3644 path_mac_files.push_back(a_pathMac);
3649 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Error occured when trying to recover paths to GATE macro files !" << endl);
3657 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Error occured when trying to recover aliases for the elements of the ecat !" << endl);
3663 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
3665 ifstream systemMac(path_mac_files[f].c_str(), ios::in);
3668 while(getline(systemMac, line))
3672 vector <string> values;
3676 entry =
"/gate/"+block_name+
"/placement/setTranslation";
3678 if (values.size()>0)
3683 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3689 if(block_pos_X!=0 && block_pos_Y !=0)
3691 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3692 Cerr(
" Block cartesian coordinates on either the X or Y axis expected to be equal to 0 "<< endl);
3697 if(block_pos_Y!=0) is_block_Y_axis =
true;
3699 scanner_radius += is_block_Y_axis ? abs(block_pos_Y) : abs(block_pos_X) ;
3704 entry = is_block_Y_axis ?
3705 "/gate/"+block_name+
"/geometry/setYLength" :
3706 "/gate/"+block_name+
"/geometry/setXLength";
3709 if (values.size()>0)
3711 double block_size = 0.;
3714 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3718 scanner_radius -= block_size/2;
3723 entry =
"/gate/"+block_name+
"/geometry/setZLength";
3725 if (values.size()>0)
3729 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3733 voxels_number_axl = fov_axl/4 + 1;
3738 entry =
"/gate/"+block_name+
"/ring/setRepeatNumber";
3740 if (values.size()>0)
3744 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3750 entry =
"/gate/"+block_name+
"/ring/setFirstAngle";
3752 if (values.size()>0)
3756 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3762 entry =
"/gate/"+block_name+
"/ring/setAngularSpan";
3764 if (values.size()>0)
3768 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3773 entry =
"/gate/"+block_name+
"/ring/setModuloNumber";
3775 if (values.size()>0)
3779 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
3784 for (
int i=1; i<8; i++)
3786 entry =
"/gate/"+block_name+
"/ring/setZShift"+
toString(i);
3788 if (values.size()>0)
3793 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3796 vec_block_Z_Shift.push_back(zshift);
3804 entry =
"/gate/"+block_name+
"/linear/setRepeatNumber";
3806 if (values.size()>0)
3810 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3816 entry =
"/gate/"+block_name+
"/linear/setRepeatVector";
3818 if (values.size()>0)
3822 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3832 entry = is_block_Y_axis ?
3833 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberX":
3834 "/gate/"+crystal_name+
"/cubicArray/setRepeatNumberY";
3837 if (values.size()>0)
3841 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3846 entry =
"/gate/"+crystal_name+
"/cubicArray/setRepeatNumberZ";
3848 if (values.size()>0)
3852 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3858 entry =
"/gate/"+crystal_name+
"/cubicArray/setRepeatVector";
3860 if (values.size()>0)
3862 string trs_step = is_block_Y_axis ?
3869 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3876 entry =
"/gate/"+crystal_name+
"/geometry/setXLength";
3878 if (values.size()>0)
3883 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3887 if (is_block_Y_axis)
3888 crystal_size_trs = x_length;
3890 crystal_size_depth = x_length;
3895 entry =
"/gate/"+crystal_name+
"/geometry/setYLength";
3897 if (values.size()>0)
3902 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3906 if (is_block_Y_axis)
3907 crystal_size_depth = y_length;
3909 crystal_size_trs = y_length;
3912 entry =
"/gate/"+crystal_name+
"/geometry/setZLength";
3914 if (values.size()>0)
3918 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3926 entry =
"/gate/digitizer/Coincidences/minSectorDifference";
3928 if (values.size()>0)
3930 double min_sector_diff;
3933 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Conversion error occured while trying to parse line: " << line<< endl);
3936 min_angle_diff = 360/number_of_blocks*min_sector_diff;
3943 number_of_elements = number_of_blocks *
3944 number_of_blocks_axl *
3945 number_of_crystals_trs *
3946 number_of_crystals_axl;
3951 fov_trs = (2*scanner_radius ) / 1.5;
3954 voxels_number_trs = ( number_of_crystals_trs
3955 * number_of_blocks_trs)
3959 if (crystal_step_axl - crystal_size_axl >= 0)
3960 crystal_gap_axl = crystal_step_axl - crystal_size_axl;
3962 if (crystal_step_trs - crystal_size_trs >= 0)
3963 crystal_gap_trs = crystal_step_trs - crystal_size_trs;
3967 block_size_Z = crystal_size_axl*number_of_crystals_axl + crystal_gap_axl*(number_of_crystals_axl-1);
3968 block_size_Y = crystal_size_trs*number_of_crystals_trs + crystal_gap_trs*(number_of_crystals_trs-1);
3971 if (block_step_axl - block_size_Z >= 0)
3972 block_gap_axl = block_step_axl - block_size_Z;
3974 if (block_step_trs - block_size_Y >= 0)
3975 block_gap_trs = block_step_trs - block_size_Y;
3978 block_first_angle -= round(atan2f(block_pos_X , block_pos_Y) * 180. / M_PI);
3982 ofstream fileGeom(a_pathGeom.c_str(), ios::out | ios::trunc);
3986 fileGeom <<
"# comments" << endl;
3987 fileGeom <<
"# Y _________ "<< endl;
3988 fileGeom <<
"# | / _ \\ \\ "<< endl;
3989 fileGeom <<
"# | | / \\ | |"<< endl;
3990 fileGeom <<
"# |_____ Z | | | | |"<< endl;
3991 fileGeom <<
"# \\ | | | | |" << endl;
3992 fileGeom <<
"# \\ | \\_/ | |" << endl;
3993 fileGeom <<
"# X \\___/_____/" << endl;
3994 fileGeom <<
"# Left-handed axis orientation"<< endl;
3995 fileGeom <<
"# scanner axis is z" << endl;
3996 fileGeom <<
"# positions in millimeters"<< endl;
3997 fileGeom <<
"# Use comma without space as separator in the tables." << endl;
4000 fileGeom <<
"modality : " << modality << endl;
4001 fileGeom <<
"scanner name : " << scanner_name << endl;
4002 fileGeom <<
"number of elements : " << number_of_elements << endl;
4003 fileGeom <<
"number of layers : " <<
"1" << endl;
4004 fileGeom <<
"" << endl;
4005 fileGeom <<
"# default reconstruction parameters" << endl;
4006 fileGeom <<
"voxels number transaxial : " << voxels_number_trs << endl;
4007 fileGeom <<
"voxels number axial : " << voxels_number_axl << endl;
4009 fileGeom <<
"field of view transaxial : " << fov_trs << endl;
4010 fileGeom <<
"field of view axial : " << fov_axl << endl;
4011 fileGeom <<
"" << endl;
4012 fileGeom <<
"description : " << description << endl;
4013 fileGeom <<
"" << endl;
4014 fileGeom <<
"scanner radius : " << scanner_radius << endl;
4015 fileGeom <<
"number of rsectors : " << number_of_blocks << endl;
4016 fileGeom <<
"number of crystals transaxial : " << number_of_crystals_trs << endl;
4017 fileGeom <<
"number of crystals axial : " << number_of_crystals_axl << endl;
4019 fileGeom <<
""<< endl;
4020 fileGeom <<
"# The 4 following parameters could be defined in arrays (SizeLayer1,SizeLayer2,SizeLayer3,etc..) if their is more than one layer"<< endl;
4021 fileGeom <<
"crystals size depth : " << crystal_size_depth << endl;
4022 fileGeom <<
"crystals size transaxial : " << crystal_size_trs << endl;
4023 fileGeom <<
"crystals size axial : " << crystal_size_axl << endl;
4024 fileGeom <<
""<< endl;
4027 fileGeom <<
"rsectors first angle : " << block_first_angle << endl;
4028 fileGeom <<
"number of modules transaxial : " << number_of_blocks_trs << endl;
4029 fileGeom <<
"number of modules axial : " << number_of_blocks_axl << endl;
4030 fileGeom <<
"module gap transaxial : " << block_gap_trs << endl;
4031 fileGeom <<
"module gap axial : " << block_gap_axl << endl;
4032 fileGeom <<
"crystal gap transaxial : " << crystal_gap_trs << endl;
4033 fileGeom <<
"crystal gap axial : " << crystal_gap_axl << endl;
4034 fileGeom <<
"rotation direction : CCW " << endl;
4035 fileGeom <<
""<< endl;
4038 if(min_angle_diff > 0.) fileGeom <<
"min angle difference : " << min_angle_diff << endl;
4041 if(block_angular_span >= 360.0005 ||
4042 block_angular_span <= 359.9995 )
4044 block_angular_span *= (double)(number_of_blocks)/(double)(number_of_blocks-1);
4045 fileGeom <<
"rsectors angular span : " << block_angular_span << endl;
4048 if(block_nb_zshifts > 0) fileGeom <<
"rsectors nbZShift :" << block_nb_zshifts << endl;
4049 if(!vec_block_Z_Shift.empty())
WriteVector(fileGeom,
"rsectors ZShift : ", vec_block_Z_Shift);
4053 Cout(
"Output geom file written at :" << a_pathGeom << endl);
4057 Cerr(
"***** dataConversionUtilities::CreateGeomWithECAT()-> Couldn't open geom file for writing "<< a_pathGeom <<
" !" << endl);
4082 string scanner_name =
GetFileFromPath(a_pathGeom.substr(0,a_pathGeom.find_first_of(
".geom")));
4083 FLTNB scanner_radius = -1.;
4084 string description =
"SPECT camera extracted from GATE macro: " + a_pathMac;
4087 string head_name =
"SPECThead";
4088 uint32_t number_of_heads = 0;
4089 FLTNB head_pos_X = 0.;
4090 FLTNB head_pos_Y = 0.;
4091 FLTNB head_first_angle = 0.;
4092 FLTNB head_angular_pitch = -1.;
4093 string head_orbit_name =
"";
4094 FLTNB head_rotation_speed = 0.;
4095 bool is_head_Y_axis =
false;
4098 string crystal_name =
"crystal";
4099 FLTNB crystal_size_trs = 0.;
4100 FLTNB crystal_size_axl = 0.;
4101 FLTNB crystal_depth = 0;
4104 string pixel_name =
"pixel";
4105 uint32_t number_of_pixels_trs = 1;
4106 uint32_t number_of_pixels_axl = 1;
4107 FLTNB pix_size_trs = 0.;
4108 FLTNB pix_size_axl = 0.;
4109 FLTNB pix_step_trs = 0.;
4110 FLTNB pix_step_axl = 0.;
4111 FLTNB pix_gap_trs = 0.;
4112 FLTNB pix_gap_axl = 0.;
4115 string focal_model_trs =
"constant";
4116 uint16_t nb_coeff_model_trs = 1;
4117 FLTNB coeff_model_trs = 0.;
4118 string focal_model_axl =
"constant";
4119 uint16_t nb_coeff_model_axl = 1;
4120 FLTNB coeff_model_axl = 0.;
4123 uint32_t voxels_number_trs;
4124 uint32_t voxels_number_axl;
4128 vector<string> path_mac_files;
4129 path_mac_files.push_back(a_pathMac);
4134 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Error occured when trying to recover paths to GATE macro files !" << endl);
4142 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Error occured when trying to recover aliases for the elements of the SPECThead !" << endl);
4147 for(uint16_t f=0 ; f<path_mac_files.size() ; f++)
4149 ifstream systemMac(path_mac_files[f].c_str(), ios::in);
4152 while(getline(systemMac, line))
4155 modality =
"SPECT_CONVERGENT";
4156 vector <string> values;
4160 entry =
"/gate/"+head_name+
"/placement/setTranslation";
4162 if (values.size()>0)
4167 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4173 if(head_pos_X!=0 && head_pos_Y !=0)
4175 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4176 Cerr(
" Block cartesian coordinates on either the X or Y axis expected to be equal to 0 "<< endl);
4181 if(head_pos_Y!=0) is_head_Y_axis =
true;
4183 scanner_radius = is_head_Y_axis ? abs(head_pos_Y) : abs(head_pos_X) ;
4187 entry =
"/gate/"+head_name+
"/geometry/setZLength";
4189 if (values.size()>0)
4193 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4197 voxels_number_axl = fov_axl/4 + 1;
4201 entry =
"/gate/"+head_name+
"/ring/setRepeatNumber";
4203 if (values.size()>0)
4207 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4213 entry =
"/gate/"+head_name+
"/ring/setFirstAngle";
4215 if (values.size()>0)
4219 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4225 entry =
"/gate/"+head_name+
"/ring/setAngularPitch";
4227 if (values.size()>0)
4231 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4236 entry =
"/gate/"+head_name+
"/moves/insert";
4238 if (values.size()>0)
4242 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4247 entry =
"/gate/"+head_orbit_name+
"/setSpeed";
4249 if (values.size()>0)
4253 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Conversion error occured while trying to parse line: " << line<< endl);
4261 entry =
"/gate/"+crystal_name+
"/geometry/setXLength";
4263 if (values.size()>0)
4268 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4273 crystal_size_trs = x_length;
4275 crystal_depth = x_length;
4278 entry =
"/gate/"+crystal_name+
"/geometry/setYLength";
4280 if (values.size()>0)
4285 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4290 crystal_depth = y_length;
4292 crystal_size_trs = y_length;
4296 entry =
"/gate/"+crystal_name+
"/geometry/setZLength";
4298 if (values.size()>0)
4302 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4312 entry = is_head_Y_axis ?
4313 "/gate/"+pixel_name+
"/cubicArray/setRepeatNumberX":
4314 "/gate/"+pixel_name+
"/cubicArray/setRepeatNumberY";
4318 if (values.size()>0)
4322 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4327 entry =
"/gate/"+pixel_name+
"/cubicArray/setRepeatNumberZ";
4329 if (values.size()>0)
4333 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4339 entry =
"/gate/"+pixel_name+
"/geometry/setXLength";
4341 if (values.size()>0)
4346 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4351 pix_size_trs = x_length;
4354 entry =
"/gate/"+pixel_name+
"/geometry/setYLength";
4356 if (values.size()>0)
4361 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4365 if (!is_head_Y_axis)
4366 pix_size_trs = y_length;
4370 entry =
"/gate/"+pixel_name+
"/geometry/setZLength";
4372 if (values.size()>0)
4376 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4382 entry =
"/gate/"+pixel_name+
"/cubicArray/setRepeatVector";
4384 if (values.size()>0)
4386 string trs_step = is_head_Y_axis ?
4393 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4400 entry = is_head_Y_axis ?
4401 "/gate/fanbeam/geometry/setFocalDistanceY":
4402 "/gate/fanbeam/geometry/setFocalDistanceX";
4404 entry =
"/gate/fanbeam/geometry/setFocalDistanceX";
4406 if (values.size()>0)
4410 Cerr(
"***** dataConversionUtilities::CreateGeomWithCylindrical()-> Conversion error occured while trying to parse line: " << line<< endl);
4414 focal_model_trs =
"polynomial";
4422 fov_trs = scanner_radius/2;
4424 voxels_number_trs = fov_trs/2 + 1;
4426 uint32_t nb_pixels = number_of_pixels_axl * number_of_pixels_trs;
4428 pix_size_axl = nb_pixels>1 ? pix_size_axl : crystal_size_axl;
4429 pix_size_trs = nb_pixels>1 ? pix_size_trs : crystal_size_trs;
4432 if (pix_step_axl - pix_size_axl >= 0)
4433 pix_gap_axl = pix_step_axl - pix_size_axl;
4435 if (pix_step_trs - pix_size_trs >= 0)
4436 pix_gap_trs = pix_step_trs - pix_size_trs;
4440 head_first_angle = round(atan2f(head_pos_X , head_pos_Y) * 180. / M_PI)
4445 ofstream fileGeom(a_pathGeom.c_str(), ios::out | ios::trunc);
4449 fileGeom <<
"modality : " << modality << endl;
4450 fileGeom <<
"scanner name : " << scanner_name << endl;
4451 fileGeom <<
"number of detector heads : " << number_of_heads << endl;
4452 fileGeom <<
"trans number of pixels : " << number_of_pixels_trs << endl;
4453 fileGeom <<
"trans pixel size : " << pix_size_trs << endl;
4454 fileGeom <<
"trans gap size : " << pix_gap_trs << endl;
4455 fileGeom <<
"axial number of pixels : " << number_of_pixels_axl << endl;
4456 fileGeom <<
"axial pixel size : " << pix_size_axl << endl;
4457 fileGeom <<
"axial gap size : " << pix_gap_axl << endl;
4459 fileGeom <<
"detector depth : " << crystal_depth << endl;
4461 fileGeom <<
"scanner radius : " << scanner_radius;
4462 for(
size_t h=1 ; h<number_of_heads ; h++)
4463 fileGeom <<
"," << scanner_radius;
4466 fileGeom <<
"# Collimator configuration : "<< endl << endl;
4467 for(
size_t h=0 ; h<number_of_heads ; h++)
4469 fileGeom <<
"head" << h+1 <<
":" << endl;
4470 fileGeom <<
"trans focal model: " << focal_model_trs << endl;
4471 fileGeom <<
"trans number of coef model: " << nb_coeff_model_trs << endl;
4472 fileGeom <<
"trans parameters: " << coeff_model_trs << endl;
4473 fileGeom <<
"axial focal model: " << focal_model_axl << endl;
4474 fileGeom <<
"axial number of coef model: " << nb_coeff_model_axl << endl;
4475 fileGeom <<
"axial parameters: " << coeff_model_axl << endl;
4479 fileGeom <<
"" << endl;
4480 fileGeom <<
"# default reconstruction parameters" << endl;
4481 fileGeom <<
"voxels number transaxial : " << voxels_number_trs << endl;
4482 fileGeom <<
"voxels number axial : " << voxels_number_axl << endl;
4484 fileGeom <<
"field of view transaxial : " << fov_trs << endl;
4485 fileGeom <<
"field of view axial : " << fov_axl << endl << endl ;
4486 fileGeom <<
""<< endl;
4488 fileGeom <<
"# description" << endl;
4489 fileGeom <<
"description : " << description << endl;
4493 Cout(
"Output geom file written at :" << a_pathGeom << endl);
4497 Cerr(
"***** dataConversionUtilities::CreateGeomWithSPECT()-> Couldn't open geom file for writing "<< a_pathGeom <<
" !" << endl);
int ReadMacECAT(string a_pathMac, uint32_t &nCrystalsTot, uint32_t &nCrystalsAxial, uint32_t &nCrystalsTransaxial, uint32_t &nBlocksLine, uint32_t &nBlocksPerRing, uint32_t &start_time_ms, uint32_t &duration_ms, int vb)
Recover informations about the scanner element of an ECAT system and acquisition duration, from a GATE macro file.
This header file is mainly used to declare some macro definitions and all includes needed from the st...
uint32_t ConvertIDecat(int32_t nBlocksPerRing, int32_t nBlocksLine, int32_t nCrystalsTransaxial, int32_t nCrystalsAxial, int32_t crystalID, int32_t blockID)
Compute a CASToR crystal index of a GATE ecat system from its indexes (block/crystal) and the system ...
This file gathers various function dedicated to data conversion in order to convert various type of G...
int IntfKeyGetRecurringValueFromFile(const string &a_pathToHeader, const string &a_key, T *ap_return, int a_nbElts, int a_mandatoryFlag, uint16_t a_nbOccurrences)
vector< string > CheckGATECommand(const string &a_key, const string &a_line)
Check if the line contains the provided GATE command. In this case, parse the line and returns the va...
int GetGATEAliasesCylindrical(vector< string > path_mac_files, string &rsector_name, string &module_name, string &submodule_name, string &crystal_name, vector< string > &layers_name, int vb)
Loop over a list of path to GATE macro files passed in parameter to recover aliases of the different ...
int IntfKeyGetValueFromFile(const string &a_pathToHeader, const string &a_key, T *ap_return, int a_nbElts, int a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_pathToHeader" interfile header matching the "a_keyword" key passed...
string GetFileFromPath(const string &a_pathToFile)
Simply return the file from a path string passed in parameter.
int ConvertFromString(const string &a_str, string *a_result)
Copy the 'a_str' string in the position pointed by 'a_result'.
int GetGATEMacFiles(const string &a_pathMac, vector< string > &ap_pathToMacFiles)
Extract the paths to each macro file contained in the main macro file.
int CreateGeomWithSPECT(string a_pathMac, string a_pathGeom)
Read a GATE macro file containing the description of a SPECThead system, and convert it to a geom fil...
int ReadIntfSPECT(string a_pathIntf, float_t &a_distToDetector, uint32_t &a_nHeads, uint32_t &a_nPixAxl, uint32_t &a_nPixTrs, float_t &a_crystalSizeAxl, float_t &a_crystalSizeTrs, uint32_t &a_nProjectionsTot, uint32_t &a_nProjectionsByHead, float_t &a_head1stAngle, float_t &a_headAngPitchDeg, float_t &a_headAngStepDeg, int &a_headRotDirection, uint32_t &a_start_time_ms, uint32_t &a_duration_ms, int vb)
Recover informations about the scanner element of an ECAT system, and acquisition duration...
void ConvertValuesTomm(vector< string > &ap_v)
Check if the vector of strings passed in parameter contains the 'cm' unit In this case...
uint32_t ConvertIDcylindrical(uint32_t nRsectorsAngPos, uint32_t nRsectorsAxial, int a_rsectorIdOrder, uint32_t nModulesTransaxial, uint32_t nModulesAxial, uint32_t nSubmodulesTransaxial, uint32_t nSubmodulesAxial, uint32_t nCrystalsTransaxial, uint32_t nCrystalsAxial, uint8_t nLayers, uint32_t *nCrystalPerLayer, vector< uint32_t > nLayersRptTransaxial, vector< uint32_t > nLayersRptAxial, int32_t layerID, int32_t crystalID, int32_t submoduleID, int32_t moduleID, int32_t rsectorID)
Compute a CASToR crystal index of a GATE cylindricalPET system from its indexes (rsector/module/submo...
int ReadMacCylindrical(string a_pathMac, uint8_t &nLayers, uint32_t *nb_crystal_per_layer, uint32_t &nCrystalsTot, uint32_t &nCrystalsAxial, uint32_t &nCrystalsTransaxial, vector< uint32_t > &nLayersRptAxial, vector< uint32_t > &nLayersRptTransaxial, uint32_t &nSubmodulesAxial, uint32_t &nSubmodulesTransaxial, uint32_t &nModulesAxial, uint32_t &nModulesTransaxial, uint32_t &nRsectorsAxial, uint32_t &nRsectorsAngPos, int &rsector_id_order, uint32_t &start_time_ms, uint32_t &duration_ms, int vb)
Recover informations about the scanner element of a cylindricalPET system and acquisition duration...
int ReadMacSPECT(string a_pathMac, float_t &a_distToDetector, uint32_t &a_nHeads, uint32_t &a_nPixAxl, uint32_t &a_nPixTrs, float_t &a_crystalSizeAxl, float_t &a_crystalSizeTrs, uint32_t &a_nProjectionsTot, uint32_t &a_nProjectionsByHead, float_t &a_head1stAngle, float_t &a_headAngPitch, float_t &a_headAngStepDeg, int &a_headRotDirection, uint32_t &a_start_time_ms, uint32_t &a_duration_ms, int vb)
Recover informations about the scanner element of an ECAT system, and acquisition duration...
int ComputeKindGATEEvent(uint32_t eventID1, uint32_t eventID2, int comptonPhantom1, int comptonPhantom2, int rayleighPhantom1, int rayleighPhantom2)
Determine kind of a given coincidence event, from its attributes.
#define KEYWORD_MANDATORY
#define GATE_SYS_CYLINDRICAL
int GetGATEAliasesEcat(vector< string > path_mac_files, string &block_name, string &crystal_name, int vb)
Loop over a list of path to GATE macro files passed in parameter to recover aliases of the different ...
uint32_t ConvertIDSPECTRoot2(uint32_t a_nbSimulatedPixels, uint32_t a_nPixTrs, uint32_t a_nPixAxl, int32_t a_headID, int32_t a_crystalID, int32_t a_pixelID, float_t a_rotAngle, float_t a_headAngPitch, float_t a_crystalSizeAxl, float_t a_crystalSizeTrs, float_t a_gPosX, float_t a_gPosY, float_t a_gPosZ)
Compute a CASToR crystal index of a GATE SPECThead system.
string toString(T a_val)
Convert a value of any type into string.
string GetPathOfFile(const string &a_pathToFile)
Simply return the path to the directory of a file path string passed in parameter.
int CreateGeomWithCylindrical(string a_pathMac, string a_pathGeom)
Read a GATE macro file containing the description of a cylindricalPET system, and convert it to a geo...
uint32_t ConvertIDSPECTRoot1(int32_t a_headID, float_t a_rotAngle, float_t a_angStep, uint32_t a_nProjectionsByHead)
Compute a CASToR projection index of a GATE SPECThead system.
#define GATE_NB_MAX_LAYERS
int CreateGeomWithECAT(string a_pathMac, string a_pathGeom)
Read a GATE macro file containing the description of an ecat system, and convert it to a geom file...
vector< string > Split(string a_line)
Split the line provided in parameter into a vector of strings (separator is blankspace) ...
int WriteVector(ofstream &file, const string &a_key, vector< T > a_vals)
Write the key and its values in the file provided in parameter.
int GetGATESystemType(const string &a_pathMac)
Read a GATE macro file and identify the system type from the 'gate/systems/' command lines...
int GetGATEAliasesSPECT(vector< string > path_mac_files, string &base_name, string &crystal_name, string &pixel_name, int vb)
Loop over a list of path to GATE macro files passed in parameter to recover aliases of the different ...