]> Creatis software - gdcm.git/blob - Example/AnonymizeMultiPatient.cxx
ENH: apply dos2unix
[gdcm.git] / Example / AnonymizeMultiPatient.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: AnonymizeMultiPatient.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/11/13 11:49:09 $
7   Version:   $Revision: 1.7 $
8                                                                                 
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.
12                                                                                 
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.
16                                                                                 
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"
27 #include "gdcmUtil.h"
28 #include "gdcmFile.h"
29 #include "gdcmFileHelper.h"
30
31 #include "gdcmArgMgr.h"
32
33 #include <iostream>
34
35 /**
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.
40   */  
41
42 int main(int argc, char *argv[]) 
43 {
44    START_USAGE(usage)
45    " \n AnonymizeMultiPatient :\n                                             ",
46    " AnonymizeMultiPatient a full gdcm-readable Dicom image                   ",
47    "         optionnaly, creates the DICOMDIR                                 ",
48    "         Warning : the image is OVERWRITTEN                               ",
49    "                   to preserve image integrity, use a copy.               ",
50    " usage: AnonymizeMultiPatient dirin=inputDirectoryName  dicomdir          ",
51    "       listOfElementsToRubOut : group-elem,g2-e2,... (in hexa, no space)  ",
52    "                                of extra Elements to rub out              ",
53    "       dicomdir   : user wants to generate a DICOMDIR                     ",
54    "       noshadowseq: user doesn't want to load Private Sequences           ",
55    "       noshadow   : user doesn't want to load Private groups (odd number) ",
56    "       noseq      : user doesn't want to load Sequences                   ",
57    "       verbose    : user wants to run the program in 'verbose mode'       ",   
58    "       debug      : user wants to run the program in 'debug mode'         ",   
59    FINISH_USAGE
60    
61
62
63    // ----- Initialize Arguments Manager ------   
64    GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
65   
66    if (argc == 1 || am->ArgMgrDefined("usage")) 
67    {
68       am->ArgMgrUsage(usage); // Display 'usage'
69       delete am;
70       return 0;
71    }
72    const char * name  = am->ArgMgrGetString("dirin");
73    if ( name == NULL )
74    {
75       delete am;
76       return 0;
77    }
78    
79    std::string dirName = name;
80    
81    bool verbose  = ( 0 != am->ArgMgrDefined("verbose") ); 
82    bool dicomdir = ( 0 != am->ArgMgrDefined("dicomdir") );
83    
84    if (am->ArgMgrDefined("debug"))
85       GDCM_NAME_SPACE::Debug::DebugOn();
86
87    int loadMode = GDCM_NAME_SPACE::LD_ALL;
88  
89    if ( am->ArgMgrDefined("noshadowseq") )
90       loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ;
91    else 
92    {
93       if ( am->ArgMgrDefined("noshadow") )
94          loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW;
95       if ( am->ArgMgrDefined("noseq") )
96          loadMode |= GDCM_NAME_SPACE::LD_NOSEQ;
97    }
98
99
100    int rubOutNb;
101    uint16_t *elemsToRubOut = am->ArgMgrGetXInt16Enum("rubout", &rubOutNb);
102  
103    // ----------- if unused Param we give up
104    if ( am->ArgMgrPrintUnusedLabels() )
105    { 
106       am->ArgMgrUsage(usage);
107       delete am;
108       return 0;
109    }
110
111    delete am;  // we don't need Argument Manager any longer
112
113  
114   // ---------------------------------------------------------- 
115   
116
117    // ----- Begin Processing -----
118
119    GDCM_NAME_SPACE::DicomDir *dcmdir;
120
121    // we ask for Directory parsing
122
123    dcmdir = GDCM_NAME_SPACE::DicomDir::New( );
124    dcmdir->SetLoadMode(loadMode);
125    dcmdir->SetDirectoryName(dirName);
126    dcmdir->Load();
127
128    if ( verbose )
129       std::cout << "======================= End Parsing Directory" << std::endl;
130       
131     // ----- Check the result
132     
133    if ( !dcmdir->GetFirstPatient() ) 
134    {
135       std::cout << "No patient found (?!?). Exiting."
136                 << std::endl;
137       dcmdir->Delete();
138       return 1;
139    }
140
141    GDCM_NAME_SPACE::DicomDirPatient *pa;
142    GDCM_NAME_SPACE::DicomDirStudy *st;
143    GDCM_NAME_SPACE::DicomDirSerie *se;
144    GDCM_NAME_SPACE::DicomDirImage *im;
145
146    std::string codedName;
147    std::string codedID;
148    std::string fullFileName;
149    std::string patName;
150    std::string patID;
151         
152    GDCM_NAME_SPACE::File *f;
153   
154    pa = dcmdir->GetFirstPatient(); 
155    while ( pa )
156    {  // on degouline les PATIENT du DICOMDIR
157       patName = pa->GetEntryString(0x0010, 0x0010);
158       codedName = "g^" + GDCM_NAME_SPACE::Util::ConvertToMD5(patName);
159       patID = pa->GetEntryString(0x0010, 0x0020);
160       codedID = GDCM_NAME_SPACE::Util::ConvertToMD5(patID);
161       
162       if (verbose) {
163          std::cout << "[" << patName << "] --> [" << codedName << "]" << std::endl;
164          std::cout << "[" << patID   << "] --> [" << codedID   << "]"  << std::endl;                 
165       } 
166       st = pa->GetFirstStudy();
167       while ( st ) 
168       { // on degouline les STUDY de ce patient
169          se = st->GetFirstSerie();
170          while ( se ) 
171          { // on degouline les SERIES de cette study
172             im = se->GetFirstImage();
173             while ( im ) 
174             { // on degouline les Images de cette serie       
175                fullFileName = dirName;
176                fullFileName +=  GDCM_NAME_SPACE::GDCM_FILESEPARATOR;
177                fullFileName += im->GetEntryString(0x0004, 0x1500);
178                if (verbose)
179                   std::cout << "FileName " << fullFileName << std::endl;
180
181                f = GDCM_NAME_SPACE::File::New( );
182                f->SetLoadMode(loadMode);
183                f->SetFileName( fullFileName );
184                if ( !f->Load() )
185                  std::cout << "Load failed for [" << fullFileName << "]" << std::endl; 
186                else
187                   if (verbose)
188                      std::cout << "Load successed for [" << fullFileName << "]" << std::endl;
189
190                // 
191                //  Choose the fields to anonymize.
192                // 
193
194                // Institution name 
195                f->AddAnonymizeElement( 0x0008, 0x0080, "Xanadoo" );
196
197                // Patient's name 
198                f->AddAnonymizeElement( 0x0010, 0x0010, codedName ); 
199     
200                // Patient's ID
201                //f->AddAnonymizeElement( 0x0010, 0x0020,"1515" );
202                f->AddAnonymizeElement( 0x0010, 0x0020,codedID );
203                // Patient's Birthdate
204                f->AddAnonymizeElement( 0x0010, 0x0030,"11111111" );
205                // Patient's Adress
206                f->AddAnonymizeElement( 0x0010, 0x1040,"Sing-sing" );
207                // Patient's Mother's Birth Name
208                f->AddAnonymizeElement( 0x0010, 0x1060,"g^Vampirella" );
209        
210                // Study Instance UID
211                // we may not brutaly overwrite it
212                //f->AddAnonymizeElement( 0x0020, 0x000d, "9.99.999.9999" );
213    
214                // Telephone
215                f->AddAnonymizeElement(0x0010, 0x2154, "3615" );
216
217                // deal with user defined Elements set
218
219                for (int ri=0; ri<rubOutNb; ri++)
220                {
221                   f->AddAnonymizeElement((uint32_t)elemsToRubOut[2*ri], 
222                                          (uint32_t)elemsToRubOut[2*ri+1],"*" ); 
223                }
224
225               // 
226               //      Overwrite the file
227               // 
228               // The GDCM_NAME_SPACE::File remains untouched in memory    
229    
230               f->AnonymizeNoLoad();     
231
232               f->ClearAnonymizeList();
233               f->Delete();
234  
235               im = se->GetNextImage();   
236            }
237            se = st->GetNextSerie();   
238         }
239         st = pa->GetNextStudy();
240      }     
241      pa = dcmdir->GetNextPatient();    
242    }
243
244    dcmdir->Delete();
245    
246    if (dicomdir)
247    {
248       std::cout << "DICOMDIR creation in progress ..." << std::endl;      
249       dcmdir = GDCM_NAME_SPACE::DicomDir::New( );
250       dcmdir->SetLoadMode(loadMode);
251       dcmdir->SetDirectoryName(dirName);
252       dcmdir->Load();
253       dcmdir->Write("DICOMDIR");   
254    }
255              
256    return 0;
257    
258 }