1 /*=========================================================================
4 Module: $RCSfile: Dense2007ToDicom.cxx,v $
6 Date: $Date: 2007/09/18 10:54:23 $
7 Version: $Revision: 1.2 $
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);
42 int main(int argc, char *argv[])
45 " \n Dense2007ToDicom :\n ",
46 " Converts the '.txt' files into 16 bits Dicom Files, ",
48 " Dense2007ToDicom strain=...strain.txt peak_strain=...peak_strain.txt ",
49 " [verbose] [debug] ",
51 " verbose : user wants to run the program in 'verbose mode' ",
52 " debug : *developer* wants to run the program in 'debug mode' ",
55 // ----- Initialize Arguments Manager ------
57 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
59 if (argc == 1 || am->ArgMgrDefined("usage"))
61 am->ArgMgrUsage(usage); // Display 'usage'
66 const char *strain = am->ArgMgrWantString("strain",usage);
67 const char *peak_strain = am->ArgMgrWantString("peak_strain",usage);
69 if (am->ArgMgrDefined("debug"))
70 GDCM_NAME_SPACE::Debug::DebugOn();
72 int verbose = am->ArgMgrDefined("verbose");
74 // if unused Param we give up
75 if ( am->ArgMgrPrintUnusedLabels() )
77 am->ArgMgrUsage(usage);
81 delete am; // we don't need Argument Manager any longer
83 // ----- Begin Processing -----
86 std::ifstream fromPeakStrain( peak_strain );
87 if ( !fromPeakStrain )
89 std::cout << "Can't open file" << peak_strain << std::endl;
93 std::ifstream fromStrain( strain );
96 std::cout << "Can't open file" << strain << std::endl;
100 std::cout << "Success in open file" << peak_strain << std::endl;
101 LoadPeakStrain(fromPeakStrain, peak_strain);
102 fromPeakStrain.close();
104 std::cout << "Success in open file" << strain << std::endl;
105 LoadStrain(fromStrain, strain);
110 // =====================================================================================================================
112 void LoadPeakStrain(std::ifstream &from, std::string textFileName)
114 // in sax_base_slice0_peak_strain.txt :
117 Number of material points (NP) = 181
118 Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.3243 3.19392
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
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
141 //Number of material points (NP) = 181
150 std::cout << "NP : " << NP << std::endl;
152 //Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.3243 3.19392 88.2381
165 float readout, phase_enc, slice_sel;
169 std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
171 // Readout direction in 3D = -0.162314 -0.0771294 -0.983720
179 float readoutX, readoutY, readoutZ;
183 std::cout << " readoutX " << readoutX << " readoutY " << readoutY << " readoutZ " << readoutZ << std::endl;
185 // Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
194 float phase_encX, phase_encY, phase_encZ;
198 std::cout << " phase_encX " << phase_encX << " phase_encY " << phase_encY << " phase_encZ " << phase_encZ << std::endl;
200 // Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
208 float slice_selX, slice_selY, slice_selZ;
212 std::cout << " slice_selX " << slice_selX << " slice_selY " << slice_selY << " slice_selZ " << slice_selZ << std::endl;
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,
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;
245 float *X = new float[NP];
246 float *Y = new float[NP];
247 float *Z = new float[NP];
251 for (i=0; i<NP; i++) {
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;
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;
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;
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;
301 std::string dcmImageName;
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);
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);
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);
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);
320 // =====================================================================================================================
322 void LoadStrain(std::ifstream &from, std::string textFileName)
325 // in sax_base_slice0_strain.txt :
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
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
352 int NP; // Number of Pints
353 int NCF; // Number of cine frames
354 float TR; // Temporal resolution
355 float FFS; // First frame starts
357 // Number of cine frames = 18
365 // Temporal resolution = 32.0000 ms
372 // First frame starts at 48.0000 ms
380 //Number of material points (NP) = 181
389 std::cout << "NP : " << NP << std::endl;
391 //Origin of (readout, phase enc, slice sel) coordinates in 3D = 87.324341 3.193918 88.238113
404 float readout, phase_enc, slice_sel;
408 std::cout << " readout " << readout << " phase_enc " << phase_enc << " slice_sel " << slice_sel << std::endl;
410 // Readout direction in 3D = -0.162314 -0.0771294 -0.983720
418 float readoutX, readoutY, readoutZ;
422 std::cout << " readoutX " << readoutX << " readoutY " << readoutY << " readoutZ " << readoutZ << std::endl;
424 // Phase Enc. direction in 3D = -0.540606 -0.827052 0.154046
433 float phase_encX, phase_encY, phase_encZ;
437 std::cout << " phase_encX " << phase_encX << " phase_encY " << phase_encY << " phase_encZ " << phase_encZ << std::endl;
439 // Slice select direction in 3D = 0.825469 -0.556809 -0.0925458
447 float slice_selX, slice_selY, slice_selZ;
451 std::cout << " slice_selX " << slice_selX << " slice_selY " << slice_selY << " slice_selZ " << slice_selZ << std::endl;
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.
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;
487 float *X = new float[NP];
488 float *Y = new float[NP];
489 float *Z = new float[NP];
493 for (i=0; i<NP; i++) {
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;
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;
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;
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;
544 std::string dcmImageName;
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);
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);
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);
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);
565 // =====================================================================================================================
568 void MakeDicomImage(float *tabVal, float *X, float *Y, float *Z, int NP, std::string dcmImageName)
570 float minX = 999., minY = 999., minZ = 999.;
571 float maxX = 0., maxY = 0., maxZ = 0.;
573 for (i=0; i<NP; i++) {
574 // std::cout << X[i] << " " << Y[i] << " " << Z[i] << std::endl;
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;
595 uint16_t *img = new uint16_t[int(maxX*maxY)];
597 for(int i3=0;i3<int(maxX*maxY);i3++)
600 for(int i2=0; i2<NP; i2++) {
601 img[ int(maxX -(X[i2]-1))+ int((maxY -Y[i2])* maxX) ] = int(tabVal[i2]*100);
604 // GDCM_NAME_SPACE::Debug::DebugOn();
606 std::ostringstream str;
607 GDCM_NAME_SPACE::File *file;
608 file = GDCM_NAME_SPACE::File::New();
610 // Set the image size
613 file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
616 file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
617 // Set the pixel type
619 file->InsertEntryString("16",0x0028,0x0100,"US"); // Bits Allocated
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
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
631 // Set Rescale Intercept
634 file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
639 file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
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();
649 if( !fileH->Write(dcmImageName))
650 std::cout << "Failed for [" << dcmImageName << "]\n"
651 << " File is unwrittable" << std::endl;