G4PartialPhantomParameterisation.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 //
00030 // class G4PartialPhantomParameterisation implementation
00031 //
00032 // May 2007 Pedro Arce (CIEMAT), first version
00033 //
00034 // --------------------------------------------------------------------
00035 
00036 #include "G4PartialPhantomParameterisation.hh"
00037 
00038 #include "globals.hh"
00039 #include "G4Material.hh"
00040 #include "G4VSolid.hh"
00041 #include "G4VPhysicalVolume.hh"
00042 #include "G4LogicalVolume.hh"
00043 #include "G4VVolumeMaterialScanner.hh"
00044 #include "G4GeometryTolerance.hh"
00045 
00046 #include <list>
00047 
00048 //------------------------------------------------------------------
00049 G4PartialPhantomParameterisation::G4PartialPhantomParameterisation()
00050   : G4PhantomParameterisation()
00051 {
00052 }
00053 
00054 
00055 //------------------------------------------------------------------
00056 G4PartialPhantomParameterisation::~G4PartialPhantomParameterisation()
00057 {
00058 }
00059 
00060 //------------------------------------------------------------------
00061 void G4PartialPhantomParameterisation::
00062 ComputeTransformation(const G4int copyNo, G4VPhysicalVolume *physVol ) const
00063 {
00064   // Voxels cannot be rotated, return translation
00065   //
00066   G4ThreeVector trans = GetTranslation( copyNo );
00067   physVol->SetTranslation( trans );
00068 }
00069 
00070 
00071 //------------------------------------------------------------------
00072 G4ThreeVector G4PartialPhantomParameterisation::
00073 GetTranslation(const G4int copyNo ) const
00074 {
00075   CheckCopyNo( copyNo );
00076 
00077   size_t nx;
00078   size_t ny;
00079   size_t nz;
00080   ComputeVoxelIndices( copyNo, nx, ny, nz );
00081 
00082   G4ThreeVector trans( (2*nx+1)*fVoxelHalfX - fContainerWallX,
00083                        (2*ny+1)*fVoxelHalfY - fContainerWallY,
00084                        (2*nz+1)*fVoxelHalfZ - fContainerWallZ);
00085   return trans;
00086 }
00087 
00088 
00089 //------------------------------------------------------------------
00090 G4Material* G4PartialPhantomParameterisation::
00091 ComputeMaterial(const G4int copyNo, G4VPhysicalVolume *, const G4VTouchable *) 
00092 { 
00093   CheckCopyNo( copyNo );
00094   size_t matIndex = GetMaterialIndex(copyNo);
00095 
00096   return fMaterials[ matIndex ];
00097 }
00098 
00099 
00100 //------------------------------------------------------------------
00101 size_t G4PartialPhantomParameterisation::
00102 GetMaterialIndex( size_t copyNo ) const
00103 {
00104   CheckCopyNo( copyNo );
00105 
00106   if( !fMaterialIndices ) { return 0; }
00107 
00108   return *(fMaterialIndices+copyNo);
00109 }
00110 
00111 
00112 //------------------------------------------------------------------
00113 size_t G4PartialPhantomParameterisation::
00114 GetMaterialIndex( size_t nx, size_t ny, size_t nz ) const
00115 {
00116   size_t copyNo = nx + fNoVoxelX*ny + fNoVoxelXY*nz;
00117   return GetMaterialIndex( copyNo );
00118 }
00119 
00120 
00121 //------------------------------------------------------------------
00122 G4Material* G4PartialPhantomParameterisation::
00123 GetMaterial( size_t nx, size_t ny, size_t nz) const
00124 {
00125   return fMaterials[GetMaterialIndex(nx,ny,nz)];
00126 }
00127 
00128 
00129 //------------------------------------------------------------------
00130 G4Material* G4PartialPhantomParameterisation::
00131 GetMaterial( size_t copyNo ) const
00132 {
00133   return fMaterials[GetMaterialIndex(copyNo)];
00134 }
00135 
00136 
00137 //------------------------------------------------------------------
00138 void G4PartialPhantomParameterisation::
00139 ComputeVoxelIndices(const G4int copyNo, size_t& nx,
00140                             size_t& ny, size_t& nz ) const
00141 {
00142   CheckCopyNo( copyNo );
00143 
00144   std::multimap<G4int,G4int>::const_iterator ite =
00145     fFilledIDs.lower_bound(size_t(copyNo));
00146   G4int dist = std::distance( fFilledIDs.begin(), ite );
00147   nz = size_t(dist/fNoVoxelY);
00148   ny = size_t( dist%fNoVoxelY );
00149 
00150   G4int ifmin = (*ite).second;
00151   G4int nvoxXprev;
00152   if( dist != 0 ) {
00153     ite--;
00154     nvoxXprev = (*ite).first;
00155   } else {
00156     nvoxXprev = -1;
00157   } 
00158 
00159   nx = ifmin+copyNo-nvoxXprev-1;
00160 }
00161 
00162 
00163 //------------------------------------------------------------------
00164 G4int G4PartialPhantomParameterisation::
00165 GetReplicaNo( const G4ThreeVector& localPoint, const G4ThreeVector& localDir )
00166 {
00167   // Check the voxel numbers corresponding to localPoint
00168   // When a particle is on a surface, it may be between -kCarTolerance and
00169   // +kCartolerance. By a simple distance as:
00170   //   G4int nx = G4int( (localPoint.x()+)/fVoxelHalfX/2.);
00171   // those between -kCartolerance and 0 will be placed on voxel N-1 and those
00172   // between 0 and kCarTolerance on voxel N.
00173   // To avoid precision problems place the tracks that are on the surface on
00174   // voxel N-1 if they have negative direction and on voxel N if they have
00175   // positive direction.
00176   // Add +kCarTolerance so that they are first placed on voxel N, and then
00177   // if the direction is negative substract 1
00178 
00179   G4double fx = (localPoint.x()+fContainerWallX+kCarTolerance)/(fVoxelHalfX*2.);
00180   G4int nx = G4int(fx);
00181 
00182   G4double fy = (localPoint.y()+fContainerWallY+kCarTolerance)/(fVoxelHalfY*2.);
00183   G4int ny = G4int(fy);
00184 
00185   G4double fz = (localPoint.z()+fContainerWallZ+kCarTolerance)/(fVoxelHalfZ*2.);
00186   G4int nz = G4int(fz);
00187 
00188   // If it is on the surface side, check the direction: if direction is
00189   // negative place it on the previous voxel (if direction is positive it is
00190   // already in the next voxel...). 
00191   // Correct also cases where n = -1 or n = fNoVoxel. It is always traced to be
00192   // due to multiple scattering: track is entering a voxel but multiple
00193   // scattering changes the angle towards outside
00194   //
00195   if( fx - nx < kCarTolerance/fVoxelHalfX )
00196   {
00197     if( localDir.x() < 0 )
00198     {
00199       if( nx != 0 )
00200       {
00201         nx -= 1;
00202       }
00203     }
00204     else
00205     {
00206       if( nx == G4int(fNoVoxelX) )  
00207       {
00208         nx -= 1;       
00209       }
00210     }
00211   }
00212   if( fy - ny < kCarTolerance/fVoxelHalfY )
00213   {
00214     if( localDir.y() < 0 )
00215     {
00216       if( ny != 0 )
00217       {
00218         ny -= 1;
00219       }
00220     }
00221     else
00222     {
00223       if( ny == G4int(fNoVoxelY) )  
00224       {
00225         ny -= 1;       
00226       }
00227     }
00228   }
00229   if( fz - nz < kCarTolerance/fVoxelHalfZ )
00230   {
00231     if( localDir.z() < 0 )
00232     {
00233       if( nz != 0 )
00234       {
00235         nz -= 1;
00236       }
00237     }
00238     else
00239     {
00240       if( nz == G4int(fNoVoxelZ) )  
00241       {
00242         nz -= 1;       
00243       }
00244     }
00245   }
00246   
00247   // Check if there are still errors 
00248   //
00249   G4bool isOK = true;
00250   if( nx < 0 )
00251   {
00252     nx = 0;
00253     isOK = false;
00254   }
00255   else if( nx >= G4int(fNoVoxelX) )
00256   {
00257     nx = fNoVoxelX-1;
00258     isOK = false;
00259   }
00260   if( ny < 0 )
00261   {
00262     ny = 0;
00263     isOK = false;
00264   }
00265   else if( ny >= G4int(fNoVoxelY) )
00266   {
00267     ny = fNoVoxelY-1;
00268     isOK = false;
00269   }
00270   if( nz < 0 )
00271   {
00272     nz = 0;
00273     isOK = false;
00274   }
00275   else if( nz >= G4int(fNoVoxelZ) )
00276   {
00277     nz = fNoVoxelZ-1;
00278     isOK = false;
00279   }
00280   if( !isOK )
00281   {
00282     std::ostringstream message;
00283     message << "Corrected the copy number! It was negative or too big."
00284             << G4endl
00285             << "          LocalPoint: " << localPoint << G4endl
00286             << "          LocalDir: " << localDir << G4endl
00287             << "          Voxel container size: " << fContainerWallX
00288             << " " << fContainerWallY << " " << fContainerWallZ << G4endl
00289             << "          LocalPoint - wall: "
00290             << localPoint.x()-fContainerWallX << " "
00291             << localPoint.y()-fContainerWallY << " "
00292             << localPoint.z()-fContainerWallZ;
00293     G4Exception("G4PartialPhantomParameterisation::GetReplicaNo()",
00294                 "GeomNav1002", JustWarning, message);
00295   }
00296 
00297   G4int nyz = nz*fNoVoxelY+ny;
00298   std::multimap<G4int,G4int>::iterator ite = fFilledIDs.begin();
00299 /*
00300   for( ite = fFilledIDs.begin(); ite != fFilledIDs.end(); ite++ )
00301   {
00302     G4cout << " G4PartialPhantomParameterisation::GetReplicaNo filled "
00303            << (*ite).first << " , " << (*ite).second << std::endl;
00304   }
00305 */
00306   ite = fFilledIDs.begin();
00307 
00308   advance(ite,nyz);
00309   std::multimap<G4int,G4int>::iterator iteant = ite; iteant--;
00310   G4int copyNo = (*iteant).first + 1 + ( nx - (*ite).second );
00311 /*
00312   G4cout << " G4PartialPhantomParameterisation::GetReplicaNo getting copyNo "
00313          << copyNo << "  nyz " << nyz << "  (*iteant).first "
00314          << (*iteant).first << "  (*ite).second " <<  (*ite).second << G4endl;
00315 
00316   G4cout << " G4PartialPhantomParameterisation::GetReplicaNo " << copyNo
00317          << " nx " << nx << " ny " << ny << " nz " << nz
00318          << " localPoint " << localPoint << " localDir " << localDir << G4endl;
00319 */
00320   return copyNo;
00321 }
00322 
00323 
00324 //------------------------------------------------------------------
00325 void G4PartialPhantomParameterisation::CheckCopyNo( const G4int copyNo ) const
00326 { 
00327   if( copyNo < 0 || copyNo >= G4int(fNoVoxel) )
00328   {
00329     std::ostringstream message;
00330     message << "Copy number is negative or too big!" << G4endl
00331             << "        Copy number: " << copyNo << G4endl
00332             << "        Total number of voxels: " << fNoVoxel;
00333     G4Exception("G4PartialPhantomParameterisation::CheckCopyNo()",
00334                 "GeomNav0002", FatalErrorInArgument, message);
00335   }
00336 }
00337 
00338 
00339 //------------------------------------------------------------------
00340 void G4PartialPhantomParameterisation::BuildContainerWalls()
00341 {
00342   fContainerWallX = fNoVoxelX * fVoxelHalfX;
00343   fContainerWallY = fNoVoxelY * fVoxelHalfY;
00344   fContainerWallZ = fNoVoxelZ * fVoxelHalfZ;
00345 }

Generated on Mon May 27 17:49:15 2013 for Geant4 by  doxygen 1.4.7