|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |