Geant4-11
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//------------------------------------------------------------------
46{
47}
48
49
50//------------------------------------------------------------------
52{
53}
54
55//------------------------------------------------------------------
57ComputeTransformation( const G4int copyNo, G4VPhysicalVolume *physVol ) const
58{
59 // Voxels cannot be rotated, return translation
60 //
61 G4ThreeVector trans = GetTranslation( copyNo );
62 physVol->SetTranslation( trans );
63}
64
65
66//------------------------------------------------------------------
68GetTranslation(const G4int copyNo ) const
69{
70 CheckCopyNo( copyNo );
71
72 size_t nx, ny, nz;
73 ComputeVoxelIndices( copyNo, nx, ny, nz );
74
77 (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
78 return trans;
79}
80
81
82//------------------------------------------------------------------
84ComputeMaterial( const G4int copyNo, G4VPhysicalVolume*, const G4VTouchable* )
85{
86 CheckCopyNo( copyNo );
87 auto matIndex = GetMaterialIndex(copyNo);
88
89 return fMaterials[ matIndex ];
90}
91
92
93//------------------------------------------------------------------
95GetMaterialIndex( size_t copyNo ) const
96{
97 CheckCopyNo( copyNo );
98
99 if( fMaterialIndices == nullptr ) { return 0; }
100
101 return *(fMaterialIndices+copyNo);
102}
103
104
105//------------------------------------------------------------------
107GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
108{
109 size_t copyNo = nx + fNoVoxelsX*ny + fNoVoxelsXY*nz;
110 return GetMaterialIndex( copyNo );
111}
112
113
114//------------------------------------------------------------------
116GetMaterial( size_t nx, size_t ny, size_t nz) const
117{
118 return fMaterials[GetMaterialIndex(nx,ny,nz)];
119}
120
121
122//------------------------------------------------------------------
124GetMaterial( size_t copyNo ) const
125{
126 return fMaterials[GetMaterialIndex(copyNo)];
127}
128
129
130//------------------------------------------------------------------
132ComputeVoxelIndices(const G4int copyNo, size_t& nx,
133 size_t& ny, size_t& nz ) const
134{
135 CheckCopyNo( copyNo );
136
137 auto ite = fFilledIDs.lower_bound(size_t(copyNo));
138 G4int dist = std::distance( fFilledIDs.cbegin(), ite );
139 nz = size_t( dist/fNoVoxelsY );
140 ny = size_t( dist%fNoVoxelsY );
141
142 G4int ifmin = (*ite).second;
143 G4int nvoxXprev;
144 if( dist != 0 )
145 {
146 ite--;
147 nvoxXprev = (*ite).first;
148 }
149 else
150 {
151 nvoxXprev = -1;
152 }
153
154 nx = ifmin+copyNo-nvoxXprev-1;
155}
156
157
158//------------------------------------------------------------------
160GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
161{
162 // Check the voxel numbers corresponding to localPoint
163 // When a particle is on a surface, it may be between -kCarTolerance and
164 // +kCartolerance. By a simple distance as:
165 // G4int nx = G4int( (localPoint.x()+)/fVoxelHalfX/2.);
166 // those between -kCartolerance and 0 will be placed on voxel N-1 and those
167 // between 0 and kCarTolerance on voxel N.
168 // To avoid precision problems place the tracks that are on the surface on
169 // voxel N-1 if they have negative direction and on voxel N if they have
170 // positive direction.
171 // Add +kCarTolerance so that they are first placed on voxel N, and then
172 // if the direction is negative substract 1
173
174 G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
175 G4int nx = G4int(fx);
176
177 G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
178 G4int ny = G4int(fy);
179
180 G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
181 G4int nz = G4int(fz);
182
183 // If it is on the surface side, check the direction: if direction is
184 // negative place it on the previous voxel (if direction is positive it is
185 // already in the next voxel...).
186 // Correct also cases where n = -1 or n = fNoVoxels. It is always traced to be
187 // due to multiple scattering: track is entering a voxel but multiple
188 // scattering changes the angle towards outside
189 //
190 if( fx - nx < kCarTolerance/fVoxelHalfX )
191 {
192 if( localDir.x() < 0 )
193 {
194 if( nx != 0 )
195 {
196 nx -= 1;
197 }
198 }
199 else
200 {
201 if( nx == G4int(fNoVoxelsX) )
202 {
203 nx -= 1;
204 }
205 }
206 }
207 if( fy - ny < kCarTolerance/fVoxelHalfY )
208 {
209 if( localDir.y() < 0 )
210 {
211 if( ny != 0 )
212 {
213 ny -= 1;
214 }
215 }
216 else
217 {
218 if( ny == G4int(fNoVoxelsY) )
219 {
220 ny -= 1;
221 }
222 }
223 }
224 if( fz - nz < kCarTolerance/fVoxelHalfZ )
225 {
226 if( localDir.z() < 0 )
227 {
228 if( nz != 0 )
229 {
230 nz -= 1;
231 }
232 }
233 else
234 {
235 if( nz == G4int(fNoVoxelsZ) )
236 {
237 nz -= 1;
238 }
239 }
240 }
241
242 // Check if there are still errors
243 //
244 G4bool isOK = true;
245 if( nx < 0 )
246 {
247 nx = 0;
248 isOK = false;
249 }
250 else if( nx >= G4int(fNoVoxelsX) )
251 {
252 nx = fNoVoxelsX-1;
253 isOK = false;
254 }
255 if( ny < 0 )
256 {
257 ny = 0;
258 isOK = false;
259 }
260 else if( ny >= G4int(fNoVoxelsY) )
261 {
262 ny = fNoVoxelsY-1;
263 isOK = false;
264 }
265 if( nz < 0 )
266 {
267 nz = 0;
268 isOK = false;
269 }
270 else if( nz >= G4int(fNoVoxelsZ) )
271 {
272 nz = fNoVoxelsZ-1;
273 isOK = false;
274 }
275 if( !isOK )
276 {
277 std::ostringstream message;
278 message << "Corrected the copy number! It was negative or too big."
279 << G4endl
280 << " LocalPoint: " << localPoint << G4endl
281 << " LocalDir: " << localDir << G4endl
282 << " Voxel container size: " << fContainerWallX
283 << " " << fContainerWallY << " " << fContainerWallZ << G4endl
284 << " LocalPoint - wall: "
285 << localPoint.x()-fContainerWallX << " "
286 << localPoint.y()-fContainerWallY << " "
287 << localPoint.z()-fContainerWallZ;
288 G4Exception("G4PartialPhantomParameterisation::GetReplicaNo()",
289 "GeomNav1002", JustWarning, message);
290 }
291
292 G4int nyz = nz*fNoVoxelsY+ny;
293 auto ite = fFilledIDs.cbegin();
294/*
295 for( ite = fFilledIDs.cbegin(); ite != fFilledIDs.cend(); ++ite )
296 {
297 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo filled "
298 << (*ite).first << " , " << (*ite).second << std::endl;
299 }
300*/
301
302 advance(ite,nyz);
303 auto iteant = ite; iteant--;
304 G4int copyNo = (*iteant).first + 1 + ( nx - (*ite).second );
305/*
306 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo getting copyNo "
307 << copyNo << " nyz " << nyz << " (*iteant).first "
308 << (*iteant).first << " (*ite).second " << (*ite).second << G4endl;
309
310 G4cout << " G4PartialPhantomParameterisation::GetReplicaNo " << copyNo
311 << " nx " << nx << " ny " << ny << " nz " << nz
312 << " localPoint " << localPoint << " localDir " << localDir << G4endl;
313*/
314 return copyNo;
315}
316
317
318//------------------------------------------------------------------
320{
321 if( copyNo < 0 || copyNo >= G4int(fNoVoxels) )
322 {
323 std::ostringstream message;
324 message << "Copy number is negative or too big!" << G4endl
325 << " Copy number: " << copyNo << G4endl
326 << " Total number of voxels: " << fNoVoxels;
327 G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
328 "GeomNav0002", FatalErrorInArgument, message);
329 }
330}
331
332
333//------------------------------------------------------------------
335{
339}
@ JustWarning
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
double z() const
double x() const
double y() const
G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=nullptr)
void ComputeVoxelIndices(const G4int copyNo, size_t &nx, size_t &ny, size_t &nz) const
void ComputeTransformation(const G4int, G4VPhysicalVolume *) const
size_t GetMaterialIndex(size_t nx, size_t ny, size_t nz) const
G4int GetReplicaNo(const G4ThreeVector &localPoint, const G4ThreeVector &localDir)
G4ThreeVector GetTranslation(const G4int copyNo) const
G4Material * GetMaterial(size_t nx, size_t ny, size_t nz) const
std::vector< G4Material * > fMaterials
void SetTranslation(const G4ThreeVector &v)