Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 09:26:12

0001 // This file is part of VecGeom and is distributed under the
0002 // conditions in the file LICENSE.txt in the top directory.
0003 // For the full list of authors see CONTRIBUTORS.txt and `git log`.
0004 
0005 /// \brief Declaration of the manager/registry class for VecGeom geometries.
0006 /// \file management/GeoManager.h
0007 /// \author created by Sandro Wenzel, Johannes de Fine Licht
0008 
0009 #ifndef VECGEOM_MANAGEMENT_GEOMANAGER_H_
0010 #define VECGEOM_MANAGEMENT_GEOMANAGER_H_
0011 
0012 #include "VecGeom/base/Global.h"
0013 
0014 #include "VecGeom/volumes/PlacedVolume.h"
0015 #include "VecGeom/volumes/LogicalVolume.h"
0016 #include "VecGeom/management/GeoVisitor.h"
0017 #include "VecGeom/navigation/NavStateFwd.h"
0018 
0019 #include <map>
0020 
0021 namespace vecgeom {
0022 
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 class UnplacedScaledShape;
0025 class Scale3D;
0026 } // namespace VECGEOM_IMPL_NAMESPACE
0027 
0028 /**
0029  * @brief A class serving as central registry for VecGeom geometries.
0030  *
0031  * The GeoManager knows about all unplaced and placed volumes created by
0032  * the user and top node defining the geometry. It also offers functions to
0033  * iterate over the geometry tree or factory functions to create volume/shape instances.
0034  */
0035 class GeoManager {
0036 
0037 private:
0038   int fVolumeCount    = 0; // total number of logical volumes
0039   int fTotalNodeCount = 0; // total number of nodes in the geometry tree
0040   VPlacedVolume const *fWorld;
0041 
0042   // consider making these things rvalues
0043   std::map<unsigned int, VPlacedVolume *> fPlacedVolumesMap;
0044   std::map<unsigned int, LogicalVolume *> fLogicalVolumesMap;
0045   std::map<VPlacedVolume const *, unsigned int> fVolumeToIndexMap;
0046   std::vector<LogicalVolume *> fLogicalVolumesArray;
0047   int fMaxDepth    = 0;     // maximum geometry depth
0048   int fCacheDepth  = 0;     // caching level for global transformations (0 = cache all)_
0049   int fMinPerScene = 1000;  // minimum number of touchables to trigger scene creation in tuple mode
0050   bool fIsClosed   = false; // geometry closed flag
0051 
0052   /// Traverses the geometry tree of placed volumes and applies injected Visitor.
0053   template <typename Visitor>
0054   void visitAllPlacedVolumes(VPlacedVolume const *, Visitor *visitor, int level = 1) const;
0055 
0056   /// Traverses the geometry tree keeping track of the state context (volume path or navigation state)
0057   /// and applies the injected Visitor
0058   template <typename Visitor>
0059   void visitAllPlacedVolumesWithContext(VPlacedVolume const *, Visitor *visitor, NavigationState *state,
0060                                         int level = 1) const;
0061 
0062   /// Traverses the geometry tree keeping track of the state context (volume path or navigation state)
0063   /// and applies the injected Visitor for building the navigation index table
0064   template <typename Visitor>
0065   void visitAllPlacedVolumesNavIndex(VPlacedVolume const *, Visitor *visitor, NavigationState *state, int level,
0066                                      int dind) const;
0067 
0068 public:
0069   static VPlacedVolume *gCompactPlacedVolBuffer;
0070   static NavIndex_t *gNavIndex;     // address of navigation index table
0071   static Precision gMillimeterUnit; // internal representation value for 1 milimmeter length (default is 0.1)
0072 
0073   /// Returns the singleton instance
0074   static GeoManager &Instance()
0075   {
0076     static GeoManager instance;
0077     return instance;
0078   }
0079 
0080   /// Returns the default length value stored as 1 mm
0081   static Precision GetMillimeterUnit() { return gMillimeterUnit; }
0082 
0083   /// Changes the default length value stored as 1 mm
0084   static void SetMillimeterUnit(Precision value) { gMillimeterUnit = value; }
0085 
0086   /**
0087    * Mark the current detector geometry as finished and initialize
0088    * important cached variables such as the maximum tree depth etc.
0089    */
0090   void CloseGeometry();
0091 
0092   /**
0093    * Returns if geometry is closed.
0094    */
0095   bool IsClosed() const { return fIsClosed; }
0096 
0097   /**
0098    * @brief Create a Index Hierarchy object
0099    */
0100   void CreateIndexHierarchy() const;
0101   bool CheckIndexHierarchy() const;
0102 
0103 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0104   /// A factory template for unplaced shapes.
0105   template <typename UnplacedShape_t, typename... ArgTypes>
0106   static UnplacedShape_t *MakeInstance(ArgTypes... Args);
0107 
0108   /// A factory for unplaced scaled shapes
0109   template <typename BaseShape_t, typename... ArgTypes>
0110   static VECGEOM_IMPL_NAMESPACE::UnplacedScaledShape *MakeScaledInstance(const VECGEOM_IMPL_NAMESPACE::Scale3D &scale,
0111                                                                          ArgTypes... args)
0112   {
0113     return Maker<VECGEOM_IMPL_NAMESPACE::UnplacedScaledShape>::MakeInstance<BaseShape_t>(scale, args...);
0114   }
0115 #endif
0116   /** Compactify memory space used by VecGeom geometry objects.
0117    *
0118    * This is an internal method which should be called by ClosedGeometry.
0119    * It analyses the geometry and puts objects in contiguous buffers for the purpose
0120    * of less memory usage, better caching, fast random access to volumes
0121    * with indices, etc.
0122    *
0123    * Note that this procedure changes the memory location of objects. So the user
0124    * needs to adjust possible pointers.
0125    */
0126   void CompactifyMemory();
0127 
0128   /** Retrieve user-defined cache level for global transformations in USE_NAVINDEX mode. */
0129   int GetTransformationCacheDepth() const { return fCacheDepth; }
0130 
0131   /** User-defined cache level for global transformations in USE_NAVINDEX mode. */
0132   void SetTransformationCacheDepth(int depth) { fCacheDepth = depth; }
0133 
0134   /**
0135    * Set the world volume defining the entry point to the geometry.
0136    */
0137   void SetWorld(VPlacedVolume const *const w) { fWorld = w; }
0138 
0139   /**
0140    * Set the world volume and close geometry.
0141    */
0142   void SetWorldAndClose(VPlacedVolume const *const w)
0143   {
0144     SetWorld(w);
0145     CloseGeometry();
0146   }
0147 
0148   /// Returns the current world volume.
0149   VPlacedVolume const *GetWorld() const { return fWorld; }
0150 
0151   /**
0152    * Initialize geometry from a pre-compiled shared library
0153    * (such as obtained from the CppExporter)
0154    * This function sets the world and closes the geometry.
0155    */
0156   void LoadGeometryFromSharedLib(std::string, bool close = true);
0157 
0158   /// Lookup a placed volume instance from a index (logarithmic complexity).
0159   VPlacedVolume const *Convert(unsigned int index) { return fPlacedVolumesMap[index]; }
0160 
0161   /// Lookup the index of a placed volume (logarithmic complexity).
0162   unsigned int Convert(VPlacedVolume const *pvol) { return fVolumeToIndexMap[pvol]; }
0163 
0164   /**
0165    *  Give back a container c containing all logical volumes in the geometry.
0166    *  Container is supposed to be any Container that can store pointers to
0167    *  LogicalVolumes.
0168    */
0169   template <typename Container>
0170   void GetAllLogicalVolumes(Container &c) const;
0171 
0172   /**
0173    *  Give back a container c containing all placed volumes in the geometry.
0174    */
0175   template <typename Container>
0176   void getAllPlacedVolumes(Container &c) const;
0177 
0178   /**
0179    *  Give back a container c containing all possible geometry paths (NavigationStates)
0180    *  in the geometry, given a logical volume lvol.
0181    *  Container has to be an (stl::)container keeping pointer to NavigationStates.
0182    */
0183   template <typename Container>
0184   void getAllPathForLogicalVolume(LogicalVolume const *lvol, Container &c) const;
0185 
0186   /**
0187    *  Returns max depth of volume hierarchy. Can only be called after the geometry is closed.
0188    */
0189   int getMaxDepth() const
0190   {
0191     VECGEOM_ASSERT(fIsClosed == true);
0192     return fMaxDepth;
0193   }
0194 
0195   void RegisterPlacedVolume(VPlacedVolume *const placed_volume);
0196 
0197   void RegisterLogicalVolume(LogicalVolume *const logical_volume);
0198 
0199   void SetMinPerScene(int touchables) { fMinPerScene = touchables; }
0200 
0201   void DeregisterPlacedVolume(const int id);
0202 
0203   void DeregisterLogicalVolume(const int id);
0204 
0205   /**
0206    * \return Volume with passed id, or nullptr if the id wasn't found.
0207    */
0208   VPlacedVolume *FindPlacedVolume(const int id);
0209 
0210   /**
0211    * \return First occurrence of volume with passed label. If multiple volumes
0212    *         are found, their id will be printed to standard output.
0213    */
0214   VPlacedVolume *FindPlacedVolume(char const *const label);
0215 
0216   VECGEOM_FORCE_INLINE VPlacedVolume *GetPlacedVolume(const uint id) const { return &gCompactPlacedVolBuffer[id]; }
0217 
0218   /**
0219    * \return Volume with passed id, or NULL is the id wasn't found.
0220    */
0221   LogicalVolume *FindLogicalVolume(const int id);
0222 
0223   /**
0224    * \return First occurrence of volume with passed label. If multiple volumes
0225    *         are found, their id will be printed to standard output.
0226    */
0227   LogicalVolume *FindLogicalVolume(char const *const label);
0228 
0229   VECGEOM_FORCE_INLINE LogicalVolume *GetLogicalVolume(const uint id) const { return fLogicalVolumesArray[id]; }
0230 
0231   /**
0232    * \return Id of logical volume with passed label, or -1 if not found
0233    */
0234   int GetLogicalVolumeId(const std::string &label);
0235 
0236   /**
0237    * \return Label of logical volumen with passed Id, or empty string if not found
0238    */
0239   std::string GetLogicalVolumeLabel(int id);
0240 
0241   /**
0242    * Clear/resets the GeoManager. All geometry information will be deleted.
0243    */
0244   void Clear();
0245 
0246   /// Returns the number of placed volumes known to the GeoManager.
0247   size_t GetPlacedVolumesCount() const { return fPlacedVolumesMap.size(); }
0248 
0249   /** Returns the number of logical volumes registered in the GeoManager (map)
0250    * includes both tracking logical volumes and virtual volumes (which are part of composites for example)
0251    * in order to get the number of logical volumes which are seen from the perspective of a user,
0252    * the user should call getAllLogicalVolumes(...) and then determine the size from the resulting container
0253    */
0254   size_t GetRegisteredVolumesCount() const { return fLogicalVolumesMap.size(); }
0255 
0256   /// Returns the map of logical volumes.
0257   decltype(fLogicalVolumesMap) const &GetLogicalVolumesMap() const { return fLogicalVolumesMap; }
0258 
0259   /**
0260    * Returns the total number of leave nodes / geometry paths from top to leave in the geometry.
0261    */
0262   size_t GetTotalNodeCount() const { return fTotalNodeCount; }
0263 
0264   /// Creates the navigation index table, caching global transformations down to a given geometry depth
0265   /// min_per_scene is the minimum number of touchables to trigger scene creation for navigation tuples
0266 #if defined(VECGEOM_USE_NAVINDEX) || defined(VECGEOM_USE_NAVTUPLE)
0267   bool MakeNavIndexTable(int depth_limit = 0, int min_per_scene = 1000, bool validate = true) const;
0268 #endif
0269 
0270 private:
0271   GeoManager()
0272       : fVolumeCount(0), fTotalNodeCount(0), fWorld(NULL), fPlacedVolumesMap(), fLogicalVolumesMap(),
0273         fVolumeToIndexMap(), fLogicalVolumesArray(), fMaxDepth(-1), fIsClosed(false)
0274   {
0275   }
0276 
0277   GeoManager(GeoManager const &);
0278   GeoManager &operator=(GeoManager const &);
0279 };
0280 
0281 template <typename Visitor>
0282 void GeoManager::visitAllPlacedVolumes(VPlacedVolume const *currentvolume, Visitor *visitor, int level) const
0283 {
0284   if (currentvolume != NULL) {
0285     visitor->apply(const_cast<VPlacedVolume *>(currentvolume), level);
0286     int size = currentvolume->GetDaughters().size();
0287     for (int i = 0; i < size; ++i) {
0288       visitAllPlacedVolumes(currentvolume->GetDaughters().operator[](i), visitor, level + 1);
0289     }
0290   }
0291 }
0292 
0293 template <typename Container>
0294 void GeoManager::GetAllLogicalVolumes(Container &c) const
0295 {
0296   c.clear();
0297   // walk all the volume hierarchy and insert
0298   // logical volume if not already in the container
0299   SimpleLogicalVolumeVisitor<Container> lv(c);
0300   visitAllPlacedVolumes(GetWorld(), &lv);
0301 }
0302 
0303 template <typename Container>
0304 void GeoManager::getAllPlacedVolumes(Container &c) const
0305 {
0306   c.clear();
0307   // walk all the volume hierarchy and insert
0308   // placed volumes if not already in the container
0309   SimplePlacedVolumeVisitor<Container> pv(c);
0310   visitAllPlacedVolumes(GetWorld(), &pv);
0311 }
0312 
0313 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0314 /// A factory for unplaced shapes. Factory redirects to the "Maker" template
0315 template <typename UnplacedShape_t, typename... Argtypes>
0316 UnplacedShape_t *GeoManager::MakeInstance(Argtypes... args)
0317 {
0318   return Maker<UnplacedShape_t>::MakeInstance(args...);
0319 }
0320 #endif
0321 } // namespace vecgeom
0322 
0323 #endif // VECGEOM_MANAGEMENT_GEOMANAGER_H_