1 /*=========================================================================
4 Module: $RCSfile: ToMRIregister.cxx,v $
6 Date: $Date: 2007/10/24 08:03:44 $
7 Version: $Revision: 1.5 $
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 "gdcmDataEntry.h"
26 #include "gdcmArgMgr.h"
30 bool AquisitionTime_0008_0032_Compare(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2);
32 bool AquisitionTime_0008_0032_Compare(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2)
34 return file1->GetEntryString(0x0008,0x0032) < file2->GetEntryString(0x0008,0x0032);
37 int main(int argc, char *argv[])
41 "\n ToMriregister :\n ",
42 " - Converts the Siemens Sonata MRI '*tfl2d1' ",
43 " to be processable by MriRegister software ",
44 " - May be used as a template for GDCM_NAME_SPACE::SerieHelper use. ",
46 "usage: ToMriRegister dirin=inputDirectoryName ",
47 " dirout=outputDirectoryName ",
48 " [ { [noshadowseq] | [noshadow][noseq] } ] [debug] ",
50 " inputDirectoryName : user wants to analyze *all* the files ",
51 " within the directory ",
52 " noshadowseq: user doesn't want to load Private Sequences ",
53 " noshadow : user doesn't want to load Private groups (odd number) ",
54 " noseq : user doesn't want to load Sequences ",
55 " verbose : user wants to run the program in 'verbose mode' ",
56 " debug : developer wants to run the program in 'debug mode' ",
59 // ----- Initialize Arguments Manager ------
61 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
63 if (am->ArgMgrDefined("usage") || argc == 1)
65 am->ArgMgrUsage(usage); // Display 'usage'
70 if (am->ArgMgrDefined("debug"))
71 GDCM_NAME_SPACE::Debug::DebugOn();
73 int verbose = am->ArgMgrDefined("verbose");
75 int loadMode = GDCM_NAME_SPACE::LD_ALL;
76 if ( am->ArgMgrDefined("noshadowseq") )
77 loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ;
80 if ( am->ArgMgrDefined("noshadow") )
81 loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW;
82 if ( am->ArgMgrDefined("noseq") )
83 loadMode |= GDCM_NAME_SPACE::LD_NOSEQ;
86 const char *dirIn = am->ArgMgrGetString("dirin");
90 << "'dirin=' must be present;"
92 am->ArgMgrUsage(usage); // Display 'usage'
97 const char *dirOut = am->ArgMgrGetString("dirout");
100 std::cout <<std::endl
101 << "'dirout=' must be present;"
103 am->ArgMgrUsage(usage); // Display 'usage'
108 /* if unused Param we give up */
109 if ( am->ArgMgrPrintUnusedLabels() )
111 am->ArgMgrUsage(usage);
116 delete am; // ------ we don't need Arguments Manager any longer ------
118 // ======================== more checking on the params ==============
120 if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirIn) )
122 std::cout << "KO : [" << dirIn << "] is not a Directory." << std::endl;
129 std::cout << "OK : [" << dirIn << "] is a Directory." << std::endl;
132 std::string systemCommand;
133 std::string strDirNameout(dirOut); // to please gcc 4
135 std::cout << "Check for output directory :[" << dirOut << "]."
137 if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirOut) ) // dirout not found
139 systemCommand = "mkdir " + strDirNameout; // create it!
141 std::cout << systemCommand << std::endl;
142 system (systemCommand.c_str());
143 if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirOut) ) // be sure it worked
145 std::cout << "KO : not a dir : [" << dirOut
146 << "] (creation failure ?)" << std::endl;
153 std::cout << "Directory [" << dirOut << "] created." << std::endl;
159 std::cout << "Output Directory [" << dirOut
160 << "] already exists; Used as is." << std::endl;
163 // ========================== Now, we can do the job! ================
165 // Just to see *all* the file names:
167 GDCM_NAME_SPACE::DirList dirList(dirIn,true); // gets (recursively) the file list
168 GDCM_NAME_SPACE::DirListType fileList = dirList.GetFilenames();
169 for( GDCM_NAME_SPACE::DirListType::iterator it = fileList.begin();
170 it != fileList.end();
173 std::cout << "file [" << it->c_str() << "]" << std::endl;
176 GDCM_NAME_SPACE::SerieHelper *s;
178 s = GDCM_NAME_SPACE::SerieHelper::New();
179 s->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ); // Don't load Sequences
181 // we could choose to ignore some Files
182 //GDCM_NAME_SPACE::TagKey t(0x0010,0x0024); // [Sequence Name]
183 // Keep only files where restriction is true
184 //s->AddRestriction(t, "*tfl2d1 ", GDCM_NAME_SPACE::GDCM_EQUAL);
186 s->SetDirectory(dirIn, true); // true : recursive exploration
189 std::cout << " ---------------------------------------- "
190 << "'Single UID' Filesets found in :["
191 << dirName << "]" << std::endl;
194 std::cout << " ------------------------------------- Result after splitting"
198 std::string fullFilename, lastFilename;
199 char fullWriteFilename[1024]; // should be enough.
201 std::ostringstream str;
203 GDCM_NAME_SPACE::XCoherentFileSetmap xcm;
204 GDCM_NAME_SPACE::FileHelper *fh;
206 // will be used for ordering.
207 s->SetUserLessThanFunction(AquisitionTime_0008_0032_Compare);
212 // For all the Single SerieUID Files Sets of the GDCM_NAME_SPACE::Serie
213 GDCM_NAME_SPACE::FileList *l = s->GetFirstSingleSerieUIDFileSet();
218 nbFiles = l->size() ;
219 if ( l->size() < 8 ) // Hope we skip Scout views !
221 std::cout << "Ignore the 'Single SerieUID' FileSet :["
222 << s->GetCurrentSerieUIDFileSetUID()
223 << "] " << nbFiles << " long" << std::endl;
224 std::cout << "-----------------------------------" << std::endl;
228 std::cout << "Split the 'Single SerieUID' FileSet :["
229 << s->GetCurrentSerieUIDFileSetUID()
230 << "] " << nbFiles << " long" << std::endl;
231 std::cout << "-----------------------------------" << std::endl;
233 xcm = s->SplitOnPosition(l);
235 //int sliceNumber = 0;
237 double position =0.0;
238 char charPosition[10];
240 for (GDCM_NAME_SPACE::XCoherentFileSetmap::iterator i = xcm.begin();
244 std::cout << "Position : ";
245 std::cout << "[" << (*i).first << "]" << std::endl;
247 s->OrderFileList((*i).second); // sort the current XCoherent Fileset
249 position = position + 1.0;
250 sprintf(charPosition, "%f", position);
252 //int imageNumber = 0;
253 for ( GDCM_NAME_SPACE::FileList::iterator it = ((*i).second)->begin();
254 it != ((*i).second)->end();
258 // Set the DataElements MriRegister needs to be happy
259 // Probabely one of the following (check it !):
261 0020 0011 IS 1 Series Number
262 0020 0012 IS 1 Acquisition Number
263 0020 0013 IS 1 Instance Number
267 Sure it needs ACR-NEMA elements : Study ID 20, 10 ?
268 Image Number 20, 12 ?
269 Location ('atof-able') -> 20, 50 ?
271 (*it)->InsertEntryString(charPosition,0x0020,0x0050, "DS");
274 (*it)->InsertEntryString("0",0x0008,0x0000, "UL"); // Needs to be present (actual length doesn't matter !)
278 (*it)->InsertEntryString(str.str(),0x0020,0x0011, "IS"); // Series Number
283 (*it)->InsertEntryString(str.str(),0x0020,0x0012, "IS"); // Acquisition Number
284 (*it)->InsertEntryString(str.str(),0x0020,0x0013, "IS"); // Instance Number
287 sprintf(numero, "%04d", imageNumber);
288 (*it)->InsertEntryString(numero,0x0020,0x0012, "IS"); // Acquisition Number
289 (*it)->InsertEntryString(numero,0x0020,0x0013, "IS"); // Instance Number
291 // Load the pixels in RAM.
293 fh = GDCM_NAME_SPACE::FileHelper::New(*it);
294 uint8_t *imageData = fh->GetImageDataRaw(); // Don't convert (Gray Pixels + LUT) into (RGB pixels) ?!?
296 std::cout << "fail to read [" << (*it)->GetFileName() << std::endl;
297 fh->SetWriteTypeToAcr();
298 fh->SetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE);
300 // forge the file name
302 fullFilename = (*it)->GetFileName();
303 lastFilename = GDCM_NAME_SPACE::Util::GetName( fullFilename );
304 //fullWriteFilename = strDirNameout + GDCM_NAME_SPACE::GDCM_FILESEPARATOR
306 sprintf(fullWriteFilename, "%s%c%04d-%04d-%04d.dcm",
307 dirOut, GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
308 serieNumber, sliceNumber, imageNumber);
312 // show [sliceLocation 0x0020,1041 (if any)] old name, -> newname
313 std::string strSliceLocation;
315 GDCM_NAME_SPACE::DataEntry e = (*it)->GetDataEntry(0x0020,0x1041);
317 strSliceLocation = e->GetString();
319 strSliceLocation = "";
321 strSliceLocation = (*it)->GetDataEntry(0x0020,0x1041)->GetString();
322 std::cout <<strSliceLocation << ": " << fullFilename << " -> " << fullWriteFilename << std::endl;
326 fh->SetWriteTypeToAcrLibido();
328 if (!fh->Write(fullWriteFilename))
330 std::cout << "Fail to write :[" << fullWriteFilename << "]"
334 ///\todo FIXME segfaults if uncommented ?!?
335 // delete(imageData);
342 std::cout << std::endl;
347 l = s->GetNextSingleSerieUIDFileSet();