Program: gdcm
Module: $RCSfile: SplitIntoDirectories.cxx,v $
Language: C++
- Date: $Date: 2007/10/19 14:12:31 $
- Version: $Revision: 1.3 $
+ Date: $Date: 2011/04/22 14:39:41 $
+ Version: $Revision: 1.10 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include <iostream>
/**
- * \brief
+ * \brief
* - explores recursively the given directory
* - keeps the requested series
* - orders the gdcm-readable found Files
* according to their Patient/Study/Serie/Image characteristics
- */
+ */
typedef std::map<std::string, GDCM_NAME_SPACE::File*> SortedFiles;
-int main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
START_USAGE(usage)
" \n SplitIntoDirectories :\n ",
" - keeps the requested series / drops the unrequested series ",
" - orders the gdcm-readable found Files according to their ",
" (0x0010, 0x0010) Patient's Name ",
- " (0x0020, 0x000d) Study Instance UID ",
+ " (0x0020, 0x000d) Study Instance UID ",
" (0x0020, 0x000e) Series Instance UID ",
" - fills a tree-like structure of directories as : ",
" - Patient ",
std::cout << "... inside " << argv[0] << std::endl;
// ----- Initialize Arguments Manager ------
-
+
GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
if (argc == 1 || am->ArgMgrDefined("usage"))
return 0;
}
- const char *dirNamein;
- dirNamein = am->ArgMgrGetString("dirin",".");
+ const char *dirNamein;
+ dirNamein = am->ArgMgrGetString("dirin",".");
const char *dirNameout;
- dirNameout = am->ArgMgrGetString("dirout",".");
+ dirNameout = am->ArgMgrGetString("dirout",".");
int loadMode = GDCM_NAME_SPACE::LD_ALL;
if ( am->ArgMgrDefined("noshadowseq") )
loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ;
- else
+ else
{
if ( am->ArgMgrDefined("noshadow") )
loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW;
bool verbose = ( 0 != am->ArgMgrDefined("verbose") );
bool listonly = ( 0 != am->ArgMgrDefined("listonly") );
bool seriedescr = ( 0 != am->ArgMgrDefined("seriedescr") );
-
+
int nbSeriesToKeep;
int *seriesToKeep = am->ArgMgrGetListOfInt("keep", &nbSeriesToKeep);
int nbSeriesToDrop;
int *seriesToDrop = am->ArgMgrGetListOfInt("drop", &nbSeriesToDrop);
-
+
if ( nbSeriesToKeep!=0 && nbSeriesToDrop!=0)
{
std::cout << "KEEP and DROP are mutually exclusive !" << std::endl;
delete am;
- return 0;
+ return 0;
}
- bool hasSkel = ( 0 != am->ArgMgrDefined("hasSkel") );
+ bool hasSkel = ( 0 != am->ArgMgrDefined("hasSkel") );
const char *skel;
if (hasSkel)
- skel = am->ArgMgrGetString("skel");
-
-
+ skel = am->ArgMgrGetString("skel");
+
+
const char *input = am->ArgMgrGetString("input","DCM");
// if unused Param we give up
if ( am->ArgMgrPrintUnusedLabels() )
- {
+ {
am->ArgMgrUsage(usage);
delete am;
return 0;
}
std::string systemCommand;
-
+
std::cout << "Check for output directory :[" << dirNameout << "]."
<<std::endl;
if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirNameout) ) // dirout not found
{
std::string strDirNameout(dirNameout); // to please gcc 4
- systemCommand = "mkdir " +strDirNameout; // create it!
+ systemCommand = "mkdir \"" +strDirNameout + "\""; // create it!
if (verbose)
std::cout << systemCommand << std::endl;
system (systemCommand.c_str());
if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirNameout) ) // be sure it worked
{
- std::cout << "KO : not a dir : [" << dirNameout << "] (creation failure ?)"
+ std::cout << "KO : not a dir : [" << dirNameout << "] (creation failure ?)"
<< std::endl;
- return 0;
-
+ return 0;
}
else
{
// VERY IMPORTANT :
- // Respect the order you choosed in 'enum Index' !
+ // While coding the various AddSeriesDetail,
+ // respect the order you choosed in 'enum Index' !
/*
enum Index
// or the field may be empty!
s->AddSeriesDetail(0x0020, 0x000d, false); // Study Instance UID (false : no convert)
-
// You may prefer 0020 0011 Series Number
// use :
// s->AddSeriesDetail(0x0020, 0x0011, true);
s->AddSeriesDetail(0x0020, 0x000e, false); // Series Instance UID (false : no convert)
s->AddSeriesDetail(0x0008, 0x103e, false); // Serie Description
- s->AddSeriesDetail(0x0020, 0x0011, false); // Serie Number (more than 1 serie may have the same Descr. don't 'convert!)
-
+ s->AddSeriesDetail(0x0020, 0x0011, false); // Serie Number (more than 1 serie may have the same Ser.Nbr don't 'convert!)
+
// Feel free to add more fields, if they can help a suitable (for you)
// image sorting
-// Loop on all the gdcm-readable files
+ // Loop on all the gdcm-readable files
for (GDCM_NAME_SPACE::DirListType::iterator it = fileNames.begin();
it != fileNames.end();
++it)
f = GDCM_NAME_SPACE::File::New();
f->SetLoadMode(loadMode);
f->SetFileName( *it );
+ if (verbose)
+ std::cout << "Try[" << *it << "]\n";
f->Load();
-
+ if (!f->Document::IsReadable())
+ {
+ if (verbose)
+ std::cout << "File : [" << *it << "] not gdcm-readable -> skipped !" << std::endl;
+ continue;
+ }
+ if (verbose)
+ std::cout << "Loaded!\n";
std::string strSeriesNumber;
int seriesNumber;
int j;
// drop all unrequested Series
bool drop = false;
if (nbSeriesToDrop != 0)
- {
+ {
strSeriesNumber = f->GetEntryString(0x0020, 0x0011 );
seriesNumber = atoi( strSeriesNumber.c_str() );
for (j=0;j<nbSeriesToDrop; j++)
{
if(seriesNumber == seriesToDrop[j])
- {
+ {
drop = true;
break;
}
}
userFileIdentifier=s->CreateUserDefinedFileIdentifier(f);
+ if (verbose)
+ std::cout << "userFileIdentifier [" << userFileIdentifier << "]" << std::endl;
tokens.clear();
GDCM_NAME_SPACE::Util::Tokenize (userFileIdentifier, tokens, token);
- //int imageNum; // Within FileName
char newName[1024];
-
+
///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
std::string name = GDCM_NAME_SPACE::Util::GetName( *it );
+ // if (verbose)
+ // std::cout << "name :[" << name << "]\n";
+
if (hasSkel)
{
int imageNum; // Within FileName
else
{
tokens[IND_FileName] = name;
- }
-
+ }
+
// Patient's Name
- // Study Instance UID
+ // Study Instance UID
// Series Instance UID
+ // SerieDescription
+ // Serie Number
// file Name
userFileIdentifier = tokens[IND_PatientName] + token +
tokens[IND_SerieDescription] + token +
tokens[IND_SerieNumber] + token +
tokens[IND_FileName];
-
if (verbose)
std::cout << "[" << userFileIdentifier << "] : " << *it << std::endl;
-
- // storing in a map ensures automatic sorting !
+
+ // storing in a map ensures automatic sorting !
sf[userFileIdentifier] = f;
}
if (verbose)
- std::cout << " " << std::endl;
+ std::cout << " ==== " << std::endl;
std::string fullFilename, lastFilename;
std::string previousPatientName, currentPatientName;
previousSerieInstanceUID = "";
GDCM_NAME_SPACE::File *currentFile;
-
+ std::string replaceChar("_");
for (it2 = sf.begin() ; it2 != sf.end(); ++it2)
{
currentFile = it2->second;
GDCM_NAME_SPACE::Util::Tokenize (it2->first, tokens, token);
currentPatientName = tokens[IND_PatientName];
- currentStudyInstanceUID = tokens[IND_StudyInstanceUID];
+ currentStudyInstanceUID = tokens[IND_StudyInstanceUID];
currentSerieInstanceUID = tokens[IND_SerieInstanceUID];
currentSerieDescription = tokens[IND_SerieDescription];
currentSerieNumber = tokens[IND_SerieNumber];
-
+
if (previousPatientName != currentPatientName)
{
previousPatientName = currentPatientName;
if (verbose)
std::cout << "==== new Patient [" << currentPatientName << "]" << std::endl;
-
+
previousPatientName = currentPatientName;
previousStudyInstanceUID = "";
previousSerieInstanceUID = "";
-
+
currentPatientWriteDir = writeDir + currentPatientName;
- systemCommand = "mkdir " + currentPatientWriteDir;
+ systemCommand = "mkdir \"" + currentPatientWriteDir + "\"";
if (verbose || listonly)
std::cout << "[" << systemCommand << "]" << std::endl;
- if (!listonly)
+ if (!listonly)
system ( systemCommand.c_str() );
}
-
+
if (previousStudyInstanceUID != currentStudyInstanceUID)
- {
+ {
previousStudyInstanceUID = currentStudyInstanceUID;
- if (verbose)
+ if (verbose)
std::cout << "==== === new Study [" << currentStudyInstanceUID << "]"
- << std::endl;
+ << std::endl;
currentStudyWriteDir = currentPatientWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR
+ currentStudyInstanceUID;
- systemCommand = "mkdir " + currentStudyWriteDir;
-
+ systemCommand = "mkdir \"" + currentStudyWriteDir + "\"";
+
+ if (verbose)
+ std::cout << "Directory [" << currentStudyWriteDir << "] created" << std::endl;
+
if (listonly)
- std::cout << "[" << systemCommand << "]" << std::endl;
+ std::cout << "[" << systemCommand << "]" << std::endl;
else
system (systemCommand.c_str());
-
}
-
+
if (previousSerieInstanceUID != currentSerieInstanceUID)
{
previousSerieInstanceUID = currentSerieInstanceUID;
if (seriedescr) // more human readable!
currentSerieWriteDir = currentStudyWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR
- + currentSerieDescription + "_" + currentSerieNumber;
+ + currentSerieDescription + "_" + currentSerieNumber
+ /*+ "_" + currentSerieInstanceUID */
+ ;
+
else
currentSerieWriteDir = currentStudyWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR
+ currentSerieInstanceUID;
-
- systemCommand = "mkdir " + currentSerieWriteDir;
+
+ systemCommand = "mkdir \"" + currentSerieWriteDir + "\"";
if (listonly)
std::cout << "[" << systemCommand << "]" << std::endl;
else
system (systemCommand.c_str());
+
+ if (verbose)
+ std::cout << "Directory [" << currentSerieWriteDir << "] created" << std::endl;
}
if ( GDCM_NAME_SPACE::Debug::GetDebugFlag())
<< GDCM_NAME_SPACE::Util::GetName( fullFilename ) << std::endl;
// If you want to create file names of your own, here is the place!
- // Just replace 'lastFilename' by anything that's better for you.
+ // Just replace 'lastFilename' by anything that's better for you.
+ GDCM_NAME_SPACE:: Util::ReplaceSpecChar(lastFilename, replaceChar);
+
fullWriteFilename = currentSerieWriteDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR
+ lastFilename;
- systemCommand = "cp " + fullFilename + " " + fullWriteFilename;
+ systemCommand = "cp \"" + fullFilename + "\" \"" + fullWriteFilename + "\"";
if (listonly)
std::cout << "[" << systemCommand << "]" << std::endl;
}
return 0;
}
-