00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4PartialPhantomParameterisation.hh"
00037
00038 #include "globals.hh"
00039 #include "G4Material.hh"
00040 #include "G4VSolid.hh"
00041 #include "G4VPhysicalVolume.hh"
00042 #include "G4LogicalVolume.hh"
00043 #include "G4VVolumeMaterialScanner.hh"
00044 #include "G4GeometryTolerance.hh"
00045
00046 #include <list>
00047
00048
00049 G4PartialPhantomParameterisation::G4PartialPhantomParameterisation()
00050 : G4PhantomParameterisation()
00051 {
00052 }
00053
00054
00055
00056 G4PartialPhantomParameterisation::~G4PartialPhantomParameterisation()
00057 {
00058 }
00059
00060
00061 void G4PartialPhantomParameterisation::
00062 ComputeTransformation(const G4int copyNo, G4VPhysicalVolume *physVol ) const
00063 {
00064
00065
00066 G4ThreeVector trans = GetTranslation( copyNo );
00067 physVol->SetTranslation( trans );
00068 }
00069
00070
00071
00072 G4ThreeVector G4PartialPhantomParameterisation::
00073 GetTranslation(const G4int copyNo ) const
00074 {
00075 CheckCopyNo( copyNo );
00076
00077 size_t nx;
00078 size_t ny;
00079 size_t nz;
00080 ComputeVoxelIndices( copyNo, nx, ny, nz );
00081
00082 G4ThreeVector trans( (2*nx+1)*fVoxelHalfX - fContainerWallX,
00083 (2*ny+1)*fVoxelHalfY - fContainerWallY,
00084 (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
00085 return trans;
00086 }
00087
00088
00089
00090 G4Material* G4PartialPhantomParameterisation::
00091 ComputeMaterial(const G4int copyNo, G4VPhysicalVolume *, const G4VTouchable *)
00092 {
00093 CheckCopyNo( copyNo );
00094 size_t matIndex = GetMaterialIndex(copyNo);
00095
00096 return fMaterials[ matIndex ];
00097 }
00098
00099
00100
00101 size_t G4PartialPhantomParameterisation::
00102 GetMaterialIndex( size_t copyNo ) const
00103 {
00104 CheckCopyNo( copyNo );
00105
00106 if( !fMaterialIndices ) { return 0; }
00107
00108 return *(fMaterialIndices+copyNo);
00109 }
00110
00111
00112
00113 size_t G4PartialPhantomParameterisation::
00114 GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
00115 {
00116 size_t copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
00117 return GetMaterialIndex( copyNo );
00118 }
00119
00120
00121
00122 G4Material* G4PartialPhantomParameterisation::
00123 GetMaterial( size_t nx, size_t ny, size_t nz) const
00124 {
00125 return fMaterials[GetMaterialIndex(nx,ny,nz)];
00126 }
00127
00128
00129
00130 G4Material* G4PartialPhantomParameterisation::
00131 GetMaterial( size_t copyNo ) const
00132 {
00133 return fMaterials[GetMaterialIndex(copyNo)];
00134 }
00135
00136
00137
00138 void G4PartialPhantomParameterisation::
00139 ComputeVoxelIndices(const G4int copyNo, size_t& nx,
00140 size_t& ny, size_t& nz ) const
00141 {
00142 CheckCopyNo( copyNo );
00143
00144 std::multimap<G4int,G4int>::const_iterator ite =
00145 fFilledIDs.lower_bound(size_t(copyNo));
00146 G4int dist = std::distance( fFilledIDs.begin(), ite );
00147 nz = size_t(dist/fNoVoxelY);
00148 ny = size_t( dist%fNoVoxelY );
00149
00150 G4int ifmin = (*ite).second;
00151 G4int nvoxXprev;
00152 if( dist != 0 ) {
00153 ite--;
00154 nvoxXprev = (*ite).first;
00155 } else {
00156 nvoxXprev = -1;
00157 }
00158
00159 nx = ifmin+copyNo-nvoxXprev-1;
00160 }
00161
00162
00163
00164 G4int G4PartialPhantomParameterisation::
00165 GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
00166 {
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
00180 G4int nx = G4int(fx);
00181
00182 G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
00183 G4int ny = G4int(fy);
00184
00185 G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
00186 G4int nz = G4int(fz);
00187
00188
00189
00190
00191
00192
00193
00194
00195 if( fx - nx < kCarTolerance/fVoxelHalfX )
00196 {
00197 if( localDir.x() < 0 )
00198 {
00199 if( nx != 0 )
00200 {
00201 nx -= 1;
00202 }
00203 }
00204 else
00205 {
00206 if( nx == G4int(fNoVoxelX) )
00207 {
00208 nx -= 1;
00209 }
00210 }
00211 }
00212 if( fy - ny < kCarTolerance/fVoxelHalfY )
00213 {
00214 if( localDir.y() < 0 )
00215 {
00216 if( ny != 0 )
00217 {
00218 ny -= 1;
00219 }
00220 }
00221 else
00222 {
00223 if( ny == G4int(fNoVoxelY) )
00224 {
00225 ny -= 1;
00226 }
00227 }
00228 }
00229 if( fz - nz < kCarTolerance/fVoxelHalfZ )
00230 {
00231 if( localDir.z() < 0 )
00232 {
00233 if( nz != 0 )
00234 {
00235 nz -= 1;
00236 }
00237 }
00238 else
00239 {
00240 if( nz == G4int(fNoVoxelZ) )
00241 {
00242 nz -= 1;
00243 }
00244 }
00245 }
00246
00247
00248
00249 G4bool isOK = true;
00250 if( nx < 0 )
00251 {
00252 nx = 0;
00253 isOK = false;
00254 }
00255 else if( nx >= G4int(fNoVoxelX) )
00256 {
00257 nx = fNoVoxelX-1;
00258 isOK = false;
00259 }
00260 if( ny < 0 )
00261 {
00262 ny = 0;
00263 isOK = false;
00264 }
00265 else if( ny >= G4int(fNoVoxelY) )
00266 {
00267 ny = fNoVoxelY-1;
00268 isOK = false;
00269 }
00270 if( nz < 0 )
00271 {
00272 nz = 0;
00273 isOK = false;
00274 }
00275 else if( nz >= G4int(fNoVoxelZ) )
00276 {
00277 nz = fNoVoxelZ-1;
00278 isOK = false;
00279 }
00280 if( !isOK )
00281 {
00282 std::ostringstream message;
00283 message << "Corrected the copy number! It was negative or too big."
00284 << G4endl
00285 << " LocalPoint: " << localPoint << G4endl
00286 << " LocalDir: " << localDir << G4endl
00287 << " Voxel container size: " << fContainerWallX
00288 << " " << fContainerWallY << " " << fContainerWallZ << G4endl
00289 << " LocalPoint - wall: "
00290 << localPoint.x()-fContainerWallX << " "
00291 << localPoint.y()-fContainerWallY << " "
00292 << localPoint.z()-fContainerWallZ;
00293 G4Exception("G4PartialPhantomParameterisation::GetReplicaNo()",
00294 "GeomNav1002", JustWarning, message);
00295 }
00296
00297 G4int nyz = nz*fNoVoxelY+ny;
00298 std::multimap<G4int,G4int>::iterator ite = fFilledIDs.begin();
00299
00300
00301
00302
00303
00304
00305
00306 ite = fFilledIDs.begin();
00307
00308 advance(ite,nyz);
00309 std::multimap<G4int,G4int>::iterator iteant = ite; iteant--;
00310 G4int copyNo = (*iteant).first + 1 + ( nx - (*ite).second );
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 return copyNo;
00321 }
00322
00323
00324
00325 void G4PartialPhantomParameterisation::CheckCopyNo( const G4int copyNo ) const
00326 {
00327 if( copyNo < 0 || copyNo >= G4int(fNoVoxel) )
00328 {
00329 std::ostringstream message;
00330 message << "Copy number is negative or too big!" << G4endl
00331 << " Copy number: " << copyNo << G4endl
00332 << " Total number of voxels: " << fNoVoxel;
00333 G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
00334 "GeomNav0002", FatalErrorInArgument, message);
00335 }
00336 }
00337
00338
00339
00340 void G4PartialPhantomParameterisation::BuildContainerWalls()
00341 {
00342 fContainerWallX = fNoVoxelX * fVoxelHalfX;
00343 fContainerWallY = fNoVoxelY * fVoxelHalfY;
00344 fContainerWallZ = fNoVoxelZ * fVoxelHalfZ;
00345 }