Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PartialPhantomParameterisation.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// class G4PartialPhantomParameterisation implementation
27//
28// May 2007 Pedro Arce (CIEMAT), first version
29// --------------------------------------------------------------------
30
32
33#include "globals.hh"
34#include "G4Material.hh"
35#include "G4VSolid.hh"
36#include "G4VPhysicalVolume.hh"
37#include "G4LogicalVolume.hh"
40
41#include <list>
42
43//------------------------------------------------------------------
47
48
49//------------------------------------------------------------------
51
52//------------------------------------------------------------------
54ComputeTransformation( const G4int copyNo, G4VPhysicalVolume *physVol ) const
55{
56 // Voxels cannot be rotated, return translation
57 //
58 G4ThreeVector trans = GetTranslation( copyNo );
59 physVol->SetTranslation( trans );
60}
61
62
63//------------------------------------------------------------------
65GetTranslation(const G4int copyNo ) const
66{
67 CheckCopyNo( copyNo );
68
69 std::size_t nx, ny, nz;
70 ComputeVoxelIndices( copyNo, nx, ny, nz );
71
74 (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
75 return trans;
76}
77
78
79//------------------------------------------------------------------
81ComputeMaterial( const G4int copyNo, G4VPhysicalVolume*, const G4VTouchable* )
82{
83 CheckCopyNo( copyNo );
84 auto matIndex = GetMaterialIndex(copyNo);
85
86 return fMaterials[ matIndex ];
87}
88
89
90//------------------------------------------------------------------
92GetMaterialIndex( std::size_t copyNo ) const
93{
94 CheckCopyNo( copyNo );
95
96 if( fMaterialIndices == nullptr ) { return 0; }
97
98 return *(fMaterialIndices+copyNo);
99}
100
101
102//------------------------------------------------------------------
104GetMaterialIndex( std::size_t nx, std::size_t ny, std::size_t nz ) const
105{
106 std::size_t copyNo = nx + fNoVoxelsX*ny + fNoVoxelsXY*nz;
107 return GetMaterialIndex( copyNo );
108}
109
110
111//------------------------------------------------------------------
113GetMaterial( std::size_t nx, std::size_t ny, std::size_t nz) const
114{
115 return fMaterials[GetMaterialIndex(nx,ny,nz)];
116}
117
118
119//------------------------------------------------------------------
121GetMaterial( std::size_t copyNo ) const
122{
123 return fMaterials[GetMaterialIndex(copyNo)];
124}
125
126
127//------------------------------------------------------------------
128void G4PartialPhantomParameterisation::
129ComputeVoxelIndices(const G4int copyNo, std::size_t& nx,
130 std::size_t& ny, std::size_t& nz ) const
131{
132 CheckCopyNo( copyNo );
133
134 auto ite = fFilledIDs.lower_bound(copyNo);
135 G4long dist = std::distance( fFilledIDs.cbegin(), ite );
136 nz = std::size_t( dist/fNoVoxelsY );
137 ny = std::size_t( dist%fNoVoxelsY );
138
139 G4int ifmin = (*ite).second;
140 G4int nvoxXprev;
141 if( dist != 0 )
142 {
143 ite--;
144 nvoxXprev = (*ite).first;
145 }
146 else
147 {
148 nvoxXprev = -1;
149 }
150
151 nx = ifmin+copyNo-nvoxXprev-1;
152}
153
154
155//------------------------------------------------------------------
157GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
158{
159 // Check the voxel numbers corresponding to localPoint
160 // When a particle is on a surface, it may be between -kCarTolerance and
161 // +kCartolerance. By a simple distance as:
162 // G4int nx = G4int( (localPoint.x()+)/fVoxelHalfX/2.);
163 // those between -kCartolerance and 0 will be placed on voxel N-1 and those
164 // between 0 and kCarTolerance on voxel N.
165 // To avoid precision problems place the tracks that are on the surface on
166 // voxel N-1 if they have negative direction and on voxel N if they have
167 // positive direction.
168 // Add +kCarTolerance so that they are first placed on voxel N, and then
169 // if the direction is negative substract 1
170
171 G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
172 auto nx = G4int(fx);
173
174 G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
175 auto ny = G4int(fy);
176
177 G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
178 auto nz = G4int(fz);
179
180 // If it is on the surface side, check the direction: if direction is
181 // negative place it on the previous voxel (if direction is positive it is
182 // already in the next voxel...).
183 // Correct also cases where n = -1 or n = fNoVoxels. It is always traced to be
184 // due to multiple scattering: track is entering a voxel but multiple
185 // scattering changes the angle towards outside
186 //
187 if( fx - nx < kCarTolerance/fVoxelHalfX )
188 {
189 if( localDir.x() < 0 )
190 {
191 if( nx != 0 )
192 {
193 nx -= 1;
194 }
195 }
196 else
197 {
198 if( nx == G4int(fNoVoxelsX) )
199 {
200 nx -= 1;
201 }
202 }
203 }
204 if( fy - ny < kCarTolerance/fVoxelHalfY )
205 {
206 if( localDir.y() < 0 )
207 {
208 if( ny != 0 )
209 {
210 ny -= 1;
211 }
212 }
213 else
214 {
215 if( ny == G4int(fNoVoxelsY) )
216 {
217 ny -= 1;
218 }
219 }
220 }
221 if( fz - nz < kCarTolerance/fVoxelHalfZ )
222 {
223 if( localDir.z() < 0 )
224 {
225 if( nz != 0 )
226 {
227 nz -= 1;
228 }
229 }
230 else
231 {
232 if( nz == G4int(fNoVoxelsZ) )
233 {
234 nz -= 1;
235 }
236 }
237 }
238
239 // Check if there are still errors
240 //
241 G4bool isOK = true;
242 if( nx < 0 )
243 {
244 nx = 0;
245 isOK = false;
246 }
247 else if( nx >= G4int(fNoVoxelsX) )
248 {
249 nx = G4int(fNoVoxelsX)-1;
250 isOK = false;
251 }
252 if( ny < 0 )
253 {
254 ny = 0;
255 isOK = false;
256 }
257 else if( ny >= G4int(fNoVoxelsY) )
258 {
259 ny = G4int(fNoVoxelsY)-1;
260 isOK = false;
261 }
262 if( nz < 0 )
263 {
264 nz = 0;
265 isOK = false;
266 }
267 else if( nz >= G4int(fNoVoxelsZ) )
268 {
269 nz = G4int(fNoVoxelsZ)-1;
270 isOK = false;
271 }
272 if( !isOK )
273 {
274 std::ostringstream message;
275 message << "Corrected the copy number! It was negative or too big."
276 << G4endl
277 << " LocalPoint: " << localPoint << G4endl
278 << " LocalDir: " << localDir << G4endl
279 << " Voxel container size: " << fContainerWallX
280 << " " << fContainerWallY << " " << fContainerWallZ << G4endl
281 << " LocalPoint - wall: "
282 << localPoint.x()-fContainerWallX << " "
283 << localPoint.y()-fContainerWallY << " "
284 << localPoint.z()-fContainerWallZ;
285 G4Exception("G4PartialPhantomParameterisation::GetReplicaNo()",
286 "GeomNav1002", JustWarning, message);
287 }
288
289 auto nyz = G4int(nz*fNoVoxelsY+ny);
290 auto ite = fFilledIDs.cbegin();
291/*
292 for( ite = fFilledIDs.cbegin(); ite != fFilledIDs.cend(); ++ite )
293 {
294 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo filled "
295 << (*ite).first << " , " << (*ite).second << std::endl;
296 }
297*/
298
299 advance(ite,nyz);
300 auto iteant = ite; iteant--;
301 G4int copyNo = (*iteant).first + 1 + ( nx - (*ite).second );
302/*
303 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo getting copyNo "
304 << copyNo << " nyz " << nyz << " (*iteant).first "
305 << (*iteant).first << " (*ite).second " << (*ite).second << G4endl;
306
307 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo " << copyNo
308 << " nx " << nx << " ny " << ny << " nz " << nz
309 << " localPoint " << localPoint << " localDir " << localDir << G4endl;
310*/
311 return copyNo;
312}
313
314
315//------------------------------------------------------------------
316void G4PartialPhantomParameterisation::CheckCopyNo( const G4long copyNo ) const
317{
318 if( copyNo < 0 || copyNo >= G4int(fNoVoxels) )
319 {
320 std::ostringstream message;
321 message << "Copy number is negative or too big!" << G4endl
322 << " Copy number: " << copyNo << G4endl
323 << " Total number of voxels: " << fNoVoxels;
324 G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
325 "GeomNav0002", FatalErrorInArgument, message);
326 }
327}
328
329
330//------------------------------------------------------------------
@ JustWarning
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
double z() const
double x() const
double y() const
std::size_t GetMaterialIndex(std::size_t nx, std::size_t ny, std::size_t nz) const
void ComputeTransformation(const G4int, G4VPhysicalVolume *) const override
G4Material * GetMaterial(std::size_t nx, std::size_t ny, std::size_t nz) const
G4int GetReplicaNo(const G4ThreeVector &localPoint, const G4ThreeVector &localDir) override
G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=nullptr) override
G4ThreeVector GetTranslation(const G4int copyNo) const
std::vector< G4Material * > fMaterials
void SetTranslation(const G4ThreeVector &v)