1 /*=========================================================================
4 Module: $RCSfile: Dense2007ToDicom.cxx,v $
6 Date: $Date: 2007/10/15 13:55:35 $
7 Version: $Revision: 1.3 $
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 =========================================================================*/
24 #include "gdcmFileHelper.h"
25 #include "gdcmDebug.h"
26 #include "gdcmDirList.h"
28 #include "gdcmArgMgr.h"
32 * Converts the "Dense" ".txt" (2007 version) files into 16 bits Dicom Files,
33 * Hope they don't change soon!
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);
43 int main(int argc, char *argv[])
46 " \n Dense2007ToDicom :\n ",
47 " Converts the '.txt' files into 16 bits Dicom Files, ",
49 " Dense2007ToDicom strain=...strain.txt peak_strain=...peak_strain.txt ",
50 " [verbose] [debug] ",
52 " verbose : user wants to run the program in 'verbose mode' ",
53 " debug : *developer* wants to run the program in 'debug mode' ",
56 // ----- Initialize Arguments Manager ------
58 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
60 if (argc == 1 || am->ArgMgrDefined("usage"))
62 am->ArgMgrUsage(usage); // Display 'usage'
67 const char *strain = am->ArgMgrWantString("strain",usage);
68 const char *peak_strain = am->ArgMgrWantString("peak_strain",usage);
70 if (am->ArgMgrDefined("debug"))
71 GDCM_NAME_SPACE::Debug::DebugOn();
73 verbose = am->ArgMgrDefined("verbose");
75 // if unused Param we give up
76 if ( am->ArgMgrPrintUnusedLabels() )
78 am->ArgMgrUsage(usage);
82 delete am; // we don't need Argument Manager any longer
84 // ----- Begin Processing -----
87 std::ifstream fromPeakStrain( peak_strain );
88 if ( !fromPeakStrain )
90 std::cout << "Can't open file" << peak_strain << std::endl;
94 std::ifstream fromStrain( strain );
97 std::cout << "Can't open file" << strain << std::endl;
101 std::cout << "Success in open file" << peak_strain << std::endl;
102 LoadPeakStrain(fromPeakStrain, peak_strain);
103 fromPeakStrain.close();
105 std::cout << "Success in open file" << strain << std::endl;
106 LoadStrain(fromStrain, strain);
111 // =====================================================================================================================
113 void LoadPeakStrain(std::ifstream &from, std::string textFileName)
115 // in sax_base_slice0_peak_strain.txt :
118 Number of material points (NP) = 181
119 Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.3243 3.19392
121 Readout direction in 3D = -0.162314 -0.0771294 -0.983720
122 Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
123 Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
124 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
125 followed by their peak Ecc strain, an array of NP elements,
126 followed by their peak Err strain, an array of NP elements,
127 followed by their peak E11 strain, an array of NP elements,
128 followed by their Peak E22 strain, an array of NP elements,
129 42.0000 10.0000 0.000000
131 -0.154905 -0.0840482 -0.157350 -0.221403 -0.168118 -0.131331
132 -0.153781 -0.148481 -0.166602 -0.232858 -0.222650 -0.213712
142 //Number of material points (NP) = 181
151 std::cout << "NP : " << NP << std::endl;
153 //Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.3243 3.19392 88.2381
166 float readout, phase_enc, slice_sel;
170 std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
172 // Readout direction in 3D = -0.162314 -0.0771294 -0.983720
180 float readoutX, readoutY, readoutZ;
184 std::cout << " readoutX " << readoutX << " readoutY " << readoutY << " readoutZ " << readoutZ << std::endl;
186 // Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
195 float phase_encX, phase_encY, phase_encZ;
199 std::cout << " phase_encX " << phase_encX << " phase_encY " << phase_encY << " phase_encZ " << phase_encZ << std::endl;
201 // Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
209 float slice_selX, slice_selY, slice_selZ;
213 std::cout << " slice_selX " << slice_selX << " slice_selY " << slice_selY << " slice_selZ " << slice_selZ << std::endl;
219 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
220 followed by their peak Ecc strain, an array of NP elements,
221 followed by their peak Err strain, an array of NP elements,
222 followed by their peak E11 strain, an array of NP elements,
223 followed by their Peak E22 strain, an array of NP elements,
226 std::cout << "------------start skipping 1 line---------------- " << std::endl;
227 std::getline(from, str1);
228 std::cout << "[" << str1 << "]" << std::endl;
229 std::cout << "------------start skipping 1 line---------------- " << std::endl;
230 std::getline(from, str1);
231 std::cout << "[" << str1 << "]" << std::endl;
232 std::cout << "------------start skipping 1 line---------------- " << std::endl;
233 std::getline(from, str1);
234 std::cout << "[" << str1 << "]" << std::endl;
235 std::cout << "------------start skipping 1 line---------------- " << std::endl;
236 std::getline(from, str1);
237 std::cout << "[" << str1 << "]" << std::endl;
238 std::cout << "------------start skipping 1 line---------------- " << std::endl;
239 std::getline(from, str1);
240 std::cout << "[" << str1 << "]" << std::endl;
241 std::cout << "------------start skipping 1 line---------------- " << std::endl;
242 std::getline(from, str1);
243 std::cout << "[" << str1 << "]" << std::endl;
244 std::cout << "------------stop skipping ---------------- " << std::endl;
246 float *X = new float[NP];
247 float *Y = new float[NP];
248 float *Z = new float[NP];
252 for (i=0; i<NP; i++) {
277 std::cout << "--------------- Ecc_strain ------------------" << std::endl;
278 float *ecc_strain = new float[NP];
279 for (i=0; i<NP; i++) {
280 from >> ecc_strain[i];
282 std::cout << ecc_strain[i] << std::endl;
285 std::cout << "--------------- Err_strain ------------------" << std::endl;
286 float *err_strain = new float[NP];
287 for (i=0; i<NP; i++) {
288 from >> err_strain[i];
290 std::cout << err_strain[i] << std::endl;
293 std::cout << "--------------- E11_strain ------------------" << std::endl;
294 float *e11_strain = new float[NP];
295 for (i=0; i<NP; i++) {
296 from >> e11_strain[i];
298 std::cout << e11_strain[i] << std::endl;
301 std::cout << "--------------- E22_strain ------------------" << std::endl;
302 float *e22_strain = new float[NP];
303 for (i=0; i<NP; i++) {
304 from >> e22_strain[i];
306 std::cout << e22_strain[i] << std::endl;
309 std::string dcmImageName;
311 //followed by their peak Ecc strain, an array of NP elements,
312 dcmImageName = textFileName + "_peak_Ecc_strain.dcm";
313 MakeDicomImage(ecc_strain, X, Y, Z, NP, dcmImageName);
315 //followed by their peak Err strain, an array of NP elements,
316 dcmImageName = textFileName + "_peak_Err_strain.dcm";
317 MakeDicomImage(err_strain, X, Y, Z, NP, dcmImageName);
319 //followed by their peak E11 strain, an array of NP elements,
320 dcmImageName = textFileName + "_peak_E11_strain.dcm";
321 MakeDicomImage(e11_strain, X, Y, Z, NP, dcmImageName);
323 //followed by their Peak E22 strain, an array of NP elements,
324 dcmImageName = textFileName + "_peak_E22_strain.dcm";
325 MakeDicomImage(e22_strain, X, Y, Z, NP, dcmImageName);
328 // =====================================================================================================================
330 void LoadStrain(std::ifstream &from, std::string textFileName)
333 // in sax_base_slice0_strain.txt :
335 Number of cine frames = 18
336 Temporal resolution = 32.0000 ms
337 First frame starts at 48.0000 ms
338 Number of material points (NP) = 181
339 Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.324341 3.193918 88.238113
340 Readout direction in 3D = -0.162314 -0.0771294 -0.983720
341 Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
342 Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
343 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
344 followed by their Ecc strain, an array of dimensions(NP, number of cine frames),
345 followed by their Err strain, an array of dimensions(NP, number of cine frames),
346 followed by their E11 strain, an array of dimensions(NP, number of cine frames),
347 followed by their E22 strain, an array of dimensions(NP, number of cine frames),
348 Note that RV Err, E11 and E22 strains are not calculated due to the small thickness.
349 42.0000 10.0000 0.000000
350 44.0000 10.0000 0.000000
352 -0.0622793 -0.0840482 -0.157350 -0.196722 -0.105844 -0.131331
353 -0.153781 -0.00940573 -0.0542236 -0.100403 -0.0369671 -0.0696840
360 int NP; // Number of Pints
361 int NCF; // Number of cine frames
362 float TR; // Temporal resolution
363 float FFS; // First frame starts
365 // Number of cine frames = 18
373 // Temporal resolution = 32.0000 ms
380 // First frame starts at 48.0000 ms
388 //Number of material points (NP) = 181
397 std::cout << "NP : " << NP << std::endl;
399 //Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.324341 3.193918 88.238113
412 float readout, phase_enc, slice_sel;
416 std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
418 // Readout direction in 3D = -0.162314 -0.0771294 -0.983720
426 float readoutX, readoutY, readoutZ;
430 std::cout << " readoutX " << readoutX << " readoutY " << readoutY << " readoutZ " << readoutZ << std::endl;
432 // Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
441 float phase_encX, phase_encY, phase_encZ;
445 std::cout << " phase_encX " << phase_encX << " phase_encY " << phase_encY << " phase_encZ " << phase_encZ << std::endl;
447 // Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
455 float slice_selX, slice_selY, slice_selZ;
459 std::cout << " slice_selX " << slice_selX << " slice_selY " << slice_selY << " slice_selZ " << slice_selZ << std::endl;
465 The following are the (readout, phase enc, slice sel) coordinates (mm) of the grid points for which strains are calculated,
466 followed by their Ecc strain, an array of dimensions(NP, number of cine frames),
467 followed by their Err strain, an array of dimensions(NP, number of cine frames),
468 followed by their E11 strain, an array of dimensions(NP, number of cine frames),
469 followed by their E22 strain, an array of dimensions(NP, number of cine frames),
470 Note that RV Err, E11 and E22 strains are not calculated due to the small thickness.
472 std::cout << "------------start skipping 1 line---------------- " << std::endl;
473 std::getline(from, str1);
474 std::cout << "[" << str1 << "]" << std::endl;
475 std::cout << "------------start skipping 1 line---------------- " << std::endl;
476 std::getline(from, str1);
477 std::cout << "[" << str1 << "]" << std::endl;
478 std::cout << "------------start skipping 1 line---------------- " << std::endl;
479 std::getline(from, str1);
480 std::cout << "[" << str1 << "]" << std::endl;
481 std::cout << "------------start skipping 1 line---------------- " << std::endl;
482 std::getline(from, str1);
483 std::cout << "[" << str1 << "]" << std::endl;
484 std::cout << "------------start skipping 1 line---------------- " << std::endl;
485 std::getline(from, str1);
486 std::cout << "[" << str1 << "]" << std::endl;
487 std::cout << "------------start skipping 1 line---------------- " << std::endl;
488 std::getline(from, str1);
489 std::cout << "[" << str1 << "]" << std::endl;
490 std::cout << "------------stop skipping ---------------- " << std::endl;
491 std::getline(from, str1);
492 std::cout << "[" << str1 << "]" << std::endl;
493 std::cout << "------------stop skipping ---------------- " << std::endl;
495 float *X = new float[NP];
496 float *Y = new float[NP];
497 float *Z = new float[NP];
501 for (i=0; i<NP; i++) {
524 std::cout << "--------------- Ecc_strain ------------------" << std::endl;
525 float *ecc_strain = new float[NP];
526 for (i=0; i<NP; i++) {
527 from >> ecc_strain[i];
529 std::cout << ecc_strain[i] << std::endl;
532 std::cout << "--------------- Err_strain ------------------" << std::endl;
533 float *err_strain = new float[NP];
534 for (i=0; i<NP; i++) {
535 from >> err_strain[i];
537 std::cout << err_strain[i] << std::endl;
540 std::cout << "--------------- E11_strain ------------------" << std::endl;
541 float *e11_strain = new float[NP];
542 for (i=0; i<NP; i++) {
543 from >> e11_strain[i];
545 std::cout << e11_strain[i] << std::endl;
548 std::cout << "--------------- E22_strain ------------------" << std::endl;
549 float *e22_strain = new float[NP];
550 for (i=0; i<NP; i++) {
551 from >> e22_strain[i];
553 std::cout << e22_strain[i] << std::endl;
556 std::string dcmImageName;
558 //followed by their Ecc strain, an array of NP elements,
559 dcmImageName = textFileName + "_Ecc_strain.dcm";
560 MakeDicomImage(ecc_strain, X, Y, Z, NP, dcmImageName);
562 //followed by their Err strain, an array of NP elements,
563 dcmImageName = textFileName + "_Err_strain.dcm";
564 MakeDicomImage(err_strain, X, Y, Z, NP, dcmImageName);
566 //followed by their E11 strain, an array of NP elements,
567 dcmImageName = textFileName + "_E11_strain.dcm";
568 MakeDicomImage(e11_strain, X, Y, Z, NP, dcmImageName);
570 //followed by their E22 strain, an array of NP elements,
571 dcmImageName = textFileName + "_E22_strain.dcm";
572 MakeDicomImage(e22_strain, X, Y, Z, NP, dcmImageName);
577 // =====================================================================================================================
580 void MakeDicomImage(float *tabVal, float *X, float *Y, float *Z, int NP, std::string dcmImageName)
582 float minX = 99999., minY = 99999., minZ = 99999.;
583 float maxX = 0., maxY = 0., maxZ = 0.;
586 for (i=0; i<NP; i++) {
587 // std::cout << X[i] << " " << Y[i] << " " << Z[i] << std::endl;
602 std::cout << "Min X,Y,Z " << minX << " " << minY << " " << minZ << std::endl;
603 std::cout << "Max X,Y,Z " << maxX << " " << maxY << " " << maxZ << std::endl;
604 std::cout << "Size X,Y,Z " << maxX-minX << " " << maxY-minY << " " << maxZ-minZ << std::endl;
606 uint16_t *img = new uint16_t[int(maxX)*int(maxY)];
608 // Set whole image to 0
609 for(int i3=0;i3<int(maxX)*int(maxY);i3++)
612 for(int i2=0; i2<NP; i2++) {
613 img[ int(maxX) -int(X[i2]-1) + (int(maxY) -int(Y[i2]))* int(maxX) ] = int(tabVal[i2]*100);
616 // GDCM_NAME_SPACE::Debug::DebugOn();
618 std::ostringstream str;
620 GDCM_NAME_SPACE::File *file;
621 file = GDCM_NAME_SPACE::File::New();
623 // Set the image size
626 file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
629 file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
631 // Set the pixel type
633 file->InsertEntryString("16",0x0028,0x0100,"US"); // Bits Allocated
635 str << 16; // may be 12 or 16 if componentSize =16
636 file->InsertEntryString("16",0x0028,0x0101,"US"); // Bits Stored
637 file->InsertEntryString("15",0x0028,0x0102,"US"); // High Bit
639 // Set the pixel representation // 0/1 , 0=unsigned
640 file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
641 // Set the samples per pixel // 1:Grey level, 3:RGB
642 file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
645 // Set Rescale Intercept
648 file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
653 file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
656 GDCM_NAME_SPACE::FileHelper *fileH;
657 fileH = GDCM_NAME_SPACE::FileHelper::New(file);
658 // cast is just to avoid warnings (*no* conversion)
659 //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!
660 fileH->SetImageData((uint8_t *)img,int(maxX)*int(maxY)*sizeof(uint16_t));
661 fileH->SetWriteModeToRaw();
662 fileH->SetWriteTypeToDcmExplVR();
664 if( !fileH->Write(dcmImageName))
665 std::cout << "Failed for [" << dcmImageName << "]\n"
666 << " File is unwrittable" << std::endl;