X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=Example%2FToInTag.cxx;h=f7e18ec8fb1019db38bcdae622fd9de42aaedc55;hb=6a5de9524996d429cd18c722261421ff4e298681;hp=7ed73f31f212ee9268754d2e21f6ad345ab7bfa6;hpb=8fd45dc6d321d1419854dc0e4fa6a37d6826b655;p=gdcm.git diff --git a/Example/ToInTag.cxx b/Example/ToInTag.cxx index 7ed73f31..f7e18ec8 100755 --- a/Example/ToInTag.cxx +++ b/Example/ToInTag.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: ToInTag.cxx,v $ Language: C++ - Date: $Date: 2007/05/23 14:18:04 $ - Version: $Revision: 1.11 $ + Date: $Date: 2007/07/04 17:39:28 $ + Version: $Revision: 1.17 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -55,27 +55,37 @@ int main(int argc, char *argv[]) " - fills a single level (*) Directory with *all* the files, ", " converted into a Brucker-like Dicom, InTags compliant ", " (*) actually : creates as many directories as Patients ", - " -that shouldn't appear, but being carefull is better ! -", + " -that shouldn't appear, but being carefull is better!- ", " or ", " - fills a tree-like structure of directories as : ", " - Patient ", " -- Serie ", " --- Position ", - " Images are (sorted by Trigger Time / ", - " Encoding Direction (Row, Column) ", - " use : ", + " ---- Images (sorted by Trigger Time / ", + " Encoding Direction (Row, Column) ", + " ", + " Note : when (0008|1090) [Model Name ] equals 'TrioTim ' : ", + " - (0008|103e)[Series Description ] is checked for ", + " '90' (-> COL) or '0' (-> ROW) ", + " - (0x0020, 0x000e) [Series Instance UID] is NOT dealt with, ", + " since row an col tagging are in 2 different Series ", + " DO NOT supply a directory holding different exams ", + " for the same Slice level! ", + " uses : ", " 0x0021, 0x1020 : 'SLICE INDEX' ", " 0x0021, 0x1040 : 'FRAME INDEX' ", " 0x0020, 0x0012 : 'SESSION INDEX' (Acquisition Number) ", + " ", " usage: ", + " ----- ", " ToInTag dirin=rootDirectoryName ", " dirout=outputDirectoryName ", " { [keep= list of seriesNumber to process] ", " | [drop= list of seriesNumber to ignore] } ", " [taggrid] [skel] ", - " [input = {ACR|DCM}] ", + " [input = {ACR|DCM|IDO}] ", " [extent=image suffix (.IMA, .NEMA, .DCM, ...)] ", - " [listonly] [split] ", + " [listonly] [split] [rubout] ", " [noshadowseq][noshadow][noseq] [verbose] [debug] ", " ", " dirout : will be created if doesn't exist ", @@ -85,15 +95,17 @@ int main(int argc, char *argv[]) " he gives the list of 'SeriesNumber' (tag 0020|0011) ", " SeriesNumber are short enough to be human readable ", " e.g : 1030,1035,1043 ", - " taggrid : user knows all the images are 'grid' -ie : not 'col', not 'raw'", + " taggrid : user knows all the images are 'grid' -ie: not 'col', not 'raw'-", " extent : DO NOT forget the leading '.' ! ", + " input : IDO when *realy* old libIDO images ", " skel: name skeleton eg : patName_1.nema -> skel=patName_ ", " split: creates a tree-like structure of directories as : ", " - Patient ", " -- Serie ", " --- Position ", - " Images are (sorted by Trigger Time / ", - " Encoding Direction (Row, Column) ", + " ---- Images (sorted by Trigger Time / ", + " Encoding Direction (Row, Column) ", + " rubout : user asks to rubout burnt-in image number ", " noshadowseq: user doesn't want to load Private Sequences ", " noshadow : user doesn't want to load Private groups (odd number) ", " noseq : user doesn't want to load Sequences ", @@ -137,7 +149,9 @@ int main(int argc, char *argv[]) int verbose = am->ArgMgrDefined("verbose"); int split = am->ArgMgrDefined("split"); int listonly = am->ArgMgrDefined("listonly"); - + + bool rubout = ( 0 != am->ArgMgrDefined("rubout") ); + int nbSeriesToKeep; int *seriesToKeep = am->ArgMgrGetListOfInt("keep", &nbSeriesToKeep); int nbSeriesToDrop; @@ -158,6 +172,7 @@ int main(int argc, char *argv[]) skel = am->ArgMgrGetString("skel"); const char *extent = am->ArgMgrGetString("extent",".DCM"); + const char *input = am->ArgMgrGetString("input","DCM"); // if unused Param we give up if ( am->ArgMgrPrintUnusedLabels() ) @@ -220,7 +235,7 @@ int main(int argc, char *argv[]) GDCM_NAME_SPACE::DirListType fileNames; fileNames = dirList.GetFilenames(); - GDCM_NAME_SPACE::SerieHelper *s; // Needed only to may use SerieHelper::AddSeriesDetail() + GDCM_NAME_SPACE::SerieHelper *s; // Needed to use SerieHelper::AddSeriesDetail() s = GDCM_NAME_SPACE::SerieHelper::New(); std::string token = "%%%"; // Hope it's enough! @@ -237,14 +252,14 @@ int main(int argc, char *argv[]) std::vector tokens; std::vector tokensForFileName; - // For Siemens pb, we need Station Name + // For Siemens pb, we need Manufacturer's Model Name GDCM_NAME_SPACE::DirListType::iterator it1 = fileNames.begin(); f = GDCM_NAME_SPACE::File::New(); f->SetLoadMode(GDCM_NAME_SPACE::LD_ALL); f->SetFileName( *it1 ); f->Load(); - std::string stationName = f->GetEntryString(0x0008,0x1010); + std::string modelName = f->GetEntryString(0x0008,0x1090); f->Delete(); /* @@ -276,7 +291,8 @@ int main(int argc, char *argv[]) SortedFiles sf; s->AddSeriesDetail(0x0010, 0x0010, false); // Patient's Name - if ( stationName != "MRC35150" ) // for Siemens MRC35150, don't deal with 'Series Instance UID' + // for Siemens TrioTim, don't deal with 'Series Instance UID' + if ( !GDCM_NAME_SPACE::Util::DicomStringEqual(modelName,"TrioTim") ) s->AddSeriesDetail(0x0020, 0x000e, false); // Series Instance UID else s->AddSeriesDetail(0x9999, 0x9999, false); // dirty trick to ignore 'Series Instance UID' @@ -340,7 +356,7 @@ int main(int argc, char *argv[]) f->Delete(); continue; } - } + } userFileIdentifier=s->CreateUserDefinedFileIdentifier(f); tokens.clear(); @@ -349,7 +365,7 @@ int main(int argc, char *argv[]) int imageNum; // Within FileName char newName[1024]; - if ( tokens[3] == "gdcmUnfound") // sometimes Trigger Time is not found. CreateUserDefinedFileIdentifier is not aware of the pb. + if ( tokens[3] == GDCM_NAME_SPACE::GDCM_UNFOUND) // sometimes Trigger Time is not found. CreateUserDefinedFileIdentifier is not aware of the pb. { ///this is a trick to build up a lexicographical compliant name : /// eg : fich001.ima vs fich100.ima as opposed to fich1.ima vs fich100.ima @@ -366,10 +382,18 @@ int main(int argc, char *argv[]) else tokens[3] = name; + // Patient's Name + // Series Instance UID + // Image Position (Patient) + // Trigger Time + // In-plane Phase Encoding Direction + // Series Description + // FileName userFileIdentifier = tokens[0] + token + tokens[1] + token + tokens[2] + token - + tokens[3] + token + tokens[4] + token + tokens[5] + token; - } + + tokens[3] + token + tokens[4] + token + tokens[5] + token + tokens[6] + token; + } + if (verbose) std::cout << "[" << userFileIdentifier << "] : " << *it << std::endl; @@ -412,7 +436,7 @@ int main(int argc, char *argv[]) frameIndex = 0; else frameIndex = 1; - + int flag = 0; GDCM_NAME_SPACE::File *currentFile; @@ -425,9 +449,11 @@ int main(int argc, char *argv[]) currentFile = it2->second; fullFilename = currentFile->GetFileName(); - lastFilename = GDCM_NAME_SPACE::Util::GetName( fullFilename ); - std::cout << " --------------------------------------------------" - << " Rewrite [" <first << "] : ["<first, tokens, token); @@ -460,12 +486,11 @@ int main(int argc, char *argv[]) if (previousPatientName != currentPatientName) { - if ( currentFile->GetEntryString(0x0020,0x000d) == GDCM_NAME_SPACE::GDCM_UNFOUND) + if ( currentFile->GetEntryString(0x0020,0x000d) == GDCM_NAME_SPACE::GDCM_UNFOUND) // Study UID { if (verbose) std::cout << "--- new Study UID created" << std::endl; defaultStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); - currentFile->InsertEntryString(defaultStudyUID, 0x0020, 0x000d, "UI" ); } previousPatientName = currentPatientName; @@ -487,8 +512,10 @@ int main(int argc, char *argv[]) system ( systemCommand.c_str() ); } } + currentFile->InsertEntryString(defaultStudyUID, 0x0020, 0x000d, "UI" ); + - if ( stationName != "MRC35150" ) // for Siemens MRC35150, don't deal with 'Series Instance UID' + if ( GDCM_NAME_SPACE::Util::DicomStringEqual(modelName,"TrioTim") ) // for Siemens TrioTim , don't deal with 'Series Instance UID' if (previousSerieInstanceUID != currentSerieInstanceUID) { @@ -501,7 +528,7 @@ int main(int argc, char *argv[]) if (verbose) std::cout << "--- --- new Serie UID created" << std::endl; defaultSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); - currentFile->InsertEntryString(defaultSerieUID, 0x0020, 0x000e, "UI" ); + // currentFile->InsertEntryString(defaultSerieUID, 0x0020, 0x000e, "UI" ); } if (split) @@ -515,8 +542,10 @@ int main(int argc, char *argv[]) previousImagePosition = ""; //currentImagePosition; previousPhaseEncodingDirection = ""; //currentPhaseEncodingDirection; } - // end of stationName != "MRC35150" - + currentFile->InsertEntryString(defaultSerieUID, 0x0020, 0x000e, "UI" ); + + // end of modelName != "TrioTim " + if (previousImagePosition != currentImagePosition) { frameIndex = 1; @@ -538,8 +567,6 @@ int main(int argc, char *argv[]) else sliceIndex += 1; } - if (verbose) - std::cout << "Slice Index : " << sliceIndex << std::endl; // We don't split on Row/Column! /* @@ -561,10 +588,6 @@ int main(int argc, char *argv[]) previousPhaseEncodingDirection = currentPhaseEncodingDirection; } */ - - if (verbose) - std::cout << "--- --- --- --- --- " << (it2->second)->GetFileName() - << std::endl; if ( GDCM_NAME_SPACE::Debug::GetDebugFlag()) std::cout << "--- --- --- --- --- " << it2->first << " " @@ -591,7 +614,6 @@ int main(int argc, char *argv[]) std::string chSessionIndex; // CLEANME - if (taggrid) { chSessionIndex = "1"; @@ -599,23 +621,24 @@ int main(int argc, char *argv[]) else { /* for SIEMENS MRI : - D 0008|1010 [SH] [Station Name ] [MRC35150] + D 0008|1090 [LO] [Manufacturer's Model Name ] [Triotim ] we have to deal with : - D 0008|103e [LO] [Series Description ] [fl2d9_line PA 15 90deg] + D 0008|103e [LO] [Series Description ] [fl2d9_line PA 15 90deg] or anything that contains '90' ! D 0008|103e [LO] [Series Description ] [fl2d9_line PA 15 0deg ] (everything is flagged as 'ROW') - */ - if ( stationName == "MRC35150" ) + */ + + if ( GDCM_NAME_SPACE::Util::DicomStringEqual(modelName,"TrioTim") ) { - if ( memcmp(seriesDescription.c_str(), "fl2d9linePA1590deg", 18) ) - chSessionIndex = "1"; - else if ( memcmp(seriesDescription.c_str(), "fl2d9linePA150deg", 18) ) - chSessionIndex = "2"; + if (seriesDescription.find("90", 0) != std::string::npos) + chSessionIndex = "1"; // 90 deg -> COL + else if (seriesDescription.find("0", 0)!= std::string::npos) + chSessionIndex = "2"; // 0 deg -> ROW else { - std::cout << "====================== seriesDescription " - << " neither fl2d9_line PA 15 90deg nor fl2d9_line PA 15 0deg (?!?) : [" + std::cout << "====================== seriesDescription doesn't contain" + << " neither '90' nor '0' (?!?) : [" << seriesDescription << "]" << std::endl; chSessionIndex = "1"; } @@ -635,6 +658,7 @@ int main(int argc, char *argv[]) } } } + if (currentFile->IsVRCoherent(0x0020) == 1 ) currentFile->InsertEntryString(chSessionIndex, 0x0020, 0x0012, " "); else @@ -656,9 +680,14 @@ int main(int argc, char *argv[]) stringVR = "IS"; currentFile->InsertEntryString(strChSliceIndex, 0x0021, 0x1020, stringVR); - currentFile->InsertEntryString(chFrameIndex, 0x0021, 0x1040, stringVR); - - + currentFile->InsertEntryString(chFrameIndex, 0x0021, 0x1040, stringVR); + + if (verbose) { + std::cout << "0x0021, 0x1020 : strChSliceIndex " << strChSliceIndex << std::endl; + std::cout << "0x0021, 0x1040 : chFrameIndex " << chFrameIndex << std::endl; + std::cout << "0x0020, 0x0012 : chSessionIndex " << chSessionIndex << std::endl; + } + std::string strImagePositionPatient = currentFile->GetEntryString(0x0020, 0x0032 ); if (strImagePositionPatient == GDCM_NAME_SPACE::GDCM_UNFOUND) { @@ -671,11 +700,11 @@ int main(int argc, char *argv[]) if (strImageOrientationPatient == GDCM_NAME_SPACE::GDCM_UNFOUND) { if (verbose) - std::cout << "Duplicate ImageOrientation into ImageOrientationPatient" << std::endl; + std::cout << "Duplicate ImageOrientation into ImageOrientationPatient" << std::endl; currentFile->InsertEntryString(currentFile->GetEntryString(0x0020, 0x0035), 0x0020, 0x0037, "DS" ); } - - if (taggrid) + + if (taggrid || strcmp(input, "IDO")==0 || strcmp(input, "ido")==0 ) frameIndex++; else { @@ -689,8 +718,6 @@ int main(int argc, char *argv[]) flag = 0; } } - if (verbose) - std::cout << "Frame Index : " << frameIndex << std::endl; if (split) @@ -701,32 +728,29 @@ int main(int argc, char *argv[]) else fullWriteFilename = currentPatientWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + lastFilename + strExtent; - - /* - systemCommand = "cp " + fullFilename + " " + fullWriteFilename; - std::cout << systemCommand << std::endl; - system ( systemCommand.c_str() ); - */ // Load the pixels in RAM. fh = GDCM_NAME_SPACE::FileHelper::New(currentFile); uint8_t *imageData = fh->GetImageDataRaw(); // Don't convert (Gray Pixels + LUT) into (RGB pixels) ?!? - fh->SetWriteTypeToDcmExplVR(); - // We didn't modify pixels -> keep unchanged the following : + fh->SetWriteTypeToDcmExplVR(); + + if (rubout) { + // Put to Black the burnt-in number. + nX = currentFile->GetXSize(); + nY = currentFile->GetYSize(); + for(int y=nY-15; y keep unchanged the following : // 'Media Storage SOP Class UID' (0x0002,0x0002) // 'SOP Class UID' (0x0008,0x0016) // 'Image Type' (0x0008,0x0008) - // 'Conversion Type' (0x0008,0x0064) - - // Put to Black the burnt-in number. - nX = currentFile->GetXSize(); - nY = currentFile->GetYSize(); - for(int y=nY-15; ySetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE); + if (!fh->Write(fullWriteFilename)) { std::cout << "Fail to write :[" << fullWriteFilename << "]" @@ -736,3 +760,4 @@ int main(int argc, char *argv[]) } return 0; } +