source: trunk/examples/extended/medical/DICOM/src/DicomHandler.cc @ 1230

Last change on this file since 1230 was 807, checked in by garnier, 16 years ago

update

File size: 23.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26// The code was written by :
27//      *Louis Archambault louis.archambault@phy.ulaval.ca,
28//      *Luc Beaulieu beaulieu@phy.ulaval.ca
29//      +Vincent Hubert-Tremblay at tigre.2@sympatico.ca
30//
31//
32// *Centre Hospitalier Universitaire de Quebec (CHUQ),
33// Hotel-Dieu de Quebec, departement de Radio-oncologie
34// 11 cote du palais. Quebec, QC, Canada, G1R 2J6
35// tel (418) 525-4444 #6720
36// fax (418) 691 5268
37//
38// + Universit.AŽé Laval, QuŽébec (QC) Canada
39//*******************************************************
40//
41//*******************************************************
42//
43//*******************************************************
44//
45// DicomHandler.cc :
46//      - Handling of DICM images
47//      - Reading headers and pixels
48//      - Transforming pixel to density and creating *.g4dcm
49//        files
50//      - Definitions are in DicomHandler.hh
51//*******************************************************
52
53#include "DicomHandler.hh"
54#include "globals.hh"
55#include "G4ios.hh"
56#include <fstream>
57
58#include <cctype>
59#include <cstring>
60
61
62DicomHandler::DicomHandler()
63    : DATABUFFSIZE(8192), LINEBUFFSIZE(128), FILENAMESIZE(512),
64      compression(0), nFiles(0), rows(0), columns(0),
65      bitAllocated(0), maxPixelValue(0), minPixelValue(0),
66      pixelSpacingX(0.), pixelSpacingY(0.),
67      sliceThickness(0.), sliceLocation(0.),
68      rescaleIntercept(0), rescaleSlope(0),
69      littleEndian(true), implicitEndian(false),
70      pixelRepresentation(0) {
71    ;
72}
73
74DicomHandler::~DicomHandler() {
75    ;
76}
77
78G4int DicomHandler::ReadFile(FILE *dicom, char * filename2)
79{
80  G4cout << " ReadFile " << filename2 << G4endl;
81    G4int returnvalue = 0;
82    char * buffer = new char[LINEBUFFSIZE];
83
84    implicitEndian = false;
85    littleEndian = true;
86
87    std::fread( buffer, 1, 128, dicom ); // The first 128 bytes
88                                         //are not important
89    // Reads the "DICOM" letters
90    std::fread( buffer, 1, 4, dicom );
91    // if there is no preamble, the FILE pointer is rewinded.
92    if(std::strncmp("DICM", buffer, 4) != 0) {
93        std::fseek(dicom, 0, SEEK_SET);
94        implicitEndian = true;
95    }
96
97    short readGroupId;    // identify the kind of input data
98    short readElementId;  // identify a particular type information
99    short elementLength2; // deal with element length in 2 bytes
100    G4int elementLength4; // deal with element length in 4 bytes
101
102    char * data = new char[DATABUFFSIZE];
103
104    // Read information up to the pixel data
105    while(true) {
106
107        //Reading groups and elements :
108        readGroupId = 0;
109        readElementId = 0;
110        // group ID
111        std::fread(buffer, 2, 1, dicom);
112        GetValue(buffer, readGroupId);
113        // element ID
114        std::fread(buffer, 2, 1, dicom);
115        GetValue(buffer, readElementId);
116
117        // Creating a tag to be identified afterward
118        G4int tagDictionary = readGroupId*0x10000 + readElementId;
119
120
121        // VR or element length
122        std::fread(buffer,2,1,dicom);
123        GetValue(buffer, elementLength2);
124
125        // If value representation (VR) is OB, OW, SQ, UN,
126        //the next length is 32 bits
127        if((elementLength2 == 0x424f ||  // "OB"
128            elementLength2 == 0x574f ||  // "OW"
129            elementLength2 == 0x5153 ||  // "SQ"
130            elementLength2 == 0x4e55) && // "UN"
131           !implicitEndian ) {           // explicit VR
132
133            std::fread(buffer, 2, 1, dicom); // Skip 2 reserved bytes
134
135            // element length
136            std::fread(buffer, 4, 1, dicom);
137            GetValue(buffer, elementLength4);
138
139            // beginning of the pixels
140            if(tagDictionary == 0x7FE00010) break;
141
142            // Reading the information with data
143            std::fread(data, elementLength4,1,dicom);
144
145
146        } else { // length is 16 bits :
147
148            if(!implicitEndian || readGroupId == 2) {
149                // element length (2 bytes)
150                std::fread(buffer, 2, 1, dicom);
151                GetValue(buffer, elementLength2);
152                elementLength4 = elementLength2;
153
154            } else { 
155                // element length (4 bytes)
156                if(std::fseek(dicom, -2, SEEK_CUR) != 0) {
157                    G4cerr << "[DicomHandler] fseek failed" << G4endl;
158                    exit(-10);
159                }
160                std::fread(buffer, 4, 1, dicom);
161                GetValue(buffer, elementLength4);
162            }
163
164            // beginning of the pixels
165            if(tagDictionary == 0x7FE00010) break;
166
167            std::fread(data, elementLength4, 1, dicom);
168        }
169
170        // NULL termination
171        data[elementLength4] = '\0';
172
173        // analyzing information
174        GetInformation(tagDictionary, data);
175    }
176
177    // Creating files to store information
178    std::ofstream foutG4DCM;
179    G4String fnameG4DCM = G4String(filename2) + ".g4dcm";
180    foutG4DCM.open(fnameG4DCM);
181    G4cout << " opened fnameG4DCM file " << fnameG4DCM << G4endl;
182
183    foutG4DCM << fMaterialIndices.size() << G4endl;
184    //--- Write materials
185    size_t ii = 0;
186    std::map<G4double,G4String>::const_iterator ite;
187    for( ite = fMaterialIndices.begin(); ite != fMaterialIndices.end(); ite++, ii++ ){
188      foutG4DCM << ii << " " << (*ite).second << G4endl;
189    }
190    //--- Write number of voxels (assume only one voxel in Z)
191    foutG4DCM << rows/compression << " " << columns/compression << " 1 " << G4endl;
192    //--- Write minimum and maximum extensions
193    foutG4DCM << -pixelSpacingX*rows/2 << " " << pixelSpacingX*rows/2 << G4endl;
194    foutG4DCM << -pixelSpacingY*columns/2 << " " << pixelSpacingY*columns/2 << G4endl;
195    foutG4DCM << sliceLocation-sliceThickness/2. << " " << sliceLocation+sliceThickness/2. << G4endl;
196   
197    ReadData( dicom, filename2 );
198   
199    StoreData( foutG4DCM );
200
201    foutG4DCM.close();
202
203    //
204    delete [] buffer;
205    delete [] data;
206
207    return returnvalue;
208}
209
210//
211void DicomHandler::GetInformation(G4int & tagDictionary, char * data) {
212    if(tagDictionary == 0x00280010 ) { // Number of Rows
213        GetValue(data, rows);
214        std::printf("[0x00280010] Rows -> %i\n",rows);
215
216    } else if(tagDictionary == 0x00280011 ) { // Number of columns
217        GetValue(data, columns);
218        std::printf("[0x00280011] Columns -> %i\n",columns);
219
220    } else if(tagDictionary == 0x00280102 ) { // High bits  ( not used )
221        short highBits;
222        GetValue(data, highBits);
223        std::printf("[0x00280102] High bits -> %i\n",highBits);
224
225    } else if(tagDictionary == 0x00280100 ) { // Bits allocated
226        GetValue(data, bitAllocated);
227        std::printf("[0x00280100] Bits allocated -> %i\n", bitAllocated);
228
229    } else if(tagDictionary == 0x00280101 ) { //  Bits stored ( not used )
230        short bitStored;
231        GetValue(data, bitStored);
232        std::printf("[0x00280101] Bits stored -> %i\n",bitStored);
233
234    } else if(tagDictionary == 0x00280106 ) { //  Min. pixel value
235        GetValue(data, minPixelValue);
236        std::printf("[0x00280106] Min. pixel value -> %i\n", minPixelValue);
237
238    } else if(tagDictionary == 0x00280107 ) { //  Max. pixel value
239        GetValue(data, maxPixelValue);
240        std::printf("[0x00280107] Max. pixel value -> %i\n", maxPixelValue);
241
242    } else if(tagDictionary == 0x00281053) { //  Rescale slope
243        rescaleSlope = atoi(data);
244        std::printf("[0x00281053] Rescale Slope -> %d\n", rescaleSlope);
245
246    } else if(tagDictionary == 0x00281052 ) { // Rescalse intercept
247        rescaleIntercept = atoi(data);
248        std::printf("[0x00281052] Rescale Intercept -> %d\n", rescaleIntercept );
249
250    } else if(tagDictionary == 0x00280103 ) {
251        //  Pixel representation ( functions not design to read signed bits )
252        pixelRepresentation = atoi(data); // 0: unsigned  1: signed
253        std::printf("[0x00280103] Pixel Representation -> %i\n", pixelRepresentation);
254        if(pixelRepresentation == 1 ) {
255            std::printf("### PIXEL REPRESENTATION = 1, BITS ARE SIGNED, ");
256            std::printf("DICOM READING SCAN FOR UNSIGNED VALUE, POSSIBLE ");
257            std::printf("ERROR !!!!!! -> \n");
258        }
259
260    } else if(tagDictionary == 0x00080006 ) { //  Modality
261        std::printf("[0x00080006] Modality -> %s\n", data);
262
263    } else if(tagDictionary == 0x00080070 ) { //  Manufacturer
264        std::printf("[0x00080070] Manufacturer -> %s\n", data);
265
266    } else if(tagDictionary == 0x00080080 ) { //  Institution Name
267        std::printf("[0x00080080] Institution Name -> %s\n", data);
268
269    } else if(tagDictionary == 0x00080081 ) { //  Institution Address
270        std::printf("[0x00080081] Institution Address -> %s\n", data);
271
272    } else if(tagDictionary == 0x00081040 ) { //  Institution Department Name
273        std::printf("[0x00081040] Institution Department Name -> %s\n", data);
274
275    } else if(tagDictionary == 0x00081090 ) { //  Manufacturer's Model Name
276        std::printf("[0x00081090] Manufacturer's Model Name -> %s\n", data);
277
278    } else if(tagDictionary == 0x00181000 ) { //  Device Serial Number
279        std::printf("[0x00181000] Device Serial Number -> %s\n", data);
280
281    } else if(tagDictionary == 0x00080008 ) { //  Image type ( not used )
282        std::printf("[0x00080008] Image Types -> %s\n", data);
283           
284    } else if(tagDictionary == 0x00283000 ) { //  Modality LUT Sequence ( not used )
285        std::printf("[0x00283000] Modality LUT Sequence SQ 1 -> %s\n", data);
286
287    } else if(tagDictionary == 0x00283002 ) { // LUT Descriptor ( not used )
288        std::printf("[0x00283002] LUT Descriptor US or SS 3 -> %s\n", data);
289
290    } else if(tagDictionary == 0x00283003 ) { // LUT Explanation ( not used )
291        std::printf("[0x00283003] LUT Explanation LO 1 -> %s\n", data);
292
293    } else if(tagDictionary == 0x00283004 ) { // Modality LUT ( not used )
294        std::printf("[0x00283004] Modality LUT Type LO 1 -> %s\n", data);
295
296    } else if(tagDictionary == 0x00283006 ) { // LUT Data ( not used )
297        std::printf("[0x00283006] LUT Data US or SS -> %s\n", data);
298
299    } else if(tagDictionary == 0x00283010 ) { // VOI LUT ( not used )
300        std::printf("[0x00283010] VOI LUT Sequence SQ 1 -> %s\n", data);
301
302    } else if(tagDictionary == 0x00280120 ) { // Pixel Padding Value ( not used )
303        std::printf("[0x00280120] Pixel Padding Value US or SS 1 -> %s\n", data);
304
305    } else if(tagDictionary == 0x00280030 ) { // Pixel Spacing
306      G4String datas(data);
307      int iss = datas.find('\\');
308      pixelSpacingX = atof( datas.substr(0,iss).c_str() );
309      pixelSpacingY = atof( datas.substr(iss+2,datas.length()).c_str() );
310
311    } else if(tagDictionary == 0x00200037 ) { // Image Orientation ( not used )
312        std::printf("[0x00200037] Image Orientation (Patient) -> %s\n", data);
313
314    } else if(tagDictionary == 0x00200032 ) { // Image Position ( not used )
315        std::printf("[0x00200032] Image Position (Patient,mm) -> %s\n", data);
316
317    } else if(tagDictionary == 0x00180050 ) { // Slice Thickness
318        sliceThickness = atof(data);
319        std::printf("[0x00180050] Slice Thickness (mm) -> %f\n", sliceThickness);
320
321    } else if(tagDictionary == 0x00201041 ) { // Slice Location
322        sliceLocation = atof(data);
323        std::printf("[0x00201041] Slice Location -> %f\n", sliceLocation);
324
325    } else if(tagDictionary == 0x00280004 ) { // Photometric Interpretation ( not used )
326        std::printf("[0x00280004] Photometric Interpretation -> %s\n", data);
327
328    } else if(tagDictionary == 0x00020010) { // Endian
329        if(strcmp(data, "1.2.840.10008.1.2") == 0)
330            implicitEndian = true;
331        else if(strncmp(data, "1.2.840.10008.1.2.2", 19) == 0)
332            littleEndian = false;
333        //else 1.2.840..10008.1.2.1 (explicit little endian)
334                   
335        std::printf("[0x00020010] Endian -> %s\n", data);
336    }
337
338    // others
339    else {
340        std::printf("[0x%x] -> %s\n", tagDictionary, data);
341
342    }
343
344}
345
346void DicomHandler::StoreData(std::ofstream& foutG4DCM) 
347{
348  G4int mean;
349  G4double density;
350  G4bool overflow = false;
351  G4int cpt=1;
352
353  //----- Print indices of material
354  if(compression == 1) { // no compression: each pixel has a density value)
355    for( G4int ww = 0; ww < rows; ww++) {
356      for( G4int xx = 0; xx < columns; xx++) {
357        mean = tab[ww][xx];
358        density = Pixel2density(mean);
359        foutG4DCM << GetMaterialIndex( density ) << " ";
360      }
361      foutG4DCM << G4endl;
362    }
363   
364  } else {
365    // density value is the average of a square region of
366    // compression*compression pixels
367    for(G4int ww = 0; ww < rows ;ww += compression ) {
368      for(G4int xx = 0; xx < columns ;xx +=compression ) {
369        overflow = false;
370        mean = 0;
371        for(int sumx = 0; sumx < compression; sumx++) {
372          for(int sumy = 0; sumy < compression; sumy++) {
373            if(ww+sumy >= rows || xx+sumx >= columns) overflow = true;
374            mean += tab[ww+sumy][xx+sumx];
375          }
376          if(overflow) break;
377        }
378        mean /= compression*compression;
379        cpt = 1;
380       
381        if(!overflow) {
382          G4double density = Pixel2density(mean);
383          foutG4DCM << GetMaterialIndex( density ) << " ";
384        }
385      }
386      foutG4DCM << G4endl;
387    }
388
389  }
390
391  //----- Print densities
392  if(compression == 1) { // no compression: each pixel has a density value)
393    for( G4int ww = 0; ww < rows; ww++) {
394      for( G4int xx = 0; xx < columns; xx++) {
395        mean = tab[ww][xx];
396        density = Pixel2density(mean);
397        foutG4DCM << density << " ";
398        if( xx%8 == 3 ) foutG4DCM << G4endl; // just for nicer reading
399      }
400    }
401   
402  } else {
403    // density value is the average of a square region of
404    // compression*compression pixels
405    for(G4int ww = 0; ww < rows ;ww += compression ) {
406      for(G4int xx = 0; xx < columns ;xx +=compression ) {
407        overflow = false;
408        mean = 0;
409        for(int sumx = 0; sumx < compression; sumx++) {
410          for(int sumy = 0; sumy < compression; sumy++) {
411            if(ww+sumy >= rows || xx+sumx >= columns) overflow = true;
412            mean += tab[ww+sumy][xx+sumx];
413          }
414          if(overflow) break;
415        }
416        mean /= compression*compression;
417        cpt = 1;
418       
419        if(!overflow) {
420          G4double density = Pixel2density(mean);
421          foutG4DCM << density  << " ";
422          if( xx/compression%8 == 3 ) foutG4DCM << G4endl; // just for nicer reading
423        }
424      }
425    }
426
427  }
428
429}
430
431void DicomHandler::ReadMaterialIndices( std::ifstream& finData)
432{
433  size_t nMate;
434  G4String mateName;
435  G4double densityMax;
436  finData >> nMate;
437  if( finData.eof() ) return;
438
439  G4cout << " ReadMaterialIndices " << nMate << G4endl;
440  for( size_t ii = 0; ii < nMate; ii++ ){
441    finData >> mateName >> densityMax;
442    fMaterialIndices[densityMax] = mateName;
443    G4cout << ii << " ReadMaterialIndices " << mateName << " " << densityMax << G4endl;
444  }
445
446}
447
448size_t DicomHandler::GetMaterialIndex( G4double density )
449{
450  size_t mateID;
451  std::map<G4double,G4String>::reverse_iterator ite;
452  G4int ii = fMaterialIndices.size();
453  for( ite = fMaterialIndices.rbegin(); ite != fMaterialIndices.rend(); ite++, ii-- ) {
454    if( density >= (*ite).first ) {
455      break;
456    }
457  }
458  //-  G4cout << " GetMaterialIndex " << density << " = " << ii << G4endl;
459  return  ii;
460
461}
462
463//
464G4int DicomHandler::ReadData(FILE *dicom,char * filename2)
465{
466    G4int returnvalue = 0;
467
468    //  READING THE PIXELS :
469    G4int w = 0;
470    G4int len = 0;
471   
472    tab = new G4int*[rows];
473    for ( G4int i = 0; i < rows; i ++ ) {
474      tab[i] = new G4int[columns];
475    }
476
477    if(bitAllocated == 8) { // Case 8 bits :
478
479        std::printf("@@@ Error! Picture != 16 bits...\n");
480        std::printf("@@@ Error! Picture != 16 bits...\n"); 
481        std::printf("@@@ Error! Picture != 16 bits...\n"); 
482
483        unsigned char ch = 0;
484
485        len = rows*columns;
486        for(G4int j = 0; j < rows; j++) {
487            for(G4int i = 0; i < columns; i++) {
488                w++;
489                std::fread( &ch, 1, 1, dicom);
490                tab[j][i] = ch*rescaleSlope + rescaleIntercept;
491            }
492        }
493        returnvalue = 1;
494
495    } else { //  from 12 to 16 bits :
496        char sbuff[2];
497        short pixel;
498        len = rows*columns;
499        for( G4int j = 0; j < rows; j++) {
500            for( G4int i = 0; i < columns; i++) {
501                w++;
502                std::fread(sbuff, 2, 1, dicom);
503                GetValue(sbuff, pixel);
504                tab[j][i] = pixel*rescaleSlope + rescaleIntercept;
505            }
506        }
507    }
508
509    // Creation of .g4 files wich contains averaged density data
510
511    char * nameProcessed = new char[FILENAMESIZE];
512    FILE* processed;
513
514    std::sprintf(nameProcessed,"%s.g4",filename2);
515    processed = std::fopen(nameProcessed,"w+b");
516    std::printf("### Writing of %s ###\n",nameProcessed);
517
518    std::fwrite(&rows, 2, 1, processed);
519    std::fwrite(&columns, 2, 1, processed);
520    std::fwrite(&pixelSpacingX, 8, 1, processed);
521    std::fwrite(&pixelSpacingY, 8, 1, processed);
522    std::fwrite(&sliceThickness, 8, 1, processed);
523    std::fwrite(&sliceLocation, 8, 1, processed);
524    std::fwrite(&compression, 2, 1, processed);
525
526    std::printf("%8i   %8i\n",rows,columns);
527    std::printf("%8f   %8f\n",pixelSpacingX,pixelSpacingY);
528    std::printf("%8f\n", sliceThickness);
529    std::printf("%8f\n", sliceLocation);
530    std::printf("%8i\n", compression);
531
532    G4int compSize = compression;
533    G4int mean;
534    G4double density;
535    G4bool overflow = false;
536    G4int cpt=1;
537
538    if(compSize == 1) { // no compression: each pixel has a density value)
539        for( G4int ww = 0; ww < rows; ww++) {
540            for( G4int xx = 0; xx < columns; xx++) {
541                mean = tab[ww][xx];
542                density = Pixel2density(mean);
543                std::fwrite(&density, sizeof(G4double), 1, processed);
544            }
545        }
546
547    } else {
548        // density value is the average of a square region of
549        // compression*compression pixels
550        for(G4int ww = 0; ww < rows ;ww += compSize ) {
551            for(G4int xx = 0; xx < columns ;xx +=compSize ) {
552                overflow = false;
553                mean = 0;
554                for(int sumx = 0; sumx < compSize; sumx++) {
555                    for(int sumy = 0; sumy < compSize; sumy++) {
556                        if(ww+sumy >= rows || xx+sumx >= columns) overflow = true;
557                        mean += tab[ww+sumy][xx+sumx];
558                    }
559                    if(overflow) break;
560                }
561                mean /= compSize*compSize;
562                cpt = 1;
563
564                if(!overflow) {
565                    G4double density = Pixel2density(mean);
566                    std::fwrite(&density, sizeof(G4double), 1, processed);
567                }
568            }
569
570        }
571    }
572    std::fclose(processed);
573
574    delete [] nameProcessed;
575
576    /*    for ( G4int i = 0; i < rows; i ++ ) {
577      delete [] tab[i];
578    }
579    delete [] tab;
580    */
581
582    return returnvalue;
583}
584
585/*
586  G4int DicomHandler::displayImage(char command[300])
587  {
588  //   Display DICOM images using ImageMagick
589  char commandName[500];
590  std::sprintf(commandName,"display  %s",command);
591  std::printf(commandName);
592  G4int i = system(commandName);
593  return (G4int )i;
594  }
595*/
596
597G4double DicomHandler::Pixel2density(G4int pixel)
598{
599    G4double density = -1.;
600    G4int nbrequali = 0;
601    G4double deltaCT = 0;
602    G4double deltaDensity = 0;
603
604    // CT2Density.dat contains the calibration curve to convert CT (Hounsfield)
605    // number to physical density
606    std::ifstream calibration("CT2Density.dat");
607    calibration >> nbrequali;
608
609    G4double * valuedensity = new G4double[nbrequali];
610    G4double * valueCT = new G4double[nbrequali];
611
612    if(!calibration) {
613        G4cerr << "@@@ No value to transform pixels in density!" << G4endl;
614        exit(1);
615
616    } else { // calibration was successfully opened
617        for(G4int i = 0; i < nbrequali; i++) { // Loop to store all the pts in CT2Density.dat
618            calibration >> valueCT[i] >> valuedensity[i];
619        }
620    }
621    calibration.close();
622
623    for(G4int j = 1; j < nbrequali; j++) {
624        if( pixel >= valueCT[j-1] && pixel < valueCT[j]) {
625
626            deltaCT = valueCT[j] - valueCT[j-1];
627            deltaDensity = valuedensity[j] - valuedensity[j-1];
628
629            // interpolating linearly
630            density = valuedensity[j] - ((valueCT[j] - pixel)*deltaDensity/deltaCT );
631            break;
632        }
633    }
634
635    if(density < 0.) {
636        std::printf("@@@ Error density = %f && Pixel = %i (0x%x) && deltaDensity/deltaCT = %f\n",density,pixel,pixel, deltaDensity/deltaCT);
637    }
638   
639    delete [] valuedensity;
640    delete [] valueCT;
641
642    return density;
643}
644
645
646void DicomHandler::CheckFileFormat()
647{
648    std::ifstream checkData("Data.dat");
649    char * oneLine = new char[128];
650
651    if(!(checkData.is_open())) { //Check existance of Data.dat
652
653        G4cout << "\nDicomG4 needs Data.dat :\n\tFirst line: number of image pixel for a "
654               << "voxel (G4Box)\n\tSecond line: number of images (CT slices) to "
655               << "read\n\tEach following line contains the name of a Dicom image except "
656               << "for the .dcm extension\n";
657        exit(0);
658    }
659
660    checkData >> compression;
661    checkData >> nFiles;
662    G4String oneName;
663    checkData.getline(oneLine,100);
664    std::ifstream testExistence;
665    G4bool existAlready = true;
666    for(G4int rep = 0; rep < nFiles; rep++) { 
667      checkData.getline(oneLine,100);
668      oneName = oneLine;
669      oneName += ".g4dcm"; // create dicomFile.g4dcm
670      G4cout << nFiles << " test file " << oneName << G4endl;
671      testExistence.open(oneName.data());
672      if(!(testExistence.is_open())) {
673        existAlready = false;
674        testExistence.clear();
675        testExistence.close();
676      }
677      testExistence.clear();
678      testExistence.close();
679    }
680
681    ReadMaterialIndices( checkData );
682
683    checkData.close();
684    delete [] oneLine;
685
686    if( existAlready == false ) { // The files *.g4dcm have to be created
687
688        G4cout << "\nAll the necessary images were not found in processed form, starting "
689               << "with .dcm images\n";
690
691        FILE * dicom;
692        FILE * lecturePref;
693        char * compressionc = new char[LINEBUFFSIZE];
694        char * maxc = new char[LINEBUFFSIZE];
695        //char name[300], inputFile[300];
696        char * name = new char[FILENAMESIZE];
697        char * inputFile = new char[FILENAMESIZE];
698
699        lecturePref = std::fopen("Data.dat","r");
700        std::fscanf(lecturePref,"%s",compressionc);
701        compression = atoi(compressionc);
702        std::fscanf(lecturePref,"%s",maxc);
703        nFiles = atoi(maxc);
704        G4cout << " nFiles " << nFiles << G4endl;
705
706        for( G4int i = 1; i <= nFiles; i++ ) { // Begin loop on filenames
707
708            std::fscanf(lecturePref,"%s",inputFile);
709            std::sprintf(name,"%s.dcm",inputFile);
710            std::cout << "check 1: " << name << std::endl;
711            //  Open input file and give it to gestion_dicom :
712            std::printf("### Opening %s and reading :\n",name);
713            dicom = std::fopen(name,"rb");
714            // Reading the .dcm in two steps:
715            //      1.  reading the header
716            //  2. reading the pixel data and store the density in Moyenne.dat
717            if( dicom != 0 ) {
718                ReadFile(dicom,inputFile);
719            } else {
720                G4cout << "\nError opening file : " << name << G4endl;
721            }
722            std::fclose(dicom);
723        }
724        std::fclose(lecturePref);
725
726        delete [] compressionc;
727        delete [] maxc;
728        delete [] name;
729        delete [] inputFile;
730
731    } 
732
733}
734
735
736template <class Type>
737void DicomHandler::GetValue(char * _val, Type & _rval) {
738
739#if BYTE_ORDER == BIG_ENDIAN
740    if(littleEndian) {      // little endian
741#else // BYTE_ORDER == LITTLE_ENDIAN
742    if(!littleEndian) {     // big endian
743#endif
744        const int SIZE = sizeof(_rval);
745        char ctemp;
746        for(int i = 0; i < SIZE/2; i++) {
747            ctemp = _val[i];
748            _val[i] = _val[SIZE - 1 - i];
749            _val[SIZE - 1 - i] = ctemp;
750        }
751    }
752    _rval = *(Type *)_val;
753}
Note: See TracBrowser for help on using the repository browser.