61 fPartialPhantomParam(0),
108 ConstructPhantomContainer();
115 void DicomPartialDetectorConstruction::ReadPhantomData()
118 std::ifstream finDF(dataFile.c_str());
120 if(finDF.good() != 1 ) {
121 G4Exception(
" DicomPartialDetectorConstruction::ReadPhantomData",
124 " Problem reading data file: Data.dat");
128 finDF >> compression;
132 if( numFiles != 1 ) {
133 G4Exception(
"DicomPartialDetectorConstruction::ReadPhantomData",
136 "More than 1 DICOM file is not supported");
138 for(
G4int i = 0; i < numFiles; i++ ) {
142 ReadPhantomDataFile(fname);
149 void DicomPartialDetectorConstruction::ReadPhantomDataFile(
154 G4cout <<
" DicomDetectorConstruction::ReadPhantomDataFile opening file "
157 std::ifstream fin(fname.c_str(), std::ios_base::in);
158 if( !fin.is_open() ) {
159 G4Exception(
"DicomPartialDetectorConstruction::ReadPhantomDataFile",
162 G4String(
"File not found " + fname).c_str());
168 for(
G4int ii = 0; ii < nMaterials; ii++ ){
169 fin >> nmate >> stemp;
170 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData reading nmate "
171 << ii <<
" = " << nmate <<
" mate " << stemp <<
G4endl;
173 G4Exception(
"DicomPartialDetectorConstruction::ReadPhantomData",
176 "Material number should be in increasing order: \
177 wrong material number ");
182 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData nVoxel X/Y/Z "
184 fin >> fOffsetX >> fDimX;
185 fDimX = (fDimX - fOffsetX)/
fNVoxelX;
186 fin >> fOffsetY >> fDimY;
187 fDimY = (fDimY - fOffsetY)/
fNVoxelY;
188 fin >> fOffsetZ >> fDimZ;
189 fDimZ = (fDimZ - fOffsetZ)/fNVoxelZ;
190 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData voxelDimX "
191 << fDimX <<
" fOffsetX " << fOffsetX <<
G4endl;
192 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData voxelDimY "
193 << fDimY <<
" fOffsetY " << fOffsetY <<
G4endl;
194 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData voxelDimZ "
195 << fDimZ <<
" fOffsetZ " << fOffsetZ <<
G4endl;
202 int ifxmin1, ifxmax1;
204 std::map< G4int, G4int > ifmin, ifmax;
206 fin >> ifxmin1 >> ifxmax1;
211 G4int ifxdiff = ifxmax1-ifxmin1+1;
212 if( ifxmax1 == -1 && ifxmin1 == -1 ) ifxdiff = 0;
213 fFilledIDs.insert(std::pair<size_t,size_t>(ifxdiff+fNVoxels-1, ifxmin1));
214 G4cout <<
"DicomPartialDetectorConstruction::ReadPhantomData insert "
215 <<
" FilledIDs " << ifxdiff+fNVoxels-1 <<
" min " << ifxmin1
216 <<
" N= " << fFilledIDs.size() <<
G4endl;
219 if( ix >=
G4int(ifxmin1) && ix <=
G4int(ifxmax1) ) {
225 fFilledMins[iz] = ifmin;
226 fFilledMaxs[iz] = ifmax;
231 fMateIDs =
new size_t[fNVoxelX*fNVoxelY*
fNVoxelZ];
234 std::map< G4int, G4int > ifmin = fFilledMins[iz];
235 std::map< G4int, G4int > ifmax = fFilledMaxs[iz];
240 if( ix >=
G4int(ifxmin1) && ix <=
G4int(ifxmax1) ) {
242 if( mateID1 < 0 || mateID1 >= nMaterials ) {
243 G4Exception(
"DicomPartialDetectorConstruction::ReadPhantomData",
246 G4String(
"Wrong index in phantom file: It should be between 0 and "
251 fMateIDs[copyNo] = mateID1;
258 ReadVoxelDensitiesPartial( fin );
264 void DicomPartialDetectorConstruction::ReadVoxelDensitiesPartial( std::ifstream& fin )
266 std::map<G4int, std::pair<G4double,G4double> > densiMinMax;
267 std::map<G4int, std::pair<G4double,G4double> >::iterator mpite;
274 char* part = getenv(
"DICOM_CHANGE_MATERIAL_DENSITY" );
277 std::map<G4int,G4double> densityDiffs;
278 if( densityDiff != -1. ) {
280 densityDiffs[ii] = densityDiff;
293 std::map< std::pair<G4Material*,G4int>,
matInfo* > newMateDens;
296 size_t ifxmin1, ifxmax1;
301 std::map< G4int, G4int > ifmin = fFilledMins[iz];
302 std::map< G4int, G4int > ifmax = fFilledMaxs[iz];
307 if( ix >=
G4int(ifxmin1) && ix <=
G4int(ifxmax1) ) {
311 mpite = densiMinMax.find( fMateIDs[copyNo] );
312 if( dens1 < (*mpite).second.first ) (*mpite).second.first = dens1;
313 if( dens1 > (*mpite).second.second ) (*mpite).second.second = dens1;
316 int mateID = fMateIDs[copyNo];
320 if( std::fabs(dens1 - mate->
GetDensity()/
g*
cm3 ) < 1.e-9 )
continue;
327 G4int densityBin = 0;
331 if( densityDiff != -1.) {
332 densityBin = (
G4int(dens1/densityDiffs[mateID]));
338 std::pair<G4Material*,G4int> matdens(mate, densityBin );
340 std::map< std::pair<G4Material*,G4int>,
matInfo* >::iterator mppite
341 = newMateDens.find( matdens );
342 if( mppite != newMateDens.end() ){
343 matInfo* mi = (*mppite).second;
353 mi->
fId = newMateDens.size()+1;
354 newMateDens[matdens] = mi;
370 std::vector<G4Material*>::const_iterator mimite;
373 fPhantomMaterials.push_back( (*mimite) );
377 std::map< std::pair<G4Material*,G4int>,
matInfo* >::iterator mppite;
378 for( mppite= newMateDens.begin(); mppite != newMateDens.end(); mppite++ ){
381 G4cout <<
"GmReadPhantomGeometry::ReadVoxelDensities AVER DENS "
382 << averdens <<
" -> " << saverdens <<
" -> "
383 <<
G4int(1000*averdens) <<
" " <<
G4int(1000*averdens)/1000 <<
" "
386 G4cout <<
"GmReadPhantomGeometry::ReadVoxelDensities AVER DENS "
387 << averdens <<
" -> " << saverdens <<
" -> "
389 <<(*mppite).second->fNvoxels <<
G4endl;
390 G4String mateName = ((*mppite).first).
first->GetName() +
"_" +
393 (*mppite).first.first,
394 averdens, mateName ) );
400 void DicomPartialDetectorConstruction::ConstructPhantomContainer()
406 G4String contname=
"PhantomContainer";
409 G4Tubs* container_tube =
new G4Tubs(contname,0., 200., 100., 0., 360*
deg);
433 void DicomPartialDetectorConstruction::ConstructPhantom()
436 G4bool bSkipEqualMaterials = 0;
437 G4int regStructureID = 2;
443 G4Box* phantom_solid =
new G4Box(voxelName, fDimX/2., fDimY/2., fDimZ/2. );
461 fPartialPhantomParam->
SetMaterials( fPhantomMaterials );
463 fPartialPhantomParam->
SetNoVoxel( fNVoxelX, fNVoxelY, fNVoxelZ );
476 if( OptimAxis ==
"kUndefined" ) {
480 }
else if( OptimAxis ==
"kXAxis" ) {
485 kXAxis, fNVoxels, fPartialPhantomParam);
488 G4Exception(
"GmReadPhantomGeometry::ConstructPhantom",
491 G4String(
"Wrong argument to parameter \
492 GmReadPhantomGeometry:Phantom:OptimAxis: \
493 Only allowed 'kUndefined' or 'kXAxis', it is: "+OptimAxis).c_str());
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
G4LogicalVolume * fWorld_logic
const G4String & GetName() const
G4double GetDensity() const
static G4String ConvertToString(G4bool boolVal)
void SetFilledIDs(std::multimap< G4int, G4int > fid)
G4LogicalVolume * fContainer_logic
void InitialisationOfMaterials()
~DicomPartialDetectorConstruction()
G4Material * BuildMaterialWithChangingDensity(const G4Material *origMate, float density, G4String newMateName)
G4GLOB_DLL std::ostream G4cout
static constexpr double m
void SetVoxelDimensions(G4double halfx, G4double halfy, G4double halfz)
Definition of the DicomPartialDetectorConstruction class.
void SetFilledMins(std::map< G4int, std::map< G4int, G4int > > fmins)
static G4double ConvertToDouble(const char *st)
static constexpr double cm3
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
virtual void SetRegularStructureId(G4int Code)
G4VPhysicalVolume * fContainer_phys
virtual G4VPhysicalVolume * Construct()
void SetSmartless(G4double s)
void BuildContainerWalls()
void SetNoVoxel(size_t nx, size_t ny, size_t nz)
void SetMaterialIndices(size_t *matInd)
DicomPartialDetectorConstruction()
void SetMaterials(std::vector< G4Material * > &mates)
std::vector< G4Material * > fMaterials
static constexpr double deg
std::vector< G4Material * > fOriginalMaterials
void SetVisAttributes(const G4VisAttributes *pVA)
void SetSkipEqualMaterials(G4bool skip)