Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:26:05

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