source: trunk/source/geometry/navigation/src/G4PartialPhantomParameterisation.cc @ 1358

Last change on this file since 1358 was 1350, checked in by garnier, 14 years ago

update to last version 4.9.4

  • Property svn:executable set to *
File size: 10.4 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: G4PartialPhantomParameterisation.cc,v 1.3 2010/12/15 07:39:00 gunter Exp $
28// GEANT4 tag $Name: geant4-09-04-ref-00 $
29//
30//
31// class G4PartialPhantomParameterisation implementation
32//
33// May 2007 Pedro Arce (CIEMAT), first version
34//
35// --------------------------------------------------------------------
36
37#include "G4PartialPhantomParameterisation.hh"
38
39#include "globals.hh"
40#include "G4Material.hh"
41#include "G4VSolid.hh"
42#include "G4VPhysicalVolume.hh"
43#include "G4LogicalVolume.hh"
44#include "G4VVolumeMaterialScanner.hh"
45#include "G4GeometryTolerance.hh"
46
47#include <list>
48
49//------------------------------------------------------------------
50G4PartialPhantomParameterisation::G4PartialPhantomParameterisation()
51  : G4PhantomParameterisation()
52{
53}
54
55
56//------------------------------------------------------------------
57G4PartialPhantomParameterisation::~G4PartialPhantomParameterisation()
58{
59}
60
61//------------------------------------------------------------------
62void G4PartialPhantomParameterisation::
63ComputeTransformation(const G4int copyNo, G4VPhysicalVolume *physVol ) const
64{
65  // Voxels cannot be rotated, return translation
66  //
67  G4ThreeVector trans = GetTranslation( copyNo );
68  physVol->SetTranslation( trans );
69}
70
71
72//------------------------------------------------------------------
73G4ThreeVector G4PartialPhantomParameterisation::
74GetTranslation(const G4int copyNo ) const
75{
76  CheckCopyNo( copyNo );
77
78  size_t nx;
79  size_t ny;
80  size_t nz;
81  ComputeVoxelIndices( copyNo, nx, ny, nz );
82
83  G4ThreeVector trans( (2*nx+1)*fVoxelHalfX - fContainerWallX,
84                       (2*ny+1)*fVoxelHalfY - fContainerWallY,
85                       (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
86  return trans;
87}
88
89
90//------------------------------------------------------------------
91G4Material* G4PartialPhantomParameterisation::
92ComputeMaterial(const G4int copyNo, G4VPhysicalVolume *, const G4VTouchable *) 
93{ 
94  CheckCopyNo( copyNo );
95  size_t matIndex = GetMaterialIndex(copyNo);
96
97  return fMaterials[ matIndex ];
98}
99
100
101//------------------------------------------------------------------
102size_t G4PartialPhantomParameterisation::
103GetMaterialIndex( size_t copyNo ) const
104{
105  CheckCopyNo( copyNo );
106
107  if( !fMaterialIndices ) { return 0; }
108
109  return *(fMaterialIndices+copyNo);
110}
111
112
113//------------------------------------------------------------------
114size_t G4PartialPhantomParameterisation::
115GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
116{
117  size_t copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
118  return GetMaterialIndex( copyNo );
119}
120
121
122//------------------------------------------------------------------
123G4Material* G4PartialPhantomParameterisation::
124GetMaterial( size_t nx, size_t ny, size_t nz) const
125{
126  return fMaterials[GetMaterialIndex(nx,ny,nz)];
127}
128
129
130//------------------------------------------------------------------
131G4Material* G4PartialPhantomParameterisation::
132GetMaterial( size_t copyNo ) const
133{
134  return fMaterials[GetMaterialIndex(copyNo)];
135}
136
137
138//------------------------------------------------------------------
139void G4PartialPhantomParameterisation::
140ComputeVoxelIndices(const G4int copyNo, size_t& nx,
141                            size_t& ny, size_t& nz ) const
142{
143  CheckCopyNo( copyNo );
144
145  std::multimap<G4int,G4int>::const_iterator ite =
146    fFilledIDs.lower_bound(size_t(copyNo));
147  G4int dist = std::distance( fFilledIDs.begin(), ite );
148  nz = size_t(dist/fNoVoxelY);
149  ny = size_t( dist%fNoVoxelY );
150
151  G4int ifmin = (*ite).second;
152  G4int nvoxXprev;
153  if( dist != 0 ) {
154    ite--;
155    nvoxXprev = (*ite).first;
156  } else {
157    nvoxXprev = -1;
158  } 
159
160  nx = ifmin+copyNo-nvoxXprev-1;
161}
162
163
164//------------------------------------------------------------------
165G4int G4PartialPhantomParameterisation::
166GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
167{
168  // Check the voxel numbers corresponding to localPoint
169  // When a particle is on a surface, it may be between -kCarTolerance and
170  // +kCartolerance. By a simple distance as:
171  //   G4int nx = G4int( (localPoint.x()+)/fVoxelHalfX/2.);
172  // those between -kCartolerance and 0 will be placed on voxel N-1 and those
173  // between 0 and kCarTolerance on voxel N.
174  // To avoid precision problems place the tracks that are on the surface on
175  // voxel N-1 if they have negative direction and on voxel N if they have
176  // positive direction.
177  // Add +kCarTolerance so that they are first placed on voxel N, and then
178  // if the direction is negative substract 1
179
180  G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
181  G4int nx = G4int(fx);
182
183  G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
184  G4int ny = G4int(fy);
185
186  G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
187  G4int nz = G4int(fz);
188
189  // If it is on the surface side, check the direction: if direction is
190  // negative place it on the previous voxel (if direction is positive it is
191  // already in the next voxel...).
192  // Correct also cases where n = -1 or n = fNoVoxel. It is always traced to be
193  // due to multiple scattering: track is entering a voxel but multiple
194  // scattering changes the angle towards outside
195  //
196  if( fx - nx < kCarTolerance/fVoxelHalfX )
197  {
198    if( localDir.x() < 0 )
199    {
200      if( nx != 0 )
201      {
202        nx -= 1;
203      }
204    }
205    else
206    {
207      if( nx == G4int(fNoVoxelX) ) 
208      {
209        nx -= 1;       
210      }
211    }
212  }
213  if( fy - ny < kCarTolerance/fVoxelHalfY )
214  {
215    if( localDir.y() < 0 )
216    {
217      if( ny != 0 )
218      {
219        ny -= 1;
220      }
221    }
222    else
223    {
224      if( ny == G4int(fNoVoxelY) ) 
225      {
226        ny -= 1;       
227      }
228    }
229  }
230  if( fz - nz < kCarTolerance/fVoxelHalfZ )
231  {
232    if( localDir.z() < 0 )
233    {
234      if( nz != 0 )
235      {
236        nz -= 1;
237      }
238    }
239    else
240    {
241      if( nz == G4int(fNoVoxelZ) ) 
242      {
243        nz -= 1;       
244      }
245    }
246  }
247 
248  // Check if there are still errors
249  //
250  G4bool isOK = true;
251  if( nx < 0 )
252  {
253    nx = 0;
254    isOK = false;
255  }
256  else if( nx >= G4int(fNoVoxelX) )
257  {
258    nx = fNoVoxelX-1;
259    isOK = false;
260  }
261  if( ny < 0 )
262  {
263    ny = 0;
264    isOK = false;
265  }
266  else if( ny >= G4int(fNoVoxelY) )
267  {
268    ny = fNoVoxelY-1;
269    isOK = false;
270  }
271  if( nz < 0 )
272  {
273    nz = 0;
274    isOK = false;
275  }
276  else if( nz >= G4int(fNoVoxelZ) )
277  {
278    nz = fNoVoxelZ-1;
279    isOK = false;
280  }
281  if( !isOK )
282  {
283    G4cerr << "WARNING - G4PartialPhantomParameterisation::GetReplicaNo()"
284           << G4endl
285           << "          LocalPoint: " << localPoint << G4endl
286           << "          LocalDir: " << localDir << G4endl
287           << "          Voxel container size: " << fContainerWallX
288           << " " << fContainerWallY << " " << fContainerWallZ << G4endl
289           << "          LocalPoint - wall: "
290           << localPoint.x()-fContainerWallX << " "
291           << localPoint.y()-fContainerWallY << " "
292           << localPoint.z()-fContainerWallZ << G4endl;
293    G4Exception("G4PartialPhantomParameterisation::GetReplicaNo()",
294                "Wrong-copy-number", JustWarning,
295                "Corrected the copy number! It was negative or too big");
296  }
297
298  G4int nyz = nz*fNoVoxelY+ny;
299  std::multimap<G4int,G4int>::iterator ite = fFilledIDs.begin();
300/*
301  for( ite = fFilledIDs.begin(); ite != fFilledIDs.end(); ite++ )
302  {
303    G4cout << " G4PartialPhantomParameterisation::GetReplicaNo filled "
304           << (*ite).first << " , " << (*ite).second << std::endl;
305  }
306*/
307  ite = fFilledIDs.begin();
308
309  advance(ite,nyz);
310  std::multimap<G4int,G4int>::iterator iteant = ite; iteant--;
311  G4int copyNo = (*iteant).first + 1 + ( nx - (*ite).second );
312/*
313  G4cout << " G4PartialPhantomParameterisation::GetReplicaNo getting copyNo "
314         << copyNo << "  nyz " << nyz << "  (*iteant).first "
315         << (*iteant).first << "  (*ite).second " <<  (*ite).second << G4endl;
316
317  G4cout << " G4PartialPhantomParameterisation::GetReplicaNo " << copyNo
318         << " nx " << nx << " ny " << ny << " nz " << nz
319         << " localPoint " << localPoint << " localDir " << localDir << G4endl;
320*/
321  return copyNo;
322}
323
324
325//------------------------------------------------------------------
326void G4PartialPhantomParameterisation::CheckCopyNo( const G4int copyNo ) const
327{ 
328  if( copyNo < 0 || copyNo >= G4int(fNoVoxel) )
329  {
330    G4cerr << "ERROR - G4PartialPhantomParameterisation::CheckCopyNo()"
331           << G4endl
332           << "        Copy number: " << copyNo << G4endl
333           << "        Total number of voxels: " << fNoVoxel << G4endl;
334    G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
335                "Wrong-copy-number", FatalErrorInArgument,
336                "Copy number is negative or too big!");
337  }
338}
339
340
341//------------------------------------------------------------------
342void G4PartialPhantomParameterisation::BuildContainerWalls()
343{
344  fContainerWallX = fNoVoxelX * fVoxelHalfX;
345  fContainerWallY = fNoVoxelY * fVoxelHalfY;
346  fContainerWallZ = fNoVoxelZ * fVoxelHalfZ;
347}
Note: See TracBrowser for help on using the repository browser.