]> Creatis software - gdcm.git/blob - Example/Dense2007ToDicom.cxx
Avoid warning
[gdcm.git] / Example / Dense2007ToDicom.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: Dense2007ToDicom.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/09/18 10:54:23 $
7   Version:   $Revision: 1.2 $
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
19 #include <fstream>
20 #include <iostream>
21 //#include <values.h>
22
23 #include "gdcmFile.h"
24 #include "gdcmFileHelper.h"
25 #include "gdcmDebug.h"
26 #include "gdcmDirList.h"
27
28 #include "gdcmArgMgr.h"
29
30 /**
31   * \brief   
32   *  Converts the "Dense" ".txt" (2007 version)  files into 16 bits Dicom Files,
33   * Hope they don't change soon!
34   */  
35
36
37 void LoadPeakStrain(std::ifstream &from, std::string imageName);
38 void LoadStrain(std::ifstream &from, std::string imageName);
39 void MakeDicomImage(float *tabVal, float *X, float *Y, float *Z, int NP, std::string dcmImageName);
40
41
42 int main(int argc, char *argv[])
43 {
44    START_USAGE(usage)
45    " \n Dense2007ToDicom :\n                                                  ",
46    "        Converts the '.txt' files into 16 bits Dicom Files,               ",
47    " usage:                                                                   ",
48    " Dense2007ToDicom strain=...strain.txt  peak_strain=...peak_strain.txt    ",
49    "                 [verbose] [debug]                                        ",
50    "                                                                          ",
51    " verbose  : user wants to run the program in 'verbose mode'               ",
52    " debug    : *developer*  wants to run the program in 'debug mode'         ",
53    FINISH_USAGE
54
55    // ----- Initialize Arguments Manager ------
56       
57    GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
58   
59    if (argc == 1 || am->ArgMgrDefined("usage")) 
60    {
61       am->ArgMgrUsage(usage); // Display 'usage'
62       delete am;
63       return 0;
64    }
65
66    const char *strain      = am->ArgMgrWantString("strain",usage);
67    const char *peak_strain = am->ArgMgrWantString("peak_strain",usage);
68    
69    if (am->ArgMgrDefined("debug"))
70       GDCM_NAME_SPACE::Debug::DebugOn();
71
72    int verbose  = am->ArgMgrDefined("verbose");      
73
74    // if unused Param we give up
75    if ( am->ArgMgrPrintUnusedLabels() )
76    { 
77       am->ArgMgrUsage(usage);
78       delete am;
79       return 0;
80    }
81    delete am;  // we don't need Argument Manager any longer
82
83    // ----- Begin Processing -----
84
85
86    std::ifstream fromPeakStrain( peak_strain );             
87    if ( !fromPeakStrain )
88    {
89       std::cout << "Can't open file" << peak_strain << std::endl;
90       exit(0);
91    }
92
93    std::ifstream fromStrain( strain );      
94    if ( !fromStrain )
95    {
96       std::cout << "Can't open file" << strain << std::endl;
97       exit(0);
98    }  
99        
100    std::cout << "Success in open file" << peak_strain << std::endl;
101    LoadPeakStrain(fromPeakStrain, peak_strain);
102    fromPeakStrain.close();  
103
104    std::cout << "Success in open file" << strain << std::endl;
105    LoadStrain(fromStrain, strain);
106    fromStrain.close();      
107    return 1;            
108 }
109
110 // =====================================================================================================================
111
112 void LoadPeakStrain(std::ifstream &from, std::string textFileName)
113 {
114 // in sax_base_slice0_peak_strain.txt :
115
116 /*
117 Number of material points (NP) = 181
118 Origin of (readout, phase enc, slice sel) coordinates in 3D =  87.3243 3.19392
119 88.2381
120 Readout direction in 3D =  -0.162314 -0.0771294 -0.983720
121 Phase Enc. direction in 3D =  -0.540606 -0.827052 0.154046
122 Slice select direction in 3D =  0.825469 -0.556809 -0.0925458
123 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
124 followed by their peak Ecc strain, an array of NP elements,
125 followed by their peak Err strain, an array of NP elements,
126 followed by their peak E11 strain, an array of NP elements,
127 followed by their Peak E22 strain, an array of NP elements,
128       42.0000      10.0000     0.000000
129       ...
130     -0.154905   -0.0840482    -0.157350    -0.221403    -0.168118    -0.131331
131     -0.153781    -0.148481    -0.166602    -0.232858    -0.222650    -0.213712
132     ...
133 */  
134
135    if (!from)
136       return;
137
138    std::string str1;
139    int NP;
140
141    //Number of material points (NP) = 181   
142     from >> str1;
143     from >> str1;
144     from >> str1;
145     from >> str1;
146     from >> str1;
147     from >> str1;
148     from >> NP;
149     
150     std::cout << "NP : " << NP << std::endl; 
151
152    //Origin of (readout, phase enc, slice sel) coordinates in 3D =  87.3243 3.19392 88.2381
153      from >> str1;
154      from >> str1;
155      from >> str1;
156      from >> str1;
157      from >> str1;
158      from >> str1;
159      from >> str1;
160      from >> str1;
161      from >> str1;
162      from >> str1;
163      from >> str1;
164      
165      float readout,  phase_enc, slice_sel;
166      from >> readout;
167      from >> phase_enc;
168      from >> slice_sel;
169      std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
170      
171     // Readout direction in 3D =  -0.162314 -0.0771294 -0.983720
172     
173     from >> str1;
174     from >> str1;
175     from >> str1;
176     from >> str1;
177     from >> str1;
178     
179     float readoutX, readoutY, readoutZ;
180     from >> readoutX;
181     from >> readoutY;       
182     from >> readoutZ;
183     std::cout << " readoutX " << readoutX <<  " readoutY " << readoutY <<  " readoutZ " << readoutZ << std::endl;
184      
185 // Phase Enc. direction in 3D =  -0.540606 -0.827052 0.154046
186
187      from >> str1;
188      from >> str1;
189      from >> str1;
190      from >> str1;
191      from >> str1;
192      from >> str1;
193      
194     float phase_encX, phase_encY, phase_encZ;
195     from >> phase_encX;
196     from >> phase_encY;       
197     from >> phase_encZ;
198     std::cout << " phase_encX " << phase_encX <<  " phase_encY " << phase_encY <<  " phase_encZ " << phase_encZ << std::endl; 
199
200 // Slice select direction in 3D =  0.825469 -0.556809 -0.0925458
201      from >> str1;
202      from >> str1;
203      from >> str1;
204      from >> str1;
205      from >> str1;
206      from >> str1;
207      
208     float slice_selX, slice_selY, slice_selZ;
209     from >> slice_selX;
210     from >> slice_selY;       
211     from >> slice_selZ;
212     std::cout << " slice_selX " << slice_selX <<  " slice_selY " << slice_selY <<  " slice_selZ " << slice_selZ << std::endl; 
213
214
215
216 // Skip 5 lines :
217 /*
218 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
219 followed by their peak Ecc strain, an array of NP elements,
220 followed by their peak Err strain, an array of NP elements,
221 followed by their peak E11 strain, an array of NP elements,
222 followed by their Peak E22 strain, an array of NP elements,
223 */
224
225 std::cout << "------------start skipping 1 line---------------- " << std::endl;
226    std::getline(from, str1);
227    std::cout << "[" << str1 << "]" << std::endl;
228 std::cout << "------------start skipping 1 line---------------- " << std::endl;
229    std::getline(from, str1);
230    std::cout << "[" << str1 << "]" << std::endl;
231 std::cout << "------------start skipping 1 line---------------- " << std::endl;
232    std::getline(from, str1);
233    std::cout << "[" << str1 << "]" << std::endl;
234 std::cout << "------------start skipping 1 line---------------- " << std::endl;
235    std::getline(from, str1);
236    std::cout << "[" << str1 << "]" << std::endl;
237 std::cout << "------------start skipping 1 line---------------- " << std::endl;
238    std::getline(from, str1);
239    std::cout << "[" << str1 << "]" << std::endl;
240 std::cout << "------------start skipping 1 line---------------- " << std::endl;
241    std::getline(from, str1);
242    std::cout << "[" << str1 << "]" << std::endl;
243 std::cout << "------------stop skipping ---------------- " << std::endl;
244   
245    float *X = new float[NP];
246    float *Y = new float[NP];   
247    float *Z = new float[NP];
248       
249    char c;
250    int i;   
251    for (i=0; i<NP; i++) {   
252       from >> X[i];
253       for (;;) {
254         if (!from.get(c))
255           break;
256         if (!isspace(c)) {
257           from.putback(c);
258           break;
259         }
260      }  
261       from >> Y[i];    
262       for (;;) {
263         if (!from.get(c))
264           break;
265         if (!isspace(c)) {
266           from.putback(c);
267           break;
268         }
269      }        
270       from >> Z[i];              
271    }
272
273    std::cout << "--------------- Ecc_strain ------------------" << std::endl;
274    float *ecc_strain = new float[NP];
275    for (i=0; i<NP; i++) {
276        from >> ecc_strain[i]; 
277        std::cout <<  ecc_strain[i] <<  std::endl;
278    }
279
280    std::cout << "--------------- Err_strain ------------------" << std::endl;
281    float *err_strain = new float[NP];
282    for (i=0; i<NP; i++) {
283        from >> err_strain[i]; 
284        std::cout <<  err_strain[i] <<  std::endl;
285    }
286    
287    std::cout << "--------------- E11_strain ------------------" << std::endl;
288    float *e11_strain = new float[NP];
289    for (i=0; i<NP; i++) {
290        from >> e11_strain[i]; 
291        std::cout <<  e11_strain[i] <<  std::endl;
292    }  
293    
294    std::cout << "--------------- E22_strain ------------------" << std::endl;
295    float *e22_strain = new float[NP];
296    for (i=0; i<NP; i++) {
297        from >> e22_strain[i]; 
298        std::cout <<  e22_strain[i] <<  std::endl;
299    }    
300  
301    std::string dcmImageName;    
302
303 //followed by their peak Ecc strain, an array of NP elements,
304    dcmImageName = textFileName + "_peak_Ecc_strain.dcm";
305    MakeDicomImage(ecc_strain, X, Y, Z, NP, dcmImageName);
306
307 //followed by their peak Err strain, an array of NP elements,
308    dcmImageName = textFileName + "_peak_Err_strain.dcm";
309    MakeDicomImage(err_strain, X, Y, Z, NP, dcmImageName);
310    
311 //followed by their peak E11 strain, an array of NP elements,
312    dcmImageName = textFileName + "_peak_E11_strain.dcm";
313    MakeDicomImage(e11_strain, X, Y, Z, NP, dcmImageName);
314    
315 //followed by their Peak E22 strain, an array of NP elements,
316    dcmImageName = textFileName + "_peak_E22_strain.dcm";
317    MakeDicomImage(e22_strain, X, Y, Z, NP, dcmImageName);         
318 }
319
320 // =====================================================================================================================
321
322 void LoadStrain(std::ifstream &from, std::string textFileName)
323 {
324
325 // in sax_base_slice0_strain.txt :
326 /*
327 Number of cine frames = 18
328 Temporal resolution = 32.0000 ms
329 First frame starts at 48.0000 ms
330 Number of material points (NP) = 181
331 Origin of (readout, phase enc, slice sel) coordinates in 3D =  87.324341 3.193918 88.238113 
332 Readout direction in 3D =  -0.162314 -0.0771294 -0.983720
333 Phase Enc. direction in 3D =  -0.540606 -0.827052 0.154046
334 Slice select direction in 3D =  0.825469 -0.556809 -0.0925458
335 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
336 followed by their Ecc strain, an array of dimensions(NP, number of cine frames),
337 followed by their Err strain, an array of dimensions(NP, number of cine frames),
338 followed by their E11 strain, an array of dimensions(NP, number of cine frames),
339 followed by their E22 strain, an array of dimensions(NP, number of cine frames),
340 Note that RV Err, E11 and E22 strains are not calculated due to the small thickness.
341       42.0000      10.0000     0.000000
342       44.0000      10.0000     0.000000
343       ...
344    -0.0622793   -0.0840482    -0.157350    -0.196722    -0.105844    -0.131331
345     -0.153781  -0.00940573   -0.0542236    -0.100403   -0.0369671   -0.0696840      
346 */ 
347
348    if (!from)
349       return;
350
351    std::string str1;
352    int NP;    // Number of Pints
353    int NCF;   // Number of cine frames
354    float TR;  // Temporal resolution
355    float FFS; // First frame starts
356    
357    // Number of cine frames = 18
358     from >> str1;
359     from >> str1;
360     from >> str1;
361     from >> str1;
362     from >> str1;
363     from >> NCF;
364
365    // Temporal resolution = 32.0000 ms
366     from >> str1;
367     from >> str1;
368     from >> str1;
369     from >> TR;
370     from >> str1;
371
372    // First frame starts at 48.0000 ms
373     from >> str1;
374     from >> str1;
375     from >> str1;
376     from >> str1;
377     from >> FFS;
378     from >> str1;        
379
380    //Number of material points (NP) = 181   
381     from >> str1;
382     from >> str1;
383     from >> str1;
384     from >> str1;
385     from >> str1;
386     from >> str1;
387     from >> NP;
388     
389     std::cout << "NP : " << NP << std::endl; 
390
391    //Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.324341 3.193918 88.238113 
392      from >> str1;
393      from >> str1;
394      from >> str1;
395      from >> str1;
396      from >> str1;
397      from >> str1;
398      from >> str1;
399      from >> str1;
400      from >> str1;
401      from >> str1;
402      from >> str1;
403      
404      float readout,  phase_enc, slice_sel;
405      from >> readout;
406      from >> phase_enc;
407      from >> slice_sel;
408      std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
409      
410     // Readout direction in 3D =  -0.162314 -0.0771294 -0.983720
411     
412     from >> str1;
413     from >> str1;
414     from >> str1;
415     from >> str1;
416     from >> str1;
417     
418     float readoutX, readoutY, readoutZ;
419     from >> readoutX;
420     from >> readoutY;       
421     from >> readoutZ;
422     std::cout << " readoutX " << readoutX <<  " readoutY " << readoutY <<  " readoutZ " << readoutZ << std::endl;
423      
424 // Phase Enc. direction in 3D =  -0.540606 -0.827052 0.154046
425
426      from >> str1;
427      from >> str1;
428      from >> str1;
429      from >> str1;
430      from >> str1;
431      from >> str1;
432      
433     float phase_encX, phase_encY, phase_encZ;
434     from >> phase_encX;
435     from >> phase_encY;       
436     from >> phase_encZ;
437     std::cout << " phase_encX " << phase_encX <<  " phase_encY " << phase_encY <<  " phase_encZ " << phase_encZ << std::endl; 
438
439 // Slice select direction in 3D =  0.825469 -0.556809 -0.0925458
440      from >> str1;
441      from >> str1;
442      from >> str1;
443      from >> str1;
444      from >> str1;
445      from >> str1;
446      
447     float slice_selX, slice_selY, slice_selZ;
448     from >> slice_selX;
449     from >> slice_selY;       
450     from >> slice_selZ;
451     std::cout << " slice_selX " << slice_selX <<  " slice_selY " << slice_selY <<  " slice_selZ " << slice_selZ << std::endl; 
452
453
454
455 // Skip 6 lines :
456 /*
457 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
458 followed by their Ecc strain, an array of dimensions(NP, number of cine frames),
459 followed by their Err strain, an array of dimensions(NP, number of cine frames),
460 followed by their E11 strain, an array of dimensions(NP, number of cine frames),
461 followed by their E22 strain, an array of dimensions(NP, number of cine frames),
462 Note that RV Err, E11 and E22 strains are not calculated due to the small thickness.
463 */
464 std::cout << "------------start skipping 1 line---------------- " << std::endl;
465    std::getline(from, str1);
466    std::cout << "[" << str1 << "]" << std::endl;
467 std::cout << "------------start skipping 1 line---------------- " << std::endl;
468    std::getline(from, str1);
469    std::cout << "[" << str1 << "]" << std::endl;
470 std::cout << "------------start skipping 1 line---------------- " << std::endl;
471    std::getline(from, str1);
472    std::cout << "[" << str1 << "]" << std::endl;
473 std::cout << "------------start skipping 1 line---------------- " << std::endl;
474    std::getline(from, str1);
475    std::cout << "[" << str1 << "]" << std::endl;
476 std::cout << "------------start skipping 1 line---------------- " << std::endl;
477    std::getline(from, str1);
478    std::cout << "[" << str1 << "]" << std::endl;
479 std::cout << "------------start skipping 1 line---------------- " << std::endl;
480    std::getline(from, str1);
481    std::cout << "[" << str1 << "]" << std::endl;
482 std::cout << "------------stop skipping ---------------- " << std::endl;
483    std::getline(from, str1);
484    std::cout << "[" << str1 << "]" << std::endl;
485 std::cout << "------------stop skipping ---------------- " << std::endl;
486   
487    float *X = new float[NP];
488    float *Y = new float[NP];   
489    float *Z = new float[NP];
490       
491    char c;
492    int i;   
493    for (i=0; i<NP; i++) {
494    
495       from >> X[i];
496       for (;;) {
497         if (!from.get(c))
498           break;
499         if (!isspace(c)) {
500           from.putback(c);
501           break;
502         }
503      }  
504       from >> Y[i];  
505       for (;;) {
506         if (!from.get(c))
507           break;
508         if (!isspace(c)) {
509           from.putback(c);
510           break;
511         }
512      }        
513       from >> Z[i];              
514    }
515
516    std::cout << "--------------- Ecc_strain ------------------" << std::endl;
517    float *ecc_strain = new float[NP];
518    for (i=0; i<NP; i++) {
519        from >> ecc_strain[i]; 
520        std::cout <<  ecc_strain[i] <<  std::endl;
521    }
522
523    std::cout << "--------------- Err_strain ------------------" << std::endl;
524    float *err_strain = new float[NP];
525    for (i=0; i<NP; i++) {
526        from >> err_strain[i]; 
527        std::cout <<  err_strain[i] <<  std::endl;
528    }
529    
530    std::cout << "--------------- E11_strain ------------------" << std::endl;
531    float *e11_strain = new float[NP];
532    for (i=0; i<NP; i++) {
533        from >> e11_strain[i]; 
534        std::cout <<  e11_strain[i] <<  std::endl;
535    }  
536    
537    std::cout << "--------------- E22_strain ------------------" << std::endl;
538    float *e22_strain = new float[NP];
539    for (i=0; i<NP; i++) {
540        from >> e22_strain[i]; 
541        std::cout <<  e22_strain[i] <<  std::endl;
542    }    
543
544    std::string dcmImageName;    
545
546 //followed by their Ecc strain, an array of NP elements,
547    dcmImageName = textFileName + "_Ecc_strain.dcm";
548    MakeDicomImage(ecc_strain, X, Y, Z, NP, dcmImageName);
549
550 //followed by their  Err strain, an array of NP elements,
551    dcmImageName = textFileName + "_Err_strain.dcm";
552    MakeDicomImage(err_strain, X, Y, Z, NP, dcmImageName);
553    
554 //followed by their E11 strain, an array of NP elements,
555    dcmImageName = textFileName + "_E11_strain.dcm";
556    MakeDicomImage(e11_strain, X, Y, Z, NP, dcmImageName);
557    
558 //followed by their E22 strain, an array of NP elements,
559    dcmImageName = textFileName + "_E22_strain.dcm";
560    MakeDicomImage(e22_strain, X, Y, Z, NP, dcmImageName);   
561       
562 }
563
564
565 // =====================================================================================================================
566     
567
568 void MakeDicomImage(float *tabVal, float *X, float *Y, float *Z, int NP, std::string dcmImageName)
569 {
570    float minX = 999., minY = 999., minZ = 999.;
571    float maxX = 0., maxY = 0., maxZ = 0.;
572    int i;
573    for (i=0; i<NP; i++) {
574       // std::cout << X[i] << " " << Y[i] << " " << Z[i] <<  std::endl;
575       if(maxX < X[i])
576          maxX = X[i];
577       if(maxY < Y[i])
578          maxY = Y[i];
579       if(maxZ < Z[i])
580          maxZ = Z[i];
581  
582       if(minX > X[i])
583          minX = X[i];
584       if(minY > Y[i])
585          minY = Y[i];
586       if(minZ > Z[i])
587          minZ = Z[i];
588  
589    }   
590       std::cout << "Min X,Y,Z " << minX << " " << minY << " " << minZ <<  std::endl;
591       std::cout << "Max X,Y,Z " << maxX << " " << maxY << " " << maxZ <<  std::endl;
592       std::cout << "Size X,Y,Z " << maxX-minX << " " << maxY-minY << " " << maxZ-minZ <<  std::endl;      
593
594
595     uint16_t *img = new uint16_t[int(maxX*maxY)];
596     
597     for(int i3=0;i3<int(maxX*maxY);i3++)
598        img[i3] = 0; 
599      
600     for(int i2=0; i2<NP; i2++) {
601     img[ int(maxX -(X[i2]-1))+  int((maxY -Y[i2])* maxX) ] = int(tabVal[i2]*100);
602     }       
603   
604  // GDCM_NAME_SPACE::Debug::DebugOn();
605   
606        std::ostringstream str; 
607        GDCM_NAME_SPACE::File *file;
608        file = GDCM_NAME_SPACE::File::New();       
609               
610   // Set the image size
611         str.str("");
612         str << (int)maxX;
613         file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
614         str.str("");
615         str << (int)maxY;
616         file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
617   // Set the pixel type
618   //      16; //8, 16, 32
619         file->InsertEntryString("16",0x0028,0x0100,"US"); // Bits Allocated
620         str.str("");
621         str << 16; // may be 12 or 16 if componentSize =16
622         file->InsertEntryString("16",0x0028,0x0101,"US"); // Bits Stored
623         file->InsertEntryString("15",0x0028,0x0102,"US"); // High Bit
624
625   // Set the pixel representation // 0/1 , 0=unsigned
626         file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
627   // Set the samples per pixel // 1:Grey level, 3:RGB
628         file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
629
630 /*
631   // Set Rescale Intercept
632         str.str("");
633         str << div;  
634         file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
635
636   // Set Rescale Slope
637         str.str("");
638         str << mini;  
639         file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
640 */
641     
642     GDCM_NAME_SPACE::FileHelper *fileH;
643     fileH = GDCM_NAME_SPACE::FileHelper::New(file);
644     // cast is just to avoid warnings (*no* conversion)
645     fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t));
646     fileH->SetWriteModeToRaw(); 
647     fileH->SetWriteTypeToDcmExplVR();
648         
649     if( !fileH->Write(dcmImageName))
650        std::cout << "Failed for [" << dcmImageName << "]\n"
651                  << "           File is unwrittable" << std::endl;
652
653     file->Print();
654            
655    delete img;
656    file->Delete();
657    fileH->Delete();  
658 }