1 /*=========================================================================
4 Module: $RCSfile: ToMRIregister.cxx,v $
6 Date: $Date: 2006/10/23 15:51:33 $
7 Version: $Revision: 1.2 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
19 #include "gdcmSerieHelper.h"
21 #include "gdcmFileHelper.h"
22 #include "gdcmDebug.h"
23 #include "gdcmDirList.h"
25 #include "gdcmArgMgr.h"
29 bool AquisitionTime_0008_0032_Compare(gdcm::File *file1, gdcm::File *file2);
31 bool AquisitionTime_0008_0032_Compare(gdcm::File *file1, gdcm::File *file2)
33 return file1->GetEntryString(0x0008,0x0032) < file2->GetEntryString(0x0008,0x0032);
36 int main(int argc, char *argv[])
40 "\n ToMriregister :\n ",
41 " - Converts the Siemens Sonata MRI '*tfl2d1' ",
42 " to be processable by MriRegister software ",
43 " - May be used as a template for gdcm::SerieHelper use. ",
45 "usage: ToMriRegister dirin=inputDirectoryName ",
46 " dirout=outputDirectoryName ",
47 " [ { [noshadowseq] | [noshadow][noseq] } ] [debug] ",
49 " inputDirectoryName : user wants to analyze *all* the files ",
50 " within the directory ",
51 " noshadowseq: user doesn't want to load Private Sequences ",
52 " noshadow : user doesn't want to load Private groups (odd number) ",
53 " noseq : user doesn't want to load Sequences ",
54 " verbose : user wants to run the program in 'verbose mode' ",
55 " debug : developer wants to run the program in 'debug mode' ",
58 // ----- Initialize Arguments Manager ------
60 gdcm::ArgMgr *am = new gdcm::ArgMgr(argc, argv);
62 if (am->ArgMgrDefined("usage") || argc == 1)
64 am->ArgMgrUsage(usage); // Display 'usage'
69 if (am->ArgMgrDefined("debug"))
70 gdcm::Debug::DebugOn();
72 int verbose = am->ArgMgrDefined("verbose");
74 int loadMode = gdcm::LD_ALL;
75 if ( am->ArgMgrDefined("noshadowseq") )
76 loadMode |= gdcm::LD_NOSHADOWSEQ;
79 if ( am->ArgMgrDefined("noshadow") )
80 loadMode |= gdcm::LD_NOSHADOW;
81 if ( am->ArgMgrDefined("noseq") )
82 loadMode |= gdcm::LD_NOSEQ;
85 const char *dirIn = am->ArgMgrGetString("dirin");
89 << "'dirin=' must be present;"
91 am->ArgMgrUsage(usage); // Display 'usage'
96 const char *dirOut = am->ArgMgrGetString("dirout");
100 << "'dirout=' must be present;"
102 am->ArgMgrUsage(usage); // Display 'usage'
107 /* if unused Param we give up */
108 if ( am->ArgMgrPrintUnusedLabels() )
110 am->ArgMgrUsage(usage);
115 delete am; // ------ we don't need Arguments Manager any longer ------
117 // ======================== more checking on the params ==============
119 if ( ! gdcm::DirList::IsDirectory(dirIn) )
121 std::cout << "KO : [" << dirIn << "] is not a Directory." << std::endl;
128 std::cout << "OK : [" << dirIn << "] is a Directory." << std::endl;
131 std::string systemCommand;
132 std::string strDirNameout(dirOut); // to please gcc 4
134 std::cout << "Check for output directory :[" << dirOut << "]."
136 if ( ! gdcm::DirList::IsDirectory(dirOut) ) // dirout not found
138 systemCommand = "mkdir " + strDirNameout; // create it!
140 std::cout << systemCommand << std::endl;
141 system (systemCommand.c_str());
142 if ( ! gdcm::DirList::IsDirectory(dirOut) ) // be sure it worked
144 std::cout << "KO : not a dir : [" << dirOut
145 << "] (creation failure ?)" << std::endl;
152 std::cout << "Directory [" << dirOut << "] created." << std::endl;
158 std::cout << "Output Directory [" << dirOut
159 << "] already exists; Used as is." << std::endl;
162 // ========================== Now, we can do the job! ================
164 // Just to see *all* the file names:
166 gdcm::DirList dirList(dirIn,true); // gets (recursively) the file list
167 gdcm::DirListType fileList = dirList.GetFilenames();
168 for( gdcm::DirListType::iterator it = fileList.begin();
169 it != fileList.end();
172 std::cout << "file [" << it->c_str() << "]" << std::endl;
175 gdcm::SerieHelper *s;
177 s = gdcm::SerieHelper::New();
178 s->SetLoadMode(gdcm::LD_NOSEQ); // Don't load Sequences
180 // we could choose to ignore some Files
181 //gdcm::TagKey t(0x0010,0x0024); // [Sequence Name]
182 // Keep only files where restriction is true
183 //s->AddRestriction(t, "*tfl2d1 ", gdcm::GDCM_EQUAL);
185 s->SetDirectory(dirIn, true); // true : recursive exploration
188 std::cout << " ---------------------------------------- "
189 << "'Single UID' Filesets found in :["
190 << dirName << "]" << std::endl;
193 std::cout << " ------------------------------------- Result after splitting"
197 std::string fullFilename, lastFilename;
198 char fullWriteFilename[1024]; // should be enough.
200 std::ostringstream str;
202 gdcm::XCoherentFileSetmap xcm;
203 gdcm::FileHelper *fh;
205 // will be used for ordering.
206 s->SetUserLessThanFunction(AquisitionTime_0008_0032_Compare);
211 // For all the Single SerieUID Files Sets of the gdcm::Serie
212 gdcm::FileList *l = s->GetFirstSingleSerieUIDFileSet();
215 nbFiles = l->size() ;
216 if ( l->size() < 8 ) // Hope we skip Scout views !
218 std::cout << "Ignore the 'Single SerieUID' FileSet :["
219 << s->GetCurrentSerieUIDFileSetUID()
220 << "] " << nbFiles << " long" << std::endl;
221 std::cout << "-----------------------------------" << std::endl;
225 std::cout << "Split the 'Single SerieUID' FileSet :["
226 << s->GetCurrentSerieUIDFileSetUID()
227 << "] " << nbFiles << " long" << std::endl;
228 std::cout << "-----------------------------------" << std::endl;
230 xcm = s->SplitOnPosition(l);
232 //int sliceNumber = 0;
234 for (gdcm::XCoherentFileSetmap::iterator i = xcm.begin();
238 std::cout << "Position : ";
239 std::cout << "[" << (*i).first << "]" << std::endl;
241 s->OrderFileList((*i).second); // sort the current XCoherent Fileset
243 //int imageNumber = 0;
244 for ( gdcm::FileList::iterator it = ((*i).second)->begin();
245 it != ((*i).second)->end();
249 // Set the DataElements MriRegister needs to be happy
250 // Probabely one of the following (check it !):
252 0020 0011 IS 1 Series Number
253 0020 0012 IS 1 Acquisition Number
254 0020 0013 IS 1 Instance Number
257 (*it)->InsertEntryString("0",0x0008,0x0000, "UL"); // Needs to be present (actual length doesn't matter !)
261 (*it)->InsertEntryString(str.str(),0x0020,0x0011, "IS"); // Series Number
265 (*it)->InsertEntryString(str.str(),0x0020,0x0013, "IS"); // Instance Number
267 // Load the pixels in RAM.
269 fh = gdcm::FileHelper::New(*it);
270 uint8_t *imageData = fh->GetImageDataRaw(); // Don't convert (Gray Pixels + LUT) into (RGB pixels) ?!?
272 std::cout << "fail to read [" << (*it)->GetFileName() << std::endl;
273 fh->SetWriteTypeToACR();
274 fh->SetContentType(gdcm::UNMODIFIED_PIXELS_IMAGE);
276 // forge the file name
278 fullFilename = (*it)->GetFileName();
279 lastFilename = gdcm::Util::GetName( fullFilename );
280 //fullWriteFilename = strDirNameout + gdcm::GDCM_FILESEPARATOR
282 sprintf(fullWriteFilename, "%s%c%04d-%04d-%04d.dcm",
283 dirOut, gdcm::GDCM_FILESEPARATOR,
284 serieNumber, sliceNumber, imageNumber);
286 std::cout << fullFilename << " -> " << fullWriteFilename << std::endl;
290 if (!fh->Write(fullWriteFilename))
292 std::cout << "Fail to write :[" << fullWriteFilename << "]"
296 ///\todo FIXME segfaults if uncommented ?!?
297 // delete(imageData);
304 std::cout << std::endl;
309 l = s->GetNextSingleSerieUIDFileSet();