ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4PartialPhantomParameterisation.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4PartialPhantomParameterisation.cc
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"
39 #include "G4GeometryTolerance.hh"
40 
41 #include <list>
42 
43 //------------------------------------------------------------------
46 {
47 }
48 
49 
50 //------------------------------------------------------------------
52 {
53 }
54 
55 //------------------------------------------------------------------
57 ComputeTransformation( 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 //------------------------------------------------------------------
68 GetTranslation(const G4int copyNo ) const
69 {
70  CheckCopyNo( copyNo );
71 
72  size_t nx, ny, nz;
73  ComputeVoxelIndices( copyNo, nx, ny, nz );
74 
75  G4ThreeVector trans( (2*nx+1)*fVoxelHalfX - fContainerWallX,
76  (2*ny+1)*fVoxelHalfY - fContainerWallY,
77  (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
78  return trans;
79 }
80 
81 
82 //------------------------------------------------------------------
85 {
86  CheckCopyNo( copyNo );
87  auto matIndex = GetMaterialIndex(copyNo);
88 
89  return fMaterials[ matIndex ];
90 }
91 
92 
93 //------------------------------------------------------------------
95 GetMaterialIndex( size_t copyNo ) const
96 {
97  CheckCopyNo( copyNo );
98 
99  if( fMaterialIndices == nullptr ) { return 0; }
100 
101  return *(fMaterialIndices+copyNo);
102 }
103 
104 
105 //------------------------------------------------------------------
107 GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
108 {
109  size_t copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
110  return GetMaterialIndex( copyNo );
111 }
112 
113 
114 //------------------------------------------------------------------
116 GetMaterial( size_t nx, size_t ny, size_t nz) const
117 {
118  return fMaterials[GetMaterialIndex(nx,ny,nz)];
119 }
120 
121 
122 //------------------------------------------------------------------
124 GetMaterial( size_t copyNo ) const
125 {
126  return fMaterials[GetMaterialIndex(copyNo)];
127 }
128 
129 
130 //------------------------------------------------------------------
132 ComputeVoxelIndices(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/fNoVoxelY );
140  ny = size_t( dist%fNoVoxelY );
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 //------------------------------------------------------------------
160 GetReplicaNo( 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 = fNoVoxel. 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(fNoVoxelX) )
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(fNoVoxelY) )
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(fNoVoxelZ) )
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(fNoVoxelX) )
251  {
252  nx = fNoVoxelX-1;
253  isOK = false;
254  }
255  if( ny < 0 )
256  {
257  ny = 0;
258  isOK = false;
259  }
260  else if( ny >= G4int(fNoVoxelY) )
261  {
262  ny = fNoVoxelY-1;
263  isOK = false;
264  }
265  if( nz < 0 )
266  {
267  nz = 0;
268  isOK = false;
269  }
270  else if( nz >= G4int(fNoVoxelZ) )
271  {
272  nz = fNoVoxelZ-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*fNoVoxelY+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(fNoVoxel) )
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: " << fNoVoxel;
327  G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
328  "GeomNav0002", FatalErrorInArgument, message);
329  }
330 }
331 
332 
333 //------------------------------------------------------------------
335 {
339 }