source: trunk/source/geometry/navigation/src/G4PhantomParameterisation.cc@ 961

Last change on this file since 961 was 831, checked in by garnier, 17 years ago

import all except CVS

  • Property svn:executable set to *
File size: 12.6 KB
Line 
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//
27// $Id: G4PhantomParameterisation.cc,v 1.4 2008/01/22 15:02:36 gcosmo Exp $
28// GEANT4 tag $ Name:$
29//
30// class G4PhantomParameterisation implementation
31//
32// May 2007 Pedro Arce, first version
33//
34// --------------------------------------------------------------------
35
36#include "G4PhantomParameterisation.hh"
37
38#include "globals.hh"
39#include "G4VSolid.hh"
40#include "G4VPhysicalVolume.hh"
41#include "G4LogicalVolume.hh"
42#include "G4VVolumeMaterialScanner.hh"
43#include "G4GeometryTolerance.hh"
44
45//------------------------------------------------------------------
46G4PhantomParameterisation::G4PhantomParameterisation()
47{
48 // Initialise data
49 //
50 fMaterialIndices = 0;
51 fContainerWallX = 0.;
52 fContainerWallY = 0.;
53 fContainerWallZ = 0.;
54
55 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
56
57 bSkipEqualMaterials = 1;
58}
59
60
61//------------------------------------------------------------------
62G4PhantomParameterisation::~G4PhantomParameterisation()
63{
64}
65
66
67//------------------------------------------------------------------
68void G4PhantomParameterisation::
69BuildContainerSolid( G4VPhysicalVolume *pMotherPhysical )
70{
71 fContainerSolid = pMotherPhysical->GetLogicalVolume()->GetSolid();
72 fContainerWallX = fNoVoxelX * fVoxelHalfX;
73 fContainerWallY = fNoVoxelY * fVoxelHalfY;
74 fContainerWallZ = fNoVoxelZ * fVoxelHalfZ;
75
76 // CheckVoxelsFillContainer();
77}
78
79
80//------------------------------------------------------------------
81void G4PhantomParameterisation::
82ComputeTransformation(const G4int copyNo, G4VPhysicalVolume *physVol ) const
83{
84 // Voxels cannot be rotated, return translation
85 //
86 G4ThreeVector trans = GetTranslation( copyNo );
87
88 physVol->SetTranslation( trans );
89}
90
91
92//------------------------------------------------------------------
93G4ThreeVector G4PhantomParameterisation::
94GetTranslation(const G4int copyNo ) const
95{
96 CheckCopyNo( copyNo );
97
98 size_t nx;
99 size_t ny;
100 size_t nz;
101
102 ComputeVoxelIndices( copyNo, nx, ny, nz );
103
104 G4ThreeVector trans( (2*nx+1)*fVoxelHalfX - fContainerWallX,
105 (2*ny+1)*fVoxelHalfY - fContainerWallY,
106 (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
107 return trans;
108}
109
110
111//------------------------------------------------------------------
112G4VSolid* G4PhantomParameterisation::
113ComputeSolid(const G4int, G4VPhysicalVolume *pPhysicalVol)
114{
115 return pPhysicalVol->GetLogicalVolume()->GetSolid();
116}
117
118
119//------------------------------------------------------------------
120G4Material* G4PhantomParameterisation::
121ComputeMaterial(const G4int copyNo, G4VPhysicalVolume *, const G4VTouchable *)
122{
123 CheckCopyNo( copyNo );
124 size_t matIndex = GetMaterialIndex(copyNo);
125
126 return fMaterials[ matIndex ];
127}
128
129
130//------------------------------------------------------------------
131size_t G4PhantomParameterisation::
132GetMaterialIndex( size_t copyNo ) const
133{
134 CheckCopyNo( copyNo );
135
136 return *(fMaterialIndices+copyNo);
137}
138
139
140//------------------------------------------------------------------
141size_t G4PhantomParameterisation::
142GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
143{
144 size_t copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
145 return GetMaterialIndex( copyNo );
146}
147
148
149//------------------------------------------------------------------
150G4Material* G4PhantomParameterisation::GetMaterial( size_t nx, size_t ny, size_t nz) const
151{
152 return fMaterials[GetMaterialIndex(nx,ny,nz)];
153}
154
155//------------------------------------------------------------------
156G4Material* G4PhantomParameterisation::GetMaterial( size_t copyNo ) const
157{
158 return fMaterials[GetMaterialIndex(copyNo)];
159}
160
161//------------------------------------------------------------------
162void G4PhantomParameterisation::
163ComputeVoxelIndices(const G4int copyNo, size_t& nx,
164 size_t& ny, size_t& nz ) const
165{
166 CheckCopyNo( copyNo );
167 nx = size_t(copyNo%fNoVoxelX);
168 ny = size_t( (copyNo/fNoVoxelX)%fNoVoxelY );
169 nz = size_t(copyNo/fNoVoxelXY);
170}
171
172
173//------------------------------------------------------------------
174void G4PhantomParameterisation::
175CheckVoxelsFillContainer( G4double contX, G4double contY, G4double contZ ) const
176{
177 G4double toleranceForWarning = 0.25*kCarTolerance;
178
179 // Any bigger value than 0.25*kCarTolerance will give a warning in
180 // G4NormalNavigation::ComputeStep(), because the Inverse of a container
181 // translation that is Z+epsilon gives -Z+epsilon (and the maximum tolerance
182 // in G4Box::Inside is 0.5*kCarTolerance
183 //
184 G4double toleranceForError = 1.*kCarTolerance;
185
186 // Any bigger value than kCarTolerance will give an error in GetReplicaNo()
187 //
188 if( std::fabs(contX-fNoVoxelX*fVoxelHalfX) >= toleranceForError
189 || std::fabs(contY-fNoVoxelY*fVoxelHalfY) >= toleranceForError
190 || std::fabs(contZ-fNoVoxelZ*fVoxelHalfZ) >= toleranceForError )
191 {
192 G4cerr << "ERROR - G4PhantomParameterisation::CheckVoxelsFillContainer()"
193 << G4endl
194 << " Voxels do not fully fill the container: "
195 << fContainerSolid->GetName() << G4endl
196 << " DiffX= " << contX-fNoVoxelX*fVoxelHalfX << G4endl
197 << " DiffY= " << contY-fNoVoxelY*fVoxelHalfY << G4endl
198 << " DiffZ= " << contZ-fNoVoxelZ*fVoxelHalfZ << G4endl
199 << " Maximum difference is: " << toleranceForError << G4endl;
200 G4Exception("G4PhantomParameterisation::CheckVoxelsFillContainer()",
201 "InvalidSetup", FatalException,
202 "Voxels do not fully fill the container!");
203
204 }
205 else if( std::fabs(contX-fNoVoxelX*fVoxelHalfX) >= toleranceForWarning
206 || std::fabs(contY-fNoVoxelY*fVoxelHalfY) >= toleranceForWarning
207 || std::fabs(contZ-fNoVoxelZ*fVoxelHalfZ) >= toleranceForWarning )
208 {
209 G4cerr << "WARNING - G4PhantomParameterisation::CheckVoxelsFillContainer()"
210 << G4endl
211 << " Voxels do not fully fill the container: "
212 << fContainerSolid->GetName() << G4endl
213 << " DiffX= " << contX-fNoVoxelX*fVoxelHalfX << G4endl
214 << " DiffY= " << contY-fNoVoxelY*fVoxelHalfY << G4endl
215 << " DiffZ= " << contZ-fNoVoxelZ*fVoxelHalfZ << G4endl
216 << " Maximum difference is: " << toleranceForWarning
217 << G4endl;
218 G4Exception("G4PhantomParameterisation::CheckVoxelsFillContainer()",
219 "InvalidSetup", JustWarning,
220 "Voxels do not fully fill the container!");
221 }
222}
223
224
225//------------------------------------------------------------------
226G4int G4PhantomParameterisation::
227GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
228{
229
230 // Check first that point is really inside voxels
231 //
232 if( fContainerSolid->Inside( localPoint ) == kOutside )
233 {
234 G4cerr << "ERROR - G4PhantomParameterisation::GetReplicaNo()" << G4endl
235 << " localPoint - " << localPoint
236 << " - is outside container solid: "
237 << fContainerSolid->GetName() << G4endl;
238 G4Exception("G4PhantomParameterisation::GetReplicaNo()", "InvalidSetup",
239 FatalErrorInArgument, "Point outside voxels!");
240 }
241
242 // Check the voxel numbers corresponding to localPoint
243 // When a particle is on a surface, it may be between -kCarTolerance and
244 // +kCartolerance. By a simple distance as:
245 // G4int nx = G4int( (localPoint.x()+)/fVoxelHalfX/2.);
246 // those between -kCartolerance and 0 will be placed on voxel N-1 and those
247 // between 0 and kCarTolerance on voxel N.
248 // To avoid precision problems place the tracks that are on the surface on
249 // voxel N-1 if they have negative direction and on voxel N if they have
250 // positive direction.
251 // Add +kCarTolerance so that they are first placed on voxel N, and then
252 // if the direction is negative substract 1
253
254 G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
255 G4int nx = G4int(fx);
256
257 G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
258 G4int ny = G4int(fy);
259
260 G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
261 G4int nz = G4int(fz);
262
263 // If it is on the surface side, check the direction: if direction is
264 // negative place it on the previous voxel (if direction is positive it is
265 // already in the next voxel...).
266 // Correct also cases where n = -1 or n = fNoVoxel. It is always traced to be
267 // due to multiple scattering: track is entering a voxel but multiple
268 // scattering changes the angle towards outside
269 //
270 if( fx - nx < kCarTolerance/fVoxelHalfX )
271 {
272 if( localDir.x() < 0 )
273 {
274 if( nx != 0 )
275 {
276 nx -= 1;
277 }
278 }
279 else
280 {
281 if( nx == G4int(fNoVoxelX) )
282 {
283 nx -= 1;
284 }
285 }
286 }
287 if( fy - ny < kCarTolerance/fVoxelHalfY )
288 {
289 if( localDir.y() < 0 )
290 {
291 if( ny != 0 )
292 {
293 ny -= 1;
294 }
295 }
296 else
297 {
298 if( ny == G4int(fNoVoxelY) )
299 {
300 ny -= 1;
301 }
302 }
303 }
304 if( fz - nz < kCarTolerance/fVoxelHalfZ )
305 {
306 if( localDir.z() < 0 )
307 {
308 if( nz != 0 )
309 {
310 nz -= 1;
311 }
312 }
313 else
314 {
315 if( nz == G4int(fNoVoxelZ) )
316 {
317 nz -= 1;
318 }
319 }
320 }
321
322 G4int copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
323
324 // Check if there are still errors
325 //
326 G4bool isOK = true;
327 if( nx < 0 )
328 {
329 nx = 0;
330 isOK = false;
331 }
332 else if( nx >= G4int(fNoVoxelX) )
333 {
334 nx = fNoVoxelX-1;
335 isOK = false;
336 }
337 if( ny < 0 )
338 {
339 ny = 0;
340 isOK = false;
341 }
342 else if( ny >= G4int(fNoVoxelY) )
343 {
344 ny = fNoVoxelY-1;
345 isOK = false;
346 }
347 if( nz < 0 )
348 {
349 nz = 0;
350 isOK = false;
351 }
352 else if( nz >= G4int(fNoVoxelZ) )
353 {
354 nz = fNoVoxelZ-1;
355 isOK = false;
356 }
357 if( !isOK )
358 {
359 G4cerr << "WARNING - G4PhantomParameterisation::GetReplicaNo()" << G4endl
360 << " LocalPoint: " << localPoint << G4endl
361 << " LocalDir: " << localDir << G4endl
362 << " Voxel container size: " << fContainerWallX
363 << " " << fContainerWallY << " " << fContainerWallZ << G4endl
364 << " LocalPoint - wall: "
365 << localPoint.x()-fContainerWallX << " "
366 << localPoint.y()-fContainerWallY << " "
367 << localPoint.z()-fContainerWallZ << G4endl;
368 G4Exception("G4PhantomParameterisation::GetReplicaNo()",
369 "Wrong-copy-number", JustWarning,
370 "Corrected the copy number! It was negative or too big");
371 copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
372 }
373
374 // CheckCopyNo( copyNo ); // not needed, just for debugging code
375
376 return copyNo;
377}
378
379
380//------------------------------------------------------------------
381void G4PhantomParameterisation::CheckCopyNo( const G4int copyNo ) const
382{
383 if( copyNo < 0 || copyNo >= G4int(fNoVoxel) )
384 {
385 G4cerr << "ERROR - G4PhantomParameterisation::CheckCopyNo()" << G4endl
386 << " Copy number: " << copyNo << G4endl
387 << " Total number of voxels: " << fNoVoxel << G4endl;
388 G4Exception("G4PhantomParameterisation::CheckCopyNo()",
389 "Wrong-copy-number", FatalErrorInArgument,
390 "Copy number is negative or too big!");
391 }
392}
Note: See TracBrowser for help on using the repository browser.