Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:57

0001 /*
0002  * GlobalLocator.h
0003  *
0004  *  Created on: Aug 27, 2015
0005  *      Author: swenzel
0006  */
0007 
0008 #ifndef NAVIGATION_GLOBALLOCATOR_H_
0009 #define NAVIGATION_GLOBALLOCATOR_H_
0010 
0011 #include "VecGeom/base/Global.h"
0012 #include "VecGeom/base/Vector3D.h"
0013 #include "VecGeom/volumes/LogicalVolume.h"
0014 #include "VecGeom/navigation/VLevelLocator.h"
0015 #include "VecGeom/navigation/NavigationState.h"
0016 
0017 namespace vecgeom {
0018 inline namespace VECGEOM_IMPL_NAMESPACE {
0019 
0020 class LogicalVolume;
0021 class VPlacedVolume;
0022 
0023 //! basic algorithms to locate a global point
0024 
0025 //! basic generic algorithm that locates a global point in a geometry hierarchy
0026 //! dispatches to specific LevelLocators
0027 //! its a namespace rather than a class since it offers only a static function
0028 namespace GlobalLocator {
0029 
0030 // modified version using different LevelLocatorInterface
0031 // this function is a generic variant which can pick from each volume
0032 // the best (or default) LevelLocator
0033 VECGEOM_FORCE_INLINE
0034 VECCORE_ATT_HOST_DEVICE
0035 VPlacedVolume const *LocateGlobalPoint(VPlacedVolume const *vol, Vector3D<Precision> const &point,
0036                                        NavigationState &path, bool top)
0037 {
0038   VPlacedVolume const *candvolume = vol;
0039   Vector3D<Precision> currentpoint(point);
0040   if (top) {
0041     assert(vol != nullptr);
0042     candvolume = (vol->UnplacedContains(point)) ? vol : nullptr;
0043   }
0044   if (candvolume) {
0045     path.Push(candvolume);
0046     LogicalVolume const *lvol         = candvolume->GetLogicalVolume();
0047     Vector<Daughter> const *daughters = lvol->GetDaughtersp();
0048 
0049     bool godeeper = true;
0050     while (daughters->size() > 0 && godeeper) {
0051       // returns nextvolume; and transformedpoint; modified path
0052       VLevelLocator const *locator = lvol->GetLevelLocator();
0053       if (locator != nullptr) { // if specialized/optimized technique attached to logical volume
0054         Vector3D<Precision> transformedpoint;
0055         godeeper = locator->LevelLocate(lvol, currentpoint, path, transformedpoint);
0056         if (godeeper) {
0057           candvolume   = path.Top();
0058           lvol         = candvolume->GetLogicalVolume();
0059           daughters    = lvol->GetDaughtersp();
0060           currentpoint = transformedpoint;
0061         }
0062       } else { // otherwise do a default implementation
0063         // GL: this code adapted from LocateGlobalPointExclVolume(...) function below
0064         godeeper = true;
0065         for (size_t i = 0; i < daughters->size() && godeeper; ++i) {
0066           VPlacedVolume const *nextvolume = (*daughters)[i];
0067           Vector3D<Precision> transformedpoint;
0068           if (nextvolume->Contains(currentpoint, transformedpoint)) {
0069             path.Push(nextvolume);
0070             currentpoint = transformedpoint;
0071             candvolume   = nextvolume;
0072             daughters    = candvolume->GetLogicalVolume()->GetDaughtersp();
0073             godeeper     = true;
0074             break;
0075           }
0076         }
0077         godeeper = false;
0078       }
0079     }
0080   }
0081   return candvolume ? path.Top() : nullptr;
0082 }
0083 
0084 // special version of locate point function that excludes searching a given volume
0085 // (useful when we know that a particle must have traversed a boundary)
0086 VECGEOM_FORCE_INLINE
0087 VECCORE_ATT_HOST_DEVICE
0088 VPlacedVolume const *LocateGlobalPointExclVolume(VPlacedVolume const *vol, VPlacedVolume const *excludedvolume,
0089                                                  Vector3D<Precision> const &point, NavigationState &path, bool top)
0090 {
0091   VPlacedVolume const *candvolume = vol;
0092   Vector3D<Precision> currentpoint(point);
0093   if (top) {
0094     assert(vol != nullptr);
0095     candvolume = (vol->UnplacedContains(point)) ? vol : nullptr;
0096   }
0097   if (candvolume) {
0098     path.Push(candvolume);
0099     LogicalVolume const *lvol         = candvolume->GetLogicalVolume();
0100     Vector<Daughter> const *daughters = lvol->GetDaughtersp();
0101 
0102     bool godeeper = true;
0103     while (daughters->size() > 0 && godeeper) {
0104       godeeper = false;
0105       // returns nextvolume; and transformedpoint; modified path
0106       VLevelLocator const *locator = lvol->GetLevelLocator();
0107       if (locator != nullptr) { // if specialized/optimized technique attached to logical volume
0108         Vector3D<Precision> transformedpoint;
0109         godeeper = locator->LevelLocateExclVol(lvol, excludedvolume, currentpoint, candvolume, transformedpoint);
0110         if (godeeper) {
0111           lvol         = candvolume->GetLogicalVolume();
0112           daughters    = lvol->GetDaughtersp();
0113           currentpoint = transformedpoint;
0114           path.Push(candvolume);
0115         }
0116       } else { // otherwise do a default implementation
0117         for (size_t i = 0; i < daughters->size(); ++i) {
0118           VPlacedVolume const *nextvolume = (*daughters)[i];
0119           if (nextvolume != excludedvolume) {
0120             Vector3D<Precision> transformedpoint;
0121             if (nextvolume->Contains(currentpoint, transformedpoint)) {
0122               path.Push(nextvolume);
0123               currentpoint = transformedpoint;
0124               candvolume   = nextvolume;
0125               daughters    = candvolume->GetLogicalVolume()->GetDaughtersp();
0126               godeeper     = true;
0127               break;
0128             }
0129           } // end if excludedvolume
0130         }
0131       }
0132     }
0133   }
0134   return candvolume;
0135 }
0136 
0137 VECGEOM_FORCE_INLINE
0138 VECCORE_ATT_HOST_DEVICE
0139 static VPlacedVolume const *RelocatePointFromPath(Vector3D<Precision> const &localpoint, NavigationState &path)
0140 {
0141   // idea: do the following:
0142   // ----- is localpoint still in current mother ? : then go down
0143   // if not: have to go up until we reach a volume that contains the
0144   // localpoint and then go down again (neglecting the volumes currently stored in the path)
0145   VPlacedVolume const *currentmother = path.Top();
0146   if (currentmother != nullptr) {
0147     Vector3D<Precision> tmp = localpoint;
0148     while (currentmother) {
0149       if (currentmother->GetLogicalVolume()->GetUnplacedVolume()->IsAssembly() ||
0150           !currentmother->UnplacedContains(tmp)) {
0151         path.Pop();
0152         Vector3D<Precision> pointhigherup = currentmother->GetTransformation()->InverseTransform(tmp);
0153         tmp                               = pointhigherup;
0154         currentmother                     = path.Top();
0155       } else {
0156         break;
0157       }
0158     }
0159 
0160     if (currentmother) {
0161       path.Pop();
0162       return LocateGlobalPoint(currentmother, tmp, path, false);
0163     }
0164   }
0165   return currentmother;
0166 }
0167 
0168 //  a version for relocation when we know that new state must be different
0169 VECGEOM_FORCE_INLINE
0170 VECCORE_ATT_HOST_DEVICE
0171 static VPlacedVolume const *RelocatePointFromPathForceDifferent(Vector3D<Precision> const &localpoint,
0172                                                                 NavigationState &path)
0173 {
0174   // idea: do the following:
0175   // ----- is localpoint still in current mother ? : then go down
0176   // if not: have to go up until we reach a volume that contains the
0177   // localpoint and then go down again (neglecting the volumes currently stored in the path)
0178   VPlacedVolume const *currentmother = path.Top();
0179   VPlacedVolume const *entryvol      = currentmother;
0180   if (currentmother != nullptr) {
0181     Vector3D<Precision> tmp = localpoint;
0182     while (currentmother) {
0183       if (currentmother == entryvol || currentmother->GetLogicalVolume()->GetUnplacedVolume()->IsAssembly() ||
0184           !currentmother->UnplacedContains(tmp)) {
0185         path.Pop();
0186         Vector3D<Precision> pointhigherup = currentmother->GetTransformation()->InverseTransform(tmp);
0187         tmp                               = pointhigherup;
0188         currentmother                     = path.Top();
0189       } else {
0190         break;
0191       }
0192     }
0193 
0194     if (currentmother) {
0195       path.Pop();
0196       return LocateGlobalPointExclVolume(currentmother, entryvol, tmp, path, false);
0197     }
0198   }
0199   return currentmother;
0200 }
0201 
0202 VECCORE_ATT_HOST_DEVICE
0203 VECGEOM_FORCE_INLINE
0204 bool HasSamePath(Vector3D<Precision> const &globalpoint, Transformation3D const &globaltransf,
0205                  NavigationState const &currentstate, NavigationState &newstate)
0206 {
0207   Vector3D<Precision> localpoint = globaltransf.Transform(globalpoint);
0208   currentstate.CopyTo(&newstate);
0209   RelocatePointFromPath(localpoint, newstate);
0210   return currentstate.HasSamePathAsOther(newstate);
0211 }
0212 
0213 /**
0214  * function to check whether global point has same path as given by currentstate
0215  * input:  A global point
0216  *         the path itself
0217  *         a new path object which is filled; Initially a copy of currentstate will be made
0218  * output: yes or no
0219  * side effects: modifies newstate to be path of globalpoint
0220  *
0221  */
0222 VECCORE_ATT_HOST_DEVICE
0223 inline bool HasSamePath(Vector3D<Precision> const &globalpoint, NavigationState const &currentstate,
0224                         NavigationState &newstate)
0225 {
0226   Transformation3D m;
0227   currentstate.TopMatrix(m);
0228   return HasSamePath(globalpoint, m, currentstate, newstate);
0229 }
0230 
0231 } // namespace GlobalLocator
0232 } // namespace VECGEOM_IMPL_NAMESPACE
0233 } // namespace vecgeom
0234 
0235 #endif /* NAVIGATION_GLOBALLOCATOR_H_ */