Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //!    \file ReflFactory.h
0002 //!    \brief Factory dealing with reflected volumes, heavily inspired by G4ReflectionFactory
0003 //!
0004 //!    \authors Author:  Andrei Gheata <andrei.gheata@cern.ch>
0005 //!
0006 
0007 #ifndef VECGEOM_MANAGEMENT_REFLFACTORY_H_
0008 #define VECGEOM_MANAGEMENT_REFLFACTORY_H_
0009 
0010 #include <string>
0011 #include <map>
0012 #include "VecGeom/base/Transformation3D.h"
0013 #include "VecGeom/volumes/LogicalVolume.h"
0014 #include "VecGeom/volumes/PlacedVolume.h"
0015 
0016 namespace vecgeom {
0017 inline namespace cxx {
0018 
0019 // Class providing functions for volumes placements with a general
0020 // transfomation that may contain reflection.
0021 // Reflection is then applied to a solid: a new UnplacedScaledShape
0022 // instance is created and is placed with a transformation containing
0023 // pure rotation and translation only.
0024 // The pair of constituent and reflected logical volumes is
0025 // considered as a generalized logical volume that is addressed
0026 // by user specifying the constituent logical volume.
0027 //
0028 // Decomposition of a general transformation that can include reflection
0029 // in a "reflection-free" transformation:
0030 //
0031 // x(inM') = TG*x(inM)         TG - general transformation
0032 //         = T*(R*x(inM))      T  - "reflection-free" transformation
0033 //         = T* x(inReflM)
0034 //
0035 // Daughters transformation:
0036 // When a volume V containing daughter D with transformation TD
0037 // is placed in mother M with a general tranformation TGV,
0038 // the TGV is decomposed. New reflected volume ReflV containing
0039 // a new daughter ReflD with reflected transformation ReflTD is created:
0040 //
0041 // x(inV) = TD * x(inD);
0042 // x(inM) = TGV * x(inV)
0043 //        = TV * R * x(inV)
0044 //        = TV * R * TD * x(inD)
0045 //        = TV * R*TD*R-1 * R*x(inD)
0046 //        = TV * ReflTD * x(inReflD)
0047 
0048 class ReflFactory {
0049 
0050   using Vector3                   = vecgeom::Vector3D<vecgeom::Precision>;
0051   using Transformation3D          = vecgeom::Transformation3D;
0052   using LogicalVolume             = vecgeom::LogicalVolume;
0053   using VPlacedVolume             = vecgeom::VPlacedVolume;
0054   using ReflectedVolumesMap       = std::map<LogicalVolume *, LogicalVolume *>;
0055   using LogicalVolumesMapIterator = ReflectedVolumesMap::const_iterator;
0056 
0057 public:
0058   ~ReflFactory() { Clean(); }
0059 
0060   static ReflFactory &Instance()
0061   {
0062     static ReflFactory instance;
0063     return instance;
0064   }
0065 
0066   // In case a reflection is detected, this creates new reflected solid and
0067   // logical volume (or retrieves them from a map if the reflected
0068   // objects were already created), transforms the daughters (if present)
0069   // and place it in the given mother.
0070   // The result is a pair of physical volumes;
0071   // the second physical volume is a placement in a reflected mother
0072   // or 0 if mother LV was not reflected.
0073   bool Place(Transformation3D const &transform3D, Vector3 const &scale, std::string const &name,
0074              vecgeom::LogicalVolume *LV, vecgeom::LogicalVolume *motherLV, int copyNo);
0075 
0076   void SetVerboseLevel(int verboseLevel) { fVerboseLevel = verboseLevel; }
0077   int GetVerboseLevel() const { return fVerboseLevel; }
0078 
0079   // Returns the consituent volume of the given reflected volume,
0080   // nullptr if the given reflected volume was not found.
0081   LogicalVolume *GetConstituentLV(LogicalVolume *reflLV) const;
0082 
0083   // Returns the reflected volume of the given consituent volume,
0084   // nullptr if the given volume was not reflected.
0085   LogicalVolume *GetReflectedLV(LogicalVolume *lv) const;
0086 
0087   // Returns true if the given volume has been already reflected
0088   // (is in the map of constituent volumes).
0089   bool IsConstituent(LogicalVolume const *lv) const;
0090 
0091   // Returns true if the given volume is a reflected volume
0092   // (is in the map reflected  volumes).
0093   bool IsReflected(LogicalVolume const *lv) const;
0094 
0095   // Returns a handle to the internal map of volumes which have
0096   // been reflected, after that placement or replication is performed.
0097   ReflectedVolumesMap const &GetReflectedVolumesMap() const { return fReflectedLVMap; }
0098 
0099   // Clear maps of constituent and reflected volumes.
0100   // To be used exclusively when volumes are removed from the stores.
0101   void Clean();
0102 
0103   // Disabled copy constructor and assignment operator.
0104   ReflFactory(const ReflFactory &)            = delete;
0105   ReflFactory &operator=(const ReflFactory &) = delete;
0106 
0107 protected:
0108   ReflFactory();
0109   // Protected singleton constructor.
0110 
0111 private:
0112   // Returns scale * pureTransform3D * scale.Inverse()
0113   Transformation3D ConvertScaledToPureTransformation(Transformation3D const &pureTransform3D, Vector3 const &scale);
0114   // Gets/creates the reflected solid and logical volume
0115   // and copies + transforms LV daughters.
0116   LogicalVolume *ReflectLV(LogicalVolume *LV, Vector3 const &scale);
0117 
0118   // Creates the reflected solid and logical volume
0119   // and add the logical volumes pair in the maps.
0120   LogicalVolume *CreateReflectedLV(LogicalVolume *LV, Vector3 const &scale);
0121 
0122   // Reflects daughters recursively.
0123   void ReflectDaughters(LogicalVolume *LV, LogicalVolume *refLV, Vector3 const &scale);
0124 
0125   // Copies and transforms daughter of PVPlacement type of
0126   // a constituent volume into a reflected volume.
0127   void ReflectPlacedVolume(VPlacedVolume const *PV, LogicalVolume *refLV, Vector3 const &scale);
0128 
0129   // Returns true if the scale is negative, false otherwise.
0130   bool IsReflection(Vector3 const &scale) const { return scale[0] * scale[1] * scale[2] < 0; }
0131 
0132 private:
0133   int fVerboseLevel = 0;
0134   std::string fNameExtension;
0135   ReflectedVolumesMap fConstituentLVMap;
0136   ReflectedVolumesMap fReflectedLVMap;
0137 };
0138 
0139 } // namespace cxx
0140 } // namespace vecgeom
0141 
0142 #endif