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 9.4.p2)


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