33 #include "dcmtk/dcmdata/dcdeftag.h"
50 DicomFileMgr::DicomFileMgr()
54 theStructureNCheck = 4;
55 theStructureNMaxROI = 100;
62 std::vector<G4String> wl;
64 theFileOutName =
"test.g4dcm";
68 if( wl[0] ==
":COMPRESSION" ) {
71 }
else if( wl[0] ==
":FILE" ) {
75 }
else if( wl[0] ==
":FILE_OUT" ) {
77 theFileOutName = wl[1];
78 }
else if( wl[0] ==
":MATE_DENS" ) {
81 }
else if( wl[0] ==
":MATE" ) {
84 }
else if( wl[0] ==
":CT2D" ) {
91 G4String(
"UNKNOWN TAG IN FILE "+wl[0]).c_str());
105 if( wl.size() != vsizeTh ) {
107 for(
size_t ii = 0; ii < wl.size(); ii++){
114 (
"Wrong number of columns in line " + std::to_string(wl.size()) +
" <> "
115 + std::to_string(vsizeTh)).c_str());
131 if( ! (dfile.loadFile(fileName.c_str())).good() ) {
135 (
"Error reading file " + fileName).c_str());
137 DcmDataset* dset = dfile.getDataset();
140 if( !dset->findAndGetOFString(DCM_Modality,dModality).good() ) {
144 " Have not read Modality");
147 if( dModality ==
"CT" ) {
152 theCTFiles[df->
GetMaxZ()] = df;
153 }
else if( dModality ==
"RTSTRUCT" ) {
158 theStructFiles.push_back(df);
159 }
else if( dModality ==
"RTPLAN" ) {
164 thePlanFiles.push_back(df);
165 }
else if( dModality ==
"PT" ) {
170 thePETFiles[df->
GetMaxZ()] = df;
176 (
G4String(
"File is not of type CT or RTSTRUCT or RTPLAN, but: ")
177 + dModality).c_str());
189 "Trying to add a Material with :MATE and another with :MATE_DENS, check your input file");
202 "Trying to add a Material with :MATE and another with :MATE_DENS, check your input file");
212 G4cout <<
this <<
" AddCT2density " << theCT2Density.size() <<
G4endl;
219 if( theCT2Density.size() == 0 ) {
223 "No :CT2D line in input file");
225 std::map<G4int,G4double>::const_iterator ite = theCT2Density.begin();
226 G4int minHval = (*ite).first;
227 if(
G4int(Hval) < minHval ) {
231 (
"Hval value too small, change input file "+std::to_string(Hval) +
" < "
232 + std::to_string(minHval)).c_str());
235 ite = theCT2Density.end(); ite--;
236 G4int maxHval = (*ite).first;
237 if(
G4int(Hval) > maxHval ) {
241 (
"Hval value too big, change CT2Density.dat file "+std::to_string(Hval) +
" > "
242 + std::to_string(maxHval)).c_str());
249 ite = theCT2Density.upper_bound(Hval);
250 std::map<G4int,G4double>::const_iterator itePrev = ite; itePrev--;
252 deltaCT = (*ite).first - (*itePrev).first;
253 deltaDensity = (*ite).second - (*itePrev).second;
256 density = (*ite).second - (((*ite).first-Hval)*deltaDensity/deltaCT );
262 G4String(
"@@@ Error negative density = " + std::to_string(density) +
" from HV = "
263 + std::to_string(Hval)).c_str());
274 std::map<G4double,G4String>::iterator ite = theMaterials.upper_bound(Hval);
275 if( ite == theMaterials.end() ) {
280 (
"Hounsfiled value too big, change input file "+std::to_string(Hval) +
" > "
281 + std::to_string((*ite).first)).c_str());
284 size_t dist = std::distance( theMaterials.begin(), ite );
294 std::map<G4double,G4String>::iterator ite = theMaterialsDensity.upper_bound(density);
295 if( ite == theMaterialsDensity.end() ) {
297 G4Exception(
"DicomFileMgr::GetMaterialIndexByDensity",
300 (
"Density too big, change input file "+std::to_string(density) +
" > "
301 + std::to_string((*ite).first)).c_str());
304 size_t dist = std::distance( theMaterialsDensity.begin(), ite );
313 if( theCTFiles.size() == 0 ) {
317 "No :FILE of type CT in input file");
328 G4cout <<
" PROCESSING PET FILES " << thePETFiles.size() <<
G4endl;
329 if( thePETFiles.size() != 0 ) {
346 size_t nSlices = theCTFiles.size();
347 G4cout <<
" DicomFileMgr::Checking CT slices: " << nSlices <<
G4endl;
349 G4bool uniformSliceThickness =
true;
353 mdct::const_iterator ite = theCTFiles.begin();
365 if(uniformSliceThickness) {
371 mdct::iterator ite0 = theCTFiles.begin();
372 mdct::iterator ite1 = ite0; ite1++;
373 mdct::iterator ite2 = ite1; ite2++;
374 for(; ite2 != theCTFiles.end(); ++ite0, ++ite1, ++ite2) {
382 G4double real_distance = real_up_distance + real_down_distance;
385 if(std::fabs(real_distance - stated_distance) > 1.E-9) {
386 unsigned int sliceNum = std::distance(theCTFiles.begin(),ite1);
387 G4cerr <<
"\tDicomFileMgr::CheckCTSlices - Slice Distance Error in slice [" << sliceNum
388 <<
"]: Distance between this slice and slices up and down = "
390 <<
" <> Slice width = " << stated_distance
393 <<
" DIFFERENCE= " << real_distance - stated_distance
395 G4cerr <<
"!! WARNING: Geant4 will reset slice width so that it extends between "
396 <<
"lower and upper slice " <<
G4endl;
401 if(ite0 == theCTFiles.begin()) {
405 if(uniformSliceThickness) {
409 if(static_cast<unsigned int>(std::distance(theCTFiles.begin(),ite2)+1)==
414 if(uniformSliceThickness) {
427 size_t nSlices = thePETFiles.size();
428 G4cout <<
" DicomFileMgr::Checking PET slices: " << nSlices <<
G4endl;
430 G4bool uniformSliceThickness =
true;
434 mdpet::const_iterator ite = thePETFiles.begin();
446 if(uniformSliceThickness) {
452 mdpet::iterator ite0 = thePETFiles.begin();
453 mdpet::iterator ite1 = ite0; ite1++;
454 mdpet::iterator ite2 = ite1; ite2++;
455 for(; ite2 != thePETFiles.end(); ++ite0, ++ite1, ++ite2) {
463 G4double real_distance = real_up_distance + real_down_distance;
466 if(std::fabs(real_distance - stated_distance) > 1.E-9) {
467 unsigned int sliceNum = std::distance(thePETFiles.begin(),ite1);
468 G4cerr <<
"\tDicomFileMgr::CheckPETSlices - Slice Distance Error in slice [" << sliceNum
469 <<
"]: Distance between this slice and slices up and down = "
471 <<
" <> Slice width = " << stated_distance
474 <<
" DIFFERENCE= " << real_distance - stated_distance
476 G4cerr <<
"!! WARNING: Geant4 will reset slice width so that it extends between "
477 <<
"lower and upper slice " <<
G4endl;
482 if(ite0 == thePETFiles.begin()) {
486 if(uniformSliceThickness) {
490 if(static_cast<unsigned int>(std::distance(thePETFiles.begin(),ite2)+1)==
495 if(uniformSliceThickness) {
509 G4cout <<
" DicomFileMgr::Building Materials " << theCTFiles.size() <<
G4endl;
510 mdct::const_iterator ite = theCTFiles.begin();
511 for( ; ite != theCTFiles.end(); ite++ ) {
512 (*ite).second->BuildMaterials();
519 G4cout <<
" DicomFileMgr::Building PETData " << thePETFiles.size() <<
G4endl;
520 mdpet::const_iterator ite = thePETFiles.begin();
521 for( ; ite != thePETFiles.end(); ite++ ) {
522 (*ite).second->BuildActivities();
529 G4cout <<
" DicomFileMgr::Merging CT Files " << theCTFiles.size() <<
G4endl;
530 mdct::const_iterator ite = theCTFiles.begin();
531 theCTFileAll =
new DicomFileCT( *((*ite).second) );
533 for( ; ite != theCTFiles.end(); ite++ ) {
534 (*theCTFileAll) += *((*ite).second);
542 G4cout <<
" DicomFileMgr::Merging PET Files " << thePETFiles.size() <<
G4endl;
543 mdpet::const_iterator ite = thePETFiles.begin();
546 for( ; ite != thePETFiles.end(); ite++ ) {
547 (*thePETFileAll) += *((*ite).second);
555 G4cout <<
" DicomFileMgr::Dumping To Text File " <<
G4endl;
556 if( theCTFiles.size() != 0 ) {
557 std::ofstream fout(theFileOutName);
560 fout << theMaterials.size() << std::endl;
561 std::map<G4double,G4String>::const_iterator ite;
563 for(ite = theMaterials.begin(); ite != theMaterials.end(); ite++, ii++){
564 fout << ii <<
" \"" << (*ite).second <<
"\"" << std::endl;
567 fout << theMaterialsDensity.size() << std::endl;
568 std::map<G4double,G4String>::const_iterator ite;
570 for(ite = theMaterialsDensity.begin(); ite != theMaterialsDensity.end(); ite++, ii++){
571 fout << ii <<
" \"" << (*ite).second <<
"\"" << std::endl;
576 for( mdct::const_iterator itect = theCTFiles.begin(); itect != theCTFiles.end(); itect++ ) {
577 (*itect).second->DumpMateIDsToTextFile(fout);
579 for( mdct::const_iterator itect = theCTFiles.begin(); itect != theCTFiles.end(); itect++ ) {
580 (*itect).second->DumpDensitiesToTextFile(fout);
582 for( mdct::const_iterator itect = theCTFiles.begin(); itect != theCTFiles.end(); itect++ ) {
583 (*itect).second->BuildStructureIDs();
584 (*itect).second->DumpStructureIDsToTextFile(fout);
588 for(
size_t i1 = 0; i1 < dfs.size(); i1++ ){
589 std::vector<DicomROI*> rois = dfs[i1]->GetROIs();
590 for(
size_t i2 = 0; i2 < rois.size(); i2++ ){
591 fout << rois[i2]->GetNumber()+1 <<
" \"" << rois[i2]->GetName() <<
"\"" <<
G4endl;
596 if( thePETFiles.size() != 0 ) {
597 std::ofstream fout(theFileOutName);
600 for( mdpet::const_iterator itect = thePETFiles.begin(); itect != thePETFiles.end(); itect++ ) {
601 (*itect).second->DumpActivitiesToTextFile(fout);
605 for(
size_t i1 = 0; i1 < thePlanFiles.size(); i1++ ){
606 thePlanFiles[i1]->DumpToFile();
G4double Hounsfield2density(Uint32 Hval)
void SetMinZ(const G4double &val)
G4int GetWordsInLine(std::vector< G4String > &wl)
void SetFileName(G4String fName)
std::vector< DicomFileStructure * > GetStructFiles() const
void AddMaterialDensity(std::vector< G4String > data)
void SetMaxZ(const G4double &val)
static G4tgrFileIn & GetInstance(const G4String &name)
G4GLOB_DLL std::ostream G4cout
void SetCompression(G4String fComp)
size_t GetMaterialIndexByDensity(G4double density)
static G4double ConvertToDouble(const char *st)
void AddCT2Density(std::vector< G4String > data)
static G4int ConvertToInt(const char *st)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void AddFile(G4String fComp)
const G4double & GetLocation() const
void DumpHeaderToTextFile(std::ofstream &fout)
void BuildPETActivities()
void CheckNColumns(std::vector< G4String > wl, size_t vsizeTh)
size_t GetMaterialIndex(G4double Hval)
void AddMaterial(std::vector< G4String > data)
void Convert(G4String fFileName)
static DicomFileMgr * GetInstance()
G4GLOB_DLL std::ostream G4cerr