1 /*=========================================================================
4 Module: $RCSfile: AnonymizeMultiPatient.cxx,v $
6 Date: $Date: 2007/05/23 14:18:04 $
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 =========================================================================*/
18 #include "gdcmDocEntry.h"
19 #include "gdcmDicomDir.h"
20 #include "gdcmDicomDirPatient.h"
21 #include "gdcmDicomDirStudy.h"
22 #include "gdcmDicomDirVisit.h"
23 #include "gdcmDicomDirSerie.h"
24 #include "gdcmDicomDirImage.h"
25 #include "gdcmDirList.h"
26 #include "gdcmDebug.h"
29 #include "gdcmFileHelper.h"
31 #include "gdcmArgMgr.h"
36 * \brief Explores recursively the given directory
37 * orders the gdcm-readable found Files
38 * according their Patient/Study/Serie/Image characteristics
39 * and anomymizes (NoLoad) them, creates a different name for each Patient.
42 int main(int argc, char *argv[])
45 " \n AnonymizeMultiPatient :\n ",
46 " AnonymizeMultiPatient a full gdcm-readable Dicom image ",
47 " Warning : the image is OVERWRITTEN ",
48 " to preserve image integrity, use a copy. ",
49 " usage: AnonymizeMultiPatient dirin=inputDirectoryName ",
50 " listOfElementsToRubOut : group-elem,g2-e2,... (in hexa, no space) ",
51 " of extra Elements to rub out ",
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 : user wants to run the program in 'debug mode' ",
61 // ----- Initialize Arguments Manager ------
62 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
64 if (argc == 1 || am->ArgMgrDefined("usage"))
66 am->ArgMgrUsage(usage); // Display 'usage'
70 const char * name = am->ArgMgrGetString("dirin");
77 std::string dirName = name;
79 int verbose = am->ArgMgrDefined("verbose");
81 if (am->ArgMgrDefined("debug"))
82 GDCM_NAME_SPACE::Debug::DebugOn();
84 int loadMode = GDCM_NAME_SPACE::LD_ALL;
86 if ( am->ArgMgrDefined("noshadowseq") )
87 loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ;
90 if ( am->ArgMgrDefined("noshadow") )
91 loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW;
92 if ( am->ArgMgrDefined("noseq") )
93 loadMode |= GDCM_NAME_SPACE::LD_NOSEQ;
98 uint16_t *elemsToRubOut = am->ArgMgrGetXInt16Enum("rubout", &rubOutNb);
100 // ----------- if unused Param we give up
101 if ( am->ArgMgrPrintUnusedLabels() )
103 am->ArgMgrUsage(usage);
108 delete am; // we don't need Argument Manager any longer
111 // ----------------------------------------------------------
114 // ----- Begin Processing -----
116 GDCM_NAME_SPACE::DicomDir *dcmdir;
118 // we ask for Directory parsing
120 dcmdir = GDCM_NAME_SPACE::DicomDir::New( );
121 dcmdir->SetLoadMode(loadMode);
122 dcmdir->SetDirectoryName(dirName);
126 std::cout << "======================= End Parsing Directory" << std::endl;
128 // ----- Check the result
130 if ( !dcmdir->GetFirstPatient() )
132 std::cout << "No patient found (?!?). Exiting."
138 GDCM_NAME_SPACE::DicomDirPatient *pa;
139 GDCM_NAME_SPACE::DicomDirStudy *st;
140 GDCM_NAME_SPACE::DicomDirSerie *se;
141 GDCM_NAME_SPACE::DicomDirImage *im;
143 std::string codedName;
144 std::string fullFileName;
147 GDCM_NAME_SPACE::File *f;
149 pa = dcmdir->GetFirstPatient();
151 { // on degouline les PATIENT du DICOMDIR
152 patName = pa->GetEntryString(0x0010, 0x0010);
153 codedName = "g^" + GDCM_NAME_SPACE::Util::ConvertToMD5(patName);
155 std::cout << patName << " --> " << codedName << std::endl;
156 st = pa->GetFirstStudy();
158 { // on degouline les STUDY de ce patient
159 se = st->GetFirstSerie();
161 { // on degouline les SERIES de cette study
162 im = se->GetFirstImage();
164 { // on degouline les Images de cette serie
165 fullFileName = dirName;
166 fullFileName += GDCM_NAME_SPACE::GDCM_FILESEPARATOR;
167 fullFileName += im->GetEntryString(0x0004, 0x1500);
169 std::cout << "FileName " << fullFileName << std::endl;
171 f = GDCM_NAME_SPACE::File::New( );
172 f->SetLoadMode(loadMode);
173 f->SetFileName( fullFileName );
175 std::cout << "Load failed for [" << fullFileName << "]" << std::endl;
178 std::cout << "Load successed for [" << fullFileName << "]" << std::endl;
181 // Choose the fields to anonymize.
185 f->AddAnonymizeElement( 0x0008, 0x0080, "Xanadoo" );
188 f->AddAnonymizeElement( 0x0010, 0x0010, codedName );
191 f->AddAnonymizeElement( 0x0010, 0x0020,"1515" );
192 // Patient's Birthdate
193 f->AddAnonymizeElement( 0x0010, 0x0030,"11111111" );
195 f->AddAnonymizeElement( 0x0010, 0x1040,"Sing-sing" );
196 // Patient's Mother's Birth Name
197 f->AddAnonymizeElement( 0x0010, 0x1060,"g^Vampirella" );
199 // Study Instance UID
200 // we may not brutaly overwrite it
201 //f->AddAnonymizeElement( 0x0020, 0x000d, "9.99.999.9999" );
204 f->AddAnonymizeElement(0x0010, 0x2154, "3615" );
206 // deal with user defined Elements set
208 for (int ri=0; ri<rubOutNb; ri++)
210 f->AddAnonymizeElement((uint32_t)elemsToRubOut[2*ri],
211 (uint32_t)elemsToRubOut[2*ri+1],"*" );
215 // Overwrite the file
217 // The GDCM_NAME_SPACE::File remains untouched in memory
219 f->AnonymizeNoLoad();
221 f->ClearAnonymizeList();
224 im = se->GetNextImage();
226 se = st->GetNextSerie();
228 st = pa->GetNextStudy();
230 pa = dcmdir->GetNextPatient();