From: jpr Date: Mon, 1 Oct 2007 09:56:42 +0000 (+0000) Subject: Like SplitIntoXCoherentDirectories; X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=867c13bf5072ec576cfb33a6e56f0872f9531b2e;p=gdcm.git Like SplitIntoXCoherentDirectories; Ignores 'Series Instance UID'. Usefull when current filestore is not suitable for user (e.g. : series are 'single slice, multi time points', user want to deal with them as 'single time point, multi slice') --- diff --git a/Example/SplitIntoXCoherentDirectoriesIgnoreSerieUID.cxx b/Example/SplitIntoXCoherentDirectoriesIgnoreSerieUID.cxx new file mode 100755 index 00000000..5b5a2263 --- /dev/null +++ b/Example/SplitIntoXCoherentDirectoriesIgnoreSerieUID.cxx @@ -0,0 +1,373 @@ +/*========================================================================= + + Program: gdcm + Module: $RCSfile: SplitIntoXCoherentDirectoriesIgnoreSerieUID.cxx,v $ + Language: C++ + Date: $Date: 2007/10/01 09:56:42 $ + Version: $Revision: 1.1 $ + + Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de + l'Image). All rights reserved. See Doc/License.txt or + http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "gdcmSerieHelper.h" +#include "gdcmFileHelper.h" +#include "gdcmFile.h" +#include "gdcmDebug.h" +#include +#include "gdcmDirList.h" +#include "gdcmUtil.h" +#include "gdcmArgMgr.h" +#include "gdcmDictSet.h" // for GetName +int main(int argc, char *argv[]) +{ + + START_USAGE(usage) + "\n SplitIntoCoherentFileSetIgnoreSerieUID :\n ", + "Shows the various 'XCoherent' Filesets within a directory ", + "Optionaly copis the images in a Directories tree ", + "usage: SplitIntoCoherentFileSetIgnoreSerieUID{dirin=inputDirectoryName} ", + " dirout=outputDirectoryName ", + " { tag=group-elem | pos | ori } [sort] ", + " [{ write | copy }] ", + " [ { [noshadowseq] | [noshadow][noseq] } ] [debug] ", + " [studyUID = ] ", + " dirin : user wants to analyze *all* the files ", + " within the directory ", + " write : user wants to create directories ", + " dirout : will be created if doesn't exist ", + " pos : user wants to split each Single SerieUID Fileset on the ", + " 'Image Position ' ", + " ori : user wants to split each Single SerieUID Fileset on the ", + " 'Image Orientation ' ", + " tag : group-elem (in hexa, no space) ", + " the user wants to split on ", + " sort : user wants FileHelper to sort the images ", + " Warning : will probabely crah if sort has no meaning ", + " (not only look at image names) ", + " studyUID : *aware* user wants to add the serie ", + " to an already existing study ", + " verbose : user wants to run the program in 'verbose mode' ", + " debug : developper wants to run the program in 'debug mode' ", + FINISH_USAGE + + // ----- Initialize Arguments Manager ------ + + GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv); + + if (am->ArgMgrDefined("usage") || argc == 1) + { + am->ArgMgrUsage(usage); // Display 'usage' + delete am; + return 0; + } + + if (am->ArgMgrDefined("debug")) + GDCM_NAME_SPACE::Debug::DebugOn(); + + int loadMode = GDCM_NAME_SPACE::LD_ALL; + + const char *dirName = am->ArgMgrGetString("dirin"); + if (dirName == 0) + { + std::cout <ArgMgrGetString("dirout","."); + + bool pos = ( 0 != am->ArgMgrDefined("pos") ); + bool ori = ( 0 != am->ArgMgrDefined("ori") ); + bool sort = ( 0 != am->ArgMgrDefined("sort") ); + bool write = ( 0 != am->ArgMgrDefined("write") ); + bool verbose = ( 0 != am->ArgMgrDefined("verbose") ); + bool tag = ( 0 != am->ArgMgrDefined("tag") ); + + if( (tag && (pos || ori)) || (pos && (tag || ori)) || (ori && (tag || pos)) ) + { + std::cout << " POS, ORI and TAG are mutually exclusive" << std::endl; + delete am; + return 0; + } + + if( (!tag && !pos && !ori)) + { + std::cout << " One of POS, ORI and TAG is mandatory!" << std::endl; + delete am; + return 0; + } + int nb; + uint16_t *groupelem; + if (tag) + { + groupelem = am->ArgMgrGetXInt16Enum("tag", &nb); + if (nb != 1) + { + std::cout << "TAG : one and only one group,elem!" << std::endl; + delete am; + return 0; + } + } + + bool userDefinedStudy = ( 0 != am->ArgMgrDefined("userDefinedStudy") ); + const char *studyUID = am->ArgMgrGetString("studyUID"); + + /* if unused Param we give up */ + if ( am->ArgMgrPrintUnusedLabels() ) + { + am->ArgMgrUsage(usage); + delete am; + return 0; + } + + delete am; // ------ we don't need Arguments Manager any longer ------ + + + + GDCM_NAME_SPACE::SerieHelper *s; + s = GDCM_NAME_SPACE::SerieHelper::New(); + + GDCM_NAME_SPACE::File *f; + + GDCM_NAME_SPACE::DirList dirlist(dirName, true); // recursive exploration + GDCM_NAME_SPACE::DirListType fileNames = dirlist.GetFilenames(); + + GDCM_NAME_SPACE::FileList *l = new GDCM_NAME_SPACE::FileList; +// Loop on all the gdcm-readable files + for (GDCM_NAME_SPACE::DirListType::iterator it = fileNames.begin(); + it != fileNames.end(); + ++it) + { + if (verbose) + std::cout << *it << std::endl; + f = GDCM_NAME_SPACE::File::New(); + f->SetLoadMode(loadMode); // load any DataElement + f->SetMaxSizeLoadEntry(0x7fff); // load any length + f->SetFileName( *it ); + f->Load(); + l->push_back(f); + } + + +/* ===========================================================================================*/ + std::string systemCommand; + std::string filenameout; + if (write) { + if (verbose) + std::cout << "Check for output directory :[" << dirNameout << "]." + < End of checking supposed-to-be-directory names + + int nbFiles; + std::string fileName; + + // For all the Single SerieUID Files Sets of the GDCM_NAME_SPACE::Serie + + //GDCM_NAME_SPACE::FileList *l = s->GetFirstSingleSerieUIDFileSet();//===> Ignore 'Serie UID" + + GDCM_NAME_SPACE::XCoherentFileSetmap xcm; + + std::string serieUID; + std::string currentSerieWriteDir = ""; + std::string xCoherentWriteDir = ""; + std::string xCoherentName = ""; + std::string serieDirectory; + std::string lastFilename; + std::string rep("_"); + int controlCount = 0; + + // 'Study Instance UID' + // The user is allowed to create his own Study, + // keeping the same 'Study Instance UID' for various images + // The user may add images to a 'Manufacturer Study', + // adding new Series to an already existing Study + std::string strStudyUID; + if ( !userDefinedStudy) + strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + else + strStudyUID = studyUID; + + +// while (l) // for each 'Single SerieUID FileSet' //===> Ignore 'Serie UID" +// { + nbFiles = l->size() ; + if ( l->size() > 2 ) // ignore a Directory with less than 2 images. + // Why not ? Just an example, for testing! + { + // Just not to make too many modif in the code + serieUID = "aaaa"; //s->GetCurrentSerieUIDFileSetUID(); + GDCM_NAME_SPACE::Util::ReplaceSpecChar(serieUID, rep); + + // --- for write + if (write) + { + currentSerieWriteDir = currentSerieWriteDir + dirNameout; + unsigned int l = strlen(dirNameout)-1; + if ( dirNameout[l] != '/' && dirNameout[l] != '\\') + currentSerieWriteDir = currentSerieWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR; + + currentSerieWriteDir = currentSerieWriteDir + serieUID; + if (verbose) + std::cout << "[" << currentSerieWriteDir<< "]" << std::endl; + // if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(currentSerieWriteDir) ) + { + systemCommand = "mkdir " + currentSerieWriteDir; + system( systemCommand.c_str()); + if (verbose) + std::cout << "1 " <SplitOnOrientation(l); + else if (pos) + xcm = s->SplitOnPosition(l); + else if (groupelem != 0) { + + std:: cout << GDCM_NAME_SPACE::Global::GetDicts()->GetDefaultPubDict()->GetEntry(groupelem[0],groupelem[1])->GetName() << std::endl; + + xcm = s->SplitOnTagValue(l, groupelem[0],groupelem[1] ); + } + + GDCM_NAME_SPACE::FileHelper *fh; + + for (GDCM_NAME_SPACE::XCoherentFileSetmap::iterator i = xcm.begin(); + i != xcm.end(); + ++i) + { + xCoherentName = (*i).first; + if (verbose) + std::cout << "xCoherentName = " << xCoherentName << std::endl; + GDCM_NAME_SPACE::Util::ReplaceSpecChar(xCoherentName, rep); + // --- for write + if (write) + { + xCoherentWriteDir = currentSerieWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR+ xCoherentName; + // if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(xCoherentWriteDir) ) + { + systemCommand = "mkdir " + xCoherentWriteDir; + system( systemCommand.c_str()); + if (verbose) + std::cout << "2 " << systemCommand << std::endl; + } + } + // --- end for write + + if (ori) + std::cout << "Orientation : "; + else if (pos) + std::cout << "Position : "; + else if (groupelem != 0) + std::cout << "Tag (" << std::hex << groupelem[0] + << "|" << groupelem[1] << ") value : "; + std::cout << "[" << (*i).first << "]" << std::endl; + + if (verbose) + std::cout << "xCoherentName [" << xCoherentName << "]" << std::endl; + + // Within a 'just to see' program, + // OrderFileList() causes trouble, since some files + // (eg:MIP views) don't have 'Position', now considered as mandatory + // --> Activated on user demand. + + if (sort) { + s->OrderFileList((*i).second); // sort the XCoherent Fileset + std::cout << "ZSpacing for the file set " << s->GetZSpacing() + << std::endl; + } + + std::string strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + + for (GDCM_NAME_SPACE::FileList::iterator it2 = ((*i).second)->begin(); + it2 != ((*i).second)->end(); + ++it2) + { + controlCount ++; + fileName = (*it2)->GetFileName(); + std::cout << " " << fileName << std::endl; + + // --- for write + if (write) + { + fh = GDCM_NAME_SPACE::FileHelper::New( (*it2) ); + fh->SetKeepOverlays( true ); + fh->InsertEntryString(strSerieUID,0x0020,0x000e,"UI"); + unsigned int dataSize = fh->GetImageDataRawSize(); + uint8_t *imageData = fh->GetImageDataRaw();// somewhat important : Loads the Pixels in memory ! + if (!imageData) + std::cout << "fail to read [" << (*it2)->GetFileName() << std::endl; + lastFilename = GDCM_NAME_SPACE::Util::GetName( fileName ); + filenameout = xCoherentWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR+ lastFilename; + //systemCommand = "cp " + fileName + " " + filenameout; + //system( systemCommand.c_str()); + + fh->SetWriteTypeToDcmExplVR(); + fh->SetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE); + if (!fh->Write(filenameout)) + { + std::cout << "Fail to write :[" << filenameout << "]" + << std::endl; + } + if (verbose) + std::cout << "3 " << systemCommand << std::endl; + fh->Delete(); + } + // --- end for write + } + std::cout << std::endl; + } + } + // l = s->GetNextSingleSerieUIDFileSet(); //===> Ignore 'Serie UID" +// } + + if ( controlCount == 0 ) + std::cout << "No suitable file was found!" << std::endl; + + s->Delete(); +/*===============================================================================================*/ + return 0; +}