Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/DICOM/src/DicomPartialDetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /examples/extended/medical/DICOM/src/DicomPartialDetectorConstruction.cc (Version 11.3.0) and /examples/extended/medical/DICOM/src/DicomPartialDetectorConstruction.cc (Version 10.6.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 /// \file medical/DICOM/src/DicomPartialDetect     27 /// \file medical/DICOM/src/DicomPartialDetectorConstruction.cc
 28 /// \brief Implementation of the DicomPartialD     28 /// \brief Implementation of the DicomPartialDetectorConstruction class
 29 //                                                 29 //
 30                                                    30 
                                                   >>  31 #include "globals.hh"
                                                   >>  32 
 31 #include "DicomPartialDetectorConstruction.hh"     33 #include "DicomPartialDetectorConstruction.hh"
 32                                                    34 
 33 #include "G4Box.hh"                                35 #include "G4Box.hh"
 34 #include "G4Colour.hh"                         << 
 35 #include "G4Element.hh"                        << 
 36 #include "G4LogicalVolume.hh"                      36 #include "G4LogicalVolume.hh"
 37 #include "G4Material.hh"                       << 
 38 #include "G4NistManager.hh"                    << 
 39 #include "G4PVParameterised.hh"                << 
 40 #include "G4PVPlacement.hh"                    << 
 41 #include "G4PartialPhantomParameterisation.hh" << 
 42 #include "G4SystemOfUnits.hh"                  << 
 43 #include "G4Tubs.hh"                           << 
 44 #include "G4UIcommand.hh"                      << 
 45 #include "G4VPhysicalVolume.hh"                    37 #include "G4VPhysicalVolume.hh"
                                                   >>  38 #include "G4PVPlacement.hh"
                                                   >>  39 #include "G4PVParameterised.hh"
                                                   >>  40 #include "G4Material.hh"
                                                   >>  41 #include "G4Element.hh"
 46 #include "G4VisAttributes.hh"                      42 #include "G4VisAttributes.hh"
                                                   >>  43 #include "G4Colour.hh"
 47 #include "G4ios.hh"                                44 #include "G4ios.hh"
 48 #include "G4tgbMaterialMgr.hh"                 <<  45 #include "G4PartialPhantomParameterisation.hh"
                                                   >>  46 #include "G4NistManager.hh"
                                                   >>  47 #include "G4UIcommand.hh"
                                                   >>  48 #include "G4Tubs.hh"
                                                   >>  49 
 49 #include "G4tgbVolumeMgr.hh"                       50 #include "G4tgbVolumeMgr.hh"
                                                   >>  51 #include "G4tgbMaterialMgr.hh"
 50 #include "G4tgrMessenger.hh"                       52 #include "G4tgrMessenger.hh"
 51 #include "globals.hh"                          <<  53 #include "G4tgrMessenger.hh"
                                                   >>  54 
                                                   >>  55 #include "G4SystemOfUnits.hh"
 52                                                    56 
 53 //....oooOO0OOooo........oooOO0OOooo........oo     57 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 54 DicomPartialDetectorConstruction::DicomPartial     58 DicomPartialDetectorConstruction::DicomPartialDetectorConstruction()
 55   : DicomDetectorConstruction(),               <<  59  : DicomDetectorConstruction(),
 56     fPartialPhantomParam(0),                   <<  60    fPartialPhantomParam(0),
 57     fNoVoxels(0),                              <<  61    fNVoxels(0),
 58     fDimX(0),                                  <<  62    fDimX(0),
 59     fDimY(0),                                  <<  63    fDimY(0),
 60     fDimZ(0),                                  <<  64    fDimZ(0),
 61     fOffsetX(0),                               <<  65    fOffsetX(0),
 62     fOffsetY(0),                               <<  66    fOffsetY(0),
 63     fOffsetZ(0)                                <<  67    fOffsetZ(0)
 64 {}                                             <<  68 {
                                                   >>  69 }
 65                                                    70 
 66 //....oooOO0OOooo........oooOO0OOooo........oo     71 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 67 DicomPartialDetectorConstruction::~DicomPartia <<  72 DicomPartialDetectorConstruction::~DicomPartialDetectorConstruction()
                                                   >>  73 {
                                                   >>  74 }
 68                                                    75 
 69 //....oooOO0OOooo........oooOO0OOooo........oo     76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 70 G4VPhysicalVolume* DicomPartialDetectorConstru     77 G4VPhysicalVolume* DicomPartialDetectorConstruction::Construct()
 71 {                                                  78 {
 72   InitialisationOfMaterials();                     79   InitialisationOfMaterials();
 73                                                    80 
 74   //----- Build world                              81   //----- Build world
 75   G4double worldXDimension = 1. * m;           <<  82   G4double worldXDimension = 1.*m;
 76   G4double worldYDimension = 1. * m;           <<  83   G4double worldYDimension = 1.*m;
 77   G4double worldZDimension = 1. * m;           <<  84   G4double worldZDimension = 1.*m;
 78                                                <<  85 
 79   G4Box* world_box = new G4Box("WorldSolid", w <<  86   G4Box* world_box = new G4Box( "WorldSolid",
 80                                                <<  87                           worldXDimension,
 81   fWorld_logic = new G4LogicalVolume(world_box <<  88                           worldYDimension,
 82                                                <<  89                           worldZDimension );
 83   G4VPhysicalVolume* world_phys =              <<  90 
 84     new G4PVPlacement(0, G4ThreeVector(0, 0, 0 <<  91   fWorld_logic = new G4LogicalVolume( world_box,
                                                   >>  92                                     fAir,
                                                   >>  93                                     "WorldLogical",
                                                   >>  94                                     0, 0, 0 );
                                                   >>  95 
                                                   >>  96   G4VPhysicalVolume* world_phys = new G4PVPlacement( 0,
                                                   >>  97                                   G4ThreeVector(0,0,0),
                                                   >>  98                                   "World",
                                                   >>  99                                   fWorld_logic,
                                                   >> 100                                   0,
                                                   >> 101                                   false,
                                                   >> 102                                   0 );
 85                                                   103 
 86   ReadPhantomData();                              104   ReadPhantomData();
 87                                                   105 
 88   ConstructPhantomContainer();                    106   ConstructPhantomContainer();
 89   ConstructPhantom();                             107   ConstructPhantom();
 90                                                   108 
 91   return world_phys;                              109   return world_phys;
 92 }                                                 110 }
 93                                                   111 
 94 //....oooOO0OOooo........oooOO0OOooo........oo    112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 95 void DicomPartialDetectorConstruction::ReadPha    113 void DicomPartialDetectorConstruction::ReadPhantomData()
 96 {                                                 114 {
 97   G4String dataFile = "Data.dat";              << 115     G4String dataFile = "Data.dat";
 98   std::ifstream finDF(dataFile.c_str());       << 116     std::ifstream finDF(dataFile.c_str());
 99   G4String fname;                              << 117     G4String fname;
100   if (finDF.good() != 1) {                     << 118     if(finDF.good() != 1 ) {
101     G4Exception(" DicomPartialDetectorConstruc << 119         G4Exception(" DicomPartialDetectorConstruction::ReadPhantomData",
102                 " Problem reading data file: D << 120                     "",
103   }                                            << 121                     FatalErrorInArgument,
                                                   >> 122                     " Problem reading data file: Data.dat");
                                                   >> 123     }
104                                                   124 
105   G4int compression;                           << 125     G4int compression;
106   finDF >> compression;  // not used here      << 126     finDF >> compression; // not used here
107                                                   127 
108   G4int numFiles;                              << 128     G4int numFiles;
109   finDF >> numFiles;  // only 1 file supported << 129     finDF >> numFiles;  // only 1 file supported for the moment
110   if (numFiles != 1) {                         << 130     if( numFiles != 1 ) {
111     G4Exception("DicomPartialDetectorConstruct << 131         G4Exception("DicomPartialDetectorConstruction::ReadPhantomData",
112                 "More than 1 DICOM file is not << 132                     "",
113   }                                            << 133                     FatalErrorInArgument,
114   for (G4int i = 0; i < numFiles; i++) {       << 134                     "More than 1 DICOM file is not supported");
115     finDF >> fname;                            << 135     }
116     //--- Read one data file                   << 136     for(G4int i = 0; i < numFiles; i++ ) {
117     fname += ".g4pdcm";                        << 137         finDF >> fname;
118     ReadPhantomDataFile(fname);                << 138         //--- Read one data file
119   }                                            << 139         fname += ".g4pdcm";
                                                   >> 140         ReadPhantomDataFile(fname);
                                                   >> 141     }
120                                                   142 
121   finDF.close();                               << 143     finDF.close();
122 }                                                 144 }
123                                                   145 
124 //....oooOO0OOooo........oooOO0OOooo........oo    146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
125 void DicomPartialDetectorConstruction::ReadPha << 147 void DicomPartialDetectorConstruction::
                                                   >> 148 ReadPhantomDataFile(const G4String& fname)
126 {                                                 149 {
127   //  G4String filename = "phantom.g4pdcm";       150   //  G4String filename = "phantom.g4pdcm";
128 #ifdef G4VERBOSE                                  151 #ifdef G4VERBOSE
129   G4cout << " DicomDetectorConstruction::ReadP << 152   G4cout << " DicomDetectorConstruction::ReadPhantomDataFile opening file "
                                                   >> 153          << fname << G4endl;
130 #endif                                            154 #endif
131   std::ifstream fin(fname.c_str(), std::ios_ba    155   std::ifstream fin(fname.c_str(), std::ios_base::in);
132   if (!fin.is_open()) {                        << 156   if( !fin.is_open() ) {
133     G4Exception("DicomPartialDetectorConstruct << 157     G4Exception("DicomPartialDetectorConstruction::ReadPhantomDataFile",
                                                   >> 158                 "",
                                                   >> 159                 FatalException,
134                 G4String("File not found " + f    160                 G4String("File not found " + fname).c_str());
135   }                                               161   }
136   G4int nMaterials;                               162   G4int nMaterials;
137   fin >> nMaterials;                              163   fin >> nMaterials;
138   G4String stemp;                                 164   G4String stemp;
139   G4int nmate;                                    165   G4int nmate;
140   for (G4int ii = 0; ii < nMaterials; ii++) {  << 166   for( G4int ii = 0; ii < nMaterials; ii++ ){
141     fin >> nmate >> stemp;                        167     fin >> nmate >> stemp;
142     G4cout << "DicomPartialDetectorConstructio << 168     G4cout << "DicomPartialDetectorConstruction::ReadPhantomData reading nmate "
143            << nmate << " mate " << stemp << G4 << 169     << ii << " = " << nmate << " mate " << stemp << G4endl;
144     if (ii != nmate)                           << 170     if( ii != nmate )
145       G4Exception("DicomPartialDetectorConstru << 171       G4Exception("DicomPartialDetectorConstruction::ReadPhantomData",
                                                   >> 172                   "",
                                                   >> 173                   FatalErrorInArgument,
146                   "Material number should be i    174                   "Material number should be in increasing order: \
147                           wrong material numbe    175                           wrong material number ");
                                                   >> 176 
148   }                                               177   }
149                                                   178 
150   fin >> fNoVoxelsX >> fNoVoxelsY >> fNoVoxels << 179   fin >> fNVoxelX >> fNVoxelY >> fNVoxelZ;
151   G4cout << "DicomPartialDetectorConstruction: << 180   G4cout << "DicomPartialDetectorConstruction::ReadPhantomData nVoxel X/Y/Z "
152          << fNoVoxelsY << " " << fNoVoxelsZ << << 181   << fNVoxelX << " " << fNVoxelY << " " << fNVoxelZ << G4endl;
153   fin >> fOffsetX >> fDimX;                       182   fin >> fOffsetX >> fDimX;
154   fDimX = (fDimX - fOffsetX) / fNoVoxelsX;     << 183   fDimX = (fDimX - fOffsetX)/fNVoxelX;
155   fin >> fOffsetY >> fDimY;                       184   fin >> fOffsetY >> fDimY;
156   fDimY = (fDimY - fOffsetY) / fNoVoxelsY;     << 185   fDimY = (fDimY - fOffsetY)/fNVoxelY;
157   fin >> fOffsetZ >> fDimZ;                       186   fin >> fOffsetZ >> fDimZ;
158   fDimZ = (fDimZ - fOffsetZ) / fNoVoxelsZ;     << 187   fDimZ = (fDimZ - fOffsetZ)/fNVoxelZ;
159   G4cout << "DicomPartialDetectorConstruction: << 188   G4cout << "DicomPartialDetectorConstruction::ReadPhantomData voxelDimX "
160          << fOffsetX << G4endl;                << 189   << fDimX << " fOffsetX " << fOffsetX << G4endl;
161   G4cout << "DicomPartialDetectorConstruction: << 190   G4cout << "DicomPartialDetectorConstruction::ReadPhantomData voxelDimY "
162          << fOffsetY << G4endl;                << 191   << fDimY << " fOffsetY " << fOffsetY << G4endl;
163   G4cout << "DicomPartialDetectorConstruction: << 192   G4cout << "DicomPartialDetectorConstruction::ReadPhantomData voxelDimZ "
164          << fOffsetZ << G4endl;                << 193   << fDimZ << " fOffsetZ " << fOffsetZ << G4endl;
165                                                   194 
166   //--- Read voxels that are filled               195   //--- Read voxels that are filled
167   fNoVoxels = 0;                               << 196   fNVoxels = 0;
168   //  G4bool* isFilled = new G4bool[fNoVoxelsX << 197   //  G4bool* isFilled = new G4bool[fNVoxelX*fNVoxelY*fNVoxelZ];
169   //  fFilledIDs = new size_t[fNoVoxelsZ*fNoVo << 198   //  fFilledIDs = new size_t[fNVoxelZ*fNVoxelY+1];
170   //?  fFilledIDs.insert(0);                      199   //?  fFilledIDs.insert(0);
171   G4int ifxmin1, ifxmax1;                         200   G4int ifxmin1, ifxmax1;
172   for (G4int iz = 0; iz < fNoVoxelsZ; iz++) {  << 201   for( G4int iz = 0; iz < fNVoxelZ; iz++ ) {
173     std::map<G4int, G4int> ifmin, ifmax;       << 202     std::map< G4int, G4int > ifmin, ifmax;
174     for (G4int iy = 0; iy < fNoVoxelsY; iy++)  << 203     for( G4int iy = 0; iy < fNVoxelY; iy++ ) {
175       fin >> ifxmin1 >> ifxmax1;                  204       fin >> ifxmin1 >> ifxmax1;
176       // check coherence ...                      205       // check coherence ...
177                                                   206 
178       ifmin[iy] = ifxmin1;                        207       ifmin[iy] = ifxmin1;
179       ifmax[iy] = ifxmax1;                        208       ifmax[iy] = ifxmax1;
180       G4int ifxdiff = ifxmax1 - ifxmin1 + 1;   << 209       G4int ifxdiff = ifxmax1-ifxmin1+1;
181       if (ifxmax1 == -1 && ifxmin1 == -1) ifxd << 210       if( ifxmax1 == -1 && ifxmin1 == -1 ) ifxdiff = 0;
182       fFilledIDs.insert(std::pair<G4int, G4int << 211       fFilledIDs.insert(std::pair<G4int,G4int>(ifxdiff+fNVoxels-1, ifxmin1));
183       G4cout << "DicomPartialDetectorConstruct    212       G4cout << "DicomPartialDetectorConstruction::ReadPhantomData insert "
184              << " FilledIDs " << ifxdiff + fNo << 213              << " FilledIDs "  << ifxdiff+fNVoxels-1 << " min " << ifxmin1
185              << " N= " << fFilledIDs.size() <<    214              << " N= " << fFilledIDs.size() << G4endl;
186       // filledIDs[iz*fNoVoxelsY+iy+1] = ifxma << 215       //filledIDs[iz*fNVoxelY+iy+1] = ifxmax1-ifxmin1+1;
187       for (G4int ix = 0; ix < fNoVoxelsX; ix++ << 216       for( G4int ix = 0; ix < fNVoxelX; ix++ ) {
188         if (ix >= G4int(ifxmin1) && ix <= G4in << 217         if( ix >= G4int(ifxmin1) && ix <= G4int(ifxmax1) ) {
189           fNoVoxels++;                         << 218           fNVoxels++;
190         }                                      << 219         } else {
191         else {                                 << 
192         }                                         220         }
193       }                                           221       }
194     }                                             222     }
195     fFilledMins[iz] = ifmin;                      223     fFilledMins[iz] = ifmin;
196     fFilledMaxs[iz] = ifmax;                      224     fFilledMaxs[iz] = ifmax;
197   }                                               225   }
198                                                   226 
199   //--- Read material IDs                         227   //--- Read material IDs
200   G4int mateID1;                                  228   G4int mateID1;
201   fMateIDs = new size_t[fNoVoxelsX * fNoVoxels << 229   fMateIDs = new size_t[fNVoxelX*fNVoxelY*fNVoxelZ];
202   G4int copyNo = 0;                               230   G4int copyNo = 0;
203   for (G4int iz = 0; iz < fNoVoxelsZ; iz++) {  << 231   for( G4int iz = 0; iz < fNVoxelZ; iz++ ) {
204     std::map<G4int, G4int> ifmin = fFilledMins << 232     std::map< G4int, G4int > ifmin = fFilledMins[iz];
205     std::map<G4int, G4int> ifmax = fFilledMaxs << 233     std::map< G4int, G4int > ifmax = fFilledMaxs[iz];
206     for (G4int iy = 0; iy < fNoVoxelsY; iy++)  << 234     for( G4int iy = 0; iy < fNVoxelY; iy++ ) {
207       ifxmin1 = ifmin[iy];                        235       ifxmin1 = ifmin[iy];
208       ifxmax1 = ifmax[iy];                        236       ifxmax1 = ifmax[iy];
209       for (G4int ix = 0; ix < fNoVoxelsX; ix++ << 237       for( G4int ix = 0; ix < fNVoxelX; ix++ ) {
210         if (ix >= G4int(ifxmin1) && ix <= G4in << 238         if( ix >= G4int(ifxmin1) && ix <= G4int(ifxmax1) ) {
211           fin >> mateID1;                         239           fin >> mateID1;
212           if (mateID1 < 0 || mateID1 >= nMater << 240           if( mateID1 < 0 || mateID1 >= nMaterials ) {
213             G4Exception("DicomPartialDetectorC << 241             G4Exception("DicomPartialDetectorConstruction::ReadPhantomData",
214                         G4String("Wrong index  << 242                         "",
215                                  + G4UIcommand << 243                         FatalException,
216                                  + G4UIcommand << 244             G4String("Wrong index in phantom file: It should be between 0 and "
217                           .c_str());           << 245                      + G4UIcommand::ConvertToString(nMaterials-1)
                                                   >> 246                      + ", while it is "
                                                   >> 247                      + G4UIcommand::ConvertToString(mateID1)).c_str());
218           }                                       248           }
219           fMateIDs[copyNo] = mateID1;             249           fMateIDs[copyNo] = mateID1;
220           copyNo++;                               250           copyNo++;
221         }                                         251         }
222       }                                           252       }
223     }                                             253     }
224   }                                               254   }
225                                                   255 
226   ReadVoxelDensitiesPartial(fin);              << 256   ReadVoxelDensitiesPartial( fin );
227                                                   257 
228   fin.close();                                    258   fin.close();
229 }                                                 259 }
230                                                   260 
231 //....oooOO0OOooo........oooOO0OOooo........oo    261 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
232 void DicomPartialDetectorConstruction::ReadVox << 262 void DicomPartialDetectorConstruction::
                                                   >> 263 ReadVoxelDensitiesPartial( std::ifstream& fin )
233 {                                                 264 {
234   std::map<G4int, std::pair<G4double, G4double << 265     std::map<G4int, std::pair<G4double,G4double> > densiMinMax;
235   std::map<G4int, std::pair<G4double, G4double << 266     std::map<G4int, std::pair<G4double,G4double> >::iterator mpite;
236   for (G4int ii = 0; ii < G4int(fOriginalMater << 267     for( G4int ii = 0; ii < G4int(fOriginalMaterials.size()); ++ii )
237     densiMinMax[ii] = std::pair<G4double, G4do << 268     {
238   }                                            << 269        densiMinMax[ii] = std::pair<G4double,G4double>(DBL_MAX,-DBL_MAX);
                                                   >> 270     }
239                                                   271 
240   //----- Define density differences (maximum  << 272     //----- Define density differences (maximum density difference to create
241   // a new material)                           << 273     // a new material)
242   char* part = std::getenv("DICOM_CHANGE_MATER << 274     char* part = std::getenv( "DICOM_CHANGE_MATERIAL_DENSITY" );
243   G4double densityDiff = -1.;                  << 275     G4double densityDiff = -1.;
244   if (part) densityDiff = G4UIcommand::Convert << 276     if( part ) densityDiff = G4UIcommand::ConvertToDouble(part);
245   std::map<G4int, G4double> densityDiffs;      << 277     std::map<G4int,G4double> densityDiffs;
246   if (densityDiff != -1.) {                    << 278     if( densityDiff != -1. )
247     for (G4int ii = 0; ii < G4int(fOriginalMat << 279     {
248       densityDiffs[ii] = densityDiff;  // curr << 280         for( G4int ii = 0; ii < G4int(fOriginalMaterials.size()); ++ii )
249       // with same step                        << 281         {
                                                   >> 282             densityDiffs[ii] = densityDiff; //currently all materials
                                                   >> 283             //with same step
                                                   >> 284         }
250     }                                             285     }
251   }                                            << 286     else
252   else {                                       << 287     {
253     if (fMaterials.size() == 0) {  // do it on << 288         if( fMaterials.size() == 0 ) { // do it only for first slice
254       for (unsigned int ii = 0; ii < fOriginal << 289             for( unsigned int ii = 0; ii < fOriginalMaterials.size(); ++ii )
255         fMaterials.push_back(fOriginalMaterial << 290             {
256       }                                        << 291                 fMaterials.push_back( fOriginalMaterials[ii] );
                                                   >> 292             }
                                                   >> 293         }
257     }                                             294     }
258   }                                            << 
259   //  densityDiffs[0] = 0.0001; //fAir            295   //  densityDiffs[0] = 0.0001; //fAir
260                                                   296 
261   //--- Calculate the average material density    297   //--- Calculate the average material density for each material/density bin
262   std::map<std::pair<G4Material*, G4int>, matI << 298   std::map< std::pair<G4Material*,G4int>, matInfo* > newMateDens;
263                                                   299 
264   G4double dens1;                                 300   G4double dens1;
265   G4int ifxmin1, ifxmax1;                         301   G4int ifxmin1, ifxmax1;
266                                                   302 
267   //---- Read the material densities              303   //---- Read the material densities
268   G4int copyNo = 0;                               304   G4int copyNo = 0;
269   for (G4int iz = 0; iz < fNoVoxelsZ; ++iz) {  << 305   for( G4int iz = 0; iz < fNVoxelZ; ++iz )
270     std::map<G4int, G4int> ifmin = fFilledMins << 306   {
271     std::map<G4int, G4int> ifmax = fFilledMaxs << 307     std::map< G4int, G4int > ifmin = fFilledMins[iz];
272     for (G4int iy = 0; iy < fNoVoxelsY; ++iy)  << 308     std::map< G4int, G4int > ifmax = fFilledMaxs[iz];
                                                   >> 309     for( G4int iy = 0; iy < fNVoxelY; ++iy )
                                                   >> 310     {
273       ifxmin1 = ifmin[iy];                        311       ifxmin1 = ifmin[iy];
274       ifxmax1 = ifmax[iy];                        312       ifxmax1 = ifmax[iy];
275       for (G4int ix = 0; ix < fNoVoxelsX; ++ix << 313       for( G4int ix = 0; ix < fNVoxelX; ++ix )
276         if (ix >= G4int(ifxmin1) && ix <= G4in << 314       {
                                                   >> 315         if( ix >= G4int(ifxmin1) && ix <= G4int(ifxmax1) ) {
277           fin >> dens1;                           316           fin >> dens1;
278           //--- store the minimum and maximum  << 317         //--- store the minimum and maximum density for each material
279           //(just for printing)                   318           //(just for printing)
280           mpite = densiMinMax.find(G4int(fMate << 319           mpite = densiMinMax.find( G4int(fMateIDs[copyNo]) );
281           if (dens1 < (*mpite).second.first) ( << 320           if( dens1 < (*mpite).second.first ) (*mpite).second.first = dens1;
282           if (dens1 > (*mpite).second.second)  << 321           if( dens1 > (*mpite).second.second ) (*mpite).second.second = dens1;
283                                                   322 
284           //--- Get material from original lis    323           //--- Get material from original list of material in file
285           G4int mateID = G4int(fMateIDs[copyNo    324           G4int mateID = G4int(fMateIDs[copyNo]);
286           G4Material* mate = fOriginalMaterial    325           G4Material* mate = fOriginalMaterials[mateID];
287           //        G4cout << copyNo << " mate    326           //        G4cout << copyNo << " mateID " << mateID << G4endl;
288           //--- Check if density is equal to t    327           //--- Check if density is equal to the original material density
289           if (std::fabs(dens1 - mate->GetDensi << 328           if( std::fabs(dens1 - mate->GetDensity()/g*cm3 ) < 1.e-9 ) continue;
290                                                   329 
291           //--- Build material name with fOrig    330           //--- Build material name with fOriginalMaterials name + density
292           //        float densityBin = density    331           //        float densityBin = densityDiffs[mateID] *
293           //        (G4int(dens1/densityDiffs[    332           //        (G4int(dens1/densityDiffs[mateID])+0.5);
294           G4String newMateName = mate->GetName    333           G4String newMateName = mate->GetName();
295                                                   334 
296           G4int densityBin = 0;                   335           G4int densityBin = 0;
297           //        G4cout << " densityBin " <    336           //        G4cout << " densityBin " << densityBin << " "
298           //        << dens1 << " " <<densityD    337           //        << dens1 << " " <<densityDiffs[mateID] << G4endl;
299                                                   338 
300           if (densityDiff != -1.) {            << 339           if( densityDiff != -1.) {
301             densityBin = (G4int(dens1 / densit << 340             densityBin = (G4int(dens1/densityDiffs[mateID]));
302             newMateName = mate->GetName() + G4 << 341             newMateName =
                                                   >> 342               mate->GetName()+G4UIcommand::ConvertToString(densityBin);
303           }                                       343           }
304                                                   344 
305           //--- Look if it is the first voxel     345           //--- Look if it is the first voxel with this material/densityBin
306           std::pair<G4Material*, G4int> matden << 346           std::pair<G4Material*,G4int> matdens(mate, densityBin );
307                                                   347 
308           auto mppite = newMateDens.find(matde << 348           auto mppite = newMateDens.find( matdens );
309           if (mppite != newMateDens.cend()) {  << 349           if( mppite != newMateDens.cend() ){
310             matInfo* mi = (*mppite).second;       350             matInfo* mi = (*mppite).second;
311             mi->fSumdens += dens1;                351             mi->fSumdens += dens1;
312             mi->fNvoxels++;                       352             mi->fNvoxels++;
313             fMateIDs[copyNo] = fOriginalMateri << 353             fMateIDs[copyNo] = fOriginalMaterials.size()-1 + mi->fId;
314             //  G4cout << copyNo << " mat new  << 354           //  G4cout << copyNo << " mat new again "
315             //<< fOriginalMaterials.size()-1 + << 355           //<< fOriginalMaterials.size()-1 + mi->id << " " << mi->id << G4endl;
316           }                                    << 356           } else {
317           else {                               << 
318             matInfo* mi = new matInfo;            357             matInfo* mi = new matInfo;
319             mi->fSumdens = dens1;                 358             mi->fSumdens = dens1;
320             mi->fNvoxels = 1;                     359             mi->fNvoxels = 1;
321             mi->fId = G4int(newMateDens.size() << 360             mi->fId = G4int(newMateDens.size()+1);
322             newMateDens[matdens] = mi;            361             newMateDens[matdens] = mi;
323             fMateIDs[copyNo] = fOriginalMateri << 362             fMateIDs[copyNo] = fOriginalMaterials.size()-1 + mi->fId;
324             //          G4cout << copyNo << "     363             //          G4cout << copyNo << " mat new first "
325             //          << fOriginalMaterials.    364             //          << fOriginalMaterials.size()-1 + mi->fId << G4endl;
326           }                                       365           }
327           copyNo++;                               366           copyNo++;
328           //        G4cout << ix << " " << iy  << 367         //        G4cout << ix << " " << iy << " " << iz
329           //  << " filling fMateIDs " << copyN << 368         //  << " filling fMateIDs " << copyNo << " = " << atoi(cid)-1 << G4endl;
330           //        fMateIDs[copyNo] = atoi(ci << 369                                       //        fMateIDs[copyNo] = atoi(cid)-1;
331         }                                         370         }
332       }                                           371       }
333     }                                             372     }
334   }                                               373   }
335                                                   374 
336   //----- Build the list of phantom materials     375   //----- Build the list of phantom materials that go to Parameterisation
337   //--- Add original materials                    376   //--- Add original materials
338   for (auto mimite = fOriginalMaterials.cbegin << 377   for( auto mimite = fOriginalMaterials.cbegin();
339     fPhantomMaterials.push_back((*mimite));    << 378             mimite != fOriginalMaterials.cend(); ++mimite )
                                                   >> 379   {
                                                   >> 380     fPhantomMaterials.push_back( (*mimite) );
340   }                                               381   }
341   //                                              382   //
342   //---- Build and add new materials              383   //---- Build and add new materials
343   for (auto mppite = newMateDens.cbegin(); mpp << 384   for( auto mppite= newMateDens.cbegin();
344     G4double averdens = (*mppite).second->fSum << 385             mppite != newMateDens.cend(); ++mppite )
345     G4double saverdens = G4int(1000.001 * aver << 386   {
346     G4cout << "GmReadPhantomGeometry::ReadVoxe << 387     G4double averdens = (*mppite).second->fSumdens/(*mppite).second->fNvoxels;
347            << saverdens << " -> " << G4int(100 << 388     G4double saverdens = G4int(1000.001*averdens)/1000.;
348            << " " << G4int(1000 * averdens) /  << 389     G4cout << "GmReadPhantomGeometry::ReadVoxelDensities AVER DENS "
349                                                << 390            << averdens << " -> " << saverdens << " -> "
350     G4cout << "GmReadPhantomGeometry::ReadVoxe << 391            << G4int(1000*averdens) << " " << G4int(1000*averdens)/1000 << " "
351            << saverdens << " -> " << G4UIcomma << 392            <<  G4int(1000*averdens)/1000. << G4endl;
352            << (*mppite).second->fNvoxels << G4 << 393 
353     G4String mateName =                        << 394     G4cout << "GmReadPhantomGeometry::ReadVoxelDensities AVER DENS "
354       ((*mppite).first).first->GetName() + "_" << 395            << averdens << " -> "  << saverdens << " -> "
355     fPhantomMaterials.push_back(               << 396            << G4UIcommand::ConvertToString(saverdens) << " Nvoxels "
356       BuildMaterialWithChangingDensity((*mppit << 397     <<(*mppite).second->fNvoxels << G4endl;
                                                   >> 398     G4String mateName = ((*mppite).first).first->GetName() + "_" +
                                                   >> 399     G4UIcommand::ConvertToString(saverdens);
                                                   >> 400     fPhantomMaterials.push_back( BuildMaterialWithChangingDensity(
                                                   >> 401                                   (*mppite).first.first,
                                                   >> 402                                  G4float(averdens), mateName ) );
357   }                                               403   }
358 }                                                 404 }
359                                                   405 
360 //....oooOO0OOooo........oooOO0OOooo........oo    406 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
361 void DicomPartialDetectorConstruction::Constru    407 void DicomPartialDetectorConstruction::ConstructPhantomContainer()
362 {                                                 408 {
363   // build a clinder that encompass the partia << 409   //build a clinder that encompass the partial phantom built in the example
364   //  /dicom/intersectWithUserVolume 0. 0. 0.  << 410   // /dicom/intersectWithUserVolume 0. 0. 0. 0.*deg 0. 0. TUBE 0. 200. 100.
365   //---- Extract number of voxels and voxel di    411   //---- Extract number of voxels and voxel dimensions
366                                                   412 
367   G4String contname = "PhantomContainer";      << 413   G4String contname= "PhantomContainer";
368                                                   414 
369   //----- Define the volume that contains all     415   //----- Define the volume that contains all the voxels
370   G4Tubs* container_tube = new G4Tubs(contname << 416   G4Tubs* container_tube = new G4Tubs(contname,0., 200., 100., 0., 360*deg);
371                                                   417 
372   fContainer_logic = new G4LogicalVolume(conta << 418   fContainer_logic =
                                                   >> 419     new G4LogicalVolume( container_tube,
                                                   >> 420                          fAir,
                                                   >> 421                          contname,
                                                   >> 422                          0, 0, 0 );
373                                                   423 
374   G4ThreeVector posCentreVoxels(0., 0., 0.);   << 424   G4ThreeVector posCentreVoxels(0.,0.,0.);
375   // G4cout << " PhantomContainer posCentreVox << 425   //G4cout << " PhantomContainer posCentreVoxels " << posCentreVoxels << G4endl;
376   G4RotationMatrix* rotm = new G4RotationMatri    426   G4RotationMatrix* rotm = new G4RotationMatrix;
377                                                   427 
378   fContainer_phys = new G4PVPlacement(rotm,  / << 428   fContainer_phys =
379                                       posCentr << 429     new G4PVPlacement(rotm,  // rotation
380                                       fContain << 430                       posCentreVoxels,
381                                       contname << 431                       fContainer_logic,     // The logic volume
382                                       fWorld_l << 432                       contname,  // Name
383                                       false,   << 433                       fWorld_logic,  // Mother
384                                       1);  //  << 434                       false,           // No op. bool.
                                                   >> 435                       1);              // Copy number
                                                   >> 436 
385 }                                                 437 }
386                                                   438 
387 //....oooOO0OOooo........oooOO0OOooo........oo    439 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
388 void DicomPartialDetectorConstruction::Constru    440 void DicomPartialDetectorConstruction::ConstructPhantom()
389 {                                                 441 {
390   G4String OptimAxis = "kXAxis";                  442   G4String OptimAxis = "kXAxis";
391   G4bool bSkipEqualMaterials = 0;                 443   G4bool bSkipEqualMaterials = 0;
392   G4int regStructureID = 2;                       444   G4int regStructureID = 2;
393                                                   445 
394   G4ThreeVector posCentreVoxels(0., 0., 0.);   << 446   G4ThreeVector posCentreVoxels(0.,0.,0.);
395                                                   447 
396   //----- Build phantom                           448   //----- Build phantom
397   G4String voxelName = "phantom";                 449   G4String voxelName = "phantom";
398   G4Box* phantom_solid = new G4Box(voxelName,  << 450   G4Box* phantom_solid = new G4Box(voxelName, fDimX/2., fDimY/2., fDimZ/2. );
399   G4LogicalVolume* phantom_logic = new G4Logic << 451   G4LogicalVolume* phantom_logic =
                                                   >> 452     new G4LogicalVolume( phantom_solid,
                                                   >> 453                          fAir,
                                                   >> 454                          voxelName,
                                                   >> 455                          0, 0, 0 );
400   G4bool pVis = 0;                                456   G4bool pVis = 0;
401   if (!pVis) {                                 << 457   if( !pVis ) {
402     G4VisAttributes* visAtt = new G4VisAttribu << 458     G4VisAttributes* visAtt = new G4VisAttributes( FALSE );
403     phantom_logic->SetVisAttributes(visAtt);   << 459     phantom_logic->SetVisAttributes( visAtt );
404   }                                               460   }
405                                                   461 
406   G4double theSmartless = 0.5;                    462   G4double theSmartless = 0.5;
407   //  fContainer_logic->SetSmartless( theSmart    463   //  fContainer_logic->SetSmartless( theSmartless );
408   phantom_logic->SetSmartless(theSmartless);   << 464   phantom_logic->SetSmartless( theSmartless );
409                                                   465 
410   fPartialPhantomParam = new G4PartialPhantomP    466   fPartialPhantomParam = new G4PartialPhantomParameterisation();
411                                                   467 
412   fPartialPhantomParam->SetMaterials(fPhantomM << 468   fPartialPhantomParam->SetMaterials( fPhantomMaterials );
413   fPartialPhantomParam->SetVoxelDimensions(fDi << 469   fPartialPhantomParam->SetVoxelDimensions( fDimX/2., fDimY/2., fDimZ/2. );
414   fPartialPhantomParam->SetNoVoxels(fNoVoxelsX << 470   fPartialPhantomParam->SetNoVoxel( fNVoxelX, fNVoxelY, fNVoxelZ );
415   fPartialPhantomParam->SetMaterialIndices(fMa << 471   fPartialPhantomParam->SetMaterialIndices( fMateIDs );
416                                                   472 
417   fPartialPhantomParam->SetFilledIDs(fFilledID    473   fPartialPhantomParam->SetFilledIDs(fFilledIDs);
418                                                   474 
419   fPartialPhantomParam->SetFilledMins(fFilledM    475   fPartialPhantomParam->SetFilledMins(fFilledMins);
420                                                   476 
421   fPartialPhantomParam->BuildContainerWalls();    477   fPartialPhantomParam->BuildContainerWalls();
422                                                   478 
423   //  G4cout << " Number of Materials " << fPh    479   //  G4cout << " Number of Materials " << fPhantomMaterials.size() << G4endl;
424   //  G4cout << " SetMaterialIndices(0) " << f    480   //  G4cout << " SetMaterialIndices(0) " << fMateIDs[0] << G4endl;
425                                                   481 
426   G4PVParameterised* phantom_phys = 0;         << 482   G4PVParameterised * phantom_phys = 0;
427   if (OptimAxis == "kUndefined") {             << 483   if( OptimAxis == "kUndefined" ) {
428     phantom_phys = new G4PVParameterised(voxel << 484     phantom_phys =
429                                          fNoVo << 485       new G4PVParameterised(voxelName,phantom_logic,fContainer_logic,
430   }                                            << 486                             kUndefined, fNVoxels, fPartialPhantomParam);
431   else if (OptimAxis == "kXAxis") {            << 487   } else   if( OptimAxis == "kXAxis" ) {
432     //    G4cout << " optim kX " << G4endl;       488     //    G4cout << " optim kX " << G4endl;
433     phantom_phys = new G4PVParameterised(voxel << 489     phantom_phys =
434                                          fNoVo << 490       new G4PVParameterised(voxelName,phantom_logic,fContainer_logic,
                                                   >> 491                             kXAxis, fNVoxels, fPartialPhantomParam);
435     fPartialPhantomParam->SetSkipEqualMaterial    492     fPartialPhantomParam->SetSkipEqualMaterials(bSkipEqualMaterials);
436   }                                            << 493   } else {
437   else {                                       << 494     G4Exception("GmReadPhantomGeometry::ConstructPhantom",
438     G4Exception("GmReadPhantomGeometry::Constr << 495                 "",
                                                   >> 496                 FatalErrorInArgument,
439                 G4String("Wrong argument to pa    497                 G4String("Wrong argument to parameter \
440          GmReadPhantomGeometry:Phantom:OptimAx    498          GmReadPhantomGeometry:Phantom:OptimAxis: \
441          Only allowed 'kUndefined' or 'kXAxis' << 499          Only allowed 'kUndefined' or 'kXAxis', it is: "+OptimAxis).c_str());
442                          + OptimAxis)          << 
443                   .c_str());                   << 
444   }                                               500   }
445                                                   501 
446   phantom_phys->SetRegularStructureId(regStruc    502   phantom_phys->SetRegularStructureId(regStructureID);
                                                   >> 503 
447 }                                                 504 }
448                                                   505